@burojs/ui-shadcn 0.3.0 → 0.5.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.
Files changed (179) hide show
  1. package/README.md +26 -7
  2. package/dist/bulk-summary-CwSd6Yjb.cjs +108 -0
  3. package/dist/bulk-summary-CwSd6Yjb.cjs.map +1 -0
  4. package/dist/bulk-summary-GxMDP4bw.js +108 -0
  5. package/dist/bulk-summary-GxMDP4bw.js.map +1 -0
  6. package/dist/button-BxnnE28H.cjs +55 -0
  7. package/dist/button-BxnnE28H.cjs.map +1 -0
  8. package/dist/button-MWVeZaqj.js +44 -0
  9. package/dist/button-MWVeZaqj.js.map +1 -0
  10. package/dist/candidates-gate-CX2PBu6l.js +63 -0
  11. package/dist/candidates-gate-CX2PBu6l.js.map +1 -0
  12. package/dist/candidates-gate-DiFI52r7.cjs +70 -0
  13. package/dist/candidates-gate-DiFI52r7.cjs.map +1 -0
  14. package/dist/candidates-relation-picker-CBsVcnPR.js +82 -0
  15. package/dist/candidates-relation-picker-CBsVcnPR.js.map +1 -0
  16. package/dist/candidates-relation-picker-Dd_GVLlu.cjs +84 -0
  17. package/dist/candidates-relation-picker-Dd_GVLlu.cjs.map +1 -0
  18. package/dist/check-confirm-dialog-BRByTFpg.cjs +1534 -0
  19. package/dist/check-confirm-dialog-BRByTFpg.cjs.map +1 -0
  20. package/dist/check-confirm-dialog-CkaVTPT9.js +1232 -0
  21. package/dist/check-confirm-dialog-CkaVTPT9.js.map +1 -0
  22. package/dist/dialog-B_rt9S1c.js +63 -0
  23. package/dist/dialog-B_rt9S1c.js.map +1 -0
  24. package/dist/dialog-DRNUq9EA.cjs +112 -0
  25. package/dist/dialog-DRNUq9EA.cjs.map +1 -0
  26. package/dist/filter-builder-B3mZFL-K.cjs +1761 -0
  27. package/dist/filter-builder-B3mZFL-K.cjs.map +1 -0
  28. package/dist/filter-builder-DOnaXNfP.js +1605 -0
  29. package/dist/filter-builder-DOnaXNfP.js.map +1 -0
  30. package/dist/flow-runtime-B6zOHYqI.cjs +255 -0
  31. package/dist/flow-runtime-B6zOHYqI.cjs.map +1 -0
  32. package/dist/flow-runtime-D8h99FSg.js +252 -0
  33. package/dist/flow-runtime-D8h99FSg.js.map +1 -0
  34. package/dist/flow-screen-CX05b3G9.cjs +705 -0
  35. package/dist/flow-screen-CX05b3G9.cjs.map +1 -0
  36. package/dist/flow-screen-CmbARSqg.js +701 -0
  37. package/dist/flow-screen-CmbARSqg.js.map +1 -0
  38. package/dist/index.cjs +6453 -17494
  39. package/dist/index.cjs.map +1 -1
  40. package/dist/index.d.cts +3754 -3621
  41. package/dist/index.d.ts +3754 -3621
  42. package/dist/index.js +6217 -17219
  43. package/dist/index.js.map +1 -1
  44. package/dist/inline-flow-host-B7U1OJUe.cjs +112 -0
  45. package/dist/inline-flow-host-B7U1OJUe.cjs.map +1 -0
  46. package/dist/inline-flow-host-C3H2UpSA.js +112 -0
  47. package/dist/inline-flow-host-C3H2UpSA.js.map +1 -0
  48. package/dist/input-BI0czGyI.cjs +23 -0
  49. package/dist/input-BI0czGyI.cjs.map +1 -0
  50. package/dist/input-CUPStzZO.js +17 -0
  51. package/dist/input-CUPStzZO.js.map +1 -0
  52. package/dist/label-66W1qbke.js +29 -0
  53. package/dist/label-66W1qbke.js.map +1 -0
  54. package/dist/label-w6JYf2cF.cjs +36 -0
  55. package/dist/label-w6JYf2cF.cjs.map +1 -0
  56. package/dist/layout/theme-storage-key.cjs +5 -10
  57. package/dist/layout/theme-storage-key.cjs.map +1 -1
  58. package/dist/layout/theme-storage-key.d.cts +2 -23
  59. package/dist/layout/theme-storage-key.d.ts +2 -23
  60. package/dist/layout/theme-storage-key.js +5 -2
  61. package/dist/layout/theme-storage-key.js.map +1 -1
  62. package/dist/lazy-relation-picker-dialog-2oxnA6IR.js +14 -0
  63. package/dist/lazy-relation-picker-dialog-2oxnA6IR.js.map +1 -0
  64. package/dist/lazy-relation-picker-dialog-BfAGKzUG.cjs +19 -0
  65. package/dist/lazy-relation-picker-dialog-BfAGKzUG.cjs.map +1 -0
  66. package/dist/markdown/index.cjs +424 -511
  67. package/dist/markdown/index.cjs.map +1 -1
  68. package/dist/markdown/index.d.cts +1072 -34
  69. package/dist/markdown/index.d.ts +1072 -34
  70. package/dist/markdown/index.js +411 -459
  71. package/dist/markdown/index.js.map +1 -1
  72. package/dist/page-flow-route-CQ7HsbBm.cjs +277 -0
  73. package/dist/page-flow-route-CQ7HsbBm.cjs.map +1 -0
  74. package/dist/page-flow-route-CyXSvXSE.js +277 -0
  75. package/dist/page-flow-route-CyXSvXSE.js.map +1 -0
  76. package/dist/peek-filter-CnqHwTMU.cjs +51 -0
  77. package/dist/peek-filter-CnqHwTMU.cjs.map +1 -0
  78. package/dist/peek-filter-ErLfO153.js +28 -0
  79. package/dist/peek-filter-ErLfO153.js.map +1 -0
  80. package/dist/place-node--GdsP688.js +7315 -0
  81. package/dist/place-node--GdsP688.js.map +1 -0
  82. package/dist/place-node-SIp4XYQH.cjs +7833 -0
  83. package/dist/place-node-SIp4XYQH.cjs.map +1 -0
  84. package/dist/related-list-cards-B6x9HQQp.js +42 -0
  85. package/dist/related-list-cards-B6x9HQQp.js.map +1 -0
  86. package/dist/related-list-cards-nxuODlIA.cjs +42 -0
  87. package/dist/related-list-cards-nxuODlIA.cjs.map +1 -0
  88. package/dist/related-list-timeline-BYJKEbmA.cjs +142 -0
  89. package/dist/related-list-timeline-BYJKEbmA.cjs.map +1 -0
  90. package/dist/related-list-timeline-DEdfd-rr.js +142 -0
  91. package/dist/related-list-timeline-DEdfd-rr.js.map +1 -0
  92. package/dist/related-rows-B4levHcR.js +186 -0
  93. package/dist/related-rows-B4levHcR.js.map +1 -0
  94. package/dist/related-rows-zh5f_4QR.cjs +209 -0
  95. package/dist/related-rows-zh5f_4QR.cjs.map +1 -0
  96. package/dist/relation-create-BOaUe12G.cjs +362 -0
  97. package/dist/relation-create-BOaUe12G.cjs.map +1 -0
  98. package/dist/relation-create-Bg-eEJLs.js +337 -0
  99. package/dist/relation-create-Bg-eEJLs.js.map +1 -0
  100. package/dist/relation-many-picker-B-NCEUgX.cjs +465 -0
  101. package/dist/relation-many-picker-B-NCEUgX.cjs.map +1 -0
  102. package/dist/relation-many-picker-gdAOD-qK.js +464 -0
  103. package/dist/relation-many-picker-gdAOD-qK.js.map +1 -0
  104. package/dist/relation-picker-BAY77ivO.js +462 -0
  105. package/dist/relation-picker-BAY77ivO.js.map +1 -0
  106. package/dist/relation-picker-Da_uhFvA.cjs +479 -0
  107. package/dist/relation-picker-Da_uhFvA.cjs.map +1 -0
  108. package/dist/relation-picker-dialog-M0pQaWlp.cjs +300 -0
  109. package/dist/relation-picker-dialog-M0pQaWlp.cjs.map +1 -0
  110. package/dist/relation-picker-dialog-hA9rYrZB.js +299 -0
  111. package/dist/relation-picker-dialog-hA9rYrZB.js.map +1 -0
  112. package/dist/resource-page-router-OSQyRA5b.cjs +1779 -0
  113. package/dist/resource-page-router-OSQyRA5b.cjs.map +1 -0
  114. package/dist/resource-page-router-T4vS5gbJ.js +1582 -0
  115. package/dist/resource-page-router-T4vS5gbJ.js.map +1 -0
  116. package/dist/rich-text-DFerywgz.js +457 -0
  117. package/dist/rich-text-DFerywgz.js.map +1 -0
  118. package/dist/rich-text-vTyVjDoa.cjs +460 -0
  119. package/dist/rich-text-vTyVjDoa.cjs.map +1 -0
  120. package/dist/search-access-B7G5oR8n.cjs +812 -0
  121. package/dist/search-access-B7G5oR8n.cjs.map +1 -0
  122. package/dist/search-access-CURsWn-U.js +669 -0
  123. package/dist/search-access-CURsWn-U.js.map +1 -0
  124. package/dist/shell-BPlk8hEa.js +205 -0
  125. package/dist/shell-BPlk8hEa.js.map +1 -0
  126. package/dist/shell-DxhlsPwm.cjs +271 -0
  127. package/dist/shell-DxhlsPwm.cjs.map +1 -0
  128. package/dist/skeleton-U2noefj5.js +13 -0
  129. package/dist/skeleton-U2noefj5.js.map +1 -0
  130. package/dist/skeleton-_1gP7wan.cjs +18 -0
  131. package/dist/skeleton-_1gP7wan.cjs.map +1 -0
  132. package/dist/styles.css +255 -17
  133. package/dist/theme/theme-css.cjs +95 -96
  134. package/dist/theme/theme-css.cjs.map +1 -1
  135. package/dist/theme/theme-css.d.cts +10 -8
  136. package/dist/theme/theme-css.d.ts +10 -8
  137. package/dist/theme/theme-css.js +94 -94
  138. package/dist/theme/theme-css.js.map +1 -1
  139. package/dist/theme/theme-storage.cjs +34 -39
  140. package/dist/theme/theme-storage.cjs.map +1 -1
  141. package/dist/theme/theme-storage.d.cts +3 -1
  142. package/dist/theme/theme-storage.d.ts +3 -1
  143. package/dist/theme/theme-storage.js +33 -37
  144. package/dist/theme/theme-storage.js.map +1 -1
  145. package/dist/theme-storage-key-pYlp4aDS.d.cts +31 -0
  146. package/dist/theme-storage-key-pYlp4aDS.d.ts +31 -0
  147. package/dist/toaster-C7CiYA4Z.cjs +248 -0
  148. package/dist/toaster-C7CiYA4Z.cjs.map +1 -0
  149. package/dist/toaster-CfCRLgR-.js +164 -0
  150. package/dist/toaster-CfCRLgR-.js.map +1 -0
  151. package/dist/use-dialog-filter-state-BBCC0OEK.cjs +92 -0
  152. package/dist/use-dialog-filter-state-BBCC0OEK.cjs.map +1 -0
  153. package/dist/use-dialog-filter-state-BDcgS5Oz.js +87 -0
  154. package/dist/use-dialog-filter-state-BDcgS5Oz.js.map +1 -0
  155. package/dist/use-theme-DFlpXils.cjs +257 -0
  156. package/dist/use-theme-DFlpXils.cjs.map +1 -0
  157. package/dist/use-theme-dnE3Od3I.js +175 -0
  158. package/dist/use-theme-dnE3Od3I.js.map +1 -0
  159. package/package.json +18 -17
  160. package/dist/chunk-ABUQPOOE.js +0 -11
  161. package/dist/chunk-ABUQPOOE.js.map +0 -1
  162. package/dist/chunk-DBGGWBFG.cjs +0 -199
  163. package/dist/chunk-DBGGWBFG.cjs.map +0 -1
  164. package/dist/chunk-FMX4GLCQ.js +0 -6
  165. package/dist/chunk-FMX4GLCQ.js.map +0 -1
  166. package/dist/chunk-UC57Z243.js +0 -143
  167. package/dist/chunk-UC57Z243.js.map +0 -1
  168. package/dist/chunk-UPGPO75B.js +0 -164
  169. package/dist/chunk-UPGPO75B.js.map +0 -1
  170. package/dist/chunk-VXJAXJ3U.cjs +0 -8
  171. package/dist/chunk-VXJAXJ3U.cjs.map +0 -1
  172. package/dist/chunk-W7AEYE7A.cjs +0 -13
  173. package/dist/chunk-W7AEYE7A.cjs.map +0 -1
  174. package/dist/chunk-YF5IW525.cjs +0 -155
  175. package/dist/chunk-YF5IW525.cjs.map +0 -1
  176. package/dist/rich-text-6V7WZ3WV.cjs +0 -518
  177. package/dist/rich-text-6V7WZ3WV.cjs.map +0 -1
  178. package/dist/rich-text-N2FZEJJV.js +0 -491
  179. package/dist/rich-text-N2FZEJJV.js.map +0 -1
@@ -0,0 +1,705 @@
1
+ const require_use_theme = require("./use-theme-DFlpXils.cjs");
2
+ const require_check_confirm_dialog = require("./check-confirm-dialog-BRByTFpg.cjs");
3
+ const require_button = require("./button-BxnnE28H.cjs");
4
+ const require_shell = require("./shell-DxhlsPwm.cjs");
5
+ const require_place_node = require("./place-node-SIp4XYQH.cjs");
6
+ let _burojs_core = require("@burojs/core");
7
+ let _burojs_react = require("@burojs/react");
8
+ let _tabler_icons_react = require("@tabler/icons-react");
9
+ let react = require("react");
10
+ let react_jsx_runtime = require("react/jsx-runtime");
11
+ let _radix_ui_react_dialog = require("@radix-ui/react-dialog");
12
+ _radix_ui_react_dialog = require_use_theme.__toESM(_radix_ui_react_dialog, 1);
13
+ let _burojs_core_internal = require("@burojs/core/internal");
14
+ let _burojs_react_flows = require("@burojs/react/flows");
15
+ //#region src/flows/review-diff.tsx
16
+ const REVIEW_DIFF_BLOCK = "buro:review-diff";
17
+ function sensitive(definition) {
18
+ if ((0, _burojs_core.fieldSensitivity)(definition) !== void 0) return true;
19
+ if (definition === null || typeof definition !== "object") return false;
20
+ const opts = definition.opts;
21
+ const marked = opts !== null && typeof opts === "object" ? opts.sensitive : void 0;
22
+ return marked !== void 0 && marked !== false && marked !== null;
23
+ }
24
+ const same = (a, b) => {
25
+ if (Object.is(a, b)) return true;
26
+ const empty = (value) => value === void 0 || value === null || value === "";
27
+ if (empty(a) && empty(b)) return true;
28
+ try {
29
+ return JSON.stringify(a) === JSON.stringify(b);
30
+ } catch {
31
+ return false;
32
+ }
33
+ };
34
+ function ReviewDiff({ form, initial, values, i18nPrefix, testid }) {
35
+ const t = (0, _burojs_react.useOptionalT)();
36
+ const changedText = (() => {
37
+ const value = t("review.changed");
38
+ return value === "review.changed" ? "changed" : value;
39
+ })();
40
+ const rows = form.fields.filter((binding) => !same(initial[binding.name], values[binding.name]));
41
+ return (0, react_jsx_runtime.jsx)("dl", {
42
+ "data-testid": `${testid}:review`,
43
+ "data-buro-block": REVIEW_DIFF_BLOCK,
44
+ className: "grid gap-2",
45
+ children: rows.map((binding) => {
46
+ const definition = binding.field;
47
+ const label = typeof definition.label === "string" ? definition.label : (0, _burojs_core.humanizeKey)(binding.name);
48
+ const hidden = sensitive(binding.field);
49
+ return (0, react_jsx_runtime.jsxs)("div", {
50
+ "data-testid": `${testid}:review:${binding.name}`,
51
+ className: "grid grid-cols-[minmax(0,1fr)_minmax(0,2fr)] gap-2 text-sm",
52
+ children: [(0, react_jsx_runtime.jsx)("dt", {
53
+ className: "font-medium",
54
+ children: label
55
+ }), (0, react_jsx_runtime.jsx)("dd", {
56
+ className: "flex flex-wrap items-center gap-2",
57
+ children: hidden ? (0, react_jsx_runtime.jsx)("span", {
58
+ className: "text-muted-foreground",
59
+ children: changedText
60
+ }) : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
61
+ (0, react_jsx_runtime.jsx)("span", {
62
+ "data-buro-review": "old",
63
+ className: "text-muted-foreground line-through",
64
+ children: (0, react_jsx_runtime.jsx)(require_place_node.FieldDisplay, {
65
+ i18nPrefix,
66
+ name: binding.name,
67
+ field: binding.field,
68
+ value: initial[binding.name],
69
+ fallback: (0, react_jsx_runtime.jsx)("span", { children: display(initial[binding.name]) })
70
+ })
71
+ }),
72
+ (0, react_jsx_runtime.jsx)("span", {
73
+ "aria-hidden": "true",
74
+ children: "→"
75
+ }),
76
+ (0, react_jsx_runtime.jsx)("span", {
77
+ "data-buro-review": "new",
78
+ children: (0, react_jsx_runtime.jsx)(require_place_node.FieldDisplay, {
79
+ i18nPrefix,
80
+ name: binding.name,
81
+ field: binding.field,
82
+ value: values[binding.name],
83
+ fallback: (0, react_jsx_runtime.jsx)("span", { children: display(values[binding.name]) })
84
+ })
85
+ })
86
+ ] })
87
+ })]
88
+ }, binding.name);
89
+ })
90
+ });
91
+ }
92
+ const display = (value) => value === void 0 || value === null || value === "" ? "—" : String(value);
93
+ //#endregion
94
+ //#region src/flows/flow-screen.tsx
95
+ const HELD = Object.freeze({
96
+ name: "AbortError",
97
+ message: "The flow run sends the values."
98
+ });
99
+ function HostedFlowScreen(props) {
100
+ const { binding, ...rest } = props;
101
+ return (0, react_jsx_runtime.jsx)(FlowHostBindingContext.Provider, {
102
+ value: binding,
103
+ children: (0, react_jsx_runtime.jsx)(FlowScreen, { ...rest })
104
+ });
105
+ }
106
+ const FlowHostBindingContext = (0, react.createContext)(null);
107
+ function OverlayBinding({ children }) {
108
+ const instance = (0, _burojs_react.useUIInstance)();
109
+ const runtime = (0, _burojs_react.useUIPresentationRuntime)();
110
+ const binding = (0, react.useMemo)(() => ({
111
+ kind: "overlay",
112
+ close: () => instance.dismiss(),
113
+ finish: () => runtime.dismiss(instance.id)
114
+ }), [instance, runtime]);
115
+ return (0, react_jsx_runtime.jsx)(FlowHostBindingContext.Provider, {
116
+ value: binding,
117
+ children
118
+ });
119
+ }
120
+ function WithBinding({ children }) {
121
+ return (0, react.useContext)(FlowHostBindingContext) !== null ? (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children }) : (0, react_jsx_runtime.jsx)(OverlayBinding, { children });
122
+ }
123
+ function text(t, key, fallback, params) {
124
+ const value = t(key, params === void 0 ? void 0 : { params });
125
+ return value === key ? fallback : value;
126
+ }
127
+ const REJECTED_KEYS = {
128
+ validation: "validation",
129
+ conflict: "conflict",
130
+ forbidden: "forbidden",
131
+ "not-found": "notFound"
132
+ };
133
+ function outcomeMessage(snapshot, busy, t) {
134
+ if (busy) return text(t, "flow.busyElsewhere", "This action is running in another tab.");
135
+ const outcome = snapshot.outcome;
136
+ if (outcome === void 0 || outcome.outcome === "success") {
137
+ if (snapshot.control === "disabled" && snapshot.reason !== void 0) return snapshot.reason;
138
+ return null;
139
+ }
140
+ if (outcome.outcome === "unknown") return [text(t, "flow.unknown", "The request timed out. It may have been applied. Nothing was resent."), ...snapshot.reason === void 0 ? [] : [snapshot.reason]].join(" ");
141
+ if (outcome.outcome === "rejected") {
142
+ if (snapshot.reason !== void 0) return snapshot.reason;
143
+ const kind = "errorKind" in outcome ? outcome.errorKind : void 0;
144
+ const key = kind === void 0 ? void 0 : REJECTED_KEYS[kind];
145
+ if (key !== void 0) return text(t, `flow.rejected.${key}`, "Nothing was saved.");
146
+ return text(t, "flow.rejected.precondition", "The record changed. Nothing was sent.");
147
+ }
148
+ if (outcome.outcome === "failed") return snapshot.reason ?? text(t, "flow.failed", "The request could not be sent. Nothing was saved.");
149
+ return null;
150
+ }
151
+ function FlowScreen(props) {
152
+ if (props.run !== void 0 && props.compiled !== void 0) return (0, react_jsx_runtime.jsx)(HeldFlowScreen, {
153
+ ...props,
154
+ run: props.run,
155
+ compiled: props.compiled
156
+ });
157
+ if (props.start !== void 0) return (0, react_jsx_runtime.jsx)(OwnedFlowScreen, {
158
+ ...props,
159
+ start: props.start
160
+ });
161
+ return null;
162
+ }
163
+ function HeldFlowScreen(props) {
164
+ const [generation, setGeneration] = (0, react.useState)(0);
165
+ return (0, react_jsx_runtime.jsx)(WithBinding, { children: (0, react_jsx_runtime.jsx)(_burojs_react.ScreenStateProvider, { children: (0, react_jsx_runtime.jsx)(FlowScreenBody, {
166
+ ...props,
167
+ onFreshForm: () => setGeneration((value) => value + 1)
168
+ }) }, generation) });
169
+ }
170
+ function OwnedFlowScreen(props) {
171
+ const { start, effects, onSettle } = props;
172
+ const flow = (0, _burojs_react_flows.useFlowRun)(start.target, {
173
+ ...start.record === void 0 ? {} : { record: start.record },
174
+ ...start.args === void 0 ? {} : { args: start.args },
175
+ ...start.selection === void 0 ? {} : { selection: start.selection },
176
+ surface: "host",
177
+ ...effects === void 0 ? {} : { thenEffects: effects }
178
+ });
179
+ flow.holdThen(true);
180
+ const latest = (0, react.useRef)(flow);
181
+ latest.current = flow;
182
+ (0, react.useEffect)(() => () => {
183
+ setTimeout(() => {
184
+ latest.current.holdThen(false);
185
+ latest.current.runThen();
186
+ }, 0);
187
+ }, []);
188
+ const { run, snapshot, compiled } = flow;
189
+ const outcome = snapshot.outcome;
190
+ (0, react.useEffect)(() => {
191
+ if (outcome !== void 0) onSettle?.(outcome);
192
+ }, [outcome, onSettle]);
193
+ const instance = (0, _burojs_react.useUIInstance)();
194
+ const t = (0, _burojs_react.useOptionalT)();
195
+ const tid = (0, _burojs_react.useTestIds)();
196
+ if (run !== null && compiled !== null && (snapshot.history.includes("open") || snapshot.step === "outcome")) return (0, react_jsx_runtime.jsx)(HeldFlowScreen, {
197
+ ...props,
198
+ run,
199
+ compiled
200
+ });
201
+ const refused = snapshot.control === "disabled" || snapshot.control === "absent";
202
+ return (0, react_jsx_runtime.jsxs)("div", {
203
+ "data-testid": compiled === null ? void 0 : `${tid.flowHost(compiled.flowId)}:opening`,
204
+ "data-buro-host": props.host,
205
+ "data-buro-flow-step": refused ? "refused" : "opening",
206
+ "aria-busy": refused ? void 0 : "true",
207
+ className: "flex min-h-0 flex-1 flex-col gap-4",
208
+ children: [
209
+ (0, react_jsx_runtime.jsx)(OwnTitleHeading, { label: props.label }),
210
+ refused ? (0, react_jsx_runtime.jsx)("p", {
211
+ role: "alert",
212
+ className: "text-sm",
213
+ children: snapshot.reason ?? text(t, "flow.unavailable", "Not allowed.")
214
+ }) : (0, react_jsx_runtime.jsx)(_tabler_icons_react.IconLoader2, {
215
+ className: "h-5 w-5 animate-spin self-center",
216
+ "aria-hidden": "true"
217
+ }),
218
+ (0, react_jsx_runtime.jsx)("div", {
219
+ className: "flex justify-end",
220
+ children: (0, react_jsx_runtime.jsx)(require_button.Button, {
221
+ type: "button",
222
+ variant: "ghost",
223
+ onClick: () => instance.dismiss(),
224
+ children: text(t, "flow.close", "Close")
225
+ })
226
+ })
227
+ ]
228
+ });
229
+ }
230
+ function OwnTitleHeading({ label }) {
231
+ const ownTitle = (0, react.useContext)(require_shell.OwnTitleContext);
232
+ const heading = (0, react_jsx_runtime.jsx)("h2", {
233
+ tabIndex: -1,
234
+ "data-buro-overlay-heading": "",
235
+ className: "text-lg font-semibold",
236
+ children: label
237
+ });
238
+ return ownTitle ? (0, react_jsx_runtime.jsx)(_radix_ui_react_dialog.Title, {
239
+ asChild: true,
240
+ children: heading
241
+ }) : heading;
242
+ }
243
+ function FlowScreenBody({ run, host, label, title: givenTitle, compiled, record, args, selection, onFreshForm }) {
244
+ const snapshot = useSyncSnapshot(run);
245
+ const binding = (0, react.useContext)(FlowHostBindingContext);
246
+ const tid = (0, _burojs_react.useTestIds)();
247
+ const t = (0, _burojs_react.useOptionalT)();
248
+ const resource = compiled.resource ?? void 0;
249
+ const caps = (0, _burojs_react.useI18nCaps)(resource);
250
+ const ownTitle = (0, react.useContext)(require_shell.OwnTitleContext);
251
+ const flowId = compiled.flowId;
252
+ const recordId = record?.[compiled.idField] ?? record?.id;
253
+ const recordTitle = (0, _burojs_react.useProjectedTitle)(resource, recordId, record);
254
+ const title = givenTitle ?? (record === void 0 || recordTitle === "" ? void 0 : recordTitle);
255
+ const form = (0, _burojs_react_flows.useFlowForm)(run, compiled, snapshot, {
256
+ ...record === void 0 ? {} : { record },
257
+ ...args === void 0 ? {} : { args },
258
+ ...selection === void 0 ? {} : { selection: selection.ids }
259
+ });
260
+ const hasForm = compiled.flow.form !== void 0;
261
+ const [busy, setBusy] = (0, react.useState)(false);
262
+ const [initial] = (0, react.useState)(() => run.getSnapshot().values);
263
+ const formErrors = form.errors.filter((issue) => issue.field === "_form");
264
+ const locked = snapshot.control === "running";
265
+ (0, _burojs_react.useDismissPending)(locked);
266
+ const outcome = snapshot.outcome?.outcome;
267
+ const unknown = outcome === "unknown";
268
+ const succeeded = outcome === "success";
269
+ const finalStep = snapshot.step === "review" || snapshot.step === "accept";
270
+ const openBlock = succeeded ? blockOpen(snapshot.effects?.open) : null;
271
+ (0, react.useEffect)(() => {
272
+ if (succeeded && !locked && openBlock === null) binding.finish();
273
+ }, [
274
+ succeeded,
275
+ locked,
276
+ openBlock,
277
+ binding
278
+ ]);
279
+ const prefix = compiled.resource === null ? `appActions.${compiled.name}` : `${compiled.resource}.actions.${compiled.name}`;
280
+ const settle = (result) => {
281
+ setBusy(result.outcome === "failed" && "reason" in result && result.reason === "busy");
282
+ };
283
+ const submit = async () => {
284
+ if (locked) return;
285
+ setBusy(false);
286
+ if (finalStep) {
287
+ settle(await run.accept());
288
+ return;
289
+ }
290
+ if (unknown && editingNew) {
291
+ let valid = false;
292
+ await form.handleSubmit(() => {
293
+ valid = true;
294
+ throw HELD;
295
+ })();
296
+ if (valid) setConfirmingNew(true);
297
+ return;
298
+ }
299
+ if (unknown) return;
300
+ if (hasForm) {
301
+ let validated = false;
302
+ await form.handleSubmit(() => {
303
+ validated = true;
304
+ throw HELD;
305
+ })();
306
+ if (!validated) return;
307
+ }
308
+ settle(await run.submit());
309
+ };
310
+ const pendingKey = compiled.resource === null ? `appActions.${compiled.name}.pending` : `resources.${compiled.resource}.actions.${compiled.name}.pending`;
311
+ const pendingLabel = caps.has(pendingKey) ? caps.t(pendingKey) : `${label}…`;
312
+ const message = outcomeMessage(snapshot, busy, t);
313
+ const couldNotCheck = snapshot.control === "disabled" && snapshot.reason !== void 0 && snapshot.reason === text(t, "flow.couldNotCheck", "Couldn't check");
314
+ const steps = form.steps;
315
+ const lastStep = steps === null || steps.ids.length === 0 || steps.current === steps.ids[steps.ids.length - 1];
316
+ const showSubmit = !unknown && !succeeded && (!hasForm || finalStep || lastStep);
317
+ const [confirmingNew, setConfirmingNew] = (0, react.useState)(false);
318
+ const [editingNew, setEditingNew] = (0, react.useState)(false);
319
+ const checkable = compiled.flow.submit.onUnknown !== void 0;
320
+ const unhandled = unknown && !checkable && !snapshot.canResend;
321
+ const exit = (action) => () => {
322
+ if (!locked) action().then(settle);
323
+ };
324
+ const close = () => {
325
+ if (binding.kind === "inline" && hasForm && !unknown) form.draft.discard();
326
+ binding.close();
327
+ };
328
+ const heading = (0, react_jsx_runtime.jsxs)("h2", {
329
+ tabIndex: -1,
330
+ "data-buro-overlay-heading": "",
331
+ className: "min-w-0 flex-1 break-words text-lg font-semibold tracking-tight focus-visible:outline-hidden",
332
+ children: [label, title === void 0 ? null : (0, react_jsx_runtime.jsx)("span", {
333
+ className: "ml-2 font-normal text-muted-foreground",
334
+ children: title
335
+ })]
336
+ });
337
+ return (0, react_jsx_runtime.jsxs)("div", {
338
+ "data-testid": tid.flowHost(flowId),
339
+ "data-buro-host": host,
340
+ "data-buro-flow-step": snapshot.step,
341
+ "aria-busy": locked ? "true" : void 0,
342
+ className: "flex min-h-0 flex-1 flex-col gap-4",
343
+ children: [
344
+ binding.kind === "inline" ? null : (0, react_jsx_runtime.jsxs)("div", {
345
+ "data-buro-region": "flow-header",
346
+ className: "flex items-center gap-2 pr-1",
347
+ children: [
348
+ ownTitle ? (0, react_jsx_runtime.jsx)(_radix_ui_react_dialog.Title, {
349
+ asChild: true,
350
+ children: heading
351
+ }) : heading,
352
+ compiled.resource === null ? null : (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.DocInfo, {
353
+ address: `${compiled.resource}/actions/${compiled.name}`,
354
+ name: label,
355
+ testId: `${tid.flowHost(flowId)}:info`
356
+ }),
357
+ binding.kind === "overlay" ? (0, react_jsx_runtime.jsx)(require_button.Button, {
358
+ type: "button",
359
+ variant: "ghost",
360
+ size: "icon",
361
+ className: "h-8 w-8 shrink-0",
362
+ "data-testid": tid.flowClose(flowId),
363
+ "aria-label": text(t, "flow.close", "Close"),
364
+ onClick: close,
365
+ children: (0, react_jsx_runtime.jsx)(_tabler_icons_react.IconX, {
366
+ className: "h-4 w-4",
367
+ "aria-hidden": "true"
368
+ })
369
+ }) : null
370
+ ]
371
+ }),
372
+ openBlock !== null ? (0, react_jsx_runtime.jsx)(FlowOpenBlock, {
373
+ open: openBlock,
374
+ prefix,
375
+ testid: tid.flowHost(flowId)
376
+ }) : null,
377
+ openBlock !== null && binding.kind !== "overlay" ? (0, react_jsx_runtime.jsx)("div", {
378
+ className: "flex justify-end",
379
+ children: (0, react_jsx_runtime.jsx)(require_button.Button, {
380
+ type: "button",
381
+ variant: "outline",
382
+ "data-testid": tid.flowClose(flowId),
383
+ onClick: close,
384
+ children: text(t, "flow.done", "Done")
385
+ })
386
+ }) : null,
387
+ (0, react_jsx_runtime.jsxs)("form", {
388
+ hidden: openBlock !== null,
389
+ noValidate: true,
390
+ className: openBlock === null ? "flex min-h-0 flex-1 flex-col gap-4" : "hidden",
391
+ onSubmit: (event) => {
392
+ event.preventDefault();
393
+ submit();
394
+ },
395
+ children: [
396
+ (0, react_jsx_runtime.jsxs)("div", {
397
+ className: "-mx-1 flex min-h-0 flex-1 flex-col gap-4 overflow-y-auto px-1",
398
+ children: [
399
+ message === null ? null : (0, react_jsx_runtime.jsxs)("div", {
400
+ role: unknown || outcome === "rejected" || outcome === "failed" ? "alert" : "status",
401
+ "data-testid": tid.flowOutcome(flowId),
402
+ "data-buro-flow-outcome": busy ? "busy" : outcome ?? snapshot.control,
403
+ className: "flex flex-wrap items-center gap-2 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive",
404
+ children: [(0, react_jsx_runtime.jsx)("span", { children: message }), couldNotCheck ? (0, react_jsx_runtime.jsx)(require_button.Button, {
405
+ type: "button",
406
+ size: "sm",
407
+ variant: "outline",
408
+ className: "ml-auto",
409
+ onClick: () => run.retryChecks(),
410
+ children: text(t, "actions.retry", "Retry")
411
+ }) : null]
412
+ }),
413
+ hasForm && form.draft.pending !== null && (!unknown || editingNew) ? (0, react_jsx_runtime.jsxs)("div", {
414
+ "data-testid": tid.flowDraft(flowId),
415
+ role: "status",
416
+ "aria-live": "polite",
417
+ className: "flex flex-wrap items-center gap-2 rounded-md border border-warning/50 bg-warning/10 px-3 py-2 text-sm",
418
+ children: [(0, react_jsx_runtime.jsx)("span", {
419
+ className: "font-medium",
420
+ children: text(t, "draft.restorePrompt", "Restore draft?")
421
+ }), (0, react_jsx_runtime.jsxs)("div", {
422
+ className: "ml-auto flex gap-2",
423
+ children: [(0, react_jsx_runtime.jsx)(require_button.Button, {
424
+ type: "button",
425
+ size: "sm",
426
+ variant: "outline",
427
+ "data-testid": `${tid.flowDraft(flowId)}:restore`,
428
+ onClick: form.draft.restore,
429
+ children: text(t, "draft.restore", "Restore")
430
+ }), (0, react_jsx_runtime.jsx)(require_button.Button, {
431
+ type: "button",
432
+ size: "sm",
433
+ variant: "ghost",
434
+ "data-testid": `${tid.flowDraft(flowId)}:discard`,
435
+ onClick: form.draft.discard,
436
+ children: text(t, "draft.discard", "Discard")
437
+ })]
438
+ })]
439
+ }) : null,
440
+ formErrors.length > 0 ? (0, react_jsx_runtime.jsx)("div", {
441
+ role: "alert",
442
+ "data-testid": `${tid.flowHost(flowId)}:form-errors`,
443
+ className: "flex flex-col gap-1 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive",
444
+ children: formErrors.map((issue, index) => (0, react_jsx_runtime.jsx)("p", { children: (0, _burojs_react.resolveValidationMessage)({
445
+ code: issue.code ?? "",
446
+ message: issue.message,
447
+ ...issue.params === void 0 ? {} : { params: issue.params }
448
+ }, { t }) }, index))
449
+ }) : null,
450
+ finalStep && compiled.flow.review === true ? (0, react_jsx_runtime.jsx)(ReviewDiff, {
451
+ form,
452
+ initial,
453
+ values: snapshot.values,
454
+ i18nPrefix: prefix,
455
+ testid: tid.flowHost(flowId)
456
+ }) : finalStep && Array.isArray(compiled.flow.review) ? (0, react_jsx_runtime.jsx)(ReviewTree, {
457
+ compiled,
458
+ tree: compiled.flow.review,
459
+ values: snapshot.values,
460
+ prefix
461
+ }) : hasForm ? (0, react_jsx_runtime.jsx)(require_place_node.ScreenTree, {
462
+ region: "form-body",
463
+ resource: prefix,
464
+ mode: "create",
465
+ compiled: form.screen,
466
+ controller: form,
467
+ leafIds: "record",
468
+ disabled: locked || unknown && !editingNew || finalStep || succeeded
469
+ }) : null,
470
+ finalStep && snapshot.warnings.length > 0 ? (0, react_jsx_runtime.jsx)("ul", {
471
+ role: "status",
472
+ "data-buro-region": "flow-warnings",
473
+ className: "flex flex-col gap-1 rounded-md border border-warning/50 bg-warning/10 px-3 py-2 text-sm text-warning-emphasis",
474
+ children: snapshot.warnings.map((warning) => (0, react_jsx_runtime.jsx)("li", {
475
+ "data-testid": `${tid.flowHost(flowId)}:warning:${warning.id}`,
476
+ children: warning.message
477
+ }, warning.id))
478
+ }) : null
479
+ ]
480
+ }),
481
+ unhandled ? (0, react_jsx_runtime.jsx)("p", {
482
+ "data-testid": `${tid.flowOutcome(flowId)}:unhandled`,
483
+ className: "text-sm",
484
+ children: text(t, "flow.unknownUnhandled", "Check the record before trying again.")
485
+ }) : null,
486
+ unknown && confirmingNew ? (0, react_jsx_runtime.jsxs)("div", {
487
+ role: "alertdialog",
488
+ "aria-label": text(t, "flow.sendAsNew", "Send as new"),
489
+ "data-testid": `${tid.flowSendAsNew(flowId)}:confirm`,
490
+ className: "flex flex-wrap items-center gap-2 rounded-md border border-warning/50 bg-warning/10 px-3 py-2 text-sm",
491
+ children: [(0, react_jsx_runtime.jsx)("span", { children: text(t, "flow.sendAsNewConfirm", "This may apply the change twice. Send it as a new request?") }), (0, react_jsx_runtime.jsxs)("div", {
492
+ className: "ml-auto flex gap-2",
493
+ children: [(0, react_jsx_runtime.jsx)(require_button.Button, {
494
+ type: "button",
495
+ size: "sm",
496
+ variant: "ghost",
497
+ "data-testid": `${tid.flowSendAsNew(flowId)}:cancel`,
498
+ onClick: () => setConfirmingNew(false),
499
+ children: text(t, "actions.cancel", "Cancel")
500
+ }), (0, react_jsx_runtime.jsx)(require_button.Button, {
501
+ type: "button",
502
+ size: "sm",
503
+ variant: "destructive",
504
+ "data-testid": `${tid.flowSendAsNew(flowId)}:ok`,
505
+ onClick: () => {
506
+ setConfirmingNew(false);
507
+ exit(() => run.sendAsNew({ confirmed: true }))();
508
+ },
509
+ children: text(t, "flow.sendAsNew", "Send as new")
510
+ })]
511
+ })]
512
+ }) : null,
513
+ unknown ? (0, react_jsx_runtime.jsxs)("div", {
514
+ "data-buro-region": "flow-unknown-exits",
515
+ className: "flex flex-wrap gap-2",
516
+ children: [
517
+ checkable ? (0, react_jsx_runtime.jsx)(require_button.Button, {
518
+ type: "button",
519
+ variant: "default",
520
+ "data-testid": tid.flowCheckAgain(flowId),
521
+ disabled: locked,
522
+ onClick: exit(() => run.checkAgain()),
523
+ children: text(t, "flow.checkAgain", "Check again")
524
+ }) : null,
525
+ snapshot.canResend ? (0, react_jsx_runtime.jsx)(require_button.Button, {
526
+ type: "button",
527
+ variant: "outline",
528
+ "data-testid": tid.flowResend(flowId),
529
+ disabled: locked,
530
+ onClick: exit(() => run.resend()),
531
+ children: text(t, "flow.resend", "Resend")
532
+ }) : null,
533
+ (0, react_jsx_runtime.jsx)(require_button.Button, {
534
+ type: "button",
535
+ variant: "outline",
536
+ "data-testid": tid.flowSendAsNew(flowId),
537
+ disabled: locked || confirmingNew || editingNew,
538
+ onClick: () => {
539
+ if (hasForm) setEditingNew(true);
540
+ else setConfirmingNew(true);
541
+ },
542
+ children: text(t, "flow.sendAsNew", "Send as new")
543
+ }),
544
+ (0, react_jsx_runtime.jsx)(require_button.Button, {
545
+ type: "button",
546
+ variant: "outline",
547
+ "data-testid": tid.flowStartOver(flowId),
548
+ disabled: locked,
549
+ onClick: () => {
550
+ run.startOver();
551
+ onFreshForm();
552
+ },
553
+ children: text(t, "flow.startOver", "I've checked — start over")
554
+ })
555
+ ]
556
+ }) : null,
557
+ (0, react_jsx_runtime.jsxs)("div", {
558
+ "data-buro-region": "flow-footer",
559
+ className: "flex flex-wrap items-center gap-2",
560
+ children: [finalStep && hasForm && !locked ? (0, react_jsx_runtime.jsx)(require_button.Button, {
561
+ type: "button",
562
+ variant: "outline",
563
+ "data-testid": tid.flowBack(flowId),
564
+ onClick: () => run.back(),
565
+ children: text(t, "flow.back", "Back")
566
+ }) : null, (0, react_jsx_runtime.jsxs)("div", {
567
+ className: "ml-auto flex gap-2",
568
+ children: [
569
+ (0, react_jsx_runtime.jsx)(require_button.Button, {
570
+ type: "button",
571
+ variant: "ghost",
572
+ "data-testid": tid.flowCancel(flowId),
573
+ disabled: locked,
574
+ onClick: close,
575
+ children: unknown ? text(t, "flow.close", "Close") : binding.kind === "inline" ? text(t, "flow.reset", "Reset") : text(t, "actions.cancel", "Cancel")
576
+ }),
577
+ unknown && editingNew ? (0, react_jsx_runtime.jsx)(require_button.Button, {
578
+ type: "submit",
579
+ variant: "destructive",
580
+ "data-testid": `${tid.flowSendAsNew(flowId)}:submit`,
581
+ disabled: locked || confirmingNew,
582
+ onMouseDown: (event) => event.preventDefault(),
583
+ children: text(t, "flow.sendAsNew", "Send as new")
584
+ }) : null,
585
+ showSubmit ? (0, react_jsx_runtime.jsxs)(require_button.Button, {
586
+ type: "submit",
587
+ variant: compiled.flow.variant === "destructive" ? "destructive" : "default",
588
+ "data-testid": tid.flowSubmit(flowId),
589
+ disabled: locked || couldNotCheck,
590
+ "aria-busy": locked ? "true" : void 0,
591
+ onMouseDown: (event) => event.preventDefault(),
592
+ children: [locked ? (0, react_jsx_runtime.jsx)(_tabler_icons_react.IconLoader2, {
593
+ className: "h-4 w-4 animate-spin",
594
+ "aria-hidden": "true"
595
+ }) : null, locked ? pendingLabel : label]
596
+ }) : null
597
+ ]
598
+ })]
599
+ })
600
+ ]
601
+ })
602
+ ]
603
+ });
604
+ }
605
+ function useSyncSnapshot(run) {
606
+ return (0, react.useSyncExternalStore)(run.subscribe, run.getSnapshot, run.getSnapshot);
607
+ }
608
+ const NO_FIELDS = Object.freeze({});
609
+ function ReviewTree({ compiled, tree, values, prefix }) {
610
+ const fields = compiled.flow.form?.fields;
611
+ const map = (0, react.useState)(() => {
612
+ if (fields === void 0) return NO_FIELDS;
613
+ const placed = placedLeaves(tree);
614
+ return (0, _burojs_core_internal.fieldEntriesToMap)(fields.map((field) => placed.has(String(field.name)) ? field : {
615
+ ...field,
616
+ in: ["create"]
617
+ }));
618
+ })[0];
619
+ const body = (0, react.useState)(() => () => tree)[0];
620
+ const blocks = (0, _burojs_react.useFlowFormCatalog)();
621
+ const review = (0, _burojs_react.useFormController)({
622
+ blocks,
623
+ fields: map,
624
+ body,
625
+ mode: "show",
626
+ i18nPrefix: prefix,
627
+ value: values
628
+ });
629
+ return (0, react_jsx_runtime.jsx)(require_place_node.ScreenTree, {
630
+ region: "form-body",
631
+ resource: prefix,
632
+ mode: "show",
633
+ compiled: review.screen,
634
+ controller: review,
635
+ leafIds: "record"
636
+ });
637
+ }
638
+ function placedLeaves(tree) {
639
+ const out = new Set();
640
+ const walk = (node) => {
641
+ if (typeof node === "string") {
642
+ out.add(node);
643
+ return;
644
+ }
645
+ if (node === null || typeof node !== "object") return;
646
+ const children = node.children;
647
+ if (Array.isArray(children)) for (const child of children) walk(child);
648
+ };
649
+ for (const node of tree) walk(node);
650
+ return out;
651
+ }
652
+ function blockOpen(open) {
653
+ if (open === null || typeof open !== "object" || !Object.hasOwn(open, "block")) return null;
654
+ const { block, props } = open;
655
+ const ref = block !== null && typeof block === "object" && "ref" in block ? block.ref : block;
656
+ if (ref === null || typeof ref !== "object" || typeof ref.namespace !== "string" || typeof ref.id !== "string") return null;
657
+ return {
658
+ block: ref,
659
+ props: props !== null && typeof props === "object" ? props : {}
660
+ };
661
+ }
662
+ function FlowOpenBlock({ open, testid }) {
663
+ const t = (0, _burojs_react.useOptionalT)();
664
+ const id = `${open.block.namespace}:${open.block.id}`;
665
+ const implementation = require_place_node.selectImplementation(id, (0, _burojs_react.useFlowOpenImplementation)(id));
666
+ const [validation, setValidation] = (0, react.useState)(() => implementation === void 0 ? null : (0, _burojs_core.validatePlacementProps)(implementation.definition, open.props));
667
+ (0, react.useEffect)(() => {
668
+ if (validation?.status !== "pending") return;
669
+ let live = true;
670
+ validation.settled.then((settled) => {
671
+ if (live) setValidation(settled);
672
+ });
673
+ return () => {
674
+ live = false;
675
+ };
676
+ }, [validation]);
677
+ const failed = implementation === void 0 || validation?.status === "failed";
678
+ const View = implementation === void 0 ? null : require_place_node.viewOf(implementation);
679
+ return (0, react_jsx_runtime.jsx)("div", {
680
+ "data-testid": `${testid}:open`,
681
+ "data-buro-block": id,
682
+ className: "min-h-0 flex-1 overflow-y-auto",
683
+ children: failed ? (0, react_jsx_runtime.jsx)("p", {
684
+ role: "alert",
685
+ className: "text-sm text-muted-foreground",
686
+ children: text(t, "block.notImplemented", "This section is not available.")
687
+ }) : View === null || validation?.status !== "ready" ? null : (0, react_jsx_runtime.jsx)(react.Suspense, {
688
+ fallback: null,
689
+ children: (0, react_jsx_runtime.jsx)(View, {
690
+ props: validation.props,
691
+ data: NO_FIELDS,
692
+ t: (key, options) => t(`blocks.${id}.${key}`, {
693
+ ...options?.params === void 0 ? {} : { params: options.params },
694
+ ...options?.count === void 0 ? {} : { count: options.count }
695
+ })
696
+ })
697
+ })
698
+ });
699
+ }
700
+ //#endregion
701
+ exports.FlowHostBindingContext = FlowHostBindingContext;
702
+ exports.FlowScreen = FlowScreen;
703
+ exports.HostedFlowScreen = HostedFlowScreen;
704
+
705
+ //# sourceMappingURL=flow-screen-CX05b3G9.cjs.map