shutro-erp 0.3.6 → 0.3.7
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_asset/.kosh/bindings.js +1 -1
- package/dist/account_asset/.kosh/schema.d.ts +530 -8
- package/dist/account_asset/i18n/bn.d.ts +2 -0
- package/dist/account_asset/i18n/bn.js +97 -0
- package/dist/account_asset/index.js +2 -0
- package/dist/account_asset/module.d.ts +4899 -1445
- package/dist/account_budget/.kosh/bindings.js +1 -1
- package/dist/account_budget/.kosh/schema.d.ts +1130 -56
- package/dist/account_budget/i18n/bn.d.ts +2 -0
- package/dist/account_budget/i18n/bn.js +63 -0
- package/dist/account_budget/index.js +14 -0
- package/dist/account_budget/module.d.ts +17958 -4532
- package/dist/account_budget/module.js +15 -0
- package/dist/account_portal/.kosh/bindings.js +1 -1
- package/dist/account_portal/.kosh/schema.d.ts +530 -8
- package/dist/account_portal/i18n/bn.d.ts +2 -0
- package/dist/account_portal/i18n/bn.js +6 -0
- package/dist/account_portal/index.js +2 -0
- package/dist/account_portal/module.d.ts +5167 -1693
- package/dist/accounting/.kosh/bindings.js +1 -1
- package/dist/accounting/.kosh/schema.d.ts +530 -8
- package/dist/accounting/closing.js +1 -0
- package/dist/accounting/fiscal.d.ts +578 -0
- package/dist/accounting/fiscal.js +401 -0
- package/dist/accounting/followups.d.ts +618 -0
- package/dist/accounting/followups.js +420 -0
- package/dist/accounting/i18n/bn.d.ts +2 -0
- package/dist/accounting/i18n/bn.js +425 -0
- package/dist/accounting/index.d.ts +2 -0
- package/dist/accounting/index.js +649 -2
- package/dist/accounting/module.d.ts +4998 -1451
- package/dist/accounting/module.js +124 -18
- package/dist/accounting/statements.d.ts +878 -0
- package/dist/accounting/statements.js +728 -0
- package/dist/accounting/web/BankReconcilePage.d.ts +9 -0
- package/dist/accounting/web/BankReconcilePage.js +138 -0
- package/dist/accounting/web/FollowupsPage.d.ts +8 -0
- package/dist/accounting/web/FollowupsPage.js +54 -0
- package/dist/accounting/web/PostingPreview.d.ts +8 -0
- package/dist/accounting/web/PostingPreview.js +26 -0
- package/dist/accounting/web/index.d.ts +3 -0
- package/dist/accounting/web/index.js +9 -0
- package/dist/accounting/web/messages.js +140 -0
- package/dist/approvals/.kosh/bindings.js +1 -1
- package/dist/approvals/.kosh/schema.d.ts +272 -4
- package/dist/approvals/demo.d.ts +7 -0
- package/dist/approvals/demo.js +41 -0
- package/dist/approvals/i18n/bn.d.ts +2 -0
- package/dist/approvals/i18n/bn.js +133 -0
- package/dist/approvals/index.d.ts +19 -1
- package/dist/approvals/index.js +477 -7
- package/dist/approvals/mails.d.ts +7 -2
- package/dist/approvals/mails.js +8 -3
- package/dist/approvals/module.d.ts +2930 -1
- package/dist/approvals/module.js +468 -7
- package/dist/approvals/web/Config.d.ts +12 -0
- package/dist/approvals/web/Config.js +60 -0
- package/dist/approvals/web/Matrix.d.ts +9 -0
- package/dist/approvals/web/Matrix.js +26 -0
- package/dist/approvals/web/index.d.ts +3 -1
- package/dist/approvals/web/index.js +8 -1
- package/dist/approvals/web/messages.js +92 -0
- package/dist/approvals_purchase/.kosh/bindings.js +15 -0
- package/dist/approvals_purchase/.kosh/schema.d.ts +1997 -0
- package/dist/approvals_purchase/i18n/bn.d.ts +2 -0
- package/dist/approvals_purchase/i18n/bn.js +5 -0
- package/dist/approvals_purchase/index.d.ts +3 -0
- package/dist/approvals_purchase/index.js +47 -0
- package/dist/approvals_purchase/module.d.ts +12670 -0
- package/dist/approvals_purchase/module.js +84 -0
- package/dist/attendance/.kosh/bindings.js +1 -1
- package/dist/attendance/.kosh/schema.d.ts +59 -1
- package/dist/attendance/i18n/bn.d.ts +2 -0
- package/dist/attendance/i18n/bn.js +147 -0
- package/dist/attendance/index.js +3 -1
- package/dist/attendance/module.d.ts +452 -8
- package/dist/automation/engine.js +1 -1
- package/dist/calendar/.kosh/bindings.js +1 -1
- package/dist/calendar/.kosh/schema.d.ts +2 -1
- package/dist/calendar/i18n/bn.d.ts +2 -0
- package/dist/calendar/i18n/bn.js +80 -0
- package/dist/calendar/index.js +77 -0
- package/dist/calendar/module.d.ts +26 -0
- package/dist/calendar/module.js +14 -4
- package/dist/cli/apps.js +25 -5
- package/dist/cli/init.js +14 -4
- package/dist/cli/templates.d.ts +1 -1
- package/dist/cli/templates.js +34 -5
- package/dist/contacts/.kosh/bindings.js +1 -1
- package/dist/contacts/.kosh/schema.d.ts +2 -1
- package/dist/contacts/i18n/bn.d.ts +2 -0
- package/dist/contacts/i18n/bn.js +67 -0
- package/dist/contacts/index.js +3 -0
- package/dist/contacts/module.d.ts +42 -0
- package/dist/contacts/module.js +6 -1
- package/dist/crm/.kosh/bindings.js +1 -1
- package/dist/crm/.kosh/schema.d.ts +2 -1
- package/dist/crm/i18n/bn.d.ts +2 -0
- package/dist/crm/i18n/bn.js +80 -0
- package/dist/crm/index.js +22 -0
- package/dist/crm/module.d.ts +20 -0
- package/dist/crm/module.js +4 -2
- package/dist/documents/.kosh/bindings.js +1 -1
- package/dist/documents/.kosh/schema.d.ts +2 -1
- package/dist/documents/i18n/bn.d.ts +2 -0
- package/dist/documents/i18n/bn.js +83 -0
- package/dist/documents/index.js +128 -1
- package/dist/documents/module.d.ts +20 -0
- package/dist/documents/module.js +1 -0
- package/dist/event/.kosh/bindings.js +1 -1
- package/dist/event/.kosh/schema.d.ts +2 -1
- package/dist/event/i18n/bn.d.ts +2 -0
- package/dist/event/i18n/bn.js +101 -0
- package/dist/event/index.js +66 -0
- package/dist/event/module.d.ts +20 -0
- package/dist/event/module.js +8 -1
- package/dist/event_account/.kosh/bindings.js +1 -1
- package/dist/event_account/.kosh/schema.d.ts +530 -8
- package/dist/event_account/i18n/bn.d.ts +2 -0
- package/dist/event_account/i18n/bn.js +5 -0
- package/dist/event_account/index.js +2 -0
- package/dist/event_account/module.d.ts +4905 -1431
- package/dist/expense/.kosh/bindings.js +1 -1
- package/dist/expense/.kosh/schema.d.ts +323 -2
- package/dist/expense/i18n/bn.d.ts +2 -0
- package/dist/expense/i18n/bn.js +155 -0
- package/dist/expense/index.js +8 -1
- package/dist/expense/module.d.ts +2715 -694
- package/dist/expense/module.js +3 -1
- package/dist/expense_account/.kosh/bindings.js +1 -1
- package/dist/expense_account/.kosh/schema.d.ts +587 -8
- package/dist/expense_account/i18n/bn.d.ts +2 -0
- package/dist/expense_account/i18n/bn.js +15 -0
- package/dist/expense_account/index.js +2 -0
- package/dist/expense_account/module.d.ts +8094 -2619
- package/dist/helpdesk/.kosh/bindings.js +1 -1
- package/dist/helpdesk/.kosh/schema.d.ts +2 -1
- package/dist/helpdesk/i18n/bn.d.ts +2 -0
- package/dist/helpdesk/i18n/bn.js +127 -0
- package/dist/helpdesk/index.js +2 -0
- package/dist/helpdesk/module.d.ts +20 -0
- package/dist/hr/.kosh/bindings.js +1 -1
- package/dist/hr/.kosh/schema.d.ts +59 -1
- package/dist/hr/demo.js +11 -1
- package/dist/hr/i18n/bn.d.ts +2 -0
- package/dist/hr/i18n/bn.js +126 -0
- package/dist/hr/index.d.ts +1 -1
- package/dist/hr/index.js +158 -12
- package/dist/hr/module.d.ts +932 -59
- package/dist/hr/module.js +114 -17
- package/dist/{mrp → indent}/.kosh/bindings.js +2 -2
- package/dist/indent/.kosh/schema.d.ts +2084 -0
- package/dist/indent/demo.d.ts +7 -0
- package/dist/indent/demo.js +48 -0
- package/dist/indent/i18n/bn.d.ts +2 -0
- package/dist/indent/i18n/bn.js +143 -0
- package/dist/indent/index.d.ts +3 -0
- package/dist/indent/index.js +450 -0
- package/dist/{mrp → indent}/module.d.ts +7164 -3075
- package/dist/indent/module.js +792 -0
- package/dist/indent_purchase/.kosh/bindings.d.ts +22 -0
- package/dist/indent_purchase/.kosh/bindings.js +15 -0
- package/dist/indent_purchase/.kosh/schema.d.ts +2710 -0
- package/dist/indent_purchase/i18n/bn.d.ts +2 -0
- package/dist/indent_purchase/i18n/bn.js +13 -0
- package/dist/indent_purchase/index.d.ts +3 -0
- package/dist/indent_purchase/index.js +61 -0
- package/dist/indent_purchase/module.d.ts +27950 -0
- package/dist/indent_purchase/module.js +163 -0
- package/dist/l10n_bd/.kosh/bindings.js +1 -1
- package/dist/l10n_bd/.kosh/schema.d.ts +530 -8
- package/dist/l10n_bd/i18n/bn.d.ts +2 -0
- package/dist/l10n_bd/i18n/bn.js +69 -0
- package/dist/l10n_bd/index.js +2 -0
- package/dist/l10n_bd/module.d.ts +5167 -1693
- package/dist/l10n_bd_payroll/.kosh/bindings.js +1 -1
- package/dist/l10n_bd_payroll/.kosh/schema.d.ts +587 -8
- package/dist/l10n_bd_payroll/i18n/bn.d.ts +2 -0
- package/dist/l10n_bd_payroll/i18n/bn.js +4 -0
- package/dist/l10n_bd_payroll/index.js +2 -0
- package/dist/l10n_bd_payroll/module.d.ts +5910 -1548
- package/dist/l10n_bd_pos/.kosh/bindings.d.ts +22 -0
- package/dist/{mrp_account → l10n_bd_pos}/.kosh/bindings.js +2 -2
- package/dist/{mrp_account → l10n_bd_pos}/.kosh/schema.d.ts +693 -651
- package/dist/l10n_bd_pos/i18n/bn.d.ts +2 -0
- package/dist/l10n_bd_pos/i18n/bn.js +32 -0
- package/dist/l10n_bd_pos/index.d.ts +3 -0
- package/dist/l10n_bd_pos/index.js +111 -0
- package/dist/{mrp_account → l10n_bd_pos}/module.d.ts +7402 -7647
- package/dist/l10n_bd_pos/module.js +43 -0
- package/dist/l10n_in/.kosh/bindings.js +1 -1
- package/dist/l10n_in/.kosh/schema.d.ts +530 -8
- package/dist/l10n_in/i18n/bn.d.ts +2 -0
- package/dist/l10n_in/i18n/bn.js +95 -0
- package/dist/l10n_in/index.js +2 -0
- package/dist/l10n_in/module.d.ts +6703 -1652
- package/dist/l10n_in/module.js +25 -5
- package/dist/l10n_in/web/GstSettings.js +2 -2
- package/dist/mail/inbound/handle.js +2 -4
- package/dist/mail/inbound/models.js +5 -3
- package/dist/mail/index.d.ts +12 -1
- package/dist/mail/index.js +139 -2
- package/dist/mail/send.d.ts +56 -0
- package/dist/mail/send.js +394 -0
- package/dist/mail/web/SendButton.d.ts +9 -0
- package/dist/mail/web/SendButton.js +71 -0
- package/dist/mail/web/SendSelected.d.ts +8 -0
- package/dist/mail/web/SendSelected.js +33 -0
- package/dist/mail/web/index.d.ts +2 -0
- package/dist/mail/web/index.js +6 -0
- package/dist/mail/web/messages.js +36 -0
- package/dist/maintenance/.kosh/bindings.js +1 -1
- package/dist/maintenance/.kosh/schema.d.ts +2 -1
- package/dist/maintenance/i18n/bn.d.ts +2 -0
- package/dist/maintenance/i18n/bn.js +132 -0
- package/dist/maintenance/index.js +85 -0
- package/dist/maintenance/module.d.ts +25 -0
- package/dist/maintenance/module.js +27 -9
- package/dist/maintenance_stock/.kosh/bindings.js +1 -1
- package/dist/maintenance_stock/.kosh/schema.d.ts +298 -2
- package/dist/maintenance_stock/i18n/bn.d.ts +2 -0
- package/dist/maintenance_stock/i18n/bn.js +21 -0
- package/dist/maintenance_stock/index.js +2 -0
- package/dist/maintenance_stock/module.d.ts +5302 -1256
- package/dist/maintenance_stock/module.js +1 -0
- package/dist/modules-sdk/apps.d.ts +10 -0
- package/dist/modules-sdk/apps.js +32 -0
- package/dist/modules-sdk/index.d.ts +1 -1
- package/dist/modules-sdk/manifest.d.ts +68 -2
- package/dist/payment/.kosh/bindings.js +1 -1
- package/dist/payment/.kosh/schema.d.ts +530 -8
- package/dist/payment/i18n/bn.d.ts +2 -0
- package/dist/payment/i18n/bn.js +59 -0
- package/dist/payment/index.js +85 -0
- package/dist/payment/module.d.ts +5134 -1660
- package/dist/payment/module.js +17 -3
- package/dist/payment/settle.js +1 -0
- package/dist/payroll/.kosh/bindings.js +1 -1
- package/dist/payroll/.kosh/schema.d.ts +59 -1
- package/dist/payroll/i18n/bn.d.ts +2 -0
- package/dist/payroll/i18n/bn.js +206 -0
- package/dist/payroll/index.js +2 -0
- package/dist/payroll/module.d.ts +936 -48
- package/dist/payroll_account/.kosh/bindings.js +1 -1
- package/dist/payroll_account/.kosh/schema.d.ts +587 -8
- package/dist/payroll_account/i18n/bn.d.ts +2 -0
- package/dist/payroll_account/i18n/bn.js +10 -0
- package/dist/payroll_account/index.js +2 -0
- package/dist/payroll_account/module.d.ts +7534 -3192
- package/dist/permissions/approvals.d.ts +97 -4
- package/dist/permissions/approvals.js +780 -31
- package/dist/permissions/index.d.ts +1 -1
- package/dist/permissions/index.js +2 -2
- package/dist/permissions/models.js +177 -5
- package/dist/permissions/routes.d.ts +3 -0
- package/dist/permissions/routes.js +36 -2
- package/dist/permissions/web/ApprovalPanel.js +43 -5
- package/dist/permissions/web/messages.js +52 -0
- package/dist/portal/.kosh/bindings.js +1 -1
- package/dist/portal/.kosh/schema.d.ts +2 -1
- package/dist/portal/documents.d.ts +3 -0
- package/dist/portal/documents.js +21 -1
- package/dist/portal/i18n/bn.d.ts +2 -0
- package/dist/portal/i18n/bn.js +33 -0
- package/dist/portal/index.js +2 -0
- package/dist/portal/module.d.ts +20 -0
- package/dist/portal/routes-documents.js +76 -0
- package/dist/pos/.kosh/bindings.js +1 -1
- package/dist/pos/.kosh/schema.d.ts +531 -8
- package/dist/pos/i18n/bn.d.ts +2 -0
- package/dist/pos/i18n/bn.js +133 -0
- package/dist/pos/index.js +83 -1
- package/dist/pos/module.d.ts +6888 -1777
- package/dist/pos/module.js +49 -5
- package/dist/pos/routes.js +80 -7
- package/dist/pos/web/Register.js +2 -5
- package/dist/pos_stock/.kosh/bindings.js +1 -1
- package/dist/pos_stock/.kosh/schema.d.ts +626 -9
- package/dist/pos_stock/i18n/bn.d.ts +2 -0
- package/dist/pos_stock/i18n/bn.js +6 -0
- package/dist/pos_stock/index.js +2 -0
- package/dist/pos_stock/module.d.ts +10798 -3276
- package/dist/product/.kosh/bindings.js +1 -1
- package/dist/product/.kosh/schema.d.ts +202 -1
- package/dist/product/i18n/bn.d.ts +2 -0
- package/dist/product/i18n/bn.js +175 -0
- package/dist/product/index.d.ts +1 -0
- package/dist/product/index.js +288 -1
- package/dist/product/module.d.ts +1725 -0
- package/dist/product/module.js +66 -6
- package/dist/product/pricelist.d.ts +575 -0
- package/dist/product/pricelist.js +257 -0
- package/dist/product/variants.d.ts +908 -0
- package/dist/product/variants.js +251 -0
- package/dist/production/.kosh/bindings.d.ts +22 -0
- package/dist/production/.kosh/bindings.js +15 -0
- package/dist/production/.kosh/schema.d.ts +2345 -0
- package/dist/{mrp → production}/demo.d.ts +1 -1
- package/dist/{mrp → production}/demo.js +5 -5
- package/dist/production/depth.d.ts +790 -0
- package/dist/production/depth.js +262 -0
- package/dist/production/i18n/bn.d.ts +2 -0
- package/dist/production/i18n/bn.js +350 -0
- package/dist/production/index.d.ts +6 -0
- package/dist/production/index.js +1256 -0
- package/dist/production/module.d.ts +17327 -0
- package/dist/production/module.js +1333 -0
- package/dist/production/plan.d.ts +921 -0
- package/dist/production/plan.js +511 -0
- package/dist/production/schedule.d.ts +656 -0
- package/dist/production/schedule.js +309 -0
- package/dist/production_account/.kosh/bindings.d.ts +22 -0
- package/dist/production_account/.kosh/bindings.js +15 -0
- package/dist/production_account/.kosh/schema.d.ts +3496 -0
- package/dist/production_account/i18n/bn.d.ts +2 -0
- package/dist/production_account/i18n/bn.js +93 -0
- package/dist/production_account/index.d.ts +4 -0
- package/dist/production_account/index.js +246 -0
- package/dist/production_account/module.d.ts +1192 -0
- package/dist/{mrp_account → production_account}/module.js +72 -18
- package/dist/production_account/overhead.d.ts +1195 -0
- package/dist/production_account/overhead.js +554 -0
- package/dist/project/.kosh/bindings.js +1 -1
- package/dist/project/.kosh/schema.d.ts +65 -2
- package/dist/project/i18n/bn.d.ts +2 -0
- package/dist/project/i18n/bn.js +383 -0
- package/dist/project/index.js +123 -0
- package/dist/project/module.d.ts +20 -0
- package/dist/project/module.js +73 -14
- package/dist/project_account/.kosh/bindings.js +1 -1
- package/dist/project_account/.kosh/schema.d.ts +530 -8
- package/dist/project_account/i18n/bn.d.ts +2 -0
- package/dist/project_account/i18n/bn.js +6 -0
- package/dist/project_account/index.js +2 -0
- package/dist/project_account/module.d.ts +4926 -1452
- package/dist/project_portal/.kosh/bindings.js +1 -1
- package/dist/project_portal/.kosh/schema.d.ts +65 -2
- package/dist/project_portal/i18n/bn.d.ts +2 -0
- package/dist/project_portal/i18n/bn.js +6 -0
- package/dist/project_portal/index.js +2 -0
- package/dist/project_portal/module.d.ts +40 -0
- package/dist/project_purchase/.kosh/bindings.js +1 -1
- package/dist/project_purchase/.kosh/schema.d.ts +1126 -53
- package/dist/project_purchase/i18n/bn.d.ts +2 -0
- package/dist/project_purchase/i18n/bn.js +4 -0
- package/dist/project_purchase/index.js +2 -0
- package/dist/project_purchase/module.d.ts +17912 -4446
- package/dist/purchase/.kosh/bindings.js +1 -1
- package/dist/purchase/.kosh/schema.d.ts +813 -3
- package/dist/purchase/comparison.d.ts +993 -0
- package/dist/purchase/comparison.js +415 -0
- package/dist/purchase/extras.d.ts +1509 -0
- package/dist/purchase/extras.js +445 -0
- package/dist/purchase/i18n/bn.d.ts +2 -0
- package/dist/purchase/i18n/bn.js +413 -0
- package/dist/purchase/index.d.ts +5 -0
- package/dist/purchase/index.js +1280 -4
- package/dist/purchase/module.d.ts +7139 -398
- package/dist/purchase/module.js +295 -11
- package/dist/purchase/request.d.ts +696 -0
- package/dist/purchase/request.js +446 -0
- package/dist/purchase/tender.d.ts +1208 -0
- package/dist/purchase/tender.js +507 -0
- package/dist/purchase/vendorprice.d.ts +340 -0
- package/dist/purchase/vendorprice.js +153 -0
- package/dist/purchase_account/.kosh/bindings.js +1 -1
- package/dist/purchase_account/.kosh/schema.d.ts +1130 -57
- package/dist/purchase_account/i18n/bn.d.ts +2 -0
- package/dist/purchase_account/i18n/bn.js +22 -0
- package/dist/purchase_account/index.js +19 -0
- package/dist/purchase_account/module.d.ts +12276 -2247
- package/dist/purchase_account/module.js +241 -9
- package/dist/purchase_portal/.kosh/bindings.js +1 -1
- package/dist/purchase_portal/.kosh/schema.d.ts +813 -3
- package/dist/purchase_portal/i18n/bn.d.ts +2 -0
- package/dist/purchase_portal/i18n/bn.js +5 -0
- package/dist/purchase_portal/index.js +2 -0
- package/dist/purchase_portal/module.d.ts +6849 -353
- package/dist/purchase_stock/.kosh/bindings.js +1 -1
- package/dist/purchase_stock/.kosh/schema.d.ts +910 -4
- package/dist/purchase_stock/i18n/bn.d.ts +2 -0
- package/dist/purchase_stock/i18n/bn.js +19 -0
- package/dist/purchase_stock/index.d.ts +1 -1
- package/dist/purchase_stock/index.js +29 -0
- package/dist/purchase_stock/module.d.ts +12410 -1864
- package/dist/purchase_stock/module.js +81 -9
- package/dist/purchase_stock/scorecard.d.ts +22 -0
- package/dist/purchase_stock/scorecard.js +77 -0
- package/dist/purchase_stock/web/Scorecard.d.ts +7 -0
- package/dist/purchase_stock/web/Scorecard.js +22 -0
- package/dist/purchase_stock/web/index.d.ts +11 -0
- package/dist/purchase_stock/web/index.js +16 -0
- package/dist/purchase_stock/web/messages.d.ts +2 -0
- package/dist/purchase_stock/web/messages.js +27 -0
- package/dist/purchase_stock_account/.kosh/bindings.js +1 -1
- package/dist/purchase_stock_account/.kosh/schema.d.ts +1286 -58
- package/dist/purchase_stock_account/i18n/bn.d.ts +2 -0
- package/dist/purchase_stock_account/i18n/bn.js +8 -0
- package/dist/purchase_stock_account/index.js +18 -0
- package/dist/purchase_stock_account/module.d.ts +7 -37995
- package/dist/purchase_stock_account/module.js +24 -3
- package/dist/recruitment/.kosh/bindings.js +1 -1
- package/dist/recruitment/.kosh/schema.d.ts +59 -1
- package/dist/recruitment/i18n/bn.d.ts +2 -0
- package/dist/recruitment/i18n/bn.js +93 -0
- package/dist/recruitment/index.js +64 -0
- package/dist/recruitment/module.d.ts +458 -8
- package/dist/recruitment/module.js +11 -3
- package/dist/reporting/documents.d.ts +5 -0
- package/dist/reporting/documents.js +11 -1
- package/dist/reporting/index.d.ts +1 -1
- package/dist/reporting/index.js +1 -1
- package/dist/reporting/web/CalendarView.d.ts +18 -5
- package/dist/reporting/web/CalendarView.js +163 -29
- package/dist/reporting/web/messages.js +18 -0
- package/dist/sale_account/.kosh/bindings.js +1 -1
- package/dist/sale_account/.kosh/schema.d.ts +642 -16
- package/dist/sale_account/i18n/bn.d.ts +2 -0
- package/dist/sale_account/i18n/bn.js +48 -0
- package/dist/sale_account/index.d.ts +1 -1
- package/dist/sale_account/index.js +102 -4
- package/dist/sale_account/module.d.ts +8254 -2212
- package/dist/sale_account/module.js +535 -46
- package/dist/sale_crm/.kosh/bindings.d.ts +22 -0
- package/dist/sale_crm/.kosh/bindings.js +15 -0
- package/dist/{mrp → sale_crm}/.kosh/schema.d.ts +389 -567
- package/dist/sale_crm/i18n/bn.d.ts +2 -0
- package/dist/sale_crm/i18n/bn.js +9 -0
- package/dist/sale_crm/index.d.ts +7 -0
- package/dist/sale_crm/index.js +104 -0
- package/dist/sale_crm/module.d.ts +5609 -0
- package/dist/sale_crm/module.js +73 -0
- package/dist/sale_portal/.kosh/bindings.js +1 -1
- package/dist/sale_portal/.kosh/schema.d.ts +291 -4
- package/dist/sale_portal/i18n/bn.d.ts +2 -0
- package/dist/sale_portal/i18n/bn.js +7 -0
- package/dist/sale_portal/index.js +10 -0
- package/dist/sale_portal/module.d.ts +2564 -294
- package/dist/sale_project/.kosh/bindings.js +1 -1
- package/dist/sale_project/.kosh/schema.d.ts +354 -5
- package/dist/sale_project/i18n/bn.d.ts +2 -0
- package/dist/sale_project/i18n/bn.js +12 -0
- package/dist/sale_project/index.js +2 -0
- package/dist/sale_project/module.d.ts +6249 -2402
- package/dist/sale_stock/.kosh/bindings.js +1 -1
- package/dist/sale_stock/.kosh/schema.d.ts +387 -5
- package/dist/sale_stock/i18n/bn.d.ts +2 -0
- package/dist/sale_stock/i18n/bn.js +15 -0
- package/dist/sale_stock/index.js +2 -0
- package/dist/sale_stock/module.d.ts +8057 -1759
- package/dist/sale_stock/module.js +20 -3
- package/dist/sales/.kosh/bindings.js +1 -1
- package/dist/sales/.kosh/schema.d.ts +291 -4
- package/dist/sales/i18n/bn.d.ts +2 -0
- package/dist/sales/i18n/bn.js +128 -0
- package/dist/sales/index.js +120 -5
- package/dist/sales/module.d.ts +3567 -633
- package/dist/sales/module.js +306 -11
- package/dist/server/api/duplicate.d.ts +14 -0
- package/dist/server/api/duplicate.js +75 -0
- package/dist/server/api/explain.d.ts +70 -0
- package/dist/server/api/explain.js +111 -0
- package/dist/server/api/metadata.d.ts +2 -0
- package/dist/server/api/metadata.js +9 -0
- package/dist/server/api/openapi.js +15 -0
- package/dist/server/api/rest.d.ts +1 -0
- package/dist/server/api/rest.js +76 -12
- package/dist/server/api/views.js +1 -1
- package/dist/server/apps.d.ts +16 -1
- package/dist/server/apps.js +164 -2
- package/dist/server/auth/base.js +2 -0
- package/dist/server/auth/service.d.ts +8 -0
- package/dist/server/auth/service.js +19 -0
- package/dist/server/events.d.ts +13 -0
- package/dist/server/events.js +22 -0
- package/dist/server/i18n.d.ts +27 -0
- package/dist/server/i18n.js +143 -0
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.js +2 -0
- package/dist/server/server.js +6 -0
- package/dist/settings/company.d.ts +3 -1
- package/dist/settings/company.js +26 -5
- package/dist/settings/routes.d.ts +10 -0
- package/dist/settings/routes.js +19 -3
- package/dist/settings/web/AppsPage.d.ts +3 -2
- package/dist/settings/web/AppsPage.js +26 -8
- package/dist/settings/web/CompaniesPage.js +91 -6
- package/dist/settings/web/messages.js +64 -0
- package/dist/sign/.kosh/bindings.js +1 -1
- package/dist/sign/.kosh/schema.d.ts +2 -1
- package/dist/sign/i18n/bn.d.ts +2 -0
- package/dist/sign/i18n/bn.js +97 -0
- package/dist/sign/index.d.ts +15 -0
- package/dist/sign/index.js +129 -1
- package/dist/sign/module.d.ts +40 -0
- package/dist/sign/module.js +11 -2
- package/dist/stock/.kosh/bindings.js +1 -1
- package/dist/stock/.kosh/schema.d.ts +298 -2
- package/dist/stock/i18n/bn.d.ts +2 -0
- package/dist/stock/i18n/bn.js +311 -0
- package/dist/stock/index.d.ts +3 -1
- package/dist/stock/index.js +442 -3
- package/dist/stock/ledger.d.ts +78 -0
- package/dist/stock/ledger.js +582 -0
- package/dist/stock/module.d.ts +5280 -2044
- package/dist/stock/module.js +222 -23
- package/dist/stock/replenish.js +16 -1
- package/dist/stock/returns.d.ts +157 -0
- package/dist/stock/returns.js +163 -0
- package/dist/stock/web/Ledger.d.ts +9 -0
- package/dist/stock/web/Ledger.js +108 -0
- package/dist/stock/web/Operations.d.ts +8 -0
- package/dist/stock/web/Operations.js +33 -0
- package/dist/stock/web/ReturnButton.d.ts +7 -0
- package/dist/stock/web/ReturnButton.js +62 -0
- package/dist/stock/web/index.d.ts +3 -0
- package/dist/stock/web/index.js +9 -0
- package/dist/stock/web/messages.js +154 -0
- package/dist/stock_account/.kosh/bindings.js +1 -1
- package/dist/stock_account/.kosh/schema.d.ts +682 -9
- package/dist/stock_account/i18n/bn.d.ts +2 -0
- package/dist/stock_account/i18n/bn.js +73 -0
- package/dist/stock_account/index.d.ts +1 -0
- package/dist/stock_account/index.js +131 -3
- package/dist/stock_account/landed.d.ts +429 -0
- package/dist/stock_account/landed.js +335 -0
- package/dist/stock_account/module.d.ts +11247 -3363
- package/dist/stock_account/module.js +135 -6
- package/dist/stock_account/web/LandedPreview.d.ts +7 -0
- package/dist/stock_account/web/LandedPreview.js +23 -0
- package/dist/stock_account/web/index.d.ts +11 -0
- package/dist/stock_account/web/index.js +16 -0
- package/dist/stock_account/web/messages.d.ts +2 -0
- package/dist/stock_account/web/messages.js +27 -0
- package/dist/todo/i18n/bn.d.ts +2 -0
- package/dist/todo/i18n/bn.js +66 -0
- package/dist/todo/index.js +59 -0
- package/dist/todo/module.d.ts +5 -0
- package/dist/todo/module.js +5 -3
- package/dist/trade_finance/.kosh/bindings.js +1 -1
- package/dist/trade_finance/.kosh/schema.d.ts +2 -1
- package/dist/trade_finance/i18n/bn.d.ts +2 -0
- package/dist/trade_finance/i18n/bn.js +162 -0
- package/dist/trade_finance/index.js +93 -0
- package/dist/trade_finance/module.d.ts +26 -0
- package/dist/trade_finance/module.js +27 -8
- package/dist/trade_finance_account/.kosh/bindings.js +1 -1
- package/dist/trade_finance_account/.kosh/schema.d.ts +530 -8
- package/dist/trade_finance_account/i18n/bn.d.ts +2 -0
- package/dist/trade_finance_account/i18n/bn.js +27 -0
- package/dist/trade_finance_account/index.js +2 -0
- package/dist/trade_finance_account/module.d.ts +4906 -1432
- package/dist/trade_finance_account/module.js +1 -0
- package/dist/trade_finance_purchase/.kosh/bindings.js +1 -1
- package/dist/trade_finance_purchase/.kosh/schema.d.ts +813 -3
- package/dist/trade_finance_purchase/i18n/bn.d.ts +2 -0
- package/dist/trade_finance_purchase/i18n/bn.js +6 -0
- package/dist/trade_finance_purchase/index.js +2 -0
- package/dist/trade_finance_purchase/module.d.ts +6909 -413
- package/dist/trade_finance_sale/.kosh/bindings.js +1 -1
- package/dist/trade_finance_sale/.kosh/schema.d.ts +291 -4
- package/dist/trade_finance_sale/i18n/bn.d.ts +2 -0
- package/dist/trade_finance_sale/i18n/bn.js +6 -0
- package/dist/trade_finance_sale/index.js +2 -0
- package/dist/trade_finance_sale/module.d.ts +2601 -331
- package/dist/ui/api.d.ts +2 -0
- package/dist/ui/app.d.ts +9 -0
- package/dist/ui/app.js +24 -4
- package/dist/ui/components/AppIcon.js +2 -2
- package/dist/ui/components/Explain.d.ts +69 -0
- package/dist/ui/components/Explain.js +62 -0
- package/dist/ui/context.d.ts +8 -1
- package/dist/ui/context.js +34 -1
- package/dist/ui/i18n/messages.d.ts +36 -0
- package/dist/ui/i18n/messages.js +72 -0
- package/dist/ui/index.d.ts +2 -1
- package/dist/ui/index.js +1 -0
- package/dist/ui/registry.d.ts +14 -0
- package/dist/ui/registry.js +10 -0
- package/dist/ui/views/FormView.d.ts +6 -0
- package/dist/ui/views/FormView.js +47 -10
- package/dist/ui/views/ListView.d.ts +8 -0
- package/dist/ui/views/ListView.js +10 -3
- package/dist/ui/views/StatsRow.js +2 -1
- package/dist/views/extend.js +12 -0
- package/dist/views/types.d.ts +13 -2
- package/dist/views/validate.js +8 -1
- package/dist/website/.kosh/bindings.js +1 -1
- package/dist/website/.kosh/schema.d.ts +2 -1
- package/dist/website/i18n/bn.d.ts +2 -0
- package/dist/website/i18n/bn.js +113 -0
- package/dist/website/index.js +36 -0
- package/dist/website/module.d.ts +20 -0
- package/dist/website/module.js +29 -5
- package/dist/website_crm/.kosh/bindings.js +1 -1
- package/dist/website_crm/.kosh/schema.d.ts +2 -1
- package/dist/website_crm/i18n/bn.d.ts +2 -0
- package/dist/website_crm/i18n/bn.js +5 -0
- package/dist/website_crm/index.js +2 -0
- package/dist/website_crm/module.d.ts +40 -0
- package/dist/website_sale/.kosh/bindings.js +1 -1
- package/dist/website_sale/.kosh/schema.d.ts +642 -17
- package/dist/website_sale/i18n/bn.d.ts +2 -0
- package/dist/website_sale/i18n/bn.js +132 -0
- package/dist/website_sale/index.js +83 -1
- package/dist/website_sale/module.d.ts +18705 -5550
- package/dist/website_sale/module.js +32 -10
- package/dist/website_sale/shop.js +22 -9
- package/dist/website_sale_stock/.kosh/bindings.js +1 -1
- package/dist/website_sale_stock/.kosh/schema.d.ts +737 -18
- package/dist/website_sale_stock/i18n/bn.d.ts +2 -0
- package/dist/website_sale_stock/i18n/bn.js +4 -0
- package/dist/website_sale_stock/index.js +2 -0
- package/dist/website_sale_stock/module.d.ts +10 -24997
- package/dist/website_sale_stock/module.js +7 -3
- package/package.json +36 -8
- package/dist/mrp/index.d.ts +0 -3
- package/dist/mrp/index.js +0 -393
- package/dist/mrp/module.js +0 -757
- package/dist/mrp_account/index.d.ts +0 -3
- package/dist/mrp_account/index.js +0 -22
- /package/dist/{mrp → approvals_purchase}/.kosh/bindings.d.ts +0 -0
- /package/dist/{mrp_account → indent}/.kosh/bindings.d.ts +0 -0
|
@@ -5,18 +5,20 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
|
|
|
5
5
|
* assistance, and saves with compare-and-set (a record changed by someone else since it was opened is not
|
|
6
6
|
* overwritten: the user reloads). Conditions only decide display; the server re-checks every write.
|
|
7
7
|
*/
|
|
8
|
-
import { evaluate, holds, } from '../../views/index.js';
|
|
8
|
+
import { evaluate, holds, resolveRecord, } from '../../views/index.js';
|
|
9
9
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
|
10
|
-
import { useBlocker, useParams } from '@tanstack/react-router';
|
|
11
|
-
import { ArrowLeft, Check, ChevronLeft, ChevronRight, CircleDot, MoreHorizontal, PanelRight, Plus, Trash2, } from 'lucide-react';
|
|
10
|
+
import { useBlocker, useNavigate, useParams } from '@tanstack/react-router';
|
|
11
|
+
import { ArrowLeft, Check, ChevronLeft, ChevronRight, CircleDot, Copy, MoreHorizontal, PanelRight, Plus, Trash2, } from 'lucide-react';
|
|
12
12
|
import { useEffect, useId, useMemo, useRef, useState } from 'react';
|
|
13
13
|
import { useTranslation } from 'react-i18next';
|
|
14
14
|
import { ApiError, NetworkError, } from '../api.js';
|
|
15
|
+
import { Explain } from '../components/Explain.js';
|
|
15
16
|
import { Alert, Button, Dialog, Label, Menu, MenuContent, MenuItem, MenuTrigger, Spinner, Tabs, TabsContent, TabsList, TabsTrigger, } from '../components/primitives.js';
|
|
16
17
|
import { useKosh } from '../context.js';
|
|
17
18
|
import { useDesign } from '../design.js';
|
|
18
19
|
import { cn } from '../lib/cn.js';
|
|
19
20
|
import { useLiveRecord } from '../live.js';
|
|
21
|
+
import { setPrefill } from '../prefill.js';
|
|
20
22
|
import { useToast } from '../shell/toast.js';
|
|
21
23
|
import { StatsRow } from './StatsRow.js';
|
|
22
24
|
import { StatusChip } from './StatusChip.js';
|
|
@@ -188,6 +190,7 @@ export function FormView({ served, recordId, defaults, onSaved, onBack, crumbs,
|
|
|
188
190
|
const design = useDesign();
|
|
189
191
|
const toast = useToast();
|
|
190
192
|
const queryClient = useQueryClient();
|
|
193
|
+
const navigateTo = useNavigate();
|
|
191
194
|
const formId = useId();
|
|
192
195
|
const [railOpen, setRailOpen] = useRail();
|
|
193
196
|
const route = useParams({ strict: false });
|
|
@@ -380,6 +383,16 @@ export function FormView({ served, recordId, defaults, onSaved, onBack, crumbs,
|
|
|
380
383
|
},
|
|
381
384
|
onError: fail,
|
|
382
385
|
});
|
|
386
|
+
// Duplicate (RFC 0023 R1): a copy made by the server as the user; the form opens it.
|
|
387
|
+
const duplicate = useMutation({
|
|
388
|
+
mutationFn: () => api.call('POST', `/api/v1/models/${model}/${String(recordId)}/duplicate`, {}),
|
|
389
|
+
onSuccess: async (copy) => {
|
|
390
|
+
await queryClient.invalidateQueries({ queryKey: ['list', model] });
|
|
391
|
+
toast({ title: t('views.duplicated') });
|
|
392
|
+
onSaved(copy.id);
|
|
393
|
+
},
|
|
394
|
+
onError: fail,
|
|
395
|
+
});
|
|
383
396
|
const remove = useMutation({
|
|
384
397
|
mutationFn: () => api.remove(model, recordId),
|
|
385
398
|
onSuccess: async () => {
|
|
@@ -447,7 +460,7 @@ export function FormView({ served, recordId, defaults, onSaved, onBack, crumbs,
|
|
|
447
460
|
const readonly = locked || field.readonly || holds(node.readonlyWhen, values, env);
|
|
448
461
|
const id = `${formId}-${node.id}`;
|
|
449
462
|
const invalid = problem?.problem.detail.includes(node.field) === true;
|
|
450
|
-
return (_jsxs("div", { className: cn('grid gap-1', (field.kind === 'text' || field.kind === 'html') && 'col-span-full'), children: [_jsxs(Label, { htmlFor: id, children: [node.label ?? field.label, (field.required || holds(node.requiredWhen, values, env)) && !readonly ? (_jsxs("span", { "aria-hidden": true, className: "text-danger", children: [' ', "*"] })) : null, recordId === 'new' && proposed?.includes(node.field) === true ? (_jsx("span", { className: "ms-2 rounded bg-accent px-1.5 py-0.5 text-[10px] font-medium text-accent-foreground", children: t('views.proposed') })) : null] }), _jsx("div", { className: "min-h-9 py-1.5 text-sm", children: _jsx(Widget, { id: id, node: node, field: field, value: values[node.field], record: values, model: model, readonly: readonly, onChange: (v) => change(node.field, v), invalid: invalid }) }), (node.help ?? field.help) === undefined ? null : (_jsx("p", { className: "text-xs text-muted-foreground", children: node.help ?? field.help }))] }, node.id));
|
|
463
|
+
return (_jsxs("div", { className: cn('grid gap-1', (field.kind === 'text' || field.kind === 'html') && 'col-span-full'), children: [_jsxs(Label, { htmlFor: id, children: [_jsx(Explain, { model: model, target: { field: node.field }, children: node.label ?? field.label }), (field.required || holds(node.requiredWhen, values, env)) && !readonly ? (_jsxs("span", { "aria-hidden": true, className: "text-danger", children: [' ', "*"] })) : null, recordId === 'new' && proposed?.includes(node.field) === true ? (_jsx("span", { className: "ms-2 rounded bg-accent px-1.5 py-0.5 text-[10px] font-medium text-accent-foreground", children: t('views.proposed') })) : null] }), _jsx("div", { className: "min-h-9 py-1.5 text-sm", children: _jsx(Widget, { id: id, node: node, field: field, value: values[node.field], record: values, model: model, readonly: readonly, onChange: (v) => change(node.field, v), invalid: invalid }) }), (node.help ?? field.help) === undefined ? null : (_jsx("p", { className: "text-xs text-muted-foreground", children: node.help ?? field.help }))] }, node.id));
|
|
451
464
|
};
|
|
452
465
|
const renderNodes = (nodes) => nodes.map((node) => {
|
|
453
466
|
switch (node.kind) {
|
|
@@ -518,9 +531,27 @@ export function FormView({ served, recordId, defaults, onSaved, onBack, crumbs,
|
|
|
518
531
|
(v === null || v === undefined || v === '' || (Array.isArray(v) && v.length === 0)));
|
|
519
532
|
})
|
|
520
533
|
.map((n) => n.field);
|
|
534
|
+
// A button that opens a new record of another model, filled from this one (RFC 0028 §3.4).
|
|
535
|
+
const openNew = (open) => {
|
|
536
|
+
void api.routes().then((routes) => {
|
|
537
|
+
const route = routes[open.model];
|
|
538
|
+
const action = open.action ?? route?.action;
|
|
539
|
+
if (action === undefined || route?.app === undefined)
|
|
540
|
+
return;
|
|
541
|
+
const filled = resolveRecord(open.values, values);
|
|
542
|
+
setPrefill(action, { values: filled, proposed: [] });
|
|
543
|
+
void navigateTo({
|
|
544
|
+
to: '/$app/a/$action/$id',
|
|
545
|
+
params: { app: route.app, action, id: 'new' },
|
|
546
|
+
});
|
|
547
|
+
});
|
|
548
|
+
};
|
|
521
549
|
// RFC 0022 §3.5: the record's document templates as a Print menu, when reporting's web is registered.
|
|
522
550
|
const Print = registry.component('reporting.Documents');
|
|
551
|
+
const Send = registry.component('mail.Send');
|
|
523
552
|
const buttons = view.header.buttons.filter((b) => {
|
|
553
|
+
if (b.open !== undefined)
|
|
554
|
+
return !isNew && visible(b.visibleWhen);
|
|
524
555
|
const spec = served.transitions.find((tr) => tr.name === b.transition);
|
|
525
556
|
return (!isNew &&
|
|
526
557
|
spec !== undefined &&
|
|
@@ -600,7 +631,7 @@ export function FormView({ served, recordId, defaults, onSaved, onBack, crumbs,
|
|
|
600
631
|
e.preventDefault();
|
|
601
632
|
if (dirty && !locked)
|
|
602
633
|
save.mutate();
|
|
603
|
-
}, children: [_jsxs("div", { className: "sticky top-12 z-20 -mx-4 flex flex-wrap items-center justify-between gap-2 border-b bg-background/95 px-4 py-2 backdrop-blur", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx(Button, { type: "button", variant: "ghost", size: "icon", "aria-label": t('views.back'), "data-kosh-back": true, onClick: onBack, children: _jsx(ArrowLeft, { className: "rtl:-scale-x-100", "aria-hidden": true }) }), _jsxs("div", { className: "min-w-0", children: [_jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-2.5", children: [_jsx("h1", { className: "truncate text-xl font-semibold", children: title }), statusbar === undefined || fields[statusbar] === undefined || isNew ? null : (_jsx(StatusChip, { field: fields[statusbar], value: state, transitions: served.transitions.filter((tr) => tr.field === statusbar) })), locked && !isNew ? (_jsx("span", { className: "rounded-full border px-2 py-0.5 text-xs text-muted-foreground", children: t('views.readonly') })) : null] }), facts.length === 0 ? null : (_jsx("p", { className: "mt-0.5 flex flex-wrap items-center gap-x-2 text-sm text-muted-foreground", children: facts.map((node, i) => {
|
|
634
|
+
}, children: [_jsxs("div", { className: "sticky top-12 z-20 -mx-4 flex flex-wrap items-center justify-between gap-2 border-b bg-background/95 px-4 py-2 backdrop-blur", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx(Button, { type: "button", variant: "ghost", size: "icon", "aria-label": t('views.back'), "data-kosh-back": true, onClick: onBack, children: _jsx(ArrowLeft, { className: "rtl:-scale-x-100", "aria-hidden": true }) }), _jsxs("div", { className: "min-w-0", children: [_jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-2.5", children: [_jsx("h1", { className: "truncate text-xl font-semibold", children: _jsx(Explain, { model: model, target: { model: true }, children: title }) }), statusbar === undefined || fields[statusbar] === undefined || isNew ? null : (_jsx(StatusChip, { field: fields[statusbar], value: state, transitions: served.transitions.filter((tr) => tr.field === statusbar) })), locked && !isNew ? (_jsx("span", { className: "rounded-full border px-2 py-0.5 text-xs text-muted-foreground", children: t('views.readonly') })) : null] }), facts.length === 0 ? null : (_jsx("p", { className: "mt-0.5 flex flex-wrap items-center gap-x-2 text-sm text-muted-foreground", children: facts.map((node, i) => {
|
|
604
635
|
const field = fields[node.field];
|
|
605
636
|
const Widget = registry.widget(node, field);
|
|
606
637
|
return (_jsxs("span", { className: "flex items-center gap-2", title: field.label, children: [i === 0 ? null : _jsx("span", { "aria-hidden": true, children: "\u00B7" }), _jsxs("span", { className: "sr-only", children: [field.label, ": "] }), _jsx(Widget, { id: `${formId}-fact-${node.id}`, node: node, field: field, value: values[node.field], record: values, readonly: true })] }, node.id));
|
|
@@ -614,7 +645,7 @@ export function FormView({ served, recordId, defaults, onSaved, onBack, crumbs,
|
|
|
614
645
|
setChanges({});
|
|
615
646
|
setLines(new Map());
|
|
616
647
|
setProblem(null);
|
|
617
|
-
}, children: t('views.discard') }), _jsx(Button, { type: "submit", variant: "primary", busy: save.isPending, "data-kosh-save": true, children: t('views.save') })] })) : null, _jsx(Button, { type: "button", variant: "ghost", size: "icon", className: "hidden xl:inline-flex", "aria-pressed": railOpen, "aria-label": railOpen ? t('views.hidePanel') : t('views.showPanel'), title: railOpen ? t('views.hidePanel') : t('views.showPanel'), onClick: () => setRailOpen(!railOpen), children: _jsx(PanelRight, { className: "rtl:-scale-x-100", "aria-hidden": true }) }), !isNew && served.operations.unlink ? (_jsxs(Menu, { children: [_jsx(MenuTrigger, { asChild: true, children: _jsx(Button, { type: "button", variant: "ghost", size: "icon", "aria-label":
|
|
648
|
+
}, children: t('views.discard') }), _jsx(Button, { type: "submit", variant: "primary", busy: save.isPending, "data-kosh-save": true, children: t('views.save') })] })) : null, _jsx(Button, { type: "button", variant: "ghost", size: "icon", className: "hidden xl:inline-flex", "aria-pressed": railOpen, "aria-label": railOpen ? t('views.hidePanel') : t('views.showPanel'), title: railOpen ? t('views.hidePanel') : t('views.showPanel'), onClick: () => setRailOpen(!railOpen), children: _jsx(PanelRight, { className: "rtl:-scale-x-100", "aria-hidden": true }) }), !isNew && (served.operations.unlink || served.operations.create) ? (_jsxs(Menu, { children: [_jsx(MenuTrigger, { asChild: true, children: _jsx(Button, { type: "button", variant: "ghost", size: "icon", "aria-label": t('views.actions'), children: _jsx(MoreHorizontal, { "aria-hidden": true }) }) }), _jsxs(MenuContent, { children: [served.operations.create ? (_jsxs(MenuItem, { disabled: duplicate.isPending, onSelect: () => duplicate.mutate(), children: [_jsx(Copy, { className: "size-4", "aria-hidden": true }), t('views.duplicate')] })) : null, served.operations.unlink ? (_jsxs(MenuItem, { onSelect: () => setDeleting(true), children: [_jsx(Trash2, { className: "size-4", "aria-hidden": true }), t('views.delete')] })) : null] })] })) : null] })] }), _jsxs("div", { className: cn('grid gap-4', showRail && 'xl:grid-cols-[minmax(0,1fr)_20rem] xl:items-start'), children: [_jsxs("div", { className: "grid min-w-0 content-start gap-4", children: [live.changedByOther ? (_jsx(Alert, { tone: "warning", action: _jsx(Button, { type: "button", size: "sm", onClick: () => {
|
|
618
649
|
setChanges({});
|
|
619
650
|
setLines(new Map());
|
|
620
651
|
live.dismiss();
|
|
@@ -625,12 +656,18 @@ export function FormView({ served, recordId, defaults, onSaved, onBack, crumbs,
|
|
|
625
656
|
void loaded.refetch();
|
|
626
657
|
}, children: t('views.reload') })) : undefined, children: problem.kind === 'stale-record' ? t('views.stale') : problem.message })), warnings.map((w) => (_jsx(Alert, { tone: "info", children: w }, w))), nextStep === undefined || nextButton === undefined || locked ? null : (_jsx(Alert, { tone: nextStep.allowed ? 'info' : 'warning', children: nextStep.allowed
|
|
627
658
|
? t('views.nextStep.ready', { step: nextButton.label ?? nextButton.transition })
|
|
628
|
-
: `${t('views.nextStep.before', { step: nextButton.label ?? nextButton.transition })} ${nextStep.message ?? ''}`.trim() })), buttons.length === 0 &&
|
|
629
|
-
|
|
630
|
-
|
|
659
|
+
: `${t('views.nextStep.before', { step: nextButton.label ?? nextButton.transition })} ${nextStep.message ?? ''}`.trim() })), buttons.length === 0 &&
|
|
660
|
+
(isNew || (Print === undefined && Send === undefined)) ? null : (_jsxs("div", { role: "toolbar", "aria-label": t('views.recordActions'), className: "flex flex-wrap gap-2", children: [isNew || Print === undefined ? null : (_jsx(Print, { node: { kind: 'component', id: 'print', component: 'reporting.Documents' }, record: record ?? null, model: model, served: served, api: api, version: loaded.data?.etag ?? null, reload: () => void loaded.refetch() })), isNew || Send === undefined ? null : (_jsx(Send, { node: { kind: 'component', id: 'send', component: 'mail.Send' }, record: record ?? null, model: model, served: served, api: api, version: loaded.data?.etag ?? null, reload: () => void loaded.refetch() })), _jsx("div", { className: "contents", children: buttons.map((b, i) => (_jsx(Explain, { model: model, asChild: true, target: b.transition === undefined ? { action: b.id } : { transition: b.transition }, children: _jsx(Button, { type: "button", size: "sm", variant: b.primary === true ||
|
|
661
|
+
(i === 0 && !buttons.some((x) => x.primary === true))
|
|
662
|
+
? 'primary'
|
|
663
|
+
: 'secondary', busy: transition.isPending && transition.variables === b.transition, onClick: () => b.open !== undefined
|
|
664
|
+
? openNew(b.open)
|
|
665
|
+
: b.confirm === undefined
|
|
666
|
+
? transition.mutate(b.transition ?? '')
|
|
667
|
+
: setConfirming(b), children: b.label ?? b.transition ?? b.id }) }, b.id))) })] })), sections.map((section) => section.nodes[0]?.kind === 'stats' ? (_jsx("div", { className: "grid", children: renderNodes(section.nodes) }, section.key)) : (_jsx("section", { className: "rounded-lg border bg-surface p-5", children: _jsx("div", { className: "grid gap-x-6 gap-y-4 sm:grid-cols-2", children: renderNodes(section.nodes) }) }, section.key))), showRail ? null : rail] }), showRail ? (_jsx("aside", { "aria-label": t('views.recordPanel'),
|
|
631
668
|
// Beside the record when wide; under it otherwise (one grid column).
|
|
632
669
|
className: "grid content-start gap-4 xl:sticky xl:top-28", children: rail })) : null] })] }), _jsx(Dialog, { open: confirming !== null, onOpenChange: (open) => !open && setConfirming(null), title: confirming?.label ?? confirming?.transition ?? '', description: confirming?.confirm ?? '', footer: _jsxs(_Fragment, { children: [_jsx(Button, { onClick: () => setConfirming(null), children: t('views.no') }), _jsx(Button, { variant: "primary", onClick: () => {
|
|
633
|
-
if (confirming !==
|
|
670
|
+
if (confirming?.transition !== undefined)
|
|
634
671
|
transition.mutate(confirming.transition);
|
|
635
672
|
setConfirming(null);
|
|
636
673
|
}, children: t('views.yes') })] }) }), _jsx(Dialog, { open: deleting, onOpenChange: setDeleting, title: t('views.confirmDelete'), footer: _jsxs(_Fragment, { children: [_jsx(Button, { onClick: () => setDeleting(false), children: t('views.no') }), _jsx(Button, { variant: "danger", busy: remove.isPending, onClick: () => remove.mutate(), children: t('views.delete') })] }) })] }));
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The list renderer (RFC 0007 §5, RFC 0010 §3.5): server-side order, paging and totals, grouping (one level,
|
|
3
|
+
* expandable), inline edit of `inlineEdit` columns with compare-and-set, row virtualization (TanStack Virtual) so
|
|
4
|
+
* large pages scroll smoothly, selection with a bulk bar (archive and delete with Undo, export, the transitions every
|
|
5
|
+
* selected record allows), export to CSV and Excel, a column chooser and density remembered per user, skeleton rows
|
|
6
|
+
* while loading and an empty state that offers the next step. Rows are a semantic table: keyboard users move with
|
|
7
|
+
* Tab and open with Enter. Every bulk action is one request per record to the existing, permission-checked routes.
|
|
8
|
+
*/
|
|
1
9
|
import { type ReactElement } from 'react';
|
|
2
10
|
import type { ViewProps } from '../registry.js';
|
|
3
11
|
/** The default list renderer. */
|
|
@@ -15,6 +15,7 @@ import { Archive, ArrowDown, ArrowUp, ChevronRight, Columns3, Download, Inbox, P
|
|
|
15
15
|
import { useEffect, useMemo, useRef, useState, } from 'react';
|
|
16
16
|
import { useTranslation } from 'react-i18next';
|
|
17
17
|
import { ApiError } from '../api.js';
|
|
18
|
+
import { Explain } from '../components/Explain.js';
|
|
18
19
|
import { Alert, Button, Checkbox, Dialog, EmptyState, Menu, MenuCheckboxItem, MenuContent, MenuItem, MenuLabel, MenuSeparator, MenuTrigger, Skeleton, } from '../components/primitives.js';
|
|
19
20
|
import { useKosh } from '../context.js';
|
|
20
21
|
import { useDesign } from '../design.js';
|
|
@@ -603,7 +604,7 @@ function Rows({ props, where, columns, fields, offset, limit, height, selection,
|
|
|
603
604
|
? 'ascending'
|
|
604
605
|
: direction === 'desc'
|
|
605
606
|
? 'descending'
|
|
606
|
-
: 'none', className: cn('relative px-3 py-2 text-start font-medium text-muted-foreground', pinnedClass(node.id)), children: [_jsxs("button", { type: "button", className: "inline-flex items-center gap-1", onClick: () => toggleOrder(node.field), children: [_jsx(table.FlexRender, { header: header }), direction === 'asc' ? (_jsx(ArrowUp, { className: "size-3", "aria-hidden": true })) : direction === 'desc' ? (_jsx(ArrowDown, { className: "size-3", "aria-hidden": true })) : null] }), _jsx(ResizeHandle, { label: t('views.resize', {
|
|
607
|
+
: 'none', className: cn('relative px-3 py-2 text-start font-medium text-muted-foreground', pinnedClass(node.id)), children: [_jsx(Explain, { model: model, target: { field: node.field }, asChild: true, children: _jsxs("button", { type: "button", className: "inline-flex items-center gap-1", onClick: () => toggleOrder(node.field), children: [_jsx(table.FlexRender, { header: header }), direction === 'asc' ? (_jsx(ArrowUp, { className: "size-3", "aria-hidden": true })) : direction === 'desc' ? (_jsx(ArrowDown, { className: "size-3", "aria-hidden": true })) : null] }) }), _jsx(ResizeHandle, { label: t('views.resize', {
|
|
607
608
|
column: node.label ?? fields[node.field]?.label ?? node.field,
|
|
608
609
|
}), width: widths[node.id] ?? null, onResize: (w) => setWidth(node.id, w), onReset: () => setWidth(node.id, null) })] }, header.id));
|
|
609
610
|
})] }, group.id))) }), _jsxs("tbody", { children: [top > 0 ? (_jsx("tr", { "aria-hidden": true, children: _jsx("td", { style: { height: top }, colSpan: span }) })) : null, virtual.map((v) => {
|
|
@@ -759,7 +760,7 @@ export function totalLabel(word, label) {
|
|
|
759
760
|
: `${word} ${label}`;
|
|
760
761
|
}
|
|
761
762
|
export function ListView(props) {
|
|
762
|
-
const { api, uid } = useKosh();
|
|
763
|
+
const { api, uid, registry } = useKosh();
|
|
763
764
|
const { t } = useTranslation();
|
|
764
765
|
const toast = useToast();
|
|
765
766
|
const queryClient = useQueryClient();
|
|
@@ -934,7 +935,13 @@ export function ListView(props) {
|
|
|
934
935
|
}),
|
|
935
936
|
});
|
|
936
937
|
// Selected rows: a floating bar at the bottom of the screen (RFC 0018 §4.3); the list's own toolbar stays put.
|
|
937
|
-
const floating = ids.length > 0 ? (_jsxs("div", { role: "toolbar", "aria-label": t('views.selected', { count: ids.length }), "data-kosh-selection-bar": true, className: "fixed inset-x-0 bottom-4 z-30 mx-auto flex w-fit max-w-[calc(100vw-2rem)] flex-wrap items-center gap-2 rounded-xl border bg-surface px-3 py-2 text-sm shadow-lg", children: [_jsx("span", { className: "font-medium", children: t('views.selected', { count: ids.length }) }), _jsx(Button, { size: "sm", variant: "ghost", "aria-label": t('views.clearSelection'), onClick: () => setSelected(new Set()), children: _jsx(X, { "aria-hidden": true }) }), _jsx("span", { className: "flex-1" }), transitions.map((tr) => (_jsx(Button, { size: "sm", busy: transition.isPending && transition.variables?.name === tr.name, onClick: () => transition.mutate({ name: tr.name, what: ids }), children: tr.name.charAt(0).toUpperCase() + tr.name.slice(1).replace(/_/g, ' ') }, tr.name))),
|
|
938
|
+
const floating = ids.length > 0 ? (_jsxs("div", { role: "toolbar", "aria-label": t('views.selected', { count: ids.length }), "data-kosh-selection-bar": true, className: "fixed inset-x-0 bottom-4 z-30 mx-auto flex w-fit max-w-[calc(100vw-2rem)] flex-wrap items-center gap-2 rounded-xl border bg-surface px-3 py-2 text-sm shadow-lg", children: [_jsx("span", { className: "font-medium", children: t('views.selected', { count: ids.length }) }), _jsx(Button, { size: "sm", variant: "ghost", "aria-label": t('views.clearSelection'), onClick: () => setSelected(new Set()), children: _jsx(X, { "aria-hidden": true }) }), _jsx("span", { className: "flex-1" }), transitions.map((tr) => (_jsx(Button, { size: "sm", busy: transition.isPending && transition.variables?.name === tr.name, onClick: () => transition.mutate({ name: tr.name, what: ids }), children: tr.name.charAt(0).toUpperCase() + tr.name.slice(1).replace(/_/g, ' ') }, tr.name))), registry.selectionActions().map((Action, i) => (_jsx(Action
|
|
939
|
+
// biome-ignore lint/suspicious/noArrayIndexKey: registered once, in a fixed order
|
|
940
|
+
, { api: api, model: model, ids: ids, done: (message, tone) => {
|
|
941
|
+
setSelected(new Set());
|
|
942
|
+
void refresh();
|
|
943
|
+
toast({ title: message, tone: tone ?? 'info' });
|
|
944
|
+
} }, i))), archivable ? (_jsxs(Button, { size: "sm", busy: archive.isPending, onClick: () => archive.mutate(ids), children: [_jsx(Archive, { "aria-hidden": true }), t('views.archive')] })) : null, served.operations.unlink ? (_jsxs(Button, { size: "sm", variant: "danger", onClick: () => setConfirmingDelete(true), children: [_jsx(Trash2, { "aria-hidden": true }), t('views.delete')] })) : null, canExport ? (_jsxs(Button, { size: "sm", busy: exportAs.isPending, onClick: () => exportAs.mutate('csv'), children: [_jsx(Download, { "aria-hidden": true }), t('views.export')] })) : null] })) : null;
|
|
938
945
|
const toolbar = (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2 border-b px-3 py-1.5 text-sm", children: [_jsx("span", { className: "text-muted-foreground", children: count === null ? (_jsx(Skeleton, { className: "inline-block h-4 w-20" })) : (t('views.records', { count })) }), _jsx("span", { className: "flex-1" }), design.active ? (_jsxs(Button, { size: "sm", variant: "ghost", className: "border border-dashed border-primary/50 text-primary", onClick: () => design.choose({
|
|
939
946
|
kind: 'list',
|
|
940
947
|
view: view.id,
|
|
@@ -7,6 +7,7 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
|
|
|
7
7
|
import { holds, resolveRecord, } from '../../views/index.js';
|
|
8
8
|
import { useQueries, useQuery } from '@tanstack/react-query';
|
|
9
9
|
import { useNavigate } from '@tanstack/react-router';
|
|
10
|
+
import { Explain } from '../components/Explain.js';
|
|
10
11
|
import { useKosh } from '../context.js';
|
|
11
12
|
import { cn } from '../lib/cn.js';
|
|
12
13
|
// The badge's tones (primitives), on the figure only.
|
|
@@ -81,7 +82,7 @@ export function StatsRow({ node, values, env, version, }) {
|
|
|
81
82
|
const result = results[i];
|
|
82
83
|
const value = textOf(result?.data, format);
|
|
83
84
|
const clickable = routes.data?.[tile.model]?.app !== undefined;
|
|
84
|
-
const body = (_jsxs(_Fragment, { children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground", children: tile.label }), _jsxs("span", { className: cn('text-xl font-semibold tabular-nums leading-tight', TONES[tile.tone ?? 'neutral']), children: [result?.isPending === true ? '…' : value.text, value.currency === undefined ? null : (_jsx("span", { className: "ms-1 text-xs font-normal text-muted-foreground", children: value.currency }))] })] }));
|
|
85
|
+
const body = (_jsxs(_Fragment, { children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground", children: _jsx(Explain, { model: tile.model, focusable: false, target: { action: tile.id, domain: wheres[i] }, children: tile.label }) }), _jsxs("span", { className: cn('text-xl font-semibold tabular-nums leading-tight', TONES[tile.tone ?? 'neutral']), children: [result?.isPending === true ? '…' : value.text, value.currency === undefined ? null : (_jsx("span", { className: "ms-1 text-xs font-normal text-muted-foreground", children: value.currency }))] })] }));
|
|
85
86
|
const className = 'grid gap-0.5 rounded-lg border bg-surface px-3 py-2 text-start transition-colors';
|
|
86
87
|
return clickable ? (_jsx("button", { type: "button", className: cn(className, 'hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring'), onClick: () => open(i), children: body }, tile.id)) : (_jsx("div", { className: className, children: body }, tile.id));
|
|
87
88
|
}) }));
|
package/dist/views/extend.js
CHANGED
|
@@ -153,6 +153,18 @@ function apply(view, op) {
|
|
|
153
153
|
break;
|
|
154
154
|
}
|
|
155
155
|
case 'form': {
|
|
156
|
+
// `append: 'header'` adds buttons to the header, which may have none yet (RFC 0028 §3.4).
|
|
157
|
+
if ('append' in op && op.append === 'header') {
|
|
158
|
+
next = {
|
|
159
|
+
...view,
|
|
160
|
+
header: {
|
|
161
|
+
...view.header,
|
|
162
|
+
buttons: [...view.header.buttons, ...op.nodes],
|
|
163
|
+
},
|
|
164
|
+
};
|
|
165
|
+
done = true;
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
156
168
|
const [buttons, inHeader] = applyIn(view.header.buttons, op);
|
|
157
169
|
if (inHeader)
|
|
158
170
|
[next, done] = [
|
package/dist/views/types.d.ts
CHANGED
|
@@ -99,7 +99,18 @@ export type FormNode = FieldNode | GroupNode | NotebookNode | LinesNode | Compon
|
|
|
99
99
|
export interface ButtonNode {
|
|
100
100
|
readonly kind: 'button';
|
|
101
101
|
readonly id: string;
|
|
102
|
-
|
|
102
|
+
/** The transition it runs (a button runs a transition, or opens a new record: `open`). */
|
|
103
|
+
readonly transition?: string;
|
|
104
|
+
/**
|
|
105
|
+
* Opens a new record of another model, filled from this one (RFC 0028 §3.4: "New quotation" on a deal): `values`
|
|
106
|
+
* may refer to the record (`{ $record: 'partner' }`); `action` defaults to the model's own. Saved like any new
|
|
107
|
+
* record: the server checks the rights then.
|
|
108
|
+
*/
|
|
109
|
+
readonly open?: {
|
|
110
|
+
readonly model: string;
|
|
111
|
+
readonly action?: string;
|
|
112
|
+
readonly values: Readonly<Record<string, unknown>>;
|
|
113
|
+
};
|
|
103
114
|
readonly label?: string;
|
|
104
115
|
readonly primary?: boolean;
|
|
105
116
|
readonly visibleWhen?: Condition;
|
|
@@ -213,7 +224,7 @@ export interface CalendarView extends ViewBase {
|
|
|
213
224
|
readonly title: string;
|
|
214
225
|
/** A field whose value colours the events. */
|
|
215
226
|
readonly color?: string;
|
|
216
|
-
readonly mode?: 'month' | 'week';
|
|
227
|
+
readonly mode?: 'month' | 'week' | 'day';
|
|
217
228
|
}
|
|
218
229
|
/** Records as bars on a timeline. */
|
|
219
230
|
export interface GanttView extends ViewBase {
|
package/dist/views/validate.js
CHANGED
|
@@ -71,7 +71,14 @@ export function validateView(view, models) {
|
|
|
71
71
|
problems.push(`stat '${node.id}': '$record' names no field '${key}' of ${view.model}`);
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
|
-
if (node.kind === 'button' &&
|
|
74
|
+
if (node.kind === 'button' && node.open !== undefined) {
|
|
75
|
+
if (models(node.open.model) === undefined)
|
|
76
|
+
problems.push(`button '${node.id}': opens unknown model ${node.open.model}`);
|
|
77
|
+
for (const key of recordKeys(node.open.values))
|
|
78
|
+
if (!info.fields.has(key))
|
|
79
|
+
problems.push(`button '${node.id}': '$record' names no field '${key}' of ${view.model}`);
|
|
80
|
+
}
|
|
81
|
+
else if (node.kind === 'button' && !info.transitions.includes(node.transition ?? ''))
|
|
75
82
|
problems.push(`unknown transition '${node.transition}' (has ${info.transitions.join(', ') || 'none'})`);
|
|
76
83
|
}
|
|
77
84
|
if (view.type === 'form')
|
|
@@ -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: 5f477c497bbd660c
|
|
2
2
|
// Bindings of module `website`: 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';
|
|
@@ -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: 5f477c497bbd660c
|
|
2
2
|
// Schema view of module `website` (RFC 0002 §7.7): the models it owns or depends on, with the extensions it can see.
|
|
3
3
|
import type { F } from '../../server/orm.js';
|
|
4
4
|
|
|
@@ -624,6 +624,7 @@ export interface ResPartner {
|
|
|
624
624
|
readonly parent: F.Many2one<'res.partner'>;
|
|
625
625
|
readonly contacts: F.One2many<'res.partner', { readonly required: true }>;
|
|
626
626
|
readonly email: F.Char;
|
|
627
|
+
readonly lang: F.Selection<'en' | 'bn'>;
|
|
627
628
|
readonly phone: F.Char;
|
|
628
629
|
readonly mobile: F.Char;
|
|
629
630
|
readonly website: F.Char;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/** Bangla for the module's labels, keyed by their English text (RFC 0023 §3.1; `pnpm i18n:extract`). */
|
|
2
|
+
export const bn = {
|
|
3
|
+
'/ for the home page, /about, /contact': 'হোম পাতার জন্য /, /about, /contact',
|
|
4
|
+
'A form block names its form.': 'ফর্ম ব্লকে তার ফর্মের নাম দিতে হবে।',
|
|
5
|
+
'A key is lower-case letters, digits and dashes, e.g. contact-us.': 'কী-তে ছোট হাতের অক্ষর, অঙ্ক ও ড্যাশ থাকে, যেমন contact-us।',
|
|
6
|
+
'A key is lower-case letters, digits and dashes, e.g. padma-traders.': 'কী-তে ছোট হাতের অক্ষর, অঙ্ক ও ড্যাশ থাকে, যেমন padma-traders।',
|
|
7
|
+
'A link is a path on the site (/contact) or an http(s) address.': 'লিংক হলো সাইটের একটি পাথ (/contact) বা একটি http(s) ঠিকানা।',
|
|
8
|
+
'A page translates another page of the same site.': 'একটি পাতা একই সাইটের অন্য পাতার অনুবাদ হতে পারে।',
|
|
9
|
+
'A path starts with / and has letters, digits, dashes, dots or underscores: /about-us.': 'পাথ / দিয়ে শুরু হয় এবং এতে অক্ষর, অঙ্ক, ড্যাশ, ডট বা আন্ডারস্কোর থাকে: /about-us।',
|
|
10
|
+
'A website form creates contacts, or what an installed app allows (a lead with Pipeline).': 'ওয়েবসাইট ফর্ম যোগাযোগ তৈরি করে, অথবা ইনস্টল করা অ্যাপ যা অনুমতি দেয় (পাইপলাইন থাকলে একটি লিড)।',
|
|
11
|
+
Active: 'সক্রিয়',
|
|
12
|
+
'An input name is lower-case letters, digits and underscores, starting with a letter.': 'ইনপুটের নামে ছোট হাতের অক্ষর, অঙ্ক ও আন্ডারস্কোর থাকে এবং তা অক্ষর দিয়ে শুরু হয়।',
|
|
13
|
+
'Another form has this key.': 'অন্য একটি ফর্মে এই কী আছে।',
|
|
14
|
+
'Another site has this key.': 'অন্য একটি সাইটে এই কী আছে।',
|
|
15
|
+
Bangla: 'বাংলা',
|
|
16
|
+
Block: 'ব্লক',
|
|
17
|
+
Button: 'বোতাম',
|
|
18
|
+
'Button link': 'বোতামের লিংক',
|
|
19
|
+
'Call to action': 'কল টু অ্যাকশন',
|
|
20
|
+
Company: 'প্রতিষ্ঠান',
|
|
21
|
+
Content: 'বিষয়বস্তু',
|
|
22
|
+
Created: 'তৈরি হয়েছে',
|
|
23
|
+
'Created (id)': 'তৈরি (আইডি)',
|
|
24
|
+
'Created (model)': 'তৈরি (মডেল)',
|
|
25
|
+
'Created At': 'তৈরির সময়',
|
|
26
|
+
'Created By': 'তৈরি করেছেন',
|
|
27
|
+
Creates: 'তৈরি করে',
|
|
28
|
+
Data: 'ডেটা',
|
|
29
|
+
Date: 'তারিখ',
|
|
30
|
+
'Default language': 'ডিফল্ট ভাষা',
|
|
31
|
+
'Display Name': 'প্রদর্শিত নাম',
|
|
32
|
+
Domain: 'ডোমেইন',
|
|
33
|
+
Draft: 'খসড়া',
|
|
34
|
+
Drafts: 'খসড়া',
|
|
35
|
+
'Editor (pages, submissions)': 'সম্পাদক (পাতা, জমা)',
|
|
36
|
+
Email: 'ইমেইল',
|
|
37
|
+
English: 'ইংরেজি',
|
|
38
|
+
Fields: 'ফিল্ড',
|
|
39
|
+
'Fields › Fills': 'ফিল্ড › পূরণ করে',
|
|
40
|
+
'Fields › Input name': 'ফিল্ড › ইনপুটের নাম',
|
|
41
|
+
'Fields › Label': 'ফিল্ড › লেবেল',
|
|
42
|
+
'Fields › Required': 'ফিল্ড › আবশ্যক',
|
|
43
|
+
'Fields › Type': 'ফিল্ড › ধরন',
|
|
44
|
+
Fills: 'পূরণ করে',
|
|
45
|
+
Form: 'ফর্ম',
|
|
46
|
+
'Form field': 'ফর্ম ফিল্ড',
|
|
47
|
+
Forms: 'ফর্ম',
|
|
48
|
+
Hero: 'হিরো',
|
|
49
|
+
ID: 'আইডি',
|
|
50
|
+
Image: 'ছবি',
|
|
51
|
+
'Image URL': 'ছবির URL',
|
|
52
|
+
'In the menu': 'মেনুতে',
|
|
53
|
+
'Input name': 'ইনপুটের নাম',
|
|
54
|
+
Key: 'কী',
|
|
55
|
+
Kind: 'ধরন',
|
|
56
|
+
Label: 'লেবেল',
|
|
57
|
+
Language: 'ভাষা',
|
|
58
|
+
'Long text': 'দীর্ঘ লেখা',
|
|
59
|
+
'Manager (sites, forms, everything)': 'ব্যবস্থাপক (সাইট, ফর্ম, সবকিছু)',
|
|
60
|
+
'Message after sending': 'পাঠানোর পরের বার্তা',
|
|
61
|
+
Name: 'নাম',
|
|
62
|
+
Number: 'সংখ্যা',
|
|
63
|
+
'Only published pages are shown on the public site.': 'পাবলিক ওয়েবসাইটে শুধু প্রকাশিত পাতাগুলো দেখানো হয়।',
|
|
64
|
+
Overview: 'সারসংক্ষেপ',
|
|
65
|
+
Page: 'পাতা',
|
|
66
|
+
Pages: 'পাতা',
|
|
67
|
+
'Pages › In the menu': 'পাতা › মেনুতে',
|
|
68
|
+
'Pages › Language': 'পাতা › ভাষা',
|
|
69
|
+
'Pages › Path': 'পাতা › পাথ',
|
|
70
|
+
'Pages › Summary': 'পাতা › সারাংশ',
|
|
71
|
+
'Pages › Title': 'পাতা › শিরোনাম',
|
|
72
|
+
'Pages published': 'প্রকাশিত পাতা',
|
|
73
|
+
Path: 'পাথ',
|
|
74
|
+
Phone: 'ফোন',
|
|
75
|
+
Publish: 'প্রকাশ করুন',
|
|
76
|
+
Published: 'প্রকাশিত',
|
|
77
|
+
'Published on': 'প্রকাশের তারিখ',
|
|
78
|
+
Received: 'প্রাপ্ত',
|
|
79
|
+
Required: 'আবশ্যক',
|
|
80
|
+
Sequence: 'ক্রম',
|
|
81
|
+
Site: 'সাইট',
|
|
82
|
+
Sites: 'সাইট',
|
|
83
|
+
'Sites editor': 'সাইট সম্পাদক',
|
|
84
|
+
'Sites manager': 'সাইট ব্যবস্থাপক',
|
|
85
|
+
Spam: 'স্প্যাম',
|
|
86
|
+
'Spam caught this month': 'এ মাসে ধরা পড়া স্প্যাম',
|
|
87
|
+
'Spam when a bot filled in the hidden field; received submissions create their record.': 'কোনো বট লুকানো ঘরটি পূরণ করলে এটি স্প্যাম; গৃহীত জমাগুলো থেকে তাদের রেকর্ড তৈরি হয়।',
|
|
88
|
+
State: 'অবস্থা',
|
|
89
|
+
Submission: 'জমা',
|
|
90
|
+
Submissions: 'জমা',
|
|
91
|
+
'Submissions by form': 'ফর্ম অনুযায়ী জমা',
|
|
92
|
+
'Submissions by month': 'মাস অনুযায়ী জমা',
|
|
93
|
+
'Submissions this month': 'এ মাসের জমা',
|
|
94
|
+
Summary: 'সারাংশ',
|
|
95
|
+
Text: 'লেখা',
|
|
96
|
+
'The form already has an input with this name.': 'ফর্মে এই নামের একটি ইনপুট আগে থেকেই আছে।',
|
|
97
|
+
'The kind of value the visitor types in this input.': 'দর্শনার্থী এই ঘরে কোন ধরনের মান লিখবেন।',
|
|
98
|
+
'The language the page is written in.': 'পাতাটি যে ভাষায় লেখা।',
|
|
99
|
+
'The language the site shows when a visitor has not chosen one.': 'দর্শনার্থী কোনো ভাষা বেছে না নিলে ওয়েবসাইট যে ভাষায় দেখায়।',
|
|
100
|
+
'The site already has a page at this path in this language.': 'সাইটে এই ভাষায় এই পাথে একটি পাতা আগে থেকেই আছে।',
|
|
101
|
+
Title: 'শিরোনাম',
|
|
102
|
+
'Translation of': 'যার অনুবাদ',
|
|
103
|
+
Type: 'ধরন',
|
|
104
|
+
Unpublish: 'প্রকাশ বন্ধ করুন',
|
|
105
|
+
'Updated At': 'হালনাগাদের সময়',
|
|
106
|
+
'Updated By': 'হালনাগাদ করেছেন',
|
|
107
|
+
Website: 'ওয়েবসাইট',
|
|
108
|
+
'Website form': 'ওয়েবসাইট ফর্ম',
|
|
109
|
+
'Website form submitted': 'ওয়েবসাইট ফর্ম জমা হয়েছে',
|
|
110
|
+
'Website pages from blocks, forms that create records, a public API': 'ব্লক দিয়ে তৈরি ওয়েবসাইট পাতা, রেকর্ড তৈরি করা ফর্ম, একটি পাবলিক API',
|
|
111
|
+
'What the block shows: a hero banner, text, an image, a call to action or a form.': 'ব্লকটি কী দেখায়: একটি হিরো ব্যানার, লেখা, ছবি, কাজের আহ্বান বা ফর্ম।',
|
|
112
|
+
'Where the public site is served, e.g. www.example.com': 'যেখানে পাবলিক সাইটটি চলে, যেমন www.example.com',
|
|
113
|
+
};
|
package/dist/website/index.js
CHANGED
|
@@ -36,6 +36,42 @@ export function websiteModule(options = {}) {
|
|
|
36
36
|
category: 'Website',
|
|
37
37
|
summary: 'Website pages from blocks, forms that create records, a public API',
|
|
38
38
|
},
|
|
39
|
+
importTemplates: [
|
|
40
|
+
{
|
|
41
|
+
key: 'website_site',
|
|
42
|
+
model: 'website.site',
|
|
43
|
+
label: 'Site',
|
|
44
|
+
columns: [
|
|
45
|
+
{ header: 'Name', field: 'name' },
|
|
46
|
+
{ header: 'Key', field: 'key' },
|
|
47
|
+
{ header: 'Domain', field: 'domain' },
|
|
48
|
+
{ header: 'Default language', field: 'lang' },
|
|
49
|
+
{ header: 'Pages › Path', field: 'pages.path' },
|
|
50
|
+
{ header: 'Pages › Language', field: 'pages.lang' },
|
|
51
|
+
{ header: 'Pages › Title', field: 'pages.title' },
|
|
52
|
+
{ header: 'Pages › Summary', field: 'pages.description' },
|
|
53
|
+
{ header: 'Pages › In the menu', field: 'pages.inMenu' },
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
key: 'website_form',
|
|
58
|
+
model: 'website.form',
|
|
59
|
+
label: 'Website form',
|
|
60
|
+
columns: [
|
|
61
|
+
{ header: 'Name', field: 'name' },
|
|
62
|
+
{ header: 'Key', field: 'key' },
|
|
63
|
+
{ header: 'Creates', field: 'target' },
|
|
64
|
+
{ header: 'Message after sending', field: 'successMessage' },
|
|
65
|
+
{ header: 'Fields › Input name', field: 'fields.name' },
|
|
66
|
+
{ header: 'Fields › Label', field: 'fields.label' },
|
|
67
|
+
{ header: 'Fields › Type', field: 'fields.kind' },
|
|
68
|
+
{ header: 'Fields › Required', field: 'fields.required' },
|
|
69
|
+
{ header: 'Fields › Fills', field: 'fields.targetField' },
|
|
70
|
+
],
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
// Bangla for the labels it serves (RFC 0023 §3.1; `pnpm i18n:extract`).
|
|
74
|
+
i18n: { bn: () => import('./i18n/bn.js') },
|
|
39
75
|
accessLevels: {
|
|
40
76
|
editor: { label: 'Editor (pages, submissions)', groups: ['website.editor'] },
|
|
41
77
|
manager: {
|
package/dist/website/module.d.ts
CHANGED
|
@@ -2612,6 +2612,16 @@ export declare const websiteShutro: import("../server/orm.js").Module<readonly [
|
|
|
2612
2612
|
readonly hasDefault: false;
|
|
2613
2613
|
readonly readonly: false;
|
|
2614
2614
|
}, string>;
|
|
2615
|
+
readonly lang: import("../server/orm.js").SelectionField<"bn" | "en", {
|
|
2616
|
+
readonly required: false;
|
|
2617
|
+
readonly computed: false;
|
|
2618
|
+
readonly inverse: false;
|
|
2619
|
+
readonly sequence: false;
|
|
2620
|
+
readonly computeName: undefined;
|
|
2621
|
+
readonly store: true;
|
|
2622
|
+
readonly hasDefault: false;
|
|
2623
|
+
readonly readonly: false;
|
|
2624
|
+
}>;
|
|
2615
2625
|
readonly phone: import("../server/orm.js").CharField<{
|
|
2616
2626
|
readonly required: false;
|
|
2617
2627
|
readonly computed: false;
|
|
@@ -2833,6 +2843,16 @@ export declare const websiteShutro: import("../server/orm.js").Module<readonly [
|
|
|
2833
2843
|
readonly hasDefault: false;
|
|
2834
2844
|
readonly readonly: false;
|
|
2835
2845
|
}, string>;
|
|
2846
|
+
readonly lang: import("../server/orm.js").SelectionField<"bn" | "en", {
|
|
2847
|
+
readonly required: false;
|
|
2848
|
+
readonly computed: false;
|
|
2849
|
+
readonly inverse: false;
|
|
2850
|
+
readonly sequence: false;
|
|
2851
|
+
readonly computeName: undefined;
|
|
2852
|
+
readonly store: true;
|
|
2853
|
+
readonly hasDefault: false;
|
|
2854
|
+
readonly readonly: false;
|
|
2855
|
+
}>;
|
|
2836
2856
|
readonly phone: import("../server/orm.js").CharField<{
|
|
2837
2857
|
readonly required: false;
|
|
2838
2858
|
readonly computed: false;
|
package/dist/website/module.js
CHANGED
|
@@ -33,7 +33,12 @@ export const WebsiteSite = defineModel('website.site', {
|
|
|
33
33
|
label: 'Domain',
|
|
34
34
|
help: 'Where the public site is served, e.g. www.example.com',
|
|
35
35
|
}),
|
|
36
|
-
lang: f.selection(LANGS, {
|
|
36
|
+
lang: f.selection(LANGS, {
|
|
37
|
+
required: true,
|
|
38
|
+
default: 'en',
|
|
39
|
+
label: 'Default language',
|
|
40
|
+
help: 'The language the site shows when a visitor has not chosen one.',
|
|
41
|
+
}),
|
|
37
42
|
pages: f.one2many('website.page', 'site'),
|
|
38
43
|
},
|
|
39
44
|
sqlConstraints: {
|
|
@@ -59,7 +64,12 @@ export const WebsitePage = defineModel('website.page', {
|
|
|
59
64
|
fields: {
|
|
60
65
|
site: f.many2one('website.site', { required: true, ondelete: 'cascade' }),
|
|
61
66
|
path: f.char({ required: true, default: '/', help: '/ for the home page, /about, /contact' }),
|
|
62
|
-
lang: f.selection(LANGS, {
|
|
67
|
+
lang: f.selection(LANGS, {
|
|
68
|
+
required: true,
|
|
69
|
+
default: 'en',
|
|
70
|
+
label: 'Language',
|
|
71
|
+
help: 'The language the page is written in.',
|
|
72
|
+
}),
|
|
63
73
|
title: f.char({ required: true }),
|
|
64
74
|
/** For search engines and link previews. */
|
|
65
75
|
description: f.text({ label: 'Summary' }),
|
|
@@ -69,6 +79,7 @@ export const WebsitePage = defineModel('website.page', {
|
|
|
69
79
|
translationOf: f.many2one('website.page', { ondelete: 'set null', label: 'Translation of' }),
|
|
70
80
|
blocks: f.one2many('website.block', 'page', { label: 'Content' }),
|
|
71
81
|
state: f.state({
|
|
82
|
+
help: 'Only published pages are shown on the public site.',
|
|
72
83
|
states: { draft: 'Draft', published: 'Published' },
|
|
73
84
|
initial: 'draft',
|
|
74
85
|
transitions: {
|
|
@@ -115,7 +126,11 @@ export const WebsiteBlock = defineModel('website.block', {
|
|
|
115
126
|
fields: {
|
|
116
127
|
page: f.many2one('website.page', { required: true, ondelete: 'cascade' }),
|
|
117
128
|
sequence: f.integer({ required: true, default: 10 }),
|
|
118
|
-
kind: f.selection({ hero: 'Hero', text: 'Text', image: 'Image', cta: 'Call to action', form: 'Form' }, {
|
|
129
|
+
kind: f.selection({ hero: 'Hero', text: 'Text', image: 'Image', cta: 'Call to action', form: 'Form' }, {
|
|
130
|
+
required: true,
|
|
131
|
+
default: 'text',
|
|
132
|
+
help: 'What the block shows: a hero banner, text, an image, a call to action or a form.',
|
|
133
|
+
}),
|
|
119
134
|
title: f.char(),
|
|
120
135
|
body: f.text({ label: 'Text' }),
|
|
121
136
|
imageUrl: f.char({ label: 'Image URL', size: 1000 }),
|
|
@@ -220,7 +235,12 @@ export const WebsiteFormField = defineModel('website.form.field', {
|
|
|
220
235
|
textarea: 'Long text',
|
|
221
236
|
number: 'Number',
|
|
222
237
|
date: 'Date',
|
|
223
|
-
}, {
|
|
238
|
+
}, {
|
|
239
|
+
required: true,
|
|
240
|
+
default: 'text',
|
|
241
|
+
label: 'Type',
|
|
242
|
+
help: 'The kind of value the visitor types in this input.',
|
|
243
|
+
}),
|
|
224
244
|
required: f.boolean({ default: false }),
|
|
225
245
|
/** The field of the created record it fills (`email`); plain fields only, checked on submission. */
|
|
226
246
|
targetField: f.char({ required: true, size: 80, label: 'Fills' }),
|
|
@@ -252,7 +272,11 @@ export const WebsiteSubmission = defineModel('website.submission', {
|
|
|
252
272
|
site: f.many2one('website.site', { ondelete: 'set null' }),
|
|
253
273
|
/** The values as sent (the form's inputs only). */
|
|
254
274
|
data: f.json({ required: true, default: {} }),
|
|
255
|
-
state: f.selection({ received: 'Received', spam: 'Spam' }, {
|
|
275
|
+
state: f.selection({ received: 'Received', spam: 'Spam' }, {
|
|
276
|
+
required: true,
|
|
277
|
+
default: 'received',
|
|
278
|
+
help: 'Spam when a bot filled in the hidden field; received submissions create their record.',
|
|
279
|
+
}),
|
|
256
280
|
resModel: f.char({ label: 'Created (model)' }),
|
|
257
281
|
resId: f.integer({ label: 'Created (id)' }),
|
|
258
282
|
/** The created record's name, as it was. */
|
|
@@ -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: e98d0ed6cfa09eb4
|
|
2
2
|
// Bindings of module `website_crm`: 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';
|
|
@@ -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: e98d0ed6cfa09eb4
|
|
2
2
|
// Schema view of module `website_crm` (RFC 0002 §7.7): the models it owns or depends on, with the extensions it can see.
|
|
3
3
|
import type { F } from '../../server/orm.js';
|
|
4
4
|
|
|
@@ -710,6 +710,7 @@ export interface ResPartner {
|
|
|
710
710
|
readonly parent: F.Many2one<'res.partner'>;
|
|
711
711
|
readonly contacts: F.One2many<'res.partner', { readonly required: true }>;
|
|
712
712
|
readonly email: F.Char;
|
|
713
|
+
readonly lang: F.Selection<'en' | 'bn'>;
|
|
713
714
|
readonly phone: F.Char;
|
|
714
715
|
readonly mobile: F.Char;
|
|
715
716
|
readonly website: F.Char;
|