2
0
mirror of https://github.com/frappe/books.git synced 2025-01-22 22:58:28 +00:00

incr: add computed, update row amount display vals

This commit is contained in:
18alantom 2022-07-12 15:53:41 +05:30
parent 3dfdf22f9f
commit eb66317dce
14 changed files with 347 additions and 42 deletions

View File

@ -610,7 +610,9 @@ export default class DatabaseCore extends DatabaseBase {
async #createTable(schemaName: string, tableName?: string) { async #createTable(schemaName: string, tableName?: string) {
tableName ??= schemaName; tableName ??= schemaName;
const fields = this.schemaMap[schemaName]!.fields; const fields = this.schemaMap[schemaName]!.fields.filter(
(f) => !f.computed
);
return await this.#runCreateTableQuery(tableName, fields); return await this.#runCreateTableQuery(tableName, fields);
} }

View File

@ -384,18 +384,27 @@ export class Doc extends Observable<DocValue | Doc[]> {
await validator(value); await validator(value);
} }
getValidDict(filterMeta: boolean = false): DocValueMap { getValidDict(
filterMeta: boolean = false,
filterComputed: boolean = false
): DocValueMap {
let fields = this.schema.fields; let fields = this.schema.fields;
if (filterMeta) { if (filterMeta) {
fields = this.schema.fields.filter((f) => !f.meta); fields = this.schema.fields.filter((f) => !f.meta);
} }
if (filterComputed) {
fields = this.schema.fields.filter((f) => !f.computed);
}
const data: DocValueMap = {}; const data: DocValueMap = {};
for (const field of fields) { for (const field of fields) {
let value = this[field.fieldname] as DocValue | DocValueMap[]; let value = this[field.fieldname] as DocValue | DocValueMap[];
if (Array.isArray(value)) { if (Array.isArray(value)) {
value = value.map((doc) => (doc as Doc).getValidDict(filterMeta)); value = value.map((doc) =>
(doc as Doc).getValidDict(filterMeta, filterComputed)
);
} }
if (isPesa(value)) { if (isPesa(value)) {
@ -577,7 +586,7 @@ export class Doc extends Observable<DocValue | Doc[]> {
continue; continue;
} }
const newVal = await this._getValueFromFormula(field, doc); const newVal = await this._getValueFromFormula(field, doc, fieldname);
const previousVal = doc.get(field.fieldname); const previousVal = doc.get(field.fieldname);
const isSame = areDocValuesEqual(newVal as DocValue, previousVal); const isSame = areDocValuesEqual(newVal as DocValue, previousVal);
if (newVal === undefined || isSame) { if (newVal === undefined || isSame) {
@ -591,7 +600,7 @@ export class Doc extends Observable<DocValue | Doc[]> {
return changed; return changed;
} }
async _getValueFromFormula(field: Field, doc: Doc) { async _getValueFromFormula(field: Field, doc: Doc, fieldname?: string) {
const { formula } = doc.formulas[field.fieldname] ?? {}; const { formula } = doc.formulas[field.fieldname] ?? {};
if (formula === undefined) { if (formula === undefined) {
return; return;
@ -599,7 +608,7 @@ export class Doc extends Observable<DocValue | Doc[]> {
let value: FormulaReturn; let value: FormulaReturn;
try { try {
value = await formula(); value = await formula(fieldname);
} catch { } catch {
return; return;
} }
@ -623,7 +632,7 @@ export class Doc extends Observable<DocValue | Doc[]> {
this._setBaseMetaValues(); this._setBaseMetaValues();
await this._preSync(); await this._preSync();
const validDict = this.getValidDict(); const validDict = this.getValidDict(false, true);
const data = await this.fyo.db.insert(this.schemaName, validDict); const data = await this.fyo.db.insert(this.schemaName, validDict);
this._syncValues(data); this._syncValues(data);
@ -636,7 +645,7 @@ export class Doc extends Observable<DocValue | Doc[]> {
this._updateModifiedMetaValues(); this._updateModifiedMetaValues();
await this._preSync(); await this._preSync();
const data = this.getValidDict(); const data = this.getValidDict(false, true);
await this.fyo.db.update(this.schemaName, data); await this.fyo.db.update(this.schemaName, data);
this._syncValues(data); this._syncValues(data);
@ -750,7 +759,7 @@ export class Doc extends Observable<DocValue | Doc[]> {
} }
duplicate(): Doc { duplicate(): Doc {
const updateMap = this.getValidDict(true); const updateMap = this.getValidDict(true, true);
for (const field in updateMap) { for (const field in updateMap) {
const value = updateMap[field]; const value = updateMap[field];
if (!Array.isArray(value)) { if (!Array.isArray(value)) {

View File

@ -18,7 +18,7 @@ import { Doc } from './doc';
* - `Required`: Regular function used to decide if a value is mandatory (there are !notnul in the db). * - `Required`: Regular function used to decide if a value is mandatory (there are !notnul in the db).
*/ */
export type FormulaReturn = DocValue | DocValueMap[] | undefined | Doc[]; export type FormulaReturn = DocValue | DocValueMap[] | undefined | Doc[];
export type Formula = () => Promise<FormulaReturn> | FormulaReturn; export type Formula = (fieldname?: string) => Promise<FormulaReturn> | FormulaReturn;
export type FormulaConfig = { dependsOn?: string[]; formula: Formula }; export type FormulaConfig = { dependsOn?: string[]; formula: Formula };
export type Default = () => DocValue; export type Default = () => DocValue;
export type Validation = (value: DocValue) => Promise<void> | void; export type Validation = (value: DocValue) => Promise<void> | void;

View File

@ -11,12 +11,33 @@ export abstract class InvoiceItem extends Doc {
amount?: Money; amount?: Money;
baseAmount?: Money; baseAmount?: Money;
exchangeRate?: number; exchangeRate?: number;
itemDiscountPercent?: number;
itemDiscountAmount?: Money;
parentdoc?: Invoice; parentdoc?: Invoice;
rate?: Money;
quantity?: number;
tax?: string;
get isSales() { get isSales() {
return this.schemaName === 'SalesInvoiceItem'; return this.schemaName === 'SalesInvoiceItem';
} }
get discountAfterTax() {
return !!this?.parentdoc?.discountAfterTax;
}
async getTotalTaxRate(): Promise<number> {
if (!this.tax) {
return 0;
}
const details =
((await this.fyo.getValue('Tax', this.tax, 'details')) as Doc[]) ?? [];
return details.reduce((acc, doc) => {
return (doc.rate as number) + acc;
}, 0);
}
formulas: FormulaMap = { formulas: FormulaMap = {
description: { description: {
formula: async () => formula: async () =>
@ -27,6 +48,102 @@ export abstract class InvoiceItem extends Doc {
)) as string, )) as string,
dependsOn: ['item'], dependsOn: ['item'],
}, },
itemDiscountAmount: {
formula: async (fieldname) => {
if (fieldname === 'itemDiscountPercent') {
return this.amount!.percent(this.itemDiscountPercent ?? 0);
}
return this.fyo.pesa(0);
},
dependsOn: ['itemDiscountPercent'],
},
itemDiscountPercent: {
formula: async (fieldname) => {
const itemDiscountAmount = this.itemDiscountAmount ?? this.fyo.pesa(0);
if (!this.discountAfterTax) {
return itemDiscountAmount.div(this.amount ?? 0).mul(100).float;
}
const totalTaxRate = await this.getTotalTaxRate();
const rate = this.rate ?? this.fyo.pesa(0);
const quantity = this.quantity ?? 1;
const taxedTotal = getTaxedTotalBeforeDiscounting(
totalTaxRate,
rate,
quantity
);
return itemDiscountAmount.div(taxedTotal).mul(100).float;
},
dependsOn: ['itemDiscountAmount'],
},
itemDiscountedTotal: {
formula: async (fieldname) => {
const totalTaxRate = await this.getTotalTaxRate();
const rate = this.rate ?? this.fyo.pesa(0);
const quantity = this.quantity ?? 1;
const itemDiscountAmount = this.itemDiscountAmount ?? this.fyo.pesa(0);
const itemDiscountPercent = this.itemDiscountPercent ?? 0;
if (!this.discountAfterTax) {
return getDiscountedTotalBeforeTaxation(
rate,
quantity,
itemDiscountAmount,
itemDiscountPercent,
fieldname
);
}
return getDiscountedTotalAfterTaxation(
totalTaxRate,
rate,
quantity,
itemDiscountAmount,
itemDiscountPercent,
fieldname
);
},
dependsOn: [
'item',
'rate',
'tax',
'quantity',
'itemDiscountAmount',
'itemDiscountPercent',
],
},
itemTaxedTotal: {
formula: async (fieldname) => {
const totalTaxRate = await this.getTotalTaxRate();
const rate = this.rate ?? this.fyo.pesa(0);
const quantity = this.quantity ?? 1;
const itemDiscountAmount = this.itemDiscountAmount ?? this.fyo.pesa(0);
const itemDiscountPercent = this.itemDiscountPercent ?? 0;
if (!this.discountAfterTax) {
return getTaxedTotalAfterDiscounting(
totalTaxRate,
rate,
quantity,
itemDiscountAmount,
itemDiscountPercent,
fieldname
);
}
return getTaxedTotalBeforeDiscounting(totalTaxRate, rate, quantity);
},
dependsOn: [
'item',
'rate',
'tax',
'quantity',
'itemDiscountAmount',
'itemDiscountPercent',
],
},
rate: { rate: {
formula: async () => { formula: async () => {
const rate = (await this.fyo.getValue( const rate = (await this.fyo.getValue(
@ -142,3 +259,88 @@ export abstract class InvoiceItem extends Doc {
}, },
}; };
} }
function getDiscountedTotalBeforeTaxation(
rate: Money,
quantity: number,
itemDiscountAmount: Money,
itemDiscountPercent: number,
fieldname?: string
) {
/**
* If Discount is applied before taxation
* Use different formulas depending on how discount is set
* - if amount : Quantity * Rate - DiscountAmount
* - if percent: Quantity * Rate (1 - DiscountPercent / 100)
*/
const amount = rate.mul(quantity);
if (fieldname === 'itemDiscountAmount') {
return amount.sub(itemDiscountAmount);
}
return amount.mul(1 - itemDiscountPercent / 100);
}
function getTaxedTotalAfterDiscounting(
totalTaxRate: number,
rate: Money,
quantity: number,
itemDiscountAmount: Money,
itemDiscountPercent: number,
fieldname?: string
) {
/**
* If Discount is applied before taxation
* Formula: Discounted Total * (1 + TotalTaxRate / 100)
*/
const discountedTotal = getDiscountedTotalBeforeTaxation(
rate,
quantity,
itemDiscountAmount,
itemDiscountPercent,
fieldname
);
return discountedTotal.mul(1 + totalTaxRate / 100);
}
function getDiscountedTotalAfterTaxation(
totalTaxRate: number,
rate: Money,
quantity: number,
itemDiscountAmount: Money,
itemDiscountPercent: number,
fieldname?: string
) {
/**
* If Discount is applied after taxation
* Use different formulas depending on how discount is set
* - if amount : Taxed Total - Discount Amount
* - if percent: Taxed Total * (1 - Discount Percent / 100)
*/
const taxedTotal = getTaxedTotalBeforeDiscounting(
totalTaxRate,
rate,
quantity
);
if (fieldname === 'itemDiscountAmount') {
return taxedTotal.sub(itemDiscountAmount);
}
return taxedTotal.mul(1 - itemDiscountPercent / 100);
}
function getTaxedTotalBeforeDiscounting(
totalTaxRate: number,
rate: Money,
quantity: number
) {
/**
* If Discount is applied after taxation
* Formula: Rate * Quantity * (1 + Total Tax Rate / 100)
*/
return rate.mul(quantity).mul(1 + totalTaxRate / 100);
}

View File

@ -66,16 +66,30 @@
}, },
{ {
"fieldname": "itemDiscountAmount", "fieldname": "itemDiscountAmount",
"label": "Item Discount Amount", "label": "Discount Amount",
"fieldtype": "Currency", "fieldtype": "Currency",
"readOnly": false "readOnly": false
}, },
{ {
"fieldname": "itemDiscountPercent", "fieldname": "itemDiscountPercent",
"label": "Item Discount Percent", "label": "Discount Percent",
"fieldtype": "Float", "fieldtype": "Float",
"readOnly": false "readOnly": false
}, },
{
"fieldname": "itemDiscountedTotal",
"label": "Discounted Total",
"fieldtype": "Currency",
"readOnly": false,
"computed": true
},
{
"fieldname": "itemTaxedTotal",
"label": "Taxed Total",
"fieldtype": "Currency",
"readOnly": false,
"computed": true
},
{ {
"fieldname": "hsnCode", "fieldname": "hsnCode",
"label": "HSN/SAC", "label": "HSN/SAC",
@ -88,12 +102,16 @@
"keywordFields": ["item", "tax"], "keywordFields": ["item", "tax"],
"quickEditFields": [ "quickEditFields": [
"item", "item",
"account",
"description", "description",
"hsnCode", "hsnCode",
"tax", "tax",
"quantity", "quantity",
"rate", "rate",
"amount",
"itemDiscountAmount", "itemDiscountAmount",
"itemDiscountPercent" "itemDiscountPercent",
"itemDiscountedTotal",
"itemTaxedTotal"
] ]
} }

View File

@ -14,8 +14,7 @@
{ {
"fieldname": "description", "fieldname": "description",
"label": "Description", "label": "Description",
"fieldtype": "Text", "fieldtype": "Text"
"hidden": true
}, },
{ {
"fieldname": "quantity", "fieldname": "quantity",
@ -39,12 +38,9 @@
{ {
"fieldname": "account", "fieldname": "account",
"label": "Account", "label": "Account",
"hidden": true,
"fieldtype": "Link", "fieldtype": "Link",
"target": "Account", "target": "Account",
"create": true, "required": true
"required": true,
"readOnly": true
}, },
{ {
"fieldname": "tax", "fieldname": "tax",
@ -67,34 +63,51 @@
}, },
{ {
"fieldname": "itemDiscountAmount", "fieldname": "itemDiscountAmount",
"label": "Item Discount Amount", "label": "Discount Amount",
"fieldtype": "Currency", "fieldtype": "Currency",
"readOnly": false "readOnly": false
}, },
{ {
"fieldname": "itemDiscountPercent", "fieldname": "itemDiscountPercent",
"label": "Item Discount Percent", "label": "Discount Percent",
"fieldtype": "Float", "fieldtype": "Float",
"readOnly": false "readOnly": false
}, },
{
"fieldname": "itemDiscountedTotal",
"label": "Discounted Total",
"fieldtype": "Currency",
"readOnly": false,
"computed": true
},
{
"fieldname": "itemTaxedTotal",
"label": "Taxed Total",
"fieldtype": "Currency",
"readOnly": false,
"computed": true
},
{ {
"fieldname": "hsnCode", "fieldname": "hsnCode",
"label": "HSN/SAC", "label": "HSN/SAC",
"fieldtype": "Int", "fieldtype": "Int",
"placeholder": "HSN/SAC Code", "placeholder": "HSN/SAC Code"
"hidden": true
} }
], ],
"tableFields": ["item", "tax", "quantity", "rate", "amount"], "tableFields": ["item", "tax", "quantity", "rate", "amount"],
"keywordFields": ["item", "tax"], "keywordFields": ["item", "tax"],
"quickEditFields": [ "quickEditFields": [
"item", "item",
"account",
"description", "description",
"hsnCode", "hsnCode",
"tax", "tax",
"quantity", "quantity",
"rate", "rate",
"amount",
"itemDiscountAmount", "itemDiscountAmount",
"itemDiscountPercent" "itemDiscountPercent",
"itemDiscountedTotal",
"itemTaxedTotal"
] ]
} }

View File

@ -33,6 +33,7 @@ export interface BaseField {
groupBy?: string; // UI Facing used in dropdowns fields groupBy?: string; // UI Facing used in dropdowns fields
meta?: boolean; // Field is a meta field, i.e. only for the db, not UI meta?: boolean; // Field is a meta field, i.e. only for the db, not UI
inline?: boolean; // UI Facing config, whether to display doc inline. inline?: boolean; // UI Facing config, whether to display doc inline.
computed?: boolean; // Computed values are not stored in the database.
} }
export type SelectOption = { value: string; label: string }; export type SelectOption = { value: string; label: string };

View File

@ -46,6 +46,7 @@
:background="false" :background="false"
@click="openRowQuickEdit" @click="openRowQuickEdit"
v-if="canEditRow" v-if="canEditRow"
:disabled="isEditing"
> >
<feather-icon name="edit" class="w-4 h-4 text-gray-600" /> <feather-icon name="edit" class="w-4 h-4 text-gray-600" />
</Button> </Button>
@ -97,6 +98,9 @@ export default {
doc: this.row, doc: this.row,
}; };
}, },
inject: {
isEditing: { default: false },
},
methods: { methods: {
onChange(df, value) { onChange(df, value) {
if (value == null) { if (value == null) {

View File

@ -16,6 +16,7 @@
</h1> </h1>
<div class="flex items-stretch window-no-drag gap-2 ml-auto"> <div class="flex items-stretch window-no-drag gap-2 ml-auto">
<slot /> <slot />
<div class="border-r" v-if="showBorder" />
<BackLink v-if="backLink" class="window-no-drag" /> <BackLink v-if="backLink" class="window-no-drag" />
<SearchBar v-if="!hideSearch" /> <SearchBar v-if="!hideSearch" />
</div> </div>
@ -33,5 +34,10 @@ export default {
border: { type: Boolean, default: true }, border: { type: Boolean, default: true },
}, },
components: { SearchBar, BackLink }, components: { SearchBar, BackLink },
computed: {
showBorder() {
return !!this.$slots.default;
},
},
}; };
</script> </script>

View File

@ -16,7 +16,7 @@
<keep-alive> <keep-alive>
<component <component
:is="Component" :is="Component"
class="w-80 flex-1" class="w-quick-edit flex-1"
:key="$route.query.schemaName + $route.query.name" :key="$route.query.schemaName + $route.query.name"
/> />
</keep-alive> </keep-alive>

View File

@ -10,6 +10,13 @@
> >
{{ t`Print` }} {{ t`Print` }}
</Button> </Button>
<Button
:icon="true"
v-if="!doc?.isSubmitted && !quickEditDoc"
@click="toggleInvoiceSettings"
>
<feather-icon name="settings" class="w-4 h-4" />
</Button>
<DropdownWithActions :actions="actions()" /> <DropdownWithActions :actions="actions()" />
<Button <Button
v-if="doc?.notInserted || doc?.dirty" v-if="doc?.notInserted || doc?.dirty"
@ -60,7 +67,6 @@
input-class="text-lg font-semibold bg-transparent" input-class="text-lg font-semibold bg-transparent"
:df="getField('party')" :df="getField('party')"
:value="doc.party" :value="doc.party"
:placeholder="getField('party').label"
@change="(value) => doc.set('party', value)" @change="(value) => doc.set('party', value)"
@new-doc="(party) => doc.set('party', party.name)" @new-doc="(party) => doc.set('party', party.name)"
:read-only="doc?.submitted" :read-only="doc?.submitted"
@ -69,7 +75,6 @@
input-class="bg-gray-100 px-3 py-2 text-base text-right" input-class="bg-gray-100 px-3 py-2 text-base text-right"
:df="getField('date')" :df="getField('date')"
:value="doc.date" :value="doc.date"
:placeholder="'Date'"
@change="(value) => doc.set('date', value)" @change="(value) => doc.set('date', value)"
:read-only="doc?.submitted" :read-only="doc?.submitted"
/> />
@ -86,10 +91,18 @@
input-class="px-3 py-2 text-base bg-transparent" input-class="px-3 py-2 text-base bg-transparent"
:df="getField('account')" :df="getField('account')"
:value="doc.account" :value="doc.account"
:placeholder="'Account'"
@change="(value) => doc.set('account', value)" @change="(value) => doc.set('account', value)"
:read-only="doc?.submitted" :read-only="doc?.submitted"
/> />
<FormControl
v-if="doc.discountPercent > 0"
class="text-base bg-gray-100 rounded"
input-class="px-3 py-2 text-base bg-transparent text-right"
:df="getField('discountPercent')"
:value="doc.discountPercent"
@change="(value) => doc.set('discountPercent', value)"
:read-only="doc?.submitted"
/>
</div> </div>
<hr /> <hr />
@ -101,7 +114,7 @@
:showHeader="true" :showHeader="true"
:max-rows-before-overflow="4" :max-rows-before-overflow="4"
@change="(value) => doc.set('items', value)" @change="(value) => doc.set('items', value)"
@editrow="(r) => (row = r)" @editrow="toggleQuickEditDoc"
:read-only="doc?.submitted" :read-only="doc?.submitted"
/> />
</div> </div>
@ -177,14 +190,19 @@
</div> </div>
</template> </template>
<template #quickedit v-if="row"> <template #quickedit v-if="quickEditDoc">
<QuickEditForm <QuickEditForm
class="w-80" class="w-quick-edit"
:name="row.name" :name="quickEditDoc.name"
:source-doc="row" :show-name="false"
:schema-name="row.schemaName" :show-save="false"
:source-doc="quickEditDoc"
:source-fields="quickEditFields"
:schema-name="quickEditDoc.schemaName"
:white="true"
:route-back="false" :route-back="false"
@close="row = null" :load-on-close="false"
@close="toggleQuickEditDoc(null)"
/> />
</template> </template>
</FormContainer> </FormContainer>
@ -227,13 +245,15 @@ export default {
schemaName: this.schemaName, schemaName: this.schemaName,
name: this.name, name: this.name,
doc: computed(() => this.doc), doc: computed(() => this.doc),
isEditing: computed(() => !!this.quickEditDoc),
}; };
}, },
data() { data() {
return { return {
chstatus: false, chstatus: false,
doc: null, doc: null,
row: null, quickEditDoc: null,
quickEditFields: [],
color: null, color: null,
printSettings: null, printSettings: null,
companyName: null, companyName: null,
@ -281,6 +301,23 @@ export default {
}, },
methods: { methods: {
routeTo, routeTo,
toggleInvoiceSettings() {
if (this.quickEditDoc || !this.schemaName) {
return;
}
const fields = [
'discountAfterTax',
'discountAmount',
'discountPercent',
].map((fn) => fyo.getField(this.schemaName, fn));
this.toggleQuickEditDoc(this.doc, fields);
},
toggleQuickEditDoc(doc, fields = []) {
this.quickEditDoc = doc;
this.quickEditFields = fields;
},
actions() { actions() {
return getActionsForDocument(this.doc); return getActionsForDocument(this.doc);
}, },

View File

@ -37,7 +37,7 @@
</div> </div>
<!-- Printview Customizer --> <!-- Printview Customizer -->
<div class="border-l w-80" v-if="showCustomiser"> <div class="border-l w-quick-edit" v-if="showCustomiser">
<div <div
class="px-4 flex items-center justify-between h-row-largest border-b" class="px-4 flex items-center justify-between h-row-largest border-b"
> >

View File

@ -6,7 +6,7 @@
<!-- Quick edit Tool bar --> <!-- Quick edit Tool bar -->
<div <div
class="flex items-center justify-between px-4 h-row-largest" class="flex items-center justify-between px-4 h-row-largest"
:class="{ 'border-b': !isChild }" :class="{ 'border-b': showName }"
> >
<!-- Close Button and Status Text --> <!-- Close Button and Status Text -->
<div class="flex items-center"> <div class="flex items-center">
@ -19,7 +19,7 @@
</div> </div>
<!-- Actions, Badge and Status Change Buttons --> <!-- Actions, Badge and Status Change Buttons -->
<div class="flex items-stretch gap-2" v-if="!isChild"> <div class="flex items-stretch gap-2" v-if="showSave">
<StatusBadge :status="status" /> <StatusBadge :status="status" />
<DropdownWithActions :actions="actions" /> <DropdownWithActions :actions="actions" />
<Button <Button
@ -52,7 +52,7 @@
<div <div
class="px-4 flex-center flex flex-col items-center gap-1.5" class="px-4 flex-center flex flex-col items-center gap-1.5"
style="height: calc(var(--h-row-mid) * 2 + 1px)" style="height: calc(var(--h-row-mid) * 2 + 1px)"
v-if="doc && !isChild" v-if="doc && showName"
> >
<FormControl <FormControl
v-if="imageField" v-if="imageField"
@ -110,8 +110,12 @@ export default {
schemaName: String, schemaName: String,
defaults: String, defaults: String,
white: { type: Boolean, default: false }, white: { type: Boolean, default: false },
sourceDoc: { type: Doc, default: null },
routeBack: { type: Boolean, default: true }, routeBack: { type: Boolean, default: true },
showName: { type: Boolean, default: true },
showSave: { type: Boolean, default: true },
sourceDoc: { type: Doc, default: null },
loadOnClose: { type: Boolean, default: true },
sourceFields: { type: Array, default: () => [] },
hideFields: { type: Array, default: () => [] }, hideFields: { type: Array, default: () => [] },
showFields: { type: Array, default: () => [] }, showFields: { type: Array, default: () => [] },
}, },
@ -162,6 +166,10 @@ export default {
return getDocStatus(this.doc); return getDocStatus(this.doc);
}, },
fields() { fields() {
if (this.sourceFields?.length) {
return this.sourceFields;
}
if (!this.schema) { if (!this.schema) {
return []; return [];
} }
@ -294,7 +302,7 @@ export default {
} }
}, },
routeToPrevious() { routeToPrevious() {
if (this.doc.dirty && !this.doc.notInserted) { if (this.loadOnClose && this.doc.dirty && !this.doc.notInserted) {
this.doc.load(); this.doc.load();
} }

View File

@ -58,6 +58,7 @@ html {
--w-sidebar: 12rem; --w-sidebar: 12rem;
--w-desk: calc(100vw - var(--w-sidebar)); --w-desk: calc(100vw - var(--w-sidebar));
--w-desk-fixed: calc(var(--w-app) - var(--w-sidebar)); --w-desk-fixed: calc(var(--w-app) - var(--w-sidebar));
--w-quick-edit: 22rem;
--w-scrollbar: 0.5rem; --w-scrollbar: 0.5rem;
/* Row Heights */ /* Row Heights */
@ -73,6 +74,10 @@ html {
width: 600px; width: 600px;
} }
.w-quick-edit {
width: var(--w-quick-edit)
}
.h-form { .h-form {
height: 800px; height: 800px;
} }