@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
@@ -1,5 +1,5 @@
1
- import { at as RELATED_GRID_CLASS } from "./place-node--GdsP688.js";
2
- import { i as useProjectedRows, n as RowContent, r as RowOpener, t as ITEM_LAYER_CLASS } from "./related-rows-B4levHcR.js";
1
+ import { lt as RELATED_GRID_CLASS } from "./place-node-NraNYKPx.js";
2
+ import { i as useProjectedRows, n as RowContent, r as RowOpener, t as ITEM_LAYER_CLASS } from "./related-rows-o0_t-Yce.js";
3
3
  import { useTestIds } from "@burojs/react";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
5
  //#region src/blocks/related-list-cards.tsx
@@ -39,4 +39,4 @@ function RelatedCards({ resource, placementKey, rows, item, columns, rowQuick, r
39
39
  //#endregion
40
40
  export { RelatedCards };
41
41
 
42
- //# sourceMappingURL=related-list-cards-B6x9HQQp.js.map
42
+ //# sourceMappingURL=related-list-cards-BWZ9GfOG.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"related-list-cards-B6x9HQQp.js","names":[],"sources":["../src/blocks/related-list-cards.tsx"],"sourcesContent":["'use client';\nimport { useTestIds } from '@burojs/react';\nimport type { ReactElement } from 'react';\nimport {\n ITEM_LAYER_CLASS,\n type RelatedRowsProps,\n RowContent,\n RowOpener,\n useProjectedRows,\n} from './related-rows.js';\nimport { RELATED_GRID_CLASS } from './related-skeletons.js';\n\n/** The grid the cards sit in; `RelatedCardsSkeleton` shares it. */\nconst GRID_CLASS = RELATED_GRID_CLASS;\n\n/** A related list as cards (`view: 'cards'`, P6 3.13): one `<article>` per row. */\nexport function RelatedCards({\n resource,\n placementKey,\n rows,\n item,\n columns,\n rowQuick,\n rowHref,\n}: RelatedRowsProps): ReactElement {\n const ids = useTestIds();\n const { project, drawn, title } = useProjectedRows(resource, rows, item);\n return (\n <div className=\"@container\">\n <ul className={GRID_CLASS}>\n {rows.map((row) => (\n <li key={row.id} className=\"min-w-0\">\n <article\n data-testid={ids.relatedCard(placementKey, String(row.id))}\n className=\"relative h-full rounded-lg border bg-card p-3 text-card-foreground\"\n >\n <RowOpener title={title(row)} href={rowHref?.(row)} quick={rowQuick?.(row) ?? null} />\n <div className={ITEM_LAYER_CLASS}>\n <RowContent\n resource={resource}\n raw={row}\n row={project(row)}\n item={item}\n drawn={drawn}\n columns={columns}\n />\n </div>\n </article>\n </li>\n ))}\n </ul>\n </div>\n );\n}\n"],"mappings":";;;;;AAaA,MAAM,aAAa;AAGnB,SAAgB,aAAa,EAC3B,UACA,cACA,MACA,MACA,SACA,UACA,WACiC;CACjC,MAAM,MAAM,WAAW;CACvB,MAAM,EAAE,SAAS,OAAO,UAAU,iBAAiB,UAAU,MAAM,IAAI;CACvE,OACE,IAAC,OAAD;EAAK,WAAU;EACb,UAAA,IAAC,MAAD;GAAI,WAAW;GACZ,UAAA,KAAK,KAAK,QACT,IAAC,MAAD;IAAiB,WAAU;IACzB,UAAA,KAAC,WAAD;KACE,eAAa,IAAI,YAAY,cAAc,OAAO,IAAI,EAAE,CAAC;KACzD,WAAU;KAFZ,UAAA,CAIE,IAAC,WAAD;MAAW,OAAO,MAAM,GAAG;MAAG,MAAM,UAAU,GAAG;MAAG,OAAO,WAAW,GAAG,KAAK;KAAO,CAAA,GACrF,IAAC,OAAD;MAAK,WAAW;MACd,UAAA,IAAC,YAAD;OACY;OACV,KAAK;OACL,KAAK,QAAQ,GAAG;OACV;OACC;OACE;MACV,CAAA;KACE,CAAA,CACE;;GACP,GAjBK,IAAI,EAiBT,CACL;EACC,CAAA;CACD,CAAA;AAET"}
1
+ {"version":3,"file":"related-list-cards-BWZ9GfOG.js","names":[],"sources":["../src/blocks/related-list-cards.tsx"],"sourcesContent":["'use client';\nimport { useTestIds } from '@burojs/react';\nimport type { ReactElement } from 'react';\nimport {\n ITEM_LAYER_CLASS,\n type RelatedRowsProps,\n RowContent,\n RowOpener,\n useProjectedRows,\n} from './related-rows.js';\nimport { RELATED_GRID_CLASS } from './related-skeletons.js';\n\n/** The grid the cards sit in; `RelatedCardsSkeleton` shares it. */\nconst GRID_CLASS = RELATED_GRID_CLASS;\n\n/** A related list as cards (`view: 'cards'`, P6 3.13): one `<article>` per row. */\nexport function RelatedCards({\n resource,\n placementKey,\n rows,\n item,\n columns,\n rowQuick,\n rowHref,\n}: RelatedRowsProps): ReactElement {\n const ids = useTestIds();\n const { project, drawn, title } = useProjectedRows(resource, rows, item);\n return (\n <div className=\"@container\">\n <ul className={GRID_CLASS}>\n {rows.map((row) => (\n <li key={row.id} className=\"min-w-0\">\n <article\n data-testid={ids.relatedCard(placementKey, String(row.id))}\n className=\"relative h-full rounded-lg border bg-card p-3 text-card-foreground\"\n >\n <RowOpener title={title(row)} href={rowHref?.(row)} quick={rowQuick?.(row) ?? null} />\n <div className={ITEM_LAYER_CLASS}>\n <RowContent\n resource={resource}\n raw={row}\n row={project(row)}\n item={item}\n drawn={drawn}\n columns={columns}\n />\n </div>\n </article>\n </li>\n ))}\n </ul>\n </div>\n );\n}\n"],"mappings":";;;;;AAaA,MAAM,aAAa;AAGnB,SAAgB,aAAa,EAC3B,UACA,cACA,MACA,MACA,SACA,UACA,WACiC;CACjC,MAAM,MAAM,WAAW;CACvB,MAAM,EAAE,SAAS,OAAO,UAAU,iBAAiB,UAAU,MAAM,IAAI;CACvE,OACE,IAAC,OAAD;EAAK,WAAU;EACb,UAAA,IAAC,MAAD;GAAI,WAAW;GACZ,UAAA,KAAK,KAAK,QACT,IAAC,MAAD;IAAiB,WAAU;IACzB,UAAA,KAAC,WAAD;KACE,eAAa,IAAI,YAAY,cAAc,OAAO,IAAI,EAAE,CAAC;KACzD,WAAU;KAFZ,UAAA,CAIE,IAAC,WAAD;MAAW,OAAO,MAAM,GAAG;MAAG,MAAM,UAAU,GAAG;MAAG,OAAO,WAAW,GAAG,KAAK;KAAO,CAAA,GACrF,IAAC,OAAD;MAAK,WAAW;MACd,UAAA,IAAC,YAAD;OACY;OACV,KAAK;OACL,KAAK,QAAQ,GAAG;OACV;OACC;OACE;MACV,CAAA;KACE,CAAA,CACE;;GACP,GAjBK,IAAI,EAiBT,CACL;EACC,CAAA;CACD,CAAA;AAET"}
@@ -1,5 +1,5 @@
1
- const require_place_node = require("./place-node-SIp4XYQH.cjs");
2
- const require_related_rows = require("./related-rows-zh5f_4QR.cjs");
1
+ const require_place_node = require("./place-node-C5SmIAYU.cjs");
2
+ const require_related_rows = require("./related-rows-ea43qhhy.cjs");
3
3
  let _burojs_react = require("@burojs/react");
4
4
  let react_jsx_runtime = require("react/jsx-runtime");
5
5
  //#region src/blocks/related-list-cards.tsx
@@ -39,4 +39,4 @@ function RelatedCards({ resource, placementKey, rows, item, columns, rowQuick, r
39
39
  //#endregion
40
40
  exports.RelatedCards = RelatedCards;
41
41
 
42
- //# sourceMappingURL=related-list-cards-nxuODlIA.cjs.map
42
+ //# sourceMappingURL=related-list-cards-CFq3meUn.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"related-list-cards-nxuODlIA.cjs","names":["RELATED_GRID_CLASS","useTestIds","useProjectedRows","RowOpener","ITEM_LAYER_CLASS","RowContent"],"sources":["../src/blocks/related-list-cards.tsx"],"sourcesContent":["'use client';\nimport { useTestIds } from '@burojs/react';\nimport type { ReactElement } from 'react';\nimport {\n ITEM_LAYER_CLASS,\n type RelatedRowsProps,\n RowContent,\n RowOpener,\n useProjectedRows,\n} from './related-rows.js';\nimport { RELATED_GRID_CLASS } from './related-skeletons.js';\n\n/** The grid the cards sit in; `RelatedCardsSkeleton` shares it. */\nconst GRID_CLASS = RELATED_GRID_CLASS;\n\n/** A related list as cards (`view: 'cards'`, P6 3.13): one `<article>` per row. */\nexport function RelatedCards({\n resource,\n placementKey,\n rows,\n item,\n columns,\n rowQuick,\n rowHref,\n}: RelatedRowsProps): ReactElement {\n const ids = useTestIds();\n const { project, drawn, title } = useProjectedRows(resource, rows, item);\n return (\n <div className=\"@container\">\n <ul className={GRID_CLASS}>\n {rows.map((row) => (\n <li key={row.id} className=\"min-w-0\">\n <article\n data-testid={ids.relatedCard(placementKey, String(row.id))}\n className=\"relative h-full rounded-lg border bg-card p-3 text-card-foreground\"\n >\n <RowOpener title={title(row)} href={rowHref?.(row)} quick={rowQuick?.(row) ?? null} />\n <div className={ITEM_LAYER_CLASS}>\n <RowContent\n resource={resource}\n raw={row}\n row={project(row)}\n item={item}\n drawn={drawn}\n columns={columns}\n />\n </div>\n </article>\n </li>\n ))}\n </ul>\n </div>\n );\n}\n"],"mappings":";;;;;AAaA,MAAM,aAAaA,mBAAAA;AAGnB,SAAgB,aAAa,EAC3B,UACA,cACA,MACA,MACA,SACA,UACA,WACiC;CACjC,MAAM,OAAA,GAAMC,cAAAA,WAAAA,CAAW;CACvB,MAAM,EAAE,SAAS,OAAO,UAAUC,qBAAAA,iBAAiB,UAAU,MAAM,IAAI;CACvE,QACE,GAAA,kBAAA,IAAA,CAAC,OAAD;EAAK,WAAU;EACb,WAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;GAAI,WAAW;GACZ,UAAA,KAAK,KAAK,SACT,GAAA,kBAAA,IAAA,CAAC,MAAD;IAAiB,WAAU;IACzB,WAAA,GAAA,kBAAA,KAAA,CAAC,WAAD;KACE,eAAa,IAAI,YAAY,cAAc,OAAO,IAAI,EAAE,CAAC;KACzD,WAAU;KAFZ,UAAA,EAIE,GAAA,kBAAA,IAAA,CAACC,qBAAAA,WAAD;MAAW,OAAO,MAAM,GAAG;MAAG,MAAM,UAAU,GAAG;MAAG,OAAO,WAAW,GAAG,KAAK;KAAO,CAAA,IACrF,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAWC,qBAAAA;MACd,WAAA,GAAA,kBAAA,IAAA,CAACC,qBAAAA,YAAD;OACY;OACV,KAAK;OACL,KAAK,QAAQ,GAAG;OACV;OACC;OACE;MACV,CAAA;KACE,CAAA,CACE;;GACP,GAjBK,IAAI,EAiBT,CACL;EACC,CAAA;CACD,CAAA;AAET"}
1
+ {"version":3,"file":"related-list-cards-CFq3meUn.cjs","names":["RELATED_GRID_CLASS","useTestIds","useProjectedRows","RowOpener","ITEM_LAYER_CLASS","RowContent"],"sources":["../src/blocks/related-list-cards.tsx"],"sourcesContent":["'use client';\nimport { useTestIds } from '@burojs/react';\nimport type { ReactElement } from 'react';\nimport {\n ITEM_LAYER_CLASS,\n type RelatedRowsProps,\n RowContent,\n RowOpener,\n useProjectedRows,\n} from './related-rows.js';\nimport { RELATED_GRID_CLASS } from './related-skeletons.js';\n\n/** The grid the cards sit in; `RelatedCardsSkeleton` shares it. */\nconst GRID_CLASS = RELATED_GRID_CLASS;\n\n/** A related list as cards (`view: 'cards'`, P6 3.13): one `<article>` per row. */\nexport function RelatedCards({\n resource,\n placementKey,\n rows,\n item,\n columns,\n rowQuick,\n rowHref,\n}: RelatedRowsProps): ReactElement {\n const ids = useTestIds();\n const { project, drawn, title } = useProjectedRows(resource, rows, item);\n return (\n <div className=\"@container\">\n <ul className={GRID_CLASS}>\n {rows.map((row) => (\n <li key={row.id} className=\"min-w-0\">\n <article\n data-testid={ids.relatedCard(placementKey, String(row.id))}\n className=\"relative h-full rounded-lg border bg-card p-3 text-card-foreground\"\n >\n <RowOpener title={title(row)} href={rowHref?.(row)} quick={rowQuick?.(row) ?? null} />\n <div className={ITEM_LAYER_CLASS}>\n <RowContent\n resource={resource}\n raw={row}\n row={project(row)}\n item={item}\n drawn={drawn}\n columns={columns}\n />\n </div>\n </article>\n </li>\n ))}\n </ul>\n </div>\n );\n}\n"],"mappings":";;;;;AAaA,MAAM,aAAaA,mBAAAA;AAGnB,SAAgB,aAAa,EAC3B,UACA,cACA,MACA,MACA,SACA,UACA,WACiC;CACjC,MAAM,OAAA,GAAMC,cAAAA,WAAAA,CAAW;CACvB,MAAM,EAAE,SAAS,OAAO,UAAUC,qBAAAA,iBAAiB,UAAU,MAAM,IAAI;CACvE,QACE,GAAA,kBAAA,IAAA,CAAC,OAAD;EAAK,WAAU;EACb,WAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;GAAI,WAAW;GACZ,UAAA,KAAK,KAAK,SACT,GAAA,kBAAA,IAAA,CAAC,MAAD;IAAiB,WAAU;IACzB,WAAA,GAAA,kBAAA,KAAA,CAAC,WAAD;KACE,eAAa,IAAI,YAAY,cAAc,OAAO,IAAI,EAAE,CAAC;KACzD,WAAU;KAFZ,UAAA,EAIE,GAAA,kBAAA,IAAA,CAACC,qBAAAA,WAAD;MAAW,OAAO,MAAM,GAAG;MAAG,MAAM,UAAU,GAAG;MAAG,OAAO,WAAW,GAAG,KAAK;KAAO,CAAA,IACrF,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAWC,qBAAAA;MACd,WAAA,GAAA,kBAAA,IAAA,CAACC,qBAAAA,YAAD;OACY;OACV,KAAK;OACL,KAAK,QAAQ,GAAG;OACV;OACC;OACE;MACV,CAAA;KACE,CAAA,CACE;;GACP,GAjBK,IAAI,EAiBT,CACL;EACC,CAAA;CACD,CAAA;AAET"}
@@ -1,4 +1,4 @@
1
- const require_related_rows = require("./related-rows-zh5f_4QR.cjs");
1
+ const require_related_rows = require("./related-rows-ea43qhhy.cjs");
2
2
  let _burojs_react = require("@burojs/react");
3
3
  let react = require("react");
4
4
  let react_jsx_runtime = require("react/jsx-runtime");
@@ -139,4 +139,4 @@ function RelatedTimeline({ resource, placementKey, rows, item, columns, rowQuick
139
139
  //#endregion
140
140
  exports.RelatedTimeline = RelatedTimeline;
141
141
 
142
- //# sourceMappingURL=related-list-timeline-BYJKEbmA.cjs.map
142
+ //# sourceMappingURL=related-list-timeline-CCzl71aA.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"related-list-timeline-BYJKEbmA.cjs","names":["useTestIds","useApp","useOptionalT","useOptionalLocale","useProjectedRows","useMemo","RowOpener","ITEM_LAYER_CLASS","RowContent"],"sources":["../src/blocks/related-list-timeline.tsx"],"sourcesContent":["'use client';\nimport { useApp, useOptionalLocale, useOptionalT, useTestIds } from '@burojs/react';\nimport { type ReactElement, useMemo } from 'react';\nimport {\n ITEM_LAYER_CLASS,\n type ListRow,\n type RelatedRowsProps,\n RowContent,\n RowOpener,\n useProjectedRows,\n} from './related-rows.js';\n\n/** The date of a row's axis value, else undefined. A date-only value is the local day it names. */\nfunction dayOf(value: unknown): { readonly date: Date; readonly timed: boolean } | undefined {\n if (typeof value === 'string') {\n const only = /^(\\d{4})-(\\d{2})-(\\d{2})$/u.exec(value);\n if (only !== null)\n return {\n date: new Date(Number(only[1]), Number(only[2]) - 1, Number(only[3])),\n timed: false,\n };\n }\n if (typeof value !== 'string' && typeof value !== 'number' && !(value instanceof Date))\n return undefined;\n const date = new Date(value);\n return Number.isNaN(date.getTime()) ? undefined : { date, timed: true };\n}\n\nconst dayKey = (date: Date) => `${date.getFullYear()}-${date.getMonth()}-${date.getDate()}`;\n\ninterface Group {\n readonly key: string;\n /** The day the group names; undefined for the undated group. */\n readonly heading: Date | undefined;\n readonly entries: {\n readonly row: ListRow;\n readonly at: Date | undefined;\n readonly timed: boolean;\n }[];\n}\n\n/**\n * A related list as a timeline (`view: 'timeline'`, P6 3.13): one column grouped by the local\n * day of the target's `views.list.defaultSort[0].field`, headings formatted by the active locale,\n * entries in the list's own (declared) order, each the time and then the item. There is no sort\n * control: the axis is the declared sort.\n *\n * The axis is read from the projected row, as every other field is: a viewer who may not see it\n * gets no day and no time. A row whose axis reads nothing (hidden, empty or unparseable) is kept\n * in one trailing \"Undated\" group, so the entries drawn are the rows the list counts.\n */\nexport function RelatedTimeline({\n resource,\n placementKey,\n rows,\n item,\n columns,\n rowQuick,\n rowHref,\n}: RelatedRowsProps): ReactElement {\n const ids = useTestIds();\n const app = useApp();\n const t = useOptionalT();\n const locale = useOptionalLocale();\n const { project, drawn, title } = useProjectedRows(resource, rows, item);\n const axis = (\n app.registry.get(resource) as\n | {\n readonly views?: {\n readonly list?: { readonly defaultSort?: readonly { readonly field: string }[] };\n };\n }\n | undefined\n )?.views?.list?.defaultSort?.[0]?.field;\n const formats = useMemo(() => {\n try {\n return {\n day: new Intl.DateTimeFormat(locale, { dateStyle: 'full' }),\n time: new Intl.DateTimeFormat(locale, { timeStyle: 'short' }),\n };\n } catch {\n return {\n day: new Intl.DateTimeFormat(undefined, { dateStyle: 'full' }),\n time: new Intl.DateTimeFormat(undefined, { timeStyle: 'short' }),\n };\n }\n }, [locale]);\n const groups = useMemo(() => {\n const out: Group[] = [];\n if (axis === undefined) return out;\n const undated: Group['entries'] = [];\n for (const row of rows) {\n const day = dayOf(project(row)[axis]);\n if (day === undefined) {\n undated.push({ row, at: undefined, timed: false });\n continue;\n }\n const key = dayKey(day.date);\n let group = out.find((entry) => entry.key === key);\n if (group === undefined) {\n group = { key, heading: day.date, entries: [] };\n out.push(group);\n }\n group.entries.push({ row, at: day.date, timed: day.timed });\n }\n if (undated.length > 0) out.push({ key: 'undated', heading: undefined, entries: undated });\n return out;\n }, [rows, axis, project]);\n const headingOf = (group: Group): string =>\n group.heading === undefined\n ? t('timeline.undated', { defaultValue: 'Undated' })\n : formats.day.format(group.heading);\n if (groups.length === 0)\n return (\n <p className=\"text-sm text-muted-foreground\">\n {t('timeline.empty', { defaultValue: 'No entries' })}\n </p>\n );\n // One rail down the whole list (a border per day broke at every heading), a dot per entry on it;\n // the day headings are the axis' labels, small and muted, and the entries carry the weight.\n return (\n <div className=\"relative flex flex-col gap-4 pl-5\">\n <span\n data-buro-timeline-rail=\"\"\n aria-hidden=\"true\"\n className=\"absolute top-1 bottom-1 left-2 w-px bg-border\"\n />\n {groups.map((group) => (\n <section key={group.key} aria-label={headingOf(group)} className=\"flex flex-col gap-1\">\n <h3 className=\"text-xs text-muted-foreground\">{headingOf(group)}</h3>\n <ol className=\"flex flex-col\">\n {group.entries.map(({ row, at, timed }) => (\n <li\n key={row.id}\n data-testid={ids.timelineEntry(placementKey, String(row.id))}\n className=\"relative flex min-w-0 items-baseline gap-3 rounded-md py-1.5 pr-2\"\n >\n <span\n data-buro-timeline-dot=\"\"\n aria-hidden=\"true\"\n className=\"absolute top-2.5 -left-[1.1rem] size-3 rounded-full border-2 border-background bg-muted-foreground\"\n />\n <RowOpener\n title={title(row)}\n href={rowHref?.(row)}\n quick={rowQuick?.(row) ?? null}\n />\n {timed && at !== undefined ? (\n <time\n dateTime={at.toISOString()}\n className=\"w-16 shrink-0 whitespace-nowrap text-xs tabular-nums text-muted-foreground\"\n >\n {formats.time.format(at)}\n </time>\n ) : null}\n <div className={`${ITEM_LAYER_CLASS} min-w-0 flex-1`}>\n <RowContent\n resource={resource}\n raw={row}\n row={project(row)}\n item={item}\n drawn={drawn}\n columns={columns}\n variant=\"entry\"\n />\n </div>\n </li>\n ))}\n </ol>\n </section>\n ))}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"related-list-timeline-CCzl71aA.cjs","names":["useTestIds","useApp","useOptionalT","useOptionalLocale","useProjectedRows","useMemo","RowOpener","ITEM_LAYER_CLASS","RowContent"],"sources":["../src/blocks/related-list-timeline.tsx"],"sourcesContent":["'use client';\nimport { useApp, useOptionalLocale, useOptionalT, useTestIds } from '@burojs/react';\nimport { type ReactElement, useMemo } from 'react';\nimport {\n ITEM_LAYER_CLASS,\n type ListRow,\n type RelatedRowsProps,\n RowContent,\n RowOpener,\n useProjectedRows,\n} from './related-rows.js';\n\n/** The date of a row's axis value, else undefined. A date-only value is the local day it names. */\nfunction dayOf(value: unknown): { readonly date: Date; readonly timed: boolean } | undefined {\n if (typeof value === 'string') {\n const only = /^(\\d{4})-(\\d{2})-(\\d{2})$/u.exec(value);\n if (only !== null)\n return {\n date: new Date(Number(only[1]), Number(only[2]) - 1, Number(only[3])),\n timed: false,\n };\n }\n if (typeof value !== 'string' && typeof value !== 'number' && !(value instanceof Date))\n return undefined;\n const date = new Date(value);\n return Number.isNaN(date.getTime()) ? undefined : { date, timed: true };\n}\n\nconst dayKey = (date: Date) => `${date.getFullYear()}-${date.getMonth()}-${date.getDate()}`;\n\ninterface Group {\n readonly key: string;\n /** The day the group names; undefined for the undated group. */\n readonly heading: Date | undefined;\n readonly entries: {\n readonly row: ListRow;\n readonly at: Date | undefined;\n readonly timed: boolean;\n }[];\n}\n\n/**\n * A related list as a timeline (`view: 'timeline'`, P6 3.13): one column grouped by the local\n * day of the target's `views.list.defaultSort[0].field`, headings formatted by the active locale,\n * entries in the list's own (declared) order, each the time and then the item. There is no sort\n * control: the axis is the declared sort.\n *\n * The axis is read from the projected row, as every other field is: a viewer who may not see it\n * gets no day and no time. A row whose axis reads nothing (hidden, empty or unparseable) is kept\n * in one trailing \"Undated\" group, so the entries drawn are the rows the list counts.\n */\nexport function RelatedTimeline({\n resource,\n placementKey,\n rows,\n item,\n columns,\n rowQuick,\n rowHref,\n}: RelatedRowsProps): ReactElement {\n const ids = useTestIds();\n const app = useApp();\n const t = useOptionalT();\n const locale = useOptionalLocale();\n const { project, drawn, title } = useProjectedRows(resource, rows, item);\n const axis = (\n app.registry.get(resource) as\n | {\n readonly views?: {\n readonly list?: { readonly defaultSort?: readonly { readonly field: string }[] };\n };\n }\n | undefined\n )?.views?.list?.defaultSort?.[0]?.field;\n const formats = useMemo(() => {\n try {\n return {\n day: new Intl.DateTimeFormat(locale, { dateStyle: 'full' }),\n time: new Intl.DateTimeFormat(locale, { timeStyle: 'short' }),\n };\n } catch {\n return {\n day: new Intl.DateTimeFormat(undefined, { dateStyle: 'full' }),\n time: new Intl.DateTimeFormat(undefined, { timeStyle: 'short' }),\n };\n }\n }, [locale]);\n const groups = useMemo(() => {\n const out: Group[] = [];\n if (axis === undefined) return out;\n const undated: Group['entries'] = [];\n for (const row of rows) {\n const day = dayOf(project(row)[axis]);\n if (day === undefined) {\n undated.push({ row, at: undefined, timed: false });\n continue;\n }\n const key = dayKey(day.date);\n let group = out.find((entry) => entry.key === key);\n if (group === undefined) {\n group = { key, heading: day.date, entries: [] };\n out.push(group);\n }\n group.entries.push({ row, at: day.date, timed: day.timed });\n }\n if (undated.length > 0) out.push({ key: 'undated', heading: undefined, entries: undated });\n return out;\n }, [rows, axis, project]);\n const headingOf = (group: Group): string =>\n group.heading === undefined\n ? t('timeline.undated', { defaultValue: 'Undated' })\n : formats.day.format(group.heading);\n if (groups.length === 0)\n return (\n <p className=\"text-sm text-muted-foreground\">\n {t('timeline.empty', { defaultValue: 'No entries' })}\n </p>\n );\n // One rail down the whole list (a border per day broke at every heading), a dot per entry on it;\n // the day headings are the axis' labels, small and muted, and the entries carry the weight.\n return (\n <div className=\"relative flex flex-col gap-4 pl-5\">\n <span\n data-buro-timeline-rail=\"\"\n aria-hidden=\"true\"\n className=\"absolute top-1 bottom-1 left-2 w-px bg-border\"\n />\n {groups.map((group) => (\n <section key={group.key} aria-label={headingOf(group)} className=\"flex flex-col gap-1\">\n <h3 className=\"text-xs text-muted-foreground\">{headingOf(group)}</h3>\n <ol className=\"flex flex-col\">\n {group.entries.map(({ row, at, timed }) => (\n <li\n key={row.id}\n data-testid={ids.timelineEntry(placementKey, String(row.id))}\n className=\"relative flex min-w-0 items-baseline gap-3 rounded-md py-1.5 pr-2\"\n >\n <span\n data-buro-timeline-dot=\"\"\n aria-hidden=\"true\"\n className=\"absolute top-2.5 -left-[1.1rem] size-3 rounded-full border-2 border-background bg-muted-foreground\"\n />\n <RowOpener\n title={title(row)}\n href={rowHref?.(row)}\n quick={rowQuick?.(row) ?? null}\n />\n {timed && at !== undefined ? (\n <time\n dateTime={at.toISOString()}\n className=\"w-16 shrink-0 whitespace-nowrap text-xs tabular-nums text-muted-foreground\"\n >\n {formats.time.format(at)}\n </time>\n ) : null}\n <div className={`${ITEM_LAYER_CLASS} min-w-0 flex-1`}>\n <RowContent\n resource={resource}\n raw={row}\n row={project(row)}\n item={item}\n drawn={drawn}\n columns={columns}\n variant=\"entry\"\n />\n </div>\n </li>\n ))}\n </ol>\n </section>\n ))}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { i as useProjectedRows, n as RowContent, r as RowOpener, t as ITEM_LAYER_CLASS } from "./related-rows-B4levHcR.js";
1
+ import { i as useProjectedRows, n as RowContent, r as RowOpener, t as ITEM_LAYER_CLASS } from "./related-rows-o0_t-Yce.js";
2
2
  import { useApp, useOptionalLocale, useOptionalT, useTestIds } from "@burojs/react";
3
3
  import { useMemo } from "react";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -139,4 +139,4 @@ function RelatedTimeline({ resource, placementKey, rows, item, columns, rowQuick
139
139
  //#endregion
140
140
  export { RelatedTimeline };
141
141
 
142
- //# sourceMappingURL=related-list-timeline-DEdfd-rr.js.map
142
+ //# sourceMappingURL=related-list-timeline-yrPsjA3F.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"related-list-timeline-DEdfd-rr.js","names":[],"sources":["../src/blocks/related-list-timeline.tsx"],"sourcesContent":["'use client';\nimport { useApp, useOptionalLocale, useOptionalT, useTestIds } from '@burojs/react';\nimport { type ReactElement, useMemo } from 'react';\nimport {\n ITEM_LAYER_CLASS,\n type ListRow,\n type RelatedRowsProps,\n RowContent,\n RowOpener,\n useProjectedRows,\n} from './related-rows.js';\n\n/** The date of a row's axis value, else undefined. A date-only value is the local day it names. */\nfunction dayOf(value: unknown): { readonly date: Date; readonly timed: boolean } | undefined {\n if (typeof value === 'string') {\n const only = /^(\\d{4})-(\\d{2})-(\\d{2})$/u.exec(value);\n if (only !== null)\n return {\n date: new Date(Number(only[1]), Number(only[2]) - 1, Number(only[3])),\n timed: false,\n };\n }\n if (typeof value !== 'string' && typeof value !== 'number' && !(value instanceof Date))\n return undefined;\n const date = new Date(value);\n return Number.isNaN(date.getTime()) ? undefined : { date, timed: true };\n}\n\nconst dayKey = (date: Date) => `${date.getFullYear()}-${date.getMonth()}-${date.getDate()}`;\n\ninterface Group {\n readonly key: string;\n /** The day the group names; undefined for the undated group. */\n readonly heading: Date | undefined;\n readonly entries: {\n readonly row: ListRow;\n readonly at: Date | undefined;\n readonly timed: boolean;\n }[];\n}\n\n/**\n * A related list as a timeline (`view: 'timeline'`, P6 3.13): one column grouped by the local\n * day of the target's `views.list.defaultSort[0].field`, headings formatted by the active locale,\n * entries in the list's own (declared) order, each the time and then the item. There is no sort\n * control: the axis is the declared sort.\n *\n * The axis is read from the projected row, as every other field is: a viewer who may not see it\n * gets no day and no time. A row whose axis reads nothing (hidden, empty or unparseable) is kept\n * in one trailing \"Undated\" group, so the entries drawn are the rows the list counts.\n */\nexport function RelatedTimeline({\n resource,\n placementKey,\n rows,\n item,\n columns,\n rowQuick,\n rowHref,\n}: RelatedRowsProps): ReactElement {\n const ids = useTestIds();\n const app = useApp();\n const t = useOptionalT();\n const locale = useOptionalLocale();\n const { project, drawn, title } = useProjectedRows(resource, rows, item);\n const axis = (\n app.registry.get(resource) as\n | {\n readonly views?: {\n readonly list?: { readonly defaultSort?: readonly { readonly field: string }[] };\n };\n }\n | undefined\n )?.views?.list?.defaultSort?.[0]?.field;\n const formats = useMemo(() => {\n try {\n return {\n day: new Intl.DateTimeFormat(locale, { dateStyle: 'full' }),\n time: new Intl.DateTimeFormat(locale, { timeStyle: 'short' }),\n };\n } catch {\n return {\n day: new Intl.DateTimeFormat(undefined, { dateStyle: 'full' }),\n time: new Intl.DateTimeFormat(undefined, { timeStyle: 'short' }),\n };\n }\n }, [locale]);\n const groups = useMemo(() => {\n const out: Group[] = [];\n if (axis === undefined) return out;\n const undated: Group['entries'] = [];\n for (const row of rows) {\n const day = dayOf(project(row)[axis]);\n if (day === undefined) {\n undated.push({ row, at: undefined, timed: false });\n continue;\n }\n const key = dayKey(day.date);\n let group = out.find((entry) => entry.key === key);\n if (group === undefined) {\n group = { key, heading: day.date, entries: [] };\n out.push(group);\n }\n group.entries.push({ row, at: day.date, timed: day.timed });\n }\n if (undated.length > 0) out.push({ key: 'undated', heading: undefined, entries: undated });\n return out;\n }, [rows, axis, project]);\n const headingOf = (group: Group): string =>\n group.heading === undefined\n ? t('timeline.undated', { defaultValue: 'Undated' })\n : formats.day.format(group.heading);\n if (groups.length === 0)\n return (\n <p className=\"text-sm text-muted-foreground\">\n {t('timeline.empty', { defaultValue: 'No entries' })}\n </p>\n );\n // One rail down the whole list (a border per day broke at every heading), a dot per entry on it;\n // the day headings are the axis' labels, small and muted, and the entries carry the weight.\n return (\n <div className=\"relative flex flex-col gap-4 pl-5\">\n <span\n data-buro-timeline-rail=\"\"\n aria-hidden=\"true\"\n className=\"absolute top-1 bottom-1 left-2 w-px bg-border\"\n />\n {groups.map((group) => (\n <section key={group.key} aria-label={headingOf(group)} className=\"flex flex-col gap-1\">\n <h3 className=\"text-xs text-muted-foreground\">{headingOf(group)}</h3>\n <ol className=\"flex flex-col\">\n {group.entries.map(({ row, at, timed }) => (\n <li\n key={row.id}\n data-testid={ids.timelineEntry(placementKey, String(row.id))}\n className=\"relative flex min-w-0 items-baseline gap-3 rounded-md py-1.5 pr-2\"\n >\n <span\n data-buro-timeline-dot=\"\"\n aria-hidden=\"true\"\n className=\"absolute top-2.5 -left-[1.1rem] size-3 rounded-full border-2 border-background bg-muted-foreground\"\n />\n <RowOpener\n title={title(row)}\n href={rowHref?.(row)}\n quick={rowQuick?.(row) ?? null}\n />\n {timed && at !== undefined ? (\n <time\n dateTime={at.toISOString()}\n className=\"w-16 shrink-0 whitespace-nowrap text-xs tabular-nums text-muted-foreground\"\n >\n {formats.time.format(at)}\n </time>\n ) : null}\n <div className={`${ITEM_LAYER_CLASS} min-w-0 flex-1`}>\n <RowContent\n resource={resource}\n raw={row}\n row={project(row)}\n item={item}\n drawn={drawn}\n columns={columns}\n variant=\"entry\"\n />\n </div>\n </li>\n ))}\n </ol>\n </section>\n ))}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"related-list-timeline-yrPsjA3F.js","names":[],"sources":["../src/blocks/related-list-timeline.tsx"],"sourcesContent":["'use client';\nimport { useApp, useOptionalLocale, useOptionalT, useTestIds } from '@burojs/react';\nimport { type ReactElement, useMemo } from 'react';\nimport {\n ITEM_LAYER_CLASS,\n type ListRow,\n type RelatedRowsProps,\n RowContent,\n RowOpener,\n useProjectedRows,\n} from './related-rows.js';\n\n/** The date of a row's axis value, else undefined. A date-only value is the local day it names. */\nfunction dayOf(value: unknown): { readonly date: Date; readonly timed: boolean } | undefined {\n if (typeof value === 'string') {\n const only = /^(\\d{4})-(\\d{2})-(\\d{2})$/u.exec(value);\n if (only !== null)\n return {\n date: new Date(Number(only[1]), Number(only[2]) - 1, Number(only[3])),\n timed: false,\n };\n }\n if (typeof value !== 'string' && typeof value !== 'number' && !(value instanceof Date))\n return undefined;\n const date = new Date(value);\n return Number.isNaN(date.getTime()) ? undefined : { date, timed: true };\n}\n\nconst dayKey = (date: Date) => `${date.getFullYear()}-${date.getMonth()}-${date.getDate()}`;\n\ninterface Group {\n readonly key: string;\n /** The day the group names; undefined for the undated group. */\n readonly heading: Date | undefined;\n readonly entries: {\n readonly row: ListRow;\n readonly at: Date | undefined;\n readonly timed: boolean;\n }[];\n}\n\n/**\n * A related list as a timeline (`view: 'timeline'`, P6 3.13): one column grouped by the local\n * day of the target's `views.list.defaultSort[0].field`, headings formatted by the active locale,\n * entries in the list's own (declared) order, each the time and then the item. There is no sort\n * control: the axis is the declared sort.\n *\n * The axis is read from the projected row, as every other field is: a viewer who may not see it\n * gets no day and no time. A row whose axis reads nothing (hidden, empty or unparseable) is kept\n * in one trailing \"Undated\" group, so the entries drawn are the rows the list counts.\n */\nexport function RelatedTimeline({\n resource,\n placementKey,\n rows,\n item,\n columns,\n rowQuick,\n rowHref,\n}: RelatedRowsProps): ReactElement {\n const ids = useTestIds();\n const app = useApp();\n const t = useOptionalT();\n const locale = useOptionalLocale();\n const { project, drawn, title } = useProjectedRows(resource, rows, item);\n const axis = (\n app.registry.get(resource) as\n | {\n readonly views?: {\n readonly list?: { readonly defaultSort?: readonly { readonly field: string }[] };\n };\n }\n | undefined\n )?.views?.list?.defaultSort?.[0]?.field;\n const formats = useMemo(() => {\n try {\n return {\n day: new Intl.DateTimeFormat(locale, { dateStyle: 'full' }),\n time: new Intl.DateTimeFormat(locale, { timeStyle: 'short' }),\n };\n } catch {\n return {\n day: new Intl.DateTimeFormat(undefined, { dateStyle: 'full' }),\n time: new Intl.DateTimeFormat(undefined, { timeStyle: 'short' }),\n };\n }\n }, [locale]);\n const groups = useMemo(() => {\n const out: Group[] = [];\n if (axis === undefined) return out;\n const undated: Group['entries'] = [];\n for (const row of rows) {\n const day = dayOf(project(row)[axis]);\n if (day === undefined) {\n undated.push({ row, at: undefined, timed: false });\n continue;\n }\n const key = dayKey(day.date);\n let group = out.find((entry) => entry.key === key);\n if (group === undefined) {\n group = { key, heading: day.date, entries: [] };\n out.push(group);\n }\n group.entries.push({ row, at: day.date, timed: day.timed });\n }\n if (undated.length > 0) out.push({ key: 'undated', heading: undefined, entries: undated });\n return out;\n }, [rows, axis, project]);\n const headingOf = (group: Group): string =>\n group.heading === undefined\n ? t('timeline.undated', { defaultValue: 'Undated' })\n : formats.day.format(group.heading);\n if (groups.length === 0)\n return (\n <p className=\"text-sm text-muted-foreground\">\n {t('timeline.empty', { defaultValue: 'No entries' })}\n </p>\n );\n // One rail down the whole list (a border per day broke at every heading), a dot per entry on it;\n // the day headings are the axis' labels, small and muted, and the entries carry the weight.\n return (\n <div className=\"relative flex flex-col gap-4 pl-5\">\n <span\n data-buro-timeline-rail=\"\"\n aria-hidden=\"true\"\n className=\"absolute top-1 bottom-1 left-2 w-px bg-border\"\n />\n {groups.map((group) => (\n <section key={group.key} aria-label={headingOf(group)} className=\"flex flex-col gap-1\">\n <h3 className=\"text-xs text-muted-foreground\">{headingOf(group)}</h3>\n <ol className=\"flex flex-col\">\n {group.entries.map(({ row, at, timed }) => (\n <li\n key={row.id}\n data-testid={ids.timelineEntry(placementKey, String(row.id))}\n className=\"relative flex min-w-0 items-baseline gap-3 rounded-md py-1.5 pr-2\"\n >\n <span\n data-buro-timeline-dot=\"\"\n aria-hidden=\"true\"\n className=\"absolute top-2.5 -left-[1.1rem] size-3 rounded-full border-2 border-background bg-muted-foreground\"\n />\n <RowOpener\n title={title(row)}\n href={rowHref?.(row)}\n quick={rowQuick?.(row) ?? null}\n />\n {timed && at !== undefined ? (\n <time\n dateTime={at.toISOString()}\n className=\"w-16 shrink-0 whitespace-nowrap text-xs tabular-nums text-muted-foreground\"\n >\n {formats.time.format(at)}\n </time>\n ) : null}\n <div className={`${ITEM_LAYER_CLASS} min-w-0 flex-1`}>\n <RowContent\n resource={resource}\n raw={row}\n row={project(row)}\n item={item}\n drawn={drawn}\n columns={columns}\n variant=\"entry\"\n />\n </div>\n </li>\n ))}\n </ol>\n </section>\n ))}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,7 +1,6 @@
1
- const require_toaster = require("./toaster-C7CiYA4Z.cjs");
2
- const require_search_access = require("./search-access-B7G5oR8n.cjs");
3
- const require_place_node = require("./place-node-SIp4XYQH.cjs");
4
- const require_peek_filter = require("./peek-filter-CnqHwTMU.cjs");
1
+ const require_toaster = require("./toaster-Cr51X7bz.cjs");
2
+ const require_search_access = require("./search-access-Dugvttlg.cjs");
3
+ const require_place_node = require("./place-node-C5SmIAYU.cjs");
5
4
  let _burojs_core = require("@burojs/core");
6
5
  let _burojs_react = require("@burojs/react");
7
6
  let react = require("react");
@@ -13,12 +12,12 @@ function DefaultItem({ resource, row, raw, columns, variant = "card" }) {
13
12
  const caps = (0, _burojs_react.useI18nCaps)(resource);
14
13
  const access = useRowAccess(resource)(raw);
15
14
  const viewVisible = useViewVisible(resource);
16
- const fields = def === void 0 ? [] : (columns ?? def.views?.list?.columns ?? Object.keys(def.fields)).filter((name, index, names) => name !== def.displayField && names.indexOf(name) === index && require_peek_filter.peekLeafAllowed(def, name, access, viewVisible));
15
+ const fields = def === void 0 ? [] : (columns ?? def.views?.list?.columns ?? Object.keys(def.fields)).filter((name, index, names) => name !== def.displayField && names.indexOf(name) === index && require_place_node.peekLeafAllowed(def, name, access, viewVisible));
17
16
  const ref = def?.ref ?? {
18
17
  namespace: "default",
19
18
  id: resource
20
19
  };
21
- const definition = (name) => require_peek_filter.peekFieldDefinition(def, name);
20
+ const definition = (name) => require_place_node.peekFieldDefinition(def, name);
22
21
  const value = (name) => (0, react_jsx_runtime.jsx)(require_place_node.ResolvedFieldDisplay, {
23
22
  resource: ref,
24
23
  name,
@@ -56,7 +55,7 @@ function DefaultItem({ resource, row, raw, columns, variant = "card" }) {
56
55
  className: "flex min-w-0 items-baseline gap-2 text-sm",
57
56
  children: [(0, react_jsx_runtime.jsx)("dt", {
58
57
  className: "w-24 shrink-0 truncate text-xs text-muted-foreground",
59
- children: (0, _burojs_core.resolveFieldLabel)(caps, name, definition(name)?.label)
58
+ children: (0, _burojs_core.resolveFieldLabel)(caps, name, (0, _burojs_core.declaredText)("field", definition(name), "label"))
60
59
  }), (0, react_jsx_runtime.jsx)("dd", {
61
60
  className: "min-w-0 break-words",
62
61
  children: value(name)
@@ -67,7 +66,7 @@ function DefaultItem({ resource, row, raw, columns, variant = "card" }) {
67
66
  "data-buro-item-trailing": "",
68
67
  className: "flex shrink-0 flex-col items-end gap-1 border-l pl-3 text-sm tabular-nums",
69
68
  children: numbers.map((name) => (0, react_jsx_runtime.jsx)("span", {
70
- title: (0, _burojs_core.resolveFieldLabel)(caps, name, definition(name)?.label),
69
+ title: (0, _burojs_core.resolveFieldLabel)(caps, name, (0, _burojs_core.declaredText)("field", definition(name), "label")),
71
70
  children: value(name)
72
71
  }, name))
73
72
  })]
@@ -113,14 +112,14 @@ function useProjectedRows(resource, rows, item) {
113
112
  const viewRow = (0, _burojs_react.useViewRow)(resource);
114
113
  const viewVisible = useViewVisible(resource);
115
114
  const idField = (def?.data)?.idField ?? "id";
116
- const project = (0, react.useCallback)((row) => def === void 0 ? viewRow(row) : require_peek_filter.peekRow(def, viewRow(row), idField, accessOf(row), viewVisible), [
115
+ const project = (0, react.useCallback)((row) => def === void 0 ? viewRow(row) : require_place_node.peekRow(def, viewRow(row), idField, accessOf(row), viewVisible), [
117
116
  def,
118
117
  idField,
119
118
  accessOf,
120
119
  viewRow,
121
120
  viewVisible
122
121
  ]);
123
- const hidden = (0, react.useCallback)((field) => field !== idField && (def === void 0 || !require_peek_filter.peekLeafAllowed(def, field, accessOf(_burojs_core.RECORD_PROBE), viewVisible)), [
122
+ const hidden = (0, react.useCallback)((field) => field !== idField && (def === void 0 || !require_place_node.peekLeafAllowed(def, field, accessOf(_burojs_core.RECORD_PROBE), viewVisible)), [
124
123
  def,
125
124
  idField,
126
125
  accessOf,
@@ -206,4 +205,4 @@ Object.defineProperty(exports, "useProjectedRows", {
206
205
  }
207
206
  });
208
207
 
209
- //# sourceMappingURL=related-rows-zh5f_4QR.cjs.map
208
+ //# sourceMappingURL=related-rows-ea43qhhy.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"related-rows-ea43qhhy.cjs","names":["useApp","useI18nCaps","peekLeafAllowed","peekFieldDefinition","ResolvedFieldDisplay","toDisplayText","recordDisplayName","Fragment","resolveFieldLabel","declaredText","useApp","useCtx","useCallback","ruleContextFor","resolveCapability","useFieldAccess","useViewRow","peekRow","peekLeafAllowed","RECORD_PROBE","useMemo","useItemDrawn","recordDisplayName","RelatedItem","useLinkComponent","ClaimedQuickLink","QUICK_ANCHOR_ATTRIBUTE","isPlainLeftClick"],"sources":["../src/blocks/default-item.tsx","../src/blocks/related-rows.tsx"],"sourcesContent":["'use client';\nimport { type EntityRef, resolveFieldLabel, declaredText } from '@burojs/core';\nimport { useApp, useI18nCaps } from '@burojs/react';\nimport { Fragment, type ReactElement } from 'react';\nimport { toDisplayText } from '../fields/display-value.js';\nimport { ResolvedFieldDisplay } from '../fields/resolved-field.js';\nimport {\n type PeekFieldSource,\n peekFieldDefinition,\n peekLeafAllowed,\n} from '../quick/peek-filter.js';\nimport { recordDisplayName } from '../resource/record-display-name.js';\nimport { type ListRow, useRowAccess, useViewVisible } from './related-rows.js';\n\n/** What a default item reads of the target's definition. */\ninterface TargetDefinition extends PeekFieldSource {\n readonly views?: { readonly list?: { readonly columns?: readonly string[] } };\n readonly ref?: EntityRef;\n}\n\n/** A field the default item puts in its trailing part: a number reads best right-aligned. */\nconst isNumeric = (field: { readonly kind?: unknown } | undefined) => field?.kind === 'number';\n\n/**\n * The item of a related list that names none (P6 3.13). As a card: the row's title (weight 500),\n * its other fields as muted label / value pairs, and its numbers in a trailing part set off by a\n * rule. As a timeline entry (`variant: 'entry'`): the title and the field values on one muted\n * meta line. `row` is the projected row, so a field the viewer may not see is already `null` and\n * is not listed.\n */\nexport function DefaultItem({\n resource,\n row,\n raw,\n columns,\n variant = 'card',\n}: {\n readonly resource: string;\n readonly row: Readonly<Record<string, unknown>>;\n /** The row as the list read it: column rules resolve over it. */\n readonly raw: ListRow;\n readonly columns?: readonly string[] | undefined;\n readonly variant?: 'card' | 'entry';\n}): ReactElement {\n const app = useApp();\n const def = app.registry.get(resource) as TargetDefinition | undefined;\n const caps = useI18nCaps(resource);\n const access = useRowAccess(resource)(raw);\n const viewVisible = useViewVisible(resource);\n const fields =\n def === undefined\n ? []\n : (columns ?? def.views?.list?.columns ?? Object.keys(def.fields)).filter(\n (name, index, names) =>\n name !== def.displayField &&\n names.indexOf(name) === index &&\n peekLeafAllowed(def, name, access, viewVisible),\n );\n const ref = def?.ref ?? { namespace: 'default', id: resource };\n const definition = (name: string) =>\n peekFieldDefinition(def!, name) as { readonly label?: string; readonly kind?: unknown };\n const value = (name: string) => (\n <ResolvedFieldDisplay\n resource={ref}\n name={name}\n field={definition(name) as never}\n value={row[name]}\n record={row}\n fallback={toDisplayText(row[name]).text}\n />\n );\n const title = (\n <p className=\"truncate text-sm font-medium\">{recordDisplayName(row, def?.displayField)}</p>\n );\n if (variant === 'entry') {\n const shown = fields.filter((name) => row[name] != null && row[name] !== '');\n return (\n <div className=\"flex min-w-0 flex-col gap-0.5\" data-buro-default-item=\"\">\n {title}\n {shown.length === 0 ? null : (\n <div data-buro-item-meta=\"\" className=\"truncate text-xs text-muted-foreground\">\n {shown.map((name, index) => (\n <Fragment key={name}>\n {index > 0 ? ' · ' : null}\n {value(name)}\n </Fragment>\n ))}\n </div>\n )}\n </div>\n );\n }\n const numbers = fields.filter((name) => isNumeric(definition(name)));\n const pairs = fields.filter((name) => !isNumeric(definition(name)));\n return (\n <div className=\"flex min-w-0 items-start gap-3\" data-buro-default-item=\"\">\n <div className=\"flex min-w-0 flex-1 flex-col gap-2\">\n {title}\n {pairs.length === 0 ? null : (\n <dl className=\"grid gap-1.5\">\n {pairs.map((name) => (\n <div key={name} className=\"flex min-w-0 items-baseline gap-2 text-sm\">\n <dt className=\"w-24 shrink-0 truncate text-xs text-muted-foreground\">\n {resolveFieldLabel(caps, name, declaredText('field', definition(name), 'label'))}\n </dt>\n <dd className=\"min-w-0 break-words\">{value(name)}</dd>\n </div>\n ))}\n </dl>\n )}\n </div>\n {numbers.length === 0 ? null : (\n <div\n data-buro-item-trailing=\"\"\n className=\"flex shrink-0 flex-col items-end gap-1 border-l pl-3 text-sm tabular-nums\"\n >\n {numbers.map((name) => (\n <span\n key={name}\n title={resolveFieldLabel(\n caps,\n name,\n declaredText('field', definition(name), 'label'),\n )}\n >\n {value(name)}\n </span>\n ))}\n </div>\n )}\n </div>\n );\n}\n","'use client';\nimport { type AppContext, RECORD_PROBE, resolveCapability, ruleContextFor } from '@burojs/core';\nimport { type CapabilityResolver, useApp, useCtx, useFieldAccess, useViewRow } from '@burojs/react';\nimport { type ReactElement, type ReactNode, useCallback, useMemo } from 'react';\nimport { QUICK_ANCHOR_ATTRIBUTE } from '@burojs/react';\nimport { ClaimedQuickLink, isPlainLeftClick } from '../fields/claimed-quick-link.js';\nimport { useLinkComponent } from '../layout/link-component.js';\nimport { type PeekFieldSource, peekLeafAllowed, peekRow } from '../quick/peek-filter.js';\nimport { recordDisplayName } from '../resource/record-display-name.js';\nimport { DefaultItem } from './default-item.js';\nimport { type ItemHandle, RelatedItem, useItemDrawn } from './related-item.js';\n\nexport type ListRow = { readonly id: string } & Readonly<Record<string, unknown>>;\n\n/** What `related-list` hands a rows view: the list's rows and how a row opens. */\nexport interface RelatedRowsProps {\n /** The target resource. */\n readonly resource: string;\n /** The placement's key (test ids). */\n readonly placementKey: string;\n readonly rows: readonly ListRow[];\n readonly item?: ItemHandle | undefined;\n /** The placement's `columns`, for the default item. */\n readonly columns?: readonly string[] | undefined;\n readonly rowQuick?: ((row: ListRow) => (() => void) | null) | undefined;\n readonly rowHref?: ((row: ListRow) => string | undefined) | undefined;\n}\n\n/**\n * A capability resolver per row: column rules resolve over the row they hide a field of, as the\n * peek's do (P6-B review), so a rule reading the record sees this row.\n */\nexport function useRowAccess(resource: string): (row: ListRow) => CapabilityResolver {\n const app = useApp();\n const scope = useCtx((c: AppContext) => c.scope);\n const user = useCtx((c: AppContext) => c.user);\n const permissions = useCtx((c: AppContext) => c.permissions);\n return useCallback(\n (row) =>\n (capability, target, defaultAllowed = true) => {\n const rules = app.ruleSource.rules(resource);\n if (rules.length === 0) return { allowed: defaultAllowed };\n const ctx = ruleContextFor({\n user,\n scope,\n permissions,\n record: row,\n mode: 'show',\n resource,\n });\n return resolveCapability(rules, capability, target, ctx, defaultAllowed);\n },\n [app.ruleSource, resource, scope, user, permissions],\n );\n}\n\n/**\n * Whether a field may be drawn on every row by its P5 view (P5 spec 3.6.6): a decision that is\n * not `visible` (`hidden`, `restricted`, `failed` and `pending` alike, so nothing is drawn while\n * the permission map loads) withholds it. A field the map does not decide is not withheld here. The decision\n * is the any-record one ({@link RECORD_PROBE}), so a rule reading the record counts as hiding.\n */\nexport function useViewVisible(resource: string): (field: string) => boolean {\n const access = useFieldAccess(resource, 'every');\n return useCallback(\n (field) => {\n const decision = access[field];\n return decision === undefined || decision.view === 'visible';\n },\n [access],\n );\n}\n\ninterface ProjectedRows {\n readonly def:\n | (PeekFieldSource & { readonly displayField?: string; readonly data?: unknown })\n | undefined;\n /** The row a card or an entry sees: the id and what the viewer may see; the rest read `null`. */\n readonly project: (row: ListRow) => ListRow;\n /** Whether the item block is drawn (decided once for the list), else the default item. */\n readonly drawn: boolean;\n readonly title: (row: ListRow) => string;\n}\n\n/**\n * The rows of a cards or timeline view, projected once and the item decided once per list.\n *\n * The rows arrive as the list read them (policy). A row is first projected by P5's field view\n * (`viewRow`: a field its user may not view for every row is left out) and then by the peek's\n * rule ({@link peekRow}): the id field and every field that is not `sensitive`, not withheld by\n * a field `requires.view` and not hidden by a `column` rule keep their values; every other\n * field reads `null`. It is the one place a row's fields are filtered before an item block or\n * the default item sees them (P6-66), and the timeline's axis reads the same row.\n */\nexport function useProjectedRows(\n resource: string,\n rows: readonly ListRow[],\n item: ItemHandle | undefined,\n): ProjectedRows {\n const app = useApp();\n const def = app.registry.get(resource) as ProjectedRows['def'];\n const accessOf = useRowAccess(resource);\n const viewRow = useViewRow(resource);\n const viewVisible = useViewVisible(resource);\n const idField = (def?.data as { readonly idField?: string } | undefined)?.idField ?? 'id';\n const project = useCallback(\n (row: ListRow): ListRow =>\n (def === undefined\n ? viewRow(row)\n : peekRow(def, viewRow(row), idField, accessOf(row), viewVisible)) as ListRow,\n [def, idField, accessOf, viewRow, viewVisible],\n );\n const hidden = useCallback(\n (field: string) =>\n field !== idField &&\n (def === undefined ||\n !peekLeafAllowed(def, field, accessOf(RECORD_PROBE as ListRow), viewVisible)),\n [def, idField, accessOf, viewVisible],\n );\n const probe = useMemo(\n () => (rows[0] === undefined ? undefined : project(rows[0])),\n [rows, project],\n );\n const drawn = useItemDrawn(item, hidden, probe);\n const title = useCallback(\n (row: ListRow) => recordDisplayName(project(row), def?.displayField),\n [project, def],\n );\n return { def, project, drawn, title };\n}\n\n/** The item block (or the default item) of one row. */\nexport function RowContent({\n resource,\n raw,\n row,\n item,\n drawn,\n columns,\n variant,\n}: {\n readonly resource: string;\n /** The row as the list read it (column rules resolve over it). */\n readonly raw: ListRow;\n /** The projected row. */\n readonly row: ListRow;\n readonly item: ItemHandle | undefined;\n readonly drawn: boolean;\n readonly columns?: readonly string[] | undefined;\n /** How the default item lays the row out: a card's, or a timeline entry's. */\n readonly variant?: 'card' | 'entry';\n}): ReactElement {\n const fallback = (\n <DefaultItem\n resource={resource}\n row={row}\n raw={raw}\n columns={columns}\n {...(variant === undefined ? {} : { variant })}\n />\n );\n if (item === undefined || !drawn) return fallback;\n return <RelatedItem handle={item} row={row} fallback={fallback} />;\n}\n\n/**\n * A card's or an entry's one opener (P6-74): the row's title as the accessible name of a single\n * anchor whose `::after` covers the positioned parent. A quick row is the page anchor claimed\n * for the opener (a modified click follows the `href`), or a link-role button without a page.\n * `open: 'none'` draws nothing.\n */\nexport function RowOpener({\n title,\n href,\n quick,\n}: {\n readonly title: string;\n readonly href: string | undefined;\n readonly quick: (() => void) | null;\n}): ReactElement | null {\n const RouterLink = useLinkComponent();\n const className =\n 'outline-none after:absolute after:inset-0 after:rounded-[inherit] focus-visible:after:ring-2 focus-visible:after:ring-ring';\n const name: ReactNode = <span className=\"sr-only\">{title}</span>;\n if (quick !== null)\n return href ? (\n <ClaimedQuickLink href={href} className={className} onOpen={quick}>\n {name}\n </ClaimedQuickLink>\n ) : (\n <button\n type=\"button\"\n role=\"link\"\n {...{ [QUICK_ANCHOR_ATTRIBUTE]: '' }}\n // A button is inline-block, so even with only an `sr-only` name it took a line of the\n // card and pushed the content down (REF-40). Zero-size and unpositioned, its `::after`\n // still covers the card.\n className={`${className} block size-0 p-0`}\n onClick={(event) => {\n if (!isPlainLeftClick(event)) return;\n quick();\n }}\n >\n {name}\n </button>\n );\n if (href)\n return (\n <RouterLink href={href} className={className}>\n {name}\n </RouterLink>\n );\n return null;\n}\n\n/**\n * The wrapper that raises an item's interactive descendants above the opener's cover (P6-74):\n * the wrapper itself lets clicks through to the opener, its controls take them.\n */\nexport const ITEM_LAYER_CLASS =\n 'relative z-[1] pointer-events-none [&_a]:pointer-events-auto [&_button]:pointer-events-auto [&_input]:pointer-events-auto [&_select]:pointer-events-auto [&_textarea]:pointer-events-auto [&_summary]:pointer-events-auto [&_[role=button]]:pointer-events-auto [&_[role=link]]:pointer-events-auto [&_[role=checkbox]]:pointer-events-auto [&_[role=switch]]:pointer-events-auto';\n"],"mappings":"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"}
@@ -1,8 +1,7 @@
1
- import { d as useLinkComponent } from "./toaster-CfCRLgR-.js";
2
- import { h as isPlainLeftClick, m as ClaimedQuickLink, p as recordDisplayName } from "./search-access-CURsWn-U.js";
3
- import { Dt as ResolvedFieldDisplay, it as useItemDrawn, kt as toDisplayText, rt as RelatedItem } from "./place-node--GdsP688.js";
4
- import { i as peekRow, n as peekLeafAllowed, t as peekFieldDefinition } from "./peek-filter-ErLfO153.js";
5
- import { RECORD_PROBE, resolveCapability, resolveFieldLabel, ruleContextFor } from "@burojs/core";
1
+ import { o as useLinkComponent } from "./toaster-C02XbB9r.js";
2
+ import { f as recordDisplayName, m as isPlainLeftClick, p as ClaimedQuickLink } from "./search-access-CPPmfuvy.js";
3
+ import { Nt as toDisplayText, a as peekFieldDefinition, c as peekRow, ct as useItemDrawn, jt as ResolvedFieldDisplay, o as peekLeafAllowed, st as RelatedItem } from "./place-node-NraNYKPx.js";
4
+ import { RECORD_PROBE, declaredText, resolveCapability, resolveFieldLabel, ruleContextFor } from "@burojs/core";
6
5
  import { QUICK_ANCHOR_ATTRIBUTE, useApp, useCtx, useFieldAccess, useI18nCaps, useViewRow } from "@burojs/react";
7
6
  import { Fragment, useCallback, useMemo } from "react";
8
7
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -56,7 +55,7 @@ function DefaultItem({ resource, row, raw, columns, variant = "card" }) {
56
55
  className: "flex min-w-0 items-baseline gap-2 text-sm",
57
56
  children: [jsx("dt", {
58
57
  className: "w-24 shrink-0 truncate text-xs text-muted-foreground",
59
- children: resolveFieldLabel(caps, name, definition(name)?.label)
58
+ children: resolveFieldLabel(caps, name, declaredText("field", definition(name), "label"))
60
59
  }), jsx("dd", {
61
60
  className: "min-w-0 break-words",
62
61
  children: value(name)
@@ -67,7 +66,7 @@ function DefaultItem({ resource, row, raw, columns, variant = "card" }) {
67
66
  "data-buro-item-trailing": "",
68
67
  className: "flex shrink-0 flex-col items-end gap-1 border-l pl-3 text-sm tabular-nums",
69
68
  children: numbers.map((name) => jsx("span", {
70
- title: resolveFieldLabel(caps, name, definition(name)?.label),
69
+ title: resolveFieldLabel(caps, name, declaredText("field", definition(name), "label")),
71
70
  children: value(name)
72
71
  }, name))
73
72
  })]
@@ -183,4 +182,4 @@ const ITEM_LAYER_CLASS = "relative z-[1] pointer-events-none [&_a]:pointer-event
183
182
  //#endregion
184
183
  export { useProjectedRows as i, RowContent as n, RowOpener as r, ITEM_LAYER_CLASS as t };
185
184
 
186
- //# sourceMappingURL=related-rows-B4levHcR.js.map
185
+ //# sourceMappingURL=related-rows-o0_t-Yce.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"related-rows-o0_t-Yce.js","names":[],"sources":["../src/blocks/default-item.tsx","../src/blocks/related-rows.tsx"],"sourcesContent":["'use client';\nimport { type EntityRef, resolveFieldLabel, declaredText } from '@burojs/core';\nimport { useApp, useI18nCaps } from '@burojs/react';\nimport { Fragment, type ReactElement } from 'react';\nimport { toDisplayText } from '../fields/display-value.js';\nimport { ResolvedFieldDisplay } from '../fields/resolved-field.js';\nimport {\n type PeekFieldSource,\n peekFieldDefinition,\n peekLeafAllowed,\n} from '../quick/peek-filter.js';\nimport { recordDisplayName } from '../resource/record-display-name.js';\nimport { type ListRow, useRowAccess, useViewVisible } from './related-rows.js';\n\n/** What a default item reads of the target's definition. */\ninterface TargetDefinition extends PeekFieldSource {\n readonly views?: { readonly list?: { readonly columns?: readonly string[] } };\n readonly ref?: EntityRef;\n}\n\n/** A field the default item puts in its trailing part: a number reads best right-aligned. */\nconst isNumeric = (field: { readonly kind?: unknown } | undefined) => field?.kind === 'number';\n\n/**\n * The item of a related list that names none (P6 3.13). As a card: the row's title (weight 500),\n * its other fields as muted label / value pairs, and its numbers in a trailing part set off by a\n * rule. As a timeline entry (`variant: 'entry'`): the title and the field values on one muted\n * meta line. `row` is the projected row, so a field the viewer may not see is already `null` and\n * is not listed.\n */\nexport function DefaultItem({\n resource,\n row,\n raw,\n columns,\n variant = 'card',\n}: {\n readonly resource: string;\n readonly row: Readonly<Record<string, unknown>>;\n /** The row as the list read it: column rules resolve over it. */\n readonly raw: ListRow;\n readonly columns?: readonly string[] | undefined;\n readonly variant?: 'card' | 'entry';\n}): ReactElement {\n const app = useApp();\n const def = app.registry.get(resource) as TargetDefinition | undefined;\n const caps = useI18nCaps(resource);\n const access = useRowAccess(resource)(raw);\n const viewVisible = useViewVisible(resource);\n const fields =\n def === undefined\n ? []\n : (columns ?? def.views?.list?.columns ?? Object.keys(def.fields)).filter(\n (name, index, names) =>\n name !== def.displayField &&\n names.indexOf(name) === index &&\n peekLeafAllowed(def, name, access, viewVisible),\n );\n const ref = def?.ref ?? { namespace: 'default', id: resource };\n const definition = (name: string) =>\n peekFieldDefinition(def!, name) as { readonly label?: string; readonly kind?: unknown };\n const value = (name: string) => (\n <ResolvedFieldDisplay\n resource={ref}\n name={name}\n field={definition(name) as never}\n value={row[name]}\n record={row}\n fallback={toDisplayText(row[name]).text}\n />\n );\n const title = (\n <p className=\"truncate text-sm font-medium\">{recordDisplayName(row, def?.displayField)}</p>\n );\n if (variant === 'entry') {\n const shown = fields.filter((name) => row[name] != null && row[name] !== '');\n return (\n <div className=\"flex min-w-0 flex-col gap-0.5\" data-buro-default-item=\"\">\n {title}\n {shown.length === 0 ? null : (\n <div data-buro-item-meta=\"\" className=\"truncate text-xs text-muted-foreground\">\n {shown.map((name, index) => (\n <Fragment key={name}>\n {index > 0 ? ' · ' : null}\n {value(name)}\n </Fragment>\n ))}\n </div>\n )}\n </div>\n );\n }\n const numbers = fields.filter((name) => isNumeric(definition(name)));\n const pairs = fields.filter((name) => !isNumeric(definition(name)));\n return (\n <div className=\"flex min-w-0 items-start gap-3\" data-buro-default-item=\"\">\n <div className=\"flex min-w-0 flex-1 flex-col gap-2\">\n {title}\n {pairs.length === 0 ? null : (\n <dl className=\"grid gap-1.5\">\n {pairs.map((name) => (\n <div key={name} className=\"flex min-w-0 items-baseline gap-2 text-sm\">\n <dt className=\"w-24 shrink-0 truncate text-xs text-muted-foreground\">\n {resolveFieldLabel(caps, name, declaredText('field', definition(name), 'label'))}\n </dt>\n <dd className=\"min-w-0 break-words\">{value(name)}</dd>\n </div>\n ))}\n </dl>\n )}\n </div>\n {numbers.length === 0 ? null : (\n <div\n data-buro-item-trailing=\"\"\n className=\"flex shrink-0 flex-col items-end gap-1 border-l pl-3 text-sm tabular-nums\"\n >\n {numbers.map((name) => (\n <span\n key={name}\n title={resolveFieldLabel(\n caps,\n name,\n declaredText('field', definition(name), 'label'),\n )}\n >\n {value(name)}\n </span>\n ))}\n </div>\n )}\n </div>\n );\n}\n","'use client';\nimport { type AppContext, RECORD_PROBE, resolveCapability, ruleContextFor } from '@burojs/core';\nimport { type CapabilityResolver, useApp, useCtx, useFieldAccess, useViewRow } from '@burojs/react';\nimport { type ReactElement, type ReactNode, useCallback, useMemo } from 'react';\nimport { QUICK_ANCHOR_ATTRIBUTE } from '@burojs/react';\nimport { ClaimedQuickLink, isPlainLeftClick } from '../fields/claimed-quick-link.js';\nimport { useLinkComponent } from '../layout/link-component.js';\nimport { type PeekFieldSource, peekLeafAllowed, peekRow } from '../quick/peek-filter.js';\nimport { recordDisplayName } from '../resource/record-display-name.js';\nimport { DefaultItem } from './default-item.js';\nimport { type ItemHandle, RelatedItem, useItemDrawn } from './related-item.js';\n\nexport type ListRow = { readonly id: string } & Readonly<Record<string, unknown>>;\n\n/** What `related-list` hands a rows view: the list's rows and how a row opens. */\nexport interface RelatedRowsProps {\n /** The target resource. */\n readonly resource: string;\n /** The placement's key (test ids). */\n readonly placementKey: string;\n readonly rows: readonly ListRow[];\n readonly item?: ItemHandle | undefined;\n /** The placement's `columns`, for the default item. */\n readonly columns?: readonly string[] | undefined;\n readonly rowQuick?: ((row: ListRow) => (() => void) | null) | undefined;\n readonly rowHref?: ((row: ListRow) => string | undefined) | undefined;\n}\n\n/**\n * A capability resolver per row: column rules resolve over the row they hide a field of, as the\n * peek's do (P6-B review), so a rule reading the record sees this row.\n */\nexport function useRowAccess(resource: string): (row: ListRow) => CapabilityResolver {\n const app = useApp();\n const scope = useCtx((c: AppContext) => c.scope);\n const user = useCtx((c: AppContext) => c.user);\n const permissions = useCtx((c: AppContext) => c.permissions);\n return useCallback(\n (row) =>\n (capability, target, defaultAllowed = true) => {\n const rules = app.ruleSource.rules(resource);\n if (rules.length === 0) return { allowed: defaultAllowed };\n const ctx = ruleContextFor({\n user,\n scope,\n permissions,\n record: row,\n mode: 'show',\n resource,\n });\n return resolveCapability(rules, capability, target, ctx, defaultAllowed);\n },\n [app.ruleSource, resource, scope, user, permissions],\n );\n}\n\n/**\n * Whether a field may be drawn on every row by its P5 view (P5 spec 3.6.6): a decision that is\n * not `visible` (`hidden`, `restricted`, `failed` and `pending` alike, so nothing is drawn while\n * the permission map loads) withholds it. A field the map does not decide is not withheld here. The decision\n * is the any-record one ({@link RECORD_PROBE}), so a rule reading the record counts as hiding.\n */\nexport function useViewVisible(resource: string): (field: string) => boolean {\n const access = useFieldAccess(resource, 'every');\n return useCallback(\n (field) => {\n const decision = access[field];\n return decision === undefined || decision.view === 'visible';\n },\n [access],\n );\n}\n\ninterface ProjectedRows {\n readonly def:\n | (PeekFieldSource & { readonly displayField?: string; readonly data?: unknown })\n | undefined;\n /** The row a card or an entry sees: the id and what the viewer may see; the rest read `null`. */\n readonly project: (row: ListRow) => ListRow;\n /** Whether the item block is drawn (decided once for the list), else the default item. */\n readonly drawn: boolean;\n readonly title: (row: ListRow) => string;\n}\n\n/**\n * The rows of a cards or timeline view, projected once and the item decided once per list.\n *\n * The rows arrive as the list read them (policy). A row is first projected by P5's field view\n * (`viewRow`: a field its user may not view for every row is left out) and then by the peek's\n * rule ({@link peekRow}): the id field and every field that is not `sensitive`, not withheld by\n * a field `requires.view` and not hidden by a `column` rule keep their values; every other\n * field reads `null`. It is the one place a row's fields are filtered before an item block or\n * the default item sees them (P6-66), and the timeline's axis reads the same row.\n */\nexport function useProjectedRows(\n resource: string,\n rows: readonly ListRow[],\n item: ItemHandle | undefined,\n): ProjectedRows {\n const app = useApp();\n const def = app.registry.get(resource) as ProjectedRows['def'];\n const accessOf = useRowAccess(resource);\n const viewRow = useViewRow(resource);\n const viewVisible = useViewVisible(resource);\n const idField = (def?.data as { readonly idField?: string } | undefined)?.idField ?? 'id';\n const project = useCallback(\n (row: ListRow): ListRow =>\n (def === undefined\n ? viewRow(row)\n : peekRow(def, viewRow(row), idField, accessOf(row), viewVisible)) as ListRow,\n [def, idField, accessOf, viewRow, viewVisible],\n );\n const hidden = useCallback(\n (field: string) =>\n field !== idField &&\n (def === undefined ||\n !peekLeafAllowed(def, field, accessOf(RECORD_PROBE as ListRow), viewVisible)),\n [def, idField, accessOf, viewVisible],\n );\n const probe = useMemo(\n () => (rows[0] === undefined ? undefined : project(rows[0])),\n [rows, project],\n );\n const drawn = useItemDrawn(item, hidden, probe);\n const title = useCallback(\n (row: ListRow) => recordDisplayName(project(row), def?.displayField),\n [project, def],\n );\n return { def, project, drawn, title };\n}\n\n/** The item block (or the default item) of one row. */\nexport function RowContent({\n resource,\n raw,\n row,\n item,\n drawn,\n columns,\n variant,\n}: {\n readonly resource: string;\n /** The row as the list read it (column rules resolve over it). */\n readonly raw: ListRow;\n /** The projected row. */\n readonly row: ListRow;\n readonly item: ItemHandle | undefined;\n readonly drawn: boolean;\n readonly columns?: readonly string[] | undefined;\n /** How the default item lays the row out: a card's, or a timeline entry's. */\n readonly variant?: 'card' | 'entry';\n}): ReactElement {\n const fallback = (\n <DefaultItem\n resource={resource}\n row={row}\n raw={raw}\n columns={columns}\n {...(variant === undefined ? {} : { variant })}\n />\n );\n if (item === undefined || !drawn) return fallback;\n return <RelatedItem handle={item} row={row} fallback={fallback} />;\n}\n\n/**\n * A card's or an entry's one opener (P6-74): the row's title as the accessible name of a single\n * anchor whose `::after` covers the positioned parent. A quick row is the page anchor claimed\n * for the opener (a modified click follows the `href`), or a link-role button without a page.\n * `open: 'none'` draws nothing.\n */\nexport function RowOpener({\n title,\n href,\n quick,\n}: {\n readonly title: string;\n readonly href: string | undefined;\n readonly quick: (() => void) | null;\n}): ReactElement | null {\n const RouterLink = useLinkComponent();\n const className =\n 'outline-none after:absolute after:inset-0 after:rounded-[inherit] focus-visible:after:ring-2 focus-visible:after:ring-ring';\n const name: ReactNode = <span className=\"sr-only\">{title}</span>;\n if (quick !== null)\n return href ? (\n <ClaimedQuickLink href={href} className={className} onOpen={quick}>\n {name}\n </ClaimedQuickLink>\n ) : (\n <button\n type=\"button\"\n role=\"link\"\n {...{ [QUICK_ANCHOR_ATTRIBUTE]: '' }}\n // A button is inline-block, so even with only an `sr-only` name it took a line of the\n // card and pushed the content down (REF-40). Zero-size and unpositioned, its `::after`\n // still covers the card.\n className={`${className} block size-0 p-0`}\n onClick={(event) => {\n if (!isPlainLeftClick(event)) return;\n quick();\n }}\n >\n {name}\n </button>\n );\n if (href)\n return (\n <RouterLink href={href} className={className}>\n {name}\n </RouterLink>\n );\n return null;\n}\n\n/**\n * The wrapper that raises an item's interactive descendants above the opener's cover (P6-74):\n * the wrapper itself lets clicks through to the opener, its controls take them.\n */\nexport const ITEM_LAYER_CLASS =\n 'relative z-[1] pointer-events-none [&_a]:pointer-events-auto [&_button]:pointer-events-auto [&_input]:pointer-events-auto [&_select]:pointer-events-auto [&_textarea]:pointer-events-auto [&_summary]:pointer-events-auto [&_[role=button]]:pointer-events-auto [&_[role=link]]:pointer-events-auto [&_[role=checkbox]]:pointer-events-auto [&_[role=switch]]:pointer-events-auto';\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  const require_use_theme = require("./use-theme-DFlpXils.cjs");
2
- const require_toaster = require("./toaster-C7CiYA4Z.cjs");
2
+ const require_toaster = require("./toaster-Cr51X7bz.cjs");
3
3
  const require_button = require("./button-BxnnE28H.cjs");
4
- const require_search_access = require("./search-access-B7G5oR8n.cjs");
4
+ const require_search_access = require("./search-access-Dugvttlg.cjs");
5
5
  let _burojs_core = require("@burojs/core");
6
6
  let _burojs_react = require("@burojs/react");
7
7
  let _tabler_icons_react = require("@tabler/icons-react");
@@ -27,7 +27,7 @@ function createdOptionScope(input) {
27
27
  ...input.searchContext === void 0 ? {} : { searchContext: input.searchContext }
28
28
  });
29
29
  }
30
- function CreatedOptionRead({ to, filter, ignoreScope, by, idField, onSettled }) {
30
+ function CreatedOptionRead({ to, filter, scope, scopeField, by, idField, onSettled }) {
31
31
  const query = (0, _burojs_react.useList)(to, {
32
32
  filter,
33
33
  pagination: {
@@ -35,7 +35,8 @@ function CreatedOptionRead({ to, filter, ignoreScope, by, idField, onSettled })
35
35
  page: 1,
36
36
  pageSize: 1
37
37
  },
38
- ...ignoreScope ? { providerOptionsOverride: { ignoreScope: true } } : {},
38
+ scope,
39
+ ...scopeField === void 0 ? {} : { scopeField },
39
40
  retry: false
40
41
  });
41
42
  const settled = react.useRef(false);
@@ -91,7 +92,7 @@ function RelationViewButton(props) {
91
92
  keyString: key
92
93
  }, key);
93
94
  }
94
- function ViewButton({ to, by, ignoreScope, fieldName, keyString, beforeOpen, open: openMode = "quick" }) {
95
+ function ViewButton({ to, by, fieldName, keyString, beforeOpen, open: openMode = "quick" }) {
95
96
  const app = (0, _burojs_react.useApp)();
96
97
  const t = (0, _burojs_react.useOptionalT)();
97
98
  const tid = (0, _burojs_react.useTestIds)();
@@ -116,7 +117,7 @@ function ViewButton({ to, by, ignoreScope, fieldName, keyString, beforeOpen, ope
116
117
  pageSize: 2
117
118
  }
118
119
  } : {},
119
- ...ignoreScope === true ? { providerOptionsOverride: { ignoreScope: true } } : {},
120
+ scope: "none",
120
121
  enabled: asked && by !== void 0,
121
122
  retry: false
122
123
  });
@@ -288,7 +289,8 @@ function useSelectCreate(input) {
288
289
  searchDecl: input.searchDecl,
289
290
  searchContext: input.searchContext
290
291
  }),
291
- ignoreScope: input.fixedFilters !== void 0 && input.fixedFilters.length > 0,
292
+ scope: input.scope,
293
+ ...input.scopeField === void 0 ? {} : { scopeField: input.scopeField },
292
294
  by: input.by,
293
295
  idField: input.idField,
294
296
  onSettled: settle
@@ -359,4 +361,4 @@ Object.defineProperty(exports, "useSelectCreate", {
359
361
  }
360
362
  });
361
363
 
362
- //# sourceMappingURL=relation-create-BOaUe12G.cjs.map
364
+ //# sourceMappingURL=relation-create-IA40t1hi.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relation-create-IA40t1hi.cjs","names":["composeListFilter","normalizeFixedFilters","useList","React","cn","buttonVariants","useEntryGate","useListAccess","useApp","useOptionalT","useTestIds","useQuick","useRouteNavigate","useLinkComponent","React","useList","linksToPage","resourceShowHref","IconEye","ClaimedQuickLink","QUICK_ANCHOR_ATTRIBUTE","isPlainLeftClick","useOptionalT","React","useListAccess","namesHiddenField","useEntryGate","useApp","useTestIds","useQuick"],"sources":["../src/fields/relation-hand-back.tsx","../src/fields/relation-view-button.tsx","../src/fields/relation-create.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport {\n composeListFilter,\n type ErasedResourceHandle,\n type FilterExpression,\n type FixedFilterInput,\n normalizeFixedFilters,\n type ScopeSource,\n type SearchDecl,\n} from '@burojs/core';\nimport { useList } from '@burojs/react';\n\ntype ErasedExpression = FilterExpression<ErasedResourceHandle>;\n\n/**\n * The filter the select re-reads a created record through (P6-33): the picker's own option query\n * for an empty search (`composeListFilter`, the same `fixed` filters, the same search\n * declaration), conjoined with `<idField> eq <id>`. The row must come back through the query the\n * select offers from, or it is not selected.\n */\nexport function createdOptionFilter(input: {\n readonly fixed: readonly FixedFilterInput[] | undefined;\n readonly idField: string;\n readonly id: string | number;\n readonly searchDecl?: SearchDecl | undefined;\n readonly searchContext?: { readonly resource: string; readonly def: unknown };\n}): ErasedExpression {\n const own = createdOptionScope(input);\n const byId = { field: input.idField, op: 'eq', value: input.id } as ErasedExpression;\n return own === undefined ? byId : ({ and: [own, byId] } as ErasedExpression);\n}\n\n/**\n * The select's option query for an empty search, without the id predicate: what the picker itself\n * sends, so the same hidden-field rule (`namesHiddenField`) judges both.\n */\nexport function createdOptionScope(input: {\n readonly fixed: readonly FixedFilterInput[] | undefined;\n readonly searchDecl?: SearchDecl | undefined;\n readonly searchContext?: { readonly resource: string; readonly def: unknown };\n}): ErasedExpression | undefined {\n return composeListFilter({\n fixed: normalizeFixedFilters(input.fixed),\n search: '',\n ...(input.searchDecl === undefined ? {} : { searchDecl: input.searchDecl }),\n ...(input.searchContext === undefined ? {} : { searchContext: input.searchContext as never }),\n });\n}\n\n/** What the re-read settled on: the value to select, \"does not fit\", or a failed read. */\nexport type CreatedOptionResult =\n | { readonly kind: 'fits'; readonly value: string | number }\n | { readonly kind: 'does-not-fit' }\n | { readonly kind: 'failed' };\n\nexport interface CreatedOptionReadProps {\n readonly to: string;\n readonly filter: ErasedExpression;\n /**\n * The select's read scope, as its option list takes it: the picker and the hand-back never\n * disagree on which rows fit.\n */\n readonly scope: ScopeSource;\n /** The record field the select writes (`useList`'s `scopeField`), as its option list passes it. */\n readonly scopeField?: string;\n readonly by: string | undefined;\n readonly idField: string;\n /** Called once, with the settled answer. */\n readonly onSettled: (result: CreatedOptionResult) => void;\n}\n\n/**\n * Mounted only while a created record is being handed back. One list read, limit 1, through the\n * select's own option query (Known finding 13): an empty answer is \"does not fit\", a failed read\n * is a failure, never \"fits\". Mounting it is the request; unmounting it drops the answer.\n */\nexport function CreatedOptionRead({\n to,\n filter,\n scope,\n scopeField,\n by,\n idField,\n onSettled,\n}: CreatedOptionReadProps): null {\n const query = useList(to, {\n filter: filter as never,\n pagination: { kind: 'offset', page: 1, pageSize: 1 },\n scope,\n ...(scopeField === undefined ? {} : { scopeField }),\n retry: false,\n });\n const settled = React.useRef(false);\n const latest = React.useRef(onSettled);\n latest.current = onSettled;\n const rows = (query.data as { readonly data?: readonly Record<string, unknown>[] } | undefined)\n ?.data;\n const answered = rows !== undefined && query.isCurrentData && !query.isFetching;\n const failed = query.isError && !query.isFetching;\n React.useEffect(() => {\n if (settled.current) return;\n if (failed) {\n settled.current = true;\n latest.current({ kind: 'failed' });\n return;\n }\n if (!answered) return;\n settled.current = true;\n const value = rows[0]?.[by ?? idField];\n latest.current(\n typeof value === 'string' || typeof value === 'number'\n ? { kind: 'fits', value }\n : { kind: 'does-not-fit' },\n );\n }, [answered, failed, rows, by, idField]);\n return null;\n}\n","'use client';\n\nimport * as React from 'react';\nimport { IconEye } from '@tabler/icons-react';\nimport { type RelationOpen, resourceShowHref } from '@burojs/core';\nimport {\n QUICK_ANCHOR_ATTRIBUTE,\n useApp,\n useEntryGate,\n useList,\n useListAccess,\n useOptionalT,\n useQuick,\n useRouteNavigate,\n useTestIds,\n} from '@burojs/react';\nimport { buttonVariants } from '../primitives/button.js';\nimport { cn } from '../lib/cn.js';\nimport { useLinkComponent } from '../layout/link-component.js';\nimport { ClaimedQuickLink, isPlainLeftClick } from './claimed-quick-link.js';\nimport { linksToPage } from './relation-display.js';\n\n/** A key a read may send: a non-empty string or a finite number (Known finding 1). */\nexport function selectKey(value: unknown): string | null {\n if (typeof value === 'string') return value.length === 0 ? null : value;\n if (typeof value === 'number') return Number.isFinite(value) ? String(value) : null;\n return null;\n}\n\nconst VIEW_CLASS = cn(buttonVariants({ variant: 'outline', size: 'icon' }), 'shrink-0');\n\nexport interface RelationViewButtonProps {\n readonly to: string;\n readonly value: unknown;\n readonly by: string | undefined;\n /** The form field holding the key: the test id's second part. */\n readonly fieldName: string;\n /** Runs before the overlay opens: the picker moves focus to its trigger, where it returns. */\n readonly beforeOpen: () => void;\n /**\n * The field's `ui.open` (P7 3.6): `quick` (default) opens the record above the form, `page`\n * goes to its show page through the navigation guard (a dirty form asks first), `none` draws\n * no button.\n */\n readonly open?: RelationOpen;\n}\n\n/**\n * \"View\" beside a relation select's trigger (P6-28): the target's `quick.show` as a new overlay\n * above the form, never a push and never closing the host. Drawn only when the select holds a\n * key and the entry gate is open without a row (the row-level re-check runs inside the overlay,\n * P3-44); while the gate is undecided nothing is drawn and nothing is read (P3-15). A `by` key is\n * resolved by the limit-2 read on click; zero or two rows open nothing.\n */\nexport function RelationViewButton(props: RelationViewButtonProps): React.ReactElement | null {\n const gate = useEntryGate();\n const { to, value, by } = props;\n const access = useListAccess(to);\n const key = selectKey(value);\n if (key === null || props.open === 'none') return null;\n // A `by` field the user may not view is never sent as a predicate: no \"view\", no read.\n if (by !== undefined && !(access.status === 'ready' && access.fieldVisible(by))) return null;\n const answer = gate(to, 'show');\n if (answer.state !== 'open') return null;\n // Keyed by the value: a click asked for one key's read and must not outlive it.\n return <ViewButton key={key} {...props} keyString={key} />;\n}\n\nfunction ViewButton({\n to,\n by,\n fieldName,\n keyString,\n beforeOpen,\n open: openMode = 'quick',\n}: RelationViewButtonProps & { readonly keyString: string }): React.ReactElement | null {\n const app = useApp();\n const t = useOptionalT();\n const tid = useTestIds();\n const quick = useQuick();\n const navigate = useRouteNavigate();\n const RouterLink = useLinkComponent();\n const [asked, setAsked] = React.useState(false);\n const requested = React.useRef(false);\n const targetDef = app.registry.get(to);\n const rawIdField = (targetDef?.data as { readonly idField?: unknown } | undefined)?.idField;\n const idField = typeof rawIdField === 'string' && rawIdField.length > 0 ? rawIdField : 'id';\n const read = useList(to, {\n ...(asked && by !== undefined\n ? {\n filter: { field: by, op: 'eq', value: keyString } as never,\n pagination: { kind: 'offset', page: 1, pageSize: 2 } as never,\n }\n : {}),\n // A key names one record: the read is never narrowed by a scope.\n scope: 'none',\n enabled: asked && by !== undefined,\n retry: false,\n });\n // Rows of this key only: a placeholder carried over from another key's read is not an answer.\n const current = read.isCurrentData && !read.isPlaceholderData && !read.isFetching;\n const rows = current\n ? (read.data as { readonly data?: readonly Record<string, unknown>[] } | undefined)?.data\n : undefined;\n const open = React.useCallback(\n (id: string) => {\n beforeOpen();\n if (openMode === 'page') {\n // The page of the record, through the navigation guard: unsaved input asks first.\n if (targetDef !== undefined && linksToPage(app, targetDef))\n navigate(resourceShowHref(app.registry, targetDef, to, id));\n return;\n }\n quick.show(to, id);\n },\n [beforeOpen, quick, to, openMode, navigate, app, targetDef],\n );\n // Only a click opens: the read answers the click that asked for it, once.\n React.useEffect(() => {\n if (by === undefined || !asked || rows === undefined || !requested.current) return;\n requested.current = false;\n if (rows.length !== 1) {\n if (rows.length > 1 && process.env.NODE_ENV !== 'production')\n console.error(\n `[burojs] ${to}: more than one row has ${by} ${keyString}; \"view\" opened nothing.`,\n );\n return;\n }\n const id = rows[0]?.[idField];\n const next = selectKey(id);\n if (next !== null) open(next);\n }, [by, asked, rows, idField, keyString, to, open]);\n\n const label = t('relationPicker.view', { defaultValue: 'View' });\n const icon = <IconEye className=\"h-4 w-4\" aria-hidden />;\n const testid = tid.relationView(to, fieldName);\n // `page` needs a page to go to (the publish check says so): without one, nothing is drawn.\n if (openMode === 'page' && (targetDef === undefined || !linksToPage(app, targetDef))) return null;\n if (openMode === 'page' && by === undefined && targetDef !== undefined)\n return (\n <RouterLink\n href={resourceShowHref(app.registry, targetDef, to, keyString)}\n data-testid={testid}\n className={VIEW_CLASS}\n onClick={() => beforeOpen()}\n >\n {icon}\n <span className=\"sr-only\">{label}</span>\n </RouterLink>\n );\n if (by === undefined && targetDef !== undefined && linksToPage(app, targetDef))\n return (\n <ClaimedQuickLink\n href={resourceShowHref(app.registry, targetDef, to, keyString)}\n testid={testid}\n className={VIEW_CLASS}\n onOpen={() => open(keyString)}\n >\n {icon}\n <span className=\"sr-only\">{label}</span>\n </ClaimedQuickLink>\n );\n return (\n <button\n type=\"button\"\n className={VIEW_CLASS}\n data-testid={testid}\n aria-label={label}\n {...{ [QUICK_ANCHOR_ATTRIBUTE]: '' }}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n // No page to follow (or, for a `by` key, no id to build it from): a modified click is\n // nothing, never an overlay the user asked to avoid.\n if (!isPlainLeftClick(event)) return;\n if (by === undefined) {\n open(keyString);\n return;\n }\n requested.current = true;\n setAsked(true);\n // A key already read opens at once; the effect answers a click made before the read.\n if (rows !== undefined && rows.length === 1) {\n const next = selectKey(rows[0]?.[idField]);\n requested.current = false;\n if (next !== null) open(next);\n }\n }}\n >\n {icon}\n </button>\n );\n}\n","'use client';\n\nimport * as React from 'react';\nimport type { FixedFilterInput, ScopeSource, SearchDecl } from '@burojs/core';\nimport {\n type QuickSettledRow,\n useApp,\n useListAccess,\n useEntryGate,\n useOptionalT,\n useQuick,\n useTestIds,\n} from '@burojs/react';\nimport { toast } from '../notification/toaster.js';\nimport {\n CreatedOptionRead,\n type CreatedOptionResult,\n createdOptionFilter,\n createdOptionScope,\n} from './relation-hand-back.js';\nimport { namesHiddenField } from './search-access.js';\nimport { selectKey } from './relation-view-button.js';\n\n/** What the picker and its dialog share: one pending create per select (P6-34). */\nexport interface SelectCreate {\n readonly pending: boolean;\n /**\n * The hand-back read is forbidden: its filter names a field P5 hides from the user (the same\n * rule that stops the picker's own option read), or the access map is not ready. A blocked\n * select offers no \"+ Create\" and starts none, so no predicate on a hidden field is ever sent.\n */\n readonly blocked: boolean;\n /** Runs `open` unless a create of this select is already pending or the select is gone. */\n start(open: () => Promise<QuickSettledRow>): void;\n}\n\ninterface SelectCreateInput {\n readonly to: string;\n readonly by: string | undefined;\n /** The row field the select holds (`by`, else the target's id field). */\n readonly valueField: string;\n readonly idField: string;\n readonly fixedFilters: readonly FixedFilterInput[] | undefined;\n /** The select's read scope: the hand-back reads as the option list does. */\n readonly scope: ScopeSource;\n /** The record field the select writes, as the option list passes it. */\n readonly scopeField?: string;\n /**\n * The select's candidates gate is not ready (pending, empty, forbidden): the filters above\n * lack the candidate filters, so the hand-back must not read.\n */\n readonly held?: boolean;\n readonly searchDecl: SearchDecl | undefined;\n readonly searchContext: { readonly resource: string; readonly def: unknown };\n /** Called with the value to select, as a user's pick would. */\n readonly onValue: (value: string | number) => void;\n}\n\n/**\n * The select's one pending create: the latch (a ref, so a double click or a second render cannot\n * start two), the mounted guard (a result arriving after the select unmounted is ignored — the\n * record exists, nothing is selected), and the hand-back re-read through the select's own option\n * query. `reader` is mounted by the select while a created record is being handed back.\n */\nexport function useSelectCreate(input: SelectCreateInput): {\n readonly create: SelectCreate;\n readonly reader: React.ReactNode;\n} {\n const t = useOptionalT();\n const { to: target } = input;\n const [pending, setPending] = React.useState(false);\n const [created, setCreated] = React.useState<{ readonly id: string } | null>(null);\n const latch = React.useRef(false);\n const mounted = React.useRef(true);\n React.useEffect(() => {\n mounted.current = true;\n return () => {\n mounted.current = false;\n };\n }, []);\n const latest = React.useRef(input);\n latest.current = input;\n const access = useListAccess(target);\n // The hand-back's own filter, judged as the picker judges its option query.\n const blocked =\n input.held === true ||\n access.status !== 'ready' ||\n namesHiddenField(\n createdOptionScope({\n fixed: input.fixedFilters,\n searchDecl: input.searchDecl,\n searchContext: input.searchContext,\n }),\n (name) => access.fieldVisible(name),\n );\n const blockedRef = React.useRef(blocked);\n blockedRef.current = blocked;\n\n const release = React.useCallback(() => {\n latch.current = false;\n if (mounted.current) {\n setPending(false);\n setCreated(null);\n }\n }, []);\n\n const start = React.useCallback(\n (open: () => Promise<QuickSettledRow>) => {\n if (latch.current || !mounted.current || blockedRef.current) return;\n latch.current = true;\n setPending(true);\n let opened: Promise<QuickSettledRow>;\n try {\n opened = open();\n } catch (error) {\n // A synchronous throw (a `beforeOpen`, the host) must not leave the select locked.\n release();\n throw error;\n }\n void opened.then(\n (row) => {\n if (!mounted.current) {\n latch.current = false;\n return;\n }\n const id =\n row === null ? null : (selectKey(row[latest.current.idField]) ?? selectKey(row.id));\n if (id === null) release();\n else setCreated({ id });\n },\n () => release(),\n );\n },\n [release],\n );\n\n const settle = React.useCallback(\n (result: CreatedOptionResult) => {\n if (mounted.current) {\n if (result.kind === 'fits') latest.current.onValue(result.value);\n else if (result.kind === 'does-not-fit')\n toast(\n t('relationPicker.createdNotFitting', {\n defaultValue: 'The record was created but does not fit this field',\n }),\n );\n else\n toast.error(\n t('relationPicker.createdNotSelected', {\n defaultValue: 'The record was created but could not be selected',\n }),\n );\n }\n release();\n },\n [release, t],\n );\n\n const create = React.useMemo<SelectCreate>(\n () => ({ pending, blocked, start }),\n [pending, blocked, start],\n );\n const reader =\n created === null || blocked ? null : (\n <CreatedOptionRead\n key={created.id}\n to={target}\n filter={createdOptionFilter({\n fixed: input.fixedFilters,\n idField: input.idField,\n id: created.id,\n searchDecl: input.searchDecl,\n searchContext: input.searchContext,\n })}\n scope={input.scope}\n {...(input.scopeField === undefined ? {} : { scopeField: input.scopeField })}\n by={input.by}\n idField={input.idField}\n onSettled={settle}\n />\n );\n return { create, reader };\n}\n\n/** A string field a typed search text may fill: declared plain, not system, not an enum. */\nfunction plainStringField(def: unknown): boolean {\n if (def === null || typeof def !== 'object') return false;\n const field = def as {\n readonly kind?: unknown;\n readonly system?: unknown;\n readonly opts?: {\n readonly system?: unknown;\n readonly enum?: unknown;\n readonly localized?: unknown;\n };\n };\n return (\n field.kind === 'string' &&\n field.system !== true &&\n field.opts?.system !== true &&\n field.opts?.enum === undefined &&\n field.opts?.localized !== true\n );\n}\n\nexport interface RelationCreateButtonProps {\n readonly to: string;\n readonly fieldName: string;\n readonly create: SelectCreate;\n /** The trusted `defaults` tier: the registry field's static `eq` literals (P6-31). */\n readonly seeds: Readonly<Record<string, unknown>> | undefined;\n /** The text typed into the select's search, if any: prefills the display field as user input. */\n readonly search?: string;\n /** Runs before the overlay opens: closes the popover, returns focus to the trigger. */\n readonly beforeOpen: () => void;\n readonly className?: string;\n readonly testId?: string;\n}\n\n/**\n * \"+ create\" (P6-29): the target's `quick.create` as a new overlay above the form. Drawn only when\n * the entry gate is open (P3 4.4: `operations.create`, `views.quick.create`, the host wired, the\n * `create` availability); undecided or denied draws nothing and reads nothing. Disabled while one\n * create of the select is pending.\n */\nexport function RelationCreateButton(props: RelationCreateButtonProps): React.ReactElement | null {\n const gate = useEntryGate();\n const { to } = props;\n if (props.create.blocked || gate(to, 'create').state !== 'open') return null;\n return <CreateButton {...props} />;\n}\n\nfunction CreateButton({\n to,\n fieldName,\n create,\n seeds,\n search,\n beforeOpen,\n className,\n testId,\n}: RelationCreateButtonProps): React.ReactElement {\n const app = useApp();\n const t = useOptionalT();\n const tid = useTestIds();\n const quick = useQuick();\n const label = t('relationPicker.create', { defaultValue: '+ Create' });\n return (\n <button\n type=\"button\"\n data-testid={testId ?? tid.relationCreate(to, fieldName)}\n disabled={create.pending}\n className={className}\n onClick={() => {\n const text = search?.trim() ?? '';\n const displayField = (\n app.registry.get(to) as { readonly displayField?: unknown } | undefined\n )?.displayField;\n const fields = (\n app.registry.get(to) as { readonly fields?: Record<string, unknown> } | undefined\n )?.fields;\n const prefill =\n text.length > 0 &&\n typeof displayField === 'string' &&\n fields !== undefined &&\n Object.hasOwn(fields, displayField) &&\n plainStringField(fields[displayField])\n ? { [displayField]: text }\n : undefined;\n create.start(() => {\n beforeOpen();\n return quick.create(to, {\n ...(seeds === undefined || Object.keys(seeds).length === 0 ? {} : { defaults: seeds }),\n ...(prefill === undefined ? {} : { input: prefill }),\n });\n });\n }}\n >\n {label}\n </button>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAsBA,SAAgB,oBAAoB,OAMf;CACnB,MAAM,MAAM,mBAAmB,KAAK;CACpC,MAAM,OAAO;EAAE,OAAO,MAAM;EAAS,IAAI;EAAM,OAAO,MAAM;CAAG;CAC/D,OAAO,QAAQ,KAAA,IAAY,OAAQ,EAAE,KAAK,CAAC,KAAK,IAAI,EAAE;AACxD;AAMA,SAAgB,mBAAmB,OAIF;CAC/B,QAAA,GAAOA,aAAAA,kBAAAA,CAAkB;EACvB,QAAA,GAAOC,aAAAA,sBAAAA,CAAsB,MAAM,KAAK;EACxC,QAAQ;EACR,GAAI,MAAM,eAAe,KAAA,IAAY,CAAC,IAAI,EAAE,YAAY,MAAM,WAAW;EACzE,GAAI,MAAM,kBAAkB,KAAA,IAAY,CAAC,IAAI,EAAE,eAAe,MAAM,cAAuB;CAC7F,CAAC;AACH;AA6BA,SAAgB,kBAAkB,EAChC,IACA,QACA,OACA,YACA,IACA,SACA,aAC+B;CAC/B,MAAM,SAAA,GAAQC,cAAAA,QAAAA,CAAQ,IAAI;EAChB;EACR,YAAY;GAAE,MAAM;GAAU,MAAM;GAAG,UAAU;EAAE;EACnD;EACA,GAAI,eAAe,KAAA,IAAY,CAAC,IAAI,EAAE,WAAW;EACjD,OAAO;CACT,CAAC;CACD,MAAM,UAAUC,MAAM,OAAO,KAAK;CAClC,MAAM,SAASA,MAAM,OAAO,SAAS;CACrC,OAAO,UAAU;CACjB,MAAM,OAAQ,MAAM,MAChB;CACJ,MAAM,WAAW,SAAS,KAAA,KAAa,MAAM,iBAAiB,CAAC,MAAM;CACrE,MAAM,SAAS,MAAM,WAAW,CAAC,MAAM;CACvC,MAAM,gBAAgB;EACpB,IAAI,QAAQ,SAAS;EACrB,IAAI,QAAQ;GACV,QAAQ,UAAU;GAClB,OAAO,QAAQ,EAAE,MAAM,SAAS,CAAC;GACjC;EACF;EACA,IAAI,CAAC,UAAU;EACf,QAAQ,UAAU;EAClB,MAAM,QAAQ,KAAK,EAAE,GAAG,MAAM;EAC9B,OAAO,QACL,OAAO,UAAU,YAAY,OAAO,UAAU,WAC1C;GAAE,MAAM;GAAQ;EAAM,IACtB,EAAE,MAAM,eAAe,CAC7B;CACF,GAAG;EAAC;EAAU;EAAQ;EAAM;EAAI;CAAO,CAAC;CACxC,OAAO;AACT;;;AC/FA,SAAgB,UAAU,OAA+B;CACvD,IAAI,OAAO,UAAU,UAAU,OAAO,MAAM,WAAW,IAAI,OAAO;CAClE,IAAI,OAAO,UAAU,UAAU,OAAO,OAAO,SAAS,KAAK,IAAI,OAAO,KAAK,IAAI;CAC/E,OAAO;AACT;AAEA,MAAM,aAAaC,kBAAAA,GAAGC,eAAAA,eAAe;CAAE,SAAS;CAAW,MAAM;AAAO,CAAC,GAAG,UAAU;AAyBtF,SAAgB,mBAAmB,OAA2D;CAC5F,MAAM,QAAA,GAAOC,cAAAA,aAAAA,CAAa;CAC1B,MAAM,EAAE,IAAI,OAAO,OAAO;CAC1B,MAAM,UAAA,GAASC,cAAAA,cAAAA,CAAc,EAAE;CAC/B,MAAM,MAAM,UAAU,KAAK;CAC3B,IAAI,QAAQ,QAAQ,MAAM,SAAS,QAAQ,OAAO;CAElD,IAAI,OAAO,KAAA,KAAa,EAAE,OAAO,WAAW,WAAW,OAAO,aAAa,EAAE,IAAI,OAAO;CAExF,IADe,KAAK,IAAI,MACf,CAAC,CAAC,UAAU,QAAQ,OAAO;CAEpC,QAAO,GAAA,kBAAA,IAAA,CAAC,YAAD;EAAsB,GAAI;EAAO,WAAW;CAAM,GAAjC,GAAiC;AAC3D;AAEA,SAAS,WAAW,EAClB,IACA,IACA,WACA,WACA,YACA,MAAM,WAAW,WACqE;CACtF,MAAM,OAAA,GAAMC,cAAAA,OAAAA,CAAO;CACnB,MAAM,KAAA,GAAIC,cAAAA,aAAAA,CAAa;CACvB,MAAM,OAAA,GAAMC,cAAAA,WAAAA,CAAW;CACvB,MAAM,SAAA,GAAQC,cAAAA,SAAAA,CAAS;CACvB,MAAM,YAAA,GAAWC,cAAAA,iBAAAA,CAAiB;CAClC,MAAM,aAAaC,gBAAAA,iBAAiB;CACpC,MAAM,CAAC,OAAO,YAAYC,MAAM,SAAS,KAAK;CAC9C,MAAM,YAAYA,MAAM,OAAO,KAAK;CACpC,MAAM,YAAY,IAAI,SAAS,IAAI,EAAE;CACrC,MAAM,cAAc,WAAW,KAAA,EAAqD;CACpF,MAAM,UAAU,OAAO,eAAe,YAAY,WAAW,SAAS,IAAI,aAAa;CACvF,MAAM,QAAA,GAAOC,cAAAA,QAAAA,CAAQ,IAAI;EACvB,GAAI,SAAS,OAAO,KAAA,IAChB;GACE,QAAQ;IAAE,OAAO;IAAI,IAAI;IAAM,OAAO;GAAU;GAChD,YAAY;IAAE,MAAM;IAAU,MAAM;IAAG,UAAU;GAAE;EACrD,IACA,CAAC;EAEL,OAAO;EACP,SAAS,SAAS,OAAO,KAAA;EACzB,OAAO;CACT,CAAC;CAGD,MAAM,OADU,KAAK,iBAAiB,CAAC,KAAK,qBAAqB,CAAC,KAAK,aAElE,KAAK,MAA6E,OACnF,KAAA;CACJ,MAAM,OAAOD,MAAM,aAChB,OAAe;EACd,WAAW;EACX,IAAI,aAAa,QAAQ;GAEvB,IAAI,cAAc,KAAA,KAAaE,sBAAAA,YAAY,KAAK,SAAS,GACvD,UAAA,GAASC,aAAAA,iBAAAA,CAAiB,IAAI,UAAU,WAAW,IAAI,EAAE,CAAC;GAC5D;EACF;EACA,MAAM,KAAK,IAAI,EAAE;CACnB,GACA;EAAC;EAAY;EAAO;EAAI;EAAU;EAAU;EAAK;CAAS,CAC5D;CAEA,MAAM,gBAAgB;EACpB,IAAI,OAAO,KAAA,KAAa,CAAC,SAAS,SAAS,KAAA,KAAa,CAAC,UAAU,SAAS;EAC5E,UAAU,UAAU;EACpB,IAAI,KAAK,WAAW,GAAG;GACrB,IAAI,KAAK,SAAS,KAAK,QAAQ,IAAI,aAAa,cAC9C,QAAQ,MACN,YAAY,GAAG,0BAA0B,GAAG,GAAG,UAAU,yBAC3D;GACF;EACF;EACA,MAAM,KAAK,KAAK,EAAE,GAAG;EACrB,MAAM,OAAO,UAAU,EAAE;EACzB,IAAI,SAAS,MAAM,KAAK,IAAI;CAC9B,GAAG;EAAC;EAAI;EAAO;EAAM;EAAS;EAAW;EAAI;CAAI,CAAC;CAElD,MAAM,QAAQ,EAAE,uBAAuB,EAAE,cAAc,OAAO,CAAC;CAC/D,MAAM,QAAO,GAAA,kBAAA,IAAA,CAACC,oBAAAA,SAAD;EAAS,WAAU;EAAU,eAAA;CAAa,CAAA;CACvD,MAAM,SAAS,IAAI,aAAa,IAAI,SAAS;CAE7C,IAAI,aAAa,WAAW,cAAc,KAAA,KAAa,CAACF,sBAAAA,YAAY,KAAK,SAAS,IAAI,OAAO;CAC7F,IAAI,aAAa,UAAU,OAAO,KAAA,KAAa,cAAc,KAAA,GAC3D,QACE,GAAA,kBAAA,KAAA,CAAC,YAAD;EACE,OAAA,GAAMC,aAAAA,iBAAAA,CAAiB,IAAI,UAAU,WAAW,IAAI,SAAS;EAC7D,eAAa;EACb,WAAW;EACX,eAAe,WAAW;EAJ5B,UAAA,CAMG,OACD,GAAA,kBAAA,IAAA,CAAC,QAAD;GAAM,WAAU;GAAW,UAAA;EAAY,CAAA,CAC7B;;CAEhB,IAAI,OAAO,KAAA,KAAa,cAAc,KAAA,KAAaD,sBAAAA,YAAY,KAAK,SAAS,GAC3E,QACE,GAAA,kBAAA,KAAA,CAACG,sBAAAA,kBAAD;EACE,OAAA,GAAMF,aAAAA,iBAAAA,CAAiB,IAAI,UAAU,WAAW,IAAI,SAAS;EACrD;EACR,WAAW;EACX,cAAc,KAAK,SAAS;EAJ9B,UAAA,CAMG,OACD,GAAA,kBAAA,IAAA,CAAC,QAAD;GAAM,WAAU;GAAW,UAAA;EAAY,CAAA,CACvB;;CAEtB,QACE,GAAA,kBAAA,IAAA,CAAC,UAAD;EACE,MAAK;EACL,WAAW;EACX,eAAa;EACb,cAAY;GACLG,cAAAA,yBAAyB;EAChC,UAAU,UAAU;GAClB,MAAM,eAAe;GACrB,MAAM,gBAAgB;GAGtB,IAAI,CAACC,sBAAAA,iBAAiB,KAAK,GAAG;GAC9B,IAAI,OAAO,KAAA,GAAW;IACpB,KAAK,SAAS;IACd;GACF;GACA,UAAU,UAAU;GACpB,SAAS,IAAI;GAEb,IAAI,SAAS,KAAA,KAAa,KAAK,WAAW,GAAG;IAC3C,MAAM,OAAO,UAAU,KAAK,EAAE,GAAG,QAAQ;IACzC,UAAU,UAAU;IACpB,IAAI,SAAS,MAAM,KAAK,IAAI;GAC9B;EACF;EAEC,UAAA;CACK,CAAA;AAEZ;;;AChIA,SAAgB,gBAAgB,OAG9B;CACA,MAAM,KAAA,GAAIC,cAAAA,aAAAA,CAAa;CACvB,MAAM,EAAE,IAAI,WAAW;CACvB,MAAM,CAAC,SAAS,cAAcC,MAAM,SAAS,KAAK;CAClD,MAAM,CAAC,SAAS,cAAcA,MAAM,SAAyC,IAAI;CACjF,MAAM,QAAQA,MAAM,OAAO,KAAK;CAChC,MAAM,UAAUA,MAAM,OAAO,IAAI;CACjC,MAAM,gBAAgB;EACpB,QAAQ,UAAU;EAClB,aAAa;GACX,QAAQ,UAAU;EACpB;CACF,GAAG,CAAC,CAAC;CACL,MAAM,SAASA,MAAM,OAAO,KAAK;CACjC,OAAO,UAAU;CACjB,MAAM,UAAA,GAASC,cAAAA,cAAAA,CAAc,MAAM;CAEnC,MAAM,UACJ,MAAM,SAAS,QACf,OAAO,WAAW,WAClBC,sBAAAA,iBACE,mBAAmB;EACjB,OAAO,MAAM;EACb,YAAY,MAAM;EAClB,eAAe,MAAM;CACvB,CAAC,IACA,SAAS,OAAO,aAAa,IAAI,CACpC;CACF,MAAM,aAAaF,MAAM,OAAO,OAAO;CACvC,WAAW,UAAU;CAErB,MAAM,UAAUA,MAAM,kBAAkB;EACtC,MAAM,UAAU;EAChB,IAAI,QAAQ,SAAS;GACnB,WAAW,KAAK;GAChB,WAAW,IAAI;EACjB;CACF,GAAG,CAAC,CAAC;CAEL,MAAM,QAAQA,MAAM,aACjB,SAAyC;EACxC,IAAI,MAAM,WAAW,CAAC,QAAQ,WAAW,WAAW,SAAS;EAC7D,MAAM,UAAU;EAChB,WAAW,IAAI;EACf,IAAI;EACJ,IAAI;GACF,SAAS,KAAK;EAChB,SAAS,OAAO;GAEd,QAAQ;GACR,MAAM;EACR;EACA,OAAY,MACT,QAAQ;GACP,IAAI,CAAC,QAAQ,SAAS;IACpB,MAAM,UAAU;IAChB;GACF;GACA,MAAM,KACJ,QAAQ,OAAO,OAAQ,UAAU,IAAI,OAAO,QAAQ,QAAQ,KAAK,UAAU,IAAI,EAAE;GACnF,IAAI,OAAO,MAAM,QAAQ;QACpB,WAAW,EAAE,GAAG,CAAC;EACxB,SACM,QAAQ,CAChB;CACF,GACA,CAAC,OAAO,CACV;CAEA,MAAM,SAASA,MAAM,aAClB,WAAgC;EAC/B,IAAI,QAAQ,SAAS;GACnB,IAAI,OAAO,SAAS,QAAQ,OAAO,QAAQ,QAAQ,OAAO,KAAK;QAC1D,IAAI,OAAO,SAAS,gBACvB,CAAA,GAAA,OAAA,MAAA,CACE,EAAE,oCAAoC,EACpC,cAAc,qDAChB,CAAC,CACH;QAEA,OAAA,MAAM,MACJ,EAAE,qCAAqC,EACrC,cAAc,mDAChB,CAAC,CACH;EACJ;EACA,QAAQ;CACV,GACA,CAAC,SAAS,CAAC,CACb;CAyBA,OAAO;EAAE,QAvBMA,MAAM,eACZ;GAAE;GAAS;GAAS;EAAM,IACjC;GAAC;GAAS;GAAS;EAAK,CAqBZ;EAAG,QAlBf,YAAY,QAAQ,UAAU,QAC5B,GAAA,kBAAA,IAAA,CAAC,mBAAD;GAEE,IAAI;GACJ,QAAQ,oBAAoB;IAC1B,OAAO,MAAM;IACb,SAAS,MAAM;IACf,IAAI,QAAQ;IACZ,YAAY,MAAM;IAClB,eAAe,MAAM;GACvB,CAAC;GACD,OAAO,MAAM;GACb,GAAK,MAAM,eAAe,KAAA,IAAY,CAAC,IAAI,EAAE,YAAY,MAAM,WAAW;GAC1E,IAAI,MAAM;GACV,SAAS,MAAM;GACf,WAAW;EACZ,GAdM,QAAQ,EAcd;CAEmB;AAC1B;AAGA,SAAS,iBAAiB,KAAuB;CAC/C,IAAI,QAAQ,QAAQ,OAAO,QAAQ,UAAU,OAAO;CACpD,MAAM,QAAQ;CASd,OACE,MAAM,SAAS,YACf,MAAM,WAAW,QACjB,MAAM,MAAM,WAAW,QACvB,MAAM,MAAM,SAAS,KAAA,KACrB,MAAM,MAAM,cAAc;AAE9B;AAsBA,SAAgB,qBAAqB,OAA6D;CAChG,MAAM,QAAA,GAAOG,cAAAA,aAAAA,CAAa;CAC1B,MAAM,EAAE,OAAO;CACf,IAAI,MAAM,OAAO,WAAW,KAAK,IAAI,QAAQ,CAAC,CAAC,UAAU,QAAQ,OAAO;CACxE,QAAO,GAAA,kBAAA,IAAA,CAAC,cAAD,EAAc,GAAI,MAAQ,CAAA;AACnC;AAEA,SAAS,aAAa,EACpB,IACA,WACA,QACA,OACA,QACA,YACA,WACA,UACgD;CAChD,MAAM,OAAA,GAAMC,cAAAA,OAAAA,CAAO;CACnB,MAAM,KAAA,GAAIL,cAAAA,aAAAA,CAAa;CACvB,MAAM,OAAA,GAAMM,cAAAA,WAAAA,CAAW;CACvB,MAAM,SAAA,GAAQC,cAAAA,SAAAA,CAAS;CACvB,MAAM,QAAQ,EAAE,yBAAyB,EAAE,cAAc,WAAW,CAAC;CACrE,QACE,GAAA,kBAAA,IAAA,CAAC,UAAD;EACE,MAAK;EACL,eAAa,UAAU,IAAI,eAAe,IAAI,SAAS;EACvD,UAAU,OAAO;EACN;EACX,eAAe;GACb,MAAM,OAAO,QAAQ,KAAK,KAAK;GAC/B,MAAM,eACJ,IAAI,SAAS,IAAI,EAAE,CAAC,EACnB;GACH,MAAM,SACJ,IAAI,SAAS,IAAI,EAAE,CAAC,EACnB;GACH,MAAM,UACJ,KAAK,SAAS,KACd,OAAO,iBAAiB,YACxB,WAAW,KAAA,KACX,OAAO,OAAO,QAAQ,YAAY,KAClC,iBAAiB,OAAO,aAAa,IACjC,GAAG,eAAe,KAAK,IACvB,KAAA;GACN,OAAO,YAAY;IACjB,WAAW;IACX,OAAO,MAAM,OAAO,IAAI;KACtB,GAAI,UAAU,KAAA,KAAa,OAAO,KAAK,KAAK,CAAC,CAAC,WAAW,IAAI,CAAC,IAAI,EAAE,UAAU,MAAM;KACpF,GAAI,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,QAAQ;IACpD,CAAC;GACH,CAAC;EACH;EAEC,UAAA;CACK,CAAA;AAEZ"}
@@ -1,7 +1,7 @@
1
1
  import { l as cn } from "./use-theme-dnE3Od3I.js";
2
- import { d as useLinkComponent, n as toast } from "./toaster-CfCRLgR-.js";
2
+ import { n as toast, o as useLinkComponent } from "./toaster-C02XbB9r.js";
3
3
  import { n as buttonVariants } from "./button-MWVeZaqj.js";
4
- import { h as isPlainLeftClick, m as ClaimedQuickLink, o as linksToPage, t as namesHiddenField } from "./search-access-CURsWn-U.js";
4
+ import { a as linksToPage, m as isPlainLeftClick, p as ClaimedQuickLink, t as namesHiddenField } from "./search-access-CPPmfuvy.js";
5
5
  import { composeListFilter, normalizeFixedFilters, resourceShowHref } from "@burojs/core";
6
6
  import { QUICK_ANCHOR_ATTRIBUTE, useApp, useEntryGate, useList, useListAccess, useOptionalT, useQuick, useRouteNavigate, useTestIds } from "@burojs/react";
7
7
  import { IconEye } from "@tabler/icons-react";
@@ -25,7 +25,7 @@ function createdOptionScope(input) {
25
25
  ...input.searchContext === void 0 ? {} : { searchContext: input.searchContext }
26
26
  });
27
27
  }
28
- function CreatedOptionRead({ to, filter, ignoreScope, by, idField, onSettled }) {
28
+ function CreatedOptionRead({ to, filter, scope, scopeField, by, idField, onSettled }) {
29
29
  const query = useList(to, {
30
30
  filter,
31
31
  pagination: {
@@ -33,7 +33,8 @@ function CreatedOptionRead({ to, filter, ignoreScope, by, idField, onSettled })
33
33
  page: 1,
34
34
  pageSize: 1
35
35
  },
36
- ...ignoreScope ? { providerOptionsOverride: { ignoreScope: true } } : {},
36
+ scope,
37
+ ...scopeField === void 0 ? {} : { scopeField },
37
38
  retry: false
38
39
  });
39
40
  const settled = React.useRef(false);
@@ -89,7 +90,7 @@ function RelationViewButton(props) {
89
90
  keyString: key
90
91
  }, key);
91
92
  }
92
- function ViewButton({ to, by, ignoreScope, fieldName, keyString, beforeOpen, open: openMode = "quick" }) {
93
+ function ViewButton({ to, by, fieldName, keyString, beforeOpen, open: openMode = "quick" }) {
93
94
  const app = useApp();
94
95
  const t = useOptionalT();
95
96
  const tid = useTestIds();
@@ -114,7 +115,7 @@ function ViewButton({ to, by, ignoreScope, fieldName, keyString, beforeOpen, ope
114
115
  pageSize: 2
115
116
  }
116
117
  } : {},
117
- ...ignoreScope === true ? { providerOptionsOverride: { ignoreScope: true } } : {},
118
+ scope: "none",
118
119
  enabled: asked && by !== void 0,
119
120
  retry: false
120
121
  });
@@ -286,7 +287,8 @@ function useSelectCreate(input) {
286
287
  searchDecl: input.searchDecl,
287
288
  searchContext: input.searchContext
288
289
  }),
289
- ignoreScope: input.fixedFilters !== void 0 && input.fixedFilters.length > 0,
290
+ scope: input.scope,
291
+ ...input.scopeField === void 0 ? {} : { scopeField: input.scopeField },
290
292
  by: input.by,
291
293
  idField: input.idField,
292
294
  onSettled: settle
@@ -334,4 +336,4 @@ function CreateButton({ to, fieldName, create, seeds, search, beforeOpen, classN
334
336
  //#endregion
335
337
  export { selectKey as i, useSelectCreate as n, RelationViewButton as r, RelationCreateButton as t };
336
338
 
337
- //# sourceMappingURL=relation-create-Bg-eEJLs.js.map
339
+ //# sourceMappingURL=relation-create-h6F9B4C4.js.map