@burojs/ui-shadcn 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/dist/{candidates-relation-picker-CGXItMN0.js → candidates-relation-picker-QvoY2bOQ.js} +3 -3
  2. package/dist/{candidates-relation-picker-CGXItMN0.js.map → candidates-relation-picker-QvoY2bOQ.js.map} +1 -1
  3. package/dist/{candidates-relation-picker-C47mF260.cjs → candidates-relation-picker-pEAWKQEY.cjs} +3 -3
  4. package/dist/{candidates-relation-picker-C47mF260.cjs.map → candidates-relation-picker-pEAWKQEY.cjs.map} +1 -1
  5. package/dist/{check-confirm-dialog-CtiRzOAt.js → check-confirm-dialog-B-CbJTln.js} +59 -6
  6. package/dist/{check-confirm-dialog-CtiRzOAt.js.map → check-confirm-dialog-B-CbJTln.js.map} +1 -1
  7. package/dist/{check-confirm-dialog-BT04Mieo.cjs → check-confirm-dialog-W-8WOmGh.cjs} +64 -5
  8. package/dist/{check-confirm-dialog-BT04Mieo.cjs.map → check-confirm-dialog-W-8WOmGh.cjs.map} +1 -1
  9. package/dist/{filter-builder-z3Axzf9Y.js → filter-builder-04nas3eq.js} +14 -6
  10. package/dist/filter-builder-04nas3eq.js.map +1 -0
  11. package/dist/{filter-builder-ByGhxLf_.cjs → filter-builder-DQX-TMFh.cjs} +14 -6
  12. package/dist/filter-builder-DQX-TMFh.cjs.map +1 -0
  13. package/dist/{flow-runtime-DrUWyTS0.js → flow-runtime-BEIyym7d.js} +3 -3
  14. package/dist/{flow-runtime-DrUWyTS0.js.map → flow-runtime-BEIyym7d.js.map} +1 -1
  15. package/dist/{flow-runtime-BVFjMU5-.cjs → flow-runtime-DyNIYfUP.cjs} +3 -3
  16. package/dist/{flow-runtime-BVFjMU5-.cjs.map → flow-runtime-DyNIYfUP.cjs.map} +1 -1
  17. package/dist/{flow-screen-3fk6J33y.js → flow-screen-DY1Z9PbG.js} +53 -14
  18. package/dist/flow-screen-DY1Z9PbG.js.map +1 -0
  19. package/dist/{flow-screen-6y5E_HT6.cjs → flow-screen-FE5Xhb3t.cjs} +52 -13
  20. package/dist/flow-screen-FE5Xhb3t.cjs.map +1 -0
  21. package/dist/index.cjs +54 -71
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.d.cts +49 -10
  24. package/dist/index.d.ts +49 -10
  25. package/dist/index.js +54 -72
  26. package/dist/index.js.map +1 -1
  27. package/dist/{inline-flow-host-YnnvWjdU.js → inline-flow-host-D6u-RlsV.js} +3 -3
  28. package/dist/{inline-flow-host-YnnvWjdU.js.map → inline-flow-host-D6u-RlsV.js.map} +1 -1
  29. package/dist/{inline-flow-host-C4KmZIYE.cjs → inline-flow-host-yVLo6-sM.cjs} +3 -3
  30. package/dist/{inline-flow-host-C4KmZIYE.cjs.map → inline-flow-host-yVLo6-sM.cjs.map} +1 -1
  31. package/dist/{lazy-relation-picker-dialog-DN4bvQfg.js → lazy-relation-picker-dialog-BaORufxQ.js} +2 -2
  32. package/dist/{lazy-relation-picker-dialog-DN4bvQfg.js.map → lazy-relation-picker-dialog-BaORufxQ.js.map} +1 -1
  33. package/dist/{lazy-relation-picker-dialog-BAKBRn3V.cjs → lazy-relation-picker-dialog-C_VlGlDz.cjs} +2 -2
  34. package/dist/{lazy-relation-picker-dialog-BAKBRn3V.cjs.map → lazy-relation-picker-dialog-C_VlGlDz.cjs.map} +1 -1
  35. package/dist/{page-flow-route-CtEfqAvU.js → page-flow-route-CyMzUidK.js} +7 -7
  36. package/dist/page-flow-route-CyMzUidK.js.map +1 -0
  37. package/dist/{page-flow-route-DEjAxHe3.cjs → page-flow-route-OFx7h7Ja.cjs} +6 -6
  38. package/dist/page-flow-route-OFx7h7Ja.cjs.map +1 -0
  39. package/dist/{place-node-Bhl8B3fF.cjs → place-node-BZF5Af6x.cjs} +67 -23
  40. package/dist/place-node-BZF5Af6x.cjs.map +1 -0
  41. package/dist/{place-node-BdxT-30h.js → place-node-DRjmJGQ_.js} +69 -25
  42. package/dist/place-node-DRjmJGQ_.js.map +1 -0
  43. package/dist/{related-list-cards-BvkD5OcC.js → related-list-cards-2hLitVkg.js} +3 -3
  44. package/dist/{related-list-cards-BvkD5OcC.js.map → related-list-cards-2hLitVkg.js.map} +1 -1
  45. package/dist/{related-list-cards-Bc_vfCE_.cjs → related-list-cards-xVvgSlu-.cjs} +3 -3
  46. package/dist/{related-list-cards-Bc_vfCE_.cjs.map → related-list-cards-xVvgSlu-.cjs.map} +1 -1
  47. package/dist/{related-list-timeline-DCrwN9oO.js → related-list-timeline-CxJqe6eK.js} +4 -4
  48. package/dist/related-list-timeline-CxJqe6eK.js.map +1 -0
  49. package/dist/{related-list-timeline-k0DtnxTs.cjs → related-list-timeline-Dsf5WewG.cjs} +4 -4
  50. package/dist/related-list-timeline-Dsf5WewG.cjs.map +1 -0
  51. package/dist/{related-rows-BW9Jr07T.cjs → related-rows-DDhp9axl.cjs} +4 -4
  52. package/dist/{related-rows-BW9Jr07T.cjs.map → related-rows-DDhp9axl.cjs.map} +1 -1
  53. package/dist/{related-rows-CPE-9FFr.js → related-rows-DL6CWsrj.js} +4 -4
  54. package/dist/{related-rows-CPE-9FFr.js.map → related-rows-DL6CWsrj.js.map} +1 -1
  55. package/dist/{relation-create-C43cdPQt.js → relation-create-6WicROWA.js} +33 -5
  56. package/dist/relation-create-6WicROWA.js.map +1 -0
  57. package/dist/{relation-create-DDEYcKfw.cjs → relation-create-_SFuPQGM.cjs} +37 -3
  58. package/dist/relation-create-_SFuPQGM.cjs.map +1 -0
  59. package/dist/{relation-many-picker-Br-zBHxT.cjs → relation-many-picker-BBNsmkaX.cjs} +12 -10
  60. package/dist/relation-many-picker-BBNsmkaX.cjs.map +1 -0
  61. package/dist/{relation-many-picker-BlrGRwMV.js → relation-many-picker-mGEQDWo2.js} +12 -10
  62. package/dist/relation-many-picker-mGEQDWo2.js.map +1 -0
  63. package/dist/{relation-picker-x7P5HKie.js → relation-picker-BbO41cFV.js} +13 -10
  64. package/dist/relation-picker-BbO41cFV.js.map +1 -0
  65. package/dist/{relation-picker-dialog-CyKliBkN.js → relation-picker-dialog-BgSG_8bU.js} +5 -5
  66. package/dist/relation-picker-dialog-BgSG_8bU.js.map +1 -0
  67. package/dist/{relation-picker-dialog-DimVQF9Y.cjs → relation-picker-dialog-Duqy2r0n.cjs} +5 -5
  68. package/dist/relation-picker-dialog-Duqy2r0n.cjs.map +1 -0
  69. package/dist/{relation-picker-ADjxI_TI.cjs → relation-picker-jk9D_uwn.cjs} +13 -10
  70. package/dist/relation-picker-jk9D_uwn.cjs.map +1 -0
  71. package/dist/{relation-select-Cr3CfNLy.cjs → relation-select-C3aV18kT.cjs} +2 -2
  72. package/dist/{relation-select-Cr3CfNLy.cjs.map → relation-select-C3aV18kT.cjs.map} +1 -1
  73. package/dist/{relation-select-B8Fq4o-t.js → relation-select-CjQT9LpS.js} +2 -2
  74. package/dist/{relation-select-B8Fq4o-t.js.map → relation-select-CjQT9LpS.js.map} +1 -1
  75. package/dist/{resource-page-router-BRpUnhay.js → resource-page-router-CzaNATSp.js} +71 -19
  76. package/dist/resource-page-router-CzaNATSp.js.map +1 -0
  77. package/dist/{resource-page-router-qEd2xb55.cjs → resource-page-router-dmVIeu5s.cjs} +81 -17
  78. package/dist/resource-page-router-dmVIeu5s.cjs.map +1 -0
  79. package/dist/{success-notices-Dl3M1fZP.cjs → success-notices-Cl4b6MLQ.cjs} +3 -2
  80. package/dist/success-notices-Cl4b6MLQ.cjs.map +1 -0
  81. package/dist/{success-notices-LDEgEkc4.js → success-notices-CrcWOGSo.js} +3 -2
  82. package/dist/success-notices-CrcWOGSo.js.map +1 -0
  83. package/dist/{use-dialog-filter-state-B_MqzHaT.js → use-dialog-filter-state-CJoeY-1j.js} +2 -2
  84. package/dist/{use-dialog-filter-state-B_MqzHaT.js.map → use-dialog-filter-state-CJoeY-1j.js.map} +1 -1
  85. package/dist/{use-dialog-filter-state-tNvqAAjh.cjs → use-dialog-filter-state-lsTJxrB4.cjs} +2 -2
  86. package/dist/{use-dialog-filter-state-tNvqAAjh.cjs.map → use-dialog-filter-state-lsTJxrB4.cjs.map} +1 -1
  87. package/dist/{use-record-subtitle-bfwIoUme.cjs → use-record-subtitle-BJ9rnj6F.cjs} +5 -8
  88. package/dist/use-record-subtitle-BJ9rnj6F.cjs.map +1 -0
  89. package/dist/{use-record-subtitle-gIaCGgbI.js → use-record-subtitle-w3ZhXNlf.js} +5 -8
  90. package/dist/use-record-subtitle-w3ZhXNlf.js.map +1 -0
  91. package/package.json +9 -9
  92. package/dist/filter-builder-ByGhxLf_.cjs.map +0 -1
  93. package/dist/filter-builder-z3Axzf9Y.js.map +0 -1
  94. package/dist/flow-screen-3fk6J33y.js.map +0 -1
  95. package/dist/flow-screen-6y5E_HT6.cjs.map +0 -1
  96. package/dist/page-flow-route-CtEfqAvU.js.map +0 -1
  97. package/dist/page-flow-route-DEjAxHe3.cjs.map +0 -1
  98. package/dist/place-node-BdxT-30h.js.map +0 -1
  99. package/dist/place-node-Bhl8B3fF.cjs.map +0 -1
  100. package/dist/related-list-timeline-DCrwN9oO.js.map +0 -1
  101. package/dist/related-list-timeline-k0DtnxTs.cjs.map +0 -1
  102. package/dist/relation-create-C43cdPQt.js.map +0 -1
  103. package/dist/relation-create-DDEYcKfw.cjs.map +0 -1
  104. package/dist/relation-many-picker-BlrGRwMV.js.map +0 -1
  105. package/dist/relation-many-picker-Br-zBHxT.cjs.map +0 -1
  106. package/dist/relation-picker-ADjxI_TI.cjs.map +0 -1
  107. package/dist/relation-picker-dialog-CyKliBkN.js.map +0 -1
  108. package/dist/relation-picker-dialog-DimVQF9Y.cjs.map +0 -1
  109. package/dist/relation-picker-x7P5HKie.js.map +0 -1
  110. package/dist/resource-page-router-BRpUnhay.js.map +0 -1
  111. package/dist/resource-page-router-qEd2xb55.cjs.map +0 -1
  112. package/dist/success-notices-Dl3M1fZP.cjs.map +0 -1
  113. package/dist/success-notices-LDEgEkc4.js.map +0 -1
  114. package/dist/use-record-subtitle-bfwIoUme.cjs.map +0 -1
  115. package/dist/use-record-subtitle-gIaCGgbI.js.map +0 -1
@@ -1,5 +1,5 @@
1
- import { pt as RELATED_GRID_CLASS } from "./place-node-BdxT-30h.js";
2
- import { i as useProjectedRows, n as RowContent, r as RowOpener, t as ITEM_LAYER_CLASS } from "./related-rows-CPE-9FFr.js";
1
+ import { pt as RELATED_GRID_CLASS } from "./place-node-DRjmJGQ_.js";
2
+ import { i as useProjectedRows, n as RowContent, r as RowOpener, t as ITEM_LAYER_CLASS } from "./related-rows-DL6CWsrj.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
@@ -44,4 +44,4 @@ function RelatedCards({ resource, placementKey, rows, item, columns, rowQuick, r
44
44
  //#endregion
45
45
  export { RelatedCards };
46
46
 
47
- //# sourceMappingURL=related-list-cards-BvkD5OcC.js.map
47
+ //# sourceMappingURL=related-list-cards-2hLitVkg.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"related-list-cards-BvkD5OcC.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 empty,\n}: RelatedRowsProps): ReactElement {\n const ids = useTestIds();\n const { project, drawn, title } = useProjectedRows(resource, rows, item);\n if (rows.length === 0 && empty !== undefined)\n return (\n <p data-buro-region=\"empty\" className=\"text-sm text-muted-foreground\">\n {empty}\n </p>\n );\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,SACA,SACiC;CACjC,MAAM,MAAM,WAAW;CACvB,MAAM,EAAE,SAAS,OAAO,UAAU,iBAAiB,UAAU,MAAM,IAAI;CACvE,IAAI,KAAK,WAAW,KAAK,UAAU,KAAA,GACjC,OACE,IAAC,KAAD;EAAG,oBAAiB;EAAQ,WAAU;EACnC,UAAA;CACA,CAAA;CAEP,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-2hLitVkg.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 empty,\n}: RelatedRowsProps): ReactElement {\n const ids = useTestIds();\n const { project, drawn, title } = useProjectedRows(resource, rows, item);\n if (rows.length === 0 && empty !== undefined)\n return (\n <p data-buro-region=\"empty\" className=\"text-sm text-muted-foreground\">\n {empty}\n </p>\n );\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,SACA,SACiC;CACjC,MAAM,MAAM,WAAW;CACvB,MAAM,EAAE,SAAS,OAAO,UAAU,iBAAiB,UAAU,MAAM,IAAI;CACvE,IAAI,KAAK,WAAW,KAAK,UAAU,KAAA,GACjC,OACE,IAAC,KAAD;EAAG,oBAAiB;EAAQ,WAAU;EACnC,UAAA;CACA,CAAA;CAEP,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-Bhl8B3fF.cjs");
2
- const require_related_rows = require("./related-rows-BW9Jr07T.cjs");
1
+ const require_place_node = require("./place-node-BZF5Af6x.cjs");
2
+ const require_related_rows = require("./related-rows-DDhp9axl.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
@@ -44,4 +44,4 @@ function RelatedCards({ resource, placementKey, rows, item, columns, rowQuick, r
44
44
  //#endregion
45
45
  exports.RelatedCards = RelatedCards;
46
46
 
47
- //# sourceMappingURL=related-list-cards-Bc_vfCE_.cjs.map
47
+ //# sourceMappingURL=related-list-cards-xVvgSlu-.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"related-list-cards-Bc_vfCE_.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 empty,\n}: RelatedRowsProps): ReactElement {\n const ids = useTestIds();\n const { project, drawn, title } = useProjectedRows(resource, rows, item);\n if (rows.length === 0 && empty !== undefined)\n return (\n <p data-buro-region=\"empty\" className=\"text-sm text-muted-foreground\">\n {empty}\n </p>\n );\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,SACA,SACiC;CACjC,MAAM,OAAA,GAAMC,cAAAA,WAAAA,CAAW;CACvB,MAAM,EAAE,SAAS,OAAO,UAAUC,qBAAAA,iBAAiB,UAAU,MAAM,IAAI;CACvE,IAAI,KAAK,WAAW,KAAK,UAAU,KAAA,GACjC,QACE,GAAA,kBAAA,IAAA,CAAC,KAAD;EAAG,oBAAiB;EAAQ,WAAU;EACnC,UAAA;CACA,CAAA;CAEP,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-xVvgSlu-.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 empty,\n}: RelatedRowsProps): ReactElement {\n const ids = useTestIds();\n const { project, drawn, title } = useProjectedRows(resource, rows, item);\n if (rows.length === 0 && empty !== undefined)\n return (\n <p data-buro-region=\"empty\" className=\"text-sm text-muted-foreground\">\n {empty}\n </p>\n );\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,SACA,SACiC;CACjC,MAAM,OAAA,GAAMC,cAAAA,WAAAA,CAAW;CACvB,MAAM,EAAE,SAAS,OAAO,UAAUC,qBAAAA,iBAAiB,UAAU,MAAM,IAAI;CACvE,IAAI,KAAK,WAAW,KAAK,UAAU,KAAA,GACjC,QACE,GAAA,kBAAA,IAAA,CAAC,KAAD;EAAG,oBAAiB;EAAQ,WAAU;EACnC,UAAA;CACA,CAAA;CAEP,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,6 +1,6 @@
1
- import { mt as RelatedTimelineSkeleton } from "./place-node-BdxT-30h.js";
2
- import { m as localeTag } from "./filter-builder-z3Axzf9Y.js";
3
- import { i as useProjectedRows, n as RowContent, r as RowOpener, t as ITEM_LAYER_CLASS } from "./related-rows-CPE-9FFr.js";
1
+ import { mt as RelatedTimelineSkeleton } from "./place-node-DRjmJGQ_.js";
2
+ import { m as localeTag } from "./filter-builder-04nas3eq.js";
3
+ import { i as useProjectedRows, n as RowContent, r as RowOpener, t as ITEM_LAYER_CLASS } from "./related-rows-DL6CWsrj.js";
4
4
  import { canonicalInstant, dayOfInstant, declaredField, epochMsToInstant, formatTimeValue, instantToWall, isCalendarDate, resolveTimeZone } from "@burojs/core";
5
5
  import { useOptionalLocale, useOptionalT, useTestIds, useTimeContext } from "@burojs/react";
6
6
  import { useMemo } from "react";
@@ -164,4 +164,4 @@ function RelatedTimeline({ resource, placementKey, rows, item, columns, rowQuick
164
164
  //#endregion
165
165
  export { RelatedTimeline };
166
166
 
167
- //# sourceMappingURL=related-list-timeline-DCrwN9oO.js.map
167
+ //# sourceMappingURL=related-list-timeline-CxJqe6eK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"related-list-timeline-CxJqe6eK.js","names":[],"sources":["../src/blocks/related-list-timeline.tsx"],"sourcesContent":["'use client';\nimport {\n type TimeZoneName,\n canonicalInstant,\n dayOfInstant,\n declaredField,\n epochMsToInstant,\n formatTimeValue,\n instantToWall,\n isCalendarDate,\n resolveTimeZone,\n} from '@burojs/core';\nimport { normaliseFieldZone } from '@burojs/core/internal';\nimport { useOptionalLocale, useOptionalT, useTestIds, useTimeContext } from '@burojs/react';\nimport { type ReactElement, useMemo } from 'react';\nimport { localeTag } from '../fields/format.js';\nimport {\n ITEM_LAYER_CLASS,\n type ListRow,\n type RelatedRowsProps,\n RowContent,\n RowOpener,\n useProjectedRows,\n} from './related-rows.js';\nimport { RelatedTimelineSkeleton } from './related-skeletons.js';\n\n/**\n * The day an axis value falls on, in `zone`: a calendar date names its own day and has no time\n * (`instant` absent); anything else is an instant, read in the zone. Undefined for a value that is\n * neither.\n */\nfunction dayOf(\n value: unknown,\n zone: TimeZoneName,\n): { readonly day: string; readonly instant: string | undefined } | undefined {\n if (typeof value === 'string' && isCalendarDate(value)) return { day: value, instant: undefined };\n const instant =\n typeof value === 'string'\n ? canonicalInstant(value)\n : typeof value === 'number' && Number.isFinite(value)\n ? canonicalInstant(epochMsToInstant(value))\n : value instanceof Date && !Number.isNaN(value.getTime())\n ? canonicalInstant(value.toISOString())\n : undefined;\n return instant === undefined ? undefined : { day: dayOfInstant(instant, zone), instant };\n}\n\ninterface Group {\n /** The calendar day (`YYYY-MM-DD`) the group names, or `undated`. */\n readonly key: string;\n /** The day the group names; undefined for the undated group. */\n readonly heading: string | undefined;\n readonly entries: {\n readonly row: ListRow;\n /** The canonical instant of a timed entry, in `zone`. */\n readonly instant: string | undefined;\n readonly zone: TimeZoneName | undefined;\n }[];\n}\n\n/**\n * A related list as a timeline (`view: 'timeline'`, P6 3.13): one column grouped by the day of\n * `axis` in the axis field's zone (REF-118 §4.2; a calendar date names its own day), the first field of the list's effective initial sort (a placement's own\n * `initial.sort`, else the target's `views.list.initial.sort`, T4 D9), 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 empty,\n axis,\n}: RelatedRowsProps & {\n /** The axis field; undefined (no initial sort) draws no group. */\n readonly axis: string | undefined;\n}): ReactElement {\n const ids = useTestIds();\n const t = useOptionalT();\n const locale = useOptionalLocale();\n const { def, project, drawn, title } = useProjectedRows(resource, rows, item);\n const timeContext = useTimeContext();\n const viewerZone =\n timeContext.levels.user ?? timeContext.levels.app ?? timeContext.levels.platform;\n const tag = localeTag(locale);\n // The axis field's own zone (REF-118 §4.2), a `ref('record', …)` read from each row.\n const axisZone = useMemo(() => {\n const declaration =\n axis === undefined || def === undefined ? undefined : declaredField(def, axis);\n return typeof declaration === 'object' && declaration !== null && 'zone' in declaration\n ? normaliseFieldZone(declaration.zone)\n : undefined;\n }, [def, axis]);\n const { groups, pending } = useMemo(() => {\n const out: Group[] = [];\n let waiting = false;\n if (axis === undefined) return { groups: out, pending: waiting };\n const undated: Group['entries'] = [];\n for (const row of rows) {\n const projected = project(row);\n const zone = resolveTimeZone(timeContext.levels, axisZone, {\n ...timeContext.sources,\n record: { status: 'ready', value: projected, refreshing: false },\n });\n if (zone.status === 'pending') {\n waiting = true;\n continue;\n }\n const day = dayOf(projected[axis], zone.zone);\n if (day === undefined) {\n undated.push({ row, instant: undefined, zone: undefined });\n continue;\n }\n let group = out.find((entry) => entry.key === day.day);\n if (group === undefined) {\n group = { key: day.day, heading: day.day, entries: [] };\n out.push(group);\n }\n group.entries.push({ row, instant: day.instant, zone: zone.zone });\n }\n if (undated.length > 0) out.push({ key: 'undated', heading: undefined, entries: undated });\n return { groups: out, pending: waiting };\n }, [rows, axis, project, axisZone, timeContext]);\n const headingOf = (group: Group): string =>\n group.heading === undefined\n ? t('timeline.undated', { defaultValue: 'Undated' })\n : (formatTimeValue('date', group.heading, {\n zone: viewerZone,\n viewerZone,\n locale: tag,\n params: { dateStyle: 'full' },\n }) ?? group.heading);\n const timeOf = (instant: string, zone: TimeZoneName): string =>\n formatTimeValue('time', instantToWall(instant, zone).time, {\n zone,\n viewerZone,\n locale: tag,\n params: { timeStyle: 'short' },\n }) ?? instant;\n if (pending) return <RelatedTimelineSkeleton />;\n if (groups.length === 0)\n return (\n <p data-buro-region=\"empty\" className=\"text-sm text-muted-foreground\">\n {(rows.length === 0 ? empty : undefined) ??\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, instant, zone }) => (\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 {instant !== undefined && zone !== undefined ? (\n <time\n dateTime={instant}\n className=\"w-16 shrink-0 whitespace-nowrap text-xs tabular-nums text-muted-foreground\"\n >\n {timeOf(instant, zone)}\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,6 +1,6 @@
1
- const require_place_node = require("./place-node-Bhl8B3fF.cjs");
2
- const require_filter_builder = require("./filter-builder-ByGhxLf_.cjs");
3
- const require_related_rows = require("./related-rows-BW9Jr07T.cjs");
1
+ const require_place_node = require("./place-node-BZF5Af6x.cjs");
2
+ const require_filter_builder = require("./filter-builder-DQX-TMFh.cjs");
3
+ const require_related_rows = require("./related-rows-DDhp9axl.cjs");
4
4
  let _burojs_core = require("@burojs/core");
5
5
  let _burojs_react = require("@burojs/react");
6
6
  let react = require("react");
@@ -164,4 +164,4 @@ function RelatedTimeline({ resource, placementKey, rows, item, columns, rowQuick
164
164
  //#endregion
165
165
  exports.RelatedTimeline = RelatedTimeline;
166
166
 
167
- //# sourceMappingURL=related-list-timeline-k0DtnxTs.cjs.map
167
+ //# sourceMappingURL=related-list-timeline-Dsf5WewG.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"related-list-timeline-Dsf5WewG.cjs","names":["isCalendarDate","canonicalInstant","epochMsToInstant","dayOfInstant","useTestIds","useOptionalT","useOptionalLocale","useProjectedRows","useTimeContext","localeTag","useMemo","declaredField","normaliseFieldZone","resolveTimeZone","formatTimeValue","instantToWall","RelatedTimelineSkeleton","RowOpener","ITEM_LAYER_CLASS","RowContent"],"sources":["../src/blocks/related-list-timeline.tsx"],"sourcesContent":["'use client';\nimport {\n type TimeZoneName,\n canonicalInstant,\n dayOfInstant,\n declaredField,\n epochMsToInstant,\n formatTimeValue,\n instantToWall,\n isCalendarDate,\n resolveTimeZone,\n} from '@burojs/core';\nimport { normaliseFieldZone } from '@burojs/core/internal';\nimport { useOptionalLocale, useOptionalT, useTestIds, useTimeContext } from '@burojs/react';\nimport { type ReactElement, useMemo } from 'react';\nimport { localeTag } from '../fields/format.js';\nimport {\n ITEM_LAYER_CLASS,\n type ListRow,\n type RelatedRowsProps,\n RowContent,\n RowOpener,\n useProjectedRows,\n} from './related-rows.js';\nimport { RelatedTimelineSkeleton } from './related-skeletons.js';\n\n/**\n * The day an axis value falls on, in `zone`: a calendar date names its own day and has no time\n * (`instant` absent); anything else is an instant, read in the zone. Undefined for a value that is\n * neither.\n */\nfunction dayOf(\n value: unknown,\n zone: TimeZoneName,\n): { readonly day: string; readonly instant: string | undefined } | undefined {\n if (typeof value === 'string' && isCalendarDate(value)) return { day: value, instant: undefined };\n const instant =\n typeof value === 'string'\n ? canonicalInstant(value)\n : typeof value === 'number' && Number.isFinite(value)\n ? canonicalInstant(epochMsToInstant(value))\n : value instanceof Date && !Number.isNaN(value.getTime())\n ? canonicalInstant(value.toISOString())\n : undefined;\n return instant === undefined ? undefined : { day: dayOfInstant(instant, zone), instant };\n}\n\ninterface Group {\n /** The calendar day (`YYYY-MM-DD`) the group names, or `undated`. */\n readonly key: string;\n /** The day the group names; undefined for the undated group. */\n readonly heading: string | undefined;\n readonly entries: {\n readonly row: ListRow;\n /** The canonical instant of a timed entry, in `zone`. */\n readonly instant: string | undefined;\n readonly zone: TimeZoneName | undefined;\n }[];\n}\n\n/**\n * A related list as a timeline (`view: 'timeline'`, P6 3.13): one column grouped by the day of\n * `axis` in the axis field's zone (REF-118 §4.2; a calendar date names its own day), the first field of the list's effective initial sort (a placement's own\n * `initial.sort`, else the target's `views.list.initial.sort`, T4 D9), 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 empty,\n axis,\n}: RelatedRowsProps & {\n /** The axis field; undefined (no initial sort) draws no group. */\n readonly axis: string | undefined;\n}): ReactElement {\n const ids = useTestIds();\n const t = useOptionalT();\n const locale = useOptionalLocale();\n const { def, project, drawn, title } = useProjectedRows(resource, rows, item);\n const timeContext = useTimeContext();\n const viewerZone =\n timeContext.levels.user ?? timeContext.levels.app ?? timeContext.levels.platform;\n const tag = localeTag(locale);\n // The axis field's own zone (REF-118 §4.2), a `ref('record', …)` read from each row.\n const axisZone = useMemo(() => {\n const declaration =\n axis === undefined || def === undefined ? undefined : declaredField(def, axis);\n return typeof declaration === 'object' && declaration !== null && 'zone' in declaration\n ? normaliseFieldZone(declaration.zone)\n : undefined;\n }, [def, axis]);\n const { groups, pending } = useMemo(() => {\n const out: Group[] = [];\n let waiting = false;\n if (axis === undefined) return { groups: out, pending: waiting };\n const undated: Group['entries'] = [];\n for (const row of rows) {\n const projected = project(row);\n const zone = resolveTimeZone(timeContext.levels, axisZone, {\n ...timeContext.sources,\n record: { status: 'ready', value: projected, refreshing: false },\n });\n if (zone.status === 'pending') {\n waiting = true;\n continue;\n }\n const day = dayOf(projected[axis], zone.zone);\n if (day === undefined) {\n undated.push({ row, instant: undefined, zone: undefined });\n continue;\n }\n let group = out.find((entry) => entry.key === day.day);\n if (group === undefined) {\n group = { key: day.day, heading: day.day, entries: [] };\n out.push(group);\n }\n group.entries.push({ row, instant: day.instant, zone: zone.zone });\n }\n if (undated.length > 0) out.push({ key: 'undated', heading: undefined, entries: undated });\n return { groups: out, pending: waiting };\n }, [rows, axis, project, axisZone, timeContext]);\n const headingOf = (group: Group): string =>\n group.heading === undefined\n ? t('timeline.undated', { defaultValue: 'Undated' })\n : (formatTimeValue('date', group.heading, {\n zone: viewerZone,\n viewerZone,\n locale: tag,\n params: { dateStyle: 'full' },\n }) ?? group.heading);\n const timeOf = (instant: string, zone: TimeZoneName): string =>\n formatTimeValue('time', instantToWall(instant, zone).time, {\n zone,\n viewerZone,\n locale: tag,\n params: { timeStyle: 'short' },\n }) ?? instant;\n if (pending) return <RelatedTimelineSkeleton />;\n if (groups.length === 0)\n return (\n <p data-buro-region=\"empty\" className=\"text-sm text-muted-foreground\">\n {(rows.length === 0 ? empty : undefined) ??\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, instant, zone }) => (\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 {instant !== undefined && zone !== undefined ? (\n <time\n dateTime={instant}\n className=\"w-16 shrink-0 whitespace-nowrap text-xs tabular-nums text-muted-foreground\"\n >\n {timeOf(instant, zone)}\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,7 @@
1
1
  const require_toaster = require("./toaster-BbByOytP.cjs");
2
- const require_relation_create = require("./relation-create-DDEYcKfw.cjs");
3
- const require_place_node = require("./place-node-Bhl8B3fF.cjs");
4
- const require_filter_builder = require("./filter-builder-ByGhxLf_.cjs");
2
+ const require_relation_create = require("./relation-create-_SFuPQGM.cjs");
3
+ const require_place_node = require("./place-node-BZF5Af6x.cjs");
4
+ const require_filter_builder = require("./filter-builder-DQX-TMFh.cjs");
5
5
  let _burojs_core = require("@burojs/core");
6
6
  let _burojs_react = require("@burojs/react");
7
7
  let react = require("react");
@@ -216,4 +216,4 @@ Object.defineProperty(exports, "useProjectedRows", {
216
216
  }
217
217
  });
218
218
 
219
- //# sourceMappingURL=related-rows-BW9Jr07T.cjs.map
219
+ //# sourceMappingURL=related-rows-DDhp9axl.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"related-rows-BW9Jr07T.cjs","names":["useApp","useI18nCaps","columnName","peekLeafAllowed","peekFieldDefinition","FieldValueFrame","ResolvedFieldDisplay","toDisplayText","recordDisplayName","Fragment","resolveFieldLabel","declaredText","useApp","scopeValueOf","useScopeSource","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 {\n type ColumnEntry,\n columnName,\n type EntityRef,\n resolveFieldLabel,\n declaredText,\n} from '@burojs/core';\nimport { useApp, useI18nCaps } from '@burojs/react';\nimport { Fragment, type ReactElement } from 'react';\nimport { toDisplayText } from '../fields/display-value.js';\nimport { FieldValueFrame } from '../fields/field-value-frame.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 ColumnEntry[] } };\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?.map(columnName) ?? 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 // A card draws the `card` surface (`ui.card` applies, REF-117 §4.13); a timeline entry is a\n // record display, so it reads `ui.display` alone.\n const surface = variant === 'card' ? 'card' : 'display';\n const value = (name: string) => (\n <FieldValueFrame\n field={{ ...(definition(name) as object), name }}\n value={row[name]}\n surface={surface}\n >\n <ResolvedFieldDisplay\n resource={ref}\n name={name}\n field={definition(name) as never}\n value={row[name]}\n record={row}\n uiSurface={surface}\n fallback={toDisplayText(row[name]).text}\n />\n </FieldValueFrame>\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 {\n type CapabilityResolver,\n useApp,\n useCtx,\n scopeValueOf,\n useFieldAccess,\n useScopeSource,\n useViewRow,\n} 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 /** The placement's `empty` text, drawn when there is no row to draw. */\n readonly empty?: string;\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 // `ctx.scope` (7d Q3): the record frames around the rows (the card), then the selection; a\n // row's own value is not read, as on a list.\n const scope = scopeValueOf(useScopeSource({ mode: 'record' }));\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: scope as never,\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
+ {"version":3,"file":"related-rows-DDhp9axl.cjs","names":["useApp","useI18nCaps","columnName","peekLeafAllowed","peekFieldDefinition","FieldValueFrame","ResolvedFieldDisplay","toDisplayText","recordDisplayName","Fragment","resolveFieldLabel","declaredText","useApp","scopeValueOf","useScopeSource","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 {\n type ColumnEntry,\n columnName,\n type EntityRef,\n resolveFieldLabel,\n declaredText,\n} from '@burojs/core';\nimport { useApp, useI18nCaps } from '@burojs/react';\nimport { Fragment, type ReactElement } from 'react';\nimport { toDisplayText } from '../fields/display-value.js';\nimport { FieldValueFrame } from '../fields/field-value-frame.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 ColumnEntry[] } };\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?.map(columnName) ?? 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 // A card draws the `card` surface (`ui.card` applies, REF-117 §4.13); a timeline entry is a\n // record display, so it reads `ui.display` alone.\n const surface = variant === 'card' ? 'card' : 'display';\n const value = (name: string) => (\n <FieldValueFrame\n field={{ ...(definition(name) as object), name }}\n value={row[name]}\n surface={surface}\n >\n <ResolvedFieldDisplay\n resource={ref}\n name={name}\n field={definition(name) as never}\n value={row[name]}\n record={row}\n uiSurface={surface}\n fallback={toDisplayText(row[name]).text}\n />\n </FieldValueFrame>\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 {\n type CapabilityResolver,\n useApp,\n useCtx,\n scopeValueOf,\n useFieldAccess,\n useScopeSource,\n useViewRow,\n} 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 /** The placement's `empty` text, drawn when there is no row to draw. */\n readonly empty?: string;\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 // `ctx.scope` (7d Q3): the record frames around the rows (the card), then the selection; a\n // row's own value is not read, as on a list.\n const scope = scopeValueOf(useScopeSource({ mode: 'record' }));\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: scope as never,\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
  import { l as useLinkComponent } from "./toaster-Ct_YHGs6.js";
2
- import { _ as isPlainLeftClick, g as ClaimedQuickLink, h as recordDisplayName } from "./relation-create-C43cdPQt.js";
3
- import { Ft as toDisplayText, Pt as FieldValueFrame, a as peekFieldDefinition, c as peekRow, dt as RelatedItem, ft as useItemDrawn, o as peekLeafAllowed } from "./place-node-BdxT-30h.js";
4
- import { F as ResolvedFieldDisplay } from "./filter-builder-z3Axzf9Y.js";
2
+ import { _ as ClaimedQuickLink, g as recordDisplayName, v as isPlainLeftClick } from "./relation-create-6WicROWA.js";
3
+ import { Ft as toDisplayText, Pt as FieldValueFrame, a as peekFieldDefinition, c as peekRow, dt as RelatedItem, ft as useItemDrawn, o as peekLeafAllowed } from "./place-node-DRjmJGQ_.js";
4
+ import { F as ResolvedFieldDisplay } from "./filter-builder-04nas3eq.js";
5
5
  import { RECORD_PROBE, columnName, declaredText, resolveCapability, resolveFieldLabel, ruleContextFor } from "@burojs/core";
6
6
  import { QUICK_ANCHOR_ATTRIBUTE, scopeValueOf, useApp, useCtx, useFieldAccess, useI18nCaps, useScopeSource, useViewRow } from "@burojs/react";
7
7
  import { Fragment, useCallback, useMemo } from "react";
@@ -193,4 +193,4 @@ const ITEM_LAYER_CLASS = "relative z-[1] pointer-events-none [&_a]:pointer-event
193
193
  //#endregion
194
194
  export { useProjectedRows as i, RowContent as n, RowOpener as r, ITEM_LAYER_CLASS as t };
195
195
 
196
- //# sourceMappingURL=related-rows-CPE-9FFr.js.map
196
+ //# sourceMappingURL=related-rows-DL6CWsrj.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"related-rows-CPE-9FFr.js","names":[],"sources":["../src/blocks/default-item.tsx","../src/blocks/related-rows.tsx"],"sourcesContent":["'use client';\nimport {\n type ColumnEntry,\n columnName,\n type EntityRef,\n resolveFieldLabel,\n declaredText,\n} from '@burojs/core';\nimport { useApp, useI18nCaps } from '@burojs/react';\nimport { Fragment, type ReactElement } from 'react';\nimport { toDisplayText } from '../fields/display-value.js';\nimport { FieldValueFrame } from '../fields/field-value-frame.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 ColumnEntry[] } };\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?.map(columnName) ?? 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 // A card draws the `card` surface (`ui.card` applies, REF-117 §4.13); a timeline entry is a\n // record display, so it reads `ui.display` alone.\n const surface = variant === 'card' ? 'card' : 'display';\n const value = (name: string) => (\n <FieldValueFrame\n field={{ ...(definition(name) as object), name }}\n value={row[name]}\n surface={surface}\n >\n <ResolvedFieldDisplay\n resource={ref}\n name={name}\n field={definition(name) as never}\n value={row[name]}\n record={row}\n uiSurface={surface}\n fallback={toDisplayText(row[name]).text}\n />\n </FieldValueFrame>\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 {\n type CapabilityResolver,\n useApp,\n useCtx,\n scopeValueOf,\n useFieldAccess,\n useScopeSource,\n useViewRow,\n} 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 /** The placement's `empty` text, drawn when there is no row to draw. */\n readonly empty?: string;\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 // `ctx.scope` (7d Q3): the record frames around the rows (the card), then the selection; a\n // row's own value is not read, as on a list.\n const scope = scopeValueOf(useScopeSource({ mode: 'record' }));\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: scope as never,\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
+ {"version":3,"file":"related-rows-DL6CWsrj.js","names":[],"sources":["../src/blocks/default-item.tsx","../src/blocks/related-rows.tsx"],"sourcesContent":["'use client';\nimport {\n type ColumnEntry,\n columnName,\n type EntityRef,\n resolveFieldLabel,\n declaredText,\n} from '@burojs/core';\nimport { useApp, useI18nCaps } from '@burojs/react';\nimport { Fragment, type ReactElement } from 'react';\nimport { toDisplayText } from '../fields/display-value.js';\nimport { FieldValueFrame } from '../fields/field-value-frame.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 ColumnEntry[] } };\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?.map(columnName) ?? 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 // A card draws the `card` surface (`ui.card` applies, REF-117 §4.13); a timeline entry is a\n // record display, so it reads `ui.display` alone.\n const surface = variant === 'card' ? 'card' : 'display';\n const value = (name: string) => (\n <FieldValueFrame\n field={{ ...(definition(name) as object), name }}\n value={row[name]}\n surface={surface}\n >\n <ResolvedFieldDisplay\n resource={ref}\n name={name}\n field={definition(name) as never}\n value={row[name]}\n record={row}\n uiSurface={surface}\n fallback={toDisplayText(row[name]).text}\n />\n </FieldValueFrame>\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 {\n type CapabilityResolver,\n useApp,\n useCtx,\n scopeValueOf,\n useFieldAccess,\n useScopeSource,\n useViewRow,\n} 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 /** The placement's `empty` text, drawn when there is no row to draw. */\n readonly empty?: string;\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 // `ctx.scope` (7d Q3): the record frames around the rows (the card), then the selection; a\n // row's own value is not read, as on a list.\n const scope = scopeValueOf(useScopeSource({ mode: 'record' }));\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: scope as never,\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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"}
@@ -2,7 +2,7 @@ import { l as cn } from "./use-theme-dnE3Od3I.js";
2
2
  import { a as technicalText, l as useLinkComponent, n as toast, o as technicalTexts, r as friendlyStringsFrom, s as toFriendlyError } from "./toaster-Ct_YHGs6.js";
3
3
  import { n as buttonVariants, t as Button } from "./button-MWVeZaqj.js";
4
4
  import { i as DialogDescription, r as DialogContent, s as DialogTitle, t as Dialog } from "./dialog-C123sVQ8.js";
5
- import { composeListFilter, hasRecordPage, normalizeDataError, normalizeFixedFilters, relationAmbiguousError, relationOpenOf, resourceKey, resourceShowHref, routeResourceKey } from "@burojs/core";
5
+ import { composeListFilter, hasRecordPage, normalizeDataError, normalizeFixedFilters, relationAmbiguousError, relationOpenOf, resolveEnumLabel, resourceKey, resourceShowHref, routeResourceKey } from "@burojs/core";
6
6
  import { PEEK_COMPONENT, QUICK_ANCHOR_ATTRIBUTE, filterFields, quickAnchorRef, specificErrorText, useApp, useChromeT, useCurrentUIActivation, useEntryGate, useI18nCaps, useList, useListAccess, useLoadErrorView, useOptionalT, useQuick, useQuickOpener, useRelatedRecord, useRouteNavigate, useT, useTestIds, useUIPresentationRuntime } from "@burojs/react";
7
7
  import { IconAlertCircle, IconEye, IconRefresh, IconSearch } from "@tabler/icons-react";
8
8
  import * as React from "react";
@@ -365,11 +365,39 @@ function recordDisplayName(record, displayField) {
365
365
  return String(record.id ?? "");
366
366
  }
367
367
  //#endregion
368
+ //#region src/resource/visible-row.ts
369
+ function visibleRow(def, access, row) {
370
+ if (access.status !== "ready") return void 0;
371
+ const idField = def?.data?.idField || "id";
372
+ const visible = {};
373
+ for (const name of Object.keys(def?.fields ?? {})) if (Object.hasOwn(row, name) && access.fieldVisible(name)) visible[name] = row[name];
374
+ if (Object.hasOwn(row, idField)) visible[idField] = row[idField];
375
+ return visible;
376
+ }
377
+ //#endregion
368
378
  //#region src/resource/use-row-title.ts
369
- function useRowTitle(target, displayField) {
379
+ function useRowTitle(target, displayField, options) {
380
+ const app = useApp();
370
381
  const access = useListAccess(target);
382
+ const caps = useI18nCaps(target);
383
+ const def = app.registry.get(target);
384
+ const hook = options?.recordTitle === true && displayField === def?.displayField ? def?.recordTitle : void 0;
371
385
  const visible = displayField !== void 0 && access.status === "ready" && access.fieldVisible(displayField);
372
- return useCallback((row) => recordDisplayName(row, visible ? displayField : void 0), [visible, displayField]);
386
+ return useCallback((row) => {
387
+ const narrowed = hook === void 0 ? void 0 : visibleRow(def, access, row);
388
+ if (hook !== void 0 && narrowed !== void 0) {
389
+ const title = hook(narrowed, { resolveEnum: (namespace, value, inlineDefault) => resolveEnumLabel(caps, namespace, value, inlineDefault) });
390
+ if (typeof title === "string" && title.trim() !== "") return title;
391
+ }
392
+ return recordDisplayName(row, visible ? displayField : void 0);
393
+ }, [
394
+ hook,
395
+ access,
396
+ def,
397
+ caps,
398
+ visible,
399
+ displayField
400
+ ]);
373
401
  }
374
402
  //#endregion
375
403
  //#region src/quick/peek-context.ts
@@ -1231,6 +1259,6 @@ function CreateButton({ to, fieldName, create, seeds, search, beforeOpen, classN
1231
1259
  });
1232
1260
  }
1233
1261
  //#endregion
1234
- export { CommandEmpty as C, CommandList as D, CommandItem as E, CommandLoading as O, CommandDialog as S, CommandInput as T, isPlainLeftClick as _, namesHiddenField as a, RecordState as b, RelationField as c, peekAnchorOpener as d, PeekContext as f, ClaimedQuickLink as g, recordDisplayName as h, selectKey as i, CommandSeparator as k, relationLinkClassName as l, useRowTitle as m, useSelectCreate as n, narrowSearchDecl as o, PeekHostContext as p, RelationViewButton as r, RelationDisplay as s, RelationCreateButton as t, focusWithoutPeek as u, InvalidRouteId as v, CommandGroup as w, Command$1 as x, LoadError as y };
1262
+ export { CommandSeparator as A, CommandDialog as C, CommandItem as D, CommandInput as E, CommandList as O, Command$1 as S, CommandGroup as T, ClaimedQuickLink as _, namesHiddenField as a, LoadError as b, RelationField as c, peekAnchorOpener as d, PeekContext as f, recordDisplayName as g, visibleRow as h, selectKey as i, CommandLoading as k, relationLinkClassName as l, useRowTitle as m, useSelectCreate as n, narrowSearchDecl as o, PeekHostContext as p, RelationViewButton as r, RelationDisplay as s, RelationCreateButton as t, focusWithoutPeek as u, isPlainLeftClick as v, CommandEmpty as w, RecordState as x, InvalidRouteId as y };
1235
1263
 
1236
- //# sourceMappingURL=relation-create-C43cdPQt.js.map
1264
+ //# sourceMappingURL=relation-create-6WicROWA.js.map