@burojs/ui-shadcn 0.6.0 → 0.8.0
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 +9 -0
- package/dist/bulk-summary-2HLgz7Il.cjs +169 -0
- package/dist/bulk-summary-2HLgz7Il.cjs.map +1 -0
- package/dist/bulk-summary-D6A0ua21.js +169 -0
- package/dist/bulk-summary-D6A0ua21.js.map +1 -0
- package/dist/{candidates-relation-picker-Cy0rTxvI.cjs → candidates-relation-picker-C47mF260.cjs} +4 -4
- package/dist/{candidates-relation-picker-Cy0rTxvI.cjs.map → candidates-relation-picker-C47mF260.cjs.map} +1 -1
- package/dist/{candidates-relation-picker-B116Bmqi.js → candidates-relation-picker-CGXItMN0.js} +3 -3
- package/dist/{candidates-relation-picker-B116Bmqi.js.map → candidates-relation-picker-CGXItMN0.js.map} +1 -1
- package/dist/{check-confirm-dialog--gPFnEeg.cjs → check-confirm-dialog-BT04Mieo.cjs} +475 -107
- package/dist/check-confirm-dialog-BT04Mieo.cjs.map +1 -0
- package/dist/{check-confirm-dialog-bRT8lt0d.js → check-confirm-dialog-CtiRzOAt.js} +391 -108
- package/dist/check-confirm-dialog-CtiRzOAt.js.map +1 -0
- package/dist/{dialog-B_rt9S1c.js → dialog-C123sVQ8.js} +4 -4
- package/dist/dialog-C123sVQ8.js.map +1 -0
- package/dist/{dialog-DRNUq9EA.cjs → dialog-vmMdfUWs.cjs} +3 -3
- package/dist/dialog-vmMdfUWs.cjs.map +1 -0
- package/dist/{filter-builder-nXqtM_h4.cjs → filter-builder-ByGhxLf_.cjs} +1021 -154
- package/dist/filter-builder-ByGhxLf_.cjs.map +1 -0
- package/dist/{filter-builder-Bhn-dhZV.js → filter-builder-z3Axzf9Y.js} +929 -140
- package/dist/filter-builder-z3Axzf9Y.js.map +1 -0
- package/dist/{flow-runtime-D3avVH0I.cjs → flow-runtime-BVFjMU5-.cjs} +64 -29
- package/dist/flow-runtime-BVFjMU5-.cjs.map +1 -0
- package/dist/{flow-runtime-s6lkRPKF.js → flow-runtime-DrUWyTS0.js} +65 -30
- package/dist/flow-runtime-DrUWyTS0.js.map +1 -0
- package/dist/{flow-screen-CCvgDI9G.js → flow-screen-3fk6J33y.js} +130 -87
- package/dist/flow-screen-3fk6J33y.js.map +1 -0
- package/dist/{flow-screen-Ci_Sik4Y.cjs → flow-screen-6y5E_HT6.cjs} +130 -87
- package/dist/flow-screen-6y5E_HT6.cjs.map +1 -0
- package/dist/index.cjs +1186 -950
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +631 -322
- package/dist/index.d.ts +631 -322
- package/dist/index.js +1100 -870
- package/dist/index.js.map +1 -1
- package/dist/{inline-flow-host-DV1et3c6.cjs → inline-flow-host-C4KmZIYE.cjs} +5 -5
- package/dist/inline-flow-host-C4KmZIYE.cjs.map +1 -0
- package/dist/{inline-flow-host-B6FI0ctQ.js → inline-flow-host-YnnvWjdU.js} +5 -5
- package/dist/inline-flow-host-YnnvWjdU.js.map +1 -0
- package/dist/{candidates-gate-D33jXLHO.cjs → lazy-relation-picker-dialog-BAKBRn3V.cjs} +10 -10
- package/dist/lazy-relation-picker-dialog-BAKBRn3V.cjs.map +1 -0
- package/dist/{candidates-gate-Bb70LPAy.js → lazy-relation-picker-dialog-DN4bvQfg.js} +11 -11
- package/dist/lazy-relation-picker-dialog-DN4bvQfg.js.map +1 -0
- package/dist/{page-flow-route-i3ZfJ1sd.js → page-flow-route-CtEfqAvU.js} +35 -23
- package/dist/page-flow-route-CtEfqAvU.js.map +1 -0
- package/dist/{page-flow-route-hdnULWqd.cjs → page-flow-route-DEjAxHe3.cjs} +42 -30
- package/dist/page-flow-route-DEjAxHe3.cjs.map +1 -0
- package/dist/{place-node-NraNYKPx.js → place-node-BdxT-30h.js} +1980 -1041
- package/dist/place-node-BdxT-30h.js.map +1 -0
- package/dist/{place-node-C5SmIAYU.cjs → place-node-Bhl8B3fF.cjs} +2038 -1087
- package/dist/place-node-Bhl8B3fF.cjs.map +1 -0
- package/dist/{related-list-cards-CFq3meUn.cjs → related-list-cards-Bc_vfCE_.cjs} +9 -4
- package/dist/{related-list-cards-CFq3meUn.cjs.map → related-list-cards-Bc_vfCE_.cjs.map} +1 -1
- package/dist/{related-list-cards-BWZ9GfOG.js → related-list-cards-BvkD5OcC.js} +9 -4
- package/dist/{related-list-cards-BWZ9GfOG.js.map → related-list-cards-BvkD5OcC.js.map} +1 -1
- package/dist/related-list-timeline-DCrwN9oO.js +167 -0
- package/dist/related-list-timeline-DCrwN9oO.js.map +1 -0
- package/dist/related-list-timeline-k0DtnxTs.cjs +167 -0
- package/dist/related-list-timeline-k0DtnxTs.cjs.map +1 -0
- package/dist/{related-rows-ea43qhhy.cjs → related-rows-BW9Jr07T.cjs} +27 -16
- package/dist/related-rows-BW9Jr07T.cjs.map +1 -0
- package/dist/{related-rows-o0_t-Yce.js → related-rows-CPE-9FFr.js} +25 -14
- package/dist/related-rows-CPE-9FFr.js.map +1 -0
- package/dist/{search-access-CPPmfuvy.js → relation-create-C43cdPQt.js} +595 -13
- package/dist/relation-create-C43cdPQt.js.map +1 -0
- package/dist/{search-access-Dugvttlg.cjs → relation-create-DDEYcKfw.cjs} +633 -14
- package/dist/relation-create-DDEYcKfw.cjs.map +1 -0
- package/dist/{relation-many-picker-bvkjkv-k.js → relation-many-picker-BlrGRwMV.js} +210 -104
- package/dist/relation-many-picker-BlrGRwMV.js.map +1 -0
- package/dist/{relation-many-picker-C8zFEjwd.cjs → relation-many-picker-Br-zBHxT.cjs} +218 -112
- package/dist/relation-many-picker-Br-zBHxT.cjs.map +1 -0
- package/dist/{relation-picker-gag0qSR5.cjs → relation-picker-ADjxI_TI.cjs} +36 -73
- package/dist/relation-picker-ADjxI_TI.cjs.map +1 -0
- package/dist/{relation-picker-dialog-B6nIiJBf.js → relation-picker-dialog-CyKliBkN.js} +134 -36
- package/dist/relation-picker-dialog-CyKliBkN.js.map +1 -0
- package/dist/{relation-picker-dialog-0IzkjmiA.cjs → relation-picker-dialog-DimVQF9Y.cjs} +133 -35
- package/dist/relation-picker-dialog-DimVQF9Y.cjs.map +1 -0
- package/dist/{relation-picker-Z0ZJJ5uS.js → relation-picker-x7P5HKie.js} +30 -61
- package/dist/relation-picker-x7P5HKie.js.map +1 -0
- package/dist/relation-select-B8Fq4o-t.js +48 -0
- package/dist/relation-select-B8Fq4o-t.js.map +1 -0
- package/dist/relation-select-Cr3CfNLy.cjs +55 -0
- package/dist/relation-select-Cr3CfNLy.cjs.map +1 -0
- package/dist/{resource-page-router-3RUf9d1j.js → resource-page-router-BRpUnhay.js} +634 -264
- package/dist/resource-page-router-BRpUnhay.js.map +1 -0
- package/dist/{resource-page-router-PXfMW9nh.cjs → resource-page-router-qEd2xb55.cjs} +694 -312
- package/dist/resource-page-router-qEd2xb55.cjs.map +1 -0
- package/dist/{rich-text-vTyVjDoa.cjs → rich-text-C_7JCvRo.cjs} +2 -2
- package/dist/{rich-text-vTyVjDoa.cjs.map → rich-text-C_7JCvRo.cjs.map} +1 -1
- package/dist/{rich-text-DFerywgz.js → rich-text-RcPBf6hr.js} +2 -2
- package/dist/{rich-text-DFerywgz.js.map → rich-text-RcPBf6hr.js.map} +1 -1
- package/dist/success-notices-Dl3M1fZP.cjs +46 -0
- package/dist/success-notices-Dl3M1fZP.cjs.map +1 -0
- package/dist/success-notices-LDEgEkc4.js +41 -0
- package/dist/success-notices-LDEgEkc4.js.map +1 -0
- package/dist/{toaster-Cr51X7bz.cjs → toaster-BbByOytP.cjs} +60 -15
- package/dist/toaster-BbByOytP.cjs.map +1 -0
- package/dist/{toaster-C02XbB9r.js → toaster-Ct_YHGs6.js} +43 -16
- package/dist/toaster-Ct_YHGs6.js.map +1 -0
- package/dist/{use-dialog-filter-state-C--oMAZG.js → use-dialog-filter-state-B_MqzHaT.js} +5 -4
- package/dist/use-dialog-filter-state-B_MqzHaT.js.map +1 -0
- package/dist/{use-dialog-filter-state-Dhe8PcB5.cjs → use-dialog-filter-state-tNvqAAjh.cjs} +6 -5
- package/dist/use-dialog-filter-state-tNvqAAjh.cjs.map +1 -0
- package/dist/use-record-subtitle-bfwIoUme.cjs +70 -0
- package/dist/use-record-subtitle-bfwIoUme.cjs.map +1 -0
- package/dist/use-record-subtitle-gIaCGgbI.js +53 -0
- package/dist/use-record-subtitle-gIaCGgbI.js.map +1 -0
- package/package.json +11 -11
- package/dist/bulk-summary-CwSd6Yjb.cjs +0 -108
- package/dist/bulk-summary-CwSd6Yjb.cjs.map +0 -1
- package/dist/bulk-summary-GxMDP4bw.js +0 -108
- package/dist/bulk-summary-GxMDP4bw.js.map +0 -1
- package/dist/candidates-gate-Bb70LPAy.js.map +0 -1
- package/dist/candidates-gate-D33jXLHO.cjs.map +0 -1
- package/dist/check-confirm-dialog--gPFnEeg.cjs.map +0 -1
- package/dist/check-confirm-dialog-bRT8lt0d.js.map +0 -1
- package/dist/dialog-B_rt9S1c.js.map +0 -1
- package/dist/dialog-DRNUq9EA.cjs.map +0 -1
- package/dist/filter-builder-Bhn-dhZV.js.map +0 -1
- package/dist/filter-builder-nXqtM_h4.cjs.map +0 -1
- package/dist/flow-runtime-D3avVH0I.cjs.map +0 -1
- package/dist/flow-runtime-s6lkRPKF.js.map +0 -1
- package/dist/flow-screen-CCvgDI9G.js.map +0 -1
- package/dist/flow-screen-Ci_Sik4Y.cjs.map +0 -1
- package/dist/inline-flow-host-B6FI0ctQ.js.map +0 -1
- package/dist/inline-flow-host-DV1et3c6.cjs.map +0 -1
- package/dist/page-flow-route-hdnULWqd.cjs.map +0 -1
- package/dist/page-flow-route-i3ZfJ1sd.js.map +0 -1
- package/dist/place-node-C5SmIAYU.cjs.map +0 -1
- package/dist/place-node-NraNYKPx.js.map +0 -1
- package/dist/related-list-timeline-CCzl71aA.cjs +0 -142
- package/dist/related-list-timeline-CCzl71aA.cjs.map +0 -1
- package/dist/related-list-timeline-yrPsjA3F.js +0 -142
- package/dist/related-list-timeline-yrPsjA3F.js.map +0 -1
- package/dist/related-rows-ea43qhhy.cjs.map +0 -1
- package/dist/related-rows-o0_t-Yce.js.map +0 -1
- package/dist/relation-create-IA40t1hi.cjs +0 -364
- package/dist/relation-create-IA40t1hi.cjs.map +0 -1
- package/dist/relation-create-h6F9B4C4.js +0 -339
- package/dist/relation-create-h6F9B4C4.js.map +0 -1
- package/dist/relation-many-picker-C8zFEjwd.cjs.map +0 -1
- package/dist/relation-many-picker-bvkjkv-k.js.map +0 -1
- package/dist/relation-picker-Z0ZJJ5uS.js.map +0 -1
- package/dist/relation-picker-dialog-0IzkjmiA.cjs.map +0 -1
- package/dist/relation-picker-dialog-B6nIiJBf.js.map +0 -1
- package/dist/relation-picker-gag0qSR5.cjs.map +0 -1
- package/dist/resource-page-router-3RUf9d1j.js.map +0 -1
- package/dist/resource-page-router-PXfMW9nh.cjs.map +0 -1
- package/dist/search-access-CPPmfuvy.js.map +0 -1
- package/dist/search-access-Dugvttlg.cjs.map +0 -1
- package/dist/shell-BPlk8hEa.js +0 -205
- package/dist/shell-BPlk8hEa.js.map +0 -1
- package/dist/shell-DxhlsPwm.cjs +0 -271
- package/dist/shell-DxhlsPwm.cjs.map +0 -1
- package/dist/toaster-C02XbB9r.js.map +0 -1
- package/dist/toaster-Cr51X7bz.cjs.map +0 -1
- package/dist/use-dialog-filter-state-C--oMAZG.js.map +0 -1
- package/dist/use-dialog-filter-state-Dhe8PcB5.cjs.map +0 -1
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
const
|
|
1
|
+
const require_use_theme = require("./use-theme-DFlpXils.cjs");
|
|
2
|
+
const require_toaster = require("./toaster-BbByOytP.cjs");
|
|
3
|
+
const require_check_confirm_dialog = require("./check-confirm-dialog-BT04Mieo.cjs");
|
|
2
4
|
const require_button = require("./button-BxnnE28H.cjs");
|
|
5
|
+
const require_relation_create = require("./relation-create-DDEYcKfw.cjs");
|
|
3
6
|
const require_skeleton = require("./skeleton-_1gP7wan.cjs");
|
|
4
|
-
const require_place_node = require("./place-node-
|
|
7
|
+
const require_place_node = require("./place-node-Bhl8B3fF.cjs");
|
|
8
|
+
const require_success_notices = require("./success-notices-Dl3M1fZP.cjs");
|
|
5
9
|
let _burojs_core = require("@burojs/core");
|
|
6
10
|
let _burojs_react = require("@burojs/react");
|
|
7
11
|
let react = require("react");
|
|
@@ -14,51 +18,104 @@ function canonicalResourceKey(def) {
|
|
|
14
18
|
return canonicalNavKey(def);
|
|
15
19
|
}
|
|
16
20
|
//#endregion
|
|
17
|
-
//#region src/layout/
|
|
18
|
-
function
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
21
|
+
//#region src/layout/layouts/secondary-sidebar-layout.tsx
|
|
22
|
+
function Row({ it }) {
|
|
23
|
+
const RouterLink = require_toaster.useLinkComponent();
|
|
24
|
+
return (0, react_jsx_runtime.jsx)("li", { children: (0, react_jsx_runtime.jsxs)(RouterLink, {
|
|
25
|
+
href: it.href,
|
|
26
|
+
"data-testid": `nav-secondary-item:${it.name}`,
|
|
27
|
+
"aria-current": it.active ? "page" : void 0,
|
|
28
|
+
className: require_use_theme.cn("flex items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium outline-hidden ring-offset-background transition-colors", "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2", it.active ? "bg-secondary text-secondary-foreground" : "text-muted-foreground hover:bg-secondary/50 hover:text-foreground"),
|
|
29
|
+
children: [it.icon != null && (0, react_jsx_runtime.jsx)("span", {
|
|
30
|
+
className: "inline-flex h-4 w-4 shrink-0 items-center justify-center",
|
|
31
|
+
"aria-hidden": "true",
|
|
32
|
+
children: it.icon
|
|
33
|
+
}), (0, react_jsx_runtime.jsx)("span", {
|
|
34
|
+
className: "truncate",
|
|
35
|
+
title: it.label,
|
|
36
|
+
children: it.label
|
|
37
|
+
})]
|
|
38
|
+
}) });
|
|
39
|
+
}
|
|
40
|
+
function SecondarySidebarLayout({ group, groupKey, items, children }) {
|
|
41
|
+
const RouterLink = require_toaster.useLinkComponent();
|
|
42
|
+
const caps = (0, _burojs_react.useI18nCaps)();
|
|
43
|
+
const id = groupKey ?? group.name;
|
|
44
|
+
const label = (0, _burojs_core.resolveNavLabel)(caps, `groups.${id}`, (0, _burojs_core.declaredText)("chrome", group, "label"));
|
|
45
|
+
return (0, react_jsx_runtime.jsxs)("div", {
|
|
46
|
+
className: "md:-m-6 md:flex md:min-h-[calc(100%+3rem)]",
|
|
47
|
+
"data-testid": `nav-secondary:${id}`,
|
|
48
|
+
children: [
|
|
49
|
+
(0, react_jsx_runtime.jsx)("aside", {
|
|
50
|
+
className: "hidden w-64 shrink-0 border-r bg-background text-foreground md:block",
|
|
51
|
+
children: (0, react_jsx_runtime.jsxs)("div", {
|
|
52
|
+
className: "space-y-4 p-4",
|
|
53
|
+
children: [(0, react_jsx_runtime.jsx)("p", {
|
|
54
|
+
className: "px-3 text-base font-semibold tracking-tight",
|
|
55
|
+
children: label
|
|
56
|
+
}), (0, react_jsx_runtime.jsx)("nav", {
|
|
57
|
+
"aria-label": label,
|
|
58
|
+
children: (0, react_jsx_runtime.jsx)("ul", {
|
|
59
|
+
className: "space-y-0.5",
|
|
60
|
+
children: items.map((it) => (0, react_jsx_runtime.jsx)(Row, { it }, it.name))
|
|
61
|
+
})
|
|
62
|
+
})]
|
|
63
|
+
})
|
|
64
|
+
}),
|
|
65
|
+
(0, react_jsx_runtime.jsx)("nav", {
|
|
66
|
+
"aria-label": label,
|
|
67
|
+
"data-testid": `nav-secondary-select:${id}`,
|
|
68
|
+
className: "-mx-1 mb-4 flex snap-x snap-proximity gap-1.5 overflow-x-auto scroll-smooth px-1 pb-1 [-ms-overflow-style:none] [mask-image:linear-gradient(to_right,transparent,black_8px,black_calc(100%-8px),transparent)] [scrollbar-width:none] md:hidden [&::-webkit-scrollbar]:hidden",
|
|
69
|
+
children: items.map((it) => (0, react_jsx_runtime.jsx)(RouterLink, {
|
|
70
|
+
href: it.href,
|
|
71
|
+
"aria-current": it.active ? "page" : void 0,
|
|
72
|
+
className: require_use_theme.cn("snap-start whitespace-nowrap rounded-full border px-3 py-1.5 text-sm outline-hidden ring-offset-background transition-colors duration-150", "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2", it.active ? "border-primary/40 bg-primary/10 font-medium text-foreground" : "border-border text-muted-foreground hover:bg-accent/60 hover:text-accent-foreground"),
|
|
73
|
+
children: it.label
|
|
74
|
+
}, it.name))
|
|
75
|
+
}),
|
|
76
|
+
(0, react_jsx_runtime.jsx)("div", {
|
|
77
|
+
className: "min-w-0 flex-1 md:overflow-x-hidden md:p-6",
|
|
78
|
+
children
|
|
79
|
+
})
|
|
80
|
+
]
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
//#endregion
|
|
84
|
+
//#region src/layout/layouts/tabs-layout.tsx
|
|
85
|
+
function TabsLayout({ group, groupKey, items, children }) {
|
|
86
|
+
const RouterLink = require_toaster.useLinkComponent();
|
|
87
|
+
const caps = (0, _burojs_react.useI18nCaps)();
|
|
88
|
+
const id = groupKey ?? group.name;
|
|
89
|
+
const label = (0, _burojs_core.resolveNavLabel)(caps, `groups.${id}`, (0, _burojs_core.declaredText)("chrome", group, "label"));
|
|
90
|
+
return (0, react_jsx_runtime.jsxs)("div", {
|
|
91
|
+
className: "flex flex-col gap-4",
|
|
92
|
+
"data-testid": `nav-tabs:${id}`,
|
|
93
|
+
children: [(0, react_jsx_runtime.jsx)("nav", {
|
|
94
|
+
"aria-label": label,
|
|
95
|
+
className: "flex gap-1 overflow-x-auto scroll-smooth border-b border-border [-ms-overflow-style:none] [mask-image:linear-gradient(to_right,transparent,black_8px,black_calc(100%-8px),transparent)] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
|
|
96
|
+
children: items.map((it) => (0, react_jsx_runtime.jsxs)(RouterLink, {
|
|
97
|
+
href: it.href,
|
|
98
|
+
"aria-current": it.active ? "page" : void 0,
|
|
99
|
+
"data-testid": `nav-tab:${it.name}`,
|
|
100
|
+
className: require_use_theme.cn("group/tab relative flex shrink-0 items-center gap-1.5 whitespace-nowrap rounded-t-sm px-3 py-2.5 text-sm outline-hidden ring-offset-background transition-colors duration-150", "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2", it.active ? "font-medium text-foreground" : "text-muted-foreground hover:text-foreground"),
|
|
101
|
+
children: [
|
|
102
|
+
it.icon != null && (0, react_jsx_runtime.jsx)("span", {
|
|
103
|
+
className: "inline-flex h-4 w-4 shrink-0 items-center justify-center",
|
|
104
|
+
"aria-hidden": "true",
|
|
105
|
+
children: it.icon
|
|
106
|
+
}),
|
|
107
|
+
it.label,
|
|
108
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
109
|
+
"aria-hidden": "true",
|
|
110
|
+
className: require_use_theme.cn("pointer-events-none absolute inset-x-2 -bottom-px h-0.5 origin-center scale-x-0 rounded-full bg-primary opacity-0 transition-all duration-300 ease-out", it.active ? "scale-x-100 opacity-100" : "group-hover/tab:scale-x-100 group-hover/tab:opacity-30")
|
|
111
|
+
})
|
|
112
|
+
]
|
|
113
|
+
}, it.name))
|
|
114
|
+
}), (0, react_jsx_runtime.jsx)("div", {
|
|
115
|
+
className: "min-w-0",
|
|
116
|
+
children
|
|
117
|
+
})]
|
|
118
|
+
});
|
|
62
119
|
}
|
|
63
120
|
//#endregion
|
|
64
121
|
//#region src/layout/nav-slots.ts
|
|
@@ -68,9 +125,33 @@ function layoutSlot(key) {
|
|
|
68
125
|
function useLayout(key) {
|
|
69
126
|
return (0, _burojs_react.useComponent)(layoutSlot(key));
|
|
70
127
|
}
|
|
128
|
+
const BUILTIN_LAYOUTS = {
|
|
129
|
+
[layoutSlot("secondary-sidebar")]: SecondarySidebarLayout,
|
|
130
|
+
[layoutSlot("tabs")]: TabsLayout
|
|
131
|
+
};
|
|
71
132
|
function useLayoutResolver() {
|
|
72
133
|
const components = (0, react.useContext)(_burojs_react.ComponentsContext);
|
|
73
|
-
return (key) => components[layoutSlot(key)];
|
|
134
|
+
return (key) => components[layoutSlot(key)] ?? BUILTIN_LAYOUTS[layoutSlot(key)];
|
|
135
|
+
}
|
|
136
|
+
const unresolvedLayoutReported = new WeakMap();
|
|
137
|
+
function useReportUnresolvedLayouts(groups, resolve) {
|
|
138
|
+
const app = (0, _burojs_react.useApp)();
|
|
139
|
+
(0, react.useEffect)(() => {
|
|
140
|
+
if (process.env.NODE_ENV === "production") return;
|
|
141
|
+
for (const group of groups) {
|
|
142
|
+
const layout = group.layout;
|
|
143
|
+
if (layout === "flat" || layout === "collapsible" || resolve(layout)) continue;
|
|
144
|
+
const key = canonicalNavKey(group);
|
|
145
|
+
let seen = unresolvedLayoutReported.get(app);
|
|
146
|
+
if (!seen) {
|
|
147
|
+
seen = new Set();
|
|
148
|
+
unresolvedLayoutReported.set(app, seen);
|
|
149
|
+
}
|
|
150
|
+
if (seen.has(key)) continue;
|
|
151
|
+
seen.add(key);
|
|
152
|
+
console.error(`[burojs] Nav group "${key}" declares layout "${layout}", and no renderer is registered for it. Register one as components["layout.${layout}"] on <BuroProvider>, or use a built-in layout: "secondary-sidebar", "tabs", "flat", "collapsible".`);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
74
155
|
}
|
|
75
156
|
//#endregion
|
|
76
157
|
//#region src/layout/use-nav-routing.ts
|
|
@@ -79,6 +160,10 @@ function useNavVisible() {
|
|
|
79
160
|
const allowed = usePageAllowed();
|
|
80
161
|
return (0, react.useCallback)((node) => (0, _burojs_core.evaluateVisible)(node.visible, ctx) && (!(0, _burojs_core.isCustomPageDef)(node) || allowed(node)), [ctx, allowed]);
|
|
81
162
|
}
|
|
163
|
+
function useResourceVisible() {
|
|
164
|
+
const ctx = (0, _burojs_react.useVisibilityCtx)();
|
|
165
|
+
return (0, react.useCallback)((def) => (0, _burojs_core.evaluateVisible)(def.visible, ctx), [ctx]);
|
|
166
|
+
}
|
|
82
167
|
function usePageAllowed() {
|
|
83
168
|
const permissions = (0, _burojs_react.usePermissions)();
|
|
84
169
|
return (0, react.useCallback)((page) => (0, _burojs_react.pageAccessFor)(page, permissions) === "allowed", [permissions]);
|
|
@@ -98,99 +183,17 @@ function useMatch() {
|
|
|
98
183
|
return path === void 0 ? null : (0, _burojs_core.matchPath)(app.registry, path, { isVisible });
|
|
99
184
|
}
|
|
100
185
|
//#endregion
|
|
101
|
-
//#region src/layout/nav-chrome-
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
function NavChromeBoundaryProvider({ claim, children }) {
|
|
107
|
-
const parent = (0, react.useContext)(NavChromeBoundaryContext);
|
|
108
|
-
const key = claim.join(" ");
|
|
109
|
-
const merged = (0, react.useMemo)(() => {
|
|
110
|
-
const s = new Set(parent);
|
|
111
|
-
for (const n of claim) s.add(n);
|
|
112
|
-
return s;
|
|
113
|
-
}, [parent, key]);
|
|
114
|
-
return (0, react_jsx_runtime.jsx)(NavChromeBoundaryContext.Provider, {
|
|
115
|
-
value: merged,
|
|
116
|
-
children
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
//#endregion
|
|
120
|
-
//#region src/layout/nav-chrome.tsx
|
|
121
|
-
const DETAIL_ACTIONS = new Set([
|
|
122
|
-
"show",
|
|
123
|
-
"edit",
|
|
124
|
-
"create"
|
|
125
|
-
]);
|
|
126
|
-
function NavChrome({ children, entryFilter, icons }) {
|
|
127
|
-
const app = (0, _burojs_react.useApp)();
|
|
128
|
-
const caps = (0, _burojs_react.useI18nCaps)();
|
|
129
|
-
const isVisible = useNavVisible();
|
|
130
|
-
const match = useMatch();
|
|
131
|
-
const resolveLayout = useLayoutResolver();
|
|
132
|
-
const boundary = useNavChromeBoundary();
|
|
133
|
-
if (!match) return (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children });
|
|
134
|
-
let content = children;
|
|
135
|
-
for (let i = match.groupChain.length - 1; i >= 0; i--) {
|
|
136
|
-
const group = match.groupChain[i];
|
|
137
|
-
if (!group) continue;
|
|
138
|
-
const groupKey = canonicalNavKey(group);
|
|
139
|
-
if (boundary.has(groupKey)) continue;
|
|
140
|
-
if (group.chromeOn === "list" && match.kind === "resource" && DETAIL_ACTIONS.has(match.action)) continue;
|
|
141
|
-
const Layout = resolveLayout(group.layout);
|
|
142
|
-
if (!Layout) continue;
|
|
143
|
-
const items = buildNavItems({
|
|
144
|
-
registry: app.registry,
|
|
145
|
-
caps,
|
|
146
|
-
groupName: groupKey,
|
|
147
|
-
match,
|
|
148
|
-
isVisible,
|
|
149
|
-
entryFilter,
|
|
150
|
-
icons
|
|
151
|
-
});
|
|
152
|
-
content = (0, react_jsx_runtime.jsx)(Layout, {
|
|
153
|
-
group,
|
|
154
|
-
groupKey,
|
|
155
|
-
items,
|
|
156
|
-
children: content
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
return (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: content });
|
|
160
|
-
}
|
|
161
|
-
//#endregion
|
|
162
|
-
//#region src/record/record-state.tsx
|
|
163
|
-
function RecordState({ state, onRetry }) {
|
|
164
|
-
const t = (0, _burojs_react.useT)();
|
|
165
|
-
if (state === "loading") return (0, react_jsx_runtime.jsx)("div", {
|
|
166
|
-
role: "status",
|
|
167
|
-
"aria-busy": "true",
|
|
168
|
-
"data-testid": "record-page:loading",
|
|
169
|
-
className: "p-6 text-sm text-muted-foreground",
|
|
170
|
-
children: t("router.recordLoading")
|
|
171
|
-
});
|
|
172
|
-
const message = state === "not-found" ? t("router.recordNotFound") : state === "session-expired" ? t("router.recordSessionExpired") : t("router.recordError");
|
|
173
|
-
return (0, react_jsx_runtime.jsxs)("div", {
|
|
174
|
-
role: "alert",
|
|
175
|
-
"data-testid": `record-page:${state}`,
|
|
176
|
-
className: "flex flex-col items-center justify-center gap-3 px-6 py-24 text-center",
|
|
177
|
-
children: [(0, react_jsx_runtime.jsx)("p", {
|
|
178
|
-
className: "max-w-sm text-sm text-muted-foreground",
|
|
179
|
-
children: message
|
|
180
|
-
}), onRetry ? (0, react_jsx_runtime.jsx)(require_button.Button, {
|
|
181
|
-
type: "button",
|
|
182
|
-
variant: "outline",
|
|
183
|
-
size: "sm",
|
|
184
|
-
"data-testid": "record-page:retry",
|
|
185
|
-
onClick: onRetry,
|
|
186
|
-
children: t("actions.retry")
|
|
187
|
-
}) : null]
|
|
188
|
-
});
|
|
186
|
+
//#region src/layout/nav-chrome-mounted.ts
|
|
187
|
+
const NavChromeMountedContext = (0, react.createContext)(false);
|
|
188
|
+
const NavChromeMountedProvider = NavChromeMountedContext.Provider;
|
|
189
|
+
function useNavChromeMounted() {
|
|
190
|
+
return (0, react.useContext)(NavChromeMountedContext);
|
|
189
191
|
}
|
|
190
192
|
//#endregion
|
|
191
193
|
//#region src/flows/page-flow-loader.tsx
|
|
192
194
|
function PageFlowRouteLoader({ match }) {
|
|
193
195
|
const t = (0, _burojs_react.useOptionalT)();
|
|
196
|
+
const chromeT = (0, _burojs_react.useChromeT)();
|
|
194
197
|
const loaded = require_check_confirm_dialog.useLoaded(require_check_confirm_dialog.loadPageFlowRoute);
|
|
195
198
|
const failed = (retry) => (0, react_jsx_runtime.jsxs)("div", {
|
|
196
199
|
role: "alert",
|
|
@@ -199,11 +202,11 @@ function PageFlowRouteLoader({ match }) {
|
|
|
199
202
|
children: [(0, react_jsx_runtime.jsx)("p", { children: require_check_confirm_dialog.loadFailedText(t) }), (0, react_jsx_runtime.jsx)("div", { children: (0, react_jsx_runtime.jsx)(require_button.Button, {
|
|
200
203
|
type: "button",
|
|
201
204
|
onClick: retry,
|
|
202
|
-
children:
|
|
205
|
+
children: chromeT("actions.retry", { defaultValue: "Retry" })
|
|
203
206
|
}) })]
|
|
204
207
|
});
|
|
205
208
|
if (loaded.error !== void 0) return failed(loaded.retry);
|
|
206
|
-
if (loaded.module === void 0) return (0, react_jsx_runtime.jsx)(RecordState, { state: "loading" });
|
|
209
|
+
if (loaded.module === void 0) return (0, react_jsx_runtime.jsx)(require_relation_create.RecordState, { state: "loading" });
|
|
207
210
|
const Route = loaded.module.PageFlowRoute;
|
|
208
211
|
return (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.FlowBoundary, {
|
|
209
212
|
fallback: (_error, reset) => failed(reset),
|
|
@@ -212,7 +215,8 @@ function PageFlowRouteLoader({ match }) {
|
|
|
212
215
|
}
|
|
213
216
|
//#endregion
|
|
214
217
|
//#region src/list-kit/resource-list-page.tsx
|
|
215
|
-
function ResourceListPage({ resource, meta, renderCell, emptyState }) {
|
|
218
|
+
function ResourceListPage({ resource: resourceInput, meta, renderCell, emptyState }) {
|
|
219
|
+
const resource = (0, _burojs_core.routeResourceKey)(resourceInput);
|
|
216
220
|
const app = (0, _burojs_react.useRouteListImplementation)();
|
|
217
221
|
const implementation = require_place_node.selectImplementation("buro:related-list", app);
|
|
218
222
|
const View = implementation === void 0 ? void 0 : require_place_node.viewOf(implementation);
|
|
@@ -251,7 +255,7 @@ function PageHost({ page, match, notFound }) {
|
|
|
251
255
|
const ctx = (0, _burojs_react.useVisibilityCtx)();
|
|
252
256
|
const access = (0, _burojs_react.usePageAccess)(page);
|
|
253
257
|
if (!((0, _burojs_core.evaluateVisible)(page.visible, ctx) && match.groupChain.every((group) => isVisible(group)))) return notFound;
|
|
254
|
-
if (access === "pending") return (0, react_jsx_runtime.jsx)(RecordState, { state: "loading" });
|
|
258
|
+
if (access === "pending") return (0, react_jsx_runtime.jsx)(require_relation_create.RecordState, { state: "loading" });
|
|
255
259
|
if (access === "denied") return notFound;
|
|
256
260
|
return (0, react_jsx_runtime.jsx)(PageParams, {
|
|
257
261
|
page,
|
|
@@ -290,7 +294,7 @@ function PageBody({ page }) {
|
|
|
290
294
|
children: [(0, react_jsx_runtime.jsx)("h1", {
|
|
291
295
|
className: "text-2xl font-semibold tracking-tight",
|
|
292
296
|
children: label
|
|
293
|
-
}), screen === null ? (0, react_jsx_runtime.jsx)(RecordState, { state: "error" }) : (0, react_jsx_runtime.jsx)(PageRouteScreen, { children: (0, react_jsx_runtime.jsx)(PlannedBody, {
|
|
297
|
+
}), screen === null ? (0, react_jsx_runtime.jsx)(require_relation_create.RecordState, { state: "error" }) : (0, react_jsx_runtime.jsx)(PageRouteScreen, { children: (0, react_jsx_runtime.jsx)(PlannedBody, {
|
|
294
298
|
screen,
|
|
295
299
|
name,
|
|
296
300
|
label
|
|
@@ -311,8 +315,9 @@ function PageRouteScreen({ children }) {
|
|
|
311
315
|
})
|
|
312
316
|
});
|
|
313
317
|
}
|
|
314
|
-
function PlannedBody({ screen, name, label }) {
|
|
315
|
-
const
|
|
318
|
+
function PlannedBody({ screen, name, label, record }) {
|
|
319
|
+
const pageOptions = (0, react.useMemo)(() => record === void 0 ? {} : { record }, [record]);
|
|
320
|
+
const page = (0, _burojs_react.usePageScreen)(screen, pageOptions);
|
|
316
321
|
const { PlacementScope } = page;
|
|
317
322
|
const route = (0, react.useContext)(_burojs_react.RouteSourceContext);
|
|
318
323
|
const catalog = (0, _burojs_react.useFrameImplementations)();
|
|
@@ -337,27 +342,23 @@ function PlannedBody({ screen, name, label }) {
|
|
|
337
342
|
};
|
|
338
343
|
return (0, react_jsx_runtime.jsx)(_burojs_react.RouteSourceContext.Provider, {
|
|
339
344
|
value: null,
|
|
340
|
-
children: (0, react_jsx_runtime.jsx)(
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
children: (0, react_jsx_runtime.jsx)(
|
|
346
|
-
|
|
347
|
-
children: (0, react_jsx_runtime.jsx)(
|
|
345
|
+
children: (0, react_jsx_runtime.jsx)(_burojs_react.ActionRouteContext.Provider, {
|
|
346
|
+
value: route,
|
|
347
|
+
children: (0, react_jsx_runtime.jsx)(PlacementScope, { children: (0, react_jsx_runtime.jsx)(require_place_node.DeepLinkScope, {
|
|
348
|
+
plan: page.plan,
|
|
349
|
+
enabled: true,
|
|
350
|
+
children: (0, react_jsx_runtime.jsx)("div", {
|
|
351
|
+
"data-buro-region": "page-body",
|
|
352
|
+
children: (0, react_jsx_runtime.jsx)(react.Suspense, {
|
|
353
|
+
fallback: null,
|
|
354
|
+
children: (0, react_jsx_runtime.jsx)(View, { ...viewProps })
|
|
355
|
+
})
|
|
348
356
|
})
|
|
349
|
-
})
|
|
350
|
-
})
|
|
357
|
+
}) })
|
|
358
|
+
})
|
|
351
359
|
});
|
|
352
360
|
}
|
|
353
361
|
//#endregion
|
|
354
|
-
//#region src/resource/form-context.tsx
|
|
355
|
-
const FormControlContext = (0, react.createContext)(null);
|
|
356
|
-
const FormControlProvider = FormControlContext.Provider;
|
|
357
|
-
function useFormControl() {
|
|
358
|
-
return (0, react.useContext)(FormControlContext);
|
|
359
|
-
}
|
|
360
|
-
//#endregion
|
|
361
362
|
//#region src/frames/obligations.tsx
|
|
362
363
|
const SlotMountsContext = (0, react.createContext)(null);
|
|
363
364
|
function useSlotOnce(slot) {
|
|
@@ -487,9 +488,9 @@ function timeAgo(savedAt, t) {
|
|
|
487
488
|
if (diff < 864e5) return t("draft.timeAgoHours", { count: Math.round(diff / 36e5) });
|
|
488
489
|
return t("draft.timeAgoDays", { count: Math.round(diff / 864e5) });
|
|
489
490
|
}
|
|
490
|
-
function frameRecordId(frame) {
|
|
491
|
+
function frameRecordId(frame, def) {
|
|
491
492
|
if (frame.recordId !== void 0) return frame.recordId;
|
|
492
|
-
const id = frame.record
|
|
493
|
+
const id = (0, _burojs_react.recordKeyOf)(def, frame.record);
|
|
493
494
|
return typeof id === "string" || typeof id === "number" ? String(id) : void 0;
|
|
494
495
|
}
|
|
495
496
|
function BodySlot() {
|
|
@@ -497,7 +498,7 @@ function BodySlot() {
|
|
|
497
498
|
const { resource, mode, controller } = frame;
|
|
498
499
|
const chrome = require_place_node.useFrameChrome();
|
|
499
500
|
const tid = (0, _burojs_react.useTestIds)();
|
|
500
|
-
const id = frameRecordId(frame);
|
|
501
|
+
const id = frameRecordId(frame, (0, _burojs_react.useApp)().registry.get(resource));
|
|
501
502
|
const tree = (0, react_jsx_runtime.jsx)("div", {
|
|
502
503
|
"data-buro-region": "record-body",
|
|
503
504
|
"data-buro-slot": _burojs_core.FORM_SLOT,
|
|
@@ -646,14 +647,14 @@ function RecordFrameView({ frame: instance }) {
|
|
|
646
647
|
...policyRecord ?? {},
|
|
647
648
|
id: typeof rowId === "string" || typeof rowId === "number" ? String(rowId) : ""
|
|
648
649
|
}), [policyRecord, rowId]);
|
|
649
|
-
const showItemActions = require_place_node.useShownItemActions(resource, actionRow, "show");
|
|
650
|
+
const showItemActions = require_place_node.useShownItemActions(resource, actionRow, "show", void 0, controller.sources);
|
|
650
651
|
const showActions = mode === "show" && record !== void 0 && showItemActions.length > 0;
|
|
651
652
|
const View = resolved.view;
|
|
652
653
|
const builtin = require_place_node.isBuiltinRecordView(resolved);
|
|
653
654
|
return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [builtin ? null : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(require_place_node.HeaderTypeNotice, { resource }), (0, react_jsx_runtime.jsx)(require_place_node.ChangeTypeButton, {})] }), (0, react_jsx_runtime.jsx)(require_place_node.TypeChromeDrawnContext.Provider, {
|
|
654
655
|
value: !builtin,
|
|
655
656
|
children: (0, react_jsx_runtime.jsx)(react.Suspense, {
|
|
656
|
-
fallback: (0, react_jsx_runtime.jsx)(RecordState, { state: "loading" }),
|
|
657
|
+
fallback: (0, react_jsx_runtime.jsx)(require_relation_create.RecordState, { state: "loading" }),
|
|
657
658
|
children: (0, react_jsx_runtime.jsx)(FrameObligations, {
|
|
658
659
|
id,
|
|
659
660
|
mode,
|
|
@@ -664,6 +665,156 @@ function RecordFrameView({ frame: instance }) {
|
|
|
664
665
|
})
|
|
665
666
|
})] });
|
|
666
667
|
}
|
|
668
|
+
function useResourceDimensionOptions(dimension, resource, labelField) {
|
|
669
|
+
const def = (0, _burojs_react.useApp)().registry.get(resource);
|
|
670
|
+
const rowTitle = require_relation_create.useRowTitle(resource, labelField ?? def?.displayField);
|
|
671
|
+
const rows = (0, _burojs_react.useList)(resource, {
|
|
672
|
+
pagination: {
|
|
673
|
+
kind: "offset",
|
|
674
|
+
page: 1,
|
|
675
|
+
pageSize: 100
|
|
676
|
+
},
|
|
677
|
+
total: false,
|
|
678
|
+
scope: {
|
|
679
|
+
default: "session",
|
|
680
|
+
dimensions: { [dimension]: "none" }
|
|
681
|
+
}
|
|
682
|
+
}).data?.data;
|
|
683
|
+
return (0, react.useMemo)(() => (rows ?? []).flatMap((row) => {
|
|
684
|
+
const key = (0, _burojs_react.recordKeyOf)(def, row);
|
|
685
|
+
return key === null || key === void 0 ? [] : [{
|
|
686
|
+
value: key,
|
|
687
|
+
label: rowTitle(row)
|
|
688
|
+
}];
|
|
689
|
+
}), [
|
|
690
|
+
rows,
|
|
691
|
+
def,
|
|
692
|
+
rowTitle
|
|
693
|
+
]);
|
|
694
|
+
}
|
|
695
|
+
//#endregion
|
|
696
|
+
//#region src/record/scope-mismatch-banner.tsx
|
|
697
|
+
const asList = (value) => value === null ? [] : Array.isArray(value) ? value : [value];
|
|
698
|
+
const isScalar = (value) => typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
699
|
+
function ScopeMismatchBanner(props) {
|
|
700
|
+
const app = (0, _burojs_react.useApp)();
|
|
701
|
+
const mapping = app.registry.get(props.resource)?.data?.scope;
|
|
702
|
+
if (app.scope === void 0 || mapping === void 0 || props.record === void 0) return null;
|
|
703
|
+
return (0, react_jsx_runtime.jsx)(Banner, {
|
|
704
|
+
...props,
|
|
705
|
+
record: props.record,
|
|
706
|
+
mapping
|
|
707
|
+
});
|
|
708
|
+
}
|
|
709
|
+
function Banner({ record, mapping, kind = "record" }) {
|
|
710
|
+
const scope = (0, _burojs_react.useScope)();
|
|
711
|
+
const chromeT = (0, _burojs_react.useChromeT)();
|
|
712
|
+
const differences = (0, react.useMemo)(() => {
|
|
713
|
+
const out = [];
|
|
714
|
+
for (const [dimension, target] of Object.entries(mapping)) {
|
|
715
|
+
const definition = scope.definition?.dimensions[dimension];
|
|
716
|
+
if (definition === void 0 || definition.select === "none") continue;
|
|
717
|
+
const selected = asList(scope.selection[dimension] ?? null);
|
|
718
|
+
if (selected.length === 0) continue;
|
|
719
|
+
const column = (0, _burojs_core.scopeColumnOf)(target);
|
|
720
|
+
if (!Object.hasOwn(record, column)) continue;
|
|
721
|
+
const held = record[column];
|
|
722
|
+
if (held === null || held === void 0 || held === "") {
|
|
723
|
+
if (kind === "created" || "field" in target && target.empty === "shared") continue;
|
|
724
|
+
out.push({
|
|
725
|
+
dimension,
|
|
726
|
+
value: null,
|
|
727
|
+
selected,
|
|
728
|
+
select: definition.select
|
|
729
|
+
});
|
|
730
|
+
continue;
|
|
731
|
+
}
|
|
732
|
+
if (!isScalar(held)) continue;
|
|
733
|
+
if (selected.some((value) => String(value) === String(held))) continue;
|
|
734
|
+
out.push({
|
|
735
|
+
dimension,
|
|
736
|
+
value: held,
|
|
737
|
+
selected,
|
|
738
|
+
select: definition.select
|
|
739
|
+
});
|
|
740
|
+
}
|
|
741
|
+
return out;
|
|
742
|
+
}, [
|
|
743
|
+
mapping,
|
|
744
|
+
record,
|
|
745
|
+
scope.definition,
|
|
746
|
+
scope.selection,
|
|
747
|
+
kind
|
|
748
|
+
]);
|
|
749
|
+
if (differences.length === 0) return null;
|
|
750
|
+
const apply = () => {
|
|
751
|
+
for (const difference of differences) scope.select(difference.dimension, difference.value === null ? null : difference.select === "multiple" ? [difference.value] : difference.value);
|
|
752
|
+
};
|
|
753
|
+
return (0, react_jsx_runtime.jsxs)("div", {
|
|
754
|
+
role: "status",
|
|
755
|
+
"data-testid": "scope-mismatch:banner",
|
|
756
|
+
className: "flex flex-wrap items-center justify-between gap-3 rounded-md border bg-muted/50 px-3 py-2 text-sm",
|
|
757
|
+
children: [(0, react_jsx_runtime.jsxs)("div", {
|
|
758
|
+
className: "space-y-1",
|
|
759
|
+
children: [(0, react_jsx_runtime.jsx)("p", {
|
|
760
|
+
className: "font-medium",
|
|
761
|
+
children: kind === "created" ? chromeT("scope.mismatch.createdOutside", { defaultValue: "Created outside the current scope" }) : chromeT("scope.mismatch.title", { defaultValue: "This record is outside the current scope" })
|
|
762
|
+
}), (0, react_jsx_runtime.jsx)("ul", {
|
|
763
|
+
className: "text-muted-foreground",
|
|
764
|
+
children: differences.map((difference) => (0, react_jsx_runtime.jsx)(DifferenceLine, {
|
|
765
|
+
difference,
|
|
766
|
+
definition: scope.definition.dimensions[difference.dimension]
|
|
767
|
+
}, difference.dimension))
|
|
768
|
+
})]
|
|
769
|
+
}), (0, react_jsx_runtime.jsx)(require_button.Button, {
|
|
770
|
+
type: "button",
|
|
771
|
+
size: "sm",
|
|
772
|
+
"data-testid": "scope-mismatch:switch",
|
|
773
|
+
onClick: apply,
|
|
774
|
+
children: chromeT("scope.mismatch.switch", { defaultValue: "Switch" })
|
|
775
|
+
})]
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
function DifferenceLine(props) {
|
|
779
|
+
const source = props.definition.values;
|
|
780
|
+
if (source !== void 0 && !Array.isArray(source)) {
|
|
781
|
+
const { resource, label } = source;
|
|
782
|
+
return (0, react_jsx_runtime.jsx)(ResourceLine, {
|
|
783
|
+
...props,
|
|
784
|
+
resource,
|
|
785
|
+
...label ? { labelField: label } : {}
|
|
786
|
+
});
|
|
787
|
+
}
|
|
788
|
+
return (0, react_jsx_runtime.jsx)(LineText, {
|
|
789
|
+
difference: props.difference,
|
|
790
|
+
options: source ?? []
|
|
791
|
+
});
|
|
792
|
+
}
|
|
793
|
+
function ResourceLine({ difference, resource, labelField }) {
|
|
794
|
+
const options = useResourceDimensionOptions(difference.dimension, resource, labelField);
|
|
795
|
+
return (0, react_jsx_runtime.jsx)(LineText, {
|
|
796
|
+
difference,
|
|
797
|
+
options
|
|
798
|
+
});
|
|
799
|
+
}
|
|
800
|
+
function LineText({ difference, options }) {
|
|
801
|
+
const chromeT = (0, _burojs_react.useChromeT)();
|
|
802
|
+
const labelOf = (value) => options.find((option) => String(option.value) === String(value))?.label ?? String(value);
|
|
803
|
+
const field = (0, _burojs_core.humanizeKey)(difference.dimension);
|
|
804
|
+
const item = difference.value === null ? chromeT("scope.mismatch.empty", { defaultValue: "not set" }) : labelOf(difference.value);
|
|
805
|
+
const items = difference.selected.map(labelOf).join(", ");
|
|
806
|
+
return (0, react_jsx_runtime.jsx)("li", {
|
|
807
|
+
"data-testid": `scope-mismatch:line:${difference.dimension}`,
|
|
808
|
+
children: chromeT("scope.mismatch.line", {
|
|
809
|
+
params: {
|
|
810
|
+
field,
|
|
811
|
+
item,
|
|
812
|
+
items
|
|
813
|
+
},
|
|
814
|
+
defaultValue: `${field}: ${item} (selected: ${items})`
|
|
815
|
+
})
|
|
816
|
+
});
|
|
817
|
+
}
|
|
667
818
|
//#endregion
|
|
668
819
|
//#region src/record/type-offer.tsx
|
|
669
820
|
function TypeOffer({ resource, offer, onChoose }) {
|
|
@@ -726,18 +877,41 @@ function isAbort(error) {
|
|
|
726
877
|
return false;
|
|
727
878
|
}
|
|
728
879
|
}
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
880
|
+
const NO_ISSUES = Object.freeze([]);
|
|
881
|
+
const APPLIED_UNREADABLE = Object.freeze({
|
|
882
|
+
code: "applied-unreadable",
|
|
883
|
+
message: Object.freeze({
|
|
884
|
+
key: "errors.appliedUnreadable",
|
|
885
|
+
default: "Saved. The server's answer could not be read, so the screen may not show the latest values."
|
|
886
|
+
}),
|
|
887
|
+
path: Object.freeze([]),
|
|
888
|
+
source: "server",
|
|
889
|
+
severity: "info"
|
|
890
|
+
});
|
|
891
|
+
function issuesOf(error) {
|
|
892
|
+
if (error === null || typeof error !== "object") return void 0;
|
|
893
|
+
try {
|
|
894
|
+
const descriptor = Object.getOwnPropertyDescriptor(error, "issues");
|
|
895
|
+
return descriptor !== void 0 && "value" in descriptor ? descriptor.value : void 0;
|
|
896
|
+
} catch {
|
|
897
|
+
return;
|
|
898
|
+
}
|
|
735
899
|
}
|
|
736
|
-
|
|
737
|
-
|
|
900
|
+
const NO_EDITED = new Set();
|
|
901
|
+
function sameValue(a, b) {
|
|
902
|
+
if (Object.is(a, b)) return true;
|
|
903
|
+
try {
|
|
904
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
905
|
+
} catch {
|
|
906
|
+
return false;
|
|
907
|
+
}
|
|
738
908
|
}
|
|
739
909
|
function RecordFrameHost(props) {
|
|
740
910
|
const { resource, mode } = props;
|
|
911
|
+
const [failed, setFailed] = (0, react.useState)(NO_ISSUES);
|
|
912
|
+
const named = (0, react.useMemo)(() => failed.length === 0 ? NO_ISSUES : (0, _burojs_core.routeServerIssues)({ issues: failed }, (segment) => segment, (field) => field !== "_form").fields, [failed]);
|
|
913
|
+
const atFailure = (0, react.useRef)({});
|
|
914
|
+
const [edited, setEdited] = (0, react.useState)(NO_EDITED);
|
|
741
915
|
const controller = (0, _burojs_react.useFormController)({
|
|
742
916
|
resource,
|
|
743
917
|
mode,
|
|
@@ -746,7 +920,8 @@ function RecordFrameHost(props) {
|
|
|
746
920
|
...props.record === void 0 ? {} : { record: props.record },
|
|
747
921
|
...props.defaults === void 0 ? {} : { defaults: props.defaults },
|
|
748
922
|
...props.onSubmit === void 0 ? {} : { onSubmit: props.onSubmit },
|
|
749
|
-
...props.hostTitle ? { entry: "quick" } : {}
|
|
923
|
+
...props.hostTitle ? { entry: "quick" } : {},
|
|
924
|
+
serverIssues: named
|
|
750
925
|
});
|
|
751
926
|
const inputApplied = (0, react.useRef)(false);
|
|
752
927
|
const { input } = props;
|
|
@@ -765,13 +940,32 @@ function RecordFrameHost(props) {
|
|
|
765
940
|
const formId = `record-form-${(0, react.useId)()}`;
|
|
766
941
|
const root = (0, react.useRef)(null);
|
|
767
942
|
const [submitError, setSubmitError] = (0, react.useState)(void 0);
|
|
943
|
+
const [submitApplied, setSubmitApplied] = (0, react.useState)(void 0);
|
|
944
|
+
(0, react.useEffect)(() => {
|
|
945
|
+
if (plan === null) return;
|
|
946
|
+
const now = Object.keys(atFailure.current).filter((name) => !edited.has(name) && plan.fields[name] === "active" && !sameValue(controller.field(name).value, atFailure.current[name]));
|
|
947
|
+
if (now.length > 0) setEdited((previous) => new Set([...previous, ...now]));
|
|
948
|
+
}, [
|
|
949
|
+
plan,
|
|
950
|
+
controller,
|
|
951
|
+
edited
|
|
952
|
+
]);
|
|
953
|
+
const notify = require_success_notices.useNoticeSink(resource);
|
|
954
|
+
const routeScreen = require_place_node.useIsRouteScreen();
|
|
955
|
+
const leavesOnCreate = mode === "create" && routeScreen;
|
|
956
|
+
const [created, setCreated] = (0, react.useState)(false);
|
|
957
|
+
const createdRef = (0, react.useRef)(false);
|
|
768
958
|
const latest = (0, react.useRef)({
|
|
769
959
|
controller,
|
|
770
|
-
onSuccess: props.onSuccess
|
|
960
|
+
onSuccess: props.onSuccess,
|
|
961
|
+
notify,
|
|
962
|
+
leavesOnCreate
|
|
771
963
|
});
|
|
772
964
|
latest.current = {
|
|
773
965
|
controller,
|
|
774
|
-
onSuccess: props.onSuccess
|
|
966
|
+
onSuccess: props.onSuccess,
|
|
967
|
+
notify,
|
|
968
|
+
leavesOnCreate
|
|
775
969
|
};
|
|
776
970
|
const mounted = (0, react.useRef)(true);
|
|
777
971
|
(0, react.useEffect)(() => {
|
|
@@ -781,29 +975,57 @@ function RecordFrameHost(props) {
|
|
|
781
975
|
};
|
|
782
976
|
}, []);
|
|
783
977
|
const submit = (0, react.useCallback)(async () => {
|
|
978
|
+
if (createdRef.current) return;
|
|
784
979
|
setSubmitError(void 0);
|
|
980
|
+
setSubmitApplied(void 0);
|
|
981
|
+
setFailed(NO_ISSUES);
|
|
982
|
+
setEdited(NO_EDITED);
|
|
983
|
+
atFailure.current = {};
|
|
785
984
|
const outcome = await latest.current.controller.submit();
|
|
786
985
|
if (!mounted.current) return;
|
|
787
|
-
if (outcome.status === "submitted"
|
|
788
|
-
|
|
986
|
+
if (latest.current.leavesOnCreate && (outcome.status === "submitted" || outcome.status === "failed" && outcome.applied === "yes")) {
|
|
987
|
+
createdRef.current = true;
|
|
988
|
+
setCreated(true);
|
|
989
|
+
}
|
|
990
|
+
if (outcome.status === "submitted") {
|
|
991
|
+
const notices = (0, _burojs_core.successNoticesOf)(outcome.result);
|
|
992
|
+
if (notices.length > 0) latest.current.notify(notices);
|
|
993
|
+
latest.current.onSuccess?.(outcome.result);
|
|
994
|
+
} else if (outcome.status === "failed" && outcome.applied === "yes") {
|
|
995
|
+
latest.current.notify([APPLIED_UNREADABLE]);
|
|
996
|
+
latest.current.onSuccess?.(void 0);
|
|
997
|
+
} else if (outcome.status === "failed" && !isAbort(outcome.error)) {
|
|
998
|
+
setSubmitError(outcome.error ?? null);
|
|
999
|
+
setSubmitApplied(outcome.applied);
|
|
1000
|
+
const issues = (0, _burojs_core.normalizeIssueInputs)(issuesOf(outcome.error)).issues;
|
|
1001
|
+
const next = issues.length === 0 ? NO_ISSUES : Object.freeze(issues.map(_burojs_core.issueOfInput));
|
|
1002
|
+
const held = {};
|
|
1003
|
+
const now = latest.current.controller;
|
|
1004
|
+
for (const issue of next) {
|
|
1005
|
+
const head = issue.path[0];
|
|
1006
|
+
if (typeof head === "string" && head !== "_form" && now.plan?.fields[head] === "active") held[head] = now.field(head).value;
|
|
1007
|
+
}
|
|
1008
|
+
atFailure.current = held;
|
|
1009
|
+
setFailed(next);
|
|
1010
|
+
}
|
|
789
1011
|
}, []);
|
|
790
1012
|
const record = controller.record;
|
|
1013
|
+
const recordText = props.recordId === void 0 ? void 0 : String(props.recordId);
|
|
791
1014
|
const frame = (0, react.useMemo)(() => ({
|
|
792
1015
|
resource,
|
|
793
|
-
recordId:
|
|
1016
|
+
recordId: recordText,
|
|
794
1017
|
mode,
|
|
795
1018
|
record,
|
|
796
1019
|
controller
|
|
797
1020
|
}), [
|
|
798
1021
|
resource,
|
|
799
|
-
|
|
1022
|
+
recordText,
|
|
800
1023
|
mode,
|
|
801
1024
|
record,
|
|
802
1025
|
controller
|
|
803
1026
|
]);
|
|
804
1027
|
const { chooseType } = props;
|
|
805
1028
|
const typedAndAccepted = mode === "create" && controller.typeOffer !== null && controller.failure === null;
|
|
806
|
-
const routeScreen = require_place_node.useIsRouteScreen();
|
|
807
1029
|
const adapter = (0, _burojs_react.useOptionalRouterAdapter)();
|
|
808
1030
|
const hostRouter = routeScreen ? adapter : null;
|
|
809
1031
|
const guardText = (0, _burojs_react.useNavigationGuardText)();
|
|
@@ -817,7 +1039,8 @@ function RecordFrameHost(props) {
|
|
|
817
1039
|
guardText.title,
|
|
818
1040
|
guardText.body
|
|
819
1041
|
]);
|
|
820
|
-
const
|
|
1042
|
+
const app = (0, _burojs_react.useApp)();
|
|
1043
|
+
const typesDecl = app.registry.get(resource)?.types;
|
|
821
1044
|
const loaded = controller.record;
|
|
822
1045
|
const unsupportedType = (0, react.useMemo)(() => {
|
|
823
1046
|
if (mode === "create" || typesDecl === void 0 || loaded === void 0) return void 0;
|
|
@@ -829,6 +1052,10 @@ function RecordFrameHost(props) {
|
|
|
829
1052
|
typesDecl,
|
|
830
1053
|
loaded
|
|
831
1054
|
]);
|
|
1055
|
+
const shownFailed = (0, react.useMemo)(() => edited.size === 0 ? failed : Object.freeze(failed.filter((issue) => {
|
|
1056
|
+
const head = issue.path[0];
|
|
1057
|
+
return typeof head !== "string" || !edited.has(head);
|
|
1058
|
+
})), [failed, edited]);
|
|
832
1059
|
const chrome = (0, react.useMemo)(() => ({
|
|
833
1060
|
...props.onCancel === void 0 ? {} : { onCancel: props.onCancel },
|
|
834
1061
|
...props.submitLabel === void 0 ? {} : { submitLabel: props.submitLabel },
|
|
@@ -838,6 +1065,9 @@ function RecordFrameHost(props) {
|
|
|
838
1065
|
...props.hostTitle ? { hostTitle: true } : {},
|
|
839
1066
|
formId,
|
|
840
1067
|
submitError,
|
|
1068
|
+
...submitApplied === void 0 ? {} : { submitApplied },
|
|
1069
|
+
serverIssues: shownFailed,
|
|
1070
|
+
...created ? { created: true } : {},
|
|
841
1071
|
submit,
|
|
842
1072
|
root
|
|
843
1073
|
}), [
|
|
@@ -849,6 +1079,9 @@ function RecordFrameHost(props) {
|
|
|
849
1079
|
props.hostTitle,
|
|
850
1080
|
formId,
|
|
851
1081
|
submitError,
|
|
1082
|
+
submitApplied,
|
|
1083
|
+
shownFailed,
|
|
1084
|
+
created,
|
|
852
1085
|
submit
|
|
853
1086
|
]);
|
|
854
1087
|
(0, _burojs_react.usePublishDocVariant)(mode === "show" ? resource : void 0, record);
|
|
@@ -863,45 +1096,51 @@ function RecordFrameHost(props) {
|
|
|
863
1096
|
resource,
|
|
864
1097
|
mode
|
|
865
1098
|
]);
|
|
866
|
-
const
|
|
867
|
-
|
|
868
|
-
}, []);
|
|
869
|
-
const formControl = (0, react.useMemo)(() => ({ setValues }), [setValues]);
|
|
870
|
-
const id = frameId(frame);
|
|
1099
|
+
const formControl = require_place_node.useFormControlOf(controller);
|
|
1100
|
+
const id = frameRecordId(frame, app.registry.get(frame.resource));
|
|
871
1101
|
const rootId = mode === "show" ? tid.pageShow(resource, id ?? "") : mode === "edit" ? tid.pageEdit(resource, id ?? "") : tid.pageCreate(resource);
|
|
1102
|
+
const claimedRoute = (0, react.useContext)(_burojs_react.RouteSourceContext);
|
|
872
1103
|
const scopeValues = mode === "show" ? controller.record : controller.values;
|
|
873
1104
|
return (0, react_jsx_runtime.jsx)(_burojs_react.RecordScopeProvider, {
|
|
874
1105
|
resource,
|
|
875
|
-
...
|
|
1106
|
+
...recordText === void 0 ? {} : { recordId: recordText },
|
|
876
1107
|
values: scopeValues,
|
|
1108
|
+
create: mode === "create",
|
|
877
1109
|
children: (0, react_jsx_runtime.jsx)(_burojs_react.RouteSourceContext.Provider, {
|
|
878
1110
|
value: null,
|
|
879
|
-
children: (0, react_jsx_runtime.jsx)(_burojs_react.
|
|
880
|
-
value:
|
|
881
|
-
children: (0, react_jsx_runtime.jsx)(
|
|
882
|
-
value:
|
|
883
|
-
children: (0, react_jsx_runtime.
|
|
884
|
-
value:
|
|
885
|
-
children:
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
"
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
1111
|
+
children: (0, react_jsx_runtime.jsx)(_burojs_react.ActionRouteContext.Provider, {
|
|
1112
|
+
value: claimedRoute,
|
|
1113
|
+
children: (0, react_jsx_runtime.jsx)(_burojs_react.RecordFrameContext.Provider, {
|
|
1114
|
+
value: frame,
|
|
1115
|
+
children: (0, react_jsx_runtime.jsx)(require_place_node.FrameChromeContext.Provider, {
|
|
1116
|
+
value: chrome,
|
|
1117
|
+
children: (0, react_jsx_runtime.jsxs)(require_place_node.FormControlProvider, {
|
|
1118
|
+
value: formControl,
|
|
1119
|
+
children: [(0, react_jsx_runtime.jsx)(require_place_node.DeepLinkScope, {
|
|
1120
|
+
plan: controller.plan,
|
|
1121
|
+
enabled: routeScreen && mode !== "create",
|
|
1122
|
+
children: (0, react_jsx_runtime.jsx)("div", {
|
|
1123
|
+
ref: root,
|
|
1124
|
+
"data-testid": rootId,
|
|
1125
|
+
className: "flex flex-col gap-[var(--buro-section-gap)]",
|
|
1126
|
+
children: offering && controller.typeOffer !== null ? (0, react_jsx_runtime.jsx)(TypeOffer, {
|
|
1127
|
+
resource,
|
|
1128
|
+
offer: controller.typeOffer,
|
|
1129
|
+
onChoose: (type) => chooseType(type)
|
|
1130
|
+
}) : failure !== null ? (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(require_relation_create.RecordState, { state: "error" }), (0, react_jsx_runtime.jsx)(require_place_node.FormActions, {})] }) : mode === "edit" && unsupportedType !== void 0 ? (0, react_jsx_runtime.jsx)(require_place_node.UndeclaredTypeNotice, {
|
|
1131
|
+
resource,
|
|
1132
|
+
typeValue: unsupportedType
|
|
1133
|
+
}) : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(ScopeMismatchBanner, {
|
|
1134
|
+
resource,
|
|
1135
|
+
record: mode === "create" ? controller.trustedSeeds : controller.record,
|
|
1136
|
+
kind: mode === "create" ? "created" : "record"
|
|
1137
|
+
}), (0, react_jsx_runtime.jsx)(RecordFrameView, { ...props.frame === void 0 ? {} : { frame: props.frame } })] })
|
|
1138
|
+
})
|
|
1139
|
+
}), controller.checkGate === null ? null : (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.CheckConfirmDialog, {
|
|
1140
|
+
state: controller.checkGate,
|
|
1141
|
+
testid: `${tid.form(resource, mode, id)}:checks`
|
|
1142
|
+
})]
|
|
1143
|
+
})
|
|
905
1144
|
})
|
|
906
1145
|
})
|
|
907
1146
|
})
|
|
@@ -913,7 +1152,8 @@ function RecordScreen(props) {
|
|
|
913
1152
|
const routeScreen = (0, react.useContext)(require_place_node.RouteScreenClaimContext);
|
|
914
1153
|
const quickScreen = (0, react.useContext)(require_place_node.QuickScreenClaimContext);
|
|
915
1154
|
const route = (0, react.useContext)(_burojs_react.RouteSourceContext);
|
|
916
|
-
const
|
|
1155
|
+
const resourceInput = props.resource;
|
|
1156
|
+
const resource = (0, _burojs_core.resourceKey)(resourceInput);
|
|
917
1157
|
const tabs = require_place_node.useTabsUrlState(props.mode, routeScreen);
|
|
918
1158
|
const adapter = (0, _burojs_react.useOptionalRouterAdapter)();
|
|
919
1159
|
const router = routeScreen ? adapter : null;
|
|
@@ -939,7 +1179,7 @@ function RecordScreen(props) {
|
|
|
939
1179
|
const query = params.toString();
|
|
940
1180
|
navigate(query === "" ? router.pathname : `${router.pathname}?${query}`);
|
|
941
1181
|
}, [router, navigate]);
|
|
942
|
-
if (app.registry.get(resource) === void 0) return (0, react_jsx_runtime.jsx)(RecordState, { state: "not-found" });
|
|
1182
|
+
if (app.registry.get(resource) === void 0) return (0, react_jsx_runtime.jsx)(require_relation_create.RecordState, { state: "not-found" });
|
|
943
1183
|
const { type: _declared, ...rest } = props;
|
|
944
1184
|
return (0, react_jsx_runtime.jsx)(require_place_node.RouteScreenClaimContext.Provider, {
|
|
945
1185
|
value: false,
|
|
@@ -1029,6 +1269,24 @@ function usePublishedRecordTrail(key) {
|
|
|
1029
1269
|
return current !== null && current.key === key ? current : null;
|
|
1030
1270
|
}
|
|
1031
1271
|
//#endregion
|
|
1272
|
+
//#region src/layout/record-targets.ts
|
|
1273
|
+
function isShowAvailable(registry, resource) {
|
|
1274
|
+
return (0, _burojs_react.recordRouteAvailable)(registry, resource, "show");
|
|
1275
|
+
}
|
|
1276
|
+
function showTarget(resource, id) {
|
|
1277
|
+
return {
|
|
1278
|
+
resource,
|
|
1279
|
+
action: "show",
|
|
1280
|
+
params: { id }
|
|
1281
|
+
};
|
|
1282
|
+
}
|
|
1283
|
+
function listTarget(resource) {
|
|
1284
|
+
return {
|
|
1285
|
+
resource,
|
|
1286
|
+
action: "list"
|
|
1287
|
+
};
|
|
1288
|
+
}
|
|
1289
|
+
//#endregion
|
|
1032
1290
|
//#region src/layout/route-trail.ts
|
|
1033
1291
|
function useTrailContext() {
|
|
1034
1292
|
const app = (0, _burojs_react.useApp)();
|
|
@@ -1056,7 +1314,8 @@ function groupCrumbs(ctx, chain) {
|
|
|
1056
1314
|
const key = canonicalNavKey(group);
|
|
1057
1315
|
return {
|
|
1058
1316
|
label: (0, _burojs_core.resolveNavLabel)(ctx.caps, `groups.${key}`, (0, _burojs_core.declaredText)("chrome", group, "label")),
|
|
1059
|
-
href: groupCrumbHref(ctx.registry, key, ctx.isVisible)
|
|
1317
|
+
href: groupCrumbHref(ctx.registry, key, ctx.isVisible),
|
|
1318
|
+
jump: true
|
|
1060
1319
|
};
|
|
1061
1320
|
});
|
|
1062
1321
|
}
|
|
@@ -1072,17 +1331,77 @@ function recordActionOf(match) {
|
|
|
1072
1331
|
default: return;
|
|
1073
1332
|
}
|
|
1074
1333
|
}
|
|
1334
|
+
function pathOf(href) {
|
|
1335
|
+
const path = href.split(/[?#]/, 1)[0] ?? "";
|
|
1336
|
+
return path.length > 1 && path.endsWith("/") ? path.slice(0, -1) : path;
|
|
1337
|
+
}
|
|
1338
|
+
function originTrail(ctx, origin, depth = _burojs_react.ORIGIN_DEPTH) {
|
|
1339
|
+
const match = (0, _burojs_core.matchPath)(ctx.registry, pathOf(origin.href), { isVisible: ctx.isVisible });
|
|
1340
|
+
if (match === null) return void 0;
|
|
1341
|
+
switch (match.kind) {
|
|
1342
|
+
case "resource": {
|
|
1343
|
+
const key = canonicalNavKey(match);
|
|
1344
|
+
if (match.action === "list") return {
|
|
1345
|
+
leading: groupCrumbs(ctx, match.groupChain),
|
|
1346
|
+
resource: key,
|
|
1347
|
+
resourceHref: origin.href,
|
|
1348
|
+
segments: []
|
|
1349
|
+
};
|
|
1350
|
+
const def = ctx.registry.get(key);
|
|
1351
|
+
const crumb = {
|
|
1352
|
+
label: match.action === "create" ? ctx.t("breadcrumbs.create") : origin.title || (match.id === void 0 ? "" : `#${match.id}`),
|
|
1353
|
+
href: origin.href
|
|
1354
|
+
};
|
|
1355
|
+
const parent = depth > 1 && origin.origin !== void 0 ? originTrail(ctx, origin.origin, depth - 1) : void 0;
|
|
1356
|
+
if (parent !== void 0) return {
|
|
1357
|
+
...parent,
|
|
1358
|
+
segments: [...parent.segments, crumb]
|
|
1359
|
+
};
|
|
1360
|
+
return {
|
|
1361
|
+
leading: groupCrumbs(ctx, match.groupChain),
|
|
1362
|
+
resource: key,
|
|
1363
|
+
...def !== void 0 && (0, _burojs_core.hasListPage)(def) ? { resourceHref: (0, _burojs_core.hrefFor)(ctx.registry, key) } : {},
|
|
1364
|
+
segments: [crumb]
|
|
1365
|
+
};
|
|
1366
|
+
}
|
|
1367
|
+
case "custom-page": {
|
|
1368
|
+
const trail = headerTrail(ctx, match);
|
|
1369
|
+
if (trail === null || trail.pageLabel === void 0) return void 0;
|
|
1370
|
+
return {
|
|
1371
|
+
leading: trail.leadingSegments ?? [],
|
|
1372
|
+
segments: [{
|
|
1373
|
+
label: trail.pageLabel,
|
|
1374
|
+
href: origin.href
|
|
1375
|
+
}]
|
|
1376
|
+
};
|
|
1377
|
+
}
|
|
1378
|
+
case "group-index": {
|
|
1379
|
+
const crumbs = groupCrumbs(ctx, match.groupChain);
|
|
1380
|
+
const own = crumbs[crumbs.length - 1];
|
|
1381
|
+
if (own === void 0) return void 0;
|
|
1382
|
+
return {
|
|
1383
|
+
leading: crumbs.slice(0, -1),
|
|
1384
|
+
segments: [{
|
|
1385
|
+
label: own.label,
|
|
1386
|
+
href: origin.href
|
|
1387
|
+
}]
|
|
1388
|
+
};
|
|
1389
|
+
}
|
|
1390
|
+
default: return;
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1075
1393
|
function recordTrail(ctx, input) {
|
|
1076
|
-
const { resource, action, id } = input;
|
|
1394
|
+
const { resource, action, id, origin } = input;
|
|
1395
|
+
if (origin !== void 0 && (action === "create" || id !== "")) return originRooted(ctx, input, origin);
|
|
1077
1396
|
const leadingSegments = nonEmpty(groupCrumbs(ctx, input.groupChain));
|
|
1078
1397
|
if (action !== "create" && id === "") return {
|
|
1079
1398
|
resource,
|
|
1080
1399
|
leadingSegments
|
|
1081
1400
|
};
|
|
1082
1401
|
const recordLabel = input.title || id;
|
|
1083
|
-
const middleSegments = action === "edit" ? [
|
|
1402
|
+
const middleSegments = action === "edit" ? [isShowAvailable(ctx.registry, resource) ? {
|
|
1084
1403
|
label: recordLabel,
|
|
1085
|
-
href: (0, _burojs_react.resolveRoute)(
|
|
1404
|
+
href: (0, _burojs_react.resolveRoute)(showTarget(resource, id), ctx.registry)
|
|
1086
1405
|
} : { label: recordLabel }] : void 0;
|
|
1087
1406
|
const pageLabel = action === "create" ? ctx.t("breadcrumbs.create") : action === "edit" ? ctx.t("breadcrumbs.edit") : recordLabel;
|
|
1088
1407
|
return {
|
|
@@ -1093,6 +1412,42 @@ function recordTrail(ctx, input) {
|
|
|
1093
1412
|
middleSegments
|
|
1094
1413
|
};
|
|
1095
1414
|
}
|
|
1415
|
+
function originRooted(ctx, input, origin) {
|
|
1416
|
+
const { resource, action, id } = input;
|
|
1417
|
+
const recordLabel = input.title || id;
|
|
1418
|
+
const drawn = new Set(origin.segments.flatMap((crumb) => crumb.href === void 0 ? [] : [pathOf(crumb.href)]));
|
|
1419
|
+
const own = action === "edit" ? [isShowAvailable(ctx.registry, resource) ? {
|
|
1420
|
+
label: recordLabel,
|
|
1421
|
+
href: (0, _burojs_react.resolveRoute)(showTarget(resource, id), ctx.registry)
|
|
1422
|
+
} : { label: recordLabel }].filter((crumb) => crumb.href === void 0 || !drawn.has(pathOf(crumb.href))) : [];
|
|
1423
|
+
const pageLabel = action === "create" ? ctx.t("breadcrumbs.create") : action === "edit" ? ctx.t("breadcrumbs.edit") : recordLabel;
|
|
1424
|
+
const recordId = action === "create" ? void 0 : id;
|
|
1425
|
+
const middleSegments = nonEmpty([...origin.segments, ...own]);
|
|
1426
|
+
if (origin.resource !== void 0 && ctx.registry.get(origin.resource) === ctx.registry.get(resource)) return {
|
|
1427
|
+
resource,
|
|
1428
|
+
recordId,
|
|
1429
|
+
pageLabel,
|
|
1430
|
+
leadingSegments: nonEmpty([...origin.leading]),
|
|
1431
|
+
...origin.resourceHref === void 0 ? {} : { resourceHref: origin.resourceHref },
|
|
1432
|
+
middleSegments
|
|
1433
|
+
};
|
|
1434
|
+
const def = origin.resource === void 0 ? void 0 : ctx.registry.get(origin.resource);
|
|
1435
|
+
const resourceCrumb = origin.resource === void 0 ? [] : [{
|
|
1436
|
+
label: (0, _burojs_core.resolveResourceLabel)(ctx.caps, origin.resource, "plural", def),
|
|
1437
|
+
...origin.resourceHref === void 0 ? {} : { href: origin.resourceHref }
|
|
1438
|
+
}];
|
|
1439
|
+
return {
|
|
1440
|
+
resource,
|
|
1441
|
+
recordId,
|
|
1442
|
+
pageLabel,
|
|
1443
|
+
rootSegments: [
|
|
1444
|
+
...origin.leading,
|
|
1445
|
+
...resourceCrumb,
|
|
1446
|
+
...origin.segments,
|
|
1447
|
+
...own
|
|
1448
|
+
]
|
|
1449
|
+
};
|
|
1450
|
+
}
|
|
1096
1451
|
function recordTrailRoute(registry, match) {
|
|
1097
1452
|
if (match === null || match.kind !== "resource") return null;
|
|
1098
1453
|
const resource = canonicalNavKey(match);
|
|
@@ -1105,7 +1460,7 @@ function recordTrailRoute(registry, match) {
|
|
|
1105
1460
|
groupChain
|
|
1106
1461
|
};
|
|
1107
1462
|
const action = recordActionOf(match);
|
|
1108
|
-
if (action === void 0 || !
|
|
1463
|
+
if (action === void 0 || !(0, _burojs_react.recordRouteAvailable)(registry, resource, action)) return null;
|
|
1109
1464
|
return {
|
|
1110
1465
|
resource,
|
|
1111
1466
|
action,
|
|
@@ -1175,24 +1530,18 @@ function parse(raw) {
|
|
|
1175
1530
|
return [];
|
|
1176
1531
|
}
|
|
1177
1532
|
}
|
|
1178
|
-
function readRecentRecords(userId) {
|
|
1179
|
-
|
|
1180
|
-
try {
|
|
1181
|
-
return parse(window.localStorage.getItem(recentStorageKey(userId)));
|
|
1182
|
-
} catch {
|
|
1183
|
-
return [];
|
|
1184
|
-
}
|
|
1533
|
+
function readRecentRecords(store, userId) {
|
|
1534
|
+
return (0, _burojs_react.maybeThen)((0, _burojs_react.settle)(() => store.get(recentStorageKey(userId)), null), parse);
|
|
1185
1535
|
}
|
|
1186
|
-
function writeRecentRecord(userId, entry) {
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
const key = recentStorageKey(userId);
|
|
1536
|
+
function writeRecentRecord(store, userId, entry) {
|
|
1537
|
+
const key = recentStorageKey(userId);
|
|
1538
|
+
return (0, _burojs_react.maybeThen)((0, _burojs_react.settle)(() => store.get(key), null), (raw) => {
|
|
1190
1539
|
const envelope = {
|
|
1191
1540
|
version: 2,
|
|
1192
|
-
items: [entry, ...parse(
|
|
1541
|
+
items: [entry, ...parse(raw).filter((item) => !(item.canonicalRef === entry.canonicalRef && item.id === entry.id))].slice(0, 5)
|
|
1193
1542
|
};
|
|
1194
|
-
|
|
1195
|
-
}
|
|
1543
|
+
return (0, _burojs_react.settle)(() => store.set(key, JSON.stringify(envelope)), void 0);
|
|
1544
|
+
});
|
|
1196
1545
|
}
|
|
1197
1546
|
function text(value) {
|
|
1198
1547
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
@@ -1218,10 +1567,12 @@ function recentLabel(record, id, isGuarded = () => false) {
|
|
|
1218
1567
|
//#region src/layout/use-record-visit.ts
|
|
1219
1568
|
function useRecordVisit(resource, record, opts) {
|
|
1220
1569
|
const userId = (0, _burojs_react.useCurrentUserId)();
|
|
1221
|
-
const
|
|
1222
|
-
const id = typeof raw === "string" || typeof raw === "number" ? String(raw) : void 0;
|
|
1570
|
+
const store = (0, _burojs_react.usePlatformStorage)().local;
|
|
1223
1571
|
const app = (0, _burojs_react.useApp)();
|
|
1224
|
-
const
|
|
1572
|
+
const def = app.registry.get(resource);
|
|
1573
|
+
const raw = (0, _burojs_react.recordKeyOf)(def, record);
|
|
1574
|
+
const id = typeof raw === "string" || typeof raw === "number" ? String(raw) : void 0;
|
|
1575
|
+
const fields = def?.fields;
|
|
1225
1576
|
const rules = app.ruleSource?.rules(resource) ?? [];
|
|
1226
1577
|
const isGuarded = (field) => fields !== void 0 && Object.hasOwn(fields, field) && (0, _burojs_core.fieldSensitivity)(fields[field]) !== void 0 || (0, _burojs_core.addressesCapability)(rules, "view", {
|
|
1227
1578
|
kind: "field",
|
|
@@ -1235,7 +1586,7 @@ function useRecordVisit(resource, record, opts) {
|
|
|
1235
1586
|
(0, react.useEffect)(() => {
|
|
1236
1587
|
if (userId === null || !isCurrentData || id === void 0 || id === "") return;
|
|
1237
1588
|
if (label === void 0) return;
|
|
1238
|
-
writeRecentRecord(userId, {
|
|
1589
|
+
writeRecentRecord(store, userId, {
|
|
1239
1590
|
canonicalRef,
|
|
1240
1591
|
id,
|
|
1241
1592
|
label,
|
|
@@ -1243,6 +1594,7 @@ function useRecordVisit(resource, record, opts) {
|
|
|
1243
1594
|
at: new Date().toISOString()
|
|
1244
1595
|
});
|
|
1245
1596
|
}, [
|
|
1597
|
+
store,
|
|
1246
1598
|
userId,
|
|
1247
1599
|
isCurrentData,
|
|
1248
1600
|
canonicalRef,
|
|
@@ -1253,12 +1605,6 @@ function useRecordVisit(resource, record, opts) {
|
|
|
1253
1605
|
}
|
|
1254
1606
|
//#endregion
|
|
1255
1607
|
//#region src/layout/record-page.tsx
|
|
1256
|
-
function recordErrorState(error) {
|
|
1257
|
-
const { kind } = (0, _burojs_core.normalizeDataError)(error);
|
|
1258
|
-
if (kind === "not-found" || kind === "forbidden") return "not-found";
|
|
1259
|
-
if (kind === "auth") return "session-expired";
|
|
1260
|
-
return "error";
|
|
1261
|
-
}
|
|
1262
1608
|
function useMountedRef() {
|
|
1263
1609
|
const mounted = (0, react.useRef)(true);
|
|
1264
1610
|
(0, react.useEffect)(() => {
|
|
@@ -1281,7 +1627,7 @@ function RecordRouteHeader({ resource, action, id, record }) {
|
|
|
1281
1627
|
...action === "create" ? {} : { recordName }
|
|
1282
1628
|
});
|
|
1283
1629
|
}
|
|
1284
|
-
function RecordShow({ resource, id, record, shown }) {
|
|
1630
|
+
function RecordShow({ resource, id, recordId, record, shown }) {
|
|
1285
1631
|
return (0, react_jsx_runtime.jsxs)("div", { children: [(0, react_jsx_runtime.jsx)(RecordRouteHeader, {
|
|
1286
1632
|
resource,
|
|
1287
1633
|
action: "show",
|
|
@@ -1290,15 +1636,14 @@ function RecordShow({ resource, id, record, shown }) {
|
|
|
1290
1636
|
}), (0, react_jsx_runtime.jsx)(RecordScreen, {
|
|
1291
1637
|
resource,
|
|
1292
1638
|
mode: "show",
|
|
1293
|
-
recordId
|
|
1639
|
+
recordId,
|
|
1294
1640
|
record
|
|
1295
1641
|
})] });
|
|
1296
1642
|
}
|
|
1297
|
-
function RecordEdit({ resource, id, record, shown }) {
|
|
1298
|
-
const app = (0, _burojs_react.useApp)();
|
|
1643
|
+
function RecordEdit({ resource, id, recordId, record, shown }) {
|
|
1299
1644
|
const navigate = (0, _burojs_react.useRouteNavigate)();
|
|
1300
1645
|
const mounted = useMountedRef();
|
|
1301
|
-
const back =
|
|
1646
|
+
const back = (0, _burojs_react.useReturnTarget)(resource, "edit", id);
|
|
1302
1647
|
return (0, react_jsx_runtime.jsxs)("div", { children: [(0, react_jsx_runtime.jsx)(RecordRouteHeader, {
|
|
1303
1648
|
resource,
|
|
1304
1649
|
action: "edit",
|
|
@@ -1307,11 +1652,11 @@ function RecordEdit({ resource, id, record, shown }) {
|
|
|
1307
1652
|
}), (0, react_jsx_runtime.jsx)(RecordScreen, {
|
|
1308
1653
|
resource,
|
|
1309
1654
|
mode: "edit",
|
|
1310
|
-
recordId
|
|
1655
|
+
recordId,
|
|
1311
1656
|
record,
|
|
1312
|
-
onCancel: () => navigate(back),
|
|
1657
|
+
onCancel: () => navigate(back, { origin: "inherit" }),
|
|
1313
1658
|
onSuccess: () => {
|
|
1314
|
-
if (mounted.current) navigate(back);
|
|
1659
|
+
if (mounted.current) navigate(back, { origin: "inherit" });
|
|
1315
1660
|
}
|
|
1316
1661
|
})] });
|
|
1317
1662
|
}
|
|
@@ -1324,7 +1669,8 @@ function RecordCreate({ resource, defaults }) {
|
|
|
1324
1669
|
const navigate = (0, _burojs_react.useRouteNavigate)();
|
|
1325
1670
|
const mounted = useMountedRef();
|
|
1326
1671
|
const adapter = (0, _burojs_react.useOptionalRouterAdapter)();
|
|
1327
|
-
const list =
|
|
1672
|
+
const list = listTarget(resource);
|
|
1673
|
+
const back = (0, _burojs_react.useReturnTarget)(resource, "create");
|
|
1328
1674
|
const type = adapter?.searchParams.get("type") ?? void 0;
|
|
1329
1675
|
return (0, react_jsx_runtime.jsxs)("div", { children: [(0, react_jsx_runtime.jsx)(RecordRouteHeader, {
|
|
1330
1676
|
resource,
|
|
@@ -1337,21 +1683,21 @@ function RecordCreate({ resource, defaults }) {
|
|
|
1337
1683
|
mode: "create",
|
|
1338
1684
|
...type === void 0 ? {} : { type },
|
|
1339
1685
|
...defaults === void 0 ? {} : { defaults },
|
|
1340
|
-
onCancel: () => navigate(
|
|
1686
|
+
onCancel: () => navigate(back, { origin: "inherit" }),
|
|
1341
1687
|
onSuccess: (result) => {
|
|
1342
1688
|
if (!mounted.current) return;
|
|
1343
1689
|
const id = createdId(result);
|
|
1344
|
-
navigate(id
|
|
1690
|
+
navigate(id !== void 0 && isShowAvailable(app.registry, resource) ? showTarget(resource, id) : list, { origin: "inherit" });
|
|
1345
1691
|
}
|
|
1346
1692
|
})
|
|
1347
1693
|
})] });
|
|
1348
1694
|
}
|
|
1349
|
-
function RecordRead({ resource, action, id }) {
|
|
1695
|
+
function RecordRead({ resource, action, id, recordId }) {
|
|
1350
1696
|
const app = (0, _burojs_react.useApp)();
|
|
1351
1697
|
const def = app.registry.get(resource);
|
|
1352
1698
|
const projection = (0, react.useMemo)(() => def === void 0 ? void 0 : (0, _burojs_core.dtoFields)(def, "record"), [def]);
|
|
1353
1699
|
const query = (0, _burojs_react.useOne)(resource, {
|
|
1354
|
-
id,
|
|
1700
|
+
id: recordId,
|
|
1355
1701
|
retry: _burojs_react.retryRecordRead,
|
|
1356
1702
|
...projection === void 0 ? {} : { projection }
|
|
1357
1703
|
});
|
|
@@ -1371,18 +1717,18 @@ function RecordRead({ resource, action, id }) {
|
|
|
1371
1717
|
const availability = (0, _burojs_react.useAvailabilityResolver)(resource, "edit");
|
|
1372
1718
|
if (result !== void 0) {
|
|
1373
1719
|
const record = result.data;
|
|
1374
|
-
if (record === null || typeof record !== "object") return (0, react_jsx_runtime.jsx)(RecordState, { state: "not-found" });
|
|
1720
|
+
if (record === null || typeof record !== "object") return (0, react_jsx_runtime.jsx)(require_relation_create.RecordState, { state: "not-found" });
|
|
1375
1721
|
const loaded = record;
|
|
1376
1722
|
if (showRuled) {
|
|
1377
|
-
if (query.isPlaceholderData || permissions?.status === "loading") return (0, react_jsx_runtime.jsx)(RecordState, { state: "loading" });
|
|
1378
|
-
if (permissions?.status === "error") return (0, react_jsx_runtime.jsx)(RecordState, { state: "not-found" });
|
|
1379
|
-
if (showHidden) return (0, react_jsx_runtime.jsx)(RecordState, { state: "not-found" });
|
|
1723
|
+
if (query.isPlaceholderData || permissions?.status === "loading") return (0, react_jsx_runtime.jsx)(require_relation_create.RecordState, { state: "loading" });
|
|
1724
|
+
if (permissions?.status === "error") return (0, react_jsx_runtime.jsx)(require_relation_create.RecordState, { state: "not-found" });
|
|
1725
|
+
if (showHidden) return (0, react_jsx_runtime.jsx)(require_relation_create.RecordState, { state: "not-found" });
|
|
1380
1726
|
}
|
|
1381
|
-
if (projected.status === "pending" || projected.value === null) return (0, react_jsx_runtime.jsx)(RecordState, { state: "loading" });
|
|
1727
|
+
if (projected.status === "pending" || projected.value === null) return (0, react_jsx_runtime.jsx)(require_relation_create.RecordState, { state: "loading" });
|
|
1382
1728
|
const shown = projected.value;
|
|
1383
1729
|
if (action === "edit") {
|
|
1384
1730
|
const edit = availability("edit", loaded).state;
|
|
1385
|
-
if (edit === "hidden" || edit === "absent") return (0, react_jsx_runtime.jsx)(RecordState, { state: "not-found" });
|
|
1731
|
+
if (edit === "hidden" || edit === "absent") return (0, react_jsx_runtime.jsx)(require_relation_create.RecordState, { state: "not-found" });
|
|
1386
1732
|
}
|
|
1387
1733
|
return (0, react_jsx_runtime.jsx)(_burojs_react.RouteSourceContext.Provider, {
|
|
1388
1734
|
value: route,
|
|
@@ -1391,30 +1737,39 @@ function RecordRead({ resource, action, id }) {
|
|
|
1391
1737
|
children: action === "edit" ? (0, react_jsx_runtime.jsx)(RecordEdit, {
|
|
1392
1738
|
resource,
|
|
1393
1739
|
id,
|
|
1740
|
+
recordId,
|
|
1394
1741
|
record: loaded,
|
|
1395
1742
|
shown
|
|
1396
1743
|
}) : (0, react_jsx_runtime.jsx)(RecordShow, {
|
|
1397
1744
|
resource,
|
|
1398
1745
|
id,
|
|
1746
|
+
recordId,
|
|
1399
1747
|
record: loaded,
|
|
1400
1748
|
shown
|
|
1401
1749
|
})
|
|
1402
1750
|
})
|
|
1403
1751
|
});
|
|
1404
1752
|
}
|
|
1405
|
-
if (query.error != null) {
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
}
|
|
1412
|
-
return (0, react_jsx_runtime.jsx)(RecordState, { state: "loading" });
|
|
1753
|
+
if (query.error != null) return (0, react_jsx_runtime.jsx)(require_relation_create.LoadError, {
|
|
1754
|
+
surface: "record",
|
|
1755
|
+
resource,
|
|
1756
|
+
error: query.error,
|
|
1757
|
+
retry: () => void query.refetch()
|
|
1758
|
+
});
|
|
1759
|
+
return (0, react_jsx_runtime.jsx)(require_relation_create.RecordState, { state: "loading" });
|
|
1413
1760
|
}
|
|
1414
1761
|
function RecordRouteBody(props) {
|
|
1415
1762
|
if (props.action === "create") return (0, react_jsx_runtime.jsx)(RecordCreate, { ...props });
|
|
1416
|
-
if (props.id === "") return (0, react_jsx_runtime.jsx)(RecordState, { state: "not-found" });
|
|
1417
|
-
return (0, react_jsx_runtime.jsx)(
|
|
1763
|
+
if (props.id === "") return (0, react_jsx_runtime.jsx)(require_relation_create.RecordState, { state: "not-found" });
|
|
1764
|
+
return (0, react_jsx_runtime.jsx)(RecordReadRoute, { ...props });
|
|
1765
|
+
}
|
|
1766
|
+
function RecordReadRoute(props) {
|
|
1767
|
+
const recordId = (0, _burojs_react.useRouteRecordId)(props.resource, props.id);
|
|
1768
|
+
if (recordId === void 0) return (0, react_jsx_runtime.jsx)(require_relation_create.InvalidRouteId, { resource: props.resource });
|
|
1769
|
+
return (0, react_jsx_runtime.jsx)(RecordRead, {
|
|
1770
|
+
...props,
|
|
1771
|
+
recordId
|
|
1772
|
+
});
|
|
1418
1773
|
}
|
|
1419
1774
|
function RecordRoute(props) {
|
|
1420
1775
|
const missingRuntime = (0, _burojs_react.useOptionalDataRuntime)() === null;
|
|
@@ -1422,7 +1777,7 @@ function RecordRoute(props) {
|
|
|
1422
1777
|
if (!missingRuntime || process.env.NODE_ENV === "production") return;
|
|
1423
1778
|
console.error(`[burojs] The '${props.resource}' record page has no data runtime to read or write with: BuroProvider.dataRuntime is not set. Pass <BuroProvider dataRuntime={…}> (createDataRuntime from @burojs/react); until then record routes render the error state.`);
|
|
1424
1779
|
}, [missingRuntime, props.resource]);
|
|
1425
|
-
if (missingRuntime) return (0, react_jsx_runtime.jsx)(RecordState, { state: "error" });
|
|
1780
|
+
if (missingRuntime) return (0, react_jsx_runtime.jsx)(require_relation_create.RecordState, { state: "error" });
|
|
1426
1781
|
return (0, react_jsx_runtime.jsx)(RecordRouteBody, { ...props }, `${props.resource}:${props.id}`);
|
|
1427
1782
|
}
|
|
1428
1783
|
function recordPageProblem(input) {
|
|
@@ -1437,7 +1792,8 @@ function RecordPage(props) {
|
|
|
1437
1792
|
const app = (0, _burojs_react.useApp)();
|
|
1438
1793
|
const match = useMatch();
|
|
1439
1794
|
const id = match === null ? null : match.id ?? "";
|
|
1440
|
-
const {
|
|
1795
|
+
const { action } = props;
|
|
1796
|
+
const resource = props.resource === void 0 ? void 0 : (0, _burojs_core.routeResourceKey)(props.resource);
|
|
1441
1797
|
const onRecordRoute = recordActionOf(match) !== void 0;
|
|
1442
1798
|
const problem = recordPageProblem({
|
|
1443
1799
|
props,
|
|
@@ -1456,7 +1812,7 @@ function RecordPage(props) {
|
|
|
1456
1812
|
logged.add(problem);
|
|
1457
1813
|
console.error(problem);
|
|
1458
1814
|
}, [app, problem]);
|
|
1459
|
-
if (resource === void 0 || action === void 0 || id === null || !onRecordRoute) return (0, react_jsx_runtime.jsx)(RecordState, { state: "not-found" });
|
|
1815
|
+
if (resource === void 0 || action === void 0 || id === null || !onRecordRoute) return (0, react_jsx_runtime.jsx)(require_relation_create.RecordState, { state: "not-found" });
|
|
1460
1816
|
const route = action === "create" ? {
|
|
1461
1817
|
resource,
|
|
1462
1818
|
action,
|
|
@@ -1503,7 +1859,7 @@ function ResourcePageRouter({ match }) {
|
|
|
1503
1859
|
}
|
|
1504
1860
|
if (match.action === "flow") return (0, react_jsx_runtime.jsx)(PageFlowRouteLoader, { match });
|
|
1505
1861
|
if (recordAction === void 0) return (0, react_jsx_runtime.jsx)(ResourcePageRouterEmpty, {});
|
|
1506
|
-
if (!
|
|
1862
|
+
if (!(0, _burojs_react.recordRouteAvailable)(app.registry, resource, recordAction)) return (0, react_jsx_runtime.jsx)(NavAreaNotFound, {});
|
|
1507
1863
|
return (0, react_jsx_runtime.jsx)(RecordRoute, {
|
|
1508
1864
|
resource,
|
|
1509
1865
|
action: recordAction,
|
|
@@ -1567,10 +1923,24 @@ function NavAreaNotFound() {
|
|
|
1567
1923
|
});
|
|
1568
1924
|
}
|
|
1569
1925
|
const adapterNoticeGiven = new WeakSet();
|
|
1926
|
+
const chromeNoticeGiven = new WeakSet();
|
|
1570
1927
|
function NavAreaPage() {
|
|
1571
1928
|
const match = useMatch();
|
|
1572
1929
|
const app = (0, _burojs_react.useApp)();
|
|
1573
1930
|
const noAdapter = (0, _burojs_react.useOptionalRouterAdapter)() === null;
|
|
1931
|
+
const chromeMounted = useNavChromeMounted();
|
|
1932
|
+
const resolveLayout = useLayoutResolver();
|
|
1933
|
+
const chromeGroup = match?.groupChain.find((g) => resolveLayout(g.layout)) ?? null;
|
|
1934
|
+
(0, react.useEffect)(() => {
|
|
1935
|
+
if (process.env.NODE_ENV === "production") return;
|
|
1936
|
+
if (chromeMounted || !chromeGroup || chromeNoticeGiven.has(app)) return;
|
|
1937
|
+
chromeNoticeGiven.add(app);
|
|
1938
|
+
console.error(`[burojs] <NavAreaPage> is inside the nav group "${canonicalNavKey(chromeGroup)}" whose layout "${chromeGroup.layout}" draws area chrome, and no <NavChrome> is mounted above it. <AppShell> mounts one by default; with your own frame, wrap your routes in <NavChrome>.`);
|
|
1939
|
+
}, [
|
|
1940
|
+
app,
|
|
1941
|
+
chromeMounted,
|
|
1942
|
+
chromeGroup
|
|
1943
|
+
]);
|
|
1574
1944
|
(0, react.useEffect)(() => {
|
|
1575
1945
|
if (!noAdapter || process.env.NODE_ENV === "production") return;
|
|
1576
1946
|
if (adapterNoticeGiven.has(app)) return;
|
|
@@ -1579,32 +1949,32 @@ function NavAreaPage() {
|
|
|
1579
1949
|
}, [app, noAdapter]);
|
|
1580
1950
|
return (0, react_jsx_runtime.jsx)(react.Suspense, {
|
|
1581
1951
|
fallback: (0, react_jsx_runtime.jsx)(NavAreaPageSkeleton, {}),
|
|
1582
|
-
children: match ? (0, react_jsx_runtime.jsx)(
|
|
1952
|
+
children: match ? (0, react_jsx_runtime.jsx)(ResourcePageRouter, { match }) : (0, react_jsx_runtime.jsx)(NavAreaNotFound, {})
|
|
1583
1953
|
});
|
|
1584
1954
|
}
|
|
1585
1955
|
//#endregion
|
|
1586
|
-
Object.defineProperty(exports, "
|
|
1956
|
+
Object.defineProperty(exports, "BUILTIN_LAYOUTS", {
|
|
1587
1957
|
enumerable: true,
|
|
1588
1958
|
get: function() {
|
|
1589
|
-
return
|
|
1959
|
+
return BUILTIN_LAYOUTS;
|
|
1590
1960
|
}
|
|
1591
1961
|
});
|
|
1592
|
-
Object.defineProperty(exports, "
|
|
1962
|
+
Object.defineProperty(exports, "NavAreaNotFound", {
|
|
1593
1963
|
enumerable: true,
|
|
1594
1964
|
get: function() {
|
|
1595
|
-
return
|
|
1965
|
+
return NavAreaNotFound;
|
|
1596
1966
|
}
|
|
1597
1967
|
});
|
|
1598
|
-
Object.defineProperty(exports, "
|
|
1968
|
+
Object.defineProperty(exports, "NavAreaPage", {
|
|
1599
1969
|
enumerable: true,
|
|
1600
1970
|
get: function() {
|
|
1601
|
-
return
|
|
1971
|
+
return NavAreaPage;
|
|
1602
1972
|
}
|
|
1603
1973
|
});
|
|
1604
|
-
Object.defineProperty(exports, "
|
|
1974
|
+
Object.defineProperty(exports, "NavChromeMountedProvider", {
|
|
1605
1975
|
enumerable: true,
|
|
1606
1976
|
get: function() {
|
|
1607
|
-
return
|
|
1977
|
+
return NavChromeMountedProvider;
|
|
1608
1978
|
}
|
|
1609
1979
|
});
|
|
1610
1980
|
Object.defineProperty(exports, "PlannedBody", {
|
|
@@ -1631,12 +2001,6 @@ Object.defineProperty(exports, "RecordScreen", {
|
|
|
1631
2001
|
return RecordScreen;
|
|
1632
2002
|
}
|
|
1633
2003
|
});
|
|
1634
|
-
Object.defineProperty(exports, "RecordState", {
|
|
1635
|
-
enumerable: true,
|
|
1636
|
-
get: function() {
|
|
1637
|
-
return RecordState;
|
|
1638
|
-
}
|
|
1639
|
-
});
|
|
1640
2004
|
Object.defineProperty(exports, "ResourceListPage", {
|
|
1641
2005
|
enumerable: true,
|
|
1642
2006
|
get: function() {
|
|
@@ -1649,10 +2013,16 @@ Object.defineProperty(exports, "ResourcePageRouter", {
|
|
|
1649
2013
|
return ResourcePageRouter;
|
|
1650
2014
|
}
|
|
1651
2015
|
});
|
|
1652
|
-
Object.defineProperty(exports, "
|
|
2016
|
+
Object.defineProperty(exports, "SecondarySidebarLayout", {
|
|
2017
|
+
enumerable: true,
|
|
2018
|
+
get: function() {
|
|
2019
|
+
return SecondarySidebarLayout;
|
|
2020
|
+
}
|
|
2021
|
+
});
|
|
2022
|
+
Object.defineProperty(exports, "TabsLayout", {
|
|
1653
2023
|
enumerable: true,
|
|
1654
2024
|
get: function() {
|
|
1655
|
-
return
|
|
2025
|
+
return TabsLayout;
|
|
1656
2026
|
}
|
|
1657
2027
|
});
|
|
1658
2028
|
Object.defineProperty(exports, "canonicalNavKey", {
|
|
@@ -1673,22 +2043,28 @@ Object.defineProperty(exports, "headerTrail", {
|
|
|
1673
2043
|
return headerTrail;
|
|
1674
2044
|
}
|
|
1675
2045
|
});
|
|
2046
|
+
Object.defineProperty(exports, "isShowAvailable", {
|
|
2047
|
+
enumerable: true,
|
|
2048
|
+
get: function() {
|
|
2049
|
+
return isShowAvailable;
|
|
2050
|
+
}
|
|
2051
|
+
});
|
|
1676
2052
|
Object.defineProperty(exports, "layoutSlot", {
|
|
1677
2053
|
enumerable: true,
|
|
1678
2054
|
get: function() {
|
|
1679
2055
|
return layoutSlot;
|
|
1680
2056
|
}
|
|
1681
2057
|
});
|
|
1682
|
-
Object.defineProperty(exports, "
|
|
2058
|
+
Object.defineProperty(exports, "originTrail", {
|
|
1683
2059
|
enumerable: true,
|
|
1684
2060
|
get: function() {
|
|
1685
|
-
return
|
|
2061
|
+
return originTrail;
|
|
1686
2062
|
}
|
|
1687
2063
|
});
|
|
1688
|
-
Object.defineProperty(exports, "
|
|
2064
|
+
Object.defineProperty(exports, "readRecentRecords", {
|
|
1689
2065
|
enumerable: true,
|
|
1690
2066
|
get: function() {
|
|
1691
|
-
return
|
|
2067
|
+
return readRecentRecords;
|
|
1692
2068
|
}
|
|
1693
2069
|
});
|
|
1694
2070
|
Object.defineProperty(exports, "recordTrail", {
|
|
@@ -1709,12 +2085,6 @@ Object.defineProperty(exports, "recordTrailRoute", {
|
|
|
1709
2085
|
return recordTrailRoute;
|
|
1710
2086
|
}
|
|
1711
2087
|
});
|
|
1712
|
-
Object.defineProperty(exports, "useFormControl", {
|
|
1713
|
-
enumerable: true,
|
|
1714
|
-
get: function() {
|
|
1715
|
-
return useFormControl;
|
|
1716
|
-
}
|
|
1717
|
-
});
|
|
1718
2088
|
Object.defineProperty(exports, "useHref", {
|
|
1719
2089
|
enumerable: true,
|
|
1720
2090
|
get: function() {
|
|
@@ -1739,12 +2109,6 @@ Object.defineProperty(exports, "useMatch", {
|
|
|
1739
2109
|
return useMatch;
|
|
1740
2110
|
}
|
|
1741
2111
|
});
|
|
1742
|
-
Object.defineProperty(exports, "useNavChromeBoundary", {
|
|
1743
|
-
enumerable: true,
|
|
1744
|
-
get: function() {
|
|
1745
|
-
return useNavChromeBoundary;
|
|
1746
|
-
}
|
|
1747
|
-
});
|
|
1748
2112
|
Object.defineProperty(exports, "useNavVisible", {
|
|
1749
2113
|
enumerable: true,
|
|
1750
2114
|
get: function() {
|
|
@@ -1775,6 +2139,24 @@ Object.defineProperty(exports, "useRecordVisit", {
|
|
|
1775
2139
|
return useRecordVisit;
|
|
1776
2140
|
}
|
|
1777
2141
|
});
|
|
2142
|
+
Object.defineProperty(exports, "useReportUnresolvedLayouts", {
|
|
2143
|
+
enumerable: true,
|
|
2144
|
+
get: function() {
|
|
2145
|
+
return useReportUnresolvedLayouts;
|
|
2146
|
+
}
|
|
2147
|
+
});
|
|
2148
|
+
Object.defineProperty(exports, "useResourceDimensionOptions", {
|
|
2149
|
+
enumerable: true,
|
|
2150
|
+
get: function() {
|
|
2151
|
+
return useResourceDimensionOptions;
|
|
2152
|
+
}
|
|
2153
|
+
});
|
|
2154
|
+
Object.defineProperty(exports, "useResourceVisible", {
|
|
2155
|
+
enumerable: true,
|
|
2156
|
+
get: function() {
|
|
2157
|
+
return useResourceVisible;
|
|
2158
|
+
}
|
|
2159
|
+
});
|
|
1778
2160
|
Object.defineProperty(exports, "useTrailContext", {
|
|
1779
2161
|
enumerable: true,
|
|
1780
2162
|
get: function() {
|
|
@@ -1782,4 +2164,4 @@ Object.defineProperty(exports, "useTrailContext", {
|
|
|
1782
2164
|
}
|
|
1783
2165
|
});
|
|
1784
2166
|
|
|
1785
|
-
//# sourceMappingURL=resource-page-router-
|
|
2167
|
+
//# sourceMappingURL=resource-page-router-qEd2xb55.cjs.map
|