2
0
mirror of https://github.com/frappe/books.git synced 2025-02-02 12:08:27 +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) { export function getInvoiceStatus(doc: Doc) {
let status = `Unpaid`; let status = 'Unpaid';
if (!doc.submitted) { if (!doc.submitted) {
status = 'Draft'; status = 'Draft';
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -16,7 +16,7 @@
:icon="true" :icon="true"
@click="sync" @click="sync"
type="primary" type="primary"
v-if="doc && doc._notInserted" v-if="doc && doc.notInserted"
class="ml-2 text-white text-xs" class="ml-2 text-white text-xs"
> >
{{ t`Save` }} {{ t`Save` }}
@ -26,11 +26,10 @@
@click="submitDoc" @click="submitDoc"
type="primary" type="primary"
v-if=" v-if="
meta && schema?.isSubmittable &&
meta.isSubmittable &&
doc && doc &&
!doc.submitted && !doc.submitted &&
!doc._notInserted && !doc.notInserted &&
!(doc.cancelled || false) !(doc.cancelled || false)
" "
class="ml-2 text-white text-xs" class="ml-2 text-white text-xs"
@ -78,17 +77,24 @@
<script> <script>
import { t } from 'fyo'; 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 FormControl from 'src/components/Controls/FormControl.vue';
import DropdownWithActions from 'src/components/DropdownWithActions'; import DropdownWithActions from 'src/components/DropdownWithActions.vue';
import StatusBadge from 'src/components/StatusBadge'; import StatusBadge from 'src/components/StatusBadge.vue';
import TwoColumnForm from 'src/components/TwoColumnForm'; import TwoColumnForm from 'src/components/TwoColumnForm.vue';
import { fyo } from 'src/initFyo'; 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 { export default {
name: 'QuickEditForm', name: 'QuickEditForm',
props: ['doctype', 'name', 'valueJSON', 'hideFields', 'showFields'], props: {
name: String,
schemaName: String,
defaults: String,
hideFields: { type: Array, default: () => [] },
showFields: { type: Array, default: () => [] },
},
components: { components: {
Button, Button,
FormControl, FormControl,
@ -99,7 +105,7 @@ export default {
provide() { provide() {
let vm = this; let vm = this;
return { return {
doctype: this.doctype, schemaName: this.schemaName,
name: this.name, name: this.name,
get doc() { get doc() {
return vm.doc; return vm.doc;
@ -107,11 +113,13 @@ export default {
}; };
}, },
mounted() { mounted() {
if (!this.valueJSON) { if (this.defaults) {
return; this.values = JSON.parse(this.defaults);
} }
this.values = JSON.parse(this.valueJSON); if (fyo.store.isDevelopment) {
window.qef = this;
}
}, },
data() { data() {
return { return {
@ -123,59 +131,64 @@ export default {
}; };
}, },
async created() { async created() {
await this.fetchMetaAndDoc(); await this.fetchFieldsAndDoc();
}, },
computed: { computed: {
meta() { schema() {
return fyo.getMeta(this.doctype); return fyo.schemaMap[this.schemaName] ?? null;
}, },
status() { status() {
if (this.doc && this.doc._notInserted) { if (this.doc && this.doc.notInserted) {
return 'Draft'; return 'Draft';
} }
return ''; return '';
}, },
fields() { fields() {
const fields = this.meta if (!this.schema) {
.getQuickEditFields() return [];
.filter((df) => !(this.hideFields || []).includes(df.fieldname)); }
if (this.showFields) { const fieldnames = (this.schema.quickEditFields ?? ['name']).filter(
fields.push( (f) => !this.hideFields.includes(f)
...this.meta.fields.filter(({ fieldname }) => );
this.showFields.includes(fieldname)
) 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() { actions() {
return getActionsForDocument(this.doc); return getActionsForDocument(this.doc);
}, },
quickEditWidget() { quickEditWidget() {
if (!this.meta.quickEditWidget) { const widget = getQuickEditWidget(this.schemaName);
if (widget === null) {
return null; return null;
} }
return this.meta.quickEditWidget(this.doc);
return widget(this.doc);
}, },
}, },
methods: { methods: {
async fetchMetaAndDoc() { async fetchFieldsAndDoc() {
this.titleField = this.meta.getField(this.meta.titleField); if (!this.schema) {
this.imageField = this.meta.getField('image'); return;
}
const titleField = this.schema.titleField;
this.titleField = fyo.getField(this.schemaName, titleField);
this.imageField = fyo.getField(this.schemaName, 'image');
await this.fetchDoc(); await this.fetchDoc();
// setup the title field // setup the title field
if (this.doc && this.doc.notInserted && this.doc[this.titleField.fieldname]) { this.setTitleField();
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);
}
}
// set default values // set default values
if (this.values) { if (this.values) {
@ -185,13 +198,30 @@ export default {
// set title size // set title size
this.setTitleSize(); 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() { async fetchDoc() {
try { 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', () => { this.doc.once('afterRename', () => {
openQuickEdit({ openQuickEdit({
doctype: this.doctype, schemaName: this.schemaName,
name: this.doc.name, name: this.doc.name,
}); });
}); });
@ -225,15 +255,19 @@ export default {
this.$router.back(); this.$router.back();
}, },
setTitleSize() { setTitleSize() {
if (this.$refs.titleControl) { if (!this.$refs.titleControl) {
let input = this.$refs.titleControl.getInput(); return;
let value = input.value;
let valueLength = (value || '').length + 1;
if (valueLength < 7) {
valueLength = 7;
}
input.size = valueLength;
} }
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 { NounEnum, Verb } from 'fyo/telemetry/types';
import ChartOfAccounts from 'src/pages/ChartOfAccounts.vue';
import Dashboard from 'src/pages/Dashboard/Dashboard.vue'; import Dashboard from 'src/pages/Dashboard/Dashboard.vue';
import GetStarted from 'src/pages/GetStarted.vue'; import GetStarted from 'src/pages/GetStarted.vue';
// import ChartOfAccounts from 'src/pages/ChartOfAccounts.vue';
// import DataImport from 'src/pages/DataImport.vue'; // import DataImport from 'src/pages/DataImport.vue';
// import InvoiceForm from 'src/pages/InvoiceForm.vue'; // import InvoiceForm from 'src/pages/InvoiceForm.vue';
// import JournalEntryForm from 'src/pages/JournalEntryForm.vue'; // import JournalEntryForm from 'src/pages/JournalEntryForm.vue';
@ -77,7 +77,9 @@ const routes: RouteRecordRaw[] = [
filters, filters,
}; };
}, },
edit: (route) => route.query, edit: (route) => {
return route.query;
},
}, },
}, },
/* /*
@ -93,6 +95,7 @@ const routes: RouteRecordRaw[] = [
component: Report, component: Report,
props: true, props: true,
}, },
*/
{ {
path: '/chart-of-accounts', path: '/chart-of-accounts',
name: 'Chart Of Accounts', name: 'Chart Of Accounts',
@ -105,6 +108,7 @@ const routes: RouteRecordRaw[] = [
edit: (route) => route.query, edit: (route) => route.query,
}, },
}, },
/*
{ {
path: '/data_import', path: '/data_import',
name: '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({ export async function openQuickEdit({
schemaName, schemaName,
name, name,
hideFields, hideFields = [],
showFields, showFields = [],
defaults = {}, defaults = {},
}: QuickEditOptions) { }: QuickEditOptions) {
const currentRoute = router.currentRoute.value; const currentRoute = router.currentRoute.value;
const query = currentRoute.query; const query = currentRoute.query;
let method: 'push' | 'replace' = 'push'; let method: 'push' | 'replace' = 'push';
if (query.edit && query.doctype === schemaName) { if (query.edit && query.schemaName === schemaName) {
// replace the current route if we are
// editing another document of the same doctype
method = 'replace'; method = 'replace';
} }
if (query.name === name) return;
if (query.name === name) {
return;
}
const forWhat = (defaults?.for ?? []) as string[]; const forWhat = (defaults?.for ?? []) as string[];
if (forWhat[0] === 'not in') { if (forWhat[0] === 'not in') {
@ -60,24 +61,18 @@ export async function openQuickEdit({
router[method]({ router[method]({
query: { query: {
edit: 1, edit: 1,
doctype: schemaName, schemaName,
name, name,
showFields: showFields ?? getShowFields(schemaName), showFields,
hideFields, hideFields,
valueJSON: stringifyCircular(defaults), defaults: stringifyCircular(defaults),
// @ts-ignore /*
lastRoute: currentRoute, lastRoute: currentRoute,
*/
}, },
}); });
} }
function getShowFields(schemaName: string) {
if (schemaName === 'Party') {
return ['customer'];
}
return [];
}
export async function showMessageDialog({ export async function showMessageDialog({
message, message,
detail, detail,