2
0
mirror of https://github.com/frappe/books.git synced 2024-12-23 03:19:01 +00:00

fix(ui): Link fieldtype, show display field

- make address a manually named entry type
- make a few more entry types searchable
- fix dropdown filter undefined issue
- reset settings docs if not saved
- fix ux dropdown toggle on click
This commit is contained in:
18alantom 2023-03-02 11:58:08 +05:30
parent 51ce718d01
commit 48e9f1b668
11 changed files with 106 additions and 28 deletions

View File

@ -41,12 +41,12 @@ export class AccountingLedgerEntry extends Doc {
static getListViewSettings(): ListViewSettings { static getListViewSettings(): ListViewSettings {
return { return {
columns: [ columns: [
'date',
'account', 'account',
'party', 'party',
'debit', 'debit',
'credit', 'credit',
'referenceName', 'referenceName',
'reverted',
], ],
}; };
} }

View File

@ -1,6 +1,11 @@
import { t } from 'fyo'; import { Fyo, t } from 'fyo';
import { Doc } from 'fyo/model/doc'; import { Doc } from 'fyo/model/doc';
import { EmptyMessageMap, FormulaMap, ListsMap } from 'fyo/model/types'; import {
EmptyMessageMap,
FormulaMap,
ListsMap,
ListViewSettings,
} from 'fyo/model/types';
import { codeStateMap } from 'regional/in'; import { codeStateMap } from 'regional/in';
import { getCountryInfo } from 'utils/misc'; import { getCountryInfo } from 'utils/misc';
@ -54,4 +59,10 @@ export class Address extends Doc {
return t`Enter Country to load States`; return t`Enter Country to load States`;
}, },
}; };
static override getListViewSettings(): ListViewSettings {
return {
columns: ['name', 'addressLine1', 'city', 'state', 'country'],
};
}
} }

View File

@ -1,7 +1,7 @@
import { Doc } from 'fyo/model/doc'; import { Doc } from 'fyo/model/doc';
import { ListViewSettings } from 'fyo/model/types';
import { Money } from 'pesa'; import { Money } from 'pesa';
export class StockLedgerEntry extends Doc { export class StockLedgerEntry extends Doc {
date?: Date; date?: Date;
item?: string; item?: string;
@ -11,4 +11,17 @@ export class StockLedgerEntry extends Doc {
referenceName?: string; referenceName?: string;
referenceType?: string; referenceType?: string;
batch?: string; batch?: string;
static override getListViewSettings(): ListViewSettings {
return {
columns: [
'date',
'item',
'location',
'rate',
'quantity',
'referenceName',
],
};
}
} }

View File

@ -1,8 +1,15 @@
{ {
"name": "Address", "name": "Address",
"label": "Address", "label": "Address",
"naming": "manual",
"isSingle": false, "isSingle": false,
"fields": [ "fields": [
{
"fieldname": "name",
"label": "Address Name",
"fieldtype": "Data",
"required": true
},
{ {
"fieldname": "addressLine1", "fieldname": "addressLine1",
"label": "Address Line 1", "label": "Address Line 1",
@ -69,6 +76,7 @@
} }
], ],
"quickEditFields": [ "quickEditFields": [
"name",
"addressLine1", "addressLine1",
"addressLine2", "addressLine2",
"city", "city",

View File

@ -35,6 +35,7 @@
"fieldtype": "Link", "fieldtype": "Link",
"target": "Address", "target": "Address",
"inline": true, "inline": true,
"create": true,
"section": "Contacts" "section": "Contacts"
}, },
{ {

View File

@ -9,6 +9,7 @@
} }
], ],
"quickEditFields": [ "quickEditFields": [
"name",
"addressLine1", "addressLine1",
"addressLine2", "addressLine2",
"city", "city",

View File

@ -25,6 +25,7 @@
:placeholder="inputPlaceholder" :placeholder="inputPlaceholder"
:readonly="isReadOnly" :readonly="isReadOnly"
@focus="(e) => !isReadOnly && onFocus(e, toggleDropdown)" @focus="(e) => !isReadOnly && onFocus(e, toggleDropdown)"
@click="(e) => !isReadOnly && onFocus(e, toggleDropdown)"
@blur="(e) => !isReadOnly && onBlur(e.target.value)" @blur="(e) => !isReadOnly && onBlur(e.target.value)"
@input="onInput" @input="onInput"
@keydown.up="highlightItemUp" @keydown.up="highlightItemUp"
@ -55,7 +56,6 @@
</template> </template>
</Dropdown> </Dropdown>
</template> </template>
<script> <script>
import { getOptionList } from 'fyo/utils'; import { getOptionList } from 'fyo/utils';
import Dropdown from 'src/components/Dropdown.vue'; import Dropdown from 'src/components/Dropdown.vue';
@ -81,7 +81,7 @@ export default {
value: { value: {
immediate: true, immediate: true,
handler(newValue) { handler(newValue) {
this.linkValue = this.getLinkValue(newValue); this.setLinkValue(this.getLinkValue(newValue));
}, },
}, },
}, },
@ -89,7 +89,8 @@ export default {
doc: { default: null }, doc: { default: null },
}, },
mounted() { mounted() {
this.linkValue = this.getLinkValue(this.linkValue || this.value); const value = this.linkValue || this.value;
this.setLinkValue(this.getLinkValue(value));
}, },
computed: { computed: {
options() { options() {
@ -101,6 +102,9 @@ export default {
}, },
}, },
methods: { methods: {
setLinkValue(value) {
this.linkValue = value;
},
getLinkValue(value) { getLinkValue(value) {
const oldValue = this.linkValue; const oldValue = this.linkValue;
let option = this.options.find((o) => o.value === value); let option = this.options.find((o) => o.value === value);
@ -116,7 +120,7 @@ export default {
}, },
async updateSuggestions(keyword) { async updateSuggestions(keyword) {
if (typeof keyword === 'string') { if (typeof keyword === 'string') {
this.linkValue = keyword; this.setLinkValue(keyword, true);
} }
this.isLoading = true; this.isLoading = true;
@ -152,12 +156,12 @@ export default {
}, },
setSuggestion(suggestion) { setSuggestion(suggestion) {
if (suggestion?.actionOnly) { if (suggestion?.actionOnly) {
this.linkValue = this.value; this.setLinkValue(this.value);
return; return;
} }
if (suggestion) { if (suggestion) {
this.linkValue = suggestion.label; this.setLinkValue(suggestion.label);
this.triggerChange(suggestion.value); this.triggerChange(suggestion.value);
} }

View File

@ -16,18 +16,42 @@ export default {
}, },
mounted() { mounted() {
if (this.value) { if (this.value) {
this.linkValue = this.value; this.setLinkValue();
} }
}, },
watch: { watch: {
value: { value: {
immediate: true, immediate: true,
handler(newValue) { handler(newValue) {
this.linkValue = newValue; this.setLinkValue(newValue);
}, },
}, },
}, },
methods: { methods: {
async setLinkValue(newValue, isInput) {
if (isInput) {
return (this.linkValue = newValue || '');
}
const value = newValue ?? this.value;
const { fieldname, target } = this.df ?? {};
const displayField = fyo.schemaMap[target ?? '']?.inlineEditDisplayField;
if (!displayField) {
return (this.linkValue = value);
}
let displayValue = this.docs?.links?.[fieldname]?.get(displayField);
if (!displayValue) {
displayValue = await fyo.getValue(
target,
this.value ?? '',
displayField
);
}
this.linkValue = displayValue;
},
getTargetSchemaName() { getTargetSchemaName() {
return this.df.target; return this.df.target;
}, },
@ -104,10 +128,11 @@ export default {
'<Badge color="blue" class="ms-2" v-if="isNewValue">{{ linkValue }}</Badge>' + '<Badge color="blue" class="ms-2" v-if="isNewValue">{{ linkValue }}</Badge>' +
'</div>', '</div>',
computed: { computed: {
value: () => this.value,
linkValue: () => this.linkValue, linkValue: () => this.linkValue,
isNewValue: () => { isNewValue: () => {
let values = this.suggestions.map((d) => d.value); let values = this.suggestions.map((d) => d.value);
return this.linkValue && !values.includes(this.linkValue); return this.value && !values.includes(this.value);
}, },
}, },
components: { Badge }, components: { Badge },
@ -134,6 +159,7 @@ export default {
this.$emit('new-doc', doc); this.$emit('new-doc', doc);
this.$router.back(); this.$router.back();
this.results = []; this.results = [];
this.triggerChange(doc.name);
}); });
}, },
async getCreateFilters() { async getCreateFilters() {

View File

@ -165,7 +165,11 @@ export default {
methods: { methods: {
getRandomString, getRandomString,
addNewFilter() { addNewFilter() {
let df = this.fields[0]; const df = this.fields[0];
if (!df) {
return;
}
this.addFilter(df.fieldname, 'like', '', false); this.addFilter(df.fieldname, 'like', '', false);
}, },
addFilter(fieldname, condition, value, implicit) { addFilter(fieldname, condition, value, implicit) {

View File

@ -12,12 +12,11 @@
class="sticky top-0 bg-white border-b" class="sticky top-0 bg-white border-b"
> >
</FormHeader> </FormHeader>
<!-- Section Container -->
<!-- Section Container -->
<div class="overflow-auto custom-scroll" v-if="doc"> <div class="overflow-auto custom-scroll" v-if="doc">
<CommonFormSection <CommonFormSection
v-for="([name, fields], idx) in activeGroup.entries()" v-for="([name, fields], idx) in activeGroup.entries()"
@editrow="(doc: Doc) => toggleQuickEditDoc(doc)"
:key="name + idx" :key="name + idx"
ref="section" ref="section"
class="p-4" class="p-4"
@ -95,13 +94,11 @@ export default defineComponent({
canSave: false, canSave: false,
activeTab: ModelNameEnum.AccountingSettings, activeTab: ModelNameEnum.AccountingSettings,
groupedFields: null, groupedFields: null,
quickEditDoc: null,
} as { } as {
errors: Record<string, string>; errors: Record<string, string>;
canSave: boolean; canSave: boolean;
activeTab: string; activeTab: string;
groupedFields: null | UIGroupedFields; groupedFields: null | UIGroupedFields;
quickEditDoc: null | Doc;
}; };
}, },
provide() { provide() {
@ -118,10 +115,26 @@ export default defineComponent({
activated(): void { activated(): void {
docsPathRef.value = docsPathMap.Settings ?? ''; docsPathRef.value = docsPathMap.Settings ?? '';
}, },
deactivated(): void { async deactivated(): Promise<void> {
docsPathRef.value = ''; docsPathRef.value = '';
if (!this.canSave) {
return;
}
await this.reset();
}, },
methods: { methods: {
async reset() {
const resetableDocs = this.schemas
.map(({ name }) => this.fyo.singles[name])
.filter((doc) => doc?.dirty) as Doc[];
for (const doc of resetableDocs) {
await doc.load();
}
this.update();
},
async sync(): Promise<void> { async sync(): Promise<void> {
const syncableDocs = this.schemas const syncableDocs = this.schemas
.map(({ name }) => this.fyo.singles[name]) .map(({ name }) => this.fyo.singles[name])
@ -151,14 +164,6 @@ export default defineComponent({
await handleErrorWithDialog(err, doc); await handleErrorWithDialog(err, doc);
} }
}, },
async toggleQuickEditDoc(doc: Doc | null): Promise<void> {
if (this.quickEditDoc && doc) {
this.quickEditDoc = null;
await nextTick();
}
this.quickEditDoc = doc;
},
async onValueChange(field: Field, value: DocValue): Promise<void> { async onValueChange(field: Field, value: DocValue): Promise<void> {
const { fieldname } = field; const { fieldname } = field;
delete this.errors[fieldname]; delete this.errors[fieldname];

View File

@ -223,6 +223,10 @@ function getListViewList(fyo: Fyo): SearchItem[] {
ModelNameEnum.PurchaseInvoice, ModelNameEnum.PurchaseInvoice,
ModelNameEnum.SalesInvoice, ModelNameEnum.SalesInvoice,
ModelNameEnum.Tax, ModelNameEnum.Tax,
ModelNameEnum.UOM,
ModelNameEnum.Address,
ModelNameEnum.AccountingLedgerEntry,
ModelNameEnum.Currency,
]; ];
const hasInventory = fyo.doc.singles.AccountingSettings?.enableInventory; const hasInventory = fyo.doc.singles.AccountingSettings?.enableInventory;
@ -231,7 +235,8 @@ function getListViewList(fyo: Fyo): SearchItem[] {
ModelNameEnum.StockMovement, ModelNameEnum.StockMovement,
ModelNameEnum.Shipment, ModelNameEnum.Shipment,
ModelNameEnum.PurchaseReceipt, ModelNameEnum.PurchaseReceipt,
ModelNameEnum.Location ModelNameEnum.Location,
ModelNameEnum.StockLedgerEntry
); );
} }