@burojs/ui-shadcn 0.7.0 → 0.9.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 (122) hide show
  1. package/dist/{bulk-summary-CrEij5vq.cjs → bulk-summary-2HLgz7Il.cjs} +31 -5
  2. package/dist/bulk-summary-2HLgz7Il.cjs.map +1 -0
  3. package/dist/{bulk-summary-BWSAS7k2.js → bulk-summary-D6A0ua21.js} +32 -6
  4. package/dist/bulk-summary-D6A0ua21.js.map +1 -0
  5. package/dist/{candidates-relation-picker-CS_JZ4Fd.js → candidates-relation-picker-QvoY2bOQ.js} +3 -3
  6. package/dist/{candidates-relation-picker-CS_JZ4Fd.js.map → candidates-relation-picker-QvoY2bOQ.js.map} +1 -1
  7. package/dist/{candidates-relation-picker-y5M6_oe4.cjs → candidates-relation-picker-pEAWKQEY.cjs} +3 -3
  8. package/dist/{candidates-relation-picker-y5M6_oe4.cjs.map → candidates-relation-picker-pEAWKQEY.cjs.map} +1 -1
  9. package/dist/{check-confirm-dialog-2j0gOd7x.js → check-confirm-dialog-B-CbJTln.js} +68 -8
  10. package/dist/{check-confirm-dialog-2j0gOd7x.js.map → check-confirm-dialog-B-CbJTln.js.map} +1 -1
  11. package/dist/{check-confirm-dialog-C-NHgMST.cjs → check-confirm-dialog-W-8WOmGh.cjs} +72 -6
  12. package/dist/check-confirm-dialog-W-8WOmGh.cjs.map +1 -0
  13. package/dist/{filter-builder-DaWHUZuV.js → filter-builder-04nas3eq.js} +127 -61
  14. package/dist/filter-builder-04nas3eq.js.map +1 -0
  15. package/dist/{filter-builder-DFu0JP-1.cjs → filter-builder-DQX-TMFh.cjs} +140 -68
  16. package/dist/filter-builder-DQX-TMFh.cjs.map +1 -0
  17. package/dist/{flow-runtime-DyqTmK3H.js → flow-runtime-BEIyym7d.js} +7 -4
  18. package/dist/{flow-runtime-DyqTmK3H.js.map → flow-runtime-BEIyym7d.js.map} +1 -1
  19. package/dist/{flow-runtime-BpmrIUb6.cjs → flow-runtime-DyNIYfUP.cjs} +7 -4
  20. package/dist/{flow-runtime-BpmrIUb6.cjs.map → flow-runtime-DyNIYfUP.cjs.map} +1 -1
  21. package/dist/{flow-screen-DCdli6Ha.js → flow-screen-DY1Z9PbG.js} +56 -15
  22. package/dist/flow-screen-DY1Z9PbG.js.map +1 -0
  23. package/dist/{flow-screen-Bcz9NF2V.cjs → flow-screen-FE5Xhb3t.cjs} +54 -13
  24. package/dist/flow-screen-FE5Xhb3t.cjs.map +1 -0
  25. package/dist/index.cjs +564 -170
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.d.cts +235 -95
  28. package/dist/index.d.ts +235 -95
  29. package/dist/index.js +562 -169
  30. package/dist/index.js.map +1 -1
  31. package/dist/{inline-flow-host-C0rI9B7f.js → inline-flow-host-D6u-RlsV.js} +3 -3
  32. package/dist/{inline-flow-host-C0rI9B7f.js.map → inline-flow-host-D6u-RlsV.js.map} +1 -1
  33. package/dist/{inline-flow-host-3vw7LzzD.cjs → inline-flow-host-yVLo6-sM.cjs} +3 -3
  34. package/dist/{inline-flow-host-3vw7LzzD.cjs.map → inline-flow-host-yVLo6-sM.cjs.map} +1 -1
  35. package/dist/{lazy-relation-picker-dialog-CAScLPb2.js → lazy-relation-picker-dialog-BaORufxQ.js} +2 -2
  36. package/dist/{lazy-relation-picker-dialog-CAScLPb2.js.map → lazy-relation-picker-dialog-BaORufxQ.js.map} +1 -1
  37. package/dist/{lazy-relation-picker-dialog-Bt8lrEIu.cjs → lazy-relation-picker-dialog-C_VlGlDz.cjs} +2 -2
  38. package/dist/{lazy-relation-picker-dialog-Bt8lrEIu.cjs.map → lazy-relation-picker-dialog-C_VlGlDz.cjs.map} +1 -1
  39. package/dist/{page-flow-route-BHUEpn0I.js → page-flow-route-CyMzUidK.js} +8 -9
  40. package/dist/page-flow-route-CyMzUidK.js.map +1 -0
  41. package/dist/{page-flow-route-DS8IVTVH.cjs → page-flow-route-OFx7h7Ja.cjs} +8 -9
  42. package/dist/page-flow-route-OFx7h7Ja.cjs.map +1 -0
  43. package/dist/{place-node-CNb3w-c7.cjs → place-node-BZF5Af6x.cjs} +224 -151
  44. package/dist/place-node-BZF5Af6x.cjs.map +1 -0
  45. package/dist/{place-node-CfzQvh4Y.js → place-node-DRjmJGQ_.js} +210 -125
  46. package/dist/place-node-DRjmJGQ_.js.map +1 -0
  47. package/dist/{related-list-cards-BIqqY69Y.js → related-list-cards-2hLitVkg.js} +3 -3
  48. package/dist/{related-list-cards-BIqqY69Y.js.map → related-list-cards-2hLitVkg.js.map} +1 -1
  49. package/dist/{related-list-cards-CelMxl4q.cjs → related-list-cards-xVvgSlu-.cjs} +3 -3
  50. package/dist/{related-list-cards-CelMxl4q.cjs.map → related-list-cards-xVvgSlu-.cjs.map} +1 -1
  51. package/dist/related-list-timeline-CxJqe6eK.js +167 -0
  52. package/dist/related-list-timeline-CxJqe6eK.js.map +1 -0
  53. package/dist/related-list-timeline-Dsf5WewG.cjs +167 -0
  54. package/dist/related-list-timeline-Dsf5WewG.cjs.map +1 -0
  55. package/dist/{related-rows-MPnLCmPF.cjs → related-rows-DDhp9axl.cjs} +4 -4
  56. package/dist/{related-rows-MPnLCmPF.cjs.map → related-rows-DDhp9axl.cjs.map} +1 -1
  57. package/dist/{related-rows--uP2iKQC.js → related-rows-DL6CWsrj.js} +4 -4
  58. package/dist/{related-rows--uP2iKQC.js.map → related-rows-DL6CWsrj.js.map} +1 -1
  59. package/dist/{relation-create-C43cdPQt.js → relation-create-6WicROWA.js} +33 -5
  60. package/dist/relation-create-6WicROWA.js.map +1 -0
  61. package/dist/{relation-create-DDEYcKfw.cjs → relation-create-_SFuPQGM.cjs} +37 -3
  62. package/dist/relation-create-_SFuPQGM.cjs.map +1 -0
  63. package/dist/{relation-many-picker-DzuGJpEl.cjs → relation-many-picker-BBNsmkaX.cjs} +18 -11
  64. package/dist/relation-many-picker-BBNsmkaX.cjs.map +1 -0
  65. package/dist/{relation-many-picker-BJhaEqxz.js → relation-many-picker-mGEQDWo2.js} +18 -11
  66. package/dist/relation-many-picker-mGEQDWo2.js.map +1 -0
  67. package/dist/{relation-picker-D-tBBZW_.js → relation-picker-BbO41cFV.js} +19 -11
  68. package/dist/relation-picker-BbO41cFV.js.map +1 -0
  69. package/dist/{relation-picker-dialog-DoEY8EkH.js → relation-picker-dialog-BgSG_8bU.js} +5 -5
  70. package/dist/relation-picker-dialog-BgSG_8bU.js.map +1 -0
  71. package/dist/{relation-picker-dialog-9Vg5vvR1.cjs → relation-picker-dialog-Duqy2r0n.cjs} +5 -5
  72. package/dist/relation-picker-dialog-Duqy2r0n.cjs.map +1 -0
  73. package/dist/{relation-picker-DaIMzf2H.cjs → relation-picker-jk9D_uwn.cjs} +19 -11
  74. package/dist/relation-picker-jk9D_uwn.cjs.map +1 -0
  75. package/dist/{relation-select-Cr3CfNLy.cjs → relation-select-C3aV18kT.cjs} +2 -2
  76. package/dist/{relation-select-Cr3CfNLy.cjs.map → relation-select-C3aV18kT.cjs.map} +1 -1
  77. package/dist/{relation-select-B8Fq4o-t.js → relation-select-CjQT9LpS.js} +2 -2
  78. package/dist/{relation-select-B8Fq4o-t.js.map → relation-select-CjQT9LpS.js.map} +1 -1
  79. package/dist/{resource-page-router-Diw6S6TK.js → resource-page-router-CzaNATSp.js} +209 -30
  80. package/dist/resource-page-router-CzaNATSp.js.map +1 -0
  81. package/dist/{resource-page-router-C_kGW2o_.cjs → resource-page-router-dmVIeu5s.cjs} +235 -32
  82. package/dist/resource-page-router-dmVIeu5s.cjs.map +1 -0
  83. package/dist/{success-notices-Dl3M1fZP.cjs → success-notices-Cl4b6MLQ.cjs} +3 -2
  84. package/dist/success-notices-Cl4b6MLQ.cjs.map +1 -0
  85. package/dist/{success-notices-LDEgEkc4.js → success-notices-CrcWOGSo.js} +3 -2
  86. package/dist/success-notices-CrcWOGSo.js.map +1 -0
  87. package/dist/{use-dialog-filter-state-B_MqzHaT.js → use-dialog-filter-state-CJoeY-1j.js} +2 -2
  88. package/dist/{use-dialog-filter-state-B_MqzHaT.js.map → use-dialog-filter-state-CJoeY-1j.js.map} +1 -1
  89. package/dist/{use-dialog-filter-state-tNvqAAjh.cjs → use-dialog-filter-state-lsTJxrB4.cjs} +2 -2
  90. package/dist/{use-dialog-filter-state-tNvqAAjh.cjs.map → use-dialog-filter-state-lsTJxrB4.cjs.map} +1 -1
  91. package/dist/use-record-subtitle-BJ9rnj6F.cjs +67 -0
  92. package/dist/use-record-subtitle-BJ9rnj6F.cjs.map +1 -0
  93. package/dist/use-record-subtitle-w3ZhXNlf.js +50 -0
  94. package/dist/use-record-subtitle-w3ZhXNlf.js.map +1 -0
  95. package/package.json +9 -9
  96. package/dist/bulk-summary-BWSAS7k2.js.map +0 -1
  97. package/dist/bulk-summary-CrEij5vq.cjs.map +0 -1
  98. package/dist/check-confirm-dialog-C-NHgMST.cjs.map +0 -1
  99. package/dist/filter-builder-DFu0JP-1.cjs.map +0 -1
  100. package/dist/filter-builder-DaWHUZuV.js.map +0 -1
  101. package/dist/flow-screen-Bcz9NF2V.cjs.map +0 -1
  102. package/dist/flow-screen-DCdli6Ha.js.map +0 -1
  103. package/dist/page-flow-route-BHUEpn0I.js.map +0 -1
  104. package/dist/page-flow-route-DS8IVTVH.cjs.map +0 -1
  105. package/dist/place-node-CNb3w-c7.cjs.map +0 -1
  106. package/dist/place-node-CfzQvh4Y.js.map +0 -1
  107. package/dist/related-list-timeline-CRh7xwLD.js +0 -141
  108. package/dist/related-list-timeline-CRh7xwLD.js.map +0 -1
  109. package/dist/related-list-timeline-DsLdi8sv.cjs +0 -141
  110. package/dist/related-list-timeline-DsLdi8sv.cjs.map +0 -1
  111. package/dist/relation-create-C43cdPQt.js.map +0 -1
  112. package/dist/relation-create-DDEYcKfw.cjs.map +0 -1
  113. package/dist/relation-many-picker-BJhaEqxz.js.map +0 -1
  114. package/dist/relation-many-picker-DzuGJpEl.cjs.map +0 -1
  115. package/dist/relation-picker-D-tBBZW_.js.map +0 -1
  116. package/dist/relation-picker-DaIMzf2H.cjs.map +0 -1
  117. package/dist/relation-picker-dialog-9Vg5vvR1.cjs.map +0 -1
  118. package/dist/relation-picker-dialog-DoEY8EkH.js.map +0 -1
  119. package/dist/resource-page-router-C_kGW2o_.cjs.map +0 -1
  120. package/dist/resource-page-router-Diw6S6TK.js.map +0 -1
  121. package/dist/success-notices-Dl3M1fZP.cjs.map +0 -1
  122. package/dist/success-notices-LDEgEkc4.js.map +0 -1
@@ -1,15 +1,15 @@
1
1
  const require_use_theme = require("./use-theme-DFlpXils.cjs");
2
2
  const require_toaster = require("./toaster-BbByOytP.cjs");
3
- const require_check_confirm_dialog = require("./check-confirm-dialog-C-NHgMST.cjs");
3
+ const require_check_confirm_dialog = require("./check-confirm-dialog-W-8WOmGh.cjs");
4
4
  const require_button = require("./button-BxnnE28H.cjs");
5
5
  const require_input = require("./input-BI0czGyI.cjs");
6
6
  const require_dialog = require("./dialog-vmMdfUWs.cjs");
7
- const require_relation_create = require("./relation-create-DDEYcKfw.cjs");
7
+ const require_relation_create = require("./relation-create-_SFuPQGM.cjs");
8
8
  const require_skeleton = require("./skeleton-_1gP7wan.cjs");
9
- const require_filter_builder = require("./filter-builder-DFu0JP-1.cjs");
9
+ const require_filter_builder = require("./filter-builder-DQX-TMFh.cjs");
10
10
  const require_label = require("./label-w6JYf2cF.cjs");
11
- const require_lazy_relation_picker_dialog = require("./lazy-relation-picker-dialog-Bt8lrEIu.cjs");
12
- const require_relation_select = require("./relation-select-Cr3CfNLy.cjs");
11
+ const require_lazy_relation_picker_dialog = require("./lazy-relation-picker-dialog-C_VlGlDz.cjs");
12
+ const require_relation_select = require("./relation-select-C3aV18kT.cjs");
13
13
  let _burojs_core = require("@burojs/core");
14
14
  let _burojs_react = require("@burojs/react");
15
15
  let _tabler_icons_react = require("@tabler/icons-react");
@@ -146,10 +146,10 @@ function copyText(value) {
146
146
  function FieldValueFrame({ field, value, surface, entry, children }) {
147
147
  const t = (0, _burojs_react.useOptionalT)();
148
148
  const clipboard = (0, _burojs_react.useClipboard)();
149
- const [copied, setCopied] = (0, react.useState)(false);
149
+ const [copied, setCopied] = (0, react.useState)(null);
150
150
  (0, react.useEffect)(() => {
151
- if (!copied) return;
152
- const timer = setTimeout(() => setCopied(false), COPIED_MS);
151
+ if (copied === null) return;
152
+ const timer = setTimeout(() => setCopied(null), COPIED_MS);
153
153
  return () => clearTimeout(timer);
154
154
  }, [copied]);
155
155
  const ui = isRecord$1(field.ui) ? field.ui : void 0;
@@ -180,7 +180,7 @@ function FieldValueFrame({ field, value, surface, entry, children }) {
180
180
  const copy = (event) => {
181
181
  event.preventDefault();
182
182
  event.stopPropagation();
183
- clipboard(copyText(value)).then(() => setCopied(true), () => void 0);
183
+ clipboard(copyText(value)).then(() => setCopied("copied"), () => setCopied("failed"));
184
184
  };
185
185
  return (0, react_jsx_runtime.jsxs)("span", {
186
186
  className: "inline-flex min-w-0 max-w-full items-center gap-1 align-bottom",
@@ -193,7 +193,7 @@ function FieldValueFrame({ field, value, surface, entry, children }) {
193
193
  title: label,
194
194
  onClick: copy,
195
195
  className: "inline-flex size-6 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
196
- children: copied ? (0, react_jsx_runtime.jsx)(_tabler_icons_react.IconCheck, {
196
+ children: copied === "copied" ? (0, react_jsx_runtime.jsx)(_tabler_icons_react.IconCheck, {
197
197
  "aria-hidden": "true",
198
198
  className: "size-3.5"
199
199
  }) : (0, react_jsx_runtime.jsx)(_tabler_icons_react.IconCopy, {
@@ -204,7 +204,7 @@ function FieldValueFrame({ field, value, surface, entry, children }) {
204
204
  (0, react_jsx_runtime.jsx)("span", {
205
205
  "aria-live": "polite",
206
206
  className: "sr-only",
207
- children: copied ? t("field.copied", { defaultValue: "Copied" }) : ""
207
+ children: copied === "copied" ? t("field.copied", { defaultValue: "Copied" }) : copied === "failed" ? t("field.copyFailed", { defaultValue: "Could not copy" }) : ""
208
208
  })
209
209
  ]
210
210
  });
@@ -284,6 +284,10 @@ function leafAttributes(size, weight) {
284
284
  ...weight === void 0 ? {} : { "data-buro-weight": String(weight) }
285
285
  };
286
286
  }
287
+ function labelHiddenOf(compiled, node) {
288
+ return compiled.nodes[node.index]?.options.label === "hidden";
289
+ }
290
+ const labelRegion = (hidden, visible) => hidden ? "sr-only" : visible;
287
291
  function FieldLeaf({ node }) {
288
292
  const { leafIds } = useScreenTree();
289
293
  if (node.state === "failed" && node.failedOn.length > 0 && node.failedOn.every((name) => name.startsWith("meta:"))) return (0, react_jsx_runtime.jsx)(MisconfiguredLeaf, { node });
@@ -295,7 +299,8 @@ function FieldLeaf({ node }) {
295
299
  return (0, react_jsx_runtime.jsx)(RecordLeaf, { node });
296
300
  }
297
301
  function MisconfiguredLeaf({ node }) {
298
- const { leafIds, resource, mode, controller } = useScreenTree();
302
+ const { leafIds, resource, mode, compiled, controller } = useScreenTree();
303
+ const hidden = labelHiddenOf(compiled, node);
299
304
  const name = node.field;
300
305
  const binding = controller.field(name);
301
306
  const caps = (0, _burojs_react.useI18nCaps)(resource);
@@ -322,7 +327,7 @@ function MisconfiguredLeaf({ node }) {
322
327
  "data-buro-field-meta": "failed",
323
328
  children: [(0, react_jsx_runtime.jsx)("div", {
324
329
  "data-buro-region": "field-label",
325
- className: "text-sm font-medium leading-none",
330
+ className: labelRegion(hidden, "text-sm font-medium leading-none"),
326
331
  children: label
327
332
  }), (0, react_jsx_runtime.jsx)("div", {
328
333
  "data-buro-region": "field-control",
@@ -330,12 +335,22 @@ function MisconfiguredLeaf({ node }) {
330
335
  })]
331
336
  });
332
337
  }
338
+ function valueAt(record, path) {
339
+ let at = record;
340
+ for (const segment of path.split(".")) {
341
+ if (at === null || typeof at !== "object") return void 0;
342
+ at = at[segment];
343
+ }
344
+ return at;
345
+ }
333
346
  function RecordLeaf({ node }) {
334
347
  const { resource, mode, compiled, controller } = useScreenTree();
335
- const name = node.field;
348
+ const head = node.field;
349
+ const name = node.fieldPath ?? head;
336
350
  const binding = controller.field(name);
337
351
  const size = useLeafSize(binding.field);
338
352
  const weight = compiled.nodes[node.index]?.options.weight;
353
+ const hidden = labelHiddenOf(compiled, node);
339
354
  const caps = (0, _burojs_react.useI18nCaps)(resource);
340
355
  const tid = (0, _burojs_react.useTestIds)();
341
356
  const label = (0, _burojs_core.resolveFieldLabel)(caps, name, (0, _burojs_core.declaredText)("field", binding.field, "label"));
@@ -352,7 +367,7 @@ function RecordLeaf({ node }) {
352
367
  "data-buro-restricted": "true",
353
368
  children: [(0, react_jsx_runtime.jsx)("div", {
354
369
  "data-buro-region": "field-label",
355
- className: "text-sm font-medium leading-none",
370
+ className: labelRegion(hidden, "text-sm font-medium leading-none"),
356
371
  children: label
357
372
  }), (0, react_jsx_runtime.jsx)("div", {
358
373
  "data-buro-region": "field-control",
@@ -372,7 +387,7 @@ function RecordLeaf({ node }) {
372
387
  });
373
388
  }
374
389
  const record = controller.record;
375
- const value = mode === "show" ? record?.[name] ?? controller.values[name] : mode === "edit" && controller.plan?.fields[name] !== "active" ? record?.[name] ?? controller.values[name] : controller.values[name];
390
+ const value = mode === "show" ? valueAt(record, name) ?? binding.value : mode === "edit" && controller.plan?.fields[head] !== "active" ? valueAt(record, name) ?? binding.value : binding.value;
376
391
  const display = (0, react_jsx_runtime.jsx)(FieldDisplay, {
377
392
  resource: binding.resource,
378
393
  name,
@@ -380,6 +395,8 @@ function RecordLeaf({ node }) {
380
395
  value,
381
396
  metaSources: controller.sources,
382
397
  ...record === void 0 ? {} : { record },
398
+ ...binding.absentPaths === void 0 ? {} : { absentPaths: binding.absentPaths },
399
+ ...binding.pathStatus === void 0 ? {} : { pathStatus: binding.pathStatus },
383
400
  fallback: value == null || value === "" ? (0, react_jsx_runtime.jsx)("span", {
384
401
  className: "text-muted-foreground",
385
402
  children: "—"
@@ -390,11 +407,11 @@ function RecordLeaf({ node }) {
390
407
  "data-testid": `show-field:${resource}:${name}`,
391
408
  children: [(0, react_jsx_runtime.jsxs)("dt", {
392
409
  "data-buro-region": "field-label",
393
- className: require_use_theme.cn("flex items-center gap-0.5", FIELD_LABEL_SHOW),
410
+ className: labelRegion(hidden, require_use_theme.cn("flex items-center gap-0.5", FIELD_LABEL_SHOW)),
394
411
  children: [(0, react_jsx_runtime.jsx)("span", {
395
412
  className: "min-w-0",
396
413
  children: label
397
- }), (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.DocInfo, {
414
+ }), hidden ? null : (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.DocInfo, {
398
415
  address: `${resource}/fields/${name}`,
399
416
  name: label
400
417
  })]
@@ -414,8 +431,8 @@ function RecordLeaf({ node }) {
414
431
  "data-testid": tid.formField(resource, mode, name),
415
432
  children: [(0, react_jsx_runtime.jsxs)("div", {
416
433
  "data-buro-region": "field-label",
417
- className: "flex items-center gap-2",
418
- children: [(0, react_jsx_runtime.jsx)(require_label.Label, { children: label }), (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.DocInfo, {
434
+ className: labelRegion(hidden, "flex items-center gap-2"),
435
+ children: [(0, react_jsx_runtime.jsx)(require_label.Label, { children: label }), hidden ? null : (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.DocInfo, {
419
436
  address: `${resource}/fields/${name}`,
420
437
  name: label,
421
438
  testId: `${tid.formField(resource, mode, name)}:info`
@@ -451,11 +468,12 @@ function RecordLeaf({ node }) {
451
468
  node,
452
469
  binding,
453
470
  label,
471
+ labelHidden: hidden,
454
472
  attributes,
455
473
  inputId
456
474
  });
457
475
  }
458
- function ActiveLeaf({ node, binding, label, attributes, inputId }) {
476
+ function ActiveLeaf({ node, binding, label, labelHidden, attributes, inputId }) {
459
477
  const { resource, mode, controller, disabled: locked } = useScreenTree();
460
478
  const caps = (0, _burojs_react.useI18nCaps)(resource);
461
479
  const tid = (0, _burojs_react.useTestIds)();
@@ -499,13 +517,13 @@ function ActiveLeaf({ node, binding, label, attributes, inputId }) {
499
517
  onBlur: binding.onBlur,
500
518
  children: [(0, react_jsx_runtime.jsxs)("div", {
501
519
  "data-buro-region": "field-label",
502
- className: "flex items-center gap-2",
520
+ className: labelRegion(labelHidden, "flex items-center gap-2"),
503
521
  children: [(0, react_jsx_runtime.jsx)(require_label.Label, {
504
522
  id: `${inputId}-label`,
505
523
  htmlFor: inputId,
506
524
  required: binding.required,
507
525
  children: label
508
- }), (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.DocInfo, {
526
+ }), labelHidden ? null : (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.DocInfo, {
509
527
  address: `${resource}/fields/${name}`,
510
528
  name: label,
511
529
  testId: `${tid.formField(resource, mode, name)}:info`
@@ -528,13 +546,17 @@ function ActiveLeaf({ node, binding, label, attributes, inputId }) {
528
546
  ...mode === "create" || record === void 0 ? {} : { record },
529
547
  form: controller.values,
530
548
  metaSources: controller.sources,
549
+ ...controller.baseline === void 0 ? {} : { baseline: controller.baseline },
531
550
  ...describedBy === void 0 ? {} : { descriptionId: describedBy },
532
551
  ...errorMessageId === void 0 ? {} : { errorId: errorMessageId },
533
552
  errorMessage: errorText,
534
553
  issues: binding.issues,
535
554
  ...binding.fixedFilters === void 0 ? {} : { fixedFilters: binding.fixedFilters },
555
+ ...binding.optionSubtitle === void 0 ? {} : { optionSubtitle: binding.optionSubtitle },
536
556
  ...binding.relationSeeds === void 0 ? {} : { relationSeeds: binding.relationSeeds },
537
557
  ...binding.link === void 0 ? {} : { link: binding.link },
558
+ ...binding.absentPaths === void 0 ? {} : { absentPaths: binding.absentPaths },
559
+ ...binding.pathStatus === void 0 ? {} : { pathStatus: binding.pathStatus },
538
560
  fallback: (0, react_jsx_runtime.jsx)(require_input.Input, {
539
561
  id: inputId,
540
562
  name: inputId,
@@ -581,6 +603,7 @@ function DeclarativeLeaf({ node, prefix, inputIds }) {
581
603
  const binding = controller.field(name);
582
604
  const size = useLeafSize(binding.field);
583
605
  const weight = compiled.nodes[node.index]?.options.weight;
606
+ const hidden = labelHiddenOf(compiled, node);
584
607
  const attributes = leafAttributes(size, weight);
585
608
  const docRef = (0, _burojs_core.i18nPrefixToRef)(prefix);
586
609
  const docScope = docRef.namespace === "default" ? docRef.id : (0, _burojs_core.formatEntityRef)(docRef);
@@ -599,7 +622,7 @@ function DeclarativeLeaf({ node, prefix, inputIds }) {
599
622
  });
600
623
  const label = (0, _burojs_core.resolveFieldLabel)(caps, name, (0, _burojs_core.declaredText)("field", binding.field, "label"));
601
624
  const hint = (0, _burojs_core.resolveFieldSlot)(caps, name, "description", require_filter_builder.fieldDescription(binding.field));
602
- const info = (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.DocInfo, {
625
+ const info = hidden ? null : (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.DocInfo, {
603
626
  address: `${docScope}/fields/${name}`,
604
627
  name: label,
605
628
  testId: `${prefix}:field:${name}:info`
@@ -616,7 +639,7 @@ function DeclarativeLeaf({ node, prefix, inputIds }) {
616
639
  children: [
617
640
  (0, react_jsx_runtime.jsxs)("div", {
618
641
  "data-buro-region": "field-label",
619
- className: "flex items-center gap-2",
642
+ className: labelRegion(hidden, "flex items-center gap-2"),
620
643
  children: [(0, react_jsx_runtime.jsx)("span", {
621
644
  className: FIELD_LABEL_SHOW,
622
645
  children: label
@@ -649,6 +672,7 @@ function DeclarativeLeaf({ node, prefix, inputIds }) {
649
672
  ...binding,
650
673
  field: binding.field,
651
674
  metaSources: controller.sources,
675
+ ...controller.baseline === void 0 ? {} : { baseline: controller.baseline },
652
676
  inputId,
653
677
  labelId: `${inputId}-label`,
654
678
  i18nPrefix: prefix,
@@ -664,7 +688,7 @@ function DeclarativeLeaf({ node, prefix, inputIds }) {
664
688
  children: [
665
689
  (0, react_jsx_runtime.jsxs)("div", {
666
690
  "data-buro-region": "field-label",
667
- className: "flex items-center gap-2",
691
+ className: labelRegion(hidden, "flex items-center gap-2"),
668
692
  children: [(0, react_jsx_runtime.jsx)(require_label.Label, {
669
693
  id: `${inputId}-label`,
670
694
  htmlFor: inputId,
@@ -858,6 +882,20 @@ function AppFlowButton({ action, variant = "ghost", size = "sm", className }) {
858
882
  actionName: action.name,
859
883
  surface: "app"
860
884
  });
885
+ if (action.undecided === true) return (0, react_jsx_runtime.jsx)(require_button.Button, {
886
+ type: "button",
887
+ variant,
888
+ size,
889
+ className,
890
+ "data-testid": testid,
891
+ "data-buro-flow-state": "undecided",
892
+ disabled: true,
893
+ "aria-busy": "true",
894
+ children: (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.ActionInner, {
895
+ icon: action.icon,
896
+ label
897
+ })
898
+ });
861
899
  if (action.hostHref !== void 0) return (0, react_jsx_runtime.jsx)(require_button.Button, {
862
900
  asChild: true,
863
901
  variant,
@@ -926,10 +964,7 @@ function RecordInlineFlow({ name }) {
926
964
  const id = frame?.recordId;
927
965
  const asRead = frame === null ? void 0 : (0, _burojs_react.policyRecordOf)(frame.controller, frame.record);
928
966
  const key = placement?.key ?? flowName;
929
- const state = frame === null || id === void 0 || asRead === void 0 ? null : resolve(flowName, {
930
- ...asRead,
931
- id
932
- });
967
+ const state = frame === null || id === void 0 || asRead === void 0 ? null : resolve(flowName, (0, _burojs_react.withRecordKeys)(asRead, { id }));
933
968
  const kept = holder?.get(key);
934
969
  const stale = state?.state === "absent" && state.cause === "when" && kept !== void 0 && kept.dirty;
935
970
  const gone = state?.state === "absent" && !stale;
@@ -941,10 +976,7 @@ function RecordInlineFlow({ name }) {
941
976
  key
942
977
  ]);
943
978
  if (frame === null || asRead === void 0 || id === void 0 || compiled === null) return null;
944
- const row = {
945
- ...asRead,
946
- id
947
- };
979
+ const row = (0, _burojs_react.withRecordKeys)(asRead, { id });
948
980
  const control = resolve(flowName, row);
949
981
  switch (control.state) {
950
982
  case "undecided":
@@ -1215,6 +1247,28 @@ function placementSeeds(where, resolved, closure) {
1215
1247
  return Object.freeze(seeds);
1216
1248
  }
1217
1249
  //#endregion
1250
+ //#region src/enum/enum-settling.tsx
1251
+ function unknownEnumValueLabel(caps, def, ns, value) {
1252
+ const declared = (0, _burojs_core.enumFallbackText)(def);
1253
+ if (def.fallback === void 0 && declared === void 0) return {
1254
+ label: value,
1255
+ fallback: false
1256
+ };
1257
+ return {
1258
+ label: (0, _burojs_core.resolveContentSlot)(caps, [(0, _burojs_core.enumFallbackKey)(ns)], { default: declared }) ?? value,
1259
+ fallback: true
1260
+ };
1261
+ }
1262
+ function EnumSettlingRow({ status, testid }) {
1263
+ const t = (0, _burojs_react.useOptionalT)();
1264
+ return (0, react_jsx_runtime.jsx)("div", {
1265
+ role: "status",
1266
+ "data-testid": testid === void 0 ? void 0 : `${testid}:${status}`,
1267
+ className: "px-2 py-1.5 text-sm text-muted-foreground",
1268
+ children: status === "pending" ? t("field.loading", { defaultValue: "Loading…" }) : t("relation.failed", { defaultValue: "Failed to load options." })
1269
+ });
1270
+ }
1271
+ //#endregion
1218
1272
  //#region src/enum/enum-badge.tsx
1219
1273
  function BadgeBody({ icon, label }) {
1220
1274
  return (0, react_jsx_runtime.jsxs)("span", {
@@ -1285,9 +1339,9 @@ function EnumBadge({ enumName: enumInput, value, testid, className, presentation
1285
1339
  children: body
1286
1340
  });
1287
1341
  }
1288
- const declaredFallback = (0, _burojs_core.enumFallbackText)(def);
1289
- if (def?.fallback !== void 0 || declaredFallback !== void 0) {
1290
- const fallbackLabel = (0, _burojs_core.resolveContentSlot)(caps, [(0, _burojs_core.enumFallbackKey)(ns)], { default: declaredFallback }) ?? value;
1342
+ const unknown = unknownEnumValueLabel(caps, def, ns, value);
1343
+ if (unknown.fallback) {
1344
+ const fallbackLabel = unknown.label;
1291
1345
  if (presentation === "plain") return (0, react_jsx_runtime.jsx)("span", {
1292
1346
  "data-testid": `${id}:fallback`,
1293
1347
  className,
@@ -1515,35 +1569,6 @@ function useShownItemActions(resource, record, surface, hideFlows, sources) {
1515
1569
  return hideFlows === void 0 ? shown : shown.filter((a) => a.flow === void 0 || !hideFlows(a.name));
1516
1570
  }
1517
1571
  //#endregion
1518
- //#region src/layout/record-targets.ts
1519
- function recordRouteAvailable(registry, resource, action) {
1520
- if ((0, _burojs_core.resolveStaticAvailability)(registry, resource, action).state !== "available") return false;
1521
- const def = registry.get(resource);
1522
- return def !== void 0 && (0, _burojs_core.hasRecordPage)(def, action);
1523
- }
1524
- function isShowAvailable(registry, resource) {
1525
- return recordRouteAvailable(registry, resource, "show");
1526
- }
1527
- function showTarget(resource, id) {
1528
- return {
1529
- resource,
1530
- action: "show",
1531
- params: { id }
1532
- };
1533
- }
1534
- function listTarget(resource) {
1535
- return {
1536
- resource,
1537
- action: "list"
1538
- };
1539
- }
1540
- function recordReturnTarget(registry, resource, id) {
1541
- return isShowAvailable(registry, resource) ? showTarget(resource, id) : listTarget(resource);
1542
- }
1543
- function editBackHref(registry, resource, id, backHref) {
1544
- return backHref ?? (0, _burojs_react.resolveRoute)(recordReturnTarget(registry, resource, id), registry);
1545
- }
1546
- //#endregion
1547
1572
  //#region src/lib/typography.ts
1548
1573
  const typography = {
1549
1574
  h1: "text-2xl font-semibold tracking-tight",
@@ -1671,16 +1696,16 @@ function ShowPageHeader({ resource: resourceInput, record, extraActions, breadcr
1671
1696
  }
1672
1697
  function EditPageHeader({ resource: resourceInput, record, backHref, breadcrumbs }) {
1673
1698
  const resource = (0, _burojs_core.routeResourceKey)(resourceInput);
1674
- const app = (0, _burojs_react.useApp)();
1675
- const def = app.registry.get(resource);
1699
+ const def = (0, _burojs_react.useApp)().registry.get(resource);
1676
1700
  const caps = (0, _burojs_react.useI18nCaps)(resource);
1677
1701
  const recordKey = (0, _burojs_react.recordKeyOf)(def, record);
1678
1702
  const recordName = (0, _burojs_react.useProjectedTitle)(resource, recordKey, record);
1703
+ const back = (0, _burojs_react.useReturnTarget)(resource, "edit", String(recordKey ?? ""));
1679
1704
  return (0, react_jsx_runtime.jsx)(PageHeader, {
1680
1705
  resource,
1681
1706
  mode: "edit",
1682
1707
  recordName,
1683
- backHref: editBackHref(app.registry, resource, String(recordKey ?? ""), backHref),
1708
+ backHref: backHref ?? back,
1684
1709
  breadcrumbs,
1685
1710
  backLabel: recordName ? `${(0, _burojs_core.resolveResourceLabel)(caps, resource, "single", def)}: ${recordName}` : void 0,
1686
1711
  actions: (0, react_jsx_runtime.jsx)(ActionOverflow, {
@@ -1969,19 +1994,26 @@ function BuroPanelFrame({ body, title, description, collapsible, open, onToggle,
1969
1994
  "data-buro-region": "panel-title",
1970
1995
  className: "flex items-center gap-1",
1971
1996
  children: [
1972
- collapsible ? (0, react_jsx_runtime.jsx)("button", {
1997
+ collapsible && title !== void 0 ? (0, react_jsx_runtime.jsx)("h3", {
1998
+ id: titleId,
1999
+ className: "min-w-0 flex-1 text-sm font-semibold",
2000
+ children: (0, react_jsx_runtime.jsxs)("button", {
2001
+ type: "button",
2002
+ "aria-expanded": open,
2003
+ "aria-controls": bodyId,
2004
+ onClick: () => onToggle(!open),
2005
+ className: "-mx-1 flex w-full items-center gap-1 rounded px-1 text-left hover:bg-muted focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring",
2006
+ children: [(0, react_jsx_runtime.jsx)(Chevron, { open }), title]
2007
+ })
2008
+ }) : collapsible ? (0, react_jsx_runtime.jsx)("button", {
1973
2009
  type: "button",
1974
2010
  "aria-expanded": open,
1975
2011
  "aria-controls": bodyId,
1976
2012
  "aria-label": open ? t("screen.collapse", { defaultValue: "Collapse" }) : t("screen.expand", { defaultValue: "Expand" }),
1977
2013
  onClick: () => onToggle(!open),
1978
2014
  className: "inline-flex size-6 items-center justify-center rounded text-muted-foreground hover:bg-muted",
1979
- children: (0, react_jsx_runtime.jsx)(_tabler_icons_react.IconChevronRight, {
1980
- className: open ? "h-4 w-4 rotate-90 transition-transform" : "h-4 w-4 transition-transform",
1981
- "aria-hidden": "true"
1982
- })
1983
- }) : null,
1984
- title === void 0 ? null : (0, react_jsx_runtime.jsx)("h3", {
2015
+ children: (0, react_jsx_runtime.jsx)(Chevron, { open })
2016
+ }) : title === void 0 ? null : (0, react_jsx_runtime.jsx)("h3", {
1985
2017
  id: titleId,
1986
2018
  className: "text-sm font-semibold",
1987
2019
  children: title
@@ -1999,6 +2031,12 @@ function BuroPanelFrame({ body, title, description, collapsible, open, onToggle,
1999
2031
  ]
2000
2032
  });
2001
2033
  }
2034
+ function Chevron({ open }) {
2035
+ return (0, react_jsx_runtime.jsx)(_tabler_icons_react.IconChevronRight, {
2036
+ className: open ? "h-4 w-4 shrink-0 rotate-90 text-muted-foreground transition-transform" : "h-4 w-4 shrink-0 text-muted-foreground transition-transform",
2037
+ "aria-hidden": "true"
2038
+ });
2039
+ }
2002
2040
  function BuroTabsFrame({ tabs, active, onSelect, info, nodeAttributes }) {
2003
2041
  if (tabs.length === 1) return (0, react_jsx_runtime.jsx)("div", {
2004
2042
  ...nodeAttributes,
@@ -2616,7 +2654,8 @@ function ColumnHeaderMenu({ label, sortDirection, sortable, onSort, pinned, onPi
2616
2654
  }
2617
2655
  //#endregion
2618
2656
  //#region src/resource/column-accessor.ts
2619
- function columnAccessor(column) {
2657
+ function columnAccessor(column, objectPath = false) {
2658
+ if (objectPath) return { accessorFn: (row) => (0, _burojs_react.readColumnValue)(row, column, true) };
2620
2659
  return column.includes(".") ? { accessorFn: (row) => row[column] } : { accessorKey: column };
2621
2660
  }
2622
2661
  //#endregion
@@ -3225,7 +3264,8 @@ function ResourceList({ resource: resourceInput, data, total, page = 1, pageSize
3225
3264
  });
3226
3265
  for (const col of visibleColumnKeys) {
3227
3266
  const target = columnTarget(app.registry, resource, col);
3228
- const field = target !== void 0 ? target.field : def === void 0 ? void 0 : (0, _burojs_core.declaredField)(def, col);
3267
+ const objectPath = (0, _burojs_react.isObjectColumn)(app.registry, resource, col);
3268
+ const field = target !== void 0 ? target.field : objectPath ? (0, _burojs_react.resolveObjectColumn)(app.registry, resource, col)?.field : def === void 0 ? void 0 : (0, _burojs_core.declaredField)(def, col);
3229
3269
  const declaredLabel = (0, _burojs_core.declaredText)("field", field, "label");
3230
3270
  const headerLabel = target === void 0 ? (0, _burojs_core.resolveFieldLabel)(volatileRef.current.i18nCaps, col, declaredLabel) : (0, _burojs_core.resolveFieldLabel)(capsOf(volatileRef.current.i18nCaps, target.resource), target.name, declaredLabel);
3231
3271
  const ui = columnUiOf(col);
@@ -3233,12 +3273,15 @@ function ResourceList({ resource: resourceInput, data, total, page = 1, pageSize
3233
3273
  ...field ?? { type: "unknown" },
3234
3274
  name: target === void 0 ? col : target.name
3235
3275
  };
3236
- const cellEntry = { display: ui.display };
3276
+ const cellEntry = { display: {
3277
+ ...ui.display,
3278
+ ...ui.display.dateDisplay
3279
+ } };
3237
3280
  const wraps = ui.display.overflow === "wrap";
3238
3281
  const columnSortable = volatileRef.current.sortable?.(col) ?? (def !== void 0 && (0, _burojs_core.isColumnSortable)(def, col, app, app.registry));
3239
3282
  cols.push({
3240
3283
  id: col,
3241
- ...columnAccessor(col),
3284
+ ...columnAccessor(col, objectPath),
3242
3285
  size: ui.default,
3243
3286
  minSize: ui.min,
3244
3287
  maxSize: ui.max ?? Number.MAX_SAFE_INTEGER,
@@ -3297,7 +3340,7 @@ function ResourceList({ resource: resourceInput, data, total, page = 1, pageSize
3297
3340
  cell: ({ row }) => {
3298
3341
  const raw = row.original;
3299
3342
  const record = volatileRef.current.viewRow(raw);
3300
- const value = record[col];
3343
+ const value = (0, _burojs_react.readColumnValue)(record, col, objectPath);
3301
3344
  const customCell = volatileRef.current.renderCell?.(col, value, record);
3302
3345
  const cellInner = customCell !== void 0 ? customCell : (0, react_jsx_runtime.jsx)(require_filter_builder.ResolvedFieldDisplay, {
3303
3346
  resource: target === void 0 ? resourceRef : target.ref,
@@ -4447,7 +4490,7 @@ function issueText(issue, caps, i18nPrefix) {
4447
4490
  }, {
4448
4491
  has: caps.has,
4449
4492
  t: caps.t,
4450
- ...issue.field === "_form" ? {} : { fieldKey: `resources.${i18nPrefix}.fields.${issue.field}` }
4493
+ ...issue.field === "_form" ? {} : { fieldKey: `resources.${i18nPrefix}.${(0, _burojs_core.propertyTextKey)([...issue.field.split("."), ...issue.path])}` }
4451
4494
  });
4452
4495
  }
4453
4496
  const EMPTY_ISSUES = Object.freeze([]);
@@ -4496,9 +4539,10 @@ function DeclarativeForm(props) {
4496
4539
  function DeclarativeFormBody(props) {
4497
4540
  const gate = useDeclarativeCheckGate();
4498
4541
  const prefix = props.i18nPrefix ?? "form";
4542
+ const mode = props.mode ?? "create";
4499
4543
  const form = (0, _burojs_react.useFormController)({
4500
4544
  fields: props.fields,
4501
- mode: "create",
4545
+ mode,
4502
4546
  onConfirmChecks: gate.confirmChecks,
4503
4547
  ...props.body === void 0 ? {} : { body: props.body },
4504
4548
  ...props.formId === void 0 ? {} : { formId: props.formId },
@@ -4563,7 +4607,7 @@ function DeclarativeFormBody(props) {
4563
4607
  children: (0, react_jsx_runtime.jsx)(ScreenTree, {
4564
4608
  region: "form-body",
4565
4609
  resource: prefix,
4566
- mode: "create",
4610
+ mode,
4567
4611
  compiled: form.screen,
4568
4612
  controller: form,
4569
4613
  leafIds,
@@ -4944,6 +4988,7 @@ function BulkFlowButton({ resource, actionName, ids, onSelectionChange }) {
4944
4988
  const each = compiled?.each ?? false;
4945
4989
  const [running, setRunning] = (0, react.useState)(false);
4946
4990
  const [summary, setSummary] = (0, react.useState)(null);
4991
+ const afterSummary = (0, react.useRef)(null);
4947
4992
  const testid = tid.bulkAction(resource, actionName);
4948
4993
  if (control.state === "absent") return null;
4949
4994
  const variant = chrome.destructive ? "destructive" : "outline";
@@ -4966,11 +5011,20 @@ function BulkFlowButton({ resource, actionName, ids, onSelectionChange }) {
4966
5011
  const finish = (result, progress) => {
4967
5012
  setRunning(false);
4968
5013
  if (progress === void 0) return;
4969
- if (result.outcome !== "success") setSummary({
5014
+ const summarize = result.outcome !== "success" || progress.rereadSkipped.some((entry) => entry.policy === "warn");
5015
+ if (summarize) setSummary({
4970
5016
  progress,
4971
5017
  total: ids.length
4972
5018
  });
4973
- onSelectionChange?.(ids.filter((id) => !progress.success.includes(id)));
5019
+ const remaining = ids.filter((id) => !progress.success.includes(id));
5020
+ if (summarize && remaining.length === 0) afterSummary.current = () => onSelectionChange?.([]);
5021
+ else onSelectionChange?.(remaining);
5022
+ };
5023
+ const closeSummary = () => {
5024
+ setSummary(null);
5025
+ const pending = afterSummary.current;
5026
+ afterSummary.current = null;
5027
+ pending?.();
4974
5028
  };
4975
5029
  return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
4976
5030
  (0, react_jsx_runtime.jsx)(require_button.Button, {
@@ -5000,7 +5054,7 @@ function BulkFlowButton({ resource, actionName, ids, onSelectionChange }) {
5000
5054
  (0, react_jsx_runtime.jsx)(require_dialog.Dialog, {
5001
5055
  open: summary !== null,
5002
5056
  onOpenChange: (open) => {
5003
- if (!open) setSummary(null);
5057
+ if (!open) closeSummary();
5004
5058
  },
5005
5059
  children: (0, react_jsx_runtime.jsxs)(require_dialog.DialogContent, {
5006
5060
  "data-testid": `${tid.bulkSummary(resource, actionName)}:dialog`,
@@ -5021,7 +5075,7 @@ function BulkFlowButton({ resource, actionName, ids, onSelectionChange }) {
5021
5075
  type: "button",
5022
5076
  variant: "outline",
5023
5077
  "data-testid": `${tid.bulkSummary(resource, actionName)}:close`,
5024
- onClick: () => setSummary(null),
5078
+ onClick: closeSummary,
5025
5079
  children: t("flow.close", { defaultValue: "Close" })
5026
5080
  }) })
5027
5081
  ]
@@ -5399,6 +5453,14 @@ function CreateButton({ resource: resourceInput, href, testid, size = "sm", vari
5399
5453
  resource,
5400
5454
  defaultValue: "Create"
5401
5455
  });
5456
+ const undecided = (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.UndecidedAction, {
5457
+ label: text,
5458
+ icon: "Plus",
5459
+ testid,
5460
+ size,
5461
+ variant,
5462
+ className
5463
+ });
5402
5464
  if (onOpen !== void 0) {
5403
5465
  const answer = gate(resource, "create");
5404
5466
  if (answer.state === "disabled") return (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.DisabledAction, {
@@ -5411,6 +5473,7 @@ function CreateButton({ resource: resourceInput, href, testid, size = "sm", vari
5411
5473
  className,
5412
5474
  resource
5413
5475
  });
5476
+ if (answer.state === "undecided") return undecided;
5414
5477
  if (answer.state !== "open") return null;
5415
5478
  return (0, react_jsx_runtime.jsxs)(require_button.Button, {
5416
5479
  type: "button",
@@ -5426,6 +5489,7 @@ function CreateButton({ resource: resourceInput, href, testid, size = "sm", vari
5426
5489
  });
5427
5490
  }
5428
5491
  if (availability.state === "absent" || availability.state === "hidden") return null;
5492
+ if (availability.state === "undecided") return undecided;
5429
5493
  if (availability.state === "disabled") return (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.DisabledAction, {
5430
5494
  reason: availability.reason,
5431
5495
  label: text,
@@ -5469,6 +5533,10 @@ const ListCreate = listPiece("ListCreate", ListCreateView);
5469
5533
  //#endregion
5470
5534
  //#region src/export/export-button.tsx
5471
5535
  const warnedProviderQueryResources = new Set();
5536
+ const EXPORT_TARGET = {
5537
+ kind: "action",
5538
+ name: "export"
5539
+ };
5472
5540
  function ExportButton({ resource: resourceInput, className }) {
5473
5541
  const resource = (0, _burojs_core.routeResourceKey)(resourceInput);
5474
5542
  if (!((0, _burojs_react.useOptionalDataRuntime)() !== null)) return null;
@@ -5482,12 +5550,11 @@ function ExportButtonActive({ resource, className }) {
5482
5550
  const { available, prefetch } = (0, _burojs_react.useResourceExport)(resource);
5483
5551
  const capability = (0, _burojs_react.useCapability)("run", {
5484
5552
  resource,
5485
- target: {
5486
- kind: "action",
5487
- name: "export"
5488
- },
5553
+ target: EXPORT_TARGET,
5489
5554
  mode: "list"
5490
5555
  });
5556
+ const app = (0, _burojs_react.useApp)();
5557
+ const undecided = (0, _burojs_react.usePermissionsUndecided)() && (0, _burojs_core.addressesCapability)(app.ruleSource.rules(resource), "run", EXPORT_TARGET);
5491
5558
  const tid = (0, _burojs_react.useTestIds)();
5492
5559
  const t = (0, _burojs_react.useOptionalT)();
5493
5560
  const [open, setOpen] = react.useState(false);
@@ -5505,18 +5572,35 @@ function ExportButtonActive({ resource, className }) {
5505
5572
  if (target !== null) lastTarget.current = target;
5506
5573
  const dialogTarget = target ?? lastTarget.current;
5507
5574
  react.useEffect(() => {
5508
- if (!available || !capability.allowed) return;
5575
+ if (!available || undecided || !capability.allowed) return;
5509
5576
  if (list.providerQuery.value === void 0) return;
5510
5577
  if (warnedProviderQueryResources.has(resource)) return;
5511
5578
  warnedProviderQueryResources.add(resource);
5512
5579
  console.warn(`[buro] ExportButton('${resource}'): this list is narrowed by \`providerQuery\` (a raw provider blob), which an export target cannot carry — the exported file will NOT be narrowed by it. See docs/adopters/data-export.md.`);
5513
5580
  }, [
5514
5581
  available,
5582
+ undecided,
5515
5583
  capability.allowed,
5516
5584
  list.providerQuery.value,
5517
5585
  resource
5518
5586
  ]);
5519
- if (!available || !capability.allowed || list.isForbidden) return null;
5587
+ if (!available || list.isForbidden) return null;
5588
+ if (undecided) return (0, react_jsx_runtime.jsx)(require_button.Button, {
5589
+ type: "button",
5590
+ variant: "outline",
5591
+ size: "icon",
5592
+ "aria-label": t("export.button.label"),
5593
+ title: t("export.button.label"),
5594
+ className: require_use_theme.cn("h-8 w-8", className),
5595
+ "data-testid": tid.exportButton(resource),
5596
+ disabled: true,
5597
+ "aria-busy": "true",
5598
+ children: (0, react_jsx_runtime.jsx)(_tabler_icons_react.IconDownload, {
5599
+ className: "size-4",
5600
+ "aria-hidden": "true"
5601
+ })
5602
+ });
5603
+ if (!capability.allowed) return null;
5520
5604
  if (target === null && !open) return null;
5521
5605
  if (dialogTarget === null) return null;
5522
5606
  return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [target === null ? null : (0, react_jsx_runtime.jsx)(require_button.Button, {
@@ -6087,10 +6171,7 @@ function RecordActionsView() {
6087
6171
  const id = useFrameId();
6088
6172
  const holder = (0, _burojs_react.useScreenState)()?.inline;
6089
6173
  if (mode === "create" || record === void 0 || id === void 0) return null;
6090
- const row = {
6091
- ...(0, _burojs_react.policyRecordOf)(controller, record),
6092
- id
6093
- };
6174
+ const row = (0, _burojs_react.withRecordKeys)((0, _burojs_react.policyRecordOf)(controller) ?? record, { id });
6094
6175
  holder?.declare(inlineFlowNames(controller.screen, controller.plan));
6095
6176
  return (0, react_jsx_runtime.jsxs)("div", {
6096
6177
  className: "flex flex-wrap items-center gap-2",
@@ -6133,26 +6214,33 @@ function FormActionsView() {
6133
6214
  const labelCaps = (0, _burojs_react.useI18nCaps)(resource);
6134
6215
  const tid = (0, _burojs_react.useTestIds)();
6135
6216
  const id = useFrameId();
6217
+ const back = (0, _burojs_react.useReturnTarget)(resource, mode === "create" ? "create" : "edit", mode === "edit" ? id : void 0);
6136
6218
  const failedIssues = chrome.serverIssues;
6137
6219
  const livePlan = controller.plan;
6138
- const alertIssues = (0, react.useMemo)(() => failedIssues === void 0 || failedIssues.length === 0 ? NO_ALERT_ISSUES : (0, _burojs_core.routeServerIssues)({ issues: failedIssues }, (segment) => segment, (field) => field !== "_form" && (livePlan === null || livePlan.fields[field] === "active")).form, [failedIssues, livePlan]);
6220
+ const placed = (0, react.useMemo)(() => new Set(livePlan?.placedPaths ?? []), [livePlan]);
6221
+ const alertIssues = (0, react.useMemo)(() => failedIssues === void 0 || failedIssues.length === 0 ? NO_ALERT_ISSUES : (0, _burojs_core.routeServerIssues)({ issues: failedIssues }, (segment) => segment, (field, path) => field !== "_form" && (livePlan === null || livePlan.fields[field] === "active" && (0, _burojs_core_internal.deepestPlacedPath)(path, placed) !== void 0)).form, [
6222
+ failedIssues,
6223
+ livePlan,
6224
+ placed
6225
+ ]);
6139
6226
  const fieldDefs = app.registry.get(resource)?.fields;
6140
6227
  if (mode === "show") return null;
6141
- const busy = controller.isSubmitting;
6228
+ const busy = controller.isSubmitting || chrome.created === true;
6142
6229
  const cancel = () => {
6143
6230
  if (chrome.onCancel !== void 0) chrome.onCancel();
6144
- else navigate(mode === "edit" && id !== void 0 ? recordReturnTarget(app.registry, resource, id) : listTarget(resource));
6231
+ else navigate(back, { origin: "inherit" });
6145
6232
  };
6146
6233
  const plan = controller.plan;
6147
6234
  const undrawn = (field) => plan === null || plan.fields[field] === void 0 || plan.fields[field] === "inactive";
6148
- const recordLevel = (issue) => issue.field === "_form" || undrawn(issue.field);
6235
+ const recordLevel = (issue) => issue.field === "_form" || undrawn((0, _burojs_core_internal.pathHead)(issue.field)) || !placed.has(issue.field);
6149
6236
  const undrawnBlockers = (controller.checkOutcome?.blockers ?? []).flatMap((issue) => {
6150
6237
  const field = typeof issue.path?.[0] === "string" ? issue.path[0] : "_form";
6151
- if (field !== "_form" && !undrawn(field)) return [];
6238
+ if (field !== "_form" && !undrawn(field) && (0, _burojs_core_internal.deepestPlacedPath)(issue.path, placed) !== void 0) return [];
6152
6239
  if (controller.errors.some((own) => own.code === issue.code && own.field === field)) return [];
6153
6240
  return [{
6154
6241
  ...issue,
6155
- field
6242
+ field,
6243
+ path: field === "_form" ? [] : issue.path.slice(1)
6156
6244
  }];
6157
6245
  });
6158
6246
  const formErrors = firstPreferred([...controller.errors.filter(recordLevel), ...undrawnBlockers]);
@@ -6172,7 +6260,7 @@ function FormActionsView() {
6172
6260
  if (!retryable.includes(checkId)) retryable.push(checkId);
6173
6261
  }
6174
6262
  const failure = chrome.submitError === void 0 ? void 0 : failureText(chrome.submitError, chrome.submitApplied, t, caps);
6175
- const serverIssues = bySeverity(alertIssues).map((issue) => {
6263
+ const serverIssues = bySeverity(alertIssues).flatMap((issue) => {
6176
6264
  const head = issue.path[0];
6177
6265
  const name = typeof head === "string" ? head : void 0;
6178
6266
  const declared = name === void 0 ? void 0 : fieldDefs?.[name];
@@ -6183,13 +6271,14 @@ function FormActionsView() {
6183
6271
  }, {
6184
6272
  has: caps.has,
6185
6273
  t: caps.t,
6186
- ...declared === void 0 ? {} : { fieldKey: `resources.${resource}.fields.${name}` }
6274
+ ...declared === void 0 ? {} : { fieldKey: `resources.${resource}.${(0, _burojs_core.propertyTextKey)(issue.path)}` }
6187
6275
  });
6188
- return {
6276
+ if (issue.path.length === 0 && message === failure) return [];
6277
+ return [{
6189
6278
  label: declared === void 0 || name === void 0 ? void 0 : (0, _burojs_core.resolveFieldLabel)(labelCaps, name, (0, _burojs_core.declaredText)("field", declared, "label")),
6190
6279
  message,
6191
6280
  severity: issue.severity
6192
- };
6281
+ }];
6193
6282
  });
6194
6283
  const steps = controller.steps;
6195
6284
  const midSteps = steps !== null && steps.ids.length > 1 && steps.current !== void 0 && steps.current !== steps.ids[steps.ids.length - 1];
@@ -6681,8 +6770,8 @@ function declaresDisplay(field) {
6681
6770
  return field !== void 0 && (0, _burojs_core.resolveSurfaceUi)(field, "column").use !== void 0;
6682
6771
  }
6683
6772
  const NO_INITIAL_FILTERS = Object.freeze({});
6684
- const RelatedCards = (0, react.lazy)(async () => ({ default: (await Promise.resolve().then(() => require("./related-list-cards-CelMxl4q.cjs"))).RelatedCards }));
6685
- const RelatedTimeline = (0, react.lazy)(async () => ({ default: (await Promise.resolve().then(() => require("./related-list-timeline-DsLdi8sv.cjs"))).RelatedTimeline }));
6773
+ const RelatedCards = (0, react.lazy)(async () => ({ default: (await Promise.resolve().then(() => require("./related-list-cards-xVvgSlu-.cjs"))).RelatedCards }));
6774
+ const RelatedTimeline = (0, react.lazy)(async () => ({ default: (await Promise.resolve().then(() => require("./related-list-timeline-Dsf5WewG.cjs"))).RelatedTimeline }));
6686
6775
  function discriminatorOptionLabel(field, value) {
6687
6776
  const text = (0, _burojs_core.fieldOptionText)(field, value);
6688
6777
  if (text !== void 0) return text;
@@ -7869,16 +7958,15 @@ function byOf(field) {
7869
7958
  }
7870
7959
  const MAX_TARGET_HOPS = 2;
7871
7960
  function targetColumns(registry, target, def) {
7872
- if (!isRecord(def) || !isRecord(def.fields)) return [];
7873
- const source = def;
7961
+ if (def === void 0) return [];
7874
7962
  const views = isRecord(def.views) ? def.views : void 0;
7875
7963
  const list = views !== void 0 && isRecord(views.list) ? views.list : void 0;
7876
7964
  return (list !== void 0 && Array.isArray(list.columns) ? list.columns.flatMap((entry) => {
7877
7965
  const name = isRecord(entry) ? entry.field : entry;
7878
7966
  return typeof name === "string" ? [name] : [];
7879
- }) : (0, _burojs_core.dtoFields)(source, "list")).filter((name) => {
7967
+ }) : (0, _burojs_core.dtoFields)(def, "list")).filter((name) => {
7880
7968
  if (name.includes(".")) return name.split(".").length - 1 <= MAX_TARGET_HOPS && (0, _burojs_react.resolveColumnField)(registry, target, name) !== void 0;
7881
- const field = peekFieldDefinition(source, name);
7969
+ const field = peekFieldDefinition(def, name);
7882
7970
  return isRecord(field) && !(0, _burojs_core.isRelationField)(field) && (0, _burojs_core.fieldSensitivity)(field) === void 0;
7883
7971
  });
7884
7972
  }
@@ -8073,7 +8161,7 @@ function RelatedListView({ props, empty }) {
8073
8161
  ...route.renderCell === void 0 ? {} : { renderCell: route.renderCell },
8074
8162
  ...route.emptyState === void 0 ? {} : { emptyState: route.emptyState }
8075
8163
  });
8076
- if (own.view !== void 0 && own.view !== "table" && permissions?.status === "loading") return (0, react_jsx_runtime.jsx)("div", {
8164
+ if (own.view !== void 0 && own.view !== "table" && (0, _burojs_core.permissionsUndecided)(permissions)) return (0, react_jsx_runtime.jsx)("div", {
8077
8165
  role: "status",
8078
8166
  "aria-busy": "true",
8079
8167
  "data-testid": `list-undecided:${resource}`,
@@ -8153,7 +8241,7 @@ function RelatedRecordView({ props, empty }) {
8153
8241
  });
8154
8242
  const result = query.data;
8155
8243
  const raw = result?.data;
8156
- const dtoRow = (0, react.useMemo)(() => raw !== null && typeof raw === "object" && projection !== void 0 ? (0, _burojs_core.projectDto)(raw, projection) : void 0, [raw, projection]);
8244
+ const dtoRow = (0, react.useMemo)(() => raw !== null && typeof raw === "object" && projection !== void 0 ? (0, _burojs_react.deriveRecord)(raw, (record) => (0, _burojs_core.projectDto)(record, projection)) : void 0, [raw, projection]);
8157
8245
  const access = (0, _burojs_react.useFieldAccess)(resource, "record", dtoRow);
8158
8246
  const projected = (0, _burojs_react.useProjectedRecord)(resource, dtoRow, { placeholder: query.isPlaceholderData === true });
8159
8247
  const fieldsKey = JSON.stringify(own.fields ?? null);
@@ -8194,10 +8282,7 @@ function RelatedRecordView({ props, empty }) {
8194
8282
  children: own.title
8195
8283
  }), own.toolbar === "item" ? (0, react_jsx_runtime.jsx)(ActionOverflow, {
8196
8284
  resource,
8197
- record: {
8198
- ...dtoRow,
8199
- id
8200
- },
8285
+ record: (0, _burojs_react.withRecordKeys)(dtoRow, { id }),
8201
8286
  surface: "show"
8202
8287
  }) : null]
8203
8288
  }), (0, react_jsx_runtime.jsx)("dl", {
@@ -8589,6 +8674,12 @@ Object.defineProperty(exports, "EnumBadge", {
8589
8674
  return EnumBadge;
8590
8675
  }
8591
8676
  });
8677
+ Object.defineProperty(exports, "EnumSettlingRow", {
8678
+ enumerable: true,
8679
+ get: function() {
8680
+ return EnumSettlingRow;
8681
+ }
8682
+ });
8592
8683
  Object.defineProperty(exports, "ExportButton", {
8593
8684
  enumerable: true,
8594
8685
  get: function() {
@@ -8757,6 +8848,12 @@ Object.defineProperty(exports, "RelatedItem", {
8757
8848
  return RelatedItem;
8758
8849
  }
8759
8850
  });
8851
+ Object.defineProperty(exports, "RelatedTimelineSkeleton", {
8852
+ enumerable: true,
8853
+ get: function() {
8854
+ return RelatedTimelineSkeleton;
8855
+ }
8856
+ });
8760
8857
  Object.defineProperty(exports, "ResourceList", {
8761
8858
  enumerable: true,
8762
8859
  get: function() {
@@ -8865,18 +8962,6 @@ Object.defineProperty(exports, "isBuiltinRecordView", {
8865
8962
  return isBuiltinRecordView;
8866
8963
  }
8867
8964
  });
8868
- Object.defineProperty(exports, "isShowAvailable", {
8869
- enumerable: true,
8870
- get: function() {
8871
- return isShowAvailable;
8872
- }
8873
- });
8874
- Object.defineProperty(exports, "listTarget", {
8875
- enumerable: true,
8876
- get: function() {
8877
- return listTarget;
8878
- }
8879
- });
8880
8965
  Object.defineProperty(exports, "peekFieldDefinition", {
8881
8966
  enumerable: true,
8882
8967
  get: function() {
@@ -8901,18 +8986,6 @@ Object.defineProperty(exports, "peekRow", {
8901
8986
  return peekRow;
8902
8987
  }
8903
8988
  });
8904
- Object.defineProperty(exports, "recordReturnTarget", {
8905
- enumerable: true,
8906
- get: function() {
8907
- return recordReturnTarget;
8908
- }
8909
- });
8910
- Object.defineProperty(exports, "recordRouteAvailable", {
8911
- enumerable: true,
8912
- get: function() {
8913
- return recordRouteAvailable;
8914
- }
8915
- });
8916
8989
  Object.defineProperty(exports, "resolveFrameView", {
8917
8990
  enumerable: true,
8918
8991
  get: function() {
@@ -8949,12 +9022,6 @@ Object.defineProperty(exports, "shadcnFrameViews", {
8949
9022
  return shadcnFrameViews;
8950
9023
  }
8951
9024
  });
8952
- Object.defineProperty(exports, "showTarget", {
8953
- enumerable: true,
8954
- get: function() {
8955
- return showTarget;
8956
- }
8957
- });
8958
9025
  Object.defineProperty(exports, "tanStackSortingToBuro", {
8959
9026
  enumerable: true,
8960
9027
  get: function() {
@@ -8973,6 +9040,12 @@ Object.defineProperty(exports, "typography", {
8973
9040
  return typography;
8974
9041
  }
8975
9042
  });
9043
+ Object.defineProperty(exports, "unknownEnumValueLabel", {
9044
+ enumerable: true,
9045
+ get: function() {
9046
+ return unknownEnumValueLabel;
9047
+ }
9048
+ });
8976
9049
  Object.defineProperty(exports, "useBuroDataTable", {
8977
9050
  enumerable: true,
8978
9051
  get: function() {
@@ -9058,4 +9131,4 @@ Object.defineProperty(exports, "viewOf", {
9058
9131
  }
9059
9132
  });
9060
9133
 
9061
- //# sourceMappingURL=place-node-CNb3w-c7.cjs.map
9134
+ //# sourceMappingURL=place-node-BZF5Af6x.cjs.map