mirror of
https://github.com/frappe/books.git
synced 2025-01-03 15:17:30 +00:00
incr: grouped action dropdowns
This commit is contained in:
parent
332bf93a1e
commit
1f259524b9
@ -64,6 +64,8 @@ export interface Action {
|
||||
label: string;
|
||||
action: (doc: Doc, router: Router) => Promise<void> | void;
|
||||
condition?: (doc: Doc) => boolean;
|
||||
group?: string;
|
||||
type?: 'primary' | 'secondary';
|
||||
component?: {
|
||||
template?: string;
|
||||
};
|
||||
|
@ -26,7 +26,8 @@ export function getInvoiceActions(fyo: Fyo): Action[] {
|
||||
|
||||
export function getMakeStockTransferAction(fyo: Fyo): Action {
|
||||
return {
|
||||
label: fyo.t`Make Stock Transfer`,
|
||||
label: fyo.t`Stock Transfer`,
|
||||
group: fyo.t`Create`,
|
||||
condition: (doc: Doc) => doc.isSubmitted && !!doc.stockNotTransferred,
|
||||
action: async (doc: Doc) => {
|
||||
const transfer = await (doc as Invoice).getStockTransfer();
|
||||
@ -43,7 +44,8 @@ export function getMakeStockTransferAction(fyo: Fyo): Action {
|
||||
|
||||
export function getMakePaymentAction(fyo: Fyo): Action {
|
||||
return {
|
||||
label: fyo.t`Make Payment`,
|
||||
label: fyo.t`Payment`,
|
||||
group: fyo.t`Create`,
|
||||
condition: (doc: Doc) =>
|
||||
doc.isSubmitted && !(doc.outstandingAmount as Money).isZero(),
|
||||
action: async (doc: Doc) => {
|
||||
@ -79,6 +81,7 @@ export function getLedgerLinkAction(
|
||||
|
||||
return {
|
||||
label,
|
||||
group: fyo.t`View`,
|
||||
condition: (doc: Doc) => doc.isSubmitted,
|
||||
action: async (doc: Doc, router: Router) => {
|
||||
router.push({
|
||||
|
@ -3,7 +3,17 @@
|
||||
<!-- Page Header (Title, Buttons, etc) -->
|
||||
<template #header v-if="doc">
|
||||
<StatusBadge :status="status" />
|
||||
<DropdownWithActions :actions="actions()" />
|
||||
<DropdownWithActions
|
||||
v-for="group of groupedActions()"
|
||||
:key="group.label"
|
||||
:type="group.type"
|
||||
:actions="group.actions"
|
||||
>
|
||||
<p v-if="group.group">
|
||||
{{ group.group }}
|
||||
</p>
|
||||
<feather-icon v-else name="more-horizontal" class="w-4 h-4" />
|
||||
</DropdownWithActions>
|
||||
<Button
|
||||
v-if="doc?.notInserted || doc?.dirty"
|
||||
type="primary"
|
||||
@ -154,6 +164,7 @@ import { docsPathMap } from 'src/utils/misc';
|
||||
import {
|
||||
docsPath,
|
||||
getActionsForDocument,
|
||||
getGroupedActionsForDocument,
|
||||
routeTo,
|
||||
showMessageDialog,
|
||||
} from 'src/utils/ui';
|
||||
@ -237,8 +248,8 @@ export default {
|
||||
this.quickEditDoc = doc;
|
||||
this.quickEditFields = fields;
|
||||
},
|
||||
actions() {
|
||||
return getActionsForDocument(this.doc);
|
||||
groupedActions() {
|
||||
return getGroupedActionsForDocument(this.doc);
|
||||
},
|
||||
getField(fieldname) {
|
||||
return fyo.getField(this.schemaName, fieldname);
|
||||
|
@ -27,7 +27,17 @@
|
||||
>
|
||||
<feather-icon name="settings" class="w-4 h-4" />
|
||||
</Button>
|
||||
<DropdownWithActions :actions="actions()" />
|
||||
<DropdownWithActions
|
||||
v-for="group of groupedActions()"
|
||||
:key="group.label"
|
||||
:type="group.type"
|
||||
:actions="group.actions"
|
||||
>
|
||||
<p v-if="group.group">
|
||||
{{ group.group }}
|
||||
</p>
|
||||
<feather-icon v-else name="more-horizontal" class="w-4 h-4" />
|
||||
</DropdownWithActions>
|
||||
<Button
|
||||
v-if="doc?.notInserted || doc?.dirty"
|
||||
type="primary"
|
||||
@ -290,7 +300,7 @@ import { fyo } from 'src/initFyo';
|
||||
import { docsPathMap } from 'src/utils/misc';
|
||||
import {
|
||||
docsPath,
|
||||
getActionsForDocument,
|
||||
getGroupedActionsForDocument,
|
||||
routeTo,
|
||||
showMessageDialog,
|
||||
} from 'src/utils/ui';
|
||||
@ -436,8 +446,8 @@ export default {
|
||||
|
||||
this.quickEditFields = fields;
|
||||
},
|
||||
actions() {
|
||||
return getActionsForDocument(this.doc);
|
||||
groupedActions() {
|
||||
return getGroupedActionsForDocument(this.doc);
|
||||
},
|
||||
getField(fieldname) {
|
||||
return fyo.getField(this.schemaName, fieldname);
|
||||
|
@ -3,7 +3,17 @@
|
||||
<!-- Page Header (Title, Buttons, etc) -->
|
||||
<template #header v-if="doc">
|
||||
<StatusBadge :status="status" />
|
||||
<DropdownWithActions :actions="actions" />
|
||||
<DropdownWithActions
|
||||
v-for="group of groupedActions()"
|
||||
:key="group.label"
|
||||
:type="group.type"
|
||||
:actions="group.actions"
|
||||
>
|
||||
<p v-if="group.group">
|
||||
{{ group.group }}
|
||||
</p>
|
||||
<feather-icon v-else name="more-horizontal" class="w-4 h-4" />
|
||||
</DropdownWithActions>
|
||||
<Button
|
||||
v-if="doc?.notInserted || doc?.dirty"
|
||||
type="primary"
|
||||
@ -141,8 +151,9 @@ import { docsPathMap } from 'src/utils/misc';
|
||||
import {
|
||||
docsPath,
|
||||
getActionsForDocument,
|
||||
getGroupedActionsForDocument,
|
||||
routeTo,
|
||||
showMessageDialog
|
||||
showMessageDialog,
|
||||
} from 'src/utils/ui';
|
||||
import { handleErrorWithDialog } from '../errorHandling';
|
||||
|
||||
@ -156,7 +167,7 @@ export default {
|
||||
FormControl,
|
||||
Table,
|
||||
FormContainer,
|
||||
FormHeader
|
||||
FormHeader,
|
||||
},
|
||||
provide() {
|
||||
return {
|
||||
@ -211,14 +222,14 @@ export default {
|
||||
}
|
||||
return fyo.format(value, 'Currency');
|
||||
},
|
||||
actions() {
|
||||
return getActionsForDocument(this.doc);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getField(fieldname) {
|
||||
return fyo.getField(ModelNameEnum.JournalEntry, fieldname);
|
||||
},
|
||||
groupedActions() {
|
||||
return getGroupedActionsForDocument(this.doc);
|
||||
},
|
||||
async sync() {
|
||||
try {
|
||||
await this.doc.sync();
|
||||
|
@ -271,6 +271,7 @@ export function getActionsForDocument(doc?: Doc): Action[] {
|
||||
.filter((d) => d.condition?.(doc) ?? true)
|
||||
.map((d) => {
|
||||
return {
|
||||
group: d.group,
|
||||
label: d.label,
|
||||
component: d.component,
|
||||
action: d.action,
|
||||
@ -278,6 +279,39 @@ export function getActionsForDocument(doc?: Doc): Action[] {
|
||||
});
|
||||
}
|
||||
|
||||
export function getGroupedActionsForDocument(doc?: Doc) {
|
||||
type Group = {
|
||||
group: string;
|
||||
label: string;
|
||||
type: string;
|
||||
actions: Action[];
|
||||
};
|
||||
|
||||
const actions = getActionsForDocument(doc);
|
||||
const actionsMap = actions.reduce((acc, ac) => {
|
||||
if (!ac.group) {
|
||||
ac.group = '';
|
||||
}
|
||||
|
||||
acc[ac.group] ??= {
|
||||
group: ac.group,
|
||||
label: ac.label ?? '',
|
||||
type: ac.type ?? 'secondary',
|
||||
actions: [],
|
||||
};
|
||||
|
||||
acc[ac.group].actions.push(ac);
|
||||
return acc;
|
||||
}, {} as Record<string, Group>);
|
||||
|
||||
const grouped = Object.keys(actionsMap)
|
||||
.filter(Boolean)
|
||||
.sort()
|
||||
.map((k) => actionsMap[k]);
|
||||
|
||||
return [grouped, actionsMap['']].flat();
|
||||
}
|
||||
|
||||
function getCancelAction(doc: Doc): Action {
|
||||
return {
|
||||
label: t`Cancel`,
|
||||
@ -329,6 +363,7 @@ function getDuplicateAction(doc: Doc): Action {
|
||||
const isSubmittable = !!doc.schema.isSubmittable;
|
||||
return {
|
||||
label: t`Duplicate`,
|
||||
group: t`Create`,
|
||||
condition: (doc: Doc) =>
|
||||
!!(
|
||||
((isSubmittable && doc.submitted) || !isSubmittable) &&
|
||||
|
Loading…
Reference in New Issue
Block a user