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

incr: get quickedit to display

This commit is contained in:
18alantom 2022-04-28 12:04:55 +05:30
parent 9ebe35fe93
commit 1bcd0f0afb
12 changed files with 155 additions and 89 deletions

View File

@ -106,7 +106,7 @@ export const statusColor = {
};
export function getInvoiceStatus(doc: Doc) {
let status = `Unpaid`;
let status = 'Unpaid';
if (!doc.submitted) {
status = 'Draft';
}

View File

@ -33,9 +33,9 @@
<script>
import { ConfigKeys } from 'fyo/core/types';
import {
getSetupComplete,
incrementOpenCount,
startTelemetry
getSetupComplete,
incrementOpenCount,
startTelemetry,
} from 'src/utils/misc';
import TelemetryModal from './components/once/TelemetryModal.vue';
import WindowsTitleBar from './components/WindowsTitleBar.vue';

View File

@ -25,7 +25,7 @@ export default {
props: {
df: Object,
value: [String, Number, Boolean, Object],
inputClass: [Function, String],
inputClass: [Function, String, Object],
placeholder: String,
size: String,
showLabel: Boolean,

View File

@ -1,10 +1,12 @@
<template>
<Badge class="text-xs flex-center px-3 ml-2" :color="color" v-if="status">{{
status
statusLabel
}}</Badge>
</template>
<script>
import { t } from 'fyo';
import { statusColor } from 'src/utils/colors';
import Badge from './Badge.vue';
export default {
name: 'StatusBadge',
@ -13,6 +15,17 @@ export default {
color() {
return statusColor[this.status];
},
statusLabel() {
return (
{
Draft: t`Draft`,
Unpaid: t`Unpaid`,
Paid: t`Paid`,
Cancelled: t`Cancelled`,
}[this.status] ?? this.status
);
},
},
components: { Badge },
};
</script>

View File

@ -51,7 +51,7 @@
<script>
import { fyo } from 'src/initFyo';
import { routeTo } from 'src/utils';
import { getStatusColumn } from '../Transaction/Transaction';
// import { getStatusColumn } from '../Transaction/Transaction';
export default {
name: 'PartyWidget',
@ -96,8 +96,9 @@ export default {
window.pendingInvoices = this.pendingInvoices;
},
getStatusBadge(doc) {
let statusColumn = getStatusColumn();
return statusColumn.render(doc);
// let statusColumn = getStatusColumn();
// return statusColumn.render(doc);
return {}
},
routeToForm(doc) {
routeTo(`/edit/${this.invoiceDoctype}/${doc.name}`);

View File

@ -120,9 +120,10 @@
</div>
</template>
<script>
import { ModelNameEnum } from 'models/types';
import PageHeader from 'src/components/PageHeader';
import { fyo } from 'src/initFyo';
import { openQuickEdit } from 'src/utils';
import { openQuickEdit } from 'src/utils/ui';
import { nextTick } from 'vue';
import { handleErrorWithDialog } from '../errorHandling';
@ -134,7 +135,7 @@ export default {
return {
root: null,
accounts: [],
doctype: 'Account',
schemaName: 'Account',
insertingAccount: false,
};
},
@ -147,8 +148,8 @@ export default {
},
methods: {
async fetchAccounts() {
this.settings = fyo.getMeta(this.doctype).treeSettings;
const { currency } = await fyo.getSingle('AccountingSettings');
this.settings = fyo.models[ModelNameEnum.Account].getTreeSettings(fyo);
const { currency } = await fyo.doc.getSingle('AccountingSettings');
this.root = {
label: await this.settings.getRootLabel(),
balance: 0,
@ -159,7 +160,7 @@ export default {
onClick(account) {
if (account.isGroup === 0) {
openQuickEdit({
doctype: 'Account',
schemaName: ModelNameEnum.Account,
name: account.name,
});
} else {
@ -180,8 +181,7 @@ export default {
}
},
async getChildren(parent = null) {
const children = await fyo.db.getAll({
doctype: this.doctype,
const children = await fyo.db.getAll(ModelNameEnum.Account, {
filters: {
parentAccount: parent,
},

View File

@ -17,7 +17,7 @@
<component
:is="Component"
class="w-80 flex-1"
:key="$route.query.doctype + $route.query.name"
:key="$route.query.schemaName + $route.query.name"
/>
</keep-alive>
</router-view>
@ -37,7 +37,7 @@ export default {
showQuickEdit() {
return (
this.$route.query.edit &&
this.$route.query.doctype &&
this.$route.query.schemaName &&
this.$route.query.name
);
},

View File

@ -29,6 +29,7 @@ import Button from 'src/components/Button';
import FilterDropdown from 'src/components/FilterDropdown';
import PageHeader from 'src/components/PageHeader';
import { fyo } from 'src/initFyo';
import { routeTo } from 'src/utils/ui';
import List from './List';
export default {

View File

@ -16,7 +16,7 @@
:icon="true"
@click="sync"
type="primary"
v-if="doc && doc._notInserted"
v-if="doc && doc.notInserted"
class="ml-2 text-white text-xs"
>
{{ t`Save` }}
@ -26,11 +26,10 @@
@click="submitDoc"
type="primary"
v-if="
meta &&
meta.isSubmittable &&
schema?.isSubmittable &&
doc &&
!doc.submitted &&
!doc._notInserted &&
!doc.notInserted &&
!(doc.cancelled || false)
"
class="ml-2 text-white text-xs"
@ -78,17 +77,24 @@
<script>
import { t } from 'fyo';
import Button from 'src/components/Button';
import Button from 'src/components/Button.vue';
import FormControl from 'src/components/Controls/FormControl.vue';
import DropdownWithActions from 'src/components/DropdownWithActions';
import StatusBadge from 'src/components/StatusBadge';
import TwoColumnForm from 'src/components/TwoColumnForm';
import DropdownWithActions from 'src/components/DropdownWithActions.vue';
import StatusBadge from 'src/components/StatusBadge.vue';
import TwoColumnForm from 'src/components/TwoColumnForm.vue';
import { fyo } from 'src/initFyo';
import { getActionsForDocument, openQuickEdit } from 'src/utils';
import { getQuickEditWidget } from 'src/utils/quickEditWidgets';
import { getActionsForDocument, openQuickEdit } from 'src/utils/ui';
export default {
name: 'QuickEditForm',
props: ['doctype', 'name', 'valueJSON', 'hideFields', 'showFields'],
props: {
name: String,
schemaName: String,
defaults: String,
hideFields: { type: Array, default: () => [] },
showFields: { type: Array, default: () => [] },
},
components: {
Button,
FormControl,
@ -99,7 +105,7 @@ export default {
provide() {
let vm = this;
return {
doctype: this.doctype,
schemaName: this.schemaName,
name: this.name,
get doc() {
return vm.doc;
@ -107,11 +113,13 @@ export default {
};
},
mounted() {
if (!this.valueJSON) {
return;
if (this.defaults) {
this.values = JSON.parse(this.defaults);
}
this.values = JSON.parse(this.valueJSON);
if (fyo.store.isDevelopment) {
window.qef = this;
}
},
data() {
return {
@ -123,59 +131,64 @@ export default {
};
},
async created() {
await this.fetchMetaAndDoc();
await this.fetchFieldsAndDoc();
},
computed: {
meta() {
return fyo.getMeta(this.doctype);
schema() {
return fyo.schemaMap[this.schemaName] ?? null;
},
status() {
if (this.doc && this.doc._notInserted) {
if (this.doc && this.doc.notInserted) {
return 'Draft';
}
return '';
},
fields() {
const fields = this.meta
.getQuickEditFields()
.filter((df) => !(this.hideFields || []).includes(df.fieldname));
if (!this.schema) {
return [];
}
if (this.showFields) {
fields.push(
...this.meta.fields.filter(({ fieldname }) =>
this.showFields.includes(fieldname)
)
const fieldnames = (this.schema.quickEditFields ?? ['name']).filter(
(f) => !this.hideFields.includes(f)
);
if (this.showFields?.length) {
fieldnames.push(
...this.schema.fields
.map((f) => f.fieldname)
.filter((f) => this.showFields.includes(f))
);
}
return fields;
return fieldnames.map((f) => fyo.getField(this.schemaName, f));
},
actions() {
return getActionsForDocument(this.doc);
},
quickEditWidget() {
if (!this.meta.quickEditWidget) {
const widget = getQuickEditWidget(this.schemaName);
if (widget === null) {
return null;
}
return this.meta.quickEditWidget(this.doc);
return widget(this.doc);
},
},
methods: {
async fetchMetaAndDoc() {
this.titleField = this.meta.getField(this.meta.titleField);
this.imageField = this.meta.getField('image');
async fetchFieldsAndDoc() {
if (!this.schema) {
return;
}
const titleField = this.schema.titleField;
this.titleField = fyo.getField(this.schemaName, titleField);
this.imageField = fyo.getField(this.schemaName, 'image');
await this.fetchDoc();
// setup the title field
if (this.doc && this.doc.notInserted && this.doc[this.titleField.fieldname]) {
if (!this.titleField.readOnly) {
this.doc.set(this.titleField.fieldname, '');
setTimeout(() => {
this.$refs.titleControl.focus();
}, 300);
} else {
this.doc.set(this.titleField.fieldname, 'New ' + this.doc.doctype);
}
}
this.setTitleField();
// set default values
if (this.values) {
@ -185,13 +198,30 @@ export default {
// set title size
this.setTitleSize();
},
setTitleField() {
const { fieldname, readOnly } = this.titleField;
if (!this.doc?.notInserted || !this.doc[fieldname]) {
return;
}
if (readOnly) {
this.doc.set(fieldname, t`New ${this.schema.label}`);
return;
}
this.doc.set(fieldname, '');
setTimeout(() => {
this.$refs.titleControl.focus();
}, 300);
},
async fetchDoc() {
try {
this.doc = await fyo.doc.getDoc(this.doctype, this.name);
this.doc = await fyo.doc.getDoc(this.schemaName, this.name);
this.doc.once('afterRename', () => {
openQuickEdit({
doctype: this.doctype,
schemaName: this.schemaName,
name: this.doc.name,
});
});
@ -225,15 +255,19 @@ export default {
this.$router.back();
},
setTitleSize() {
if (this.$refs.titleControl) {
let input = this.$refs.titleControl.getInput();
let value = input.value;
let valueLength = (value || '').length + 1;
if (valueLength < 7) {
valueLength = 7;
}
input.size = valueLength;
if (!this.$refs.titleControl) {
return;
}
const input = this.$refs.titleControl.getInput();
const value = input.value;
let valueLength = (value || '').length + 1;
if (valueLength < 7) {
valueLength = 7;
}
input.size = valueLength;
},
},
};

View File

@ -1,7 +1,7 @@
import { NounEnum, Verb } from 'fyo/telemetry/types';
import ChartOfAccounts from 'src/pages/ChartOfAccounts.vue';
import Dashboard from 'src/pages/Dashboard/Dashboard.vue';
import GetStarted from 'src/pages/GetStarted.vue';
// import ChartOfAccounts from 'src/pages/ChartOfAccounts.vue';
// import DataImport from 'src/pages/DataImport.vue';
// import InvoiceForm from 'src/pages/InvoiceForm.vue';
// import JournalEntryForm from 'src/pages/JournalEntryForm.vue';
@ -77,7 +77,9 @@ const routes: RouteRecordRaw[] = [
filters,
};
},
edit: (route) => route.query,
edit: (route) => {
return route.query;
},
},
},
/*
@ -93,6 +95,7 @@ const routes: RouteRecordRaw[] = [
component: Report,
props: true,
},
*/
{
path: '/chart-of-accounts',
name: 'Chart Of Accounts',
@ -105,6 +108,7 @@ const routes: RouteRecordRaw[] = [
edit: (route) => route.query,
},
},
/*
{
path: '/data_import',
name: 'Data Import',

View File

@ -0,0 +1,18 @@
import { Doc } from 'fyo/model/doc';
import { ModelNameEnum } from 'models/types';
import PartyWidget from 'src/components/Widgets/PartyWidget.vue';
import { h } from 'vue';
export function getQuickEditWidget(schemaName: string) {
if (schemaName === ModelNameEnum.Party) {
return (doc: Doc) => ({
render() {
return h(PartyWidget, {
doc,
});
},
});
}
return null;
}

View File

@ -24,20 +24,21 @@ import {
export async function openQuickEdit({
schemaName,
name,
hideFields,
showFields,
hideFields = [],
showFields = [],
defaults = {},
}: QuickEditOptions) {
const currentRoute = router.currentRoute.value;
const query = currentRoute.query;
let method: 'push' | 'replace' = 'push';
if (query.edit && query.doctype === schemaName) {
// replace the current route if we are
// editing another document of the same doctype
if (query.edit && query.schemaName === schemaName) {
method = 'replace';
}
if (query.name === name) return;
if (query.name === name) {
return;
}
const forWhat = (defaults?.for ?? []) as string[];
if (forWhat[0] === 'not in') {
@ -60,24 +61,18 @@ export async function openQuickEdit({
router[method]({
query: {
edit: 1,
doctype: schemaName,
schemaName,
name,
showFields: showFields ?? getShowFields(schemaName),
showFields,
hideFields,
valueJSON: stringifyCircular(defaults),
// @ts-ignore
defaults: stringifyCircular(defaults),
/*
lastRoute: currentRoute,
*/
},
});
}
function getShowFields(schemaName: string) {
if (schemaName === 'Party') {
return ['customer'];
}
return [];
}
export async function showMessageDialog({
message,
detail,