@plumile/backoffice-react 0.2.9 → 0.2.11
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/README.md +4 -0
- package/lib/esm/components/backoffice/columns/buildDataTableColumns.js +71 -68
- package/lib/esm/components/backoffice/columns/buildDataTableColumns.js.map +1 -1
- package/lib/esm/components/backoffice/detail/BackofficeUsageCostBreakdown.js +8 -5
- package/lib/esm/components/backoffice/detail/BackofficeUsageCostBreakdown.js.map +1 -1
- package/lib/esm/pages/BackofficeDashboardPage.js +54 -52
- package/lib/esm/pages/BackofficeDashboardPage.js.map +1 -1
- package/lib/esm/pages/BackofficeEntityDetailLayoutPage.js +67 -64
- package/lib/esm/pages/BackofficeEntityDetailLayoutPage.js.map +1 -1
- package/lib/esm/pages/BackofficeEntityDetailPage.view-helpers.js +10 -9
- package/lib/esm/pages/BackofficeEntityDetailPage.view-helpers.js.map +1 -1
- package/lib/types/components/backoffice/columns/buildDataTableColumns.d.ts.map +1 -1
- package/lib/types/components/backoffice/detail/BackofficeUsageCostBreakdown.d.ts +8 -4
- package/lib/types/components/backoffice/detail/BackofficeUsageCostBreakdown.d.ts.map +1 -1
- package/lib/types/pages/BackofficeDashboardPage.d.ts.map +1 -1
- package/lib/types/pages/BackofficeEntityDetailLayoutPage.d.ts.map +1 -1
- package/lib/types/pages/BackofficeEntityDetailPage.view-helpers.d.ts +4 -3
- package/lib/types/pages/BackofficeEntityDetailPage.view-helpers.d.ts.map +1 -1
- package/package.json +19 -19
package/README.md
CHANGED
|
@@ -140,6 +140,10 @@ only helpers tied to backoffice mutations, connections, and typed data.
|
|
|
140
140
|
The reusable picker visuals live in `@plumile/ui` as
|
|
141
141
|
`BackofficePickerShell`, `BackofficePickerList`, and `BackofficePickerRow`.
|
|
142
142
|
|
|
143
|
+
`BackofficeUsageCostBreakdown` totals accept rich `value` content when copying
|
|
144
|
+
is disabled. A total with `copyValue` requires a `UiText` value (`string | number`),
|
|
145
|
+
matching the shared `MetricCard` copy contract at compile time.
|
|
146
|
+
|
|
143
147
|
Backoffice React no longer exports generic toolbar or detail-header wrappers.
|
|
144
148
|
Use `BackofficeToolbar`, `BackofficeListFilterToolbar`,
|
|
145
149
|
`BackofficeListFooter`, and `PageHeader` from `@plumile/ui` for
|
|
@@ -14,76 +14,79 @@ var c = (e, t) => e(t), l = (e, t) => e == null || typeof e == "string" && e.tri
|
|
|
14
14
|
};
|
|
15
15
|
function f(f, p) {
|
|
16
16
|
let { tApp: m, t: h } = p, g = h("common.notAvailable");
|
|
17
|
-
return f.filter((e) => e.key !== "id").map((f) =>
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
17
|
+
return f.filter((e) => e.key !== "id").map((f) => {
|
|
18
|
+
let p = u(f);
|
|
19
|
+
return {
|
|
20
|
+
id: f.key,
|
|
21
|
+
header: c(f.header, m),
|
|
22
|
+
size: f.size,
|
|
23
|
+
isPrimary: f.visibility.priority === "primary",
|
|
24
|
+
priority: f.visibility.priority,
|
|
25
|
+
align: f.visibility.align,
|
|
26
|
+
mobileRole: p,
|
|
27
|
+
minVisibleAt: d(f.visibility.minVisibleAt),
|
|
28
|
+
cell: (c) => {
|
|
29
|
+
let { cell: u } = f;
|
|
30
|
+
switch (u.type) {
|
|
31
|
+
case "text": return l(u.value(c), g);
|
|
32
|
+
case "link": {
|
|
33
|
+
let e = u.value(c);
|
|
34
|
+
return e == null || typeof e == "string" && e.trim() === "" ? g : /* @__PURE__ */ i(o, {
|
|
35
|
+
to: u.to(c),
|
|
36
|
+
preloadOnHover: "code",
|
|
37
|
+
children: e
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
case "badge": {
|
|
41
|
+
let e = u.value(c);
|
|
42
|
+
if (e == null || e.trim() === "") return g;
|
|
43
|
+
let { tone: t } = u;
|
|
44
|
+
return typeof t == "function" && (t = t(c)), /* @__PURE__ */ i(s, {
|
|
45
|
+
tone: t,
|
|
46
|
+
children: e
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
case "dateTime": {
|
|
50
|
+
let e = u.value(c);
|
|
51
|
+
return /* @__PURE__ */ i(t, {
|
|
52
|
+
value: e,
|
|
53
|
+
fallback: g,
|
|
54
|
+
options: a
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
case "entityRef": {
|
|
58
|
+
let t = u.value(c);
|
|
59
|
+
if (t.trim() === "") return g;
|
|
60
|
+
let n = u.label?.(c);
|
|
61
|
+
if (n == null || n.trim() === "") return h("filters.placeholders.unresolved");
|
|
62
|
+
let r = {
|
|
63
|
+
kind: "entity-detail",
|
|
64
|
+
entityId: u.entity,
|
|
65
|
+
id: t
|
|
66
|
+
};
|
|
67
|
+
return /* @__PURE__ */ i(e, {
|
|
68
|
+
target: r,
|
|
69
|
+
children: n
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
case "technicalIdentifier": {
|
|
73
|
+
let e = u.value(c);
|
|
74
|
+
return e == null || String(e).trim() === "" ? g : /* @__PURE__ */ i(n, {
|
|
75
|
+
value: e,
|
|
76
|
+
copyValue: u.copyValue?.(c) ?? void 0,
|
|
77
|
+
abbreviation: u.abbreviation,
|
|
78
|
+
copyLabel: h("common.actions.copy")
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
case "custom": {
|
|
82
|
+
let e = u.render(c);
|
|
83
|
+
return e == null || e === "" ? g : /* @__PURE__ */ i(r, { children: e });
|
|
84
|
+
}
|
|
85
|
+
default: return g;
|
|
37
86
|
}
|
|
38
|
-
case "badge": {
|
|
39
|
-
let e = u.value(c);
|
|
40
|
-
if (e == null || e.trim() === "") return g;
|
|
41
|
-
let { tone: t } = u;
|
|
42
|
-
return typeof t == "function" && (t = t(c)), /* @__PURE__ */ i(s, {
|
|
43
|
-
tone: t,
|
|
44
|
-
children: e
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
case "dateTime": {
|
|
48
|
-
let e = u.value(c);
|
|
49
|
-
return /* @__PURE__ */ i(t, {
|
|
50
|
-
value: e,
|
|
51
|
-
fallback: g,
|
|
52
|
-
options: a
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
case "entityRef": {
|
|
56
|
-
let t = u.value(c);
|
|
57
|
-
if (t.trim() === "") return g;
|
|
58
|
-
let n = u.label?.(c);
|
|
59
|
-
if (n == null || n.trim() === "") return h("filters.placeholders.unresolved");
|
|
60
|
-
let r = {
|
|
61
|
-
kind: "entity-detail",
|
|
62
|
-
entityId: u.entity,
|
|
63
|
-
id: t
|
|
64
|
-
};
|
|
65
|
-
return /* @__PURE__ */ i(e, {
|
|
66
|
-
target: r,
|
|
67
|
-
children: n
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
case "technicalIdentifier": {
|
|
71
|
-
let e = u.value(c);
|
|
72
|
-
return e == null || String(e).trim() === "" ? g : /* @__PURE__ */ i(n, {
|
|
73
|
-
value: e,
|
|
74
|
-
copyValue: u.copyValue?.(c) ?? void 0,
|
|
75
|
-
abbreviation: u.abbreviation,
|
|
76
|
-
copyLabel: h("common.actions.copy")
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
case "custom": {
|
|
80
|
-
let e = u.render(c);
|
|
81
|
-
return e == null || e === "" ? g : /* @__PURE__ */ i(r, { children: e });
|
|
82
|
-
}
|
|
83
|
-
default: return g;
|
|
84
87
|
}
|
|
85
|
-
}
|
|
86
|
-
})
|
|
88
|
+
};
|
|
89
|
+
});
|
|
87
90
|
}
|
|
88
91
|
//#endregion
|
|
89
92
|
export { f as buildDataTableColumns };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buildDataTableColumns.js","names":[],"sources":["../../../../../src/components/backoffice/columns/buildDataTableColumns.tsx"],"sourcesContent":["import { BACKOFFICE_DATE_TIME_OPTIONS } from '@plumile/backoffice-core/constants.js';\nimport type {\n BackofficeColumnSpec,\n BackofficeFieldSize,\n BackofficeListColumnVisibility,\n I18nLabel,\n} from '@plumile/backoffice-core/types.js';\nimport type { TFunction } from 'i18next';\nimport Link from '@plumile/router/routing/Link.js';\nimport {\n FormattedDate,\n TechnicalIdentifierValue,\n type DataTableBreakpoint,\n type ResponsiveRecordListColumn,\n} from '@plumile/ui';\nimport { Tag } from '@plumile/ui/backoffice/atoms/tag/Tag.js';\n\nimport { BackofficeInlineLink } from '../links/BackofficeInlineLink.js';\nimport type { BackofficeLinkTarget } from '../links/types.js';\n\nconst resolveLabel = (label: I18nLabel, tApp: TFunction): string => {\n return label(tApp);\n};\n\nconst resolveTextValue = (\n value: string | number | null,\n fallback: string,\n): string => {\n if (value == null) {\n return fallback;\n }\n if (typeof value === 'string' && value.trim() === '') {\n return fallback;\n }\n return String(value);\n};\n\nexport type BuildDataTableColumnsOptions = {\n tApp: TFunction;\n t: TFunction;\n};\n\nexport type BackofficeSizedDataTableColumn<Row> =\n ResponsiveRecordListColumn<Row> & {\n size: BackofficeFieldSize;\n };\n\nconst resolveMobileRole = <Row,>(\n column: BackofficeColumnSpec<Row>,\n): ResponsiveRecordListColumn<Row>['mobileRole'] => {\n const role = column.visibility?.mobile;\n if (role == null) {\n throw new Error(\n `[buildDataTableColumns] column \"${column.key}\" must declare visibility.mobile.`,\n );\n }\n return role;\n};\n\nconst resolveBreakpoint = (\n value: BackofficeListColumnVisibility['minVisibleAt'] | undefined,\n): DataTableBreakpoint | undefined => {\n if (\n value === 'sm' ||\n value === 'md' ||\n value === 'lg' ||\n value === 'xl' ||\n value === '2xl'\n ) {\n return value;\n }\n return undefined;\n};\n\n/**\n *\n */\nexport function buildDataTableColumns<Row>(\n columns: readonly BackofficeColumnSpec<Row>[],\n options: BuildDataTableColumnsOptions,\n): readonly BackofficeSizedDataTableColumn<Row>[] {\n const { tApp, t } = options;\n const fallback = t('common.notAvailable');\n const filteredColumns = columns.filter((column) => {\n return column.key !== 'id';\n });\n\n return filteredColumns.map((column) => {\n return {\n id: column.key,\n header: resolveLabel(column.header, tApp),\n size: column.size,\n isPrimary: column.visibility
|
|
1
|
+
{"version":3,"file":"buildDataTableColumns.js","names":[],"sources":["../../../../../src/components/backoffice/columns/buildDataTableColumns.tsx"],"sourcesContent":["import { BACKOFFICE_DATE_TIME_OPTIONS } from '@plumile/backoffice-core/constants.js';\nimport type {\n BackofficeColumnSpec,\n BackofficeFieldSize,\n BackofficeListColumnVisibility,\n I18nLabel,\n} from '@plumile/backoffice-core/types.js';\nimport type { TFunction } from 'i18next';\nimport Link from '@plumile/router/routing/Link.js';\nimport {\n FormattedDate,\n TechnicalIdentifierValue,\n type DataTableBreakpoint,\n type ResponsiveRecordListColumn,\n} from '@plumile/ui';\nimport { Tag } from '@plumile/ui/backoffice/atoms/tag/Tag.js';\n\nimport { BackofficeInlineLink } from '../links/BackofficeInlineLink.js';\nimport type { BackofficeLinkTarget } from '../links/types.js';\n\nconst resolveLabel = (label: I18nLabel, tApp: TFunction): string => {\n return label(tApp);\n};\n\nconst resolveTextValue = (\n value: string | number | null,\n fallback: string,\n): string => {\n if (value == null) {\n return fallback;\n }\n if (typeof value === 'string' && value.trim() === '') {\n return fallback;\n }\n return String(value);\n};\n\nexport type BuildDataTableColumnsOptions = {\n tApp: TFunction;\n t: TFunction;\n};\n\nexport type BackofficeSizedDataTableColumn<Row> =\n ResponsiveRecordListColumn<Row> & {\n size: BackofficeFieldSize;\n };\n\nconst resolveMobileRole = <Row,>(\n column: BackofficeColumnSpec<Row>,\n): ResponsiveRecordListColumn<Row>['mobileRole'] => {\n // JavaScript callers can bypass the required TypeScript contract.\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const role = column.visibility?.mobile;\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- Untyped callers.\n if (role == null) {\n throw new Error(\n `[buildDataTableColumns] column \"${column.key}\" must declare visibility.mobile.`,\n );\n }\n return role;\n};\n\nconst resolveBreakpoint = (\n value: BackofficeListColumnVisibility['minVisibleAt'] | undefined,\n): DataTableBreakpoint | undefined => {\n if (\n value === 'sm' ||\n value === 'md' ||\n value === 'lg' ||\n value === 'xl' ||\n value === '2xl'\n ) {\n return value;\n }\n return undefined;\n};\n\n/**\n *\n */\nexport function buildDataTableColumns<Row>(\n columns: readonly BackofficeColumnSpec<Row>[],\n options: BuildDataTableColumnsOptions,\n): readonly BackofficeSizedDataTableColumn<Row>[] {\n const { tApp, t } = options;\n const fallback = t('common.notAvailable');\n const filteredColumns = columns.filter((column) => {\n return column.key !== 'id';\n });\n\n return filteredColumns.map((column) => {\n const mobileRole = resolveMobileRole(column);\n return {\n id: column.key,\n header: resolveLabel(column.header, tApp),\n size: column.size,\n isPrimary: column.visibility.priority === 'primary',\n priority: column.visibility.priority,\n align: column.visibility.align,\n mobileRole,\n minVisibleAt: resolveBreakpoint(column.visibility.minVisibleAt),\n cell: (row) => {\n const { cell } = column;\n switch (cell.type) {\n case 'text': {\n return resolveTextValue(cell.value(row), fallback);\n }\n case 'link': {\n const value = cell.value(row);\n if (\n value == null ||\n (typeof value === 'string' && value.trim() === '')\n ) {\n return fallback;\n }\n return (\n <Link to={cell.to(row)} preloadOnHover=\"code\">\n {value}\n </Link>\n );\n }\n case 'badge': {\n const value = cell.value(row);\n if (value == null || value.trim() === '') {\n return fallback;\n }\n let { tone } = cell;\n if (typeof tone === 'function') {\n tone = tone(row);\n }\n return <Tag tone={tone}>{value}</Tag>;\n }\n case 'dateTime': {\n const value = cell.value(row);\n return (\n <FormattedDate\n value={value}\n fallback={fallback}\n options={BACKOFFICE_DATE_TIME_OPTIONS}\n />\n );\n }\n case 'entityRef': {\n const id = cell.value(row);\n if (id.trim() === '') {\n return fallback;\n }\n const label = cell.label?.(row);\n if (label == null || label.trim() === '') {\n return t('filters.placeholders.unresolved');\n }\n const target = {\n kind: 'entity-detail',\n entityId: cell.entity,\n id,\n } as BackofficeLinkTarget;\n return (\n <BackofficeInlineLink target={target}>\n {label}\n </BackofficeInlineLink>\n );\n }\n case 'technicalIdentifier': {\n const value = cell.value(row);\n if (value == null || String(value).trim() === '') {\n return fallback;\n }\n return (\n <TechnicalIdentifierValue\n value={value}\n copyValue={cell.copyValue?.(row) ?? undefined}\n abbreviation={cell.abbreviation}\n copyLabel={t('common.actions.copy')}\n />\n );\n }\n case 'custom': {\n const rendered = cell.render(row);\n if (rendered == null || rendered === '') {\n return fallback;\n }\n return <>{rendered}</>;\n }\n default: {\n return fallback;\n }\n }\n },\n };\n });\n}\n"],"mappings":";;;;;;;AAoBA,IAAM,KAAgB,GAAkB,MAC/B,EAAM,CAAI,GAGb,KACJ,GACA,MAEI,KAAS,QAGT,OAAO,KAAU,YAAY,EAAM,KAAK,MAAM,KACzC,IAEF,OAAO,CAAK,GAaf,KACJ,MACkD;CAGlD,IAAM,IAAO,EAAO,YAAY;CAEhC,IAAI,KAAQ,MACV,MAAU,MACR,mCAAmC,EAAO,IAAI,kCAChD;CAEF,OAAO;AACT,GAEM,KACJ,MACoC;CACpC,IACE,MAAU,QACV,MAAU,QACV,MAAU,QACV,MAAU,QACV,MAAU,OAEV,OAAO;AAGX;AAKA,SAAgB,EACd,GACA,GACgD;CAChD,IAAM,EAAE,SAAM,SAAM,GACd,IAAW,EAAE,qBAAqB;CAKxC,OAJwB,EAAQ,QAAQ,MAC/B,EAAO,QAAQ,IAGjB,CAAA,CAAgB,KAAK,MAAW;EACrC,IAAM,IAAa,EAAkB,CAAM;EAC3C,OAAO;GACL,IAAI,EAAO;GACX,QAAQ,EAAa,EAAO,QAAQ,CAAI;GACxC,MAAM,EAAO;GACb,WAAW,EAAO,WAAW,aAAa;GAC1C,UAAU,EAAO,WAAW;GAC5B,OAAO,EAAO,WAAW;GACzB;GACA,cAAc,EAAkB,EAAO,WAAW,YAAY;GAC9D,OAAO,MAAQ;IACb,IAAM,EAAE,YAAS;IACjB,QAAQ,EAAK,MAAb;KACE,KAAK,QACH,OAAO,EAAiB,EAAK,MAAM,CAAG,GAAG,CAAQ;KAEnD,KAAK,QAAQ;MACX,IAAM,IAAQ,EAAK,MAAM,CAAG;MAO5B,OALE,KAAS,QACR,OAAO,KAAU,YAAY,EAAM,KAAK,MAAM,KAExC,IAGP,kBAAC,GAAD;OAAM,IAAI,EAAK,GAAG,CAAG;OAAG,gBAAe;OACpC,UAAA;MACG,CAAA;KAEV;KACA,KAAK,SAAS;MACZ,IAAM,IAAQ,EAAK,MAAM,CAAG;MAC5B,IAAI,KAAS,QAAQ,EAAM,KAAK,MAAM,IACpC,OAAO;MAET,IAAI,EAAE,YAAS;MAIf,OAHI,OAAO,KAAS,eAClB,IAAO,EAAK,CAAG,IAEV,kBAAC,GAAD;OAAW;OAAO,UAAA;MAAW,CAAA;KACtC;KACA,KAAK,YAAY;MACf,IAAM,IAAQ,EAAK,MAAM,CAAG;MAC5B,OACE,kBAAC,GAAD;OACS;OACG;OACV,SAAS;MACV,CAAA;KAEL;KACA,KAAK,aAAa;MAChB,IAAM,IAAK,EAAK,MAAM,CAAG;MACzB,IAAI,EAAG,KAAK,MAAM,IAChB,OAAO;MAET,IAAM,IAAQ,EAAK,QAAQ,CAAG;MAC9B,IAAI,KAAS,QAAQ,EAAM,KAAK,MAAM,IACpC,OAAO,EAAE,iCAAiC;MAE5C,IAAM,IAAS;OACb,MAAM;OACN,UAAU,EAAK;OACf;MACF;MACA,OACE,kBAAC,GAAD;OAA8B;OAC3B,UAAA;MACmB,CAAA;KAE1B;KACA,KAAK,uBAAuB;MAC1B,IAAM,IAAQ,EAAK,MAAM,CAAG;MAI5B,OAHI,KAAS,QAAQ,OAAO,CAAK,CAAC,CAAC,KAAK,MAAM,KACrC,IAGP,kBAAC,GAAD;OACS;OACP,WAAW,EAAK,YAAY,CAAG,KAAK,KAAA;OACpC,cAAc,EAAK;OACnB,WAAW,EAAE,qBAAqB;MACnC,CAAA;KAEL;KACA,KAAK,UAAU;MACb,IAAM,IAAW,EAAK,OAAO,CAAG;MAIhC,OAHI,KAAY,QAAQ,MAAa,KAC5B,IAEF,kBAAA,GAAA,EAAA,UAAG,EAAW,CAAA;KACvB;KACA,SACE,OAAO;IAEX;GACF;EACF;CACF,CAAC;AACH"}
|
|
@@ -24,19 +24,22 @@ var c = ({ title: c, rows: l, totals: u, emptyLabel: d, columnLabels: f }) => {
|
|
|
24
24
|
density: "compact",
|
|
25
25
|
minColumn: "180",
|
|
26
26
|
children: u.map((e) => {
|
|
27
|
-
let t =
|
|
28
|
-
...
|
|
29
|
-
|
|
27
|
+
let t = {
|
|
28
|
+
...e.copyValue == null || e.copyValue.trim() === "" ? {
|
|
29
|
+
value: e.value,
|
|
30
|
+
copyValue: void 0
|
|
31
|
+
} : {
|
|
32
|
+
value: e.value,
|
|
33
|
+
copyValue: e.copyValue.trim(),
|
|
30
34
|
copyLabel: p("common.actions.copy"),
|
|
31
35
|
copiedLabel: p("common.actions.copied")
|
|
32
36
|
},
|
|
33
37
|
label: e.label,
|
|
34
|
-
value: e.value,
|
|
35
38
|
hint: e.hint,
|
|
36
39
|
tone: e.tone ?? "neutral",
|
|
37
40
|
density: "compact"
|
|
38
41
|
};
|
|
39
|
-
return /* @__PURE__ */ a(n, { ...
|
|
42
|
+
return /* @__PURE__ */ a(n, { ...t }, e.id);
|
|
40
43
|
})
|
|
41
44
|
}), l.length > 0 && /* @__PURE__ */ o("div", {
|
|
42
45
|
className: "txvbqb5m1 txvbqb6rp",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BackofficeUsageCostBreakdown.js","names":[],"sources":["../../../../../src/components/backoffice/detail/BackofficeUsageCostBreakdown.tsx"],"sourcesContent":["import { type JSX, type ReactNode } from 'react';\nimport { BackofficeDetailSection } from '@plumile/ui/backoffice/molecules/backoffice_detail_section/BackofficeDetailSection.js';\nimport {\n MetricCard,\n type MetricCardProps,\n type MetricTone,\n MetricTileGroup,\n} from '@plumile/ui';\nimport { cx } from '@plumile/ui/theme';\n\nimport { useBackofficeReactTranslation } from '../../../i18n/useBackofficeReactTranslation.js';\nimport * as styles from './backofficeUsageCostBreakdown.css.js';\n\nexport type BackofficeMoneyValue = {\n readonly amount: string | number;\n readonly currency: string;\n};\n\nexport type BackofficeUsageCostBreakdownRow = {\n readonly id: string;\n readonly label: string;\n readonly rawCost?: ReactNode;\n readonly markup?: ReactNode;\n readonly charged?: ReactNode;\n readonly eventsCount?: ReactNode;\n readonly quantity?: ReactNode;\n};\n\nexport type BackofficeUsageCostBreakdownTotal = {\n readonly id: string;\n readonly label: string;\n readonly
|
|
1
|
+
{"version":3,"file":"BackofficeUsageCostBreakdown.js","names":[],"sources":["../../../../../src/components/backoffice/detail/BackofficeUsageCostBreakdown.tsx"],"sourcesContent":["import { type JSX, type ReactNode } from 'react';\nimport { BackofficeDetailSection } from '@plumile/ui/backoffice/molecules/backoffice_detail_section/BackofficeDetailSection.js';\nimport {\n MetricCard,\n type MetricCardProps,\n type MetricTone,\n type UiText,\n MetricTileGroup,\n} from '@plumile/ui';\nimport { cx } from '@plumile/ui/theme';\n\nimport { useBackofficeReactTranslation } from '../../../i18n/useBackofficeReactTranslation.js';\nimport * as styles from './backofficeUsageCostBreakdown.css.js';\n\nexport type BackofficeMoneyValue = {\n readonly amount: string | number;\n readonly currency: string;\n};\n\nexport type BackofficeUsageCostBreakdownRow = {\n readonly id: string;\n readonly label: string;\n readonly rawCost?: ReactNode;\n readonly markup?: ReactNode;\n readonly charged?: ReactNode;\n readonly eventsCount?: ReactNode;\n readonly quantity?: ReactNode;\n};\n\nexport type BackofficeUsageCostBreakdownTotal = {\n readonly id: string;\n readonly label: string;\n readonly hint?: ReactNode;\n readonly tone?: MetricTone;\n} & (\n | { readonly copyValue?: undefined; readonly value: ReactNode }\n | { readonly copyValue: string; readonly value: UiText }\n);\n\nexport type BackofficeUsageCostBreakdownProps = {\n readonly title: string;\n readonly rows: readonly BackofficeUsageCostBreakdownRow[];\n readonly totals?: readonly BackofficeUsageCostBreakdownTotal[];\n readonly emptyLabel?: string;\n readonly columnLabels?: {\n readonly name: string;\n readonly rawCost: string;\n readonly markup: string;\n readonly charged: string;\n readonly events: string;\n };\n};\n\nexport const BackofficeUsageCostBreakdown = ({\n title,\n rows,\n totals,\n emptyLabel,\n columnLabels,\n}: BackofficeUsageCostBreakdownProps): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n const missing = t('common.notAvailable');\n const labels = columnLabels ?? {\n name: t('detail.columns.name'),\n rawCost: t('detail.columns.rawCost'),\n markup: t('detail.columns.markup'),\n charged: t('detail.columns.charged'),\n events: t('detail.columns.events'),\n };\n\n if (rows.length === 0 && (totals == null || totals.length === 0)) {\n return (\n <BackofficeDetailSection title={title}>\n {emptyLabel ?? missing}\n </BackofficeDetailSection>\n );\n }\n\n return (\n <BackofficeDetailSection title={title}>\n <div className={styles.content}>\n {totals != null && totals.length > 0 && (\n <MetricTileGroup density=\"compact\" minColumn=\"180\">\n {totals.map((total) => {\n const copyProps =\n total.copyValue == null || total.copyValue.trim() === ''\n ? { value: total.value, copyValue: undefined }\n : {\n value: total.value,\n copyValue: total.copyValue.trim(),\n copyLabel: t('common.actions.copy'),\n copiedLabel: t('common.actions.copied'),\n };\n const metricProps = {\n ...copyProps,\n label: total.label,\n hint: total.hint,\n tone: total.tone ?? 'neutral',\n density: 'compact',\n } satisfies MetricCardProps;\n return <MetricCard key={total.id} {...metricProps} />;\n })}\n </MetricTileGroup>\n )}\n {rows.length > 0 && (\n <div className={styles.table}>\n <div className={styles.row}>\n <span className={styles.header}>{labels.name}</span>\n <span className={styles.header}>{labels.rawCost}</span>\n <span className={styles.header}>{labels.markup}</span>\n <span className={styles.header}>{labels.charged}</span>\n <span className={styles.header}>{labels.events}</span>\n </div>\n {rows.map((row) => {\n return (\n <div className={styles.row} key={row.id}>\n <span className={cx(styles.cell, styles.label)}>\n {row.label}\n </span>\n <span className={styles.cell}>{row.rawCost ?? missing}</span>\n <span className={styles.cell}>{row.markup ?? missing}</span>\n <span className={styles.cell}>{row.charged ?? missing}</span>\n <span className={styles.cell}>\n {row.eventsCount ?? row.quantity ?? missing}\n </span>\n </div>\n );\n })}\n </div>\n )}\n </div>\n </BackofficeDetailSection>\n );\n};\n\nexport default BackofficeUsageCostBreakdown;\n"],"mappings":";;;;;;;AAqDA,IAAa,KAAgC,EAC3C,UACA,SACA,WACA,eACA,sBACoD;CACpD,IAAM,EAAE,SAAM,EAA8B,GACtC,IAAU,EAAE,qBAAqB,GACjC,IAAS,KAAgB;EAC7B,MAAM,EAAE,qBAAqB;EAC7B,SAAS,EAAE,wBAAwB;EACnC,QAAQ,EAAE,uBAAuB;EACjC,SAAS,EAAE,wBAAwB;EACnC,QAAQ,EAAE,uBAAuB;CACnC;CAUA,OARI,EAAK,WAAW,MAAM,KAAU,QAAQ,EAAO,WAAW,KAE1D,kBAAC,GAAD;EAAgC;EAC7B,UAAA,KAAc;CACQ,CAAA,IAK3B,kBAAC,GAAD;EAAgC;EAC9B,UAAA,kBAAC,OAAD;GAAK,WAAW;GAAhB,UAAA,CACG,KAAU,QAAQ,EAAO,SAAS,KACjC,kBAAC,GAAD;IAAiB,SAAQ;IAAU,WAAU;IAC1C,UAAA,EAAO,KAAK,MAAU;KAUrB,IAAM,IAAc;MAClB,GATA,EAAM,aAAa,QAAQ,EAAM,UAAU,KAAK,MAAM,KAClD;OAAE,OAAO,EAAM;OAAO,WAAW,KAAA;MAAU,IAC3C;OACE,OAAO,EAAM;OACb,WAAW,EAAM,UAAU,KAAK;OAChC,WAAW,EAAE,qBAAqB;OAClC,aAAa,EAAE,uBAAuB;MACxC;MAGJ,OAAO,EAAM;MACb,MAAM,EAAM;MACZ,MAAM,EAAM,QAAQ;MACpB,SAAS;KACX;KACA,OAAO,kBAAC,GAAD,EAA2B,GAAI,EAAc,GAA5B,EAAM,EAAsB;IACtD,CAAC;GACc,CAAA,GAElB,EAAK,SAAS,KACb,kBAAC,OAAD;IAAK,WAAW;IAAhB,UAAA,CACE,kBAAC,OAAD;KAAK,WAAW;KAAhB,UAAA;MACE,kBAAC,QAAD;OAAM,WAAW;OAAgB,UAAA,EAAO;MAAW,CAAA;MACnD,kBAAC,QAAD;OAAM,WAAW;OAAgB,UAAA,EAAO;MAAc,CAAA;MACtD,kBAAC,QAAD;OAAM,WAAW;OAAgB,UAAA,EAAO;MAAa,CAAA;MACrD,kBAAC,QAAD;OAAM,WAAW;OAAgB,UAAA,EAAO;MAAc,CAAA;MACtD,kBAAC,QAAD;OAAM,WAAW;OAAgB,UAAA,EAAO;MAAa,CAAA;KAClD;IACJ,CAAA,GAAA,EAAK,KAAK,MAEP,kBAAC,OAAD;KAAK,WAAW;KAAhB,UAAA;MACE,kBAAC,QAAD;OAAM,WAAW,EAAG,gCAAa,WAAY;OAC1C,UAAA,EAAI;MACD,CAAA;MACN,kBAAC,QAAD;OAAM,WAAW;OAAc,UAAA,EAAI,WAAW;MAAc,CAAA;MAC5D,kBAAC,QAAD;OAAM,WAAW;OAAc,UAAA,EAAI,UAAU;MAAc,CAAA;MAC3D,kBAAC,QAAD;OAAM,WAAW;OAAc,UAAA,EAAI,WAAW;MAAc,CAAA;MAC5D,kBAAC,QAAD;OAAM,WAAW;OACd,UAAA,EAAI,eAAe,EAAI,YAAY;MAChC,CAAA;KACH;IAV4B,GAAA,EAAI,EAUhC,CAER,CACE;GAEJ,CAAA,CAAA;;CACkB,CAAA;AAE7B"}
|
|
@@ -7,24 +7,24 @@ import { useBackofficeDashboardConfig as a } from "../provider/useBackofficeLazy
|
|
|
7
7
|
import { getWidgetLabel as o, resolveLabel as s } from "./BackofficeDashboardPage.helpers.js";
|
|
8
8
|
import { loadingBody as c, tileBody as l, tileCount as u } from "./backofficeDashboardPage.css.js";
|
|
9
9
|
import { Suspense as d, lazy as f, useMemo as p, useState as m } from "react";
|
|
10
|
-
import { DashboardGrid as h,
|
|
11
|
-
import { jsx as
|
|
12
|
-
import { useTranslation as
|
|
13
|
-
import { Spinner as
|
|
14
|
-
import { BackofficeEmptyState as
|
|
15
|
-
import { DetailPageTemplate as
|
|
10
|
+
import { DashboardGrid as h, DashboardPanel as g, DashboardQuickActions as _ } from "@plumile/ui";
|
|
11
|
+
import { jsx as v, jsxs as y } from "react/jsx-runtime";
|
|
12
|
+
import { useTranslation as b } from "react-i18next";
|
|
13
|
+
import { Spinner as x } from "@plumile/ui/backoffice/atoms/spinner/Spinner.js";
|
|
14
|
+
import { BackofficeEmptyState as S } from "@plumile/ui/backoffice/molecules/backoffice_empty_state/BackofficeEmptyState.js";
|
|
15
|
+
import { DetailPageTemplate as C } from "@plumile/ui/backoffice/templates/detail_page_template/DetailPageTemplate.js";
|
|
16
16
|
//#region src/pages/BackofficeDashboardPage.tsx
|
|
17
|
-
var
|
|
17
|
+
var w = f(async () => ({ default: (await import("./BackofficeDashboardWidgetContent.js")).BackofficeDashboardWidgetContent })), T = {
|
|
18
18
|
id: "24h",
|
|
19
19
|
label: (e) => e("common.time.lastDay", "24 h"),
|
|
20
20
|
durationMs: 864e5
|
|
21
|
-
},
|
|
21
|
+
}, E = [
|
|
22
22
|
{
|
|
23
23
|
id: "1h",
|
|
24
24
|
label: (e) => e("common.time.lastHour", "1 h"),
|
|
25
25
|
durationMs: 36e5
|
|
26
26
|
},
|
|
27
|
-
|
|
27
|
+
T,
|
|
28
28
|
{
|
|
29
29
|
id: "7d",
|
|
30
30
|
label: (e) => e("common.time.lastSevenDays", "7 j"),
|
|
@@ -35,20 +35,20 @@ var T = f(async () => ({ default: (await import("./BackofficeDashboardWidgetCont
|
|
|
35
35
|
label: (e) => e("common.time.lastThirtyDays", "30 j"),
|
|
36
36
|
durationMs: 2592e6
|
|
37
37
|
}
|
|
38
|
-
],
|
|
38
|
+
], D = () => {
|
|
39
39
|
let { t } = e();
|
|
40
|
-
return /* @__PURE__ */
|
|
41
|
-
},
|
|
40
|
+
return /* @__PURE__ */ v(S, { title: t("common.notAvailable") });
|
|
41
|
+
}, O = () => {
|
|
42
42
|
let { t } = e();
|
|
43
|
-
return /* @__PURE__ */
|
|
43
|
+
return /* @__PURE__ */ y("div", {
|
|
44
44
|
className: c,
|
|
45
|
-
children: [/* @__PURE__ */
|
|
45
|
+
children: [/* @__PURE__ */ v(x, { ariaLabel: t("common.loading") }), /* @__PURE__ */ v("span", { children: t("common.loading") })]
|
|
46
46
|
});
|
|
47
|
-
},
|
|
47
|
+
}, k = (e) => e ?? "m", A = (e) => {
|
|
48
48
|
if (e.layout?.span != null) return e.layout.span;
|
|
49
|
-
let t =
|
|
49
|
+
let t = k(e.size);
|
|
50
50
|
return t === "s" ? 3 : t === "m" ? 4 : t === "l" ? 6 : t === "xl" ? 8 : 12;
|
|
51
|
-
},
|
|
51
|
+
}, j = (e) => e.layout?.tabletSpan, M = (e) => e.windowPresets != null && e.windowPresets.length > 0 ? e.windowPresets : E, N = (e, t) => e.defaultWindowPresetId != null && t.some((t) => t.id === e.defaultWindowPresetId) ? e.defaultWindowPresetId : t[1]?.id ?? t[0]?.id ?? "24h", P = (e, t) => {
|
|
52
52
|
let n = new Date(t), r = new Date(t - e.durationMs);
|
|
53
53
|
return {
|
|
54
54
|
id: e.id,
|
|
@@ -56,73 +56,75 @@ var T = f(async () => ({ default: (await import("./BackofficeDashboardWidgetCont
|
|
|
56
56
|
from: r.toISOString(),
|
|
57
57
|
to: n.toISOString()
|
|
58
58
|
};
|
|
59
|
-
},
|
|
60
|
-
let { t: r } =
|
|
59
|
+
}, F = ({ config: t }) => {
|
|
60
|
+
let { t: r } = b(), { t: i } = e(), a = p(() => M(t), [t]), [c, l] = m(() => N(t, a)), [u, f] = m(() => Date.now()), _ = s(t.title, r), y = t.subtitle == null ? void 0 : s(t.subtitle, r), x = { window: P(a.find((e) => e.id === c) ?? a[0] ?? T, u) }, S = (e) => {
|
|
61
61
|
l(e), f(Date.now());
|
|
62
62
|
};
|
|
63
|
-
return /* @__PURE__ */
|
|
63
|
+
return /* @__PURE__ */ v(C, {
|
|
64
64
|
header: {
|
|
65
|
-
title:
|
|
66
|
-
subtitle:
|
|
65
|
+
title: _,
|
|
66
|
+
subtitle: y ?? i("dashboard.subtitle")
|
|
67
67
|
},
|
|
68
|
-
children: /* @__PURE__ */
|
|
68
|
+
children: /* @__PURE__ */ v(h, {
|
|
69
69
|
columns: 12,
|
|
70
|
-
|
|
70
|
+
items: t.widgets.map((e) => {
|
|
71
71
|
let i = s(o(e, t), r);
|
|
72
|
-
return
|
|
72
|
+
return {
|
|
73
|
+
key: e.id,
|
|
73
74
|
minHeight: e.minHeight ?? "auto",
|
|
74
|
-
span:
|
|
75
|
-
tabletSpan:
|
|
76
|
-
|
|
77
|
-
fallback: () => /* @__PURE__ */
|
|
75
|
+
span: A(e),
|
|
76
|
+
tabletSpan: j(e),
|
|
77
|
+
content: /* @__PURE__ */ v(n, {
|
|
78
|
+
fallback: () => /* @__PURE__ */ v(g, {
|
|
78
79
|
title: i,
|
|
79
|
-
children: /* @__PURE__ */
|
|
80
|
+
children: /* @__PURE__ */ v(D, {})
|
|
80
81
|
}),
|
|
81
|
-
children: /* @__PURE__ */
|
|
82
|
-
fallback: /* @__PURE__ */
|
|
82
|
+
children: /* @__PURE__ */ v(d, {
|
|
83
|
+
fallback: /* @__PURE__ */ v(g, {
|
|
83
84
|
title: i,
|
|
84
|
-
children: /* @__PURE__ */
|
|
85
|
+
children: /* @__PURE__ */ v(O, {})
|
|
85
86
|
}),
|
|
86
|
-
children: /* @__PURE__ */
|
|
87
|
+
children: /* @__PURE__ */ v(w, {
|
|
87
88
|
widget: e,
|
|
88
|
-
context:
|
|
89
|
+
context: x,
|
|
89
90
|
windowPresets: a,
|
|
90
91
|
activeWindowPresetId: c,
|
|
91
|
-
onWindowPresetChange:
|
|
92
|
+
onWindowPresetChange: S
|
|
92
93
|
})
|
|
93
94
|
})
|
|
94
95
|
})
|
|
95
|
-
}
|
|
96
|
+
};
|
|
96
97
|
})
|
|
97
98
|
})
|
|
98
99
|
});
|
|
99
|
-
},
|
|
100
|
-
let { t: o } =
|
|
100
|
+
}, I = ({ prepared: n }) => {
|
|
101
|
+
let { t: o } = b(), { t: c } = e(), { entities: d } = t(), f = a(), p = n?.config ?? f, m = i(c);
|
|
101
102
|
if (p == null) {
|
|
102
103
|
let e = Object.values(d).filter((e) => e.kind === "list-detail" && e.hasList).map((e) => ({
|
|
103
104
|
config: e,
|
|
104
105
|
label: s(e.label, o)
|
|
105
106
|
})).sort((e, t) => e.label.localeCompare(t.label));
|
|
106
|
-
return /* @__PURE__ */
|
|
107
|
+
return /* @__PURE__ */ v(r, {
|
|
107
108
|
breadcrumb: m,
|
|
108
|
-
children: /* @__PURE__ */
|
|
109
|
+
children: /* @__PURE__ */ v(C, {
|
|
109
110
|
header: {
|
|
110
111
|
title: c("dashboard.title"),
|
|
111
112
|
subtitle: c("dashboard.subtitle")
|
|
112
113
|
},
|
|
113
|
-
children: /* @__PURE__ */
|
|
114
|
+
children: /* @__PURE__ */ v(h, {
|
|
114
115
|
columns: 12,
|
|
115
|
-
|
|
116
|
+
items: e.map(({ config: e, label: t }) => ({
|
|
117
|
+
key: e.id,
|
|
116
118
|
span: 4,
|
|
117
|
-
|
|
119
|
+
content: /* @__PURE__ */ v(g, {
|
|
118
120
|
title: t,
|
|
119
|
-
children: /* @__PURE__ */
|
|
121
|
+
children: /* @__PURE__ */ y("div", {
|
|
120
122
|
className: l,
|
|
121
|
-
children: [/* @__PURE__ */
|
|
123
|
+
children: [/* @__PURE__ */ v("div", {
|
|
122
124
|
className: u,
|
|
123
125
|
children: c("common.notAvailable")
|
|
124
|
-
}), /* @__PURE__ */
|
|
125
|
-
emptyState: /* @__PURE__ */
|
|
126
|
+
}), /* @__PURE__ */ v(_, {
|
|
127
|
+
emptyState: /* @__PURE__ */ v(D, {}),
|
|
126
128
|
actions: [{
|
|
127
129
|
id: e.id,
|
|
128
130
|
href: e.routes.list,
|
|
@@ -131,17 +133,17 @@ var T = f(async () => ({ default: (await import("./BackofficeDashboardWidgetCont
|
|
|
131
133
|
})]
|
|
132
134
|
})
|
|
133
135
|
})
|
|
134
|
-
}
|
|
136
|
+
}))
|
|
135
137
|
})
|
|
136
138
|
})
|
|
137
139
|
});
|
|
138
140
|
}
|
|
139
|
-
return /* @__PURE__ */
|
|
141
|
+
return /* @__PURE__ */ v(r, {
|
|
140
142
|
breadcrumb: m,
|
|
141
|
-
children: /* @__PURE__ */
|
|
143
|
+
children: /* @__PURE__ */ v(F, { config: p })
|
|
142
144
|
});
|
|
143
145
|
};
|
|
144
146
|
//#endregion
|
|
145
|
-
export {
|
|
147
|
+
export { I as BackofficeDashboardPage, I as default };
|
|
146
148
|
|
|
147
149
|
//# sourceMappingURL=BackofficeDashboardPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BackofficeDashboardPage.js","names":[],"sources":["../../../src/pages/BackofficeDashboardPage.tsx"],"sourcesContent":["import { lazy, type JSX, Suspense, useMemo, useState } from 'react';\nimport type {\n BackofficeDashboardConfig,\n BackofficeDashboardContext,\n BackofficeDashboardWindowPreset,\n BackofficeDashboardWindowState,\n BackofficeDashboardWidget,\n BackofficeDashboardWidgetSpan,\n BackofficeDashboardWidgetTabletSpan,\n BackofficeDashboardWidgetSize,\n} from '@plumile/backoffice-core/types.js';\nimport { Spinner } from '@plumile/ui/backoffice/atoms/spinner/Spinner.js';\nimport { BackofficeEmptyState } from '@plumile/ui/backoffice/molecules/backoffice_empty_state/BackofficeEmptyState.js';\nimport { DetailPageTemplate } from '@plumile/ui/backoffice/templates/detail_page_template/DetailPageTemplate.js';\nimport {\n DashboardPanel,\n DashboardQuickActions,\n DashboardGrid,\n DashboardGridItem,\n} from '@plumile/ui';\nimport { useTranslation } from 'react-i18next';\n\nimport { BackofficeErrorBoundary } from '../components/backoffice/errors/BackofficeErrorBoundary.js';\nimport { useBackofficeReactTranslation } from '../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficeConfig } from '../provider/BackofficeConfigContext.js';\nimport { useBackofficeDashboardConfig } from '../provider/useBackofficeLazyValue.js';\nimport type { BackofficePreparedDashboardRoute } from '../router/createBackofficeRoutes.js';\nimport { BackofficeRightPageLayout } from '../components/backoffice/layout/breadcrumb/BackofficeRightPageLayout.js';\nimport { buildDashboardBreadcrumb } from '../components/backoffice/layout/breadcrumb/buildBreadcrumbs.js';\nimport {\n getWidgetLabel,\n resolveLabel,\n} from './BackofficeDashboardPage.helpers.js';\n\nimport * as styles from './backofficeDashboardPage.css.js';\n\nconst LazyBackofficeDashboardWidgetContent = lazy(async () => {\n const module = await import('./BackofficeDashboardWidgetContent.js');\n return {\n default: module.BackofficeDashboardWidgetContent,\n };\n});\n\nconst fallbackDashboardWindowPreset: BackofficeDashboardWindowPreset = {\n id: '24h',\n label: (t) => {\n return t('common.time.lastDay', '24 h');\n },\n durationMs: 24 * 60 * 60 * 1000,\n};\n\nconst defaultDashboardWindowPresets: readonly BackofficeDashboardWindowPreset[] =\n [\n {\n id: '1h',\n label: (t) => {\n return t('common.time.lastHour', '1 h');\n },\n durationMs: 60 * 60 * 1000,\n },\n fallbackDashboardWindowPreset,\n {\n id: '7d',\n label: (t) => {\n return t('common.time.lastSevenDays', '7 j');\n },\n durationMs: 7 * 24 * 60 * 60 * 1000,\n },\n {\n id: '30d',\n label: (t) => {\n return t('common.time.lastThirtyDays', '30 j');\n },\n durationMs: 30 * 24 * 60 * 60 * 1000,\n },\n ];\n\nconst DashboardUnavailableState = (): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n\n return <BackofficeEmptyState title={t('common.notAvailable')} />;\n};\n\nconst DashboardLoadingState = (): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n\n return (\n <div className={styles.loadingBody}>\n <Spinner ariaLabel={t('common.loading')} />\n <span>{t('common.loading')}</span>\n </div>\n );\n};\n\nconst resolveWidgetSize = (\n size: BackofficeDashboardWidgetSize | undefined,\n): BackofficeDashboardWidgetSize => {\n return size ?? 'm';\n};\n\nconst resolveWidgetSpan = (\n widget: BackofficeDashboardWidget,\n): BackofficeDashboardWidgetSpan => {\n if (widget.layout?.span != null) {\n return widget.layout.span;\n }\n\n const size = resolveWidgetSize(widget.size);\n if (size === 's') {\n return 3;\n }\n if (size === 'm') {\n return 4;\n }\n if (size === 'l') {\n return 6;\n }\n if (size === 'xl') {\n return 8;\n }\n return 12;\n};\n\nconst resolveWidgetTabletSpan = (\n widget: BackofficeDashboardWidget,\n): BackofficeDashboardWidgetTabletSpan | undefined => {\n return widget.layout?.tabletSpan;\n};\n\ntype DashboardContentProps = {\n config: BackofficeDashboardConfig;\n};\n\nconst resolveDashboardWindowPresets = (\n config: BackofficeDashboardConfig,\n): readonly BackofficeDashboardWindowPreset[] => {\n if (config.windowPresets != null && config.windowPresets.length > 0) {\n return config.windowPresets;\n }\n return defaultDashboardWindowPresets;\n};\n\nconst resolveDefaultDashboardWindowPresetId = (\n config: BackofficeDashboardConfig,\n presets: readonly BackofficeDashboardWindowPreset[],\n): string => {\n if (\n config.defaultWindowPresetId != null &&\n presets.some((preset) => {\n return preset.id === config.defaultWindowPresetId;\n })\n ) {\n return config.defaultWindowPresetId;\n }\n return presets[1]?.id ?? presets[0]?.id ?? '24h';\n};\n\nconst buildDashboardWindowState = (\n preset: BackofficeDashboardWindowPreset,\n nowMs: number,\n): BackofficeDashboardWindowState => {\n const to = new Date(nowMs);\n const from = new Date(nowMs - preset.durationMs);\n return {\n id: preset.id,\n label: preset.label,\n from: from.toISOString(),\n to: to.toISOString(),\n };\n};\n\nconst DashboardContent = ({ config }: DashboardContentProps): JSX.Element => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const presets = useMemo(() => {\n return resolveDashboardWindowPresets(config);\n }, [config]);\n const [activeWindowPresetId, setActiveWindowPresetId] = useState(() => {\n return resolveDefaultDashboardWindowPresetId(config, presets);\n });\n const [windowNowMs, setWindowNowMs] = useState(() => {\n return Date.now();\n });\n\n const title = resolveLabel(config.title, tApp);\n const subtitle =\n config.subtitle != null ? resolveLabel(config.subtitle, tApp) : undefined;\n const activePreset =\n presets.find((preset) => {\n return preset.id === activeWindowPresetId;\n }) ??\n presets[0] ??\n fallbackDashboardWindowPreset;\n const dashboardContext: BackofficeDashboardContext = {\n window: buildDashboardWindowState(activePreset, windowNowMs),\n };\n const handleWindowPresetChange = (presetId: string): void => {\n setActiveWindowPresetId(presetId);\n setWindowNowMs(Date.now());\n };\n\n return (\n <DetailPageTemplate\n header={{\n title,\n subtitle: subtitle ?? t('dashboard.subtitle'),\n }}\n >\n <DashboardGrid columns={12}>\n {config.widgets.map((widget) => {\n const widgetTitle = resolveLabel(\n getWidgetLabel(widget, config),\n tApp,\n );\n return (\n <DashboardGridItem\n key={widget.id}\n minHeight={widget.minHeight ?? 'auto'}\n span={resolveWidgetSpan(widget)}\n tabletSpan={resolveWidgetTabletSpan(widget)}\n >\n <BackofficeErrorBoundary\n fallback={() => {\n return (\n <DashboardPanel title={widgetTitle}>\n <DashboardUnavailableState />\n </DashboardPanel>\n );\n }}\n >\n <Suspense\n fallback={\n <DashboardPanel title={widgetTitle}>\n <DashboardLoadingState />\n </DashboardPanel>\n }\n >\n <LazyBackofficeDashboardWidgetContent\n widget={widget}\n context={dashboardContext}\n windowPresets={presets}\n activeWindowPresetId={activeWindowPresetId}\n onWindowPresetChange={handleWindowPresetChange}\n />\n </Suspense>\n </BackofficeErrorBoundary>\n </DashboardGridItem>\n );\n })}\n </DashboardGrid>\n </DetailPageTemplate>\n );\n};\n\nexport type BackofficeDashboardPageProps = {\n prepared?: BackofficePreparedDashboardRoute | null;\n};\n\nexport const BackofficeDashboardPage = ({\n prepared,\n}: BackofficeDashboardPageProps): JSX.Element => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const { entities } = useBackofficeConfig();\n const rootDashboard = useBackofficeDashboardConfig();\n const dashboard = prepared?.config ?? rootDashboard;\n const breadcrumb = buildDashboardBreadcrumb(t);\n\n if (dashboard == null) {\n const items = Object.values(entities)\n .filter((config) => {\n return config.kind === 'list-detail' && config.hasList;\n })\n .map((config) => {\n return {\n config,\n label: resolveLabel(config.label, tApp),\n };\n })\n .sort((left, right) => {\n return left.label.localeCompare(right.label);\n });\n\n return (\n <BackofficeRightPageLayout breadcrumb={breadcrumb}>\n <DetailPageTemplate\n header={{\n title: t('dashboard.title'),\n subtitle: t('dashboard.subtitle'),\n }}\n >\n <DashboardGrid columns={12}>\n {items.map(({ config, label }) => {\n return (\n <DashboardGridItem key={config.id} span={4}>\n <DashboardPanel title={label}>\n <div className={styles.tileBody}>\n <div className={styles.tileCount}>\n {t('common.notAvailable')}\n </div>\n <DashboardQuickActions\n emptyState={<DashboardUnavailableState />}\n actions={[\n {\n id: config.id,\n href: config.routes.list,\n label: t('dashboard.actions.openList'),\n },\n ]}\n />\n </div>\n </DashboardPanel>\n </DashboardGridItem>\n );\n })}\n </DashboardGrid>\n </DetailPageTemplate>\n </BackofficeRightPageLayout>\n );\n }\n\n return (\n <BackofficeRightPageLayout breadcrumb={breadcrumb}>\n <DashboardContent config={dashboard} />\n </BackofficeRightPageLayout>\n );\n};\n\nexport default BackofficeDashboardPage;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"BackofficeDashboardPage.js","names":[],"sources":["../../../src/pages/BackofficeDashboardPage.tsx"],"sourcesContent":["import { lazy, type JSX, Suspense, useMemo, useState } from 'react';\nimport type {\n BackofficeDashboardConfig,\n BackofficeDashboardContext,\n BackofficeDashboardWindowPreset,\n BackofficeDashboardWindowState,\n BackofficeDashboardWidget,\n BackofficeDashboardWidgetSpan,\n BackofficeDashboardWidgetTabletSpan,\n BackofficeDashboardWidgetSize,\n} from '@plumile/backoffice-core/types.js';\nimport { Spinner } from '@plumile/ui/backoffice/atoms/spinner/Spinner.js';\nimport { BackofficeEmptyState } from '@plumile/ui/backoffice/molecules/backoffice_empty_state/BackofficeEmptyState.js';\nimport { DetailPageTemplate } from '@plumile/ui/backoffice/templates/detail_page_template/DetailPageTemplate.js';\nimport {\n DashboardPanel,\n DashboardQuickActions,\n DashboardGrid,\n} from '@plumile/ui';\nimport { useTranslation } from 'react-i18next';\n\nimport { BackofficeErrorBoundary } from '../components/backoffice/errors/BackofficeErrorBoundary.js';\nimport { useBackofficeReactTranslation } from '../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficeConfig } from '../provider/BackofficeConfigContext.js';\nimport { useBackofficeDashboardConfig } from '../provider/useBackofficeLazyValue.js';\nimport type { BackofficePreparedDashboardRoute } from '../router/createBackofficeRoutes.js';\nimport { BackofficeRightPageLayout } from '../components/backoffice/layout/breadcrumb/BackofficeRightPageLayout.js';\nimport { buildDashboardBreadcrumb } from '../components/backoffice/layout/breadcrumb/buildBreadcrumbs.js';\nimport {\n getWidgetLabel,\n resolveLabel,\n} from './BackofficeDashboardPage.helpers.js';\n\nimport * as styles from './backofficeDashboardPage.css.js';\n\nconst LazyBackofficeDashboardWidgetContent = lazy(async () => {\n const module = await import('./BackofficeDashboardWidgetContent.js');\n return {\n default: module.BackofficeDashboardWidgetContent,\n };\n});\n\nconst fallbackDashboardWindowPreset: BackofficeDashboardWindowPreset = {\n id: '24h',\n label: (t) => {\n return t('common.time.lastDay', '24 h');\n },\n durationMs: 24 * 60 * 60 * 1000,\n};\n\nconst defaultDashboardWindowPresets: readonly BackofficeDashboardWindowPreset[] =\n [\n {\n id: '1h',\n label: (t) => {\n return t('common.time.lastHour', '1 h');\n },\n durationMs: 60 * 60 * 1000,\n },\n fallbackDashboardWindowPreset,\n {\n id: '7d',\n label: (t) => {\n return t('common.time.lastSevenDays', '7 j');\n },\n durationMs: 7 * 24 * 60 * 60 * 1000,\n },\n {\n id: '30d',\n label: (t) => {\n return t('common.time.lastThirtyDays', '30 j');\n },\n durationMs: 30 * 24 * 60 * 60 * 1000,\n },\n ];\n\nconst DashboardUnavailableState = (): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n\n return <BackofficeEmptyState title={t('common.notAvailable')} />;\n};\n\nconst DashboardLoadingState = (): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n\n return (\n <div className={styles.loadingBody}>\n <Spinner ariaLabel={t('common.loading')} />\n <span>{t('common.loading')}</span>\n </div>\n );\n};\n\nconst resolveWidgetSize = (\n size: BackofficeDashboardWidgetSize | undefined,\n): BackofficeDashboardWidgetSize => {\n return size ?? 'm';\n};\n\nconst resolveWidgetSpan = (\n widget: BackofficeDashboardWidget,\n): BackofficeDashboardWidgetSpan => {\n if (widget.layout?.span != null) {\n return widget.layout.span;\n }\n\n const size = resolveWidgetSize(widget.size);\n if (size === 's') {\n return 3;\n }\n if (size === 'm') {\n return 4;\n }\n if (size === 'l') {\n return 6;\n }\n if (size === 'xl') {\n return 8;\n }\n return 12;\n};\n\nconst resolveWidgetTabletSpan = (\n widget: BackofficeDashboardWidget,\n): BackofficeDashboardWidgetTabletSpan | undefined => {\n return widget.layout?.tabletSpan;\n};\n\ntype DashboardContentProps = {\n config: BackofficeDashboardConfig;\n};\n\nconst resolveDashboardWindowPresets = (\n config: BackofficeDashboardConfig,\n): readonly BackofficeDashboardWindowPreset[] => {\n if (config.windowPresets != null && config.windowPresets.length > 0) {\n return config.windowPresets;\n }\n return defaultDashboardWindowPresets;\n};\n\nconst resolveDefaultDashboardWindowPresetId = (\n config: BackofficeDashboardConfig,\n presets: readonly BackofficeDashboardWindowPreset[],\n): string => {\n if (\n config.defaultWindowPresetId != null &&\n presets.some((preset) => {\n return preset.id === config.defaultWindowPresetId;\n })\n ) {\n return config.defaultWindowPresetId;\n }\n return presets[1]?.id ?? presets[0]?.id ?? '24h';\n};\n\nconst buildDashboardWindowState = (\n preset: BackofficeDashboardWindowPreset,\n nowMs: number,\n): BackofficeDashboardWindowState => {\n const to = new Date(nowMs);\n const from = new Date(nowMs - preset.durationMs);\n return {\n id: preset.id,\n label: preset.label,\n from: from.toISOString(),\n to: to.toISOString(),\n };\n};\n\nconst DashboardContent = ({ config }: DashboardContentProps): JSX.Element => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const presets = useMemo(() => {\n return resolveDashboardWindowPresets(config);\n }, [config]);\n const [activeWindowPresetId, setActiveWindowPresetId] = useState(() => {\n return resolveDefaultDashboardWindowPresetId(config, presets);\n });\n const [windowNowMs, setWindowNowMs] = useState(() => {\n return Date.now();\n });\n\n const title = resolveLabel(config.title, tApp);\n const subtitle =\n config.subtitle != null ? resolveLabel(config.subtitle, tApp) : undefined;\n const activePreset =\n presets.find((preset) => {\n return preset.id === activeWindowPresetId;\n }) ??\n presets[0] ??\n fallbackDashboardWindowPreset;\n const dashboardContext: BackofficeDashboardContext = {\n window: buildDashboardWindowState(activePreset, windowNowMs),\n };\n const handleWindowPresetChange = (presetId: string): void => {\n setActiveWindowPresetId(presetId);\n setWindowNowMs(Date.now());\n };\n\n return (\n <DetailPageTemplate\n header={{\n title,\n subtitle: subtitle ?? t('dashboard.subtitle'),\n }}\n >\n <DashboardGrid\n columns={12}\n items={config.widgets.map((widget) => {\n const widgetTitle = resolveLabel(\n getWidgetLabel(widget, config),\n tApp,\n );\n return {\n key: widget.id,\n minHeight: widget.minHeight ?? 'auto',\n span: resolveWidgetSpan(widget),\n tabletSpan: resolveWidgetTabletSpan(widget),\n content: (\n <BackofficeErrorBoundary\n fallback={() => {\n return (\n <DashboardPanel title={widgetTitle}>\n <DashboardUnavailableState />\n </DashboardPanel>\n );\n }}\n >\n <Suspense\n fallback={\n <DashboardPanel title={widgetTitle}>\n <DashboardLoadingState />\n </DashboardPanel>\n }\n >\n <LazyBackofficeDashboardWidgetContent\n widget={widget}\n context={dashboardContext}\n windowPresets={presets}\n activeWindowPresetId={activeWindowPresetId}\n onWindowPresetChange={handleWindowPresetChange}\n />\n </Suspense>\n </BackofficeErrorBoundary>\n ),\n };\n })}\n />\n </DetailPageTemplate>\n );\n};\n\nexport type BackofficeDashboardPageProps = {\n prepared?: BackofficePreparedDashboardRoute | null;\n};\n\nexport const BackofficeDashboardPage = ({\n prepared,\n}: BackofficeDashboardPageProps): JSX.Element => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const { entities } = useBackofficeConfig();\n const rootDashboard = useBackofficeDashboardConfig();\n const dashboard = prepared?.config ?? rootDashboard;\n const breadcrumb = buildDashboardBreadcrumb(t);\n\n if (dashboard == null) {\n const items = Object.values(entities)\n .filter((config) => {\n return config.kind === 'list-detail' && config.hasList;\n })\n .map((config) => {\n return {\n config,\n label: resolveLabel(config.label, tApp),\n };\n })\n .sort((left, right) => {\n return left.label.localeCompare(right.label);\n });\n\n return (\n <BackofficeRightPageLayout breadcrumb={breadcrumb}>\n <DetailPageTemplate\n header={{\n title: t('dashboard.title'),\n subtitle: t('dashboard.subtitle'),\n }}\n >\n <DashboardGrid\n columns={12}\n items={items.map(({ config, label }) => {\n return {\n key: config.id,\n span: 4,\n content: (\n <DashboardPanel title={label}>\n <div className={styles.tileBody}>\n <div className={styles.tileCount}>\n {t('common.notAvailable')}\n </div>\n <DashboardQuickActions\n emptyState={<DashboardUnavailableState />}\n actions={[\n {\n id: config.id,\n href: config.routes.list,\n label: t('dashboard.actions.openList'),\n },\n ]}\n />\n </div>\n </DashboardPanel>\n ),\n };\n })}\n />\n </DetailPageTemplate>\n </BackofficeRightPageLayout>\n );\n }\n\n return (\n <BackofficeRightPageLayout breadcrumb={breadcrumb}>\n <DashboardContent config={dashboard} />\n </BackofficeRightPageLayout>\n );\n};\n\nexport default BackofficeDashboardPage;\n"],"mappings":"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"}
|