shutro-erp 0.3.3 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/account_portal/.kosh/bindings.js +1 -1
- package/dist/account_portal/.kosh/schema.d.ts +181 -3
- package/dist/account_portal/module.d.ts +359 -6
- package/dist/accounting/.kosh/bindings.js +1 -1
- package/dist/accounting/.kosh/schema.d.ts +181 -3
- package/dist/accounting/index.js +214 -2
- package/dist/accounting/module.d.ts +217 -5
- package/dist/accounting/module.js +23 -2
- package/dist/calendar/.kosh/bindings.d.ts +22 -0
- package/dist/calendar/.kosh/bindings.js +15 -0
- package/dist/calendar/.kosh/schema.d.ts +795 -0
- package/dist/calendar/demo.d.ts +6 -0
- package/dist/calendar/demo.js +24 -0
- package/dist/calendar/index.d.ts +3 -0
- package/dist/calendar/index.js +291 -0
- package/dist/calendar/module.d.ts +1705 -0
- package/dist/calendar/module.js +180 -0
- package/dist/cli/init.js +48 -0
- package/dist/cli/templates.d.ts +1 -1
- package/dist/cli/templates.js +137 -0
- package/dist/contacts/.kosh/bindings.js +1 -1
- package/dist/contacts/.kosh/schema.d.ts +205 -3
- package/dist/contacts/demo.js +30 -1
- package/dist/contacts/index.d.ts +1 -1
- package/dist/contacts/index.js +155 -9
- package/dist/contacts/module.d.ts +338 -2
- package/dist/contacts/module.js +82 -5
- package/dist/crm/.kosh/bindings.d.ts +22 -0
- package/dist/crm/.kosh/bindings.js +15 -0
- package/dist/crm/.kosh/schema.d.ts +799 -0
- package/dist/crm/demo.d.ts +6 -0
- package/dist/crm/demo.js +45 -0
- package/dist/crm/index.d.ts +3 -0
- package/dist/crm/index.js +361 -0
- package/dist/crm/module.d.ts +1843 -0
- package/dist/crm/module.js +207 -0
- package/dist/event/.kosh/bindings.d.ts +22 -0
- package/dist/event/.kosh/bindings.js +15 -0
- package/dist/event/.kosh/schema.d.ts +843 -0
- package/dist/event/demo.d.ts +6 -0
- package/dist/event/demo.js +65 -0
- package/dist/event/index.d.ts +14 -0
- package/dist/event/index.js +333 -0
- package/dist/event/mails.d.ts +15 -0
- package/dist/event/mails.js +112 -0
- package/dist/event/module.d.ts +2800 -0
- package/dist/event/module.js +323 -0
- package/dist/event/web/CheckInBox.d.ts +9 -0
- package/dist/event/web/CheckInBox.js +87 -0
- package/dist/event/web/index.d.ts +11 -0
- package/dist/event/web/index.js +16 -0
- package/dist/event/web/messages.d.ts +2 -0
- package/dist/event/web/messages.js +23 -0
- package/dist/event_account/.kosh/bindings.d.ts +22 -0
- package/dist/event_account/.kosh/bindings.js +15 -0
- package/dist/event_account/.kosh/schema.d.ts +1639 -0
- package/dist/event_account/index.d.ts +3 -0
- package/dist/event_account/index.js +28 -0
- package/dist/event_account/module.d.ts +6968 -0
- package/dist/event_account/module.js +90 -0
- package/dist/hr/.kosh/bindings.d.ts +22 -0
- package/dist/hr/.kosh/bindings.js +15 -0
- package/dist/hr/.kosh/schema.d.ts +878 -0
- package/dist/hr/demo.d.ts +6 -0
- package/dist/hr/demo.js +60 -0
- package/dist/hr/index.d.ts +3 -0
- package/dist/hr/index.js +483 -0
- package/dist/hr/module.d.ts +2611 -0
- package/dist/hr/module.js +350 -0
- package/dist/integrations/index.js +12 -0
- package/dist/integrations/web/OAuthAppsPage.d.ts +9 -0
- package/dist/integrations/web/OAuthAppsPage.js +79 -0
- package/dist/integrations/web/index.d.ts +1 -0
- package/dist/integrations/web/index.js +3 -0
- package/dist/integrations/web/messages.js +58 -0
- package/dist/l10n_bd/.kosh/bindings.js +1 -1
- package/dist/l10n_bd/.kosh/schema.d.ts +181 -3
- package/dist/l10n_bd/module.d.ts +359 -6
- package/dist/l10n_in/.kosh/bindings.js +1 -1
- package/dist/l10n_in/.kosh/schema.d.ts +181 -3
- package/dist/l10n_in/module.d.ts +380 -7
- package/dist/maintenance/.kosh/bindings.d.ts +22 -0
- package/dist/maintenance/.kosh/bindings.js +15 -0
- package/dist/maintenance/.kosh/schema.d.ts +911 -0
- package/dist/maintenance/demo.d.ts +6 -0
- package/dist/maintenance/demo.js +60 -0
- package/dist/maintenance/index.d.ts +3 -0
- package/dist/maintenance/index.js +422 -0
- package/dist/maintenance/module.d.ts +3545 -0
- package/dist/maintenance/module.js +446 -0
- package/dist/maintenance_stock/.kosh/bindings.d.ts +22 -0
- package/dist/maintenance_stock/.kosh/bindings.js +15 -0
- package/dist/maintenance_stock/.kosh/schema.d.ts +1371 -0
- package/dist/maintenance_stock/index.d.ts +9 -0
- package/dist/maintenance_stock/index.js +52 -0
- package/dist/maintenance_stock/module.d.ts +6953 -0
- package/dist/maintenance_stock/module.js +192 -0
- package/dist/messaging/web/index.js +1 -1
- package/dist/modules-sdk/index.d.ts +1 -1
- package/dist/modules-sdk/manifest.d.ts +70 -0
- package/dist/modules-sdk/manifest.js +35 -1
- package/dist/mrp/.kosh/bindings.d.ts +22 -0
- package/dist/mrp/.kosh/bindings.js +15 -0
- package/dist/mrp/.kosh/schema.d.ts +1378 -0
- package/dist/mrp/demo.d.ts +7 -0
- package/dist/mrp/demo.js +42 -0
- package/dist/mrp/index.d.ts +3 -0
- package/dist/mrp/index.js +392 -0
- package/dist/mrp/module.d.ts +8608 -0
- package/dist/mrp/module.js +695 -0
- package/dist/mrp_account/.kosh/bindings.d.ts +22 -0
- package/dist/mrp_account/.kosh/bindings.js +15 -0
- package/dist/mrp_account/.kosh/schema.d.ts +2106 -0
- package/dist/mrp_account/index.d.ts +3 -0
- package/dist/mrp_account/index.js +22 -0
- package/dist/mrp_account/module.d.ts +20840 -0
- package/dist/mrp_account/module.js +123 -0
- package/dist/notify/web/index.js +1 -1
- package/dist/payment/.kosh/bindings.js +1 -1
- package/dist/payment/.kosh/schema.d.ts +181 -3
- package/dist/payment/module.d.ts +359 -6
- package/dist/portal/.kosh/bindings.js +1 -1
- package/dist/portal/.kosh/schema.d.ts +205 -3
- package/dist/portal/module.d.ts +166 -2
- package/dist/pos/.kosh/bindings.d.ts +22 -0
- package/dist/pos/.kosh/bindings.js +15 -0
- package/dist/pos/.kosh/schema.d.ts +1690 -0
- package/dist/pos/accounting.d.ts +10 -0
- package/dist/pos/accounting.js +149 -0
- package/dist/pos/demo.d.ts +6 -0
- package/dist/pos/demo.js +90 -0
- package/dist/pos/index.d.ts +9 -0
- package/dist/pos/index.js +349 -0
- package/dist/pos/module.d.ts +9636 -0
- package/dist/pos/module.js +423 -0
- package/dist/pos/routes.d.ts +39 -0
- package/dist/pos/routes.js +368 -0
- package/dist/pos/web/Register.d.ts +9 -0
- package/dist/pos/web/Register.js +252 -0
- package/dist/pos/web/index.d.ts +11 -0
- package/dist/pos/web/index.js +16 -0
- package/dist/pos/web/messages.d.ts +2 -0
- package/dist/pos/web/messages.js +87 -0
- package/dist/pos_stock/.kosh/bindings.d.ts +22 -0
- package/dist/pos_stock/.kosh/bindings.js +15 -0
- package/dist/pos_stock/.kosh/schema.d.ts +2015 -0
- package/dist/pos_stock/index.d.ts +9 -0
- package/dist/pos_stock/index.js +35 -0
- package/dist/pos_stock/module.d.ts +11935 -0
- package/dist/pos_stock/module.js +115 -0
- package/dist/product/.kosh/bindings.js +1 -1
- package/dist/product/.kosh/schema.d.ts +178 -1
- package/dist/product/index.js +81 -4
- package/dist/product/module.d.ts +43 -1
- package/dist/product/module.js +9 -2
- package/dist/project/.kosh/bindings.js +1 -1
- package/dist/project/.kosh/schema.d.ts +181 -3
- package/dist/project/index.js +147 -7
- package/dist/project/module.d.ts +210 -2
- package/dist/project/module.js +52 -5
- package/dist/project_portal/.kosh/bindings.js +1 -1
- package/dist/project_portal/.kosh/schema.d.ts +181 -3
- package/dist/project_portal/module.d.ts +353 -4
- package/dist/purchase/.kosh/bindings.js +1 -1
- package/dist/purchase/.kosh/schema.d.ts +181 -3
- package/dist/purchase/index.js +163 -3
- package/dist/purchase/module.d.ts +215 -3
- package/dist/purchase/module.js +21 -3
- package/dist/purchase_account/.kosh/bindings.js +1 -1
- package/dist/purchase_account/.kosh/schema.d.ts +182 -3
- package/dist/purchase_account/index.js +26 -1
- package/dist/purchase_account/module.d.ts +393 -7
- package/dist/purchase_portal/.kosh/bindings.js +1 -1
- package/dist/purchase_portal/.kosh/schema.d.ts +181 -3
- package/dist/purchase_portal/module.d.ts +366 -5
- package/dist/purchase_stock/.kosh/bindings.d.ts +22 -0
- package/dist/purchase_stock/.kosh/bindings.js +15 -0
- package/dist/purchase_stock/.kosh/schema.d.ts +1310 -0
- package/dist/purchase_stock/index.d.ts +7 -0
- package/dist/purchase_stock/index.js +91 -0
- package/dist/purchase_stock/module.d.ts +6763 -0
- package/dist/purchase_stock/module.js +144 -0
- package/dist/purchase_stock_account/.kosh/bindings.d.ts +22 -0
- package/dist/purchase_stock_account/.kosh/bindings.js +15 -0
- package/dist/purchase_stock_account/.kosh/schema.d.ts +1959 -0
- package/dist/purchase_stock_account/index.d.ts +3 -0
- package/dist/purchase_stock_account/index.js +24 -0
- package/dist/purchase_stock_account/module.d.ts +35366 -0
- package/dist/purchase_stock_account/module.js +162 -0
- package/dist/recruitment/.kosh/bindings.d.ts +22 -0
- package/dist/recruitment/.kosh/bindings.js +15 -0
- package/dist/recruitment/.kosh/schema.d.ts +990 -0
- package/dist/recruitment/demo.d.ts +6 -0
- package/dist/recruitment/demo.js +45 -0
- package/dist/recruitment/index.d.ts +3 -0
- package/dist/recruitment/index.js +385 -0
- package/dist/recruitment/module.d.ts +3247 -0
- package/dist/recruitment/module.js +193 -0
- package/dist/recruitment/web/HireButton.d.ts +9 -0
- package/dist/recruitment/web/HireButton.js +32 -0
- package/dist/recruitment/web/index.d.ts +11 -0
- package/dist/recruitment/web/index.js +16 -0
- package/dist/recruitment/web/messages.d.ts +2 -0
- package/dist/recruitment/web/messages.js +19 -0
- package/dist/reporting/documents.d.ts +5 -0
- package/dist/reporting/documents.js +28 -1
- package/dist/reporting/index.d.ts +1 -1
- package/dist/reporting/index.js +4 -2
- package/dist/reporting/models.js +9 -0
- package/dist/reporting/overviews.d.ts +16 -0
- package/dist/reporting/overviews.js +56 -0
- package/dist/reporting/routes-documents.js +1 -1
- package/dist/reporting/routes.js +138 -80
- package/dist/reporting/web/DashboardView.d.ts +11 -0
- package/dist/reporting/web/DashboardView.js +2 -2
- package/dist/reporting/web/DesignerView.js +5 -0
- package/dist/reporting/web/Overview.d.ts +9 -0
- package/dist/reporting/web/Overview.js +53 -0
- package/dist/reporting/web/index.d.ts +1 -0
- package/dist/reporting/web/index.js +4 -1
- package/dist/reporting/web/messages.js +9 -0
- package/dist/sale_account/.kosh/bindings.js +1 -1
- package/dist/sale_account/.kosh/schema.d.ts +186 -3
- package/dist/sale_account/index.js +22 -1
- package/dist/sale_account/module.d.ts +461 -7
- package/dist/sale_portal/.kosh/bindings.js +1 -1
- package/dist/sale_portal/.kosh/schema.d.ts +185 -3
- package/dist/sale_portal/module.d.ts +434 -5
- package/dist/sale_project/.kosh/bindings.js +1 -1
- package/dist/sale_project/.kosh/schema.d.ts +187 -3
- package/dist/sale_project/module.d.ts +476 -6
- package/dist/sale_stock/.kosh/bindings.d.ts +22 -0
- package/dist/sale_stock/.kosh/bindings.js +15 -0
- package/dist/sale_stock/.kosh/schema.d.ts +1228 -0
- package/dist/sale_stock/index.d.ts +7 -0
- package/dist/sale_stock/index.js +84 -0
- package/dist/sale_stock/module.d.ts +6791 -0
- package/dist/sale_stock/module.js +146 -0
- package/dist/sales/.kosh/bindings.js +1 -1
- package/dist/sales/.kosh/schema.d.ts +185 -3
- package/dist/sales/index.js +191 -4
- package/dist/sales/module.d.ts +355 -3
- package/dist/sales/module.js +78 -3
- package/dist/server/api/metadata.d.ts +5 -0
- package/dist/server/api/metadata.js +5 -0
- package/dist/server/api/rest.js +64 -1
- package/dist/server/api/views.js +1 -0
- package/dist/server/app-settings.d.ts +7 -0
- package/dist/server/app-settings.js +10 -0
- package/dist/server/auth/base.js +85 -0
- package/dist/server/auth/oauth.d.ts +21 -0
- package/dist/server/auth/oauth.js +579 -0
- package/dist/server/auth/service.d.ts +4 -0
- package/dist/server/auth/service.js +17 -0
- package/dist/server/identity.d.ts +2 -0
- package/dist/server/images.d.ts +12 -0
- package/dist/server/images.js +139 -0
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.js +2 -0
- package/dist/server/server.d.ts +4 -0
- package/dist/server/server.js +9 -1
- package/dist/settings/app-settings.d.ts +2 -0
- package/dist/settings/app-settings.js +518 -0
- package/dist/settings/company.js +3 -1
- package/dist/settings/index.d.ts +1 -0
- package/dist/settings/index.js +15 -0
- package/dist/settings/people.js +32 -6
- package/dist/settings/web/AppSettingsPage.d.ts +11 -0
- package/dist/settings/web/AppSettingsPage.js +210 -0
- package/dist/settings/web/CompaniesPage.js +2 -2
- package/dist/settings/web/CompanyPage.js +13 -2
- package/dist/settings/web/ConnectedAppsPage.d.ts +7 -0
- package/dist/settings/web/ConnectedAppsPage.js +33 -0
- package/dist/settings/web/OverviewPage.js +28 -4
- package/dist/settings/web/PeoplePage.js +23 -18
- package/dist/settings/web/ProfilePage.js +9 -7
- package/dist/settings/web/index.d.ts +2 -0
- package/dist/settings/web/index.js +8 -0
- package/dist/settings/web/messages.js +146 -2
- package/dist/stock/.kosh/bindings.d.ts +22 -0
- package/dist/stock/.kosh/bindings.js +15 -0
- package/dist/stock/.kosh/schema.d.ts +1147 -0
- package/dist/stock/demo.d.ts +7 -0
- package/dist/stock/demo.js +55 -0
- package/dist/stock/index.d.ts +3 -0
- package/dist/stock/index.js +674 -0
- package/dist/stock/module.d.ts +6330 -0
- package/dist/stock/module.js +1325 -0
- package/dist/stock/web/ScanBox.d.ts +8 -0
- package/dist/stock/web/ScanBox.js +90 -0
- package/dist/stock/web/index.d.ts +11 -0
- package/dist/stock/web/index.js +16 -0
- package/dist/stock/web/messages.d.ts +2 -0
- package/dist/stock/web/messages.js +25 -0
- package/dist/stock_account/.kosh/bindings.d.ts +22 -0
- package/dist/stock_account/.kosh/bindings.js +15 -0
- package/dist/stock_account/.kosh/schema.d.ts +1875 -0
- package/dist/stock_account/index.d.ts +3 -0
- package/dist/stock_account/index.js +130 -0
- package/dist/stock_account/module.d.ts +10655 -0
- package/dist/stock_account/module.js +339 -0
- package/dist/storage/attachments.d.ts +5 -0
- package/dist/storage/attachments.js +12 -1
- package/dist/storage/models.js +3 -0
- package/dist/storage/routes.js +13 -2
- package/dist/todo/.kosh/bindings.d.ts +22 -0
- package/dist/todo/.kosh/bindings.js +15 -0
- package/dist/todo/.kosh/schema.d.ts +732 -0
- package/dist/todo/demo.d.ts +6 -0
- package/dist/todo/demo.js +35 -0
- package/dist/todo/index.d.ts +3 -0
- package/dist/todo/index.js +187 -0
- package/dist/todo/module.d.ts +1180 -0
- package/dist/todo/module.js +130 -0
- package/dist/trade_finance/.kosh/bindings.d.ts +22 -0
- package/dist/trade_finance/.kosh/bindings.js +15 -0
- package/dist/trade_finance/.kosh/schema.d.ts +884 -0
- package/dist/trade_finance/demo.d.ts +6 -0
- package/dist/trade_finance/demo.js +63 -0
- package/dist/trade_finance/index.d.ts +3 -0
- package/dist/trade_finance/index.js +413 -0
- package/dist/trade_finance/module.d.ts +3779 -0
- package/dist/trade_finance/module.js +505 -0
- package/dist/trade_finance_account/.kosh/bindings.d.ts +22 -0
- package/dist/trade_finance_account/.kosh/bindings.js +15 -0
- package/dist/trade_finance_account/.kosh/schema.d.ts +1711 -0
- package/dist/trade_finance_account/index.d.ts +3 -0
- package/dist/trade_finance_account/index.js +92 -0
- package/dist/trade_finance_account/module.d.ts +7928 -0
- package/dist/trade_finance_account/module.js +244 -0
- package/dist/trade_finance_purchase/.kosh/bindings.d.ts +22 -0
- package/dist/trade_finance_purchase/.kosh/bindings.js +15 -0
- package/dist/trade_finance_purchase/.kosh/schema.d.ts +1153 -0
- package/dist/trade_finance_purchase/index.d.ts +8 -0
- package/dist/trade_finance_purchase/index.js +50 -0
- package/dist/trade_finance_purchase/module.d.ts +4252 -0
- package/dist/trade_finance_purchase/module.js +44 -0
- package/dist/trade_finance_sale/.kosh/bindings.d.ts +22 -0
- package/dist/trade_finance_sale/.kosh/bindings.js +15 -0
- package/dist/trade_finance_sale/.kosh/schema.d.ts +1071 -0
- package/dist/trade_finance_sale/index.d.ts +8 -0
- package/dist/trade_finance_sale/index.js +50 -0
- package/dist/trade_finance_sale/module.d.ts +4280 -0
- package/dist/trade_finance_sale/module.js +44 -0
- package/dist/ui/api.d.ts +6 -1
- package/dist/ui/api.js +2 -1
- package/dist/ui/app.js +51 -17
- package/dist/ui/components/AppIcon.js +33 -1
- package/dist/ui/components/Avatar.d.ts +21 -0
- package/dist/ui/components/Avatar.js +71 -0
- package/dist/ui/components/primitives.d.ts +2 -0
- package/dist/ui/components/primitives.js +7 -1
- package/dist/ui/i18n/messages.d.ts +53 -0
- package/dist/ui/i18n/messages.js +98 -0
- package/dist/ui/index.d.ts +2 -0
- package/dist/ui/index.js +2 -0
- package/dist/ui/offline/queue.d.ts +5 -1
- package/dist/ui/offline/queue.js +2 -0
- package/dist/ui/registry.d.ts +12 -1
- package/dist/ui/registry.js +10 -1
- package/dist/ui/search/ViewTabs.d.ts +14 -0
- package/dist/ui/search/ViewTabs.js +42 -0
- package/dist/ui/shell/Consent.d.ts +5 -0
- package/dist/ui/shell/Consent.js +35 -0
- package/dist/ui/shell/Home.js +136 -16
- package/dist/ui/shell/Sidebar.js +15 -22
- package/dist/ui/views/FormView.js +98 -17
- package/dist/ui/views/KanbanView.d.ts +2 -0
- package/dist/ui/views/KanbanView.js +32 -3
- package/dist/ui/views/ListView.js +155 -31
- package/dist/ui/views/StatsRow.d.ts +14 -0
- package/dist/ui/views/StatsRow.js +88 -0
- package/dist/ui/views/widgets.d.ts +2 -1
- package/dist/ui/views/widgets.js +194 -1
- package/dist/views/builders.d.ts +19 -2
- package/dist/views/builders.js +21 -1
- package/dist/views/condition.d.ts +6 -0
- package/dist/views/condition.js +20 -0
- package/dist/views/documents.d.ts +8 -0
- package/dist/views/extend.d.ts +2 -2
- package/dist/views/extend.js +11 -1
- package/dist/views/index.d.ts +2 -2
- package/dist/views/index.js +2 -2
- package/dist/views/types.d.ts +52 -5
- package/dist/views/validate.js +39 -1
- package/dist/website/.kosh/bindings.d.ts +22 -0
- package/dist/website/.kosh/bindings.js +15 -0
- package/dist/website/.kosh/schema.d.ts +881 -0
- package/dist/website/demo.d.ts +6 -0
- package/dist/website/demo.js +115 -0
- package/dist/website/index.d.ts +9 -0
- package/dist/website/index.js +250 -0
- package/dist/website/module.d.ts +2987 -0
- package/dist/website/module.js +281 -0
- package/dist/website/render.d.ts +45 -0
- package/dist/website/render.js +102 -0
- package/dist/website/routes.d.ts +12 -0
- package/dist/website/routes.js +246 -0
- package/dist/website/web/PagePreview.d.ts +7 -0
- package/dist/website/web/PagePreview.js +33 -0
- package/dist/website/web/index.d.ts +11 -0
- package/dist/website/web/index.js +16 -0
- package/dist/website/web/messages.d.ts +2 -0
- package/dist/website/web/messages.js +15 -0
- package/dist/website_crm/.kosh/bindings.d.ts +22 -0
- package/dist/website_crm/.kosh/bindings.js +15 -0
- package/dist/website_crm/.kosh/schema.d.ts +966 -0
- package/dist/website_crm/index.d.ts +3 -0
- package/dist/website_crm/index.js +39 -0
- package/dist/website_crm/module.d.ts +2955 -0
- package/dist/website_crm/module.js +44 -0
- package/package.json +118 -1
package/dist/reporting/routes.js
CHANGED
|
@@ -6,9 +6,11 @@
|
|
|
6
6
|
* - `POST /api/v1/models/:model/export/xlsx` a list as a formatted XLSX (needs `export`; audited)
|
|
7
7
|
*/
|
|
8
8
|
import { audit, HttpProblem, publicApiModels, } from '../server/index.js';
|
|
9
|
+
import { renderPdf } from './documents.js';
|
|
9
10
|
import { ReportError, runReport, } from './pivot.js';
|
|
10
11
|
import { moneyFormat, workbook } from './xlsx.js';
|
|
11
12
|
const LIST_XLSX_LIMIT = 100_000;
|
|
13
|
+
const LIST_PDF_LIMIT = 2000;
|
|
12
14
|
const search = (env, model, query) => env.model(model).search(query);
|
|
13
15
|
function bad(detail) {
|
|
14
16
|
return new HttpProblem(400, 'invalid-report', 'Invalid report', detail);
|
|
@@ -220,91 +222,34 @@ export function registerReportRoutes(context) {
|
|
|
220
222
|
const limit = raw['limit'] === undefined ? LIST_XLSX_LIMIT : Number(raw['limit']);
|
|
221
223
|
if (!Number.isInteger(limit) || limit < 1 || limit > LIST_XLSX_LIMIT)
|
|
222
224
|
throw bad(`limit must be 1–${LIST_XLSX_LIMIT}.`);
|
|
223
|
-
const sheet = await request.env(
|
|
224
|
-
env.access.check(model.name, 'export');
|
|
225
|
-
const fields = (keys.length > 0
|
|
226
|
-
? keys
|
|
227
|
-
: model.fields
|
|
228
|
-
.filter((f) => f.stored &&
|
|
229
|
-
f.kind !== 'binary' &&
|
|
230
|
-
f.kind !== 'one2many' &&
|
|
231
|
-
f.kind !== 'many2many')
|
|
232
|
-
.map((f) => f.key))
|
|
233
|
-
.map((k) => model.byKey.get(k))
|
|
234
|
-
.filter((f) => f !== undefined && env.access.canField(model.name, f.key, 'read'));
|
|
235
|
-
const found = await search(env, model.name, {
|
|
236
|
-
...(where === undefined ? {} : { where }),
|
|
237
|
-
order: ['id asc'],
|
|
238
|
-
limit,
|
|
239
|
-
});
|
|
240
|
-
const loaded = found.length === 0
|
|
241
|
-
? []
|
|
242
|
-
: (await found.load(['id', ...fields.map((f) => f?.key)])).read(fields.map((f) => f?.key));
|
|
243
|
-
// many2one columns show names, not ids.
|
|
244
|
-
const names = new Map();
|
|
245
|
-
for (const f of fields)
|
|
246
|
-
if (f?.kind === 'many2one' && f.target !== null) {
|
|
247
|
-
const ids = [
|
|
248
|
-
...new Set(loaded.map((r) => r[f.key]).filter((v) => typeof v === 'number')),
|
|
249
|
-
];
|
|
250
|
-
names.set(f.key, ids.length === 0 ? new Map() : await displayNames(env, f.target, ids));
|
|
251
|
-
}
|
|
252
|
-
await audit(env, {
|
|
253
|
-
kind: 'data.export',
|
|
254
|
-
summary: `Exported ${loaded.length} ${model.name} record(s) as xlsx.`,
|
|
255
|
-
targetModel: model.name,
|
|
256
|
-
details: { fields: fields.map((f) => f?.key), count: loaded.length, filter: where ?? null },
|
|
257
|
-
ip: request.ip,
|
|
258
|
-
});
|
|
259
|
-
const header = fields.map((f) => f?.label ?? '');
|
|
260
|
-
const body = loaded.map((r) => fields.map((f) => {
|
|
261
|
-
if (f === undefined)
|
|
262
|
-
return null;
|
|
263
|
-
const v = r[f.key];
|
|
264
|
-
if (v === null || v === undefined)
|
|
265
|
-
return null;
|
|
266
|
-
switch (f.kind) {
|
|
267
|
-
case 'many2one':
|
|
268
|
-
return names.get(f.key)?.get(v) ?? `#${String(v)}`;
|
|
269
|
-
case 'decimal':
|
|
270
|
-
case 'float':
|
|
271
|
-
return { decimal: String(v) };
|
|
272
|
-
case 'monetary': {
|
|
273
|
-
const m = (typeof v.toJSON === 'function'
|
|
274
|
-
? v.toJSON()
|
|
275
|
-
: v);
|
|
276
|
-
return {
|
|
277
|
-
decimal: String(m.amount ?? v),
|
|
278
|
-
format: moneyFormat(String(m.currency ?? '')),
|
|
279
|
-
};
|
|
280
|
-
}
|
|
281
|
-
case 'date':
|
|
282
|
-
return new Date(`${String(v).slice(0, 10)}T00:00:00Z`);
|
|
283
|
-
case 'datetime':
|
|
284
|
-
return v instanceof Date ? v : new Date(String(v));
|
|
285
|
-
case 'selection':
|
|
286
|
-
case 'state':
|
|
287
|
-
return f.options?.find(([value]) => value === v)?.[1] ?? String(v);
|
|
288
|
-
case 'boolean':
|
|
289
|
-
return v === true;
|
|
290
|
-
case 'integer':
|
|
291
|
-
case 'bigint':
|
|
292
|
-
return Number(v);
|
|
293
|
-
default:
|
|
294
|
-
return String(v);
|
|
295
|
-
}
|
|
296
|
-
}));
|
|
297
|
-
return {
|
|
298
|
-
name: model.label,
|
|
299
|
-
rows: [header, ...body],
|
|
300
|
-
widths: fields.map((f) => Math.min(48, Math.max(10, (f?.label.length ?? 10) + 4))),
|
|
301
|
-
};
|
|
302
|
-
});
|
|
225
|
+
const sheet = await request.env((env) => listSheet(env, model, keys, where, limit, request.ip, 'xlsx'));
|
|
303
226
|
await reply
|
|
304
227
|
.type('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
|
|
305
228
|
.header('content-disposition', `attachment; filename="${model.name}.xlsx"`)
|
|
306
229
|
.send(workbook([sheet]));
|
|
307
230
|
});
|
|
231
|
+
// RFC 0022 §3.5: a list printed as PDF — the columns shown, the filter, up to LIST_PDF_LIMIT rows.
|
|
232
|
+
app.post('/api/v1/models/:model/export/pdf', async (request, reply) => {
|
|
233
|
+
const model = modelOf(request.params);
|
|
234
|
+
const raw = bodyOf(request);
|
|
235
|
+
const keys = strings(raw['fields'], 'fields');
|
|
236
|
+
const where = raw['filter'];
|
|
237
|
+
const limit = raw['limit'] === undefined ? LIST_PDF_LIMIT : Number(raw['limit']);
|
|
238
|
+
if (!Number.isInteger(limit) || limit < 1 || limit > LIST_PDF_LIMIT)
|
|
239
|
+
throw bad(`limit must be 1–${LIST_PDF_LIMIT}.`);
|
|
240
|
+
const sheet = await request.env((env) => listSheet(env, model, keys, where, limit, request.ip, 'pdf'));
|
|
241
|
+
const lang = String(request.headers['accept-language'] ?? 'en').slice(0, 2);
|
|
242
|
+
const html = listHtml(sheet, { lang, dir: lang === 'ar' || lang === 'he' ? 'rtl' : 'ltr' });
|
|
243
|
+
const pdf = await renderPdf(html, {
|
|
244
|
+
paper: 'A4',
|
|
245
|
+
orientation: (sheet.rows[0]?.length ?? 0) > 6 ? 'landscape' : 'portrait',
|
|
246
|
+
blocks: [],
|
|
247
|
+
});
|
|
248
|
+
await reply
|
|
249
|
+
.type('application/pdf')
|
|
250
|
+
.header('content-disposition', `attachment; filename="${model.name}.pdf"`)
|
|
251
|
+
.send(pdf);
|
|
252
|
+
});
|
|
308
253
|
}
|
|
309
254
|
function csvCell(value) {
|
|
310
255
|
let t = value;
|
|
@@ -312,3 +257,116 @@ function csvCell(value) {
|
|
|
312
257
|
t = `'${t}`;
|
|
313
258
|
return /[",\r\n]/.test(t) ? `"${t.replaceAll('"', '""')}"` : t;
|
|
314
259
|
}
|
|
260
|
+
/** The rows of a list for an export: the columns the user may read, many2one names, typed cells; audited. */
|
|
261
|
+
async function listSheet(env, model, keys, where, limit, ip, format) {
|
|
262
|
+
env.access.check(model.name, 'export');
|
|
263
|
+
const fields = (keys.length > 0
|
|
264
|
+
? keys
|
|
265
|
+
: model.fields
|
|
266
|
+
.filter((f) => f.stored && f.kind !== 'binary' && f.kind !== 'one2many' && f.kind !== 'many2many')
|
|
267
|
+
.map((f) => f.key))
|
|
268
|
+
.map((k) => model.byKey.get(k))
|
|
269
|
+
.filter((f) => f !== undefined && env.access.canField(model.name, f.key, 'read'));
|
|
270
|
+
const found = await search(env, model.name, {
|
|
271
|
+
...(where === undefined ? {} : { where }),
|
|
272
|
+
order: ['id asc'],
|
|
273
|
+
limit,
|
|
274
|
+
});
|
|
275
|
+
const loaded = found.length === 0
|
|
276
|
+
? []
|
|
277
|
+
: (await found.load(['id', ...fields.map((f) => f?.key)])).read(fields.map((f) => f?.key));
|
|
278
|
+
// many2one columns show names, not ids.
|
|
279
|
+
const names = new Map();
|
|
280
|
+
for (const f of fields)
|
|
281
|
+
if (f?.kind === 'many2one' && f.target !== null) {
|
|
282
|
+
const ids = [
|
|
283
|
+
...new Set(loaded.map((r) => r[f.key]).filter((v) => typeof v === 'number')),
|
|
284
|
+
];
|
|
285
|
+
names.set(f.key, ids.length === 0 ? new Map() : await displayNames(env, f.target, ids));
|
|
286
|
+
}
|
|
287
|
+
await audit(env, {
|
|
288
|
+
kind: 'data.export',
|
|
289
|
+
summary: `Exported ${loaded.length} ${model.name} record(s) as ${format}.`,
|
|
290
|
+
targetModel: model.name,
|
|
291
|
+
details: { fields: fields.map((f) => f?.key), count: loaded.length, filter: where ?? null },
|
|
292
|
+
ip,
|
|
293
|
+
});
|
|
294
|
+
const header = fields.map((f) => f?.label ?? '');
|
|
295
|
+
const body = loaded.map((r) => fields.map((f) => {
|
|
296
|
+
if (f === undefined)
|
|
297
|
+
return null;
|
|
298
|
+
const v = r[f.key];
|
|
299
|
+
if (v === null || v === undefined)
|
|
300
|
+
return null;
|
|
301
|
+
switch (f.kind) {
|
|
302
|
+
case 'many2one':
|
|
303
|
+
return names.get(f.key)?.get(v) ?? `#${String(v)}`;
|
|
304
|
+
case 'decimal':
|
|
305
|
+
case 'float':
|
|
306
|
+
return { decimal: String(v) };
|
|
307
|
+
case 'monetary': {
|
|
308
|
+
const m = (typeof v.toJSON === 'function'
|
|
309
|
+
? v.toJSON()
|
|
310
|
+
: v);
|
|
311
|
+
return {
|
|
312
|
+
decimal: String(m.amount ?? v),
|
|
313
|
+
format: moneyFormat(String(m.currency ?? '')),
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
case 'date':
|
|
317
|
+
return new Date(`${String(v).slice(0, 10)}T00:00:00Z`);
|
|
318
|
+
case 'datetime':
|
|
319
|
+
return v instanceof Date ? v : new Date(String(v));
|
|
320
|
+
case 'selection':
|
|
321
|
+
case 'state':
|
|
322
|
+
return f.options?.find(([value]) => value === v)?.[1] ?? String(v);
|
|
323
|
+
case 'boolean':
|
|
324
|
+
return v === true;
|
|
325
|
+
case 'integer':
|
|
326
|
+
case 'bigint':
|
|
327
|
+
return Number(v);
|
|
328
|
+
default:
|
|
329
|
+
return String(v);
|
|
330
|
+
}
|
|
331
|
+
}));
|
|
332
|
+
return {
|
|
333
|
+
name: model.label,
|
|
334
|
+
rows: [header, ...body],
|
|
335
|
+
widths: fields.map((f) => Math.min(48, Math.max(10, (f?.label.length ?? 10) + 4))),
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
const escapeHtml = (text) => text.replace(/[&<>"']/g, (c) => ({ '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' })[c] ?? c);
|
|
339
|
+
/** A cell as text on paper. */
|
|
340
|
+
function cellText(cell) {
|
|
341
|
+
if (cell === null)
|
|
342
|
+
return '';
|
|
343
|
+
if (cell instanceof Date)
|
|
344
|
+
return cell.toISOString().slice(0, 10);
|
|
345
|
+
if (typeof cell === 'boolean')
|
|
346
|
+
return cell ? '✓' : '';
|
|
347
|
+
if (typeof cell === 'object')
|
|
348
|
+
return 'decimal' in cell ? cell.decimal : cell.text;
|
|
349
|
+
return String(cell);
|
|
350
|
+
}
|
|
351
|
+
/** A list as a printable page: the title, the count, a table with the header on every page. */
|
|
352
|
+
function listHtml(sheet, options) {
|
|
353
|
+
const [header = [], ...body] = sheet.rows;
|
|
354
|
+
const numeric = header.map((_, i) => body.every((row) => {
|
|
355
|
+
const c = row[i];
|
|
356
|
+
return (c === null ||
|
|
357
|
+
c === undefined ||
|
|
358
|
+
typeof c === 'number' ||
|
|
359
|
+
(typeof c === 'object' && 'decimal' in c));
|
|
360
|
+
}));
|
|
361
|
+
const th = header.map((h) => `<th>${escapeHtml(cellText(h))}</th>`).join('');
|
|
362
|
+
const tr = body
|
|
363
|
+
.map((row) => `<tr>${row.map((c, i) => `<td${numeric[i] ? ' class="n"' : ''}>${escapeHtml(cellText(c))}</td>`).join('')}</tr>`)
|
|
364
|
+
.join('\n');
|
|
365
|
+
return `<!doctype html><html lang="${escapeHtml(options.lang)}" dir="${options.dir}"><head><meta charset="utf-8"><title>${escapeHtml(sheet.name)}</title><style>
|
|
366
|
+
body{font:10pt/1.4 "Inter","Noto Sans Bengali",system-ui,sans-serif;color:#111;margin:0}
|
|
367
|
+
h1{font-size:14pt;margin:0 0 2mm}p{margin:0 0 4mm;color:#555}
|
|
368
|
+
table{width:100%;border-collapse:collapse}thead{display:table-header-group}
|
|
369
|
+
th,td{padding:1.2mm 2mm;border-bottom:0.2mm solid #ccc;text-align:start;vertical-align:top}
|
|
370
|
+
th{font-weight:600;background:#f3f4f6}td.n,th.n{text-align:end;font-variant-numeric:tabular-nums}
|
|
371
|
+
tr{break-inside:avoid}</style></head><body><h1>${escapeHtml(sheet.name)}</h1><p>${body.length}</p><table><thead><tr>${th}</tr></thead><tbody>${tr}</tbody></table></body></html>`;
|
|
372
|
+
}
|
|
@@ -20,4 +20,15 @@ export interface Card {
|
|
|
20
20
|
readonly w: 3 | 4 | 6 | 12;
|
|
21
21
|
}
|
|
22
22
|
export declare function measureOf(text: string): MeasureSpec;
|
|
23
|
+
export declare function Records({ model, domain, onClose, }: {
|
|
24
|
+
readonly model: string;
|
|
25
|
+
readonly domain: Condition;
|
|
26
|
+
readonly onClose: () => void;
|
|
27
|
+
}): ReactElement;
|
|
28
|
+
export declare function CardFrame({ card, editing, onRemove, onDrill, }: {
|
|
29
|
+
readonly card: Card;
|
|
30
|
+
readonly editing: boolean;
|
|
31
|
+
readonly onRemove: () => void;
|
|
32
|
+
readonly onDrill: (domain: Condition) => void;
|
|
33
|
+
}): ReactElement;
|
|
23
34
|
export declare function DashboardView(_props: ViewProps): ReactElement;
|
|
@@ -25,7 +25,7 @@ function thisMonth() {
|
|
|
25
25
|
const to = new Date(Date.UTC(now.getFullYear(), now.getMonth() + 1, 1));
|
|
26
26
|
return { from: from.toISOString().slice(0, 10), to: to.toISOString().slice(0, 10) };
|
|
27
27
|
}
|
|
28
|
-
function Records({ model, domain, onClose, }) {
|
|
28
|
+
export function Records({ model, domain, onClose, }) {
|
|
29
29
|
const { api } = useKosh();
|
|
30
30
|
const { t } = useTranslation('reporting');
|
|
31
31
|
const rows = useQuery({
|
|
@@ -90,7 +90,7 @@ const SPAN = {
|
|
|
90
90
|
6: 'lg:col-span-6',
|
|
91
91
|
12: 'lg:col-span-12',
|
|
92
92
|
};
|
|
93
|
-
function CardFrame({ card, editing, onRemove, onDrill, }) {
|
|
93
|
+
export function CardFrame({ card, editing, onRemove, onDrill, }) {
|
|
94
94
|
const { t } = useTranslation('reporting');
|
|
95
95
|
const drag = useDraggable({ id: card.id, disabled: !editing });
|
|
96
96
|
const drop = useDroppable({ id: card.id });
|
|
@@ -21,6 +21,7 @@ const KINDS = [
|
|
|
21
21
|
'divider',
|
|
22
22
|
'pageBreak',
|
|
23
23
|
'signature',
|
|
24
|
+
'qr',
|
|
24
25
|
];
|
|
25
26
|
function newBlock(kind, n) {
|
|
26
27
|
const id = `${kind}_${n}`;
|
|
@@ -39,6 +40,8 @@ function newBlock(kind, n) {
|
|
|
39
40
|
return { kind, id, left: [], right: [] };
|
|
40
41
|
case 'signature':
|
|
41
42
|
return { kind, id, labels: ['Prepared by', 'Approved by'] };
|
|
43
|
+
case 'qr':
|
|
44
|
+
return { kind, id, bind: 'name' };
|
|
42
45
|
default:
|
|
43
46
|
return { kind, id };
|
|
44
47
|
}
|
|
@@ -52,6 +55,8 @@ function BlockEditor({ block, onChange, }) {
|
|
|
52
55
|
return (_jsxs("div", { className: "grid gap-2", children: [text(t('designer.text'), block.text, (v) => onChange({ ...block, text: v })), _jsx(Select, { label: "Level", value: String(block.level ?? 1), options: ['1', '2', '3'].map((l) => ({ value: l, label: `H${l}` })), onChange: (v) => onChange({ ...block, level: Number(v) }) })] }));
|
|
53
56
|
case 'text':
|
|
54
57
|
return text(t('designer.text'), block.text, (v) => onChange({ ...block, text: v }), true);
|
|
58
|
+
case 'qr':
|
|
59
|
+
return (_jsxs("div", { className: "grid gap-2", children: [text(t('designer.bind'), block.bind, (v) => onChange({ ...block, bind: v })), text(t('designer.label'), block.label ?? '', (v) => onChange({ ...block, label: v === '' ? undefined : v }))] }));
|
|
55
60
|
case 'field':
|
|
56
61
|
return (_jsxs("div", { className: "grid gap-2", children: [text(t('designer.bind'), block.bind, (v) => onChange({ ...block, bind: v })), text(t('designer.label'), block.label ?? '', (v) => onChange({ ...block, label: v === '' ? undefined : v }))] }));
|
|
57
62
|
case 'fields':
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An app's overview page (RFC 0022 §3.2): the cards its manifest declared — KPIs with their change against the
|
|
3
|
+
* previous period, charts, small pivots, top records — opened by the app's first menu. The cards come from the
|
|
4
|
+
* overview route; each one queries the reports as the user (their rights and record rules apply), and a chart point
|
|
5
|
+
* or a pivot row opens the records behind it. Read-only: the layout belongs to the app (personal layouts: step 3).
|
|
6
|
+
*/
|
|
7
|
+
import { type PageProps } from '../../ui/index.js';
|
|
8
|
+
import { type ReactElement } from 'react';
|
|
9
|
+
export declare function Overview({ app }: PageProps): ReactElement;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* An app's overview page (RFC 0022 §3.2): the cards its manifest declared — KPIs with their change against the
|
|
4
|
+
* previous period, charts, small pivots, top records — opened by the app's first menu. The cards come from the
|
|
5
|
+
* overview route; each one queries the reports as the user (their rights and record rules apply), and a chart point
|
|
6
|
+
* or a pivot row opens the records behind it. Read-only: the layout belongs to the app (personal layouts: step 3).
|
|
7
|
+
*/
|
|
8
|
+
import { Alert, Button, Spinner, useKosh } from '../../ui/index.js';
|
|
9
|
+
import { useQuery } from '@tanstack/react-query';
|
|
10
|
+
import { useState } from 'react';
|
|
11
|
+
import { useTranslation } from 'react-i18next';
|
|
12
|
+
import { CardFrame, Records } from './DashboardView.js';
|
|
13
|
+
export function Overview({ app }) {
|
|
14
|
+
const { api, uid } = useKosh();
|
|
15
|
+
const { t } = useTranslation('reporting');
|
|
16
|
+
const [drill, setDrill] = useState(null);
|
|
17
|
+
// RFC 0022 step 3: the cards a person hid, kept in their browser (like a list's columns).
|
|
18
|
+
const hiddenKey = `kosh.overview.${uid}.${app ?? ''}`;
|
|
19
|
+
const [hidden, setHidden] = useState(() => {
|
|
20
|
+
try {
|
|
21
|
+
const raw = localStorage.getItem(hiddenKey);
|
|
22
|
+
return raw === null ? [] : JSON.parse(raw);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return [];
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
const [editing, setEditing] = useState(false);
|
|
29
|
+
const hide = (ids) => {
|
|
30
|
+
setHidden(ids);
|
|
31
|
+
try {
|
|
32
|
+
localStorage.setItem(hiddenKey, JSON.stringify(ids));
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// storage unavailable: the choice lasts for the page
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
const overview = useQuery({
|
|
39
|
+
queryKey: ['overview', app],
|
|
40
|
+
queryFn: () => api.call('GET', `/api/v1/reports/overview?app=${encodeURIComponent(app ?? '')}`),
|
|
41
|
+
enabled: app !== undefined,
|
|
42
|
+
});
|
|
43
|
+
if (overview.isError)
|
|
44
|
+
return _jsx(Alert, { children: overview.error.message });
|
|
45
|
+
if (overview.data === undefined)
|
|
46
|
+
return _jsx(Spinner, { label: t('overview') });
|
|
47
|
+
return (_jsxs("div", { className: "grid gap-3", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("h2", { className: "text-base font-semibold", children: `${overview.data.label} · ${t('overview')}` }), _jsxs("div", { className: "ms-auto flex items-center gap-2", children: [hidden.length === 0 ? null : (_jsx(Button, { size: "sm", variant: "ghost", onClick: () => hide([]), children: t('showAllCards', { count: hidden.length }) })), _jsx(Button, { size: "sm", onClick: () => setEditing((e) => !e), children: editing ? t('done') : t('customise') })] })] }), _jsx("div", { className: "grid grid-cols-12 gap-3", children: overview.data.cards
|
|
48
|
+
.filter((card) => editing || !hidden.includes(card.id))
|
|
49
|
+
.map((card) => (_jsx(CardFrame, { card: card, editing: editing && !hidden.includes(card.id), onRemove: () => hide([...hidden, card.id]), onDrill: (domain) => setDrill({
|
|
50
|
+
model: card.model,
|
|
51
|
+
domain: card.filter === undefined ? domain : { and: [card.filter, domain] },
|
|
52
|
+
}) }, card.id))) }), drill === null ? null : (_jsx(Records, { model: drill.model, domain: drill.domain, onClose: () => setDrill(null) }))] }));
|
|
53
|
+
}
|
|
@@ -17,6 +17,7 @@ export { GanttView, windowOf } from './GanttView.js';
|
|
|
17
17
|
export { chartData, GraphView, ReportChart, type ReportChartProps } from './GraphView.js';
|
|
18
18
|
export { HierarchyView } from './HierarchyView.js';
|
|
19
19
|
export { DEFAULT_MAP_STYLE, MapView } from './MapView.js';
|
|
20
|
+
export { Overview } from './Overview.js';
|
|
20
21
|
export { PivotView } from './PivotView.js';
|
|
21
22
|
export { SpreadsheetView } from './SpreadsheetView.js';
|
|
22
23
|
/** Registers the report views (and their messages in `i18n`, when given). */
|
|
@@ -15,6 +15,7 @@ import { GraphView } from './GraphView.js';
|
|
|
15
15
|
import { HierarchyView } from './HierarchyView.js';
|
|
16
16
|
import { MapView } from './MapView.js';
|
|
17
17
|
import { messages } from './messages.js';
|
|
18
|
+
import { Overview } from './Overview.js';
|
|
18
19
|
import { PivotView } from './PivotView.js';
|
|
19
20
|
import { SpreadsheetView } from './SpreadsheetView.js';
|
|
20
21
|
export { CalendarView, gridDays } from './CalendarView.js';
|
|
@@ -27,6 +28,7 @@ export { GanttView, windowOf } from './GanttView.js';
|
|
|
27
28
|
export { chartData, GraphView, ReportChart } from './GraphView.js';
|
|
28
29
|
export { HierarchyView } from './HierarchyView.js';
|
|
29
30
|
export { DEFAULT_MAP_STYLE, MapView } from './MapView.js';
|
|
31
|
+
export { Overview } from './Overview.js';
|
|
30
32
|
export { PivotView } from './PivotView.js';
|
|
31
33
|
export { SpreadsheetView } from './SpreadsheetView.js';
|
|
32
34
|
/** Registers the report views (and their messages in `i18n`, when given). */
|
|
@@ -43,7 +45,8 @@ export function registerReportingWeb(registry, i18n) {
|
|
|
43
45
|
.registerView('dashboard', DashboardView)
|
|
44
46
|
.registerView('designer', DesignerView)
|
|
45
47
|
.registerComponent('reporting.Documents', Documents)
|
|
46
|
-
.registerComponent('reporting.ScheduleOutputs', ScheduleOutputs)
|
|
48
|
+
.registerComponent('reporting.ScheduleOutputs', ScheduleOutputs)
|
|
49
|
+
.registerPage('reporting.Overview', Overview);
|
|
47
50
|
if (i18n !== undefined)
|
|
48
51
|
addMessages(i18n, 'reporting', messages);
|
|
49
52
|
return registry;
|
|
@@ -33,6 +33,10 @@ export const messages = {
|
|
|
33
33
|
churn: 'Closed',
|
|
34
34
|
newSheet: 'New spreadsheet',
|
|
35
35
|
newDashboard: 'New dashboard',
|
|
36
|
+
overview: 'Overview',
|
|
37
|
+
customise: 'Customise',
|
|
38
|
+
showAllCards_one: 'Show the {{count}} hidden card',
|
|
39
|
+
showAllCards_other: 'Show the {{count}} hidden cards',
|
|
36
40
|
name: 'Name',
|
|
37
41
|
save: 'Save',
|
|
38
42
|
saved: 'Saved',
|
|
@@ -87,6 +91,7 @@ export const messages = {
|
|
|
87
91
|
divider: 'Divider',
|
|
88
92
|
pageBreak: 'Page break',
|
|
89
93
|
signature: 'Signatures',
|
|
94
|
+
qr: 'QR code',
|
|
90
95
|
},
|
|
91
96
|
},
|
|
92
97
|
},
|
|
@@ -112,6 +117,10 @@ export const messages = {
|
|
|
112
117
|
next: 'পরের',
|
|
113
118
|
newSheet: 'নতুন স্প্রেডশিট',
|
|
114
119
|
newDashboard: 'নতুন ড্যাশবোর্ড',
|
|
120
|
+
overview: 'সারসংক্ষেপ',
|
|
121
|
+
customise: 'সাজান',
|
|
122
|
+
showAllCards_one: 'লুকানো {{count}}টি কার্ড দেখান',
|
|
123
|
+
showAllCards_other: 'লুকানো {{count}}টি কার্ড দেখান',
|
|
115
124
|
name: 'নাম',
|
|
116
125
|
save: 'সংরক্ষণ',
|
|
117
126
|
addCard: 'কার্ড যোগ করুন',
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash:
|
|
1
|
+
// GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: 6e014c4aaba6871d
|
|
2
2
|
// Bindings of module `sale_account`: import the definition API from here to get types scoped to what it can see.
|
|
3
3
|
export { defineModel, defineModule, extendModel, f, replace } from '../../server/orm.js';
|
|
4
4
|
import { definitions } from '../../server/orm.js';
|