From 6e16a13e9cac23352ddad6ccc5bf5af4fbe3902a Mon Sep 17 00:00:00 2001 From: Mildred Ki'Lya Date: Wed, 20 Nov 2024 17:02:43 +0100 Subject: [PATCH] feat: allow to create custom list views --- .../baseModels/SidebarEntry/SidebarEntry.ts | 22 +++++ models/index.ts | 2 + models/types.ts | 1 + schemas/app/SidebarEntry.json | 46 +++++++++++ schemas/schemas.ts | 2 + src/components/Sidebar.vue | 12 +++ src/pages/ListView/ListView.vue | 22 +++++ src/utils/sidebarConfig.ts | 82 ++++++++++++++++++- 8 files changed, 187 insertions(+), 2 deletions(-) create mode 100644 models/baseModels/SidebarEntry/SidebarEntry.ts create mode 100644 schemas/app/SidebarEntry.json diff --git a/models/baseModels/SidebarEntry/SidebarEntry.ts b/models/baseModels/SidebarEntry/SidebarEntry.ts new file mode 100644 index 000000000..f1d52ed2c --- /dev/null +++ b/models/baseModels/SidebarEntry/SidebarEntry.ts @@ -0,0 +1,22 @@ +import { Doc } from 'fyo/model/doc'; +import type { QueryFilter } from 'utils/db/types'; + +export class SidebarEntry extends Doc { + section?: string; + route?: string; + model?: string; + filters?: string; + + fullRoute(): string { + switch (this.route) { + case '/list': + return `/list/${this.model!}/${this.name!}`; + default: + return this.route!; + } + } + + parsedFilters(): QueryFilter { + return JSON.parse(this.filters!) as QueryFilter; + } +} diff --git a/models/index.ts b/models/index.ts index ed4973b3e..ec91d1f44 100644 --- a/models/index.ts +++ b/models/index.ts @@ -30,6 +30,7 @@ import { SalesInvoiceItem } from './baseModels/SalesInvoiceItem/SalesInvoiceItem import { SalesQuote } from './baseModels/SalesQuote/SalesQuote'; import { SalesQuoteItem } from './baseModels/SalesQuoteItem/SalesQuoteItem'; import { SetupWizard } from './baseModels/SetupWizard/SetupWizard'; +import { SidebarEntry } from './baseModels/SidebarEntry/SidebarEntry'; import { Tax } from './baseModels/Tax/Tax'; import { TaxSummary } from './baseModels/TaxSummary/TaxSummary'; import { Batch } from './inventory/Batch'; @@ -83,6 +84,7 @@ export const models = { SalesQuoteItem, SerialNumber, SetupWizard, + SidebarEntry, PrintTemplate, Tax, TaxSummary, diff --git a/models/types.ts b/models/types.ts index 2420b8feb..5cf277ecd 100644 --- a/models/types.ts +++ b/models/types.ts @@ -23,6 +23,7 @@ export enum ModelNameEnum { LoyaltyPointEntry = 'LoyaltyPointEntry', CollectionRulesItems = 'CollectionRulesItems', CouponCode = 'CouponCode', + SidebarEntry = 'SidebarEntry', AppliedCouponCodes = 'AppliedCouponCodes', Payment = 'Payment', diff --git a/schemas/app/SidebarEntry.json b/schemas/app/SidebarEntry.json new file mode 100644 index 000000000..c828b0d94 --- /dev/null +++ b/schemas/app/SidebarEntry.json @@ -0,0 +1,46 @@ +{ + "name": "SidebarEntry", + "label": "Sidebar Entry", + "naming": "manual", + "fields": [ + { + "fieldname": "name", + "section": "Default", + "label": "Name", + "fieldtype": "Data", + "required": true, + "placeholder": "Entry Name" + }, + { + "fieldname": "section", + "section": "Default", + "label": "Section", + "fieldtype": "Data", + "required": false + }, + { + "fieldname": "route", + "section": "Default", + "label": "Route", + "fieldtype": "Data", + "required": true, + "default": "/list" + }, + { + "fieldname": "model", + "section": "Default", + "label": "Document Type", + "fieldtype": "Data", + "required": true, + "default": "JournalEntry" + }, + { + "fieldname": "filters", + "section": "Default", + "label": "Filters", + "fieldtype": "Data", + "required": true, + "default": "{}" + } + ] +} diff --git a/schemas/schemas.ts b/schemas/schemas.ts index f3d56c23c..8c8e83f8f 100644 --- a/schemas/schemas.ts +++ b/schemas/schemas.ts @@ -48,6 +48,7 @@ import PurchaseReceiptItem from './app/inventory/PurchaseReceiptItem.json'; import SerialNumber from './app/inventory/SerialNumber.json'; import Shipment from './app/inventory/Shipment.json'; import ShipmentItem from './app/inventory/ShipmentItem.json'; +import SidebarEntry from './app/SidebarEntry.json'; import StockLedgerEntry from './app/inventory/StockLedgerEntry.json'; import StockMovement from './app/inventory/StockMovement.json'; import StockMovementItem from './app/inventory/StockMovementItem.json'; @@ -92,6 +93,7 @@ export const appSchemas: Schema[] | SchemaStub[] = [ SetupWizard as Schema, GetStarted as Schema, PrintTemplate as Schema, + SidebarEntry as Schema, Color as Schema, Currency as Schema, diff --git a/src/components/Sidebar.vue b/src/components/Sidebar.vue index ed47d1ec1..76de284de 100644 --- a/src/components/Sidebar.vue +++ b/src/components/Sidebar.vue @@ -315,6 +315,15 @@ export default defineComponent({ }); this.shortcuts?.set(COMPONENT_NAME, ['F1'], () => this.openDocumentation()); + fyo.doc.observer.on( + 'sync:SidebarEntry', + async () => await this.refreshSidebar() + ); + fyo.doc.observer.on( + 'delete:SidebarEntry', + async () => await this.refreshSidebar() + ); + this.showDevMode = this.fyo.store.isDevelopment; }, unmounted() { @@ -324,6 +333,9 @@ export default defineComponent({ routeTo, reportIssue, toggleSidebar, + async refreshSidebar() { + this.groups = await getSidebarConfig(); + }, async toggleProvisionalMode() { let title, detail, provisionalModeSince, showUnlimited; if (fyo.singles.SystemSettings?.provisionalModeSince != null) { diff --git a/src/pages/ListView/ListView.vue b/src/pages/ListView/ListView.vue index 11ce00107..cd0e78128 100644 --- a/src/pages/ListView/ListView.vue +++ b/src/pages/ListView/ListView.vue @@ -1,6 +1,9 @@