@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,5 +1,6 @@
|
|
|
1
|
-
require("./toaster-
|
|
2
|
-
const require_check_confirm_dialog = require("./check-confirm-dialog
|
|
1
|
+
require("./toaster-BbByOytP.cjs");
|
|
2
|
+
const require_check_confirm_dialog = require("./check-confirm-dialog-BT04Mieo.cjs");
|
|
3
|
+
const require_success_notices = require("./success-notices-Dl3M1fZP.cjs");
|
|
3
4
|
let _burojs_core = require("@burojs/core");
|
|
4
5
|
let _burojs_react = require("@burojs/react");
|
|
5
6
|
let react = require("react");
|
|
@@ -11,6 +12,9 @@ let sonner = require("sonner");
|
|
|
11
12
|
const NO_ISSUES = Object.freeze([]);
|
|
12
13
|
function useFlowLauncher(flow, host, chrome, resource, testid) {
|
|
13
14
|
const t = (0, _burojs_react.useOptionalT)();
|
|
15
|
+
const own = resource === _burojs_core.APP_ACTION_RESOURCE ? void 0 : resource;
|
|
16
|
+
const caps = (0, _burojs_react.useI18nCaps)(own);
|
|
17
|
+
const showNotices = require_success_notices.useNoticeSink(own);
|
|
14
18
|
const [confirming, setConfirming] = (0, react.useState)(false);
|
|
15
19
|
const decide = (0, react.useRef)(null);
|
|
16
20
|
const latest = (0, react.useRef)(flow);
|
|
@@ -40,12 +44,28 @@ function useFlowLauncher(flow, host, chrome, resource, testid) {
|
|
|
40
44
|
}
|
|
41
45
|
result = await run.accept();
|
|
42
46
|
}
|
|
47
|
+
if (result.outcome === "success") {
|
|
48
|
+
const { notices } = run.getSnapshot();
|
|
49
|
+
if (notices.length > 0) showNotices(notices);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
43
52
|
if (result.outcome === "failed" && "reason" in result && result.reason === "busy") {
|
|
44
|
-
(0, sonner.toast)(
|
|
53
|
+
(0, sonner.toast)(t("flow.busyElsewhere", { defaultValue: "This action is running in another tab." }));
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (result.outcome === "unavailable") {
|
|
57
|
+
const reason = run.getSnapshot().reason;
|
|
58
|
+
(0, sonner.toast)(reason === void 0 ? t("availability.denied", { defaultValue: "This action isn't available" }) : require_check_confirm_dialog.reasonText(caps, reason, own));
|
|
45
59
|
return;
|
|
46
60
|
}
|
|
47
61
|
if (result.outcome === "rejected" || result.outcome === "failed" || result.outcome === "unknown" || result.outcome === "halted" && result.step === "outcome") await (host.open("dialog") ?? Promise.resolve());
|
|
48
|
-
}, [
|
|
62
|
+
}, [
|
|
63
|
+
host,
|
|
64
|
+
t,
|
|
65
|
+
caps,
|
|
66
|
+
own,
|
|
67
|
+
showNotices
|
|
68
|
+
]);
|
|
49
69
|
const { snapshot, compiled } = flow;
|
|
50
70
|
const gate = {
|
|
51
71
|
resource,
|
|
@@ -55,12 +75,12 @@ function useFlowLauncher(flow, host, chrome, resource, testid) {
|
|
|
55
75
|
blockers: NO_ISSUES,
|
|
56
76
|
confirmable: confirming ? snapshot.warnings.map((warning) => ({
|
|
57
77
|
code: "check.warning",
|
|
58
|
-
message:
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
checkId: warning.id,
|
|
62
|
-
resolved: true
|
|
78
|
+
message: {
|
|
79
|
+
...(0, _burojs_core_internal.toMessageRef)(warning.message, `checks.${warning.id}`),
|
|
80
|
+
params: { resolved: true }
|
|
63
81
|
},
|
|
82
|
+
path: [],
|
|
83
|
+
check: { id: warning.id },
|
|
64
84
|
source: "check",
|
|
65
85
|
severity: "warning"
|
|
66
86
|
})) : NO_ISSUES,
|
|
@@ -72,8 +92,9 @@ function useFlowLauncher(flow, host, chrome, resource, testid) {
|
|
|
72
92
|
dialog: compiled === null || compiled.hasHost ? null : (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.CheckConfirmDialog, {
|
|
73
93
|
state: gate,
|
|
74
94
|
testid: `${testid}:confirm`,
|
|
75
|
-
title: chrome.
|
|
76
|
-
proceedLabel: chrome.
|
|
95
|
+
title: chrome.confirmTitle,
|
|
96
|
+
proceedLabel: chrome.confirmProceed,
|
|
97
|
+
...chrome.dismiss === void 0 ? {} : { cancelLabel: chrome.dismiss },
|
|
77
98
|
tone: chrome.destructive ? "destructive" : "default"
|
|
78
99
|
})
|
|
79
100
|
};
|
|
@@ -88,7 +109,8 @@ function FlowRunner({ resource, actionName, record, scope, onClose }) {
|
|
|
88
109
|
surface: scope === "row" ? "row" : "menu"
|
|
89
110
|
});
|
|
90
111
|
const chrome = require_check_confirm_dialog.useFlowChrome(resource, actionName);
|
|
91
|
-
const
|
|
112
|
+
const recordKey = (0, _burojs_react.recordKeyOf)((0, _burojs_react.useApp)().registry.get(resource), record);
|
|
113
|
+
const title = (0, _burojs_react.useProjectedTitle)(resource, recordKey, record);
|
|
92
114
|
const host = (0, _burojs_react_flows.useFlowHost)(flow, {
|
|
93
115
|
label: chrome.labelText,
|
|
94
116
|
...record === void 0 || title === "" ? {} : { title },
|
|
@@ -96,7 +118,8 @@ function FlowRunner({ resource, actionName, record, scope, onClose }) {
|
|
|
96
118
|
});
|
|
97
119
|
const tid = (0, _burojs_react.useTestIds)();
|
|
98
120
|
const t = (0, _burojs_react.useOptionalT)();
|
|
99
|
-
const
|
|
121
|
+
const caps = (0, _burojs_react.useI18nCaps)(resource);
|
|
122
|
+
const { launch, dialog } = useFlowLauncher(flow, host, chrome, resource, require_check_confirm_dialog.makeTestId(scope, resource, actionName, String(recordKey ?? ""), tid));
|
|
100
123
|
const started = (0, react.useRef)(false);
|
|
101
124
|
const onCloseRef = (0, react.useRef)(onClose);
|
|
102
125
|
onCloseRef.current = onClose;
|
|
@@ -106,7 +129,7 @@ function FlowRunner({ resource, actionName, record, scope, onClose }) {
|
|
|
106
129
|
if (!decided || started.current) return;
|
|
107
130
|
started.current = true;
|
|
108
131
|
if (snapshot.control !== "ready") {
|
|
109
|
-
(0, sonner.toast)(snapshot.reason
|
|
132
|
+
(0, sonner.toast)(snapshot.reason === void 0 ? t("availability.denied", { defaultValue: "This action isn't available" }) : require_check_confirm_dialog.reasonText(caps, snapshot.reason, resource));
|
|
110
133
|
onCloseRef.current();
|
|
111
134
|
return;
|
|
112
135
|
}
|
|
@@ -116,7 +139,8 @@ function FlowRunner({ resource, actionName, record, scope, onClose }) {
|
|
|
116
139
|
snapshot.control,
|
|
117
140
|
snapshot.reason,
|
|
118
141
|
launch,
|
|
119
|
-
t
|
|
142
|
+
t,
|
|
143
|
+
caps
|
|
120
144
|
]);
|
|
121
145
|
return dialog;
|
|
122
146
|
}
|
|
@@ -127,10 +151,12 @@ function AppFlowRunner({ name, label, testid, onClose }) {
|
|
|
127
151
|
label,
|
|
128
152
|
labelText: label,
|
|
129
153
|
icon: void 0,
|
|
130
|
-
destructive: false
|
|
154
|
+
destructive: false,
|
|
155
|
+
...require_check_confirm_dialog.useFlowDialogTexts("", name, label)
|
|
131
156
|
};
|
|
132
157
|
const host = (0, _burojs_react_flows.useFlowHost)(flow, { label });
|
|
133
158
|
const t = (0, _burojs_react.useOptionalT)();
|
|
159
|
+
const caps = (0, _burojs_react.useI18nCaps)();
|
|
134
160
|
const { launch, dialog } = useFlowLauncher(flow, host, chrome, _burojs_core.APP_ACTION_RESOURCE, testid);
|
|
135
161
|
const started = (0, react.useRef)(false);
|
|
136
162
|
const onCloseRef = (0, react.useRef)(onClose);
|
|
@@ -141,7 +167,7 @@ function AppFlowRunner({ name, label, testid, onClose }) {
|
|
|
141
167
|
if (!decided || started.current) return;
|
|
142
168
|
started.current = true;
|
|
143
169
|
if (snapshot.control !== "ready") {
|
|
144
|
-
(0, sonner.toast)(snapshot.reason
|
|
170
|
+
(0, sonner.toast)(snapshot.reason === void 0 ? t("availability.denied", { defaultValue: "This action isn't available" }) : require_check_confirm_dialog.reasonText(caps, snapshot.reason));
|
|
145
171
|
onCloseRef.current();
|
|
146
172
|
return;
|
|
147
173
|
}
|
|
@@ -151,13 +177,15 @@ function AppFlowRunner({ name, label, testid, onClose }) {
|
|
|
151
177
|
snapshot.control,
|
|
152
178
|
snapshot.reason,
|
|
153
179
|
launch,
|
|
154
|
-
t
|
|
180
|
+
t,
|
|
181
|
+
caps
|
|
155
182
|
]);
|
|
156
183
|
return dialog;
|
|
157
184
|
}
|
|
158
185
|
function BulkFlowRunner({ resource, actionName, ids, onFinish }) {
|
|
159
186
|
const tid = (0, _burojs_react.useTestIds)();
|
|
160
187
|
const t = (0, _burojs_react.useOptionalT)();
|
|
188
|
+
const caps = (0, _burojs_react.useI18nCaps)(resource);
|
|
161
189
|
const idsKey = ids.join("\0");
|
|
162
190
|
const selection = (0, react.useMemo)(() => ({
|
|
163
191
|
ids: [...ids],
|
|
@@ -189,7 +217,8 @@ function BulkFlowRunner({ resource, actionName, ids, onFinish }) {
|
|
|
189
217
|
started.current = true;
|
|
190
218
|
(async () => {
|
|
191
219
|
if (run.getSnapshot().control !== "ready") {
|
|
192
|
-
|
|
220
|
+
const refusal = run.getSnapshot().reason;
|
|
221
|
+
(0, sonner.toast)(refusal === void 0 ? t("availability.denied", { defaultValue: "This action isn't available" }) : require_check_confirm_dialog.reasonText(caps, refusal, resource));
|
|
193
222
|
onFinishRef.current(Object.freeze({
|
|
194
223
|
outcome: "unavailable",
|
|
195
224
|
state: "disabled"
|
|
@@ -211,13 +240,15 @@ function BulkFlowRunner({ resource, actionName, ids, onFinish }) {
|
|
|
211
240
|
}
|
|
212
241
|
result = await run.accept();
|
|
213
242
|
}
|
|
214
|
-
if (result.outcome === "failed" && "reason" in result && result.reason === "busy") (0, sonner.toast)(
|
|
243
|
+
if (result.outcome === "failed" && "reason" in result && result.reason === "busy") (0, sonner.toast)(t("flow.busyElsewhere", { defaultValue: "This action is running in another tab." }));
|
|
215
244
|
onFinishRef.current(result, run.getSnapshot().bulk);
|
|
216
245
|
})();
|
|
217
246
|
}, [
|
|
218
247
|
decided,
|
|
219
248
|
run,
|
|
220
|
-
t
|
|
249
|
+
t,
|
|
250
|
+
caps,
|
|
251
|
+
resource
|
|
221
252
|
]);
|
|
222
253
|
const gate = {
|
|
223
254
|
resource,
|
|
@@ -227,12 +258,15 @@ function BulkFlowRunner({ resource, actionName, ids, onFinish }) {
|
|
|
227
258
|
blockers: NO_ISSUES,
|
|
228
259
|
confirmable: confirming ? snapshot.warnings.map((warning) => ({
|
|
229
260
|
code: "check.warning",
|
|
230
|
-
message:
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
261
|
+
message: {
|
|
262
|
+
...(0, _burojs_core_internal.toMessageRef)(warning.rows === void 0 ? warning.message : `${warning.message} — ${t("flow.bulkWarningRows", {
|
|
263
|
+
defaultValue: warning.rows === 1 ? "1 row" : `${warning.rows} rows`,
|
|
264
|
+
count: warning.rows
|
|
265
|
+
})}`, `checks.${warning.id}`),
|
|
266
|
+
params: { resolved: true }
|
|
235
267
|
},
|
|
268
|
+
path: [],
|
|
269
|
+
check: { id: warning.id },
|
|
236
270
|
source: "check",
|
|
237
271
|
severity: "warning"
|
|
238
272
|
})) : NO_ISSUES,
|
|
@@ -242,8 +276,9 @@ function BulkFlowRunner({ resource, actionName, ids, onFinish }) {
|
|
|
242
276
|
return (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.CheckConfirmDialog, {
|
|
243
277
|
state: gate,
|
|
244
278
|
testid: `${testid}:confirm`,
|
|
245
|
-
title: chrome.
|
|
246
|
-
proceedLabel: chrome.
|
|
279
|
+
title: chrome.confirmTitle,
|
|
280
|
+
proceedLabel: chrome.confirmProceed,
|
|
281
|
+
...chrome.dismiss === void 0 ? {} : { cancelLabel: chrome.dismiss },
|
|
247
282
|
tone: chrome.destructive ? "destructive" : "default"
|
|
248
283
|
});
|
|
249
284
|
}
|
|
@@ -252,4 +287,4 @@ exports.AppFlowRunner = AppFlowRunner;
|
|
|
252
287
|
exports.BulkFlowRunner = BulkFlowRunner;
|
|
253
288
|
exports.FlowRunner = FlowRunner;
|
|
254
289
|
|
|
255
|
-
//# sourceMappingURL=flow-runtime-
|
|
290
|
+
//# sourceMappingURL=flow-runtime-BVFjMU5-.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flow-runtime-BVFjMU5-.cjs","names":["useOptionalT","APP_ACTION_RESOURCE","useI18nCaps","useNoticeSink","useState","useRef","useCallback","reasonText","toMessageRef","CheckConfirmDialog","useMemo","useFlowRun","useFlowChrome","recordKeyOf","useApp","useProjectedTitle","useFlowHost","useTestIds","makeTestId","useFlowDialogTexts"],"sources":["../src/flows/flow-runtime.tsx"],"sourcesContent":["'use client';\n/**\n * The flow runtime's side of the UI kit (P4, the coordinator's ruling on the bundle): every\n * component that holds a run. It loads on the first sign that a user means to run a flow (a\n * hover, a focus, a menu opening, at the latest the click) through `./load-runtime.js`, and with\n * it `@burojs/react/flows` and `@burojs/core/flows` — the flow machine stays out of an\n * application's first screen.\n */\nimport { toMessageRef } from '@burojs/core/internal';\nimport {\n APP_ACTION_RESOURCE,\n type BulkProgress,\n type FlowControlState,\n type FlowResult,\n type Row,\n type ValidationIssue,\n} from '@burojs/core';\nimport {\n type CheckGateState,\n recordKeyOf,\n useApp,\n useI18nCaps,\n useOptionalT,\n useProjectedTitle,\n useTestIds,\n} from '@burojs/react';\nimport {\n type FlowHostControl,\n type UseFlowRunResult,\n useFlowHost,\n useFlowRun,\n} from '@burojs/react/flows';\nimport { type ReactElement, useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { makeTestId } from '../actions/action-button.js';\nimport { CheckConfirmDialog } from '../checks/check-confirm-dialog.js';\nimport { useNoticeSink } from '../forms/success-notices.js';\nimport { reasonText } from '../lib/reason-text.js';\nimport { toast } from '../notification/toaster.js';\nimport { type FlowChrome, useFlowChrome, useFlowDialogTexts } from './chrome.js';\n\nconst NO_ISSUES: readonly ValidationIssue[] = Object.freeze([]);\n\n/**\n * Runs a flow from its control (4.15): a flow with a host presents it and the interaction ends\n * when it closes; a `{ label, submit }` flow sends, asks through the confirm dialog when\n * `confirm` or a fired warning asks, and shows `rejected`, `failed` and `unknown` in the flow's\n * screen in a dialog (`success` notifies through the flow's `then` and shows the write's notices; a lock another tab holds\n * says so; an `unavailable` send toasts the run's reason). `launch()` settles when the interaction is over.\n */\nfunction useFlowLauncher(\n flow: UseFlowRunResult,\n host: FlowHostControl,\n chrome: FlowChrome,\n resource: string,\n testid: string,\n): { readonly launch: () => Promise<void>; readonly dialog: ReactElement | null } {\n const t = useOptionalT();\n // An app flow's reason resolves app-wide: it has no resource bundle of its own.\n const own = resource === APP_ACTION_RESOURCE ? undefined : resource;\n const caps = useI18nCaps(own);\n // The write's own notices (spec 4.7): a host-less flow mounts no flow screen to show them, so\n // the launcher shows them through the same sink the flow screen uses.\n const showNotices = useNoticeSink(own);\n const [confirming, setConfirming] = useState(false);\n const decide = useRef<((proceed: boolean) => void) | null>(null);\n const latest = useRef(flow);\n latest.current = flow;\n useEffect(\n () => () => {\n decide.current?.(false);\n decide.current = null;\n },\n [],\n );\n\n const launch = useCallback(async (): Promise<void> => {\n const { run, compiled } = latest.current;\n if (run === null || compiled === null) return;\n if (compiled.hasHost) {\n await (host.open() ?? Promise.resolve());\n return;\n }\n let result: FlowResult = await run.submit();\n while (result.outcome === 'halted' && (result.step === 'accept' || result.step === 'review')) {\n setConfirming(true);\n const proceed = await new Promise<boolean>((resolve) => {\n decide.current = resolve;\n });\n decide.current = null;\n setConfirming(false);\n if (!proceed) {\n run.startOver();\n return;\n }\n result = await run.accept();\n }\n if (result.outcome === 'success') {\n const { notices } = run.getSnapshot();\n if (notices.length > 0) showNotices(notices);\n return;\n }\n // Another tab holds the attempt's lock: nothing was sent (4.10).\n if (result.outcome === 'failed' && 'reason' in result && result.reason === 'busy') {\n toast(t('flow.busyElsewhere', { defaultValue: 'This action is running in another tab.' }));\n return;\n }\n // The send found the flow unavailable (a check that runs at submit, access revoked since the\n // click): the run's reason, as a refusal before the click shows it.\n if (result.outcome === 'unavailable') {\n const reason = run.getSnapshot().reason;\n toast(\n reason === undefined\n ? t('availability.denied', { defaultValue: \"This action isn't available\" })\n : reasonText(caps, reason, own),\n );\n return;\n }\n if (\n result.outcome === 'rejected' ||\n result.outcome === 'failed' ||\n result.outcome === 'unknown' ||\n (result.outcome === 'halted' && result.step === 'outcome')\n )\n await (host.open('dialog') ?? Promise.resolve());\n }, [host, t, caps, own, showNotices]);\n\n const { snapshot, compiled } = flow;\n const gate: CheckGateState = {\n resource,\n open: confirming,\n busy: false,\n header: null,\n blockers: NO_ISSUES,\n confirmable: confirming\n ? snapshot.warnings.map(\n (warning): ValidationIssue => ({\n code: 'check.warning',\n // The machine's text (bundle and params resolved); the key is the check's.\n message: {\n ...toMessageRef(warning.message, `checks.${warning.id}`),\n // The run's text is final (bundle and params resolved): the dialog shows it as is.\n params: { resolved: true },\n },\n path: [],\n check: { id: warning.id },\n source: 'check',\n severity: 'warning',\n }),\n )\n : NO_ISSUES,\n proceed: () => decide.current?.(true),\n cancel: () => decide.current?.(false),\n };\n const dialog =\n compiled === null || compiled.hasHost ? null : (\n <CheckConfirmDialog\n state={gate}\n testid={`${testid}:confirm`}\n title={chrome.confirmTitle}\n proceedLabel={chrome.confirmProceed}\n {...(chrome.dismiss === undefined ? {} : { cancelLabel: chrome.dismiss })}\n tone={chrome.destructive ? 'destructive' : 'default'}\n />\n );\n return { launch, dialog };\n}\n\nexport interface FlowRunnerProps {\n readonly resource: string;\n readonly actionName: string;\n readonly record?: Row;\n readonly scope: string;\n /** The interaction is over (the host closed, the write answered, the confirm was declined). */\n readonly onClose: () => void;\n}\n\n/**\n * @internal A flow started from a control that holds no run — a row's button, a menu item\n * (4.15: a menu item \"presents its host through the runtime from `onSelect`, so the menu closes\n * normally\"). It renders no control: it starts the run (its `with` sources load now) and, once\n * the run has decided, presents the host or sends; `onClose` reports the end of the\n * interaction. A run that decides against the click (a check over a `with` source fired) says\n * why.\n */\nexport function FlowRunner({\n resource,\n actionName,\n record,\n scope,\n onClose,\n}: FlowRunnerProps): ReactElement | null {\n const target = useMemo(() => ({ resource, action: actionName }), [resource, actionName]);\n const flow = useFlowRun(target, {\n ...(record === undefined ? {} : { record }),\n surface: scope === 'row' ? 'row' : 'menu',\n });\n const chrome = useFlowChrome(resource, actionName);\n const recordKey = recordKeyOf(useApp().registry.get(resource), record);\n const title = useProjectedTitle(resource, recordKey, record);\n const host = useFlowHost(flow, {\n label: chrome.labelText,\n ...(record === undefined || title === '' ? {} : { title }),\n ...(record === undefined ? {} : { record }),\n });\n const tid = useTestIds();\n const t = useOptionalT();\n const caps = useI18nCaps(resource);\n const testid = makeTestId(scope, resource, actionName, String(recordKey ?? ''), tid);\n const { launch, dialog } = useFlowLauncher(flow, host, chrome, resource, testid);\n const started = useRef(false);\n const onCloseRef = useRef(onClose);\n onCloseRef.current = onClose;\n const { snapshot, compiled } = flow;\n const decided =\n compiled !== null &&\n (snapshot.control === 'disabled' ||\n snapshot.control === 'absent' ||\n (snapshot.control === 'ready' &&\n (!compiled.hasHost || snapshot.history.includes('open') || snapshot.step === 'outcome')));\n useEffect(() => {\n if (!decided || started.current) return;\n started.current = true;\n if (snapshot.control !== 'ready') {\n toast(\n snapshot.reason === undefined\n ? t('availability.denied', { defaultValue: \"This action isn't available\" })\n : reasonText(caps, snapshot.reason, resource),\n );\n onCloseRef.current();\n return;\n }\n void launch().finally(() => onCloseRef.current());\n }, [decided, snapshot.control, snapshot.reason, launch, t, caps]);\n return dialog;\n}\n\nexport interface AppFlowRunnerProps {\n /** The app action's name (`defineAppAction({ name, kind: 'flow' })`). */\n readonly name: string;\n /** Its label, as the opener resolved it (`appActions.<name>` over the declared default). */\n readonly label: string;\n /** The opener's test id: the confirm dialog's ids suffix it (`<testid>:confirm:…`). */\n readonly testid: string;\n readonly onClose: () => void;\n}\n\n/**\n * @internal An app flow started from its control (`AppFlowButton`, P4-D): the same launcher as a\n * resource flow's — the host when the flow has a form or a review, else the send with the\n * confirm dialog — over the target `{ appAction: name }`, with no record.\n */\nexport function AppFlowRunner({\n name,\n label,\n testid,\n onClose,\n}: AppFlowRunnerProps): ReactElement | null {\n const target = useMemo(() => ({ appAction: name }), [name]);\n const flow = useFlowRun(target, { surface: 'app' });\n const dialogTexts = useFlowDialogTexts('', name, label);\n const chrome: FlowChrome = {\n label,\n labelText: label,\n icon: undefined,\n destructive: false,\n ...dialogTexts,\n };\n const host = useFlowHost(flow, { label });\n const t = useOptionalT();\n const caps = useI18nCaps();\n const { launch, dialog } = useFlowLauncher(flow, host, chrome, APP_ACTION_RESOURCE, testid);\n const started = useRef(false);\n const onCloseRef = useRef(onClose);\n onCloseRef.current = onClose;\n const { snapshot, compiled } = flow;\n const decided =\n compiled !== null &&\n (snapshot.control === 'disabled' ||\n snapshot.control === 'absent' ||\n (snapshot.control === 'ready' &&\n (!compiled.hasHost || snapshot.history.includes('open') || snapshot.step === 'outcome')));\n useEffect(() => {\n if (!decided || started.current) return;\n started.current = true;\n if (snapshot.control !== 'ready') {\n toast(\n snapshot.reason === undefined\n ? t('availability.denied', { defaultValue: \"This action isn't available\" })\n : reasonText(caps, snapshot.reason),\n );\n onCloseRef.current();\n return;\n }\n void launch().finally(() => onCloseRef.current());\n }, [decided, snapshot.control, snapshot.reason, launch, t, caps]);\n return dialog;\n}\n\nexport interface BulkFlowRunnerProps {\n readonly resource: string;\n readonly actionName: string;\n readonly ids: readonly string[];\n /** The run is over: its result and its per-id report (absent when nothing was sent). */\n readonly onFinish: (result: FlowResult, progress: BulkProgress | undefined) => void;\n}\n\n/**\n * @internal A bulk flow's run over the selection (4.16), started by the bar's click: the confirm\n * (`confirm` and the fired warnings) asks through the confirm dialog, then the run (re-reading the\n * rows first where the flow declares `submit.reread`) writes each under its own key; `onFinish` reports the result and the per-id report.\n */\nexport function BulkFlowRunner({\n resource,\n actionName,\n ids,\n onFinish,\n}: BulkFlowRunnerProps): ReactElement | null {\n const tid = useTestIds();\n const t = useOptionalT();\n const caps = useI18nCaps(resource);\n const idsKey = ids.join('\\u0000');\n // biome-ignore lint/correctness/useExhaustiveDependencies: keyed by the ids' values\n const selection = useMemo(() => ({ ids: [...ids], count: ids.length }), [idsKey]);\n const target = useMemo(() => ({ resource, action: actionName }), [resource, actionName]);\n const flow = useFlowRun(target, { selection, surface: 'bulk' });\n const chrome = useFlowChrome(resource, actionName);\n const testid = tid.bulkAction(resource, actionName);\n const [confirming, setConfirming] = useState(false);\n const decide = useRef<((proceed: boolean) => void) | null>(null);\n const started = useRef(false);\n const onFinishRef = useRef(onFinish);\n onFinishRef.current = onFinish;\n const { run, snapshot } = flow;\n useEffect(\n () => () => {\n decide.current?.(false);\n decide.current = null;\n },\n [],\n );\n const decided =\n run !== null && snapshot.control !== 'undecided' && snapshot.control !== 'pending';\n useEffect(() => {\n if (!decided || started.current || run === null) return;\n started.current = true;\n void (async () => {\n if (run.getSnapshot().control !== 'ready') {\n const refusal = run.getSnapshot().reason;\n toast(\n refusal === undefined\n ? t('availability.denied', { defaultValue: \"This action isn't available\" })\n : reasonText(caps, refusal, resource),\n );\n onFinishRef.current(\n Object.freeze({ outcome: 'unavailable', state: 'disabled' }),\n undefined,\n );\n return;\n }\n let result = await run.submit();\n while (\n result.outcome === 'halted' &&\n (result.step === 'accept' || result.step === 'review')\n ) {\n setConfirming(true);\n const proceed = await new Promise<boolean>((resolve) => {\n decide.current = resolve;\n });\n decide.current = null;\n setConfirming(false);\n if (!proceed) {\n run.startOver();\n onFinishRef.current(result, undefined);\n return;\n }\n result = await run.accept();\n }\n if (result.outcome === 'failed' && 'reason' in result && result.reason === 'busy')\n toast(t('flow.busyElsewhere', { defaultValue: 'This action is running in another tab.' }));\n onFinishRef.current(result, run.getSnapshot().bulk);\n })();\n }, [decided, run, t, caps, resource]);\n const gate: CheckGateState = {\n resource,\n open: confirming,\n busy: false,\n header: null,\n blockers: NO_ISSUES,\n confirmable: confirming\n ? snapshot.warnings.map(\n (warning): ValidationIssue => ({\n code: 'check.warning',\n // The machine's text (bundle and params resolved); the key is the check's.\n message: {\n ...toMessageRef(\n warning.rows === undefined\n ? warning.message\n : `${warning.message} — ${t('flow.bulkWarningRows', {\n defaultValue: warning.rows === 1 ? '1 row' : `${warning.rows} rows`,\n count: warning.rows,\n })}`,\n `checks.${warning.id}`,\n ),\n // The run's text is final (bundle and params resolved): the dialog shows it as is.\n params: { resolved: true },\n },\n path: [],\n check: { id: warning.id },\n source: 'check',\n severity: 'warning',\n }),\n )\n : NO_ISSUES,\n proceed: () => decide.current?.(true),\n cancel: () => decide.current?.(false),\n };\n return (\n <CheckConfirmDialog\n state={gate}\n testid={`${testid}:confirm`}\n title={chrome.confirmTitle}\n proceedLabel={chrome.confirmProceed}\n {...(chrome.dismiss === undefined ? {} : { cancelLabel: chrome.dismiss })}\n tone={chrome.destructive ? 'destructive' : 'default'}\n />\n );\n}\n"],"mappings":";;;;;;;;;;;AAwCA,MAAM,YAAwC,OAAO,OAAO,CAAC,CAAC;AAS9D,SAAS,gBACP,MACA,MACA,QACA,UACA,QACgF;CAChF,MAAM,KAAA,GAAIA,cAAAA,aAAAA,CAAa;CAEvB,MAAM,MAAM,aAAaC,aAAAA,sBAAsB,KAAA,IAAY;CAC3D,MAAM,QAAA,GAAOC,cAAAA,YAAAA,CAAY,GAAG;CAG5B,MAAM,cAAcC,wBAAAA,cAAc,GAAG;CACrC,MAAM,CAAC,YAAY,kBAAA,GAAiBC,MAAAA,SAAAA,CAAS,KAAK;CAClD,MAAM,UAAA,GAASC,MAAAA,OAAAA,CAA4C,IAAI;CAC/D,MAAM,UAAA,GAASA,MAAAA,OAAAA,CAAO,IAAI;CAC1B,OAAO,UAAU;CACjB,CAAA,GAAA,MAAA,UAAA,aACc;EACV,OAAO,UAAU,KAAK;EACtB,OAAO,UAAU;CACnB,GACA,CAAC,CACH;CAEA,MAAM,UAAA,GAASC,MAAAA,YAAAA,CAAY,YAA2B;EACpD,MAAM,EAAE,KAAK,aAAa,OAAO;EACjC,IAAI,QAAQ,QAAQ,aAAa,MAAM;EACvC,IAAI,SAAS,SAAS;GACpB,OAAO,KAAK,KAAK,KAAK,QAAQ,QAAQ;GACtC;EACF;EACA,IAAI,SAAqB,MAAM,IAAI,OAAO;EAC1C,OAAO,OAAO,YAAY,aAAa,OAAO,SAAS,YAAY,OAAO,SAAS,WAAW;GAC5F,cAAc,IAAI;GAClB,MAAM,UAAU,MAAM,IAAI,SAAkB,YAAY;IACtD,OAAO,UAAU;GACnB,CAAC;GACD,OAAO,UAAU;GACjB,cAAc,KAAK;GACnB,IAAI,CAAC,SAAS;IACZ,IAAI,UAAU;IACd;GACF;GACA,SAAS,MAAM,IAAI,OAAO;EAC5B;EACA,IAAI,OAAO,YAAY,WAAW;GAChC,MAAM,EAAE,YAAY,IAAI,YAAY;GACpC,IAAI,QAAQ,SAAS,GAAG,YAAY,OAAO;GAC3C;EACF;EAEA,IAAI,OAAO,YAAY,YAAY,YAAY,UAAU,OAAO,WAAW,QAAQ;GACjF,CAAA,GAAA,OAAA,MAAA,CAAM,EAAE,sBAAsB,EAAE,cAAc,yCAAyC,CAAC,CAAC;GACzF;EACF;EAGA,IAAI,OAAO,YAAY,eAAe;GACpC,MAAM,SAAS,IAAI,YAAY,CAAC,CAAC;GACjC,CAAA,GAAA,OAAA,MAAA,CACE,WAAW,KAAA,IACP,EAAE,uBAAuB,EAAE,cAAc,8BAA8B,CAAC,IACxEC,6BAAAA,WAAW,MAAM,QAAQ,GAAG,CAClC;GACA;EACF;EACA,IACE,OAAO,YAAY,cACnB,OAAO,YAAY,YACnB,OAAO,YAAY,aAClB,OAAO,YAAY,YAAY,OAAO,SAAS,WAEhD,OAAO,KAAK,KAAK,QAAQ,KAAK,QAAQ,QAAQ;CAClD,GAAG;EAAC;EAAM;EAAG;EAAM;EAAK;CAAW,CAAC;CAEpC,MAAM,EAAE,UAAU,aAAa;CAC/B,MAAM,OAAuB;EAC3B;EACA,MAAM;EACN,MAAM;EACN,QAAQ;EACR,UAAU;EACV,aAAa,aACT,SAAS,SAAS,KACf,aAA8B;GAC7B,MAAM;GAEN,SAAS;IACP,IAAA,GAAGC,sBAAAA,aAAAA,CAAa,QAAQ,SAAS,UAAU,QAAQ,IAAI;IAEvD,QAAQ,EAAE,UAAU,KAAK;GAC3B;GACA,MAAM,CAAC;GACP,OAAO,EAAE,IAAI,QAAQ,GAAG;GACxB,QAAQ;GACR,UAAU;EACZ,EACF,IACA;EACJ,eAAe,OAAO,UAAU,IAAI;EACpC,cAAc,OAAO,UAAU,KAAK;CACtC;CAYA,OAAO;EAAE;EAAQ,QAVf,aAAa,QAAQ,SAAS,UAAU,QACtC,GAAA,kBAAA,IAAA,CAACC,6BAAAA,oBAAD;GACE,OAAO;GACP,QAAQ,GAAG,OAAO;GAClB,OAAO,OAAO;GACd,cAAc,OAAO;GACrB,GAAK,OAAO,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,aAAa,OAAO,QAAQ;GACvE,MAAM,OAAO,cAAc,gBAAgB;EAC5C,CAAA;CAEmB;AAC1B;AAmBA,SAAgB,WAAW,EACzB,UACA,YACA,QACA,OACA,WACuC;CACvC,MAAM,UAAA,GAASC,MAAAA,QAAAA,QAAe;EAAE;EAAU,QAAQ;CAAW,IAAI,CAAC,UAAU,UAAU,CAAC;CACvF,MAAM,QAAA,GAAOC,oBAAAA,WAAAA,CAAW,QAAQ;EAC9B,GAAI,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO;EACzC,SAAS,UAAU,QAAQ,QAAQ;CACrC,CAAC;CACD,MAAM,SAASC,6BAAAA,cAAc,UAAU,UAAU;CACjD,MAAM,aAAA,GAAYC,cAAAA,YAAAA,EAAAA,GAAYC,cAAAA,OAAAA,CAAO,CAAC,CAAC,SAAS,IAAI,QAAQ,GAAG,MAAM;CACrE,MAAM,SAAA,GAAQC,cAAAA,kBAAAA,CAAkB,UAAU,WAAW,MAAM;CAC3D,MAAM,QAAA,GAAOC,oBAAAA,YAAAA,CAAY,MAAM;EAC7B,OAAO,OAAO;EACd,GAAI,WAAW,KAAA,KAAa,UAAU,KAAK,CAAC,IAAI,EAAE,MAAM;EACxD,GAAI,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO;CAC3C,CAAC;CACD,MAAM,OAAA,GAAMC,cAAAA,WAAAA,CAAW;CACvB,MAAM,KAAA,GAAIjB,cAAAA,aAAAA,CAAa;CACvB,MAAM,QAAA,GAAOE,cAAAA,YAAAA,CAAY,QAAQ;CAEjC,MAAM,EAAE,QAAQ,WAAW,gBAAgB,MAAM,MAAM,QAAQ,UADhDgB,6BAAAA,WAAW,OAAO,UAAU,YAAY,OAAO,aAAa,EAAE,GAAG,GACF,CAAC;CAC/E,MAAM,WAAA,GAAUb,MAAAA,OAAAA,CAAO,KAAK;CAC5B,MAAM,cAAA,GAAaA,MAAAA,OAAAA,CAAO,OAAO;CACjC,WAAW,UAAU;CACrB,MAAM,EAAE,UAAU,aAAa;CAC/B,MAAM,UACJ,aAAa,SACZ,SAAS,YAAY,cACpB,SAAS,YAAY,YACpB,SAAS,YAAY,YACnB,CAAC,SAAS,WAAW,SAAS,QAAQ,SAAS,MAAM,KAAK,SAAS,SAAS;CACnF,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,IAAI,CAAC,WAAW,QAAQ,SAAS;EACjC,QAAQ,UAAU;EAClB,IAAI,SAAS,YAAY,SAAS;GAChC,CAAA,GAAA,OAAA,MAAA,CACE,SAAS,WAAW,KAAA,IAChB,EAAE,uBAAuB,EAAE,cAAc,8BAA8B,CAAC,IACxEE,6BAAAA,WAAW,MAAM,SAAS,QAAQ,QAAQ,CAChD;GACA,WAAW,QAAQ;GACnB;EACF;EACA,OAAY,CAAC,CAAC,cAAc,WAAW,QAAQ,CAAC;CAClD,GAAG;EAAC;EAAS,SAAS;EAAS,SAAS;EAAQ;EAAQ;EAAG;CAAI,CAAC;CAChE,OAAO;AACT;AAiBA,SAAgB,cAAc,EAC5B,MACA,OACA,QACA,WAC0C;CAC1C,MAAM,UAAA,GAASG,MAAAA,QAAAA,QAAe,EAAE,WAAW,KAAK,IAAI,CAAC,IAAI,CAAC;CAC1D,MAAM,QAAA,GAAOC,oBAAAA,WAAAA,CAAW,QAAQ,EAAE,SAAS,MAAM,CAAC;CAElD,MAAM,SAAqB;EACzB;EACA,WAAW;EACX,MAAM,KAAA;EACN,aAAa;EACb,GANkBQ,6BAAAA,mBAAmB,IAAI,MAAM,KAMlC;CACf;CACA,MAAM,QAAA,GAAOH,oBAAAA,YAAAA,CAAY,MAAM,EAAE,MAAM,CAAC;CACxC,MAAM,KAAA,GAAIhB,cAAAA,aAAAA,CAAa;CACvB,MAAM,QAAA,GAAOE,cAAAA,YAAAA,CAAY;CACzB,MAAM,EAAE,QAAQ,WAAW,gBAAgB,MAAM,MAAM,QAAQD,aAAAA,qBAAqB,MAAM;CAC1F,MAAM,WAAA,GAAUI,MAAAA,OAAAA,CAAO,KAAK;CAC5B,MAAM,cAAA,GAAaA,MAAAA,OAAAA,CAAO,OAAO;CACjC,WAAW,UAAU;CACrB,MAAM,EAAE,UAAU,aAAa;CAC/B,MAAM,UACJ,aAAa,SACZ,SAAS,YAAY,cACpB,SAAS,YAAY,YACpB,SAAS,YAAY,YACnB,CAAC,SAAS,WAAW,SAAS,QAAQ,SAAS,MAAM,KAAK,SAAS,SAAS;CACnF,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,IAAI,CAAC,WAAW,QAAQ,SAAS;EACjC,QAAQ,UAAU;EAClB,IAAI,SAAS,YAAY,SAAS;GAChC,CAAA,GAAA,OAAA,MAAA,CACE,SAAS,WAAW,KAAA,IAChB,EAAE,uBAAuB,EAAE,cAAc,8BAA8B,CAAC,IACxEE,6BAAAA,WAAW,MAAM,SAAS,MAAM,CACtC;GACA,WAAW,QAAQ;GACnB;EACF;EACA,OAAY,CAAC,CAAC,cAAc,WAAW,QAAQ,CAAC;CAClD,GAAG;EAAC;EAAS,SAAS;EAAS,SAAS;EAAQ;EAAQ;EAAG;CAAI,CAAC;CAChE,OAAO;AACT;AAeA,SAAgB,eAAe,EAC7B,UACA,YACA,KACA,YAC2C;CAC3C,MAAM,OAAA,GAAMU,cAAAA,WAAAA,CAAW;CACvB,MAAM,KAAA,GAAIjB,cAAAA,aAAAA,CAAa;CACvB,MAAM,QAAA,GAAOE,cAAAA,YAAAA,CAAY,QAAQ;CACjC,MAAM,SAAS,IAAI,KAAK,IAAQ;CAEhC,MAAM,aAAA,GAAYQ,MAAAA,QAAAA,QAAe;EAAE,KAAK,CAAC,GAAG,GAAG;EAAG,OAAO,IAAI;CAAO,IAAI,CAAC,MAAM,CAAC;CAChF,MAAM,UAAA,GAASA,MAAAA,QAAAA,QAAe;EAAE;EAAU,QAAQ;CAAW,IAAI,CAAC,UAAU,UAAU,CAAC;CACvF,MAAM,QAAA,GAAOC,oBAAAA,WAAAA,CAAW,QAAQ;EAAE;EAAW,SAAS;CAAO,CAAC;CAC9D,MAAM,SAASC,6BAAAA,cAAc,UAAU,UAAU;CACjD,MAAM,SAAS,IAAI,WAAW,UAAU,UAAU;CAClD,MAAM,CAAC,YAAY,kBAAA,GAAiBR,MAAAA,SAAAA,CAAS,KAAK;CAClD,MAAM,UAAA,GAASC,MAAAA,OAAAA,CAA4C,IAAI;CAC/D,MAAM,WAAA,GAAUA,MAAAA,OAAAA,CAAO,KAAK;CAC5B,MAAM,eAAA,GAAcA,MAAAA,OAAAA,CAAO,QAAQ;CACnC,YAAY,UAAU;CACtB,MAAM,EAAE,KAAK,aAAa;CAC1B,CAAA,GAAA,MAAA,UAAA,aACc;EACV,OAAO,UAAU,KAAK;EACtB,OAAO,UAAU;CACnB,GACA,CAAC,CACH;CACA,MAAM,UACJ,QAAQ,QAAQ,SAAS,YAAY,eAAe,SAAS,YAAY;CAC3E,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,IAAI,CAAC,WAAW,QAAQ,WAAW,QAAQ,MAAM;EACjD,QAAQ,UAAU;EAClB,CAAM,YAAY;GAChB,IAAI,IAAI,YAAY,CAAC,CAAC,YAAY,SAAS;IACzC,MAAM,UAAU,IAAI,YAAY,CAAC,CAAC;IAClC,CAAA,GAAA,OAAA,MAAA,CACE,YAAY,KAAA,IACR,EAAE,uBAAuB,EAAE,cAAc,8BAA8B,CAAC,IACxEE,6BAAAA,WAAW,MAAM,SAAS,QAAQ,CACxC;IACA,YAAY,QACV,OAAO,OAAO;KAAE,SAAS;KAAe,OAAO;IAAW,CAAC,GAC3D,KAAA,CACF;IACA;GACF;GACA,IAAI,SAAS,MAAM,IAAI,OAAO;GAC9B,OACE,OAAO,YAAY,aAClB,OAAO,SAAS,YAAY,OAAO,SAAS,WAC7C;IACA,cAAc,IAAI;IAClB,MAAM,UAAU,MAAM,IAAI,SAAkB,YAAY;KACtD,OAAO,UAAU;IACnB,CAAC;IACD,OAAO,UAAU;IACjB,cAAc,KAAK;IACnB,IAAI,CAAC,SAAS;KACZ,IAAI,UAAU;KACd,YAAY,QAAQ,QAAQ,KAAA,CAAS;KACrC;IACF;IACA,SAAS,MAAM,IAAI,OAAO;GAC5B;GACA,IAAI,OAAO,YAAY,YAAY,YAAY,UAAU,OAAO,WAAW,QACzE,CAAA,GAAA,OAAA,MAAA,CAAM,EAAE,sBAAsB,EAAE,cAAc,yCAAyC,CAAC,CAAC;GAC3F,YAAY,QAAQ,QAAQ,IAAI,YAAY,CAAC,CAAC,IAAI;EACpD,EAAA,CAAG;CACL,GAAG;EAAC;EAAS;EAAK;EAAG;EAAM;CAAQ,CAAC;CACpC,MAAM,OAAuB;EAC3B;EACA,MAAM;EACN,MAAM;EACN,QAAQ;EACR,UAAU;EACV,aAAa,aACT,SAAS,SAAS,KACf,aAA8B;GAC7B,MAAM;GAEN,SAAS;IACP,IAAA,GAAGC,sBAAAA,aAAAA,CACD,QAAQ,SAAS,KAAA,IACb,QAAQ,UACR,GAAG,QAAQ,QAAQ,KAAK,EAAE,wBAAwB;KAChD,cAAc,QAAQ,SAAS,IAAI,UAAU,GAAG,QAAQ,KAAK;KAC7D,OAAO,QAAQ;IACjB,CAAC,KACL,UAAU,QAAQ,IACpB;IAEA,QAAQ,EAAE,UAAU,KAAK;GAC3B;GACA,MAAM,CAAC;GACP,OAAO,EAAE,IAAI,QAAQ,GAAG;GACxB,QAAQ;GACR,UAAU;EACZ,EACF,IACA;EACJ,eAAe,OAAO,UAAU,IAAI;EACpC,cAAc,OAAO,UAAU,KAAK;CACtC;CACA,QACE,GAAA,kBAAA,IAAA,CAACC,6BAAAA,oBAAD;EACE,OAAO;EACP,QAAQ,GAAG,OAAO;EAClB,OAAO,OAAO;EACd,cAAc,OAAO;EACrB,GAAK,OAAO,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,aAAa,OAAO,QAAQ;EACvE,MAAM,OAAO,cAAc,gBAAgB;CAC5C,CAAA;AAEL"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { n as toast } from "./toaster-
|
|
2
|
-
import { h as
|
|
1
|
+
import { n as toast } from "./toaster-Ct_YHGs6.js";
|
|
2
|
+
import { _ as reasonText, h as useFlowDialogTexts, i as makeTestId, m as useFlowChrome, t as CheckConfirmDialog } from "./check-confirm-dialog-CtiRzOAt.js";
|
|
3
|
+
import { t as useNoticeSink } from "./success-notices-LDEgEkc4.js";
|
|
3
4
|
import { APP_ACTION_RESOURCE } from "@burojs/core";
|
|
4
|
-
import { useOptionalT, useProjectedTitle, useTestIds } from "@burojs/react";
|
|
5
|
+
import { recordKeyOf, useApp, useI18nCaps, useOptionalT, useProjectedTitle, useTestIds } from "@burojs/react";
|
|
5
6
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
6
7
|
import { jsx } from "react/jsx-runtime";
|
|
7
8
|
import { toMessageRef } from "@burojs/core/internal";
|
|
@@ -10,6 +11,9 @@ import { useFlowHost, useFlowRun } from "@burojs/react/flows";
|
|
|
10
11
|
const NO_ISSUES = Object.freeze([]);
|
|
11
12
|
function useFlowLauncher(flow, host, chrome, resource, testid) {
|
|
12
13
|
const t = useOptionalT();
|
|
14
|
+
const own = resource === APP_ACTION_RESOURCE ? void 0 : resource;
|
|
15
|
+
const caps = useI18nCaps(own);
|
|
16
|
+
const showNotices = useNoticeSink(own);
|
|
13
17
|
const [confirming, setConfirming] = useState(false);
|
|
14
18
|
const decide = useRef(null);
|
|
15
19
|
const latest = useRef(flow);
|
|
@@ -39,12 +43,28 @@ function useFlowLauncher(flow, host, chrome, resource, testid) {
|
|
|
39
43
|
}
|
|
40
44
|
result = await run.accept();
|
|
41
45
|
}
|
|
46
|
+
if (result.outcome === "success") {
|
|
47
|
+
const { notices } = run.getSnapshot();
|
|
48
|
+
if (notices.length > 0) showNotices(notices);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
42
51
|
if (result.outcome === "failed" && "reason" in result && result.reason === "busy") {
|
|
43
|
-
toast(
|
|
52
|
+
toast(t("flow.busyElsewhere", { defaultValue: "This action is running in another tab." }));
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (result.outcome === "unavailable") {
|
|
56
|
+
const reason = run.getSnapshot().reason;
|
|
57
|
+
toast(reason === void 0 ? t("availability.denied", { defaultValue: "This action isn't available" }) : reasonText(caps, reason, own));
|
|
44
58
|
return;
|
|
45
59
|
}
|
|
46
60
|
if (result.outcome === "rejected" || result.outcome === "failed" || result.outcome === "unknown" || result.outcome === "halted" && result.step === "outcome") await (host.open("dialog") ?? Promise.resolve());
|
|
47
|
-
}, [
|
|
61
|
+
}, [
|
|
62
|
+
host,
|
|
63
|
+
t,
|
|
64
|
+
caps,
|
|
65
|
+
own,
|
|
66
|
+
showNotices
|
|
67
|
+
]);
|
|
48
68
|
const { snapshot, compiled } = flow;
|
|
49
69
|
const gate = {
|
|
50
70
|
resource,
|
|
@@ -54,12 +74,12 @@ function useFlowLauncher(flow, host, chrome, resource, testid) {
|
|
|
54
74
|
blockers: NO_ISSUES,
|
|
55
75
|
confirmable: confirming ? snapshot.warnings.map((warning) => ({
|
|
56
76
|
code: "check.warning",
|
|
57
|
-
message:
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
checkId: warning.id,
|
|
61
|
-
resolved: true
|
|
77
|
+
message: {
|
|
78
|
+
...toMessageRef(warning.message, `checks.${warning.id}`),
|
|
79
|
+
params: { resolved: true }
|
|
62
80
|
},
|
|
81
|
+
path: [],
|
|
82
|
+
check: { id: warning.id },
|
|
63
83
|
source: "check",
|
|
64
84
|
severity: "warning"
|
|
65
85
|
})) : NO_ISSUES,
|
|
@@ -71,8 +91,9 @@ function useFlowLauncher(flow, host, chrome, resource, testid) {
|
|
|
71
91
|
dialog: compiled === null || compiled.hasHost ? null : jsx(CheckConfirmDialog, {
|
|
72
92
|
state: gate,
|
|
73
93
|
testid: `${testid}:confirm`,
|
|
74
|
-
title: chrome.
|
|
75
|
-
proceedLabel: chrome.
|
|
94
|
+
title: chrome.confirmTitle,
|
|
95
|
+
proceedLabel: chrome.confirmProceed,
|
|
96
|
+
...chrome.dismiss === void 0 ? {} : { cancelLabel: chrome.dismiss },
|
|
76
97
|
tone: chrome.destructive ? "destructive" : "default"
|
|
77
98
|
})
|
|
78
99
|
};
|
|
@@ -87,7 +108,8 @@ function FlowRunner({ resource, actionName, record, scope, onClose }) {
|
|
|
87
108
|
surface: scope === "row" ? "row" : "menu"
|
|
88
109
|
});
|
|
89
110
|
const chrome = useFlowChrome(resource, actionName);
|
|
90
|
-
const
|
|
111
|
+
const recordKey = recordKeyOf(useApp().registry.get(resource), record);
|
|
112
|
+
const title = useProjectedTitle(resource, recordKey, record);
|
|
91
113
|
const host = useFlowHost(flow, {
|
|
92
114
|
label: chrome.labelText,
|
|
93
115
|
...record === void 0 || title === "" ? {} : { title },
|
|
@@ -95,7 +117,8 @@ function FlowRunner({ resource, actionName, record, scope, onClose }) {
|
|
|
95
117
|
});
|
|
96
118
|
const tid = useTestIds();
|
|
97
119
|
const t = useOptionalT();
|
|
98
|
-
const
|
|
120
|
+
const caps = useI18nCaps(resource);
|
|
121
|
+
const { launch, dialog } = useFlowLauncher(flow, host, chrome, resource, makeTestId(scope, resource, actionName, String(recordKey ?? ""), tid));
|
|
99
122
|
const started = useRef(false);
|
|
100
123
|
const onCloseRef = useRef(onClose);
|
|
101
124
|
onCloseRef.current = onClose;
|
|
@@ -105,7 +128,7 @@ function FlowRunner({ resource, actionName, record, scope, onClose }) {
|
|
|
105
128
|
if (!decided || started.current) return;
|
|
106
129
|
started.current = true;
|
|
107
130
|
if (snapshot.control !== "ready") {
|
|
108
|
-
toast(snapshot.reason
|
|
131
|
+
toast(snapshot.reason === void 0 ? t("availability.denied", { defaultValue: "This action isn't available" }) : reasonText(caps, snapshot.reason, resource));
|
|
109
132
|
onCloseRef.current();
|
|
110
133
|
return;
|
|
111
134
|
}
|
|
@@ -115,7 +138,8 @@ function FlowRunner({ resource, actionName, record, scope, onClose }) {
|
|
|
115
138
|
snapshot.control,
|
|
116
139
|
snapshot.reason,
|
|
117
140
|
launch,
|
|
118
|
-
t
|
|
141
|
+
t,
|
|
142
|
+
caps
|
|
119
143
|
]);
|
|
120
144
|
return dialog;
|
|
121
145
|
}
|
|
@@ -126,10 +150,12 @@ function AppFlowRunner({ name, label, testid, onClose }) {
|
|
|
126
150
|
label,
|
|
127
151
|
labelText: label,
|
|
128
152
|
icon: void 0,
|
|
129
|
-
destructive: false
|
|
153
|
+
destructive: false,
|
|
154
|
+
...useFlowDialogTexts("", name, label)
|
|
130
155
|
};
|
|
131
156
|
const host = useFlowHost(flow, { label });
|
|
132
157
|
const t = useOptionalT();
|
|
158
|
+
const caps = useI18nCaps();
|
|
133
159
|
const { launch, dialog } = useFlowLauncher(flow, host, chrome, APP_ACTION_RESOURCE, testid);
|
|
134
160
|
const started = useRef(false);
|
|
135
161
|
const onCloseRef = useRef(onClose);
|
|
@@ -140,7 +166,7 @@ function AppFlowRunner({ name, label, testid, onClose }) {
|
|
|
140
166
|
if (!decided || started.current) return;
|
|
141
167
|
started.current = true;
|
|
142
168
|
if (snapshot.control !== "ready") {
|
|
143
|
-
toast(snapshot.reason
|
|
169
|
+
toast(snapshot.reason === void 0 ? t("availability.denied", { defaultValue: "This action isn't available" }) : reasonText(caps, snapshot.reason));
|
|
144
170
|
onCloseRef.current();
|
|
145
171
|
return;
|
|
146
172
|
}
|
|
@@ -150,13 +176,15 @@ function AppFlowRunner({ name, label, testid, onClose }) {
|
|
|
150
176
|
snapshot.control,
|
|
151
177
|
snapshot.reason,
|
|
152
178
|
launch,
|
|
153
|
-
t
|
|
179
|
+
t,
|
|
180
|
+
caps
|
|
154
181
|
]);
|
|
155
182
|
return dialog;
|
|
156
183
|
}
|
|
157
184
|
function BulkFlowRunner({ resource, actionName, ids, onFinish }) {
|
|
158
185
|
const tid = useTestIds();
|
|
159
186
|
const t = useOptionalT();
|
|
187
|
+
const caps = useI18nCaps(resource);
|
|
160
188
|
const idsKey = ids.join("\0");
|
|
161
189
|
const selection = useMemo(() => ({
|
|
162
190
|
ids: [...ids],
|
|
@@ -188,7 +216,8 @@ function BulkFlowRunner({ resource, actionName, ids, onFinish }) {
|
|
|
188
216
|
started.current = true;
|
|
189
217
|
(async () => {
|
|
190
218
|
if (run.getSnapshot().control !== "ready") {
|
|
191
|
-
|
|
219
|
+
const refusal = run.getSnapshot().reason;
|
|
220
|
+
toast(refusal === void 0 ? t("availability.denied", { defaultValue: "This action isn't available" }) : reasonText(caps, refusal, resource));
|
|
192
221
|
onFinishRef.current(Object.freeze({
|
|
193
222
|
outcome: "unavailable",
|
|
194
223
|
state: "disabled"
|
|
@@ -210,13 +239,15 @@ function BulkFlowRunner({ resource, actionName, ids, onFinish }) {
|
|
|
210
239
|
}
|
|
211
240
|
result = await run.accept();
|
|
212
241
|
}
|
|
213
|
-
if (result.outcome === "failed" && "reason" in result && result.reason === "busy") toast(
|
|
242
|
+
if (result.outcome === "failed" && "reason" in result && result.reason === "busy") toast(t("flow.busyElsewhere", { defaultValue: "This action is running in another tab." }));
|
|
214
243
|
onFinishRef.current(result, run.getSnapshot().bulk);
|
|
215
244
|
})();
|
|
216
245
|
}, [
|
|
217
246
|
decided,
|
|
218
247
|
run,
|
|
219
|
-
t
|
|
248
|
+
t,
|
|
249
|
+
caps,
|
|
250
|
+
resource
|
|
220
251
|
]);
|
|
221
252
|
const gate = {
|
|
222
253
|
resource,
|
|
@@ -226,12 +257,15 @@ function BulkFlowRunner({ resource, actionName, ids, onFinish }) {
|
|
|
226
257
|
blockers: NO_ISSUES,
|
|
227
258
|
confirmable: confirming ? snapshot.warnings.map((warning) => ({
|
|
228
259
|
code: "check.warning",
|
|
229
|
-
message:
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
260
|
+
message: {
|
|
261
|
+
...toMessageRef(warning.rows === void 0 ? warning.message : `${warning.message} — ${t("flow.bulkWarningRows", {
|
|
262
|
+
defaultValue: warning.rows === 1 ? "1 row" : `${warning.rows} rows`,
|
|
263
|
+
count: warning.rows
|
|
264
|
+
})}`, `checks.${warning.id}`),
|
|
265
|
+
params: { resolved: true }
|
|
234
266
|
},
|
|
267
|
+
path: [],
|
|
268
|
+
check: { id: warning.id },
|
|
235
269
|
source: "check",
|
|
236
270
|
severity: "warning"
|
|
237
271
|
})) : NO_ISSUES,
|
|
@@ -241,12 +275,13 @@ function BulkFlowRunner({ resource, actionName, ids, onFinish }) {
|
|
|
241
275
|
return jsx(CheckConfirmDialog, {
|
|
242
276
|
state: gate,
|
|
243
277
|
testid: `${testid}:confirm`,
|
|
244
|
-
title: chrome.
|
|
245
|
-
proceedLabel: chrome.
|
|
278
|
+
title: chrome.confirmTitle,
|
|
279
|
+
proceedLabel: chrome.confirmProceed,
|
|
280
|
+
...chrome.dismiss === void 0 ? {} : { cancelLabel: chrome.dismiss },
|
|
246
281
|
tone: chrome.destructive ? "destructive" : "default"
|
|
247
282
|
});
|
|
248
283
|
}
|
|
249
284
|
//#endregion
|
|
250
285
|
export { AppFlowRunner, BulkFlowRunner, FlowRunner };
|
|
251
286
|
|
|
252
|
-
//# sourceMappingURL=flow-runtime-
|
|
287
|
+
//# sourceMappingURL=flow-runtime-DrUWyTS0.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flow-runtime-DrUWyTS0.js","names":[],"sources":["../src/flows/flow-runtime.tsx"],"sourcesContent":["'use client';\n/**\n * The flow runtime's side of the UI kit (P4, the coordinator's ruling on the bundle): every\n * component that holds a run. It loads on the first sign that a user means to run a flow (a\n * hover, a focus, a menu opening, at the latest the click) through `./load-runtime.js`, and with\n * it `@burojs/react/flows` and `@burojs/core/flows` — the flow machine stays out of an\n * application's first screen.\n */\nimport { toMessageRef } from '@burojs/core/internal';\nimport {\n APP_ACTION_RESOURCE,\n type BulkProgress,\n type FlowControlState,\n type FlowResult,\n type Row,\n type ValidationIssue,\n} from '@burojs/core';\nimport {\n type CheckGateState,\n recordKeyOf,\n useApp,\n useI18nCaps,\n useOptionalT,\n useProjectedTitle,\n useTestIds,\n} from '@burojs/react';\nimport {\n type FlowHostControl,\n type UseFlowRunResult,\n useFlowHost,\n useFlowRun,\n} from '@burojs/react/flows';\nimport { type ReactElement, useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { makeTestId } from '../actions/action-button.js';\nimport { CheckConfirmDialog } from '../checks/check-confirm-dialog.js';\nimport { useNoticeSink } from '../forms/success-notices.js';\nimport { reasonText } from '../lib/reason-text.js';\nimport { toast } from '../notification/toaster.js';\nimport { type FlowChrome, useFlowChrome, useFlowDialogTexts } from './chrome.js';\n\nconst NO_ISSUES: readonly ValidationIssue[] = Object.freeze([]);\n\n/**\n * Runs a flow from its control (4.15): a flow with a host presents it and the interaction ends\n * when it closes; a `{ label, submit }` flow sends, asks through the confirm dialog when\n * `confirm` or a fired warning asks, and shows `rejected`, `failed` and `unknown` in the flow's\n * screen in a dialog (`success` notifies through the flow's `then` and shows the write's notices; a lock another tab holds\n * says so; an `unavailable` send toasts the run's reason). `launch()` settles when the interaction is over.\n */\nfunction useFlowLauncher(\n flow: UseFlowRunResult,\n host: FlowHostControl,\n chrome: FlowChrome,\n resource: string,\n testid: string,\n): { readonly launch: () => Promise<void>; readonly dialog: ReactElement | null } {\n const t = useOptionalT();\n // An app flow's reason resolves app-wide: it has no resource bundle of its own.\n const own = resource === APP_ACTION_RESOURCE ? undefined : resource;\n const caps = useI18nCaps(own);\n // The write's own notices (spec 4.7): a host-less flow mounts no flow screen to show them, so\n // the launcher shows them through the same sink the flow screen uses.\n const showNotices = useNoticeSink(own);\n const [confirming, setConfirming] = useState(false);\n const decide = useRef<((proceed: boolean) => void) | null>(null);\n const latest = useRef(flow);\n latest.current = flow;\n useEffect(\n () => () => {\n decide.current?.(false);\n decide.current = null;\n },\n [],\n );\n\n const launch = useCallback(async (): Promise<void> => {\n const { run, compiled } = latest.current;\n if (run === null || compiled === null) return;\n if (compiled.hasHost) {\n await (host.open() ?? Promise.resolve());\n return;\n }\n let result: FlowResult = await run.submit();\n while (result.outcome === 'halted' && (result.step === 'accept' || result.step === 'review')) {\n setConfirming(true);\n const proceed = await new Promise<boolean>((resolve) => {\n decide.current = resolve;\n });\n decide.current = null;\n setConfirming(false);\n if (!proceed) {\n run.startOver();\n return;\n }\n result = await run.accept();\n }\n if (result.outcome === 'success') {\n const { notices } = run.getSnapshot();\n if (notices.length > 0) showNotices(notices);\n return;\n }\n // Another tab holds the attempt's lock: nothing was sent (4.10).\n if (result.outcome === 'failed' && 'reason' in result && result.reason === 'busy') {\n toast(t('flow.busyElsewhere', { defaultValue: 'This action is running in another tab.' }));\n return;\n }\n // The send found the flow unavailable (a check that runs at submit, access revoked since the\n // click): the run's reason, as a refusal before the click shows it.\n if (result.outcome === 'unavailable') {\n const reason = run.getSnapshot().reason;\n toast(\n reason === undefined\n ? t('availability.denied', { defaultValue: \"This action isn't available\" })\n : reasonText(caps, reason, own),\n );\n return;\n }\n if (\n result.outcome === 'rejected' ||\n result.outcome === 'failed' ||\n result.outcome === 'unknown' ||\n (result.outcome === 'halted' && result.step === 'outcome')\n )\n await (host.open('dialog') ?? Promise.resolve());\n }, [host, t, caps, own, showNotices]);\n\n const { snapshot, compiled } = flow;\n const gate: CheckGateState = {\n resource,\n open: confirming,\n busy: false,\n header: null,\n blockers: NO_ISSUES,\n confirmable: confirming\n ? snapshot.warnings.map(\n (warning): ValidationIssue => ({\n code: 'check.warning',\n // The machine's text (bundle and params resolved); the key is the check's.\n message: {\n ...toMessageRef(warning.message, `checks.${warning.id}`),\n // The run's text is final (bundle and params resolved): the dialog shows it as is.\n params: { resolved: true },\n },\n path: [],\n check: { id: warning.id },\n source: 'check',\n severity: 'warning',\n }),\n )\n : NO_ISSUES,\n proceed: () => decide.current?.(true),\n cancel: () => decide.current?.(false),\n };\n const dialog =\n compiled === null || compiled.hasHost ? null : (\n <CheckConfirmDialog\n state={gate}\n testid={`${testid}:confirm`}\n title={chrome.confirmTitle}\n proceedLabel={chrome.confirmProceed}\n {...(chrome.dismiss === undefined ? {} : { cancelLabel: chrome.dismiss })}\n tone={chrome.destructive ? 'destructive' : 'default'}\n />\n );\n return { launch, dialog };\n}\n\nexport interface FlowRunnerProps {\n readonly resource: string;\n readonly actionName: string;\n readonly record?: Row;\n readonly scope: string;\n /** The interaction is over (the host closed, the write answered, the confirm was declined). */\n readonly onClose: () => void;\n}\n\n/**\n * @internal A flow started from a control that holds no run — a row's button, a menu item\n * (4.15: a menu item \"presents its host through the runtime from `onSelect`, so the menu closes\n * normally\"). It renders no control: it starts the run (its `with` sources load now) and, once\n * the run has decided, presents the host or sends; `onClose` reports the end of the\n * interaction. A run that decides against the click (a check over a `with` source fired) says\n * why.\n */\nexport function FlowRunner({\n resource,\n actionName,\n record,\n scope,\n onClose,\n}: FlowRunnerProps): ReactElement | null {\n const target = useMemo(() => ({ resource, action: actionName }), [resource, actionName]);\n const flow = useFlowRun(target, {\n ...(record === undefined ? {} : { record }),\n surface: scope === 'row' ? 'row' : 'menu',\n });\n const chrome = useFlowChrome(resource, actionName);\n const recordKey = recordKeyOf(useApp().registry.get(resource), record);\n const title = useProjectedTitle(resource, recordKey, record);\n const host = useFlowHost(flow, {\n label: chrome.labelText,\n ...(record === undefined || title === '' ? {} : { title }),\n ...(record === undefined ? {} : { record }),\n });\n const tid = useTestIds();\n const t = useOptionalT();\n const caps = useI18nCaps(resource);\n const testid = makeTestId(scope, resource, actionName, String(recordKey ?? ''), tid);\n const { launch, dialog } = useFlowLauncher(flow, host, chrome, resource, testid);\n const started = useRef(false);\n const onCloseRef = useRef(onClose);\n onCloseRef.current = onClose;\n const { snapshot, compiled } = flow;\n const decided =\n compiled !== null &&\n (snapshot.control === 'disabled' ||\n snapshot.control === 'absent' ||\n (snapshot.control === 'ready' &&\n (!compiled.hasHost || snapshot.history.includes('open') || snapshot.step === 'outcome')));\n useEffect(() => {\n if (!decided || started.current) return;\n started.current = true;\n if (snapshot.control !== 'ready') {\n toast(\n snapshot.reason === undefined\n ? t('availability.denied', { defaultValue: \"This action isn't available\" })\n : reasonText(caps, snapshot.reason, resource),\n );\n onCloseRef.current();\n return;\n }\n void launch().finally(() => onCloseRef.current());\n }, [decided, snapshot.control, snapshot.reason, launch, t, caps]);\n return dialog;\n}\n\nexport interface AppFlowRunnerProps {\n /** The app action's name (`defineAppAction({ name, kind: 'flow' })`). */\n readonly name: string;\n /** Its label, as the opener resolved it (`appActions.<name>` over the declared default). */\n readonly label: string;\n /** The opener's test id: the confirm dialog's ids suffix it (`<testid>:confirm:…`). */\n readonly testid: string;\n readonly onClose: () => void;\n}\n\n/**\n * @internal An app flow started from its control (`AppFlowButton`, P4-D): the same launcher as a\n * resource flow's — the host when the flow has a form or a review, else the send with the\n * confirm dialog — over the target `{ appAction: name }`, with no record.\n */\nexport function AppFlowRunner({\n name,\n label,\n testid,\n onClose,\n}: AppFlowRunnerProps): ReactElement | null {\n const target = useMemo(() => ({ appAction: name }), [name]);\n const flow = useFlowRun(target, { surface: 'app' });\n const dialogTexts = useFlowDialogTexts('', name, label);\n const chrome: FlowChrome = {\n label,\n labelText: label,\n icon: undefined,\n destructive: false,\n ...dialogTexts,\n };\n const host = useFlowHost(flow, { label });\n const t = useOptionalT();\n const caps = useI18nCaps();\n const { launch, dialog } = useFlowLauncher(flow, host, chrome, APP_ACTION_RESOURCE, testid);\n const started = useRef(false);\n const onCloseRef = useRef(onClose);\n onCloseRef.current = onClose;\n const { snapshot, compiled } = flow;\n const decided =\n compiled !== null &&\n (snapshot.control === 'disabled' ||\n snapshot.control === 'absent' ||\n (snapshot.control === 'ready' &&\n (!compiled.hasHost || snapshot.history.includes('open') || snapshot.step === 'outcome')));\n useEffect(() => {\n if (!decided || started.current) return;\n started.current = true;\n if (snapshot.control !== 'ready') {\n toast(\n snapshot.reason === undefined\n ? t('availability.denied', { defaultValue: \"This action isn't available\" })\n : reasonText(caps, snapshot.reason),\n );\n onCloseRef.current();\n return;\n }\n void launch().finally(() => onCloseRef.current());\n }, [decided, snapshot.control, snapshot.reason, launch, t, caps]);\n return dialog;\n}\n\nexport interface BulkFlowRunnerProps {\n readonly resource: string;\n readonly actionName: string;\n readonly ids: readonly string[];\n /** The run is over: its result and its per-id report (absent when nothing was sent). */\n readonly onFinish: (result: FlowResult, progress: BulkProgress | undefined) => void;\n}\n\n/**\n * @internal A bulk flow's run over the selection (4.16), started by the bar's click: the confirm\n * (`confirm` and the fired warnings) asks through the confirm dialog, then the run (re-reading the\n * rows first where the flow declares `submit.reread`) writes each under its own key; `onFinish` reports the result and the per-id report.\n */\nexport function BulkFlowRunner({\n resource,\n actionName,\n ids,\n onFinish,\n}: BulkFlowRunnerProps): ReactElement | null {\n const tid = useTestIds();\n const t = useOptionalT();\n const caps = useI18nCaps(resource);\n const idsKey = ids.join('\\u0000');\n // biome-ignore lint/correctness/useExhaustiveDependencies: keyed by the ids' values\n const selection = useMemo(() => ({ ids: [...ids], count: ids.length }), [idsKey]);\n const target = useMemo(() => ({ resource, action: actionName }), [resource, actionName]);\n const flow = useFlowRun(target, { selection, surface: 'bulk' });\n const chrome = useFlowChrome(resource, actionName);\n const testid = tid.bulkAction(resource, actionName);\n const [confirming, setConfirming] = useState(false);\n const decide = useRef<((proceed: boolean) => void) | null>(null);\n const started = useRef(false);\n const onFinishRef = useRef(onFinish);\n onFinishRef.current = onFinish;\n const { run, snapshot } = flow;\n useEffect(\n () => () => {\n decide.current?.(false);\n decide.current = null;\n },\n [],\n );\n const decided =\n run !== null && snapshot.control !== 'undecided' && snapshot.control !== 'pending';\n useEffect(() => {\n if (!decided || started.current || run === null) return;\n started.current = true;\n void (async () => {\n if (run.getSnapshot().control !== 'ready') {\n const refusal = run.getSnapshot().reason;\n toast(\n refusal === undefined\n ? t('availability.denied', { defaultValue: \"This action isn't available\" })\n : reasonText(caps, refusal, resource),\n );\n onFinishRef.current(\n Object.freeze({ outcome: 'unavailable', state: 'disabled' }),\n undefined,\n );\n return;\n }\n let result = await run.submit();\n while (\n result.outcome === 'halted' &&\n (result.step === 'accept' || result.step === 'review')\n ) {\n setConfirming(true);\n const proceed = await new Promise<boolean>((resolve) => {\n decide.current = resolve;\n });\n decide.current = null;\n setConfirming(false);\n if (!proceed) {\n run.startOver();\n onFinishRef.current(result, undefined);\n return;\n }\n result = await run.accept();\n }\n if (result.outcome === 'failed' && 'reason' in result && result.reason === 'busy')\n toast(t('flow.busyElsewhere', { defaultValue: 'This action is running in another tab.' }));\n onFinishRef.current(result, run.getSnapshot().bulk);\n })();\n }, [decided, run, t, caps, resource]);\n const gate: CheckGateState = {\n resource,\n open: confirming,\n busy: false,\n header: null,\n blockers: NO_ISSUES,\n confirmable: confirming\n ? snapshot.warnings.map(\n (warning): ValidationIssue => ({\n code: 'check.warning',\n // The machine's text (bundle and params resolved); the key is the check's.\n message: {\n ...toMessageRef(\n warning.rows === undefined\n ? warning.message\n : `${warning.message} — ${t('flow.bulkWarningRows', {\n defaultValue: warning.rows === 1 ? '1 row' : `${warning.rows} rows`,\n count: warning.rows,\n })}`,\n `checks.${warning.id}`,\n ),\n // The run's text is final (bundle and params resolved): the dialog shows it as is.\n params: { resolved: true },\n },\n path: [],\n check: { id: warning.id },\n source: 'check',\n severity: 'warning',\n }),\n )\n : NO_ISSUES,\n proceed: () => decide.current?.(true),\n cancel: () => decide.current?.(false),\n };\n return (\n <CheckConfirmDialog\n state={gate}\n testid={`${testid}:confirm`}\n title={chrome.confirmTitle}\n proceedLabel={chrome.confirmProceed}\n {...(chrome.dismiss === undefined ? {} : { cancelLabel: chrome.dismiss })}\n tone={chrome.destructive ? 'destructive' : 'default'}\n />\n );\n}\n"],"mappings":"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"}
|