shutro-erp 0.3.2 → 0.3.3
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 +29 -1
- package/dist/accounting/.kosh/bindings.js +1 -1
- package/dist/accounting/.kosh/schema.d.ts +29 -1
- package/dist/assistant/index.js +1 -1
- package/dist/contacts/.kosh/bindings.js +1 -1
- package/dist/contacts/.kosh/schema.d.ts +29 -1
- package/dist/l10n_bd/.kosh/bindings.js +1 -1
- package/dist/l10n_bd/.kosh/schema.d.ts +29 -1
- package/dist/l10n_in/.kosh/bindings.js +1 -1
- package/dist/l10n_in/.kosh/schema.d.ts +29 -4
- package/dist/l10n_in/module.d.ts +0 -62
- package/dist/l10n_in/module.js +2 -4
- package/dist/payment/.kosh/bindings.js +1 -1
- package/dist/payment/.kosh/schema.d.ts +30 -2
- package/dist/payment/bkash.d.ts +28 -0
- package/dist/payment/bkash.js +169 -0
- package/dist/payment/index.d.ts +4 -0
- package/dist/payment/index.js +80 -24
- package/dist/payment/module.d.ts +7 -4
- package/dist/payment/module.js +3 -0
- package/dist/payment/money.d.ts +7 -0
- package/dist/payment/money.js +37 -0
- package/dist/payment/providers.d.ts +13 -2
- package/dist/payment/razorpay.d.ts +12 -0
- package/dist/payment/razorpay.js +149 -0
- package/dist/payment/sslcommerz.js +1 -1
- package/dist/payment/stripe.d.ts +15 -0
- package/dist/payment/stripe.js +182 -0
- package/dist/permissions/admin.d.ts +3 -0
- package/dist/permissions/admin.js +108 -10
- package/dist/permissions/index.d.ts +1 -0
- package/dist/permissions/index.js +3 -0
- package/dist/permissions/roles.d.ts +2 -0
- package/dist/permissions/roles.js +236 -0
- package/dist/portal/.kosh/bindings.js +1 -1
- package/dist/portal/.kosh/schema.d.ts +29 -1
- package/dist/product/.kosh/bindings.js +1 -1
- package/dist/product/.kosh/schema.d.ts +29 -1
- package/dist/project/.kosh/bindings.js +1 -1
- package/dist/project/.kosh/schema.d.ts +29 -1
- package/dist/project_portal/.kosh/bindings.js +1 -1
- package/dist/project_portal/.kosh/schema.d.ts +29 -1
- package/dist/purchase/.kosh/bindings.js +1 -1
- package/dist/purchase/.kosh/schema.d.ts +29 -1
- package/dist/purchase_account/.kosh/bindings.js +1 -1
- package/dist/purchase_account/.kosh/schema.d.ts +29 -1
- package/dist/purchase_portal/.kosh/bindings.js +1 -1
- package/dist/purchase_portal/.kosh/schema.d.ts +29 -1
- package/dist/sale_account/.kosh/bindings.js +1 -1
- package/dist/sale_account/.kosh/schema.d.ts +29 -1
- package/dist/sale_portal/.kosh/bindings.js +1 -1
- package/dist/sale_portal/.kosh/schema.d.ts +29 -1
- package/dist/sale_project/.kosh/bindings.js +1 -1
- package/dist/sale_project/.kosh/schema.d.ts +29 -1
- package/dist/sales/.kosh/bindings.js +1 -1
- package/dist/sales/.kosh/schema.d.ts +29 -1
- package/dist/server/auth/base.js +22 -0
- package/dist/server/auth/routes.d.ts +3 -0
- package/dist/server/auth/routes.js +29 -0
- package/dist/server/auth/service.d.ts +52 -0
- package/dist/server/auth/service.js +168 -3
- package/dist/server/identity.d.ts +2 -0
- package/dist/server/index.d.ts +1 -1
- package/dist/server/server.js +11 -3
- package/dist/settings/company.d.ts +34 -0
- package/dist/settings/company.js +187 -0
- package/dist/settings/index.d.ts +10 -10
- package/dist/settings/index.js +159 -30
- package/dist/settings/people.d.ts +16 -0
- package/dist/settings/people.js +505 -0
- package/dist/settings/security.d.ts +13 -0
- package/dist/settings/security.js +158 -0
- package/dist/settings/web/AuditPage.d.ts +8 -0
- package/dist/settings/web/AuditPage.js +74 -0
- package/dist/settings/web/CompaniesPage.d.ts +8 -0
- package/dist/settings/web/CompaniesPage.js +52 -0
- package/dist/settings/web/CompanyPage.d.ts +9 -0
- package/dist/settings/web/CompanyPage.js +94 -0
- package/dist/settings/web/OverviewPage.d.ts +9 -0
- package/dist/settings/web/OverviewPage.js +66 -0
- package/dist/settings/web/PeoplePage.d.ts +9 -0
- package/dist/settings/web/PeoplePage.js +163 -0
- package/dist/settings/web/ProfilePage.d.ts +14 -0
- package/dist/settings/web/ProfilePage.js +194 -0
- package/dist/settings/web/RolesEditor.d.ts +35 -0
- package/dist/settings/web/RolesEditor.js +49 -0
- package/dist/settings/web/RolesPage.d.ts +9 -0
- package/dist/settings/web/RolesPage.js +296 -0
- package/dist/settings/web/SecurityPage.d.ts +8 -0
- package/dist/settings/web/SecurityPage.js +81 -0
- package/dist/settings/web/index.d.ts +9 -0
- package/dist/settings/web/index.js +26 -1
- package/dist/settings/web/messages.js +566 -0
- package/dist/ui/api.d.ts +4 -0
- package/dist/ui/app.d.ts +5 -0
- package/dist/ui/app.js +108 -31
- package/dist/ui/components/primitives.d.ts +9 -1
- package/dist/ui/components/primitives.js +12 -4
- package/dist/ui/context.d.ts +10 -1
- package/dist/ui/context.js +60 -2
- package/dist/ui/i18n/messages.d.ts +46 -0
- package/dist/ui/i18n/messages.js +92 -0
- package/dist/ui/index.d.ts +2 -1
- package/dist/ui/index.js +2 -1
- package/dist/ui/lib/accent.d.ts +13 -0
- package/dist/ui/lib/accent.js +36 -0
- package/dist/ui/shell/Activate.d.ts +6 -0
- package/dist/ui/shell/Activate.js +39 -0
- package/dist/ui/shell/CommandPalette.d.ts +7 -1
- package/dist/ui/shell/CommandPalette.js +16 -2
- package/dist/ui/shell/Sidebar.d.ts +27 -0
- package/dist/ui/shell/Sidebar.js +84 -0
- package/dist/ui/shell/TwoFactorSetup.d.ts +5 -0
- package/dist/ui/shell/TwoFactorSetup.js +32 -0
- package/dist/ui/shell/shortcuts.d.ts +3 -0
- package/dist/ui/shell/shortcuts.js +13 -4
- package/dist/ui/styles.css +70 -28
- package/dist/ui/views/DateField.d.ts +10 -0
- package/dist/ui/views/DateField.js +129 -0
- package/dist/ui/views/FormView.js +161 -21
- package/dist/ui/views/ListView.d.ts +2 -0
- package/dist/ui/views/ListView.js +8 -3
- package/dist/ui/views/StatusChip.d.ts +10 -0
- package/dist/ui/views/StatusChip.js +22 -0
- package/dist/ui/views/widgets.d.ts +3 -0
- package/dist/ui/views/widgets.js +26 -8
- package/dist/views/types.d.ts +7 -0
- package/dist/views/validate.js +4 -0
- package/package.json +2 -2
package/dist/ui/views/widgets.js
CHANGED
|
@@ -11,6 +11,7 @@ import { useTranslation } from 'react-i18next';
|
|
|
11
11
|
import { Badge, Checkbox, Input, Select, Textarea } from '../components/primitives.js';
|
|
12
12
|
import { useKosh } from '../context.js';
|
|
13
13
|
import { cn } from '../lib/cn.js';
|
|
14
|
+
import { DateField } from './DateField.js';
|
|
14
15
|
const text = (v) => (v === null || v === undefined ? '' : String(v));
|
|
15
16
|
function CharWidget({ id, value, readonly, onChange, field, invalid }) {
|
|
16
17
|
if (onChange === undefined || readonly)
|
|
@@ -56,11 +57,11 @@ function BooleanWidget({ id, value, readonly, onChange, field }) {
|
|
|
56
57
|
return _jsx("span", { children: value === true ? t('views.yes') : t('views.no') });
|
|
57
58
|
return (_jsx(Checkbox, { id: id, checked: value === true, disabled: readonly, "aria-label": field.label, onCheckedChange: (c) => onChange(c === true) }));
|
|
58
59
|
}
|
|
59
|
-
function DateWidget({ id, value, readonly, onChange }) {
|
|
60
|
+
function DateWidget({ id, value, readonly, onChange, field, invalid }) {
|
|
60
61
|
const { format } = useKosh();
|
|
61
62
|
if (onChange === undefined || readonly)
|
|
62
63
|
return _jsx("span", { children: format.date(value === null || value === undefined ? null : String(value)) });
|
|
63
|
-
return (_jsx(
|
|
64
|
+
return (_jsx(DateField, { id: id, value: value === null || value === undefined || value === '' ? null : text(value).slice(0, 10), onChange: onChange, required: field.required, ...(invalid === undefined ? {} : { invalid }) }));
|
|
64
65
|
}
|
|
65
66
|
function DatetimeWidget({ id, value, readonly, onChange }) {
|
|
66
67
|
const { format } = useKosh();
|
|
@@ -80,14 +81,31 @@ function SelectionWidget({ id, value, readonly, onChange, field }) {
|
|
|
80
81
|
return _jsx("span", { children: label });
|
|
81
82
|
return (_jsx(Select, { id: id, label: field.label, value: value === null || value === undefined ? null : String(value), options: options, onChange: onChange }));
|
|
82
83
|
}
|
|
83
|
-
|
|
84
|
+
/** What a state's value means, by the words ERP states use (`posted`, `to_approve`, `cancel`…). */
|
|
85
|
+
const MEANINGS = [
|
|
86
|
+
[
|
|
87
|
+
/(^|_)(cancel|cancelled|canceled|failed|refused|rejected|lost|blocked|overdue|error|bounced)($|_)/,
|
|
88
|
+
'danger',
|
|
89
|
+
],
|
|
90
|
+
[
|
|
91
|
+
/(^|_)(to|not|partial|partially|pending|waiting|wait|hold|review|approve|quarantine)($|_)/,
|
|
92
|
+
'warning',
|
|
93
|
+
],
|
|
94
|
+
[
|
|
95
|
+
/(^|_)(done|paid|posted|sale|confirmed|approved|won|delivered|validated|completed|complete|reconciled|invoiced|handled|active|accepted|signed|locked)($|_)/,
|
|
96
|
+
'success',
|
|
97
|
+
],
|
|
98
|
+
[/(^|_)(sent|open|progress|received|in|scheduled|running|purchase|ordered)($|_)/, 'info'],
|
|
99
|
+
];
|
|
100
|
+
export function toneOf(value) {
|
|
101
|
+
const v = value.toLowerCase();
|
|
102
|
+
return MEANINGS.find(([pattern]) => pattern.test(v))?.[1] ?? 'neutral';
|
|
103
|
+
}
|
|
84
104
|
function BadgeWidget({ value, field }) {
|
|
85
105
|
if (value === null || value === undefined || value === '')
|
|
86
106
|
return null;
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
const label = options[index]?.label ?? text(value);
|
|
90
|
-
return _jsx(Badge, { tone: TONES[Math.max(index, 0) % TONES.length] ?? 'neutral', children: label });
|
|
107
|
+
const label = (field.options ?? []).find((o) => o.value === value)?.label ?? text(value);
|
|
108
|
+
return _jsx(Badge, { tone: toneOf(text(value)), children: label });
|
|
91
109
|
}
|
|
92
110
|
/** Display names a list or kanban loaded in one batch per model, so cells do not query one by one. */
|
|
93
111
|
export const PrefetchedNames = createContext(new Map());
|
|
@@ -166,7 +184,7 @@ function Many2oneWidget({ id, value, readonly, onChange, field, invalid, }) {
|
|
|
166
184
|
const label = current === null ? '' : (names.get(current) ?? `#${current}`);
|
|
167
185
|
if (onChange === undefined || readonly)
|
|
168
186
|
return _jsx("span", { children: label });
|
|
169
|
-
return (_jsxs(Popover.Root, { open: open, onOpenChange: setOpen, children: [_jsx(Popover.Trigger, { asChild: true, children: _jsx("button", { id: id, type: "button", role: "combobox", "aria-expanded": open, "aria-controls": listId, "aria-invalid": invalid === true ? true : undefined, className: "flex h-
|
|
187
|
+
return (_jsxs(Popover.Root, { open: open, onOpenChange: setOpen, children: [_jsx(Popover.Trigger, { asChild: true, children: _jsx("button", { id: id, type: "button", role: "combobox", "aria-expanded": open, "aria-controls": listId, "aria-invalid": invalid === true ? true : undefined, className: "flex h-[var(--control-h)] w-full items-center justify-between rounded-md border border-input bg-surface px-3 text-start text-sm aria-invalid:border-danger", children: _jsx("span", { className: cn(current === null && 'text-muted-foreground'), children: current === null ? t('views.choose') : label }) }) }), _jsx(Popover.Portal, { children: _jsxs(Popover.Content, { align: "start", sideOffset: 4, className: "z-50 w-[var(--radix-popover-trigger-width)] rounded-md border bg-surface p-1 shadow-lg", children: [_jsx(Input, { autoFocus: true, "aria-label": field.label, placeholder: t('search.placeholder'), value: q, onChange: (e) => setQ(e.target.value) }), _jsxs("div", { id: listId, role: "listbox", "aria-label": field.label, className: "mt-1 max-h-60 overflow-auto", children: [field.required ? null : (_jsx("button", { type: "button", role: "option", "aria-selected": current === null, className: "w-full rounded-sm px-2 py-1.5 text-start text-sm text-muted-foreground hover:bg-muted", onClick: () => {
|
|
170
188
|
onChange(null);
|
|
171
189
|
setOpen(false);
|
|
172
190
|
}, children: t('views.none') })), (results.data ?? []).map((r) => (_jsx("button", { type: "button", role: "option", "aria-selected": r.id === current, className: "w-full rounded-sm px-2 py-1.5 text-start text-sm hover:bg-muted", onClick: () => {
|
package/dist/views/types.d.ts
CHANGED
|
@@ -96,6 +96,13 @@ export interface FormView extends ViewBase {
|
|
|
96
96
|
readonly readonlyWhen?: Condition;
|
|
97
97
|
/** Messages and activities (RFC 0006). */
|
|
98
98
|
readonly chatter?: boolean;
|
|
99
|
+
/**
|
|
100
|
+
* The key facts under the title (RFC 0018 §4.2): the customer, the date, the total. Default: the first many2one,
|
|
101
|
+
* date and monetary fields of the form.
|
|
102
|
+
*/
|
|
103
|
+
readonly subtitle?: readonly string[];
|
|
104
|
+
/** The fields of the right rail's Summary (RFC 0018 §4.2). Default: the group named `totals`. */
|
|
105
|
+
readonly summary?: readonly string[];
|
|
99
106
|
}
|
|
100
107
|
export interface KanbanCard {
|
|
101
108
|
readonly title: string;
|
package/dist/views/validate.js
CHANGED
|
@@ -58,6 +58,10 @@ export function validateView(view, models) {
|
|
|
58
58
|
if (node.kind === 'button' && !info.transitions.includes(node.transition))
|
|
59
59
|
problems.push(`unknown transition '${node.transition}' (has ${info.transitions.join(', ') || 'none'})`);
|
|
60
60
|
}
|
|
61
|
+
if (view.type === 'form')
|
|
62
|
+
for (const key of [...(view.subtitle ?? []), ...(view.summary ?? [])])
|
|
63
|
+
if (!info.fields.has(key))
|
|
64
|
+
problems.push(`unknown field '${key}' in the subtitle or summary`);
|
|
61
65
|
if (view.type === 'form' && view.header.statusbar !== undefined) {
|
|
62
66
|
const kind = info.fields.get(view.header.statusbar)?.kind;
|
|
63
67
|
if (kind !== 'state' && kind !== 'selection')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shutro-erp",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "Shutro ERP (Kosh): a modern ERP framework on TypeScript, PostgreSQL and the Shutro ORM — typed end to end, permissions enforced on the server, metadata-driven views, reporting, documents and a chatter on every record.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"erp",
|
|
@@ -289,7 +289,7 @@
|
|
|
289
289
|
"postal-mime": "^4.1.4",
|
|
290
290
|
"radix-ui": "^1.8.1",
|
|
291
291
|
"sanitize-html": "^2.18.1",
|
|
292
|
-
"shutro": "^0.3.
|
|
292
|
+
"shutro": "^0.3.3",
|
|
293
293
|
"tailwind-merge": "^3.7.0",
|
|
294
294
|
"web-push": "^3.6.7"
|
|
295
295
|
},
|