@burojs/ui-shadcn 0.5.0 → 0.6.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 (133) hide show
  1. package/dist/candidates-gate-Bb70LPAy.js +135 -0
  2. package/dist/candidates-gate-Bb70LPAy.js.map +1 -0
  3. package/dist/candidates-gate-D33jXLHO.cjs +153 -0
  4. package/dist/candidates-gate-D33jXLHO.cjs.map +1 -0
  5. package/dist/candidates-relation-picker-B116Bmqi.js +31 -0
  6. package/dist/candidates-relation-picker-B116Bmqi.js.map +1 -0
  7. package/dist/candidates-relation-picker-Cy0rTxvI.cjs +31 -0
  8. package/dist/candidates-relation-picker-Cy0rTxvI.cjs.map +1 -0
  9. package/dist/{check-confirm-dialog-BRByTFpg.cjs → check-confirm-dialog--gPFnEeg.cjs} +27 -14
  10. package/dist/check-confirm-dialog--gPFnEeg.cjs.map +1 -0
  11. package/dist/{check-confirm-dialog-CkaVTPT9.js → check-confirm-dialog-bRT8lt0d.js} +28 -15
  12. package/dist/check-confirm-dialog-bRT8lt0d.js.map +1 -0
  13. package/dist/{filter-builder-DOnaXNfP.js → filter-builder-Bhn-dhZV.js} +30 -14
  14. package/dist/filter-builder-Bhn-dhZV.js.map +1 -0
  15. package/dist/{filter-builder-B3mZFL-K.cjs → filter-builder-nXqtM_h4.cjs} +39 -11
  16. package/dist/filter-builder-nXqtM_h4.cjs.map +1 -0
  17. package/dist/{flow-runtime-B6zOHYqI.cjs → flow-runtime-D3avVH0I.cjs} +3 -3
  18. package/dist/{flow-runtime-B6zOHYqI.cjs.map → flow-runtime-D3avVH0I.cjs.map} +1 -1
  19. package/dist/{flow-runtime-D8h99FSg.js → flow-runtime-s6lkRPKF.js} +3 -3
  20. package/dist/{flow-runtime-D8h99FSg.js.map → flow-runtime-s6lkRPKF.js.map} +1 -1
  21. package/dist/{flow-screen-CmbARSqg.js → flow-screen-CCvgDI9G.js} +11 -8
  22. package/dist/flow-screen-CCvgDI9G.js.map +1 -0
  23. package/dist/{flow-screen-CX05b3G9.cjs → flow-screen-Ci_Sik4Y.cjs} +10 -7
  24. package/dist/flow-screen-Ci_Sik4Y.cjs.map +1 -0
  25. package/dist/index.cjs +577 -56
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.d.cts +181 -103
  28. package/dist/index.d.ts +181 -103
  29. package/dist/index.js +567 -45
  30. package/dist/index.js.map +1 -1
  31. package/dist/{inline-flow-host-C3H2UpSA.js → inline-flow-host-B6FI0ctQ.js} +3 -3
  32. package/dist/{inline-flow-host-C3H2UpSA.js.map → inline-flow-host-B6FI0ctQ.js.map} +1 -1
  33. package/dist/{inline-flow-host-B7U1OJUe.cjs → inline-flow-host-DV1et3c6.cjs} +3 -3
  34. package/dist/{inline-flow-host-B7U1OJUe.cjs.map → inline-flow-host-DV1et3c6.cjs.map} +1 -1
  35. package/dist/label-66W1qbke.js.map +1 -1
  36. package/dist/label-w6JYf2cF.cjs.map +1 -1
  37. package/dist/markdown/index.d.cts +2 -3
  38. package/dist/markdown/index.d.ts +2 -3
  39. package/dist/{page-flow-route-CQ7HsbBm.cjs → page-flow-route-hdnULWqd.cjs} +6 -6
  40. package/dist/{page-flow-route-CQ7HsbBm.cjs.map → page-flow-route-hdnULWqd.cjs.map} +1 -1
  41. package/dist/{page-flow-route-CyXSvXSE.js → page-flow-route-i3ZfJ1sd.js} +6 -6
  42. package/dist/{page-flow-route-CyXSvXSE.js.map → page-flow-route-i3ZfJ1sd.js.map} +1 -1
  43. package/dist/{place-node-SIp4XYQH.cjs → place-node-C5SmIAYU.cjs} +441 -135
  44. package/dist/place-node-C5SmIAYU.cjs.map +1 -0
  45. package/dist/{place-node--GdsP688.js → place-node-NraNYKPx.js} +420 -138
  46. package/dist/place-node-NraNYKPx.js.map +1 -0
  47. package/dist/{related-list-cards-B6x9HQQp.js → related-list-cards-BWZ9GfOG.js} +3 -3
  48. package/dist/{related-list-cards-B6x9HQQp.js.map → related-list-cards-BWZ9GfOG.js.map} +1 -1
  49. package/dist/{related-list-cards-nxuODlIA.cjs → related-list-cards-CFq3meUn.cjs} +3 -3
  50. package/dist/{related-list-cards-nxuODlIA.cjs.map → related-list-cards-CFq3meUn.cjs.map} +1 -1
  51. package/dist/{related-list-timeline-BYJKEbmA.cjs → related-list-timeline-CCzl71aA.cjs} +2 -2
  52. package/dist/{related-list-timeline-BYJKEbmA.cjs.map → related-list-timeline-CCzl71aA.cjs.map} +1 -1
  53. package/dist/{related-list-timeline-DEdfd-rr.js → related-list-timeline-yrPsjA3F.js} +2 -2
  54. package/dist/{related-list-timeline-DEdfd-rr.js.map → related-list-timeline-yrPsjA3F.js.map} +1 -1
  55. package/dist/{related-rows-zh5f_4QR.cjs → related-rows-ea43qhhy.cjs} +10 -11
  56. package/dist/related-rows-ea43qhhy.cjs.map +1 -0
  57. package/dist/{related-rows-B4levHcR.js → related-rows-o0_t-Yce.js} +7 -8
  58. package/dist/related-rows-o0_t-Yce.js.map +1 -0
  59. package/dist/{relation-create-BOaUe12G.cjs → relation-create-IA40t1hi.cjs} +10 -8
  60. package/dist/relation-create-IA40t1hi.cjs.map +1 -0
  61. package/dist/{relation-create-Bg-eEJLs.js → relation-create-h6F9B4C4.js} +10 -8
  62. package/dist/relation-create-h6F9B4C4.js.map +1 -0
  63. package/dist/{relation-many-picker-B-NCEUgX.cjs → relation-many-picker-C8zFEjwd.cjs} +14 -12
  64. package/dist/relation-many-picker-C8zFEjwd.cjs.map +1 -0
  65. package/dist/{relation-many-picker-gdAOD-qK.js → relation-many-picker-bvkjkv-k.js} +13 -11
  66. package/dist/relation-many-picker-bvkjkv-k.js.map +1 -0
  67. package/dist/{relation-picker-BAY77ivO.js → relation-picker-Z0ZJJ5uS.js} +68 -37
  68. package/dist/relation-picker-Z0ZJJ5uS.js.map +1 -0
  69. package/dist/{relation-picker-dialog-M0pQaWlp.cjs → relation-picker-dialog-0IzkjmiA.cjs} +17 -13
  70. package/dist/relation-picker-dialog-0IzkjmiA.cjs.map +1 -0
  71. package/dist/{relation-picker-dialog-hA9rYrZB.js → relation-picker-dialog-B6nIiJBf.js} +18 -14
  72. package/dist/relation-picker-dialog-B6nIiJBf.js.map +1 -0
  73. package/dist/{relation-picker-Da_uhFvA.cjs → relation-picker-gag0qSR5.cjs} +74 -37
  74. package/dist/relation-picker-gag0qSR5.cjs.map +1 -0
  75. package/dist/{resource-page-router-T4vS5gbJ.js → resource-page-router-3RUf9d1j.js} +44 -38
  76. package/dist/resource-page-router-3RUf9d1j.js.map +1 -0
  77. package/dist/{resource-page-router-OSQyRA5b.cjs → resource-page-router-PXfMW9nh.cjs} +42 -36
  78. package/dist/resource-page-router-PXfMW9nh.cjs.map +1 -0
  79. package/dist/{search-access-CURsWn-U.js → search-access-CPPmfuvy.js} +4 -19
  80. package/dist/search-access-CPPmfuvy.js.map +1 -0
  81. package/dist/{search-access-B7G5oR8n.cjs → search-access-Dugvttlg.cjs} +3 -24
  82. package/dist/search-access-Dugvttlg.cjs.map +1 -0
  83. package/dist/{toaster-CfCRLgR-.js → toaster-C02XbB9r.js} +30 -59
  84. package/dist/toaster-C02XbB9r.js.map +1 -0
  85. package/dist/{toaster-C7CiYA4Z.cjs → toaster-Cr51X7bz.cjs} +30 -83
  86. package/dist/toaster-Cr51X7bz.cjs.map +1 -0
  87. package/dist/{use-dialog-filter-state-BDcgS5Oz.js → use-dialog-filter-state-C--oMAZG.js} +2 -2
  88. package/dist/{use-dialog-filter-state-BDcgS5Oz.js.map → use-dialog-filter-state-C--oMAZG.js.map} +1 -1
  89. package/dist/{use-dialog-filter-state-BBCC0OEK.cjs → use-dialog-filter-state-Dhe8PcB5.cjs} +2 -2
  90. package/dist/{use-dialog-filter-state-BBCC0OEK.cjs.map → use-dialog-filter-state-Dhe8PcB5.cjs.map} +1 -1
  91. package/dist/use-theme-DFlpXils.cjs.map +1 -1
  92. package/dist/use-theme-dnE3Od3I.js.map +1 -1
  93. package/package.json +9 -9
  94. package/dist/candidates-gate-CX2PBu6l.js +0 -63
  95. package/dist/candidates-gate-CX2PBu6l.js.map +0 -1
  96. package/dist/candidates-gate-DiFI52r7.cjs +0 -70
  97. package/dist/candidates-gate-DiFI52r7.cjs.map +0 -1
  98. package/dist/candidates-relation-picker-CBsVcnPR.js +0 -82
  99. package/dist/candidates-relation-picker-CBsVcnPR.js.map +0 -1
  100. package/dist/candidates-relation-picker-Dd_GVLlu.cjs +0 -84
  101. package/dist/candidates-relation-picker-Dd_GVLlu.cjs.map +0 -1
  102. package/dist/check-confirm-dialog-BRByTFpg.cjs.map +0 -1
  103. package/dist/check-confirm-dialog-CkaVTPT9.js.map +0 -1
  104. package/dist/filter-builder-B3mZFL-K.cjs.map +0 -1
  105. package/dist/filter-builder-DOnaXNfP.js.map +0 -1
  106. package/dist/flow-screen-CX05b3G9.cjs.map +0 -1
  107. package/dist/flow-screen-CmbARSqg.js.map +0 -1
  108. package/dist/lazy-relation-picker-dialog-2oxnA6IR.js +0 -14
  109. package/dist/lazy-relation-picker-dialog-2oxnA6IR.js.map +0 -1
  110. package/dist/lazy-relation-picker-dialog-BfAGKzUG.cjs +0 -19
  111. package/dist/lazy-relation-picker-dialog-BfAGKzUG.cjs.map +0 -1
  112. package/dist/peek-filter-CnqHwTMU.cjs +0 -51
  113. package/dist/peek-filter-CnqHwTMU.cjs.map +0 -1
  114. package/dist/peek-filter-ErLfO153.js +0 -28
  115. package/dist/peek-filter-ErLfO153.js.map +0 -1
  116. package/dist/place-node--GdsP688.js.map +0 -1
  117. package/dist/place-node-SIp4XYQH.cjs.map +0 -1
  118. package/dist/related-rows-B4levHcR.js.map +0 -1
  119. package/dist/related-rows-zh5f_4QR.cjs.map +0 -1
  120. package/dist/relation-create-BOaUe12G.cjs.map +0 -1
  121. package/dist/relation-create-Bg-eEJLs.js.map +0 -1
  122. package/dist/relation-many-picker-B-NCEUgX.cjs.map +0 -1
  123. package/dist/relation-many-picker-gdAOD-qK.js.map +0 -1
  124. package/dist/relation-picker-BAY77ivO.js.map +0 -1
  125. package/dist/relation-picker-Da_uhFvA.cjs.map +0 -1
  126. package/dist/relation-picker-dialog-M0pQaWlp.cjs.map +0 -1
  127. package/dist/relation-picker-dialog-hA9rYrZB.js.map +0 -1
  128. package/dist/resource-page-router-OSQyRA5b.cjs.map +0 -1
  129. package/dist/resource-page-router-T4vS5gbJ.js.map +0 -1
  130. package/dist/search-access-B7G5oR8n.cjs.map +0 -1
  131. package/dist/search-access-CURsWn-U.js.map +0 -1
  132. package/dist/toaster-C7CiYA4Z.cjs.map +0 -1
  133. package/dist/toaster-CfCRLgR-.js.map +0 -1
package/dist/index.cjs CHANGED
@@ -1,22 +1,21 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_use_theme = require("./use-theme-DFlpXils.cjs");
3
- const require_toaster = require("./toaster-C7CiYA4Z.cjs");
4
- const require_check_confirm_dialog = require("./check-confirm-dialog-BRByTFpg.cjs");
3
+ const require_toaster = require("./toaster-Cr51X7bz.cjs");
4
+ const require_check_confirm_dialog = require("./check-confirm-dialog--gPFnEeg.cjs");
5
5
  const require_button = require("./button-BxnnE28H.cjs");
6
6
  const require_input = require("./input-BI0czGyI.cjs");
7
7
  const require_dialog = require("./dialog-DRNUq9EA.cjs");
8
- const require_search_access = require("./search-access-B7G5oR8n.cjs");
8
+ const require_search_access = require("./search-access-Dugvttlg.cjs");
9
9
  const require_shell = require("./shell-DxhlsPwm.cjs");
10
10
  const require_skeleton = require("./skeleton-_1gP7wan.cjs");
11
- const require_place_node = require("./place-node-SIp4XYQH.cjs");
11
+ const require_place_node = require("./place-node-C5SmIAYU.cjs");
12
12
  const require_layout_theme_storage_key = require("./layout/theme-storage-key.cjs");
13
- const require_resource_page_router = require("./resource-page-router-OSQyRA5b.cjs");
13
+ const require_filter_builder = require("./filter-builder-nXqtM_h4.cjs");
14
+ const require_resource_page_router = require("./resource-page-router-PXfMW9nh.cjs");
14
15
  const require_label = require("./label-w6JYf2cF.cjs");
15
- const require_filter_builder = require("./filter-builder-B3mZFL-K.cjs");
16
- const require_relation_picker = require("./relation-picker-Da_uhFvA.cjs");
17
- const require_lazy_relation_picker_dialog = require("./lazy-relation-picker-dialog-BfAGKzUG.cjs");
18
- const require_use_dialog_filter_state = require("./use-dialog-filter-state-BBCC0OEK.cjs");
19
- const require_peek_filter = require("./peek-filter-CnqHwTMU.cjs");
16
+ const require_relation_picker = require("./relation-picker-gag0qSR5.cjs");
17
+ const require_candidates_gate = require("./candidates-gate-D33jXLHO.cjs");
18
+ const require_use_dialog_filter_state = require("./use-dialog-filter-state-Dhe8PcB5.cjs");
20
19
  let _burojs_core = require("@burojs/core");
21
20
  let _burojs_react = require("@burojs/react");
22
21
  let _tabler_icons_react = require("@tabler/icons-react");
@@ -1309,7 +1308,7 @@ function useLanguageSwitch() {
1309
1308
  locale,
1310
1309
  locales: (0, react.useMemo)(() => i18n?.locales?.() ?? [locale], [i18n, locale]),
1311
1310
  change: (0, react.useCallback)((code) => {
1312
- require_toaster.saveLocale(code, storageKey);
1311
+ require_filter_builder.saveLocale(code, storageKey);
1313
1312
  changeLocale(code);
1314
1313
  }, [changeLocale, storageKey])
1315
1314
  };
@@ -1753,9 +1752,9 @@ function useNavTree(opts = {}) {
1753
1752
  const topLevelCustomPages = allCustomPages.filter((p) => !p.section && !p.group).filter(pageAllowed).filter(passesEntryFilter);
1754
1753
  const resourceHref = (def) => (0, _burojs_core.hrefFor)(app.registry, require_resource_page_router.canonicalResourceKey(def));
1755
1754
  const resourceLabel = (def) => (0, _burojs_core.resolveResourceNavLabel)(caps, require_resource_page_router.canonicalResourceKey(def), def);
1756
- const pageLabel = (page) => (0, _burojs_core.resolveNavLabel)(caps, `pages.${require_resource_page_router.canonicalNavKey(page)}`, page.label);
1757
- const sectionLabel = (section) => (0, _burojs_core.resolveNavLabel)(caps, `sections.${require_resource_page_router.canonicalNavKey(section)}`, section.label);
1758
- const groupLabel = (group) => (0, _burojs_core.resolveNavLabel)(caps, `groups.${require_resource_page_router.canonicalNavKey(group)}`, group.label);
1755
+ const pageLabel = (page) => (0, _burojs_core.resolveNavLabel)(caps, `pages.${require_resource_page_router.canonicalNavKey(page)}`, (0, _burojs_core.declaredText)("chrome", page, "label"));
1756
+ const sectionLabel = (section) => (0, _burojs_core.resolveNavLabel)(caps, `sections.${require_resource_page_router.canonicalNavKey(section)}`, (0, _burojs_core.declaredText)("chrome", section, "label"));
1757
+ const groupLabel = (group) => (0, _burojs_core.resolveNavLabel)(caps, `groups.${require_resource_page_router.canonicalNavKey(group)}`, (0, _burojs_core.declaredText)("chrome", group, "label"));
1759
1758
  const pageEntry = (page) => {
1760
1759
  const href = page.path;
1761
1760
  return {
@@ -2046,7 +2045,7 @@ function SecondarySidebarLayout({ group, groupKey, items, children }) {
2046
2045
  const RouterLink = require_toaster.useLinkComponent();
2047
2046
  const caps = (0, _burojs_react.useI18nCaps)();
2048
2047
  const id = groupKey ?? group.name;
2049
- const label = (0, _burojs_core.resolveNavLabel)(caps, `groups.${id}`, group.label);
2048
+ const label = (0, _burojs_core.resolveNavLabel)(caps, `groups.${id}`, (0, _burojs_core.declaredText)("chrome", group, "label"));
2050
2049
  return (0, react_jsx_runtime.jsxs)("div", {
2051
2050
  className: "md:-m-6 md:flex md:min-h-[calc(100%+3rem)]",
2052
2051
  "data-testid": `nav-secondary:${id}`,
@@ -2091,7 +2090,7 @@ function TabsLayout({ group, groupKey, items, children }) {
2091
2090
  const RouterLink = require_toaster.useLinkComponent();
2092
2091
  const caps = (0, _burojs_react.useI18nCaps)();
2093
2092
  const id = groupKey ?? group.name;
2094
- const label = (0, _burojs_core.resolveNavLabel)(caps, `groups.${id}`, group.label);
2093
+ const label = (0, _burojs_core.resolveNavLabel)(caps, `groups.${id}`, (0, _burojs_core.declaredText)("chrome", group, "label"));
2095
2094
  return (0, react_jsx_runtime.jsxs)("div", {
2096
2095
  className: "flex flex-col gap-4",
2097
2096
  "data-testid": `nav-tabs:${id}`,
@@ -2558,7 +2557,7 @@ function CommandPaletteNavigationGroups({ onSelect, getTestId }) {
2558
2557
  navigate(href);
2559
2558
  };
2560
2559
  const resourceLabel = (def) => (0, _burojs_core.resolveResourceLabel)(caps, require_resource_page_router.canonicalResourceKey(def), "plural", def);
2561
- const pageLabel = (def) => (0, _burojs_core.resolveNavLabel)(caps, `pages.${require_resource_page_router.canonicalNavKey(def)}`, def.label);
2560
+ const pageLabel = (def) => (0, _burojs_core.resolveNavLabel)(caps, `pages.${require_resource_page_router.canonicalNavKey(def)}`, (0, _burojs_core.declaredText)("chrome", def, "label"));
2562
2561
  const groups = [];
2563
2562
  if (topLevelResources.length > 0) groups.push((0, react_jsx_runtime.jsx)(require_search_access.CommandGroup, {
2564
2563
  heading: t("commandPalette.resources", { defaultValue: "Resources" }),
@@ -2590,7 +2589,7 @@ function CommandPaletteNavigationGroups({ onSelect, getTestId }) {
2590
2589
  }, "pages"));
2591
2590
  for (const { section, children } of sectionGroups) {
2592
2591
  const sectionKey = require_resource_page_router.canonicalNavKey(section);
2593
- const sectionLabel = (0, _burojs_core.resolveNavLabel)(caps, `sections.${sectionKey}`, section.label);
2592
+ const sectionLabel = (0, _burojs_core.resolveNavLabel)(caps, `sections.${sectionKey}`, (0, _burojs_core.declaredText)("chrome", section, "label"));
2594
2593
  groups.push((0, react_jsx_runtime.jsxs)(require_search_access.CommandGroup, {
2595
2594
  heading: sectionLabel,
2596
2595
  children: [(0, react_jsx_runtime.jsx)(require_search_access.CommandItem, {
@@ -2629,7 +2628,7 @@ function CommandPaletteNavigationGroups({ onSelect, getTestId }) {
2629
2628
  const items = [];
2630
2629
  if (!!resolveLayout(group.layout)) {
2631
2630
  const groupKey = require_resource_page_router.canonicalNavKey(group);
2632
- const label = (0, _burojs_core.resolveNavLabel)(caps, `groups.${groupKey}`, group.label);
2631
+ const label = (0, _burojs_core.resolveNavLabel)(caps, `groups.${groupKey}`, (0, _burojs_core.declaredText)("chrome", group, "label"));
2633
2632
  const href = (0, _burojs_core.navHrefFor)(app.registry, groupKey, { isVisible });
2634
2633
  items.push((0, react_jsx_runtime.jsx)(require_search_access.CommandItem, {
2635
2634
  value: `group:${idPath}:${label}`,
@@ -2683,7 +2682,7 @@ function CommandPaletteNavigationGroups({ onSelect, getTestId }) {
2683
2682
  const groupKey = require_resource_page_router.canonicalNavKey(group);
2684
2683
  const items = collectGroupItems(group, groupKey, 0);
2685
2684
  if (items.length === 0) continue;
2686
- const heading = (0, _burojs_core.resolveNavLabel)(caps, `groups.${groupKey}`, group.label);
2685
+ const heading = (0, _burojs_core.resolveNavLabel)(caps, `groups.${groupKey}`, (0, _burojs_core.declaredText)("chrome", group, "label"));
2687
2686
  groups.push((0, react_jsx_runtime.jsx)(require_search_access.CommandGroup, {
2688
2687
  heading,
2689
2688
  children: items
@@ -2855,6 +2854,7 @@ function PerResourceSearchHits({ def, displayField, query, pageSize, goTo, recor
2855
2854
  page: 1,
2856
2855
  pageSize
2857
2856
  },
2857
+ scope: "session",
2858
2858
  enabled: shouldFetch
2859
2859
  });
2860
2860
  const report = useCommandPaletteResults(`records:${resource}`);
@@ -3226,7 +3226,6 @@ function localizedSchema(t) {
3226
3226
  function LoginForm({ onSubmit, title, description, className }) {
3227
3227
  const tid = (0, _burojs_react.useTestIds)();
3228
3228
  const t = (0, _burojs_react.useOptionalT)();
3229
- const locale = (0, _burojs_react.useLocale)();
3230
3229
  const resolvedTitle = title ?? t("auth.signIn", { defaultValue: "Sign in" });
3231
3230
  const { register, handleSubmit, formState: { errors, isSubmitting } } = (0, react_hook_form.useForm)({
3232
3231
  resolver: (0, _hookform_resolvers_zod.zodResolver)(localizedSchema(t)),
@@ -3242,7 +3241,7 @@ function LoginForm({ onSubmit, title, description, className }) {
3242
3241
  await onSubmit(values);
3243
3242
  } catch (e) {
3244
3243
  const raw = e instanceof Error ? e.message : String(e);
3245
- const friendly = require_toaster.toFriendlyError(raw, "", locale);
3244
+ const friendly = require_toaster.toFriendlyError(raw, "", require_toaster.friendlyStringsFrom(t));
3246
3245
  setSubmitError(friendly.replaced ? `${friendly.title}. ${friendly.detail}` : credentialsMessage(raw, t));
3247
3246
  }
3248
3247
  });
@@ -3434,7 +3433,7 @@ function EnumPicker({ enumName, value, onChange, renderAs = "select", name, id,
3434
3433
  ...ariaErrorMessage ? { "aria-errormessage": ariaErrorMessage } : {},
3435
3434
  "data-testid": `${tid}:option:${entry.value}`,
3436
3435
  className: "h-4 w-4"
3437
- }), (0, react_jsx_runtime.jsx)("span", { children: (0, _burojs_core.resolveEnumLabel)(caps, ns, entry.value, entry.label) })]
3436
+ }), (0, react_jsx_runtime.jsx)("span", { children: (0, _burojs_core.resolveEnumLabel)(caps, ns, entry.value, (0, _burojs_core.enumValueText)(def, entry.value) ?? entry.label) })]
3438
3437
  }, entry.value);
3439
3438
  })
3440
3439
  });
@@ -3455,7 +3454,7 @@ function EnumPicker({ enumName, value, onChange, renderAs = "select", name, id,
3455
3454
  disabled,
3456
3455
  onClick: () => onChange(entry.value),
3457
3456
  className: require_use_theme.cn("inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium transition-all", "data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-xs", "disabled:pointer-events-none disabled:opacity-50", "focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring"),
3458
- children: (0, _burojs_core.resolveEnumLabel)(caps, ns, entry.value, entry.label)
3457
+ children: (0, _burojs_core.resolveEnumLabel)(caps, ns, entry.value, (0, _burojs_core.enumValueText)(def, entry.value) ?? entry.label)
3459
3458
  }, entry.value);
3460
3459
  })
3461
3460
  });
@@ -3487,7 +3486,7 @@ function EnumPicker({ enumName, value, onChange, renderAs = "select", name, id,
3487
3486
  "data-testid": `${tid}:option:__clear__`,
3488
3487
  children: clearLabel
3489
3488
  }), values.map((entry) => {
3490
- const optionLabel = (0, _burojs_core.resolveEnumLabel)(caps, ns, entry.value, entry.label);
3489
+ const optionLabel = (0, _burojs_core.resolveEnumLabel)(caps, ns, entry.value, (0, _burojs_core.enumValueText)(def, entry.value) ?? entry.label);
3491
3490
  const optionDoc = (0, _burojs_core.resolveDoc)(caps, `enum/${ns}/${entry.value}`)?.summary;
3492
3491
  return (0, react_jsx_runtime.jsx)(require_filter_builder.SelectItem, {
3493
3492
  value: entry.value,
@@ -3577,20 +3576,28 @@ function DateInput({ name, id, value, onChange, testid, disabled, required, aria
3577
3576
  function optionLabel(caps, field, value, inline) {
3578
3577
  const ns = (0, _burojs_core.enumNamespaceOf)(field);
3579
3578
  if (ns) return (0, _burojs_core.resolveEnumLabel)(caps, ns, value, inline);
3580
- return field ? (0, _burojs_core.resolveContentSlot)(caps, [(0, _burojs_core.fieldOptionKey)(field.name, value)], { default: inline }) : inline;
3579
+ return field ? (0, _burojs_core.resolveFieldOptionLabel)(caps, field.name, value, inline) : inline;
3580
+ }
3581
+ function declaredOptionLabel(option, value, enumDef) {
3582
+ return (enumDef === void 0 ? void 0 : (0, _burojs_core.enumValueText)(enumDef, value)) ?? (typeof option?.label === "string" ? option.label : value);
3583
+ }
3584
+ function useBoundEnum(field) {
3585
+ const app = (0, _burojs_react.useOptionalApp)();
3586
+ const namespace = (0, _burojs_core.enumNamespaceOf)(field);
3587
+ return namespace === void 0 ? void 0 : app?.registry.enums.get(namespace);
3581
3588
  }
3582
3589
  function useOptionCaps(resource) {
3583
3590
  return (0, _burojs_react.useI18nCaps)((0, react.useContext)(_burojs_react.ResourceContext).resource ?? resource);
3584
3591
  }
3585
3592
  function EnumDisplay({ value, options, field, resource }) {
3586
3593
  const caps = useOptionCaps(resource);
3594
+ const enumDef = useBoundEnum(field);
3587
3595
  if (value == null || value === "") return (0, react_jsx_runtime.jsx)("span", {
3588
3596
  className: "text-muted-foreground",
3589
3597
  children: "—"
3590
3598
  });
3591
3599
  const opt = options?.find((o) => o.value === String(value));
3592
- const inline = typeof opt?.label === "string" ? opt.label : String(value);
3593
- const label = optionLabel(caps, field, String(value), inline);
3600
+ const label = optionLabel(caps, field, String(value), declaredOptionLabel(opt, String(value), enumDef));
3594
3601
  return (0, react_jsx_runtime.jsxs)("span", {
3595
3602
  className: "inline-flex items-center gap-1",
3596
3603
  children: [opt?.icon ? (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.Icon, {
@@ -3602,6 +3609,7 @@ function EnumDisplay({ value, options, field, resource }) {
3602
3609
  function EnumInput({ name, id, value, onChange, testid, options, field, placeholder, disabled, required, ariaInvalid, ariaDescribedBy, ariaErrorMessage, resource }) {
3603
3610
  const t = (0, _burojs_react.useOptionalT)();
3604
3611
  const caps = useOptionCaps(resource);
3612
+ const enumDef = useBoundEnum(field);
3605
3613
  return (0, react_jsx_runtime.jsxs)(require_filter_builder.Select, {
3606
3614
  value: value ?? "",
3607
3615
  onValueChange: onChange,
@@ -3623,7 +3631,7 @@ function EnumInput({ name, id, value, onChange, testid, options, field, placehol
3623
3631
  children: [o.icon ? (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.Icon, {
3624
3632
  name: o.icon,
3625
3633
  className: "size-3.5 shrink-0 text-muted-foreground"
3626
- }) : null, optionLabel(caps, field, o.value, typeof o.label === "string" ? o.label : o.value)]
3634
+ }) : null, optionLabel(caps, field, o.value, declaredOptionLabel(o, o.value, enumDef))]
3627
3635
  })
3628
3636
  }, o.value)) })]
3629
3637
  });
@@ -3996,6 +4004,7 @@ function JsonDisplay({ value, presentation, testid }) {
3996
4004
  });
3997
4005
  }
3998
4006
  function JsonInput({ name, id, value, onChange, testid, disabled, required, ariaInvalid, ariaDescribedBy, ariaErrorMessage }) {
4007
+ const t = (0, _burojs_react.useOptionalT)();
3999
4008
  const seed = react.useMemo(() => {
4000
4009
  if (value == null || value === "") return "";
4001
4010
  return require_place_node.toDisplayText(value).text;
@@ -4039,13 +4048,13 @@ function JsonInput({ name, id, value, onChange, testid, disabled, required, aria
4039
4048
  }), invalid && (0, react_jsx_runtime.jsx)("p", {
4040
4049
  className: "text-[13px] leading-snug text-destructive",
4041
4050
  "data-testid": `${testid}-json-error`,
4042
- children: "Некорректный JSON — изменения не будут сохранены, пока он не станет валидным."
4051
+ children: t("field.jsonInvalid", { defaultValue: "Invalid JSON. Changes will not be saved until it is valid." })
4043
4052
  })]
4044
4053
  });
4045
4054
  }
4046
4055
  //#endregion
4047
4056
  //#region src/fields/lazy-relation-many.tsx
4048
- const RelationManyPickerInput = (0, react.lazy)(() => Promise.resolve().then(() => require("./relation-many-picker-B-NCEUgX.cjs")).then((module) => ({ default: module.RelationManyPickerInput })));
4057
+ const RelationManyPickerInput = (0, react.lazy)(() => Promise.resolve().then(() => require("./relation-many-picker-C8zFEjwd.cjs")).then((module) => ({ default: module.RelationManyPickerInput })));
4049
4058
  function LazyRelationManyInput(props) {
4050
4059
  return (0, react_jsx_runtime.jsx)(react.Suspense, {
4051
4060
  fallback: (0, react_jsx_runtime.jsx)(require_skeleton.Skeleton, {
@@ -4156,6 +4165,192 @@ function NumberInput({ name, id, value, onChange, testid, placeholder, disabled,
4156
4165
  });
4157
4166
  }
4158
4167
  //#endregion
4168
+ //#region src/fields/link-keys-display.tsx
4169
+ const isRecord$1 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
4170
+ function qualify(name, owner) {
4171
+ try {
4172
+ const namespace = (0, _burojs_core.normalizeEntityRef)(owner).namespace;
4173
+ const ref = (0, _burojs_core.normalizeEntityRef)(name, { defaultNamespace: namespace });
4174
+ return ref.namespace === "default" ? ref.id : `${ref.namespace}:${ref.id}`;
4175
+ } catch {
4176
+ return;
4177
+ }
4178
+ }
4179
+ function idFieldOf(def) {
4180
+ const declared = (def?.data)?.idField;
4181
+ return typeof declared === "string" && declared.length > 0 ? declared : "id";
4182
+ }
4183
+ function byOf(field) {
4184
+ const by = isRecord$1(field) && isRecord$1(field.meta) ? field.meta.by : void 0;
4185
+ return typeof by === "string" && by.length > 0 ? by : void 0;
4186
+ }
4187
+ const chipClassName = "inline-flex items-center rounded-md border border-border bg-muted/40 px-1.5 py-0.5 text-xs";
4188
+ function LinkKeysDisplay(props) {
4189
+ const { field, record } = props;
4190
+ const owner = props.owner ?? props.resource ?? "";
4191
+ const name = field?.name ?? "";
4192
+ const app = (0, _burojs_react.useApp)();
4193
+ const t = (0, _burojs_react.useOptionalT)();
4194
+ const tid = (0, _burojs_react.useTestIds)();
4195
+ const ownerDef = owner === "" ? void 0 : app.registry.get(owner);
4196
+ const declaration = ownerDef === void 0 ? void 0 : (0, _burojs_core.declaredField)(ownerDef, name);
4197
+ const link = isRecord$1(declaration) ? (0, _burojs_core.linkOf)(declaration) : void 0;
4198
+ const junctionName = link === void 0 ? void 0 : qualify(link.junction, owner);
4199
+ const junctionDef = junctionName === void 0 ? void 0 : app.registry.get(junctionName);
4200
+ const junctionField = (key) => junctionDef === void 0 ? void 0 : (0, _burojs_core.declaredField)(junctionDef, key);
4201
+ const ownerField = link === void 0 ? idFieldOf(ownerDef) : byOf(junctionField(link.sourceKey)) ?? idFieldOf(ownerDef);
4202
+ const targetBy = link === void 0 ? void 0 : byOf(junctionField(link.targetKey));
4203
+ const ownerKey = record?.[ownerField];
4204
+ const { keys, complete, isLoading, error } = (0, _burojs_react.useLinkKeys)(owner, name, ownerKey);
4205
+ const [missed, setMissed] = (0, react.useState)(() => new Set());
4206
+ const onMiss = (0, react.useCallback)((key, miss) => {
4207
+ setMissed((current) => {
4208
+ if (current.has(key) === miss) return current;
4209
+ const next = new Set(current);
4210
+ if (miss) next.add(key);
4211
+ else next.delete(key);
4212
+ return next;
4213
+ });
4214
+ }, []);
4215
+ const target = (isRecord$1(declaration) && isRecord$1(declaration.meta) ? declaration.meta.to : void 0) ?? field?.meta?.to;
4216
+ const chipField = (0, react.useMemo)(() => ({
4217
+ name,
4218
+ meta: {
4219
+ ...target === void 0 ? {} : { to: target },
4220
+ ...targetBy === void 0 ? {} : { by: targetBy }
4221
+ },
4222
+ ...field?.ui === void 0 ? {} : { ui: field.ui }
4223
+ }), [
4224
+ name,
4225
+ target,
4226
+ field?.ui,
4227
+ targetBy
4228
+ ]);
4229
+ const chipsId = tid.linkChips(owner, name);
4230
+ if (error) return (0, react_jsx_runtime.jsx)("span", {
4231
+ "data-testid": tid.linkError(owner, name),
4232
+ role: "status",
4233
+ className: "text-destructive text-xs",
4234
+ title: error.message,
4235
+ children: t("fields.link.failed", { defaultValue: "Links could not be loaded" })
4236
+ });
4237
+ if (keys === void 0) {
4238
+ if (!isLoading) return (0, react_jsx_runtime.jsx)("span", {
4239
+ "data-testid": "relation-many-display:empty",
4240
+ className: "text-muted-foreground",
4241
+ children: "—"
4242
+ });
4243
+ return (0, react_jsx_runtime.jsx)("span", {
4244
+ "data-testid": `${chipsId}:loading`,
4245
+ className: "inline-block h-5 w-20 animate-pulse rounded bg-muted",
4246
+ "aria-busy": "true"
4247
+ });
4248
+ }
4249
+ if (!complete) return (0, react_jsx_runtime.jsx)("span", {
4250
+ "data-testid": chipsId,
4251
+ className: "inline-flex flex-wrap gap-1",
4252
+ children: (0, react_jsx_runtime.jsx)("span", {
4253
+ "data-testid": tid.linkIncomplete(owner, name),
4254
+ className: "text-muted-foreground",
4255
+ children: t("fields.link.incomplete", {
4256
+ count: keys.length,
4257
+ defaultValue: "More than {{count}} links"
4258
+ })
4259
+ })
4260
+ });
4261
+ if (keys.length === 0) return (0, react_jsx_runtime.jsx)("span", {
4262
+ "data-testid": "relation-many-display:empty",
4263
+ className: "text-muted-foreground",
4264
+ children: "—"
4265
+ });
4266
+ const hidden = keys.filter((key) => missed.has(String(key))).length;
4267
+ return (0, react_jsx_runtime.jsxs)("span", {
4268
+ "data-testid": chipsId,
4269
+ className: "inline-flex flex-wrap gap-1",
4270
+ children: [keys.map((key) => (0, react_jsx_runtime.jsx)(LinkChip, {
4271
+ value: key,
4272
+ field: chipField,
4273
+ onMiss
4274
+ }, String(key))), hidden > 0 ? (0, react_jsx_runtime.jsx)("span", {
4275
+ "data-testid": tid.linkHidden(owner, name),
4276
+ className: `${chipClassName} text-muted-foreground`,
4277
+ children: t("fields.link.hidden", {
4278
+ count: hidden,
4279
+ defaultValue: "{{count}} not visible"
4280
+ })
4281
+ }) : null]
4282
+ });
4283
+ }
4284
+ function LinkChip({ value, field, onMiss }) {
4285
+ const gate = (0, _burojs_react.useEntryGate)();
4286
+ const meta = field.meta;
4287
+ let to;
4288
+ try {
4289
+ to = meta?.to === void 0 ? void 0 : (0, _burojs_core.resourceKey)(meta.to);
4290
+ } catch {
4291
+ to = void 0;
4292
+ }
4293
+ const answer = to === void 0 ? void 0 : gate(to, "show");
4294
+ if (!(to !== void 0 && answer !== void 0 && answer.state !== "undecided" && answer.state !== "hidden" && answer.state !== "disabled")) return (0, react_jsx_runtime.jsx)("span", {
4295
+ className: chipClassName,
4296
+ children: (0, react_jsx_runtime.jsx)(require_search_access.RelationDisplay, {
4297
+ value,
4298
+ field
4299
+ })
4300
+ });
4301
+ return (0, react_jsx_runtime.jsx)(ReadChip, {
4302
+ to,
4303
+ value,
4304
+ field,
4305
+ onMiss
4306
+ });
4307
+ }
4308
+ function ReadChip({ to, value, field, onMiss }) {
4309
+ const app = (0, _burojs_react.useApp)();
4310
+ const by = field.meta?.by;
4311
+ const { record, isLoading, error, ambiguous } = (0, _burojs_react.useRelatedRecord)(to, value, typeof by === "string" ? { by } : void 0);
4312
+ const miss = app.registry.get(to) !== void 0 && !isLoading && !error && !ambiguous && !record;
4313
+ const key = String(value);
4314
+ (0, react.useEffect)(() => {
4315
+ onMiss(key, miss);
4316
+ }, [
4317
+ onMiss,
4318
+ key,
4319
+ miss
4320
+ ]);
4321
+ (0, react.useEffect)(() => () => onMiss(key, false), [onMiss, key]);
4322
+ if (miss) return null;
4323
+ return (0, react_jsx_runtime.jsx)("span", {
4324
+ className: chipClassName,
4325
+ children: (0, react_jsx_runtime.jsx)(require_search_access.RelationDisplay, {
4326
+ value,
4327
+ field
4328
+ })
4329
+ });
4330
+ }
4331
+ function RelationManyDisplay(props) {
4332
+ const app = (0, _burojs_react.useApp)();
4333
+ const owner = props.owner ?? props.resource ?? "";
4334
+ const ownerDef = owner === "" ? void 0 : app.registry.get(owner);
4335
+ const declared = ownerDef === void 0 || props.field?.name === void 0 ? void 0 : (0, _burojs_core.declaredField)(ownerDef, props.field.name);
4336
+ if (isRecord$1(declared) && (0, _burojs_core.linkOf)(declared) !== void 0) return (0, react_jsx_runtime.jsx)(LinkKeysDisplay, { ...props });
4337
+ const { value, field } = props;
4338
+ const keys = Array.isArray(value) ? value : [];
4339
+ if (keys.length === 0) return (0, react_jsx_runtime.jsx)("span", {
4340
+ "data-testid": "relation-many-display:empty",
4341
+ className: "text-muted-foreground",
4342
+ children: "—"
4343
+ });
4344
+ return (0, react_jsx_runtime.jsx)("span", {
4345
+ className: "inline-flex flex-wrap gap-x-2",
4346
+ "data-testid": "relation-many-display",
4347
+ children: keys.map((key, index) => (0, react_jsx_runtime.jsx)(require_search_access.RelationDisplay, {
4348
+ value: key,
4349
+ field
4350
+ }, `${String(key)}:${index}`))
4351
+ });
4352
+ }
4353
+ //#endregion
4159
4354
  //#region src/fields/relation-meta-schema.ts
4160
4355
  const isRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
4161
4356
  const relationMetaSchema = Object.freeze({ "~standard": Object.freeze({
@@ -4287,20 +4482,28 @@ function TextareaInput({ name, id, value, onChange, testid, placeholder, disable
4287
4482
  //#region src/fields/default-renderers.ts
4288
4483
  function legacyField(props) {
4289
4484
  const name = typeof props.path.at(-1) === "string" ? props.path.at(-1) : "field";
4485
+ const texts = props.field.texts;
4290
4486
  return Object.freeze({
4291
4487
  name,
4292
4488
  meta: props.meta,
4293
4489
  ui: props.ui,
4294
- codec: props.field.codec
4490
+ codec: props.field.codec,
4491
+ ...texts === void 0 ? {} : { texts }
4295
4492
  });
4296
4493
  }
4297
- function legacyOptions(options) {
4494
+ function legacyOptions(options, field) {
4298
4495
  if (options.length === 0) return void 0;
4299
- return options.map((option) => Object.freeze({
4300
- value: String(option.value ?? ""),
4301
- label: option.label,
4302
- ...typeof option.meta?.icon === "string" ? { icon: option.meta.icon } : {}
4303
- }));
4496
+ return options.map((option) => {
4497
+ const value = String(option.value ?? "");
4498
+ return Object.freeze({
4499
+ value,
4500
+ label: (0, _burojs_core.fieldOptionText)(field, value) ?? value,
4501
+ ...typeof option.meta?.icon === "string" ? { icon: option.meta.icon } : {}
4502
+ });
4503
+ });
4504
+ }
4505
+ function registryKey(ref) {
4506
+ return ref.namespace === "default" ? ref.id : (0, _burojs_core.formatEntityRef)(ref);
4304
4507
  }
4305
4508
  function display(renderer) {
4306
4509
  return function ShadcnDisplay(props) {
@@ -4308,8 +4511,9 @@ function display(renderer) {
4308
4511
  value: props.value,
4309
4512
  multiple: props.multiple,
4310
4513
  field: legacyField(props),
4311
- options: legacyOptions(props.options),
4514
+ options: legacyOptions(props.options, props.field),
4312
4515
  resource: props.resource.id,
4516
+ owner: registryKey(props.resource),
4313
4517
  record: props.record,
4314
4518
  presentation: props.presentation,
4315
4519
  testid: props.testIds.display
@@ -4334,7 +4538,7 @@ function input(renderer) {
4334
4538
  multiple: props.multiple,
4335
4539
  onChange: props.onChange ?? (() => void 0),
4336
4540
  testid: props.testIds.input,
4337
- options: legacyOptions(props.options),
4541
+ options: legacyOptions(props.options, props.field),
4338
4542
  placeholder: typeof props.ui.placeholder === "string" ? props.ui.placeholder : void 0,
4339
4543
  disabled: props.disabled,
4340
4544
  required: props.field.required === true,
@@ -4475,7 +4679,7 @@ const rich = {
4475
4679
  Input: LazyRichTextInput
4476
4680
  };
4477
4681
  const relationMany = collection({
4478
- Display: require_search_access.RelationManyDisplay,
4682
+ Display: RelationManyDisplay,
4479
4683
  Input: LazyRelationManyInput
4480
4684
  });
4481
4685
  const shadcnFieldImplementations = Object.freeze({
@@ -4508,6 +4712,313 @@ const shadcnFieldImplementations = Object.freeze({
4508
4712
  file: scalarOrCollection(file, { size: "full" })
4509
4713
  });
4510
4714
  //#endregion
4715
+ //#region src/fields/use-relation-picker.tsx
4716
+ const noop = () => void 0;
4717
+ function safeKey(input) {
4718
+ if (input === void 0 || input === null) return void 0;
4719
+ try {
4720
+ return (0, _burojs_core.resourceKey)(input);
4721
+ } catch {
4722
+ return;
4723
+ }
4724
+ }
4725
+ function sessionIdentity(runtime) {
4726
+ const state = runtime.dataSession.getState();
4727
+ const snapshot = state.status === "ready" ? state.snapshot : state.target;
4728
+ let scopeKey;
4729
+ try {
4730
+ scopeKey = JSON.stringify(snapshot.scopeKey) ?? "";
4731
+ } catch {
4732
+ scopeKey = String(snapshot.scopeKey);
4733
+ }
4734
+ return {
4735
+ sessionKey: snapshot.sessionKey,
4736
+ scopeKey
4737
+ };
4738
+ }
4739
+ function PickerHost(props) {
4740
+ const { register } = props;
4741
+ react.useEffect(() => register(), [register]);
4742
+ return (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: props.children });
4743
+ }
4744
+ function useRelationPicker(options) {
4745
+ const app = (0, _burojs_react.useApp)();
4746
+ const runtime = (0, _burojs_react.useDataRuntime)();
4747
+ const frame = (0, _burojs_react.useOptionalRecordFrame)();
4748
+ const frames = (0, _burojs_react.useRecordScopeFrames)();
4749
+ const multiple = options.multiple === true;
4750
+ const fieldName = options.field;
4751
+ let to;
4752
+ let declaredBy;
4753
+ let declaredCandidates;
4754
+ if (fieldName !== void 0) {
4755
+ const meta = ((frame === null ? void 0 : app.registry.get(frame.resource)?.fields)?.[fieldName])?.meta;
4756
+ to = safeKey(meta?.to);
4757
+ declaredBy = typeof meta?.by === "string" ? meta.by : void 0;
4758
+ declaredCandidates = Array.isArray(meta?.candidates) ? meta.candidates : void 0;
4759
+ } else to = safeKey(options.to);
4760
+ const target = to ?? "";
4761
+ const by = options.valueField ?? declaredBy;
4762
+ const scope = options.scope ?? "context";
4763
+ const selection = require_candidates_gate.useCandidateSelection({
4764
+ to,
4765
+ candidates: options.candidates ?? declaredCandidates,
4766
+ sources: frame?.controller.sources,
4767
+ resource: frame?.resource ?? "",
4768
+ fieldName: fieldName ?? target,
4769
+ fixedFilters: options.fixedFilters
4770
+ });
4771
+ const held = selection.gate !== void 0;
4772
+ const pendingRef = react.useRef(null);
4773
+ const [active, setActive] = react.useState(null);
4774
+ const activeRef = react.useRef(null);
4775
+ activeRef.current = active;
4776
+ const rowsRef = react.useRef(new Map());
4777
+ const createdRowRef = react.useRef(void 0);
4778
+ const alive = react.useRef(true);
4779
+ const mounts = react.useRef(0);
4780
+ const sequence = react.useRef(0);
4781
+ const latest = react.useRef({
4782
+ multiple,
4783
+ select: options.select,
4784
+ idField: "id",
4785
+ valueField: "id",
4786
+ available: false,
4787
+ frames
4788
+ });
4789
+ const project = react.useCallback((row) => {
4790
+ const select = latest.current.select;
4791
+ if (select === void 0) return { ...row };
4792
+ const out = {};
4793
+ const key = row.id !== void 0 ? row.id : row[latest.current.idField];
4794
+ if (key !== void 0) out.id = key;
4795
+ const { valueField } = latest.current;
4796
+ if (Object.hasOwn(row, valueField)) out[valueField] = row[valueField];
4797
+ for (const name of select) if (Object.hasOwn(row, name)) out[name] = row[name];
4798
+ return out;
4799
+ }, []);
4800
+ const settle = react.useCallback((result) => {
4801
+ const pending = pendingRef.current;
4802
+ if (pending === null) return;
4803
+ pendingRef.current = null;
4804
+ pending.detach();
4805
+ if (alive.current) setActive(null);
4806
+ pending.resolve(result);
4807
+ }, []);
4808
+ const toggle = react.useCallback((key, row) => {
4809
+ setActive((current) => {
4810
+ if (current === null) return current;
4811
+ const has = current.selected.some((k) => String(k) === String(key));
4812
+ if (has) rowsRef.current.delete(String(key));
4813
+ else if (row !== void 0) rowsRef.current.set(String(key), row);
4814
+ const selected = has ? current.selected.filter((k) => String(k) !== String(key)) : [...current.selected, key];
4815
+ const next = {
4816
+ ...current,
4817
+ selected
4818
+ };
4819
+ activeRef.current = next;
4820
+ return next;
4821
+ });
4822
+ }, []);
4823
+ const onValue = react.useCallback((value) => {
4824
+ const row = createdRowRef.current;
4825
+ createdRowRef.current = void 0;
4826
+ if (latest.current.multiple) {
4827
+ const current = activeRef.current;
4828
+ if (current !== null && !current.selected.some((k) => String(k) === String(value))) toggle(value, row);
4829
+ return;
4830
+ }
4831
+ settle({
4832
+ kind: "selected",
4833
+ keys: [value],
4834
+ rows: row === void 0 ? [] : [project(row)]
4835
+ });
4836
+ }, [
4837
+ project,
4838
+ settle,
4839
+ toggle
4840
+ ]);
4841
+ const wiring = require_relation_picker.useRelationSelect({
4842
+ to: target,
4843
+ by,
4844
+ fixedFilters: selection.fixedFilters,
4845
+ scope,
4846
+ ...fieldName === void 0 ? {} : { scopeField: fieldName },
4847
+ held,
4848
+ onValue
4849
+ });
4850
+ latest.current = {
4851
+ multiple,
4852
+ select: options.select,
4853
+ idField: wiring.idField,
4854
+ valueField: wiring.valueField,
4855
+ available: to !== void 0 && wiring.targetDef !== void 0 && !held,
4856
+ frames
4857
+ };
4858
+ const { create: shared } = wiring;
4859
+ const create = react.useMemo(() => ({
4860
+ ...shared,
4861
+ start: (openCreate) => shared.start(() => {
4862
+ const opened = openCreate();
4863
+ opened.then((row) => {
4864
+ createdRowRef.current = row === null ? void 0 : { ...row };
4865
+ }, noop);
4866
+ return opened;
4867
+ })
4868
+ }), [shared]);
4869
+ react.useEffect(() => runtime.dataSession.subscribe(() => {
4870
+ const pending = pendingRef.current;
4871
+ if (pending === null) return;
4872
+ const now = sessionIdentity(runtime);
4873
+ if (now.sessionKey !== pending.sessionKey || now.scopeKey !== pending.scopeKey) settle({
4874
+ kind: "cancelled",
4875
+ reason: "session-changed"
4876
+ });
4877
+ }), [runtime, settle]);
4878
+ react.useEffect(() => {
4879
+ alive.current = true;
4880
+ return () => {
4881
+ alive.current = false;
4882
+ settle({
4883
+ kind: "cancelled",
4884
+ reason: "unmounted"
4885
+ });
4886
+ };
4887
+ }, [settle]);
4888
+ react.useEffect(() => {
4889
+ if (held) settle({
4890
+ kind: "cancelled",
4891
+ reason: "unavailable"
4892
+ });
4893
+ }, [held, settle]);
4894
+ const register = react.useCallback(() => {
4895
+ mounts.current += 1;
4896
+ return () => {
4897
+ mounts.current -= 1;
4898
+ if (mounts.current === 0) settle({
4899
+ kind: "cancelled",
4900
+ reason: "unmounted"
4901
+ });
4902
+ };
4903
+ }, [settle]);
4904
+ const open = react.useCallback((opts = {}) => new Promise((resolve) => {
4905
+ settle({
4906
+ kind: "cancelled",
4907
+ reason: "superseded"
4908
+ });
4909
+ if (mounts.current === 0) {
4910
+ if (process.env.NODE_ENV !== "production") console.error("[burojs] useRelationPicker: open() was called but its element is not rendered — render `handle.element` once in your tree.");
4911
+ resolve({
4912
+ kind: "cancelled",
4913
+ reason: "not-mounted"
4914
+ });
4915
+ return;
4916
+ }
4917
+ const { signal } = opts;
4918
+ if (signal?.aborted === true) {
4919
+ resolve({
4920
+ kind: "cancelled",
4921
+ reason: "aborted"
4922
+ });
4923
+ return;
4924
+ }
4925
+ if (!latest.current.available) {
4926
+ resolve({
4927
+ kind: "cancelled",
4928
+ reason: "unavailable"
4929
+ });
4930
+ return;
4931
+ }
4932
+ sequence.current += 1;
4933
+ const id = sequence.current;
4934
+ const onAbort = () => {
4935
+ if (pendingRef.current?.id === id) settle({
4936
+ kind: "cancelled",
4937
+ reason: "aborted"
4938
+ });
4939
+ };
4940
+ signal?.addEventListener("abort", onAbort, { once: true });
4941
+ pendingRef.current = {
4942
+ id,
4943
+ ...sessionIdentity(runtime),
4944
+ resolve,
4945
+ detach: () => signal?.removeEventListener("abort", onAbort)
4946
+ };
4947
+ rowsRef.current = new Map();
4948
+ createdRowRef.current = void 0;
4949
+ const next = {
4950
+ id,
4951
+ frames: latest.current.frames,
4952
+ selected: opts.selected ?? []
4953
+ };
4954
+ activeRef.current = next;
4955
+ setActive(next);
4956
+ }), [runtime, settle]);
4957
+ const onSelectRow = react.useCallback((row) => {
4958
+ const field = wiring.valueField;
4959
+ const value = field === "id" ? row.id : row[field];
4960
+ if (typeof value !== "string" && typeof value !== "number") return;
4961
+ settle({
4962
+ kind: "selected",
4963
+ keys: [value],
4964
+ rows: [project(row)]
4965
+ });
4966
+ }, [
4967
+ wiring.valueField,
4968
+ settle,
4969
+ project
4970
+ ]);
4971
+ const onDone = react.useCallback(() => {
4972
+ const keys = activeRef.current?.selected ?? [];
4973
+ const rows = keys.flatMap((key) => {
4974
+ const row = rowsRef.current.get(String(key));
4975
+ return row === void 0 ? [] : [project(row)];
4976
+ });
4977
+ settle({
4978
+ kind: "selected",
4979
+ keys,
4980
+ rows
4981
+ });
4982
+ }, [settle, project]);
4983
+ const onOpenChange = react.useCallback((next) => {
4984
+ if (!next) settle({
4985
+ kind: "cancelled",
4986
+ reason: "dismissed"
4987
+ });
4988
+ }, [settle]);
4989
+ return {
4990
+ open,
4991
+ element: (0, react_jsx_runtime.jsx)(PickerHost, {
4992
+ register,
4993
+ children: active === null || held ? null : (0, react_jsx_runtime.jsxs)(_burojs_react.RecordScopeChain, {
4994
+ frames: active.frames,
4995
+ children: [(0, react_jsx_runtime.jsx)(require_candidates_gate.LazyRelationPickerDialog, {
4996
+ to: target,
4997
+ open: true,
4998
+ onOpenChange,
4999
+ onSelect: noop,
5000
+ onSelectRow,
5001
+ valueField: wiring.valueField,
5002
+ ...selection.fixedFilters === void 0 ? {} : { fixedFilters: selection.fixedFilters },
5003
+ scope,
5004
+ ...fieldName === void 0 ? {} : { scopeField: fieldName },
5005
+ ...options.create === void 0 ? {} : {
5006
+ create,
5007
+ ...options.create.seeds === void 0 ? {} : { createSeeds: options.create.seeds }
5008
+ },
5009
+ fieldName: fieldName ?? target,
5010
+ ...multiple ? {
5011
+ multiple: true,
5012
+ selected: active.selected,
5013
+ onToggle: (value, row) => toggle(value, row),
5014
+ onDone
5015
+ } : {}
5016
+ }), wiring.reader]
5017
+ }, active.id)
5018
+ })
5019
+ };
5020
+ }
5021
+ //#endregion
4511
5022
  //#region src/forms/declarative-display.tsx
4512
5023
  function DeclarativeDisplay(props) {
4513
5024
  return (0, react_jsx_runtime.jsx)(_burojs_react.ScreenStateProvider, { children: (0, react_jsx_runtime.jsx)(DisplayBody, { ...props }) });
@@ -4563,7 +5074,7 @@ function EnumDisplay$1({ enumName, value, variant = "badge", testid, className }
4563
5074
  children: value
4564
5075
  });
4565
5076
  const entry = values?.find((v) => v.value === value);
4566
- const label = entry === void 0 && def?.fallback ? (0, _burojs_core.resolveContentSlot)(caps, [(0, _burojs_core.enumFallbackKey)(ns)], { default: def.fallback.label }) ?? value : (0, _burojs_core.resolveEnumLabel)(caps, ns, value, entry?.label);
5077
+ const label = entry === void 0 && (def?.fallback !== void 0 || (0, _burojs_core.enumFallbackText)(def) !== void 0) ? (0, _burojs_core.resolveContentSlot)(caps, [(0, _burojs_core.enumFallbackKey)(ns)], { default: (0, _burojs_core.enumFallbackText)(def) }) ?? value : (0, _burojs_core.resolveEnumLabel)(caps, ns, value, (0, _burojs_core.enumValueText)(def, value) ?? entry?.label);
4567
5078
  const icon = entry?.icon;
4568
5079
  if (variant === "icon-label") return (0, react_jsx_runtime.jsxs)("span", {
4569
5080
  "data-testid": id,
@@ -4883,7 +5394,11 @@ const OPERATOR_LABELS = {
4883
5394
  null: "is null",
4884
5395
  nnull: "is not null",
4885
5396
  startswith: "starts with",
4886
- endswith: "ends with"
5397
+ endswith: "ends with",
5398
+ has: "has",
5399
+ hasAny: "has any of",
5400
+ hasAll: "has all of",
5401
+ hasNone: "has none of"
4887
5402
  };
4888
5403
  function formatOperatorLabel(op, t) {
4889
5404
  return t ? t(`filters.operators.${op}`, { defaultValue: OPERATOR_LABELS[op] }) : OPERATOR_LABELS[op];
@@ -5138,7 +5653,7 @@ function peekFields(def, columns, capabilityFor, fieldVisible = () => true) {
5138
5653
  for (const name of columns) {
5139
5654
  if (out.length === 5) break;
5140
5655
  if (name === def.displayField || out.includes(name) || !record.has(name)) continue;
5141
- if (!require_peek_filter.peekLeafAllowed(def, name, capabilityFor, fieldVisible) || relation(require_peek_filter.peekFieldDefinition(def, name))) continue;
5656
+ if (!require_place_node.peekLeafAllowed(def, name, capabilityFor, fieldVisible) || relation(require_place_node.peekFieldDefinition(def, name))) continue;
5142
5657
  out.push(name);
5143
5658
  }
5144
5659
  return Object.freeze(out);
@@ -5205,6 +5720,7 @@ function PeekByKey({ target, by }) {
5205
5720
  page: 1,
5206
5721
  pageSize: 2
5207
5722
  },
5723
+ scope: "none",
5208
5724
  enabled: by.key !== "",
5209
5725
  retry: false
5210
5726
  });
@@ -5325,7 +5841,7 @@ function PeekRecord({ target, testid, row }) {
5325
5841
  ]);
5326
5842
  const access = (0, _burojs_react.useFieldAccess)(target, "record", dto);
5327
5843
  const fieldVisible = (0, react.useCallback)((name) => access[name]?.view === "visible", [access]);
5328
- const record = (0, react.useMemo)(() => require_peek_filter.peekRecord(def, dto, idField, capabilityFor, fieldVisible), [
5844
+ const record = (0, react.useMemo)(() => require_place_node.peekRecord(def, dto, idField, capabilityFor, fieldVisible), [
5329
5845
  dto,
5330
5846
  def,
5331
5847
  idField,
@@ -5336,7 +5852,7 @@ function PeekRecord({ target, testid, row }) {
5336
5852
  if (def === void 0 || screen === void 0) return record;
5337
5853
  const drawn = new Set();
5338
5854
  for (const node of screen.nodes) if (node.kind === "field" && node.field !== void 0) drawn.add(node.field);
5339
- return require_peek_filter.peekRow(def, dto, idField, capabilityFor, fieldVisible, drawn);
5855
+ return require_place_node.peekRow(def, dto, idField, capabilityFor, fieldVisible, drawn);
5340
5856
  }, [
5341
5857
  def,
5342
5858
  screen,
@@ -5418,7 +5934,7 @@ function DeclaredPeekBody({ target, testid, record, frameRecord, def, capability
5418
5934
  const compiled = controller.screen;
5419
5935
  const hidden = (0, react.useMemo)(() => {
5420
5936
  const out = new Set();
5421
- for (const entry of compiled?.fields ?? []) if (def === void 0 || !require_peek_filter.peekLeafAllowed(def, entry.name, capabilityFor, fieldVisible)) out.add(entry.name);
5937
+ for (const entry of compiled?.fields ?? []) if (def === void 0 || !require_place_node.peekLeafAllowed(def, entry.name, capabilityFor, fieldVisible)) out.add(entry.name);
5422
5938
  return out;
5423
5939
  }, [
5424
5940
  compiled,
@@ -5521,14 +6037,14 @@ function DefaultPeekBody({ target, testid, row, open }) {
5521
6037
  }), columns.length === 0 ? null : (0, react_jsx_runtime.jsx)("dl", {
5522
6038
  className: "grid gap-1.5",
5523
6039
  children: columns.map((name) => {
5524
- const field = require_peek_filter.peekFieldDefinition(def, name);
6040
+ const field = require_place_node.peekFieldDefinition(def, name);
5525
6041
  const value = record[name];
5526
6042
  return (0, react_jsx_runtime.jsxs)("div", {
5527
6043
  "data-testid": `${testid}:field:${name}`,
5528
6044
  className: "flex min-w-0 items-baseline gap-2 text-sm",
5529
6045
  children: [(0, react_jsx_runtime.jsx)("dt", {
5530
6046
  className: "w-24 shrink-0 truncate text-xs text-muted-foreground",
5531
- children: (0, _burojs_core.resolveFieldLabel)(caps, name, field?.label)
6047
+ children: (0, _burojs_core.resolveFieldLabel)(caps, name, (0, _burojs_core.declaredText)("field", field, "label"))
5532
6048
  }), (0, react_jsx_runtime.jsx)("dd", {
5533
6049
  className: "min-w-0 break-words",
5534
6050
  children: (0, react_jsx_runtime.jsx)(require_place_node.ResolvedFieldDisplay, {
@@ -5549,6 +6065,12 @@ function DefaultPeekBody({ target, testid, row, open }) {
5549
6065
  //#region src/quick/quick-body.tsx
5550
6066
  const EMPTY_ROUTE = Object.freeze({});
5551
6067
  function QuickBody({ entry }) {
6068
+ return (0, react_jsx_runtime.jsx)(_burojs_react.RecordScopeChain, {
6069
+ frames: entry.scopeFrames ?? _burojs_react.NO_RECORD_SCOPE_FRAMES,
6070
+ children: (0, react_jsx_runtime.jsx)(QuickBodyOf, { entry })
6071
+ });
6072
+ }
6073
+ function QuickBodyOf({ entry }) {
5552
6074
  if (entry.mode === "create") return (0, react_jsx_runtime.jsx)(QuickScreenOf, {
5553
6075
  entry,
5554
6076
  route: EMPTY_ROUTE
@@ -6431,7 +6953,6 @@ exports.ContextPicker = ContextPicker;
6431
6953
  exports.CopyId = require_place_node.CopyId;
6432
6954
  exports.CreateButton = require_place_node.CreateButton;
6433
6955
  exports.CursorLoadMore = require_place_node.CursorLoadMore;
6434
- exports.DEFAULT_LANGUAGE = require_toaster.DEFAULT_LANGUAGE;
6435
6956
  exports.DEFAULT_LANGUAGE_STORAGE_KEY = _burojs_react.DEFAULT_LANGUAGE_STORAGE_KEY;
6436
6957
  exports.DataTable = require_place_node.DataTable;
6437
6958
  exports.DataTableDateRangeFilter = DataTableDateRangeFilter;
@@ -6515,6 +7036,7 @@ exports.Label = require_label.Label;
6515
7036
  exports.LanguageSubmenu = LanguageSubmenu;
6516
7037
  exports.LanguageSwitch = LanguageSwitch;
6517
7038
  exports.LinkComponentProvider = require_toaster.LinkComponentProvider;
7039
+ exports.LinkKeysDisplay = LinkKeysDisplay;
6518
7040
  exports.ListBody = require_place_node.ListBody;
6519
7041
  exports.ListBulkBar = require_place_node.ListBulkBar;
6520
7042
  exports.ListColumns = require_place_node.ListColumns;
@@ -6555,9 +7077,9 @@ exports.RecordTitle = require_place_node.RecordTitle;
6555
7077
  exports.RefreshButton = RefreshButton;
6556
7078
  exports.RelationDisplay = require_search_access.RelationDisplay;
6557
7079
  exports.RelationField = require_search_access.RelationField;
6558
- exports.RelationManyDisplay = require_search_access.RelationManyDisplay;
7080
+ exports.RelationManyDisplay = RelationManyDisplay;
6559
7081
  exports.RelationPicker = require_relation_picker.RelationPicker;
6560
- exports.RelationPickerDialog = require_lazy_relation_picker_dialog.LazyRelationPickerDialog;
7082
+ exports.RelationPickerDialog = require_candidates_gate.LazyRelationPickerDialog;
6561
7083
  exports.RelationPickerInput = require_relation_picker.RelationPickerInput;
6562
7084
  exports.ResourceList = require_place_node.ResourceList;
6563
7085
  exports.ResourceListPage = require_resource_page_router.ResourceListPage;
@@ -6655,8 +7177,7 @@ exports.i18nPrefixToRef = _burojs_core.i18nPrefixToRef;
6655
7177
  exports.isImage = _burojs_file_storage.isImage;
6656
7178
  exports.layoutSlot = require_resource_page_router.layoutSlot;
6657
7179
  exports.listSlot = require_check_confirm_dialog.listSlot;
6658
- exports.loadLanguage = require_toaster.loadLanguage;
6659
- exports.loadLocale = require_toaster.loadLocale;
7180
+ exports.loadLocale = require_filter_builder.loadLocale;
6660
7181
  exports.localeLabel = localeLabel;
6661
7182
  Object.defineProperty(exports, "modeForSurface", {
6662
7183
  enumerable: true,
@@ -6669,8 +7190,7 @@ exports.registerIcons = require_check_confirm_dialog.registerIcons;
6669
7190
  exports.relationLinkClassName = require_search_access.relationLinkClassName;
6670
7191
  exports.resolveNavIcon = resolveNavIcon;
6671
7192
  exports.resolveUpdater = require_place_node.resolveUpdater;
6672
- exports.saveLanguage = require_toaster.saveLanguage;
6673
- exports.saveLocale = require_toaster.saveLocale;
7193
+ exports.saveLocale = require_filter_builder.saveLocale;
6674
7194
  exports.shadcnBlockImplementations = require_place_node.shadcnBlockImplementations;
6675
7195
  exports.shadcnFieldImplementations = shadcnFieldImplementations;
6676
7196
  exports.shadcnPresentationHosts = shadcnPresentationHosts;
@@ -6701,6 +7221,7 @@ exports.useNavVisible = require_resource_page_router.useNavVisible;
6701
7221
  exports.useOptionalSidebar = useOptionalSidebar;
6702
7222
  exports.usePaletteState = require_place_node.usePaletteState;
6703
7223
  exports.usePresentationCopy = usePresentationCopy;
7224
+ exports.useRelationPicker = useRelationPicker;
6704
7225
  exports.useShell = require_place_node.useShell;
6705
7226
  exports.useSidebar = useSidebar;
6706
7227
  exports.useTheme = require_use_theme.useTheme;