@burojs/ui-shadcn 0.9.0 → 0.10.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.
- package/dist/{bulk-summary-2HLgz7Il.cjs → bulk-summary-Chc61Pyw.cjs} +9 -7
- package/dist/bulk-summary-Chc61Pyw.cjs.map +1 -0
- package/dist/{bulk-summary-D6A0ua21.js → bulk-summary-DpSQD2Fq.js} +9 -7
- package/dist/bulk-summary-DpSQD2Fq.js.map +1 -0
- package/dist/{candidates-relation-picker-QvoY2bOQ.js → candidates-relation-picker-DRsHKe6N.js} +3 -3
- package/dist/{candidates-relation-picker-QvoY2bOQ.js.map → candidates-relation-picker-DRsHKe6N.js.map} +1 -1
- package/dist/{candidates-relation-picker-pEAWKQEY.cjs → candidates-relation-picker-GIxsp7D_.cjs} +3 -3
- package/dist/{candidates-relation-picker-pEAWKQEY.cjs.map → candidates-relation-picker-GIxsp7D_.cjs.map} +1 -1
- package/dist/{check-confirm-dialog-W-8WOmGh.cjs → check-confirm-dialog-BMSb7wFv.cjs} +17 -9
- package/dist/check-confirm-dialog-BMSb7wFv.cjs.map +1 -0
- package/dist/{check-confirm-dialog-B-CbJTln.js → check-confirm-dialog-B_u3YVHS.js} +18 -10
- package/dist/{check-confirm-dialog-B-CbJTln.js.map → check-confirm-dialog-B_u3YVHS.js.map} +1 -1
- package/dist/{filter-builder-04nas3eq.js → filter-builder-DX-xC3Yd.js} +2 -2
- package/dist/{filter-builder-04nas3eq.js.map → filter-builder-DX-xC3Yd.js.map} +1 -1
- package/dist/{filter-builder-DQX-TMFh.cjs → filter-builder-Dt5E8PSX.cjs} +2 -2
- package/dist/{filter-builder-DQX-TMFh.cjs.map → filter-builder-Dt5E8PSX.cjs.map} +1 -1
- package/dist/{flow-runtime-DyNIYfUP.cjs → flow-runtime-CQ4wf8co.cjs} +2 -2
- package/dist/{flow-runtime-DyNIYfUP.cjs.map → flow-runtime-CQ4wf8co.cjs.map} +1 -1
- package/dist/{flow-runtime-BEIyym7d.js → flow-runtime-Q2vD7R3c.js} +2 -2
- package/dist/{flow-runtime-BEIyym7d.js.map → flow-runtime-Q2vD7R3c.js.map} +1 -1
- package/dist/{flow-screen-DY1Z9PbG.js → flow-screen-B1y2yizP.js} +18 -18
- package/dist/flow-screen-B1y2yizP.js.map +1 -0
- package/dist/{flow-screen-FE5Xhb3t.cjs → flow-screen-sw2cP70t.cjs} +18 -18
- package/dist/flow-screen-sw2cP70t.cjs.map +1 -0
- package/dist/index.cjs +2183 -109
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +76 -8
- package/dist/index.d.ts +76 -8
- package/dist/index.js +2095 -24
- package/dist/index.js.map +1 -1
- package/dist/{inline-flow-host-yVLo6-sM.cjs → inline-flow-host-CkhoA69R.cjs} +3 -3
- package/dist/{inline-flow-host-yVLo6-sM.cjs.map → inline-flow-host-CkhoA69R.cjs.map} +1 -1
- package/dist/{inline-flow-host-D6u-RlsV.js → inline-flow-host-DqbXqcPS.js} +3 -3
- package/dist/{inline-flow-host-D6u-RlsV.js.map → inline-flow-host-DqbXqcPS.js.map} +1 -1
- package/dist/{lazy-relation-picker-dialog-BaORufxQ.js → lazy-relation-picker-dialog-BaIEWLbF.js} +3 -52
- package/dist/lazy-relation-picker-dialog-BaIEWLbF.js.map +1 -0
- package/dist/{lazy-relation-picker-dialog-C_VlGlDz.cjs → lazy-relation-picker-dialog-CeRzOAi0.cjs} +3 -52
- package/dist/lazy-relation-picker-dialog-CeRzOAi0.cjs.map +1 -0
- package/dist/{page-flow-route-CyMzUidK.js → page-flow-route-CP7cS7FY.js} +5 -5
- package/dist/page-flow-route-CP7cS7FY.js.map +1 -0
- package/dist/{page-flow-route-OFx7h7Ja.cjs → page-flow-route-UDx8qvdM.cjs} +9 -9
- package/dist/page-flow-route-UDx8qvdM.cjs.map +1 -0
- package/dist/{place-node-BZF5Af6x.cjs → place-node-C5ZmuHaN.cjs} +149 -40
- package/dist/place-node-C5ZmuHaN.cjs.map +1 -0
- package/dist/{place-node-DRjmJGQ_.js → place-node-DwWAigv0.js} +146 -43
- package/dist/place-node-DwWAigv0.js.map +1 -0
- package/dist/record-trail-store-Cjo9vtod.cjs +126 -0
- package/dist/record-trail-store-Cjo9vtod.cjs.map +1 -0
- package/dist/record-trail-store-Dn6bVry4.js +91 -0
- package/dist/record-trail-store-Dn6bVry4.js.map +1 -0
- package/dist/{related-list-cards-xVvgSlu-.cjs → related-list-cards-BypKfm9t.cjs} +3 -3
- package/dist/{related-list-cards-xVvgSlu-.cjs.map → related-list-cards-BypKfm9t.cjs.map} +1 -1
- package/dist/{related-list-cards-2hLitVkg.js → related-list-cards-Dcmruy09.js} +3 -3
- package/dist/{related-list-cards-2hLitVkg.js.map → related-list-cards-Dcmruy09.js.map} +1 -1
- package/dist/{related-list-timeline-Dsf5WewG.cjs → related-list-timeline-D-KClgKb.cjs} +4 -4
- package/dist/{related-list-timeline-Dsf5WewG.cjs.map → related-list-timeline-D-KClgKb.cjs.map} +1 -1
- package/dist/{related-list-timeline-CxJqe6eK.js → related-list-timeline-DZON_qSc.js} +4 -4
- package/dist/{related-list-timeline-CxJqe6eK.js.map → related-list-timeline-DZON_qSc.js.map} +1 -1
- package/dist/{related-rows-DDhp9axl.cjs → related-rows-DgF05ssi.cjs} +4 -4
- package/dist/{related-rows-DDhp9axl.cjs.map → related-rows-DgF05ssi.cjs.map} +1 -1
- package/dist/{related-rows-DL6CWsrj.js → related-rows-ETZl5CB9.js} +4 -4
- package/dist/{related-rows-DL6CWsrj.js.map → related-rows-ETZl5CB9.js.map} +1 -1
- package/dist/{relation-create-_SFuPQGM.cjs → relation-create-B8zngAcA.cjs} +46 -11
- package/dist/relation-create-B8zngAcA.cjs.map +1 -0
- package/dist/{relation-create-6WicROWA.js → relation-create-CeCWyxIb.js} +47 -12
- package/dist/relation-create-CeCWyxIb.js.map +1 -0
- package/dist/{relation-many-picker-mGEQDWo2.js → relation-many-picker-CT7nKfE2.js} +4 -4
- package/dist/{relation-many-picker-mGEQDWo2.js.map → relation-many-picker-CT7nKfE2.js.map} +1 -1
- package/dist/{relation-many-picker-BBNsmkaX.cjs → relation-many-picker-Cq0EHY5I.cjs} +4 -4
- package/dist/{relation-many-picker-BBNsmkaX.cjs.map → relation-many-picker-Cq0EHY5I.cjs.map} +1 -1
- package/dist/{relation-picker-BbO41cFV.js → relation-picker-CCyuMeGq.js} +6 -6
- package/dist/{relation-picker-BbO41cFV.js.map → relation-picker-CCyuMeGq.js.map} +1 -1
- package/dist/{relation-picker-jk9D_uwn.cjs → relation-picker-DmwTzgsd.cjs} +6 -6
- package/dist/{relation-picker-jk9D_uwn.cjs.map → relation-picker-DmwTzgsd.cjs.map} +1 -1
- package/dist/{relation-picker-dialog-BgSG_8bU.js → relation-picker-dialog-CoWKjNv8.js} +4 -4
- package/dist/{relation-picker-dialog-BgSG_8bU.js.map → relation-picker-dialog-CoWKjNv8.js.map} +1 -1
- package/dist/{relation-picker-dialog-Duqy2r0n.cjs → relation-picker-dialog-mbwyNK43.cjs} +4 -4
- package/dist/{relation-picker-dialog-Duqy2r0n.cjs.map → relation-picker-dialog-mbwyNK43.cjs.map} +1 -1
- package/dist/{relation-select-C3aV18kT.cjs → relation-select-CguIo2M5.cjs} +2 -2
- package/dist/{relation-select-C3aV18kT.cjs.map → relation-select-CguIo2M5.cjs.map} +1 -1
- package/dist/{relation-select-CjQT9LpS.js → relation-select-nAYxhopN.js} +2 -2
- package/dist/{relation-select-CjQT9LpS.js.map → relation-select-nAYxhopN.js.map} +1 -1
- package/dist/{use-dialog-filter-state-lsTJxrB4.cjs → use-dialog-filter-state-CpWblz3C.cjs} +2 -2
- package/dist/{use-dialog-filter-state-lsTJxrB4.cjs.map → use-dialog-filter-state-CpWblz3C.cjs.map} +1 -1
- package/dist/{use-dialog-filter-state-CJoeY-1j.js → use-dialog-filter-state-ZYxOp5WO.js} +2 -2
- package/dist/{use-dialog-filter-state-CJoeY-1j.js.map → use-dialog-filter-state-ZYxOp5WO.js.map} +1 -1
- package/dist/{use-record-subtitle-BJ9rnj6F.cjs → use-record-subtitle-B4lTR7pf.cjs} +2 -2
- package/dist/{use-record-subtitle-BJ9rnj6F.cjs.map → use-record-subtitle-B4lTR7pf.cjs.map} +1 -1
- package/dist/{use-record-subtitle-w3ZhXNlf.js → use-record-subtitle-pWMBqQx9.js} +2 -2
- package/dist/{use-record-subtitle-w3ZhXNlf.js.map → use-record-subtitle-pWMBqQx9.js.map} +1 -1
- package/package.json +9 -9
- package/dist/bulk-summary-2HLgz7Il.cjs.map +0 -1
- package/dist/bulk-summary-D6A0ua21.js.map +0 -1
- package/dist/check-confirm-dialog-W-8WOmGh.cjs.map +0 -1
- package/dist/flow-screen-DY1Z9PbG.js.map +0 -1
- package/dist/flow-screen-FE5Xhb3t.cjs.map +0 -1
- package/dist/lazy-relation-picker-dialog-BaORufxQ.js.map +0 -1
- package/dist/lazy-relation-picker-dialog-C_VlGlDz.cjs.map +0 -1
- package/dist/page-flow-route-CyMzUidK.js.map +0 -1
- package/dist/page-flow-route-OFx7h7Ja.cjs.map +0 -1
- package/dist/place-node-BZF5Af6x.cjs.map +0 -1
- package/dist/place-node-DRjmJGQ_.js.map +0 -1
- package/dist/relation-create-6WicROWA.js.map +0 -1
- package/dist/relation-create-_SFuPQGM.cjs.map +0 -1
- package/dist/resource-page-router-CzaNATSp.js +0 -2010
- package/dist/resource-page-router-CzaNATSp.js.map +0 -1
- package/dist/resource-page-router-dmVIeu5s.cjs +0 -2231
- package/dist/resource-page-router-dmVIeu5s.cjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
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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"}
|
|
1
|
+
{"version":3,"file":"related-rows-ETZl5CB9.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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"}
|
|
@@ -820,6 +820,8 @@ function RelationDisplayBody({ to, by, id, idStr, app, open: openMode, quickTarg
|
|
|
820
820
|
const baseId = `relation-display:${to}:${idStr}`;
|
|
821
821
|
const RouterLink = require_toaster.useLinkComponent();
|
|
822
822
|
const open = (0, _burojs_react.useQuickOpener)();
|
|
823
|
+
const gate = (0, _burojs_react.useEntryGate)();
|
|
824
|
+
const collectionRow = (0, _burojs_react.useCollectionRows)(to);
|
|
823
825
|
const { record, isLoading, error, ambiguous } = (0, _burojs_react.useRelatedRecord)(to, id, by === void 0 ? void 0 : { by });
|
|
824
826
|
if (!targetDef) {
|
|
825
827
|
if (process.env.NODE_ENV !== "production") console.warn(`[RelationDisplay] target resource '${to}' not registered — rendering raw value '${idStr}'`);
|
|
@@ -866,7 +868,9 @@ function RelationDisplayBody({ to, by, id, idStr, app, open: openMode, quickTarg
|
|
|
866
868
|
className: "text-muted-foreground",
|
|
867
869
|
children: displayName
|
|
868
870
|
});
|
|
869
|
-
const
|
|
871
|
+
const kind = collectionRow?.(record);
|
|
872
|
+
const member = kind !== void 0 && "member" in kind ? kind.member : void 0;
|
|
873
|
+
const href = linksToPage(app, (member === void 0 ? void 0 : app.registry.get(member)) ?? targetDef) ? (0, _burojs_core.resourceShowHref)(app.registry, targetDef, to, String(rowId), record) : null;
|
|
870
874
|
if (openMode === "none") return (0, react_jsx_runtime.jsx)("span", {
|
|
871
875
|
"data-testid": baseId,
|
|
872
876
|
children: displayName
|
|
@@ -879,6 +883,21 @@ function RelationDisplayBody({ to, by, id, idStr, app, open: openMode, quickTarg
|
|
|
879
883
|
open,
|
|
880
884
|
children: displayName
|
|
881
885
|
});
|
|
886
|
+
if (collectionRow !== void 0) {
|
|
887
|
+
const answer = gate(to, "show", record);
|
|
888
|
+
if (answer.state === "hidden" || answer.state === "disabled" || answer.state === "undecided") return (0, react_jsx_runtime.jsx)("span", {
|
|
889
|
+
"data-testid": `${baseId}:text`,
|
|
890
|
+
children: idStr
|
|
891
|
+
});
|
|
892
|
+
if (member !== void 0 && answer.state === "open" && openMode === "quick") return (0, react_jsx_runtime.jsx)(RowOpener, {
|
|
893
|
+
to: answer.target,
|
|
894
|
+
rowId: String(rowId),
|
|
895
|
+
href,
|
|
896
|
+
testid: baseId,
|
|
897
|
+
open,
|
|
898
|
+
children: displayName
|
|
899
|
+
});
|
|
900
|
+
}
|
|
882
901
|
if (href === null) return (0, react_jsx_runtime.jsx)("span", {
|
|
883
902
|
"data-testid": baseId,
|
|
884
903
|
children: displayName
|
|
@@ -997,16 +1016,20 @@ const TITLE_CLASS = "min-w-0 max-w-[16rem] truncate";
|
|
|
997
1016
|
const TITLE_VIEW_CLASS = require_use_theme.cn(TITLE_CLASS, "cursor-pointer rounded-sm text-left hover:underline focus:outline-hidden focus-visible:ring-2 focus-visible:ring-ring");
|
|
998
1017
|
function RelationViewButton(props) {
|
|
999
1018
|
const gate = (0, _burojs_react.useEntryGate)();
|
|
1019
|
+
const availability = (0, _burojs_react.useAvailabilityGate)("show");
|
|
1000
1020
|
const { to, value, by } = props;
|
|
1021
|
+
const collection = (0, _burojs_react.useCollectionRows)(to) !== void 0;
|
|
1001
1022
|
const access = (0, _burojs_react.useListAccess)(to);
|
|
1002
1023
|
const key = selectKey(value);
|
|
1003
1024
|
const plain = plainTitle(props.title);
|
|
1004
1025
|
if (key === null || props.open === "none") return plain;
|
|
1005
1026
|
if (by !== void 0 && !(access.status === "ready" && access.fieldVisible(by))) return plain;
|
|
1006
|
-
|
|
1027
|
+
const answer = gate(to, "show");
|
|
1028
|
+
if (!(collection ? answer.state === "absent" && availability(to, "show").state === "available" : answer.state === "open")) return plain;
|
|
1007
1029
|
return (0, react_jsx_runtime.jsx)(ViewButton, {
|
|
1008
1030
|
...props,
|
|
1009
|
-
keyString: key
|
|
1031
|
+
keyString: key,
|
|
1032
|
+
collection
|
|
1010
1033
|
}, key);
|
|
1011
1034
|
}
|
|
1012
1035
|
function plainTitle(title) {
|
|
@@ -1015,18 +1038,21 @@ function plainTitle(title) {
|
|
|
1015
1038
|
children: title
|
|
1016
1039
|
});
|
|
1017
1040
|
}
|
|
1018
|
-
function ViewButton({ to, by, fieldName, keyString, beforeOpen, open: openMode = "quick", title }) {
|
|
1041
|
+
function ViewButton({ to, by: byField, fieldName, keyString, beforeOpen, open: openMode = "quick", title, collection }) {
|
|
1019
1042
|
const app = (0, _burojs_react.useApp)();
|
|
1020
1043
|
const t = (0, _burojs_react.useOptionalT)();
|
|
1021
1044
|
const tid = (0, _burojs_react.useTestIds)();
|
|
1022
1045
|
const quick = (0, _burojs_react.useQuick)();
|
|
1046
|
+
const openQuick = (0, _burojs_react.useQuickOpener)();
|
|
1023
1047
|
const navigate = (0, _burojs_react.useRouteNavigate)();
|
|
1048
|
+
const availability = (0, _burojs_react.useAvailabilityGate)("show");
|
|
1024
1049
|
const RouterLink = require_toaster.useLinkComponent();
|
|
1025
1050
|
const [asked, setAsked] = react.useState(false);
|
|
1026
1051
|
const requested = react.useRef(false);
|
|
1027
1052
|
const targetDef = app.registry.get(to);
|
|
1028
1053
|
const rawIdField = (targetDef?.data)?.idField;
|
|
1029
1054
|
const idField = typeof rawIdField === "string" && rawIdField.length > 0 ? rawIdField : "id";
|
|
1055
|
+
const by = byField ?? (collection && openMode !== "page" ? idField : void 0);
|
|
1030
1056
|
const read = (0, _burojs_react.useList)(to, {
|
|
1031
1057
|
...asked && by !== void 0 ? {
|
|
1032
1058
|
filter: {
|
|
@@ -1045,21 +1071,30 @@ function ViewButton({ to, by, fieldName, keyString, beforeOpen, open: openMode =
|
|
|
1045
1071
|
retry: false
|
|
1046
1072
|
});
|
|
1047
1073
|
const rows = read.isCurrentData && !read.isPlaceholderData && !read.isFetching ? read.data?.data : void 0;
|
|
1048
|
-
const open = react.useCallback((id) => {
|
|
1074
|
+
const open = react.useCallback((id, row) => {
|
|
1049
1075
|
beforeOpen();
|
|
1050
1076
|
if (openMode === "page") {
|
|
1051
|
-
if (targetDef !== void 0 && linksToPage(app, targetDef)) navigate((0, _burojs_core.resourceShowHref)(app.registry, targetDef, to, id));
|
|
1077
|
+
if (targetDef !== void 0 && linksToPage(app, targetDef)) navigate((0, _burojs_core.resourceShowHref)(app.registry, targetDef, to, id, row));
|
|
1078
|
+
return;
|
|
1079
|
+
}
|
|
1080
|
+
if (!collection) {
|
|
1081
|
+
quick.show(to, id);
|
|
1052
1082
|
return;
|
|
1053
1083
|
}
|
|
1054
|
-
|
|
1084
|
+
if (openQuick(to, id, { row }) !== "absent" || targetDef === void 0) return;
|
|
1085
|
+
const href = (0, _burojs_react.collectionRowHref)(app.registry, targetDef, to, id, row, availability);
|
|
1086
|
+
if (href !== void 0 && href !== "") navigate(href);
|
|
1055
1087
|
}, [
|
|
1056
1088
|
beforeOpen,
|
|
1057
1089
|
quick,
|
|
1090
|
+
openQuick,
|
|
1091
|
+
collection,
|
|
1058
1092
|
to,
|
|
1059
1093
|
openMode,
|
|
1060
1094
|
navigate,
|
|
1061
1095
|
app,
|
|
1062
|
-
targetDef
|
|
1096
|
+
targetDef,
|
|
1097
|
+
availability
|
|
1063
1098
|
]);
|
|
1064
1099
|
react.useEffect(() => {
|
|
1065
1100
|
if (by === void 0 || !asked || rows === void 0 || !requested.current) return;
|
|
@@ -1070,7 +1105,7 @@ function ViewButton({ to, by, fieldName, keyString, beforeOpen, open: openMode =
|
|
|
1070
1105
|
}
|
|
1071
1106
|
const id = rows[0]?.[idField];
|
|
1072
1107
|
const next = selectKey(id);
|
|
1073
|
-
if (next !== null) open(next);
|
|
1108
|
+
if (next !== null) open(next, rows[0]);
|
|
1074
1109
|
}, [
|
|
1075
1110
|
by,
|
|
1076
1111
|
asked,
|
|
@@ -1127,7 +1162,7 @@ function ViewButton({ to, by, fieldName, keyString, beforeOpen, open: openMode =
|
|
|
1127
1162
|
if (rows !== void 0 && rows.length === 1) {
|
|
1128
1163
|
const next = selectKey(rows[0]?.[idField]);
|
|
1129
1164
|
requested.current = false;
|
|
1130
|
-
if (next !== null) open(next);
|
|
1165
|
+
if (next !== null) open(next, rows[0]);
|
|
1131
1166
|
}
|
|
1132
1167
|
},
|
|
1133
1168
|
children: content
|
|
@@ -1441,4 +1476,4 @@ Object.defineProperty(exports, "visibleRow", {
|
|
|
1441
1476
|
}
|
|
1442
1477
|
});
|
|
1443
1478
|
|
|
1444
|
-
//# sourceMappingURL=relation-create-
|
|
1479
|
+
//# sourceMappingURL=relation-create-B8zngAcA.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relation-create-B8zngAcA.cjs","names":["React","CommandPrimitive","cn","IconSearch","Dialog","DialogContent","DialogTitle","DialogDescription","useT","useChromeT","Button","useOptionalT","useChromeT","cn","IconAlertCircle","Button","IconRefresh","normalizeDataError","technicalTexts","useOptionalT","useI18nCaps","specificErrorText","friendlyStringsFrom","toFriendlyError","useChromeT","cn","Button","Component","useLoadErrorView","useMemo","normalizeDataError","useLinkComponent","QUICK_ANCHOR_ATTRIBUTE","useApp","useListAccess","useI18nCaps","useCallback","resolveEnumLabel","createContext","useContext","useEntryGate","useUIPresentationRuntime","useCurrentUIActivation","useState","useRef","useCallback","useSyncExternalStore","PEEK_COMPONENT","useQuickOpener","useApp","resourceKey","relationOpenOf","routeResourceKey","hasRecordPage","QUICK_ANCHOR_ATTRIBUTE","useLinkComponent","useEntryGate","useQuickOpener","resourceShowHref","useOptionalT","useState","useList","useRef","technicalText","relationAmbiguousError","useCollectionRows","useRelatedRecord","useCallback","filterFields","composeListFilter","normalizeFixedFilters","useList","React","cn","buttonVariants","useEntryGate","useAvailabilityGate","useCollectionRows","useListAccess","useApp","useOptionalT","useTestIds","useQuick","useQuickOpener","useRouteNavigate","useLinkComponent","React","useList","resourceShowHref","collectionRowHref","IconEye","QUICK_ANCHOR_ATTRIBUTE","useOptionalT","React","useListAccess","useEntryGate","useApp","useTestIds","useQuick"],"sources":["../src/primitives/command.tsx","../src/record/record-state.tsx","../src/load-error/list-error-panel.tsx","../src/load-error/state.ts","../src/load-error/load-error-view.tsx","../src/fields/claimed-quick-link.tsx","../src/resource/record-display-name.ts","../src/resource/visible-row.ts","../src/resource/use-row-title.ts","../src/quick/peek-context.ts","../src/quick/use-peek-intent.tsx","../src/fields/relation-display.tsx","../src/fields/search-access.ts","../src/fields/relation-hand-back.tsx","../src/fields/relation-view-button.tsx","../src/fields/relation-create.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { Command as CommandPrimitive } from 'cmdk';\nimport { IconSearch } from '@tabler/icons-react';\nimport { cn } from '../lib/cn.js';\nimport {\n Dialog,\n DialogContent,\n DialogTitle,\n DialogDescription,\n type DialogContentProps,\n} from './dialog.js';\n\n/**\n * Shadcn-canonical Command primitive built on `cmdk`. Provides\n * keyboard-navigable, ARIA-correct combobox/listbox semantics: arrow\n * keys to navigate items, Enter to select, type-ahead search via the\n * embedded `<CommandInput>`. Use this for any searchable list inside a\n * Popover (typeaheads, command palettes, relation pickers).\n *\n * Filter behavior: by default cmdk filters items client-side based on\n * the input text. For server-side filtering (typical for relation\n * pickers that hit `useList` with a `contains` operator), pass\n * `shouldFilter={false}` to the root `<Command>` and drive the option\n * list yourself from the server-side results.\n */\nconst Command = React.forwardRef<\n React.ElementRef<typeof CommandPrimitive>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive>\n>(({ className, ...props }, ref) => (\n <CommandPrimitive\n ref={ref}\n className={cn(\n 'flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground',\n className,\n )}\n {...props}\n />\n));\nCommand.displayName = CommandPrimitive.displayName;\n\nconst CommandInput = React.forwardRef<\n React.ElementRef<typeof CommandPrimitive.Input>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>\n>(({ className, ...props }, ref) => (\n <div className=\"flex items-center border-b px-3\" cmdk-input-wrapper=\"\">\n <IconSearch className=\"mr-2 h-4 w-4 shrink-0 opacity-50\" aria-hidden=\"true\" />\n <CommandPrimitive.Input\n ref={ref}\n className={cn(\n 'flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-input-disabled',\n className,\n )}\n {...props}\n />\n </div>\n));\nCommandInput.displayName = CommandPrimitive.Input.displayName;\n\nconst CommandList = React.forwardRef<\n React.ElementRef<typeof CommandPrimitive.List>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>\n>(({ className, ...props }, ref) => (\n <CommandPrimitive.List\n ref={ref}\n className={cn('max-h-[300px] overflow-y-auto overflow-x-hidden', className)}\n {...props}\n />\n));\nCommandList.displayName = CommandPrimitive.List.displayName;\n\nconst CommandEmpty = React.forwardRef<\n React.ElementRef<typeof CommandPrimitive.Empty>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>\n>((props, ref) => (\n <CommandPrimitive.Empty\n ref={ref}\n className=\"py-6 text-center text-sm text-muted-foreground\"\n {...props}\n />\n));\nCommandEmpty.displayName = CommandPrimitive.Empty.displayName;\n\nconst CommandGroup = React.forwardRef<\n React.ElementRef<typeof CommandPrimitive.Group>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>\n>(({ className, ...props }, ref) => (\n <CommandPrimitive.Group\n ref={ref}\n className={cn(\n 'overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground',\n className,\n )}\n {...props}\n />\n));\nCommandGroup.displayName = CommandPrimitive.Group.displayName;\n\nconst CommandSeparator = React.forwardRef<\n React.ElementRef<typeof CommandPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <CommandPrimitive.Separator\n ref={ref}\n className={cn('-mx-1 h-px bg-border', className)}\n {...props}\n />\n));\nCommandSeparator.displayName = CommandPrimitive.Separator.displayName;\n\nconst CommandItem = React.forwardRef<\n React.ElementRef<typeof CommandPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>\n>(({ className, ...props }, ref) => (\n <CommandPrimitive.Item\n ref={ref}\n className={cn(\n \"group relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-hidden data-[disabled=true]:pointer-events-none data-[selected='true']:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-50\",\n className,\n )}\n {...props}\n />\n));\nCommandItem.displayName = CommandPrimitive.Item.displayName;\n\nexport type CommandLoadingProps = React.ComponentPropsWithoutRef<typeof CommandPrimitive.Loading>;\n\nconst CommandLoading = React.forwardRef<\n React.ElementRef<typeof CommandPrimitive.Loading>,\n CommandLoadingProps\n>(({ ...props }, ref) => <CommandPrimitive.Loading ref={ref} {...props} />);\nCommandLoading.displayName = CommandPrimitive.Loading.displayName;\n\n/**\n * Props for `<CommandDialog>`. Mirrors Radix Dialog's `Root` props\n * (`open`, `onOpenChange`, `defaultOpen`, `modal`) plus optional\n * accessibility labels and dialog-content className overrides.\n *\n * The shadcn-canonical pattern wraps a Radix `<Dialog>` around the\n * `<Command>` root so cmdk's keyboard navigation (arrow keys, Enter,\n * type-ahead) operates on the items rendered as children. We render\n * a visually-hidden `<DialogTitle>` + `<DialogDescription>` for the\n * a11y tree (Radix requires a labelled dialog or it warns at runtime).\n */\nexport interface CommandDialogProps {\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n defaultOpen?: boolean;\n modal?: boolean;\n /** Accessible title (visually hidden). Defaults to \"Command Palette\". */\n title?: string;\n /** Accessible description (visually hidden). Defaults to \"Search and run actions.\" */\n description?: string;\n /** Forwarded to the `<DialogContent>` className. */\n className?: string;\n /** Forwarded to the inner `<Command>` className. */\n commandClassName?: string;\n /** The Command groups + items + input. */\n children?: React.ReactNode;\n /** Optional dialog-content overrides (e.g. style for animations). */\n contentProps?: Omit<DialogContentProps, 'children' | 'className'>;\n}\n\n/**\n * Modal command palette. Combines Radix Dialog with cmdk's `<Command>`\n * root so adopters can compose `<CommandInput>`, `<CommandList>`,\n * `<CommandGroup>`, `<CommandItem>` as children and get focus-trapped\n * keyboard navigation out of the box.\n *\n * Usage:\n * ```tsx\n * <CommandDialog open={open} onOpenChange={setOpen}>\n * <CommandInput placeholder=\"Search…\" />\n * <CommandList>\n * <CommandEmpty>No matches.</CommandEmpty>\n * <CommandGroup heading=\"Resources\">\n * <CommandItem onSelect={...}>Documents</CommandItem>\n * </CommandGroup>\n * </CommandList>\n * </CommandDialog>\n * ```\n */\nfunction CommandDialog({\n open,\n onOpenChange,\n defaultOpen,\n modal,\n title = 'Command Palette',\n description = 'Search and run actions.',\n className,\n commandClassName,\n children,\n contentProps,\n}: CommandDialogProps) {\n return (\n <Dialog open={open} onOpenChange={onOpenChange} defaultOpen={defaultOpen} modal={modal}>\n <DialogContent\n {...contentProps}\n // Width: cap to 480px regardless of breakpoint (the shadcn default\n // `DialogContent` uses `max-w-lg` ~512px). `sm:max-w-[480px]`\n // re-asserts at the `sm` breakpoint so any built-in `sm:max-w-lg`\n // override loses to ours.\n className={cn('overflow-hidden p-0 shadow-lg max-w-[480px] sm:max-w-[480px]', className)}\n // Backdrop blur for the command palette specifically: softens\n // the underlying chrome so the palette feels like a focused\n // overlay rather than a stacked panel. Other dialogs keep the\n // shadcn-default solid backdrop.\n overlayClassName=\"backdrop-blur-sm\"\n >\n {/* Visually-hidden labels: Radix Dialog needs them for a11y, but\n the palette UI itself supplies its own search affordance. */}\n <DialogTitle className=\"sr-only\">{title}</DialogTitle>\n <DialogDescription className=\"sr-only\">{description}</DialogDescription>\n <Command\n className={cn(\n '[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5',\n commandClassName,\n )}\n >\n {children}\n </Command>\n </DialogContent>\n </Dialog>\n );\n}\nCommandDialog.displayName = 'CommandDialog';\n\nexport {\n Command,\n CommandInput,\n CommandList,\n CommandEmpty,\n CommandGroup,\n CommandItem,\n CommandSeparator,\n CommandLoading,\n CommandDialog,\n};\n","'use client';\nimport { useChromeT, useT } from '@burojs/react';\nimport type { ReactElement } from 'react';\nimport type { LoadErrorState } from '../load-error/state.js';\nimport { Button } from '../primitives/button.js';\n\nexport type RecordErrorState = LoadErrorState;\n\n/**\n * A record that is loading or cannot be shown: `record-page:loading`, or\n * `record-page:<state>` with Retry when the caller passes `onRetry`. Shared by\n * the record route and `<RecordScreen>`.\n */\nexport function RecordState({\n state,\n onRetry,\n message: given,\n}: {\n readonly state: RecordErrorState | 'loading';\n readonly onRetry?: () => void;\n /** The sentence to show instead of the state's `router.record*` text (a load error's own). */\n readonly message?: string;\n}): ReactElement {\n const t = useT();\n const chromeT = useChromeT();\n if (state === 'loading') {\n return (\n <div\n role=\"status\"\n aria-busy=\"true\"\n data-testid=\"record-page:loading\"\n className=\"p-6 text-sm text-muted-foreground\"\n >\n {t('router.recordLoading')}\n </div>\n );\n }\n const message =\n given ??\n (state === 'not-found'\n ? t('record.notFoundOrNoAccess')\n : state === 'session-expired'\n ? t('router.recordSessionExpired')\n : t('router.recordError'));\n return (\n <div\n // A failed read is announced; loading stays a polite `status`.\n role=\"alert\"\n data-testid={`record-page:${state}`}\n className=\"flex flex-col items-center justify-center gap-3 px-6 py-24 text-center\"\n >\n <p className=\"max-w-sm text-sm text-muted-foreground\">{message}</p>\n {onRetry ? (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n data-testid=\"record-page:retry\"\n onClick={onRetry}\n >\n {chromeT('actions.retry')}\n </Button>\n ) : null}\n </div>\n );\n}\n","'use client';\nimport { useChromeT, useOptionalT, useT } from '@burojs/react';\nimport { IconAlertCircle, IconRefresh } from '@tabler/icons-react';\nimport { cn } from '../lib/cn.js';\nimport { Button } from '../primitives/button.js';\nimport type { ListErrorStateProps } from '../resource/list-error-state.js';\n\n/**\n * The kit's default `list` load-error view: the panel `<ListErrorState>` draws. Its sentence is\n * the load error's one text (`useLoadErrorText`, the rule every surface shares); the technical\n * text is shown under Details in development only.\n */\nexport function ListErrorPanel({\n text,\n technical,\n onRetry,\n resource,\n title,\n className,\n}: Omit<ListErrorStateProps, 'error'> & {\n /** The sentence the user reads. */\n readonly text: string;\n /** The failure's first technical text, for whoever diagnoses it. */\n readonly technical?: string | undefined;\n}): React.ReactElement {\n // `useT()` keeps this panel provider-only (it throws without a BuroProvider) and subscribes\n // to the locale; `useOptionalT()` is the translator that honours a `defaultValue`.\n useT();\n const t = useOptionalT();\n const chromeT = useChromeT();\n const raw = process.env.NODE_ENV === 'production' ? undefined : technical;\n\n return (\n <div\n role=\"alert\"\n className={cn(\n 'flex flex-col items-center justify-center gap-3 px-6 py-16 rounded-lg border border-destructive/40 bg-destructive/5 text-center',\n className,\n )}\n data-testid=\"error\"\n >\n <div className=\"rounded-full bg-destructive/10 p-3 text-destructive\">\n <IconAlertCircle className=\"size-6\" aria-hidden=\"true\" />\n </div>\n <div className=\"space-y-1\">\n <h3 className=\"text-base font-semibold tracking-tight text-destructive\">\n {title ?? t('list.errorTitle')}\n </h3>\n <p className=\"max-w-md text-sm text-muted-foreground\">{text}</p>\n </div>\n {/*\n The raw string still matters — to whoever has to diagnose it, not to\n the operator staring at a broken page. Collapsed, and only when it\n actually differs from what is already shown.\n */}\n {raw && raw !== text ? (\n <details className=\"max-w-md text-left\">\n <summary className=\"cursor-pointer text-xs text-muted-foreground hover:text-foreground\">\n {t('list.errorDetails')}\n </summary>\n <p\n className=\"mt-1.5 break-all font-mono text-xs text-muted-foreground\"\n data-testid=\"list-error-detail\"\n >\n {raw}\n </p>\n </details>\n ) : null}\n {onRetry && (\n <div className=\"flex justify-center pt-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n data-testid={resource ? `list-error-retry:${resource}` : 'list-error-retry'}\n onClick={onRetry}\n className=\"gap-1.5\"\n >\n <IconRefresh className=\"size-3.5\" aria-hidden=\"true\" />\n {chromeT('actions.retry')}\n </Button>\n </div>\n )}\n </div>\n );\n}\n","import { normalizeDataError } from '@burojs/core';\nimport type { LoadErrorViewProps } from '@burojs/react';\n\n/** The state a failed read renders: {@link LoadErrorViewProps.state}. */\nexport type LoadErrorState = LoadErrorViewProps['state'];\n\n/**\n * The state a failed read renders. `not-found` and `forbidden` render\n * identically (no existence oracle). `auth` is a session-expired state with no\n * Retry: the session failed rather than the request, and the runtime's auth\n * controller has already tried to recover. Every other kind — including an\n * error of no recognisable shape, which normalizes to `transport` — is the\n * error state with Retry. The mapping is the providers' job, never a status\n * fallback here.\n */\nexport function recordErrorState(error: unknown): LoadErrorState {\n const { kind } = normalizeDataError(error);\n if (kind === 'not-found' || kind === 'forbidden') return 'not-found';\n if (kind === 'auth') return 'session-expired';\n return 'error';\n}\n","'use client';\nimport { type DataError, normalizeDataError } from '@burojs/core';\nimport {\n type LoadErrorViewProps,\n specificErrorText,\n useChromeT,\n useI18nCaps,\n useLoadErrorView,\n useOptionalT,\n} from '@burojs/react';\nimport { Component, type ErrorInfo, type ReactElement, type ReactNode, useMemo } from 'react';\nimport { cn } from '../lib/cn.js';\nimport { friendlyStringsFrom, technicalTexts, toFriendlyError } from '../lib/friendly-error.js';\nimport { Button } from '../primitives/button.js';\nimport { RecordState } from '../record/record-state.js';\nimport { ListErrorPanel } from './list-error-panel.js';\nimport { type LoadErrorState, recordErrorState } from './state.js';\n\n/** The text a surface falls back to, when no specific text of the error answers (spec 4.15, kind tier). */\nexport interface LoadErrorFallback {\n readonly key: string;\n readonly default: string;\n}\n\nexport interface LoadErrorProps {\n /** Whatever the read threw; the app's view receives it normalized. */\n readonly error: unknown;\n readonly surface: LoadErrorViewProps['surface'];\n readonly resource?: string;\n /** The state to render; derived from the error's kind when omitted. */\n readonly state?: LoadErrorState;\n /** The Retry the surface offers; the kit passes it on for the `'error'` state only. */\n readonly retry?: () => void;\n /** The sentence a surface falls back to (record: `router.record*`, by state). */\n readonly fallback?: LoadErrorFallback;\n /** The default view's test id (a compact surface keeps the id it always had). */\n readonly testId?: string;\n readonly className?: string;\n /** A compact surface's visible content; the sentence is its `title`. */\n readonly children?: ReactNode;\n /** The `list` surface's heading override. */\n readonly title?: string;\n /** Extra DOM attributes for the default alert (a screen node's `data-buro-*`). */\n readonly attributes?: Readonly<Record<string, string | undefined>>;\n}\n\n/** What the kit's default view reads besides the view props. */\ntype DefaultViewProps = LoadErrorViewProps & {\n readonly original: unknown;\n readonly fallback: LoadErrorFallback | undefined;\n readonly testId: string | undefined;\n readonly className: string | undefined;\n readonly title: string | undefined;\n readonly attributes: LoadErrorProps['attributes'];\n readonly children?: ReactNode;\n};\n\nconst RECORD_KEYS: Record<LoadErrorState, string> = {\n 'not-found': 'record.notFoundOrNoAccess',\n 'session-expired': 'router.recordSessionExpired',\n error: 'router.recordError',\n};\n\n/** The list surface's sentence for a failure with no text of its own. */\nconst LIST_FALLBACK: LoadErrorFallback = {\n key: 'list.errorBody',\n default: 'Failed to load data. Please try again.',\n};\n\n/**\n * Every developer-facing text of a failed read: the normalized error's (`details`, `cause`), then\n * the value as thrown (a legacy object's string `message`). For the friendly sentence and the\n * development details only; never the sentence itself.\n */\nexport function loadErrorTechnicalTexts(error: DataError, original: unknown): readonly string[] {\n const out = [...technicalTexts(error), ...technicalTexts(original)];\n if (original !== null && typeof original === 'object' && !(original instanceof Error)) {\n const message = (original as { readonly message?: unknown }).message;\n if (typeof message === 'string') out.push(message);\n }\n return out.filter((text, index) => text.length > 0 && out.indexOf(text) === index);\n}\n\n/**\n * The one sentence of a load error on every surface (spec 4.15 and 4.16). Not-found and forbidden\n * read the not-found sentence and never the error's own text, so no surface tells a missing record\n * from a forbidden one; an expired session reads the session sentence. Every other failure reads\n * the error's own text (the code's, the provider's reference), then the plain-language sentence of\n * a dead network or an unavailable service recognised in its technical text, then the surface's\n * sentence. Technical text itself is never the sentence.\n */\nfunction useLoadErrorText(\n error: DataError,\n original: unknown,\n state: LoadErrorState,\n surface: LoadErrorViewProps['surface'],\n fallback: LoadErrorFallback | undefined,\n): string {\n const t = useOptionalT();\n const caps = useI18nCaps();\n if (state !== 'error') return t(RECORD_KEYS[state]);\n const own = specificErrorText(error, caps);\n if (own !== undefined) return own;\n const strings = friendlyStringsFrom(t);\n for (const text of loadErrorTechnicalTexts(error, original)) {\n const friendly = toFriendlyError(text, '', strings);\n // \"Please try again.\" alone says less than the surface's own sentence.\n if (friendly.replaced && friendly.detail !== strings.generic) return friendly.detail;\n }\n const generic = surface === 'list' ? (fallback ?? LIST_FALLBACK) : fallback;\n if (surface === 'record' || generic === undefined) return t(RECORD_KEYS.error);\n return t(generic.key, { defaultValue: generic.default });\n}\n\n/** The kit's view of a load error, for every surface. */\nfunction DefaultLoadErrorView(props: DefaultViewProps): ReactElement {\n const {\n error,\n surface,\n state,\n retry,\n original,\n fallback,\n testId,\n className,\n children,\n attributes,\n } = props;\n const text = useLoadErrorText(error, original, state, surface, fallback);\n const chromeT = useChromeT();\n if (surface === 'record') {\n return (\n <RecordState\n state={state}\n message={text}\n {...(retry === undefined ? {} : { onRetry: retry })}\n />\n );\n }\n if (surface === 'list') {\n return (\n <ListErrorPanel\n text={text}\n technical={loadErrorTechnicalTexts(error, original)[0]}\n {...(retry === undefined ? {} : { onRetry: retry })}\n {...(props.resource === undefined ? {} : { resource: props.resource })}\n {...(props.title === undefined ? {} : { title: props.title })}\n {...(className === undefined ? {} : { className })}\n />\n );\n }\n if (surface === 'relation' || surface === 'picker') {\n // The raw failure text is for whoever diagnoses it: a tooltip detail in development only.\n const technical =\n process.env.NODE_ENV === 'production'\n ? undefined\n : loadErrorTechnicalTexts(error, original)[0];\n return (\n <span\n {...attributes}\n {...(testId === undefined ? {} : { 'data-testid': testId })}\n className={className}\n title={technical === undefined ? text : `${text} (${technical})`}\n >\n {children ?? text}\n </span>\n );\n }\n return (\n <div\n {...attributes}\n role=\"alert\"\n {...(testId === undefined ? {} : { 'data-testid': testId })}\n className={cn(\n 'flex flex-wrap items-center gap-2 rounded-md border border-dashed px-3 py-2 text-sm text-muted-foreground',\n className,\n )}\n >\n <span>{text}</span>\n {retry === undefined ? null : (\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={retry}>\n {chromeT('actions.retry', { defaultValue: 'Retry' })}\n </Button>\n )}\n </div>\n );\n}\n\ninterface BoundaryProps {\n readonly error: unknown;\n readonly fallback: ReactElement;\n readonly children: ReactNode;\n}\n\n/**\n * Renders the app's view; if it throws, the kit's view takes over and one development error names\n * the failure. A new error to show gives the app's view another chance.\n */\nconst UNSET = Symbol('unset');\n\nclass AppViewBoundary extends Component<BoundaryProps, { failedFor: unknown; failed: boolean }> {\n override state: { failedFor: unknown; failed: boolean } = { failedFor: UNSET, failed: false };\n\n static getDerivedStateFromError(): { failed: true } {\n return { failed: true };\n }\n\n static getDerivedStateFromProps(\n props: BoundaryProps,\n state: { failedFor: unknown; failed: boolean },\n ): { failedFor: unknown; failed: boolean } | null {\n if (state.failed && state.failedFor !== UNSET && state.failedFor !== props.error) {\n return { failedFor: UNSET, failed: false };\n }\n return null;\n }\n\n override componentDidCatch(error: unknown, _info: ErrorInfo): void {\n this.setState({ failedFor: this.props.error });\n if (process.env.NODE_ENV !== 'production') {\n console.error(\n \"[burojs] load-error.view-threw: the app's views.loadError threw while rendering; the kit's view is shown instead.\",\n error,\n );\n }\n }\n\n override render(): ReactNode {\n return this.state.failed ? this.props.fallback : this.props.children;\n }\n}\n\n/**\n * A failed read, drawn by the app's `views.loadError` when it has one and by the kit's view\n * otherwise. The error is normalized once, here; the app's view receives the raw {@link DataError}.\n */\nexport function LoadError(props: LoadErrorProps): ReactElement {\n const App = useLoadErrorView();\n const { error: original, surface, resource } = props;\n const error = useMemo(() => normalizeDataError(original), [original]);\n const state = props.state ?? recordErrorState(error);\n const retry = state === 'error' ? props.retry : undefined;\n const viewProps: LoadErrorViewProps = {\n error,\n surface,\n state,\n ...(resource === undefined ? {} : { resource }),\n ...(retry === undefined ? {} : { retry }),\n };\n const standard = (\n <DefaultLoadErrorView\n {...viewProps}\n original={original}\n fallback={props.fallback}\n testId={props.testId}\n className={props.className}\n title={props.title}\n attributes={props.attributes}\n >\n {props.children}\n </DefaultLoadErrorView>\n );\n if (App === undefined) return standard;\n return (\n <AppViewBoundary error={original} fallback={standard}>\n <App {...viewProps} />\n </AppViewBoundary>\n );\n}\n\n/**\n * What a route's id that names no record reads as (`/orders/abc` for a numeric id field): a\n * not-found answered without a request, under the framework's `invalid-record-id` code.\n */\nconst INVALID_ROUTE_ID: DataError = Object.freeze({\n kind: 'not-found',\n code: 'invalid-record-id',\n});\n\n/**\n * The not-found of a record route whose id is no valid id of its resource (spec 4.19), through\n * {@link LoadError}, so an app's `views.loadError` draws it like any other not-found.\n */\nexport function InvalidRouteId({ resource }: { readonly resource: string }): ReactElement {\n return (\n <LoadError surface=\"record\" resource={resource} state=\"not-found\" error={INVALID_ROUTE_ID} />\n );\n}\n","'use client';\nimport { QUICK_ANCHOR_ATTRIBUTE, quickAnchorRef } from '@burojs/react';\nimport type * as React from 'react';\nimport { useLinkComponent } from '../layout/link-component.js';\n\n/** A plain left click: the main button, no modifier. Anything else follows the `href`. */\nexport function isPlainLeftClick(event: React.MouseEvent): boolean {\n return event.button === 0 && !event.metaKey && !event.ctrlKey && !event.shiftKey && !event.altKey;\n}\n\n/** Claims the anchor an app's link component rendered (it may not forward a ref). */\nfunction claimAnchor(wrapper: HTMLSpanElement | null): void {\n const anchor = wrapper?.querySelector('a') ?? null;\n quickAnchorRef(anchor);\n}\n\n/**\n * A quick opener's anchor (spec 4.5): the app's link component to the record's page, marked with\n * `data-buro-quick` and claimed for its opener, so the navigation guard leaves its click to it. A\n * plain left click calls `preventDefault()` and `onOpen()`; a modified click follows the `href`\n * (a new tab, guarded as any link).\n */\nexport function ClaimedQuickLink({\n href,\n testid,\n className,\n onOpen,\n children,\n}: {\n readonly href: string;\n readonly testid?: string;\n readonly className?: string;\n readonly onOpen: () => void;\n readonly children: React.ReactNode;\n}): React.ReactElement {\n const RouterLink = useLinkComponent();\n return (\n <span ref={claimAnchor} className=\"contents\">\n <RouterLink\n href={href}\n {...(testid === undefined ? {} : { 'data-testid': testid })}\n {...{ [QUICK_ANCHOR_ATTRIBUTE]: '' }}\n {...(className === undefined ? {} : { className })}\n onClick={(event: React.MouseEvent<HTMLAnchorElement>) => {\n event.stopPropagation();\n if (!isPlainLeftClick(event) || event.currentTarget.target === '_blank') return;\n event.preventDefault();\n onOpen();\n }}\n >\n {children}\n </RouterLink>\n </span>\n );\n}\n","/**\n * A record's display name: its `displayField` value when present and non-empty, else its `id`.\n * Exported for consumers building delete dialogs, breadcrumbs and relation labels.\n */\nexport function recordDisplayName(record: Record<string, unknown>, displayField?: string): string {\n if (displayField && record[displayField] != null && record[displayField] !== '') {\n return String(record[displayField]);\n }\n return String(record.id ?? '');\n}\n","import type { useApp, useListAccess } from '@burojs/react';\n\ntype ResourceDefOf = ReturnType<ReturnType<typeof useApp>['registry']['get']>;\n\n/**\n * A list row as a declared hook (`recordTitle`, `recordSubtitle`) may read it (P5 spec 3.6): the\n * row's declared fields its user may view in any-record reach, and its id. `undefined` while the\n * access decision is pending, when a hook reads nothing.\n */\nexport function visibleRow(\n def: ResourceDefOf,\n access: ReturnType<typeof useListAccess>,\n row: Readonly<Record<string, unknown>>,\n): Record<string, unknown> | undefined {\n if (access.status !== 'ready') return undefined;\n const idField = def?.data?.idField || 'id';\n const visible: Record<string, unknown> = {};\n for (const name of Object.keys(def?.fields ?? {}))\n if (Object.hasOwn(row, name) && access.fieldVisible(name)) visible[name] = row[name];\n if (Object.hasOwn(row, idField)) visible[idField] = row[idField];\n return visible;\n}\n","import { type RecordTitleContext, resolveEnumLabel } from '@burojs/core';\nimport { useApp, useI18nCaps, useListAccess } from '@burojs/react';\nimport { useCallback } from 'react';\nimport { recordDisplayName } from './record-display-name.js';\nimport { visibleRow } from './visible-row.js';\n\n/**\n * The display name of a row of `target` as a list surface may show it (P5 spec 3.6, decision\n * P5-27): the row's `displayField` value, else the id; the display field is read only while it is\n * visible, and while the decision is pending the id is shown, never a value. Picker options,\n * relation displays, related labels and palette results read their titles through this.\n *\n * With `recordTitle: true` (the picker options and chips of a relation field, and the relation\n * filter's options and value labels: L3 9.12) the target's `recordTitle` hook comes first. It\n * sees only the row's declared fields its user may view in any-record reach, and its id, as\n * `recordSubtitle` does, and applies only when `displayField` is the target's own (a surface that\n * titles rows by another field, such as a dimension's `labelField`, asked for that field). A\n * relation's display in a cell or on a show page keeps the display field.\n */\nexport function useRowTitle(\n target: string,\n displayField: string | undefined,\n options?: { readonly recordTitle?: boolean },\n): (row: Record<string, unknown>) => string {\n const app = useApp();\n const access = useListAccess(target);\n const caps = useI18nCaps(target);\n const def = app.registry.get(target);\n const hook =\n options?.recordTitle === true && displayField === def?.displayField\n ? def?.recordTitle\n : undefined;\n const visible =\n displayField !== undefined && access.status === 'ready' && access.fieldVisible(displayField);\n return useCallback(\n (row) => {\n const narrowed = hook === undefined ? undefined : visibleRow(def, access, row);\n if (hook !== undefined && narrowed !== undefined) {\n const ctx: RecordTitleContext = {\n resolveEnum: (namespace, value, inlineDefault) =>\n resolveEnumLabel(caps, namespace, value, inlineDefault),\n };\n const title = hook(narrowed, ctx);\n if (typeof title === 'string' && title.trim() !== '') return title;\n }\n return recordDisplayName(row, visible ? displayField : undefined);\n },\n [hook, access, def, caps, visible, displayField],\n );\n}\n","'use client';\nimport { createContext } from 'react';\n\n/**\n * @internal What the popover host gives the screen inside it: the anchor element it is positioned\n * against (the relation display the peek was opened from), and a setter for the popover's\n * accessible name once the screen knows the record's title.\n */\nexport interface PeekHostValue {\n readonly anchor: HTMLElement | null;\n setLabel(label: string): void;\n}\n\n/** @internal Provided by `PopoverPresentationHost`; `null` outside a popover. */\nexport const PeekHostContext = createContext<PeekHostValue | null>(null);\n\n/**\n * @internal True inside a peek (provided by `PeekScreen`): a relation display there attaches no\n * hover intent, so a peek never opens a second peek (spec 4.6).\n */\nexport const PeekContext = createContext(false);\n","'use client';\nimport {\n PEEK_COMPONENT,\n type PeekScreenProps,\n useCurrentUIActivation,\n useEntryGate,\n useQuickOpener,\n useUIPresentationRuntime,\n} from '@burojs/react';\nimport {\n type FocusEvent,\n type PointerEvent,\n type ReactElement,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n useSyncExternalStore,\n} from 'react';\nimport { PeekContext } from './peek-context.js';\n\n/** The hover (and keyboard-focus) delay before a peek opens (spec 4.6). */\nexport const PEEK_DELAY_MS = 500;\n/** Focus this soon after a Tab or arrow keydown is keyboard modality. */\nconst KEYBOARD_FOCUS_WINDOW_MS = 100;\n\nconst NAVIGATION_KEYS = new Set(['Tab', 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight']);\n\n/** When the last Tab or arrow keydown happened; a pointer down forgets it. */\nlet lastNavigationKeyAt = Number.NEGATIVE_INFINITY;\nconst listening = new WeakSet<Document>();\n\nfunction listenForModality(doc: Document): void {\n if (listening.has(doc)) return;\n listening.add(doc);\n doc.addEventListener(\n 'keydown',\n (event) => {\n if (NAVIGATION_KEYS.has(event.key)) lastNavigationKeyAt = Date.now();\n },\n true,\n );\n const forget = () => {\n lastNavigationKeyAt = Number.NEGATIVE_INFINITY;\n };\n doc.addEventListener('pointerdown', forget, true);\n doc.addEventListener('mousedown', forget, true);\n}\n\n/** Whether a focus now came from the keyboard (a Tab or arrow keydown just before it). */\nfunction keyboardModality(): boolean {\n return Date.now() - lastNavigationKeyAt <= KEYBOARD_FOCUS_WINDOW_MS;\n}\n\n/** Elements about to be focused by code: their next focus opens no peek. */\nconst focusedByCode = new WeakSet<Element>();\n\n/**\n * @internal Focus `element` by code (the peek's anchor, when its title opens `quick.show`): the\n * focus opens no peek, whatever key was pressed last.\n */\nexport function focusWithoutPeek(element: HTMLElement): void {\n focusedByCode.add(element);\n element.focus();\n focusedByCode.delete(element);\n}\n\n/** What opens a record from where an anchor sits: its display's own quick opener. */\nexport type PeekAnchorOpener = (target: string, id: string) => void;\n\n/**\n * Each anchor's opener, taken where the display renders: inside a quick sheet it pushes into that\n * sheet, inside a dialog it closes the dialog first. The peek renders beside the overlays, outside\n * the sheet's context, so its title opens through this instead of its own opener.\n */\nconst anchorOpeners = new WeakMap<Element, PeekAnchorOpener>();\n\n/** @internal The opener registered for `anchor` by its peek intent, if any. */\nexport function peekAnchorOpener(anchor: Element | null): PeekAnchorOpener | undefined {\n return anchor === null ? undefined : anchorOpeners.get(anchor);\n}\n\n/** What a peek previews: the display's target and the key it holds (an id, or a `by` key). */\nexport interface PeekTarget {\n readonly to: string;\n readonly id?: string;\n readonly by?: { readonly field: string; readonly key: string };\n}\n\n/** The anchor inside the wrapper: the opener (`data-buro-quick`), else the first element. */\nfunction anchorIn(wrapper: HTMLElement | null): HTMLElement | null {\n if (wrapper === null) return null;\n const marked = wrapper.querySelector<HTMLElement>('[data-buro-quick]');\n if (marked !== null) return marked;\n const first = wrapper.firstElementChild;\n return first instanceof HTMLElement ? first : null;\n}\n\nconst noSubscription = () => () => undefined;\n\n/**\n * A relation display's hover intent (spec 4.6): a `mouse` or `pen` pointer resting on the anchor,\n * or keyboard-modality focus on it (a Tab or arrow keydown just before, never focus set by code),\n * for {@link PEEK_DELAY_MS} asks the entry gate for the target's peek; only `open` presents it,\n * after dismissing any other open peek. Leaving or blurring before then cancels. Nothing is read\n * before the peek opens. Inside a peek it renders its children only.\n */\nexport function PeekIntent({\n target,\n children,\n}: {\n readonly target: PeekTarget;\n readonly children: ReactNode;\n}): ReactElement {\n const inside = useContext(PeekContext);\n if (inside) return <>{children}</>;\n return <ActivePeekIntent target={target}>{children}</ActivePeekIntent>;\n}\n\nfunction ActivePeekIntent({\n target,\n children,\n}: {\n readonly target: PeekTarget;\n readonly children: ReactNode;\n}): ReactElement {\n const gate = useEntryGate();\n const runtime = useUIPresentationRuntime();\n const activation = useCurrentUIActivation();\n const [anchor, setAnchor] = useState<HTMLElement | null>(null);\n const wrapper = useRef<HTMLSpanElement | null>(null);\n const timer = useRef<ReturnType<typeof setTimeout> | null>(null);\n // The latest of each, read when the timer fires (the access answer may have changed since).\n const latest = useRef({ gate, target, activation });\n latest.current = { gate, target, activation };\n\n const attach = useCallback((element: HTMLSpanElement | null) => {\n wrapper.current = element;\n if (element !== null && element.ownerDocument !== undefined)\n listenForModality(element.ownerDocument);\n setAnchor(anchorIn(element));\n }, []);\n\n const expanded = useSyncExternalStore(\n anchor === null ? noSubscription : runtime.subscribe,\n () =>\n anchor !== null &&\n runtime\n .getSnapshot()\n .some((d) => d.component === PEEK_COMPONENT && d.anchor?.element === anchor),\n () => false,\n );\n const peekable = gate(target.to, 'peek').state === 'open';\n\n // The anchor is the app's link (it may not forward props): its popup state is set on it.\n useEffect(() => {\n if (anchor === null) return;\n if (!peekable) {\n anchor.removeAttribute('aria-haspopup');\n anchor.removeAttribute('aria-expanded');\n return;\n }\n anchor.setAttribute('aria-haspopup', 'dialog');\n anchor.setAttribute('aria-expanded', expanded ? 'true' : 'false');\n }, [anchor, peekable, expanded]);\n\n // The opener of where this display sits (a sheet pushes, a dialog closes first), for every\n // display with a peek: an eager one, a lazy `by` one and one under undecided access alike.\n const quickOpen = useQuickOpener();\n const onOpen = useCallback<PeekAnchorOpener>((to, id) => void quickOpen(to, id), [quickOpen]);\n useEffect(() => {\n if (anchor === null) return;\n anchorOpeners.set(anchor, onOpen);\n return () => {\n if (anchorOpeners.get(anchor) === onOpen) anchorOpeners.delete(anchor);\n };\n }, [anchor, onOpen]);\n\n const cancel = useCallback(() => {\n if (timer.current === null) return;\n clearTimeout(timer.current);\n timer.current = null;\n }, []);\n useEffect(() => cancel, [cancel]);\n\n const fire = useCallback(() => {\n timer.current = null;\n const { gate: ask, target: what, activation: from } = latest.current;\n const element = anchorIn(wrapper.current);\n if (element === null || !element.isConnected) return;\n // Only `open` presents: undecided access reads nothing (spec 4.14), a refusal opens nothing.\n const answer = ask(what.to, 'peek');\n if (answer.state !== 'open') return;\n const snapshot = runtime.getSnapshot();\n if (snapshot.some((d) => d.component === PEEK_COMPONENT && d.anchor?.element === element))\n return;\n // One peek at a time.\n for (const descriptor of snapshot)\n if (descriptor.component === PEEK_COMPONENT) runtime.dismiss(descriptor.id);\n const props: PeekScreenProps = {\n target: answer.target,\n ...(what.id === undefined ? {} : { id: what.id }),\n ...(what.by === undefined ? {} : { by: what.by }),\n };\n runtime.present({\n component: PEEK_COMPONENT,\n host: 'popover',\n anchor: { element },\n props: props as unknown as Readonly<Record<string, unknown>>,\n activation: from,\n });\n }, [runtime]);\n\n const schedule = useCallback(() => {\n if (timer.current !== null) return;\n timer.current = setTimeout(fire, PEEK_DELAY_MS);\n }, [fire]);\n\n return (\n // biome-ignore lint/a11y/noStaticElementInteractions: a `display: contents` wrapper that only observes the anchor inside it; the anchor is the interactive element\n <span\n ref={attach}\n className=\"contents\"\n onPointerEnter={(event: PointerEvent) => {\n if (event.pointerType === 'mouse' || event.pointerType === 'pen') schedule();\n }}\n onPointerLeave={cancel}\n onFocus={(event: FocusEvent) => {\n if (focusedByCode.has(event.target)) return;\n if (keyboardModality()) schedule();\n }}\n onBlur={cancel}\n // A click is always quick.show (spec 4.6): it cancels a pending peek.\n onPointerDown={cancel}\n onClickCapture={cancel}\n >\n {children}\n </span>\n );\n}\n","'use client';\nimport type * as React from 'react';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport {\n hasRecordPage,\n relationAmbiguousError,\n resourceKey,\n relationOpenOf,\n type RelationOpen,\n resourceShowHref,\n type ResourceDef,\n type ResourceRefInput,\n routeResourceKey,\n type ResourceNameOrRef,\n} from '@burojs/core';\nimport {\n QUICK_ANCHOR_ATTRIBUTE,\n useApp,\n useCollectionRows,\n useEntryGate,\n useList,\n useOptionalT,\n useQuickOpener,\n useRelatedRecord,\n} from '@burojs/react';\nimport { LoadError } from '../load-error/load-error-view.js';\nimport { technicalText } from '../lib/friendly-error.js';\nimport { useRowTitle } from '../resource/use-row-title.js';\nimport { useLinkComponent } from '../layout/link-component.js';\nimport { PeekIntent, type PeekTarget } from '../quick/use-peek-intent.js';\nimport { ClaimedQuickLink } from './claimed-quick-link.js';\nimport type { FieldRendererProps } from './registry.js';\n\ntype App = ReturnType<typeof useApp>;\n\n/**\n * Shared link styling for in-table relation/row links. Persistent muted\n * dotted underline at idle that snaps to a solid foreground underline on\n * hover. Color stays at `text-foreground` so the link blends with body\n * text — affordance is carried by the underline alone, avoiding the\n * \"every link in brand color\" noise common in admin tables.\n *\n * Used by `<RelationDisplay>` and the first-cell row-anchor link in\n * `<ResourceList>`.\n *\n * `underline-offset-4` is intentional (vs the more common `-2`) to\n * clear the descenders of non-Latin glyphs seen in our\n * playground's Locations column.\n */\nexport const relationLinkClassName =\n 'rounded text-foreground underline decoration-muted-foreground/40 decoration-dotted underline-offset-4 transition-all hover:decoration-foreground hover:decoration-solid focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring';\n\n/**\n * Render a foreign-key value as a clickable link to the related\n * entity's show page.\n *\n * Resolution order:\n * 1. Read `field.meta.to` to get the target resource name (set by\n * `f.relation({ to: '<name>' })`).\n * 2. Look up the target resource's `displayField` from the app\n * registry — used to resolve the link text.\n * 3. Fetch the target record via `useRelatedRecord(to, id)`.\n * 4. Render `<a href=\"/<to>/<id>\">{displayName}</a>`.\n *\n * Fallbacks (matches the fail-soft policy used by `<EnumBadge>`):\n * - Value null/undefined/empty → em-dash placeholder, no fetch.\n * - Target resource not in registry → raw value as muted plain text.\n * Do NOT fire the fetch — the data provider would 404.\n * - Loading → small skeleton placeholder.\n * - Fetch errored → raw value muted, with the error message as title.\n * - Target row not found (no error, no record) → raw value muted with\n * `title=\"<resource>#<id> not found\"`.\n */\nexport function RelationDisplay({ value, field }: FieldRendererProps): React.ReactElement {\n const app = useApp();\n const meta = field?.meta as\n | { to?: ResourceRefInput; by?: unknown; resolve?: unknown }\n | undefined;\n const by = typeof meta?.by === 'string' ? meta.by : undefined;\n const lazy = meta?.resolve === 'lazy';\n // A target this surface cannot name — a builder field's thunk `to` that no app registration\n // lowered (a declarative form or display), or a malformed ref — renders like no target, as the\n // picker does, instead of throwing during render.\n let to: string | undefined;\n try {\n to = meta?.to === undefined ? undefined : resourceKey(meta.to);\n } catch {\n to = undefined;\n }\n const id = value as string | number | null | undefined;\n const idStr = String(value ?? '');\n const baseId = `relation-display:${to ?? 'unknown'}:${idStr}`;\n // What a click on the title opens: the overlay (default), the page, or nothing (`ui.open`).\n const open = relationOpenOf({ ui: (field as { readonly ui?: unknown } | undefined)?.ui });\n\n // Empty / null FK — render em-dash, do not fetch.\n // NB: do NOT short-circuit on `value === 0`; the relation schema is\n // `string | number`, and a target row with PK 0 (rare but valid) would\n // otherwise be silently treated as missing.\n if (value == null || value === '') {\n return (\n <span data-testid={`${baseId}:empty`} className=\"text-muted-foreground\">\n —\n </span>\n );\n }\n\n // Target resource not declared on the field. Without a target we\n // cannot build a link — degrade to plain text.\n if (!to) {\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.warn(\n `[RelationDisplay] no meta.to declared on field — rendering raw value '${idStr}'`,\n );\n }\n return <span data-testid={`relation-display:unknown:${idStr}:no-target`}>{idStr}</span>;\n }\n\n // `lazy` (spec 4.3): nothing registers, nothing is read — the key itself is shown.\n if (lazy) return <LazyRelationDisplay to={to} by={by} idStr={idStr} app={app} open={open} />;\n\n return (\n <GatedRelationDisplay\n to={to}\n by={by}\n id={id as string | number}\n idStr={idStr}\n app={app}\n open={open}\n />\n );\n}\n\n/**\n * Public, adopter-facing entry point for rendering a foreign-key value.\n * Thin convenience wrapper over `<RelationDisplay>`: adopters write\n * `<RelationField to=\"reference_locations\" value={id} />` instead of\n * constructing the field-registry `{ name, meta }` shape by hand.\n * `RelationDisplay` itself stays the field-kind renderer registered for\n * `f.relation(...)` — its `{ value, field }` signature is dictated by the\n * `FieldRendererProps` contract and is unchanged.\n *\n * `RelationDisplay` reads the target resource from `field.meta.to` (see\n * `RelationDisplay` above), so this wrapper just shapes that `meta` object;\n * `field.name` is set to `''` since standalone usage has no owning field.\n */\nexport function RelationField<const N extends string = string>({\n to: toInput,\n value,\n}: {\n /** Target resource name (matches `f.relation({ to: '...' })`). */\n to: ResourceNameOrRef<N>;\n /** FK value to resolve, or null/undefined/'' when empty. */\n value: unknown;\n}): React.ReactElement {\n const to = routeResourceKey(toInput);\n return <RelationDisplay value={value} field={{ name: '', meta: { to } }} />;\n}\n\n/** What a key's peek previews: the row by id, or by the `by` field the key holds. */\nfunction peekTarget(to: string, by: string | undefined, key: string): PeekTarget {\n return by === undefined ? { to, id: key } : { to, by: { field: by, key } };\n}\n\n/** The definition whose record pages a link to `def`'s record lands on (`routesTo.show`). */\nfunction showPageDef(app: App, def: ResourceDef): ResourceDef | undefined {\n const delegate = def.routesTo?.show;\n if (delegate === undefined) return def;\n try {\n return app.registry.get(resourceKey(delegate as ResourceRefInput));\n } catch {\n return undefined;\n }\n}\n\n/** Whether `def`'s record has a show page to link to, following `routesTo.show`. */\nexport function linksToPage(app: App, def: ResourceDef): boolean {\n const target = showPageDef(app, def);\n return target !== undefined && hasRecordPage(target, 'show');\n}\n\n/**\n * A relation display's opener (spec 4.5): the title as an anchor to the page (when there is one)\n * or a button (when there is none), carrying `data-buro-quick` and claimed for the opener, whose\n * plain left click opens `quick.show` instead of navigating. A modified click follows the `href`.\n */\nfunction QuickOpener({\n href,\n testid,\n onOpen,\n children,\n}: {\n readonly href: string | null;\n readonly testid: string;\n readonly onOpen: () => void;\n readonly children: React.ReactNode;\n}): React.ReactElement {\n if (href === null)\n return (\n <button\n type=\"button\"\n data-testid={testid}\n {...{ [QUICK_ANCHOR_ATTRIBUTE]: '' }}\n className={`${relationLinkClassName} text-left`}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n onOpen();\n }}\n >\n {children}\n </button>\n );\n return (\n <ClaimedQuickLink href={href} testid={testid} className={relationLinkClassName} onOpen={onOpen}>\n {children}\n </ClaimedQuickLink>\n );\n}\n\n/**\n * A lazy relation's key (spec 4.3, 4.5): nothing is read until it is clicked. An id key is the\n * opener of the target's `quick.show`; a `by` key is a button whose click reads the one row the\n * key names (`where <by> eq <key>`, two rows) and opens it — no row renders the not-available\n * text, two rows the muted key with the development error, and neither opens anything.\n */\nfunction LazyRelationDisplay({\n to,\n by,\n idStr,\n app,\n open: openMode,\n}: Omit<BodyProps, 'id'>): React.ReactElement {\n const RouterLink = useLinkComponent();\n const gate = useEntryGate();\n const open = useQuickOpener();\n const targetDef = app.registry.get(to);\n const baseId = `relation-display:${to}:${idStr}`;\n if (!targetDef || openMode === 'none') return <span data-testid={`${baseId}:lazy`}>{idStr}</span>;\n const answer = gate(to, 'show');\n // Undecided: the key as text, nothing read; its peek asks the gate again when it would open.\n if (answer.state === 'undecided')\n return (\n <PeekIntent target={peekTarget(to, by, idStr)}>\n <span data-testid={`${baseId}:lazy`}>{idStr}</span>\n </PeekIntent>\n );\n // Denied: the key as text, nothing to open (no read, no anchor).\n if (answer.state === 'hidden' || answer.state === 'disabled')\n return <span data-testid={`${baseId}:lazy`}>{idStr}</span>;\n const page = linksToPage(app, targetDef);\n // `open: 'page'`: the key is a plain page link whatever the gate says about the overlay.\n if (openMode === 'page') {\n if (by !== undefined || !page) return <span data-testid={`${baseId}:lazy`}>{idStr}</span>;\n return (\n <RouterLink\n href={resourceShowHref(app.registry, targetDef, to, idStr)}\n data-testid={`${baseId}:lazy`}\n className={relationLinkClassName}\n onClick={(e) => e.stopPropagation()}\n >\n {idStr}\n </RouterLink>\n );\n }\n if (answer.state !== 'open') {\n if (by !== undefined || !page) return <span data-testid={`${baseId}:lazy`}>{idStr}</span>;\n return (\n <RouterLink\n href={resourceShowHref(app.registry, targetDef, to, idStr)}\n data-testid={`${baseId}:lazy`}\n className={relationLinkClassName}\n onClick={(e) => e.stopPropagation()}\n >\n {idStr}\n </RouterLink>\n );\n }\n if (by !== undefined)\n return (\n <PeekIntent target={peekTarget(to, by, idStr)}>\n <LazyByOpener to={to} by={by} idStr={idStr} target={answer.target} />\n </PeekIntent>\n );\n const openKey = () => void open(to, idStr);\n return (\n <PeekIntent target={peekTarget(to, undefined, idStr)}>\n <QuickOpener\n href={page ? resourceShowHref(app.registry, targetDef, to, idStr) : null}\n testid={`${baseId}:lazy`}\n onOpen={openKey}\n >\n {idStr}\n </QuickOpener>\n </PeekIntent>\n );\n}\n\n/** A lazy `by` key's button: one `where <by> eq <key>` read on click, then the row it names. */\nfunction LazyByOpener({\n to,\n by,\n idStr,\n target,\n}: {\n readonly to: string;\n readonly by: string;\n readonly idStr: string;\n readonly target: string;\n}): React.ReactElement {\n const app = useApp();\n const t = useOptionalT();\n const open = useQuickOpener();\n const [asked, setAsked] = useState(false);\n const read = useList(to, {\n ...(asked\n ? {\n filter: { field: by, op: 'eq', value: idStr } as never,\n pagination: { kind: 'offset', page: 1, pageSize: 2 } as never,\n }\n : {}),\n // A key names one record: never narrowed by a scope. The quick peek reads this same\n // descriptor (`peek-screen.tsx`), so both say `'none'`.\n scope: 'none',\n enabled: asked,\n retry: false,\n });\n const rows = (read.data as { readonly data?: readonly Record<string, unknown>[] } | undefined)\n ?.data;\n const baseId = `relation-display:${to}:${idStr}`;\n const idField = (app.registry.get(target)?.data as { readonly idField?: unknown } | undefined)\n ?.idField;\n const rowId =\n rows?.length === 1\n ? rows[0]?.[typeof idField === 'string' && idField.length > 0 ? idField : 'id']\n : undefined;\n // Only a click opens: a click before the row is read leaves a request here, the effect below\n // answers it once; a refetch that changes the rows later opens nothing.\n const requested = useRef(false);\n useEffect(() => {\n if (!asked || rows === undefined || !requested.current) return;\n if (rows.length > 1) {\n requested.current = false;\n if (process.env.NODE_ENV !== 'production')\n console.error(`[burojs] ${technicalText(relationAmbiguousError(to, by, idStr))}`);\n return;\n }\n requested.current = false;\n if (rows.length === 1 && rowId !== undefined && rowId !== null) open(to, String(rowId));\n }, [asked, rows, rowId, open, to, by, idStr]);\n if (asked && rows !== undefined && rows.length === 0)\n return (\n <span data-testid={`${baseId}:unavailable`} className=\"text-muted-foreground\">\n {t('relation.unavailable', { defaultValue: 'Not available' })}\n </span>\n );\n if (asked && rows !== undefined && rows.length > 1)\n return (\n <span data-testid={`${baseId}:ambiguous`} className=\"text-muted-foreground\">\n {idStr}\n </span>\n );\n return (\n <button\n type=\"button\"\n data-testid={`${baseId}:lazy`}\n {...{ [QUICK_ANCHOR_ATTRIBUTE]: '' }}\n className={`${relationLinkClassName} text-left`}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n // A key already read opens its row at once; otherwise the read answers this click.\n if (asked && rowId !== undefined && rowId !== null) open(to, String(rowId));\n else {\n requested.current = true;\n setAsked(true);\n }\n }}\n >\n {idStr}\n </button>\n );\n}\n\ninterface BodyProps {\n to: string;\n /** The target field the key holds (`meta.by`); the target's id field when absent. */\n by?: string;\n id: string | number;\n idStr: string;\n app: App;\n /** What a click on the title opens (`ui.open`). */\n open: RelationOpen;\n}\n\n/**\n * The entry gate decides before anything is read (spec 4.4, 4.14): while it is undecided (the\n * permission map loads) or when `show` is denied, the key renders as plain text and the display\n * registers no read; otherwise the body reads the title and renders the opener — or, when the\n * target has no quick show (`absent`), the page link of before, or text when there is no page.\n */\nfunction GatedRelationDisplay(props: BodyProps): React.ReactElement {\n const gate = useEntryGate();\n const target = props.to;\n const { idStr } = props;\n const answer = gate(target, 'show');\n // Undecided: plain text and no read; its peek (hover) asks the gate again when it would open,\n // and opens nothing until access is decided (spec 4.14).\n if (answer.state === 'undecided')\n return (\n <PeekIntent target={peekTarget(target, props.by, idStr)}>\n <span data-testid={`relation-display:${target}:${idStr}:text`}>{idStr}</span>\n </PeekIntent>\n );\n if (answer.state === 'hidden' || answer.state === 'disabled')\n return <span data-testid={`relation-display:${target}:${idStr}:text`}>{idStr}</span>;\n return (\n <RelationDisplayBody\n {...props}\n quickTarget={answer.state === 'open' && props.open === 'quick' ? answer.target : null}\n />\n );\n}\n\n/**\n * Split body so the hook is only called when we know `to` is set and\n * the value is non-falsy. React's rules of hooks require unconditional\n * hook calls per render — separating the body keeps the early-return\n * branches above hook-free.\n */\nfunction RelationDisplayBody({\n to,\n by,\n id,\n idStr,\n app,\n open: openMode,\n quickTarget,\n}: BodyProps & { readonly quickTarget: string | null }): React.ReactElement {\n const targetDef = app.registry.get(to);\n const rowTitle = useRowTitle(to, targetDef?.displayField);\n const baseId = `relation-display:${to}:${idStr}`;\n const RouterLink = useLinkComponent();\n const open = useQuickOpener();\n const gate = useEntryGate();\n const collectionRow = useCollectionRows(to);\n const { record, isLoading, error, ambiguous } = useRelatedRecord(\n to,\n id,\n by === undefined ? undefined : { by },\n );\n\n // Target resource not in registry — degrade to plain text. No link\n // can be built without a basePath. Same fail-soft as `<EnumBadge>`.\n if (!targetDef) {\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.warn(\n `[RelationDisplay] target resource '${to}' not registered — rendering raw value '${idStr}'`,\n );\n }\n return (\n <span data-testid={`${baseId}:unregistered`} className=\"text-muted-foreground\">\n {idStr}\n </span>\n );\n }\n\n if (isLoading) {\n return (\n <span\n data-testid={`relation-display-loading:${to}`}\n className=\"inline-block h-5 w-20 animate-pulse rounded bg-muted\"\n aria-busy=\"true\"\n />\n );\n }\n\n // A key two rows hold: the raw key, muted — never either row (spec 4.2, fail closed).\n if (ambiguous) {\n return (\n <span\n data-testid={`${baseId}:ambiguous`}\n className=\"text-muted-foreground\"\n title={`${to}: more than one row has ${by ?? 'id'} ${idStr}`}\n >\n {idStr}\n </span>\n );\n }\n\n if (error) {\n return (\n <LoadError\n surface=\"relation\"\n error={error}\n resource={to}\n testId={`${baseId}:error`}\n className=\"text-muted-foreground\"\n fallback={{ key: 'relation.failed', default: 'Failed to load options.' }}\n >\n {idStr}\n </LoadError>\n );\n }\n\n if (!record) {\n return (\n <span\n data-testid={`${baseId}:not-found`}\n className=\"text-muted-foreground\"\n title={`${to} #${idStr} not found`}\n >\n {idStr}\n </span>\n );\n }\n\n const displayName = rowTitle(record);\n // The link names the resolved row by its id field (spec 4.2), never by the key: a `by` key is\n // not an id, and the target's id field need not be `id`.\n const idField = (targetDef.data as { readonly idField?: unknown } | undefined)?.idField;\n const rowId = record[typeof idField === 'string' && idField.length > 0 ? idField : 'id'];\n if (rowId === null || rowId === undefined || rowId === '')\n return (\n <span data-testid={`${baseId}:no-id`} className=\"text-muted-foreground\">\n {displayName}\n </span>\n );\n // A collection's loaded row is its member's (REF-131 B12): the link goes to the member's\n // page, and the title opens and peeks the member, as the member's entry gate answers for this\n // row. A row of a type no member claims links to the collection's record URL, which redirects.\n const kind = collectionRow?.(record);\n const member = kind !== undefined && 'member' in kind ? kind.member : undefined;\n const memberDef = member === undefined ? undefined : app.registry.get(member);\n const page = linksToPage(app, memberDef ?? targetDef);\n const href = page ? resourceShowHref(app.registry, targetDef, to, String(rowId), record) : null;\n // `open: 'none'`: the title is text, no anchor and no button.\n if (openMode === 'none') return <span data-testid={baseId}>{displayName}</span>;\n if (quickTarget !== null)\n return (\n <RowOpener to={to} rowId={String(rowId)} href={href} testid={baseId} open={open}>\n {displayName}\n </RowOpener>\n );\n if (collectionRow !== undefined) {\n // The gate answers for the row: its member's rules for a member's row, the collection's own\n // `show` for a row no member claims. Denied or not yet decided, the key is text, as a denied\n // target's is (spec 4.14): never the title the read returned.\n const answer = gate(to, 'show', record);\n if (answer.state === 'hidden' || answer.state === 'disabled' || answer.state === 'undecided')\n return <span data-testid={`${baseId}:text`}>{idStr}</span>;\n if (member !== undefined && answer.state === 'open' && openMode === 'quick')\n return (\n <RowOpener to={answer.target} rowId={String(rowId)} href={href} testid={baseId} open={open}>\n {displayName}\n </RowOpener>\n );\n }\n // No quick show (switched off, or no host wired): the page link, or text without a page.\n if (href === null) return <span data-testid={baseId}>{displayName}</span>;\n return (\n <RouterLink\n href={href}\n data-testid={baseId}\n className={relationLinkClassName}\n onClick={(e) => e.stopPropagation()}\n >\n {displayName}\n </RouterLink>\n );\n}\n\n/**\n * A resolved row's opener: a click opens its `quick.show`, a hover its peek — by the row's id,\n * the record descriptor `quick.show` reads, so the two share one read.\n */\nfunction RowOpener({\n to,\n rowId,\n href,\n testid,\n open,\n children,\n}: {\n readonly to: string;\n readonly rowId: string;\n readonly href: string | null;\n readonly testid: string;\n readonly open: ReturnType<typeof useQuickOpener>;\n readonly children: React.ReactNode;\n}): React.ReactElement {\n const onOpen = useCallback(() => void open(to, rowId), [open, to, rowId]);\n return (\n <PeekIntent target={peekTarget(to, undefined, rowId)}>\n <QuickOpener href={href} testid={testid} onOpen={onOpen}>\n {children}\n </QuickOpener>\n </PeekIntent>\n );\n}\n","import type { ErasedResourceHandle, FilterExpression, SearchDecl } from '@burojs/core';\nimport { filterFields } from '@burojs/react';\n\n/**\n * A declared search set without the fields its user may not view (P5 spec 3.7, decision P5-17).\n * No field left means no search. A function search is kept: its output is checked by\n * {@link namesHiddenField}.\n */\nexport function narrowSearchDecl(\n declared: SearchDecl | undefined,\n visible: (field: string) => boolean,\n): SearchDecl | undefined {\n if (declared === undefined || typeof declared === 'function') return declared;\n if (!Array.isArray(declared.fields)) return declared;\n const fields = declared.fields.filter((ref) =>\n visible(typeof ref === 'string' ? ref : ref.field),\n );\n if (fields.length === declared.fields.length) return declared;\n return fields.length === 0 ? undefined : { ...declared, fields };\n}\n\n/**\n * Whether a composed filter names a field its user may not view: an author predicate (a fixed\n * filter) or a function search's output. Such a read is forbidden, never narrowed — dropping a\n * narrowing predicate would fail open.\n */\nexport function namesHiddenField(\n filter: FilterExpression<ErasedResourceHandle> | undefined,\n visible: (field: string) => boolean,\n): boolean {\n return filter !== undefined && filterFields(filter).some((field) => !visible(field));\n}\n","'use client';\n\nimport * as React from 'react';\nimport {\n composeListFilter,\n type ErasedResourceHandle,\n type FilterExpression,\n type FixedFilterInput,\n normalizeFixedFilters,\n type ScopeSource,\n type SearchDecl,\n} from '@burojs/core';\nimport { useList } from '@burojs/react';\n\ntype ErasedExpression = FilterExpression<ErasedResourceHandle>;\n\n/**\n * The filter the select re-reads a created record through (P6-33): the picker's own option query\n * for an empty search (`composeListFilter`, the same `fixed` filters, the same search\n * declaration), conjoined with `<idField> eq <id>`. The row must come back through the query the\n * select offers from, or it is not selected.\n */\nexport function createdOptionFilter(input: {\n readonly fixed: readonly FixedFilterInput[] | undefined;\n readonly idField: string;\n readonly id: string | number;\n readonly searchDecl?: SearchDecl | undefined;\n readonly searchContext?: { readonly resource: string; readonly def: unknown };\n}): ErasedExpression {\n const own = createdOptionScope(input);\n const byId = { field: input.idField, op: 'eq', value: input.id } as ErasedExpression;\n return own === undefined ? byId : ({ and: [own, byId] } as ErasedExpression);\n}\n\n/**\n * The select's option query for an empty search, without the id predicate: what the picker itself\n * sends, so the same hidden-field rule (`namesHiddenField`) judges both.\n */\nexport function createdOptionScope(input: {\n readonly fixed: readonly FixedFilterInput[] | undefined;\n readonly searchDecl?: SearchDecl | undefined;\n readonly searchContext?: { readonly resource: string; readonly def: unknown };\n}): ErasedExpression | undefined {\n return composeListFilter({\n fixed: normalizeFixedFilters(input.fixed),\n search: '',\n ...(input.searchDecl === undefined ? {} : { searchDecl: input.searchDecl }),\n ...(input.searchContext === undefined ? {} : { searchContext: input.searchContext as never }),\n });\n}\n\n/** What the re-read settled on: the value to select, \"does not fit\", or a failed read. */\nexport type CreatedOptionResult =\n | { readonly kind: 'fits'; readonly value: string | number }\n | { readonly kind: 'does-not-fit' }\n | { readonly kind: 'failed' };\n\nexport interface CreatedOptionReadProps {\n readonly to: string;\n readonly filter: ErasedExpression;\n /**\n * The select's read scope, as its option list takes it: the picker and the hand-back never\n * disagree on which rows fit.\n */\n readonly scope: ScopeSource;\n /** The record field the select writes (`useList`'s `scopeField`), as its option list passes it. */\n readonly scopeField?: string;\n readonly by: string | undefined;\n readonly idField: string;\n /** Called once, with the settled answer. */\n readonly onSettled: (result: CreatedOptionResult) => void;\n}\n\n/**\n * Mounted only while a created record is being handed back. One list read, limit 1, through the\n * select's own option query (Known finding 13): an empty answer is \"does not fit\", a failed read\n * is a failure, never \"fits\". Mounting it is the request; unmounting it drops the answer.\n */\nexport function CreatedOptionRead({\n to,\n filter,\n scope,\n scopeField,\n by,\n idField,\n onSettled,\n}: CreatedOptionReadProps): null {\n const query = useList(to, {\n filter: filter as never,\n pagination: { kind: 'offset', page: 1, pageSize: 1 },\n scope,\n ...(scopeField === undefined ? {} : { scopeField }),\n retry: false,\n });\n const settled = React.useRef(false);\n const latest = React.useRef(onSettled);\n latest.current = onSettled;\n const rows = (query.data as { readonly data?: readonly Record<string, unknown>[] } | undefined)\n ?.data;\n const answered = rows !== undefined && query.isCurrentData && !query.isFetching;\n const failed = query.isError && !query.isFetching;\n React.useEffect(() => {\n if (settled.current) return;\n if (failed) {\n settled.current = true;\n latest.current({ kind: 'failed' });\n return;\n }\n if (!answered) return;\n settled.current = true;\n const value = rows[0]?.[by ?? idField];\n latest.current(\n typeof value === 'string' || typeof value === 'number'\n ? { kind: 'fits', value }\n : { kind: 'does-not-fit' },\n );\n }, [answered, failed, rows, by, idField]);\n return null;\n}\n","'use client';\n\nimport * as React from 'react';\nimport { IconEye } from '@tabler/icons-react';\nimport { type RelationOpen, resourceShowHref } from '@burojs/core';\nimport {\n QUICK_ANCHOR_ATTRIBUTE,\n collectionRowHref,\n useApp,\n useAvailabilityGate,\n useCollectionRows,\n useEntryGate,\n useList,\n useListAccess,\n useOptionalT,\n useQuick,\n useQuickOpener,\n useRouteNavigate,\n useTestIds,\n} from '@burojs/react';\nimport { buttonVariants } from '../primitives/button.js';\nimport { cn } from '../lib/cn.js';\nimport { useLinkComponent } from '../layout/link-component.js';\nimport { ClaimedQuickLink, isPlainLeftClick } from './claimed-quick-link.js';\nimport { linksToPage } from './relation-display.js';\n\n/** A key a read may send: a non-empty string or a finite number (Known finding 1). */\nexport function selectKey(value: unknown): string | null {\n if (typeof value === 'string') return value.length === 0 ? null : value;\n if (typeof value === 'number') return Number.isFinite(value) ? String(value) : null;\n return null;\n}\n\nconst VIEW_CLASS = cn(buttonVariants({ variant: 'outline', size: 'icon' }), 'shrink-0');\nconst TITLE_CLASS = 'min-w-0 max-w-[16rem] truncate';\nconst TITLE_VIEW_CLASS = cn(\n TITLE_CLASS,\n 'cursor-pointer rounded-sm text-left hover:underline focus:outline-hidden focus-visible:ring-2 focus-visible:ring-ring',\n);\n\nexport interface RelationViewButtonProps {\n readonly to: string;\n readonly value: unknown;\n readonly by: string | undefined;\n /** The form field holding the key: the test id's second part. */\n readonly fieldName: string;\n /** Runs before the overlay opens: the picker moves focus to its trigger, where it returns. */\n readonly beforeOpen: () => void;\n /**\n * The field's `ui.open` (P7 3.6): `quick` (default) opens the record above the form, `page`\n * goes to its show page through the navigation guard (a dirty form asks first), `none` draws\n * no button.\n */\n readonly open?: RelationOpen;\n /**\n * Draw the record's title as the trigger instead of the eye icon (a relation chip): the title\n * itself opens the record. Where \"view\" is not offered, the title is drawn as plain text.\n */\n readonly title?: string;\n}\n\n/**\n * \"View\" beside a relation select's trigger (P6-28): the target's `quick.show` as a new overlay\n * above the form, never a push and never closing the host. Drawn only when the select holds a\n * key and the entry gate is open without a row (the row-level re-check runs inside the overlay,\n * P3-44); while the gate is undecided nothing is drawn and nothing is read (P3-15). A `by` key is\n * resolved by the limit-2 read on click; zero or two rows open nothing.\n */\nexport function RelationViewButton(props: RelationViewButtonProps): React.ReactElement | null {\n const gate = useEntryGate();\n const availability = useAvailabilityGate('show');\n const { to, value, by } = props;\n const collection = useCollectionRows(to) !== undefined;\n const access = useListAccess(to);\n const key = selectKey(value);\n const plain = plainTitle(props.title);\n if (key === null || props.open === 'none') return plain;\n // A `by` field the user may not view is never sent as a predicate: no \"view\", no read.\n if (by !== undefined && !(access.status === 'ready' && access.fieldVisible(by))) return plain;\n const answer = gate(to, 'show');\n // A collection has no entry of its own: asked without a row its gate is `absent` once\n // decided, and \"view\" then reads the row (the overlay opens as its member) or links to the\n // collection's record URL, which redirects. Its own `show` must still be available.\n const viewable = collection\n ? answer.state === 'absent' && availability(to, 'show').state === 'available'\n : answer.state === 'open';\n if (!viewable) return plain;\n // Keyed by the value: a click asked for one key's read and must not outlive it.\n return <ViewButton key={key} {...props} keyString={key} collection={collection} />;\n}\n\nfunction plainTitle(title: string | undefined): React.ReactElement | null {\n return title === undefined ? null : <span className={TITLE_CLASS}>{title}</span>;\n}\n\nfunction ViewButton({\n to,\n by: byField,\n fieldName,\n keyString,\n beforeOpen,\n open: openMode = 'quick',\n title,\n collection,\n}: RelationViewButtonProps & {\n readonly keyString: string;\n readonly collection: boolean;\n}): React.ReactElement | null {\n const app = useApp();\n const t = useOptionalT();\n const tid = useTestIds();\n const quick = useQuick();\n const openQuick = useQuickOpener();\n const navigate = useRouteNavigate();\n const availability = useAvailabilityGate('show');\n const RouterLink = useLinkComponent();\n const [asked, setAsked] = React.useState(false);\n const requested = React.useRef(false);\n const targetDef = app.registry.get(to);\n const rawIdField = (targetDef?.data as { readonly idField?: unknown } | undefined)?.idField;\n const idField = typeof rawIdField === 'string' && rawIdField.length > 0 ? rawIdField : 'id';\n // The field the click reads the row by. A collection's overlay opens as the row's member, so\n // even an id key is read first (`where <id> eq <key>`), and the row goes to the opener.\n const by = byField ?? (collection && openMode !== 'page' ? idField : undefined);\n const read = useList(to, {\n ...(asked && by !== undefined\n ? {\n filter: { field: by, op: 'eq', value: keyString } as never,\n pagination: { kind: 'offset', page: 1, pageSize: 2 } as never,\n }\n : {}),\n // A key names one record: the read is never narrowed by a scope.\n scope: 'none',\n enabled: asked && by !== undefined,\n retry: false,\n });\n // Rows of this key only: a placeholder carried over from another key's read is not an answer.\n const current = read.isCurrentData && !read.isPlaceholderData && !read.isFetching;\n const rows = current\n ? (read.data as { readonly data?: readonly Record<string, unknown>[] } | undefined)?.data\n : undefined;\n const open = React.useCallback(\n (id: string, row?: unknown) => {\n beforeOpen();\n if (openMode === 'page') {\n // The page of the record, through the navigation guard: unsaved input asks first. A row\n // read for a `by` key names its member when the target is a collection (B12).\n if (targetDef !== undefined && linksToPage(app, targetDef))\n navigate(resourceShowHref(app.registry, targetDef, to, id, row));\n return;\n }\n if (!collection) {\n quick.show(to, id);\n return;\n }\n // The row's member may open nothing above the form (a row of a type no member claims, a\n // member denying `show` or without `quick.show`, no host): the click then goes where the\n // collection's list row would link, the member's show or edit page or the collection's\n // record URL, and does nothing only when that row links nowhere either. An undecided gate\n // waits, as the row link does.\n if (openQuick(to, id, { row }) !== 'absent' || targetDef === undefined) return;\n const href = collectionRowHref(app.registry, targetDef, to, id, row, availability);\n if (href !== undefined && href !== '') navigate(href);\n },\n [\n beforeOpen,\n quick,\n openQuick,\n collection,\n to,\n openMode,\n navigate,\n app,\n targetDef,\n availability,\n ],\n );\n // Only a click opens: the read answers the click that asked for it, once.\n React.useEffect(() => {\n if (by === undefined || !asked || rows === undefined || !requested.current) return;\n requested.current = false;\n if (rows.length !== 1) {\n if (rows.length > 1 && process.env.NODE_ENV !== 'production')\n console.error(\n `[burojs] ${to}: more than one row has ${by} ${keyString}; \"view\" opened nothing.`,\n );\n return;\n }\n const id = rows[0]?.[idField];\n const next = selectKey(id);\n if (next !== null) open(next, rows[0]);\n }, [by, asked, rows, idField, keyString, to, open]);\n\n const label = t('relationPicker.view', { defaultValue: 'View' });\n const content = title === undefined ? <IconEye className=\"h-4 w-4\" aria-hidden /> : title;\n const className = title === undefined ? VIEW_CLASS : TITLE_VIEW_CLASS;\n const testid = tid.relationView(to, fieldName);\n // `page` needs a page to go to (the publish check says so): without one, nothing is drawn.\n if (openMode === 'page' && (targetDef === undefined || !linksToPage(app, targetDef)))\n return plainTitle(title);\n if (openMode === 'page' && by === undefined && targetDef !== undefined)\n return (\n <RouterLink\n href={resourceShowHref(app.registry, targetDef, to, keyString)}\n data-testid={testid}\n className={className}\n onClick={() => beforeOpen()}\n >\n <span className=\"sr-only\">{label} </span>\n {content}\n </RouterLink>\n );\n if (by === undefined && targetDef !== undefined && linksToPage(app, targetDef))\n return (\n <ClaimedQuickLink\n href={resourceShowHref(app.registry, targetDef, to, keyString)}\n testid={testid}\n className={className}\n onOpen={() => open(keyString)}\n >\n <span className=\"sr-only\">{label} </span>\n {content}\n </ClaimedQuickLink>\n );\n return (\n <button\n type=\"button\"\n className={className}\n data-testid={testid}\n aria-label={title === undefined ? label : `${label} ${title}`}\n {...{ [QUICK_ANCHOR_ATTRIBUTE]: '' }}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n // No page to follow (or, for a `by` key, no id to build it from): a modified click is\n // nothing, never an overlay the user asked to avoid.\n if (!isPlainLeftClick(event)) return;\n if (by === undefined) {\n open(keyString);\n return;\n }\n requested.current = true;\n setAsked(true);\n // A key already read opens at once; the effect answers a click made before the read.\n if (rows !== undefined && rows.length === 1) {\n const next = selectKey(rows[0]?.[idField]);\n requested.current = false;\n if (next !== null) open(next, rows[0]);\n }\n }}\n >\n {content}\n </button>\n );\n}\n","'use client';\n\nimport * as React from 'react';\nimport type { FixedFilterInput, ScopeSource, SearchDecl } from '@burojs/core';\nimport {\n type QuickSettledRow,\n useApp,\n useListAccess,\n useEntryGate,\n useOptionalT,\n useQuick,\n useTestIds,\n} from '@burojs/react';\nimport { toast } from '../notification/toaster.js';\nimport {\n CreatedOptionRead,\n type CreatedOptionResult,\n createdOptionFilter,\n createdOptionScope,\n} from './relation-hand-back.js';\nimport { namesHiddenField } from './search-access.js';\nimport { selectKey } from './relation-view-button.js';\n\n/** What the picker and its dialog share: one pending create per select (P6-34). */\nexport interface SelectCreate {\n readonly pending: boolean;\n /**\n * The hand-back read is forbidden: its filter names a field P5 hides from the user (the same\n * rule that stops the picker's own option read), or the access map is not ready. A blocked\n * select offers no \"+ Create\" and starts none, so no predicate on a hidden field is ever sent.\n */\n readonly blocked: boolean;\n /** Runs `open` unless a create of this select is already pending or the select is gone. */\n start(open: () => Promise<QuickSettledRow>): void;\n}\n\ninterface SelectCreateInput {\n readonly to: string;\n readonly by: string | undefined;\n /** The row field the select holds (`by`, else the target's id field). */\n readonly valueField: string;\n readonly idField: string;\n readonly fixedFilters: readonly FixedFilterInput[] | undefined;\n /** The select's read scope: the hand-back reads as the option list does. */\n readonly scope: ScopeSource;\n /** The record field the select writes, as the option list passes it. */\n readonly scopeField?: string;\n /**\n * The select's candidates gate is not ready (pending, empty, forbidden): the filters above\n * lack the candidate filters, so the hand-back must not read.\n */\n readonly held?: boolean;\n readonly searchDecl: SearchDecl | undefined;\n readonly searchContext: { readonly resource: string; readonly def: unknown };\n /** Called with the value to select, as a user's pick would. */\n readonly onValue: (value: string | number) => void;\n}\n\n/**\n * The select's one pending create: the latch (a ref, so a double click or a second render cannot\n * start two), the mounted guard (a result arriving after the select unmounted is ignored — the\n * record exists, nothing is selected), and the hand-back re-read through the select's own option\n * query. `reader` is mounted by the select while a created record is being handed back.\n */\nexport function useSelectCreate(input: SelectCreateInput): {\n readonly create: SelectCreate;\n readonly reader: React.ReactNode;\n} {\n const t = useOptionalT();\n const { to: target } = input;\n const [pending, setPending] = React.useState(false);\n const [created, setCreated] = React.useState<{ readonly id: string } | null>(null);\n const latch = React.useRef(false);\n const mounted = React.useRef(true);\n React.useEffect(() => {\n mounted.current = true;\n return () => {\n mounted.current = false;\n };\n }, []);\n const latest = React.useRef(input);\n latest.current = input;\n const access = useListAccess(target);\n // The hand-back's own filter, judged as the picker judges its option query.\n const blocked =\n input.held === true ||\n access.status !== 'ready' ||\n namesHiddenField(\n createdOptionScope({\n fixed: input.fixedFilters,\n searchDecl: input.searchDecl,\n searchContext: input.searchContext,\n }),\n (name) => access.fieldVisible(name),\n );\n const blockedRef = React.useRef(blocked);\n blockedRef.current = blocked;\n\n const release = React.useCallback(() => {\n latch.current = false;\n if (mounted.current) {\n setPending(false);\n setCreated(null);\n }\n }, []);\n\n const start = React.useCallback(\n (open: () => Promise<QuickSettledRow>) => {\n if (latch.current || !mounted.current || blockedRef.current) return;\n latch.current = true;\n setPending(true);\n let opened: Promise<QuickSettledRow>;\n try {\n opened = open();\n } catch (error) {\n // A synchronous throw (a `beforeOpen`, the host) must not leave the select locked.\n release();\n throw error;\n }\n void opened.then(\n (row) => {\n if (!mounted.current) {\n latch.current = false;\n return;\n }\n const id =\n row === null ? null : (selectKey(row[latest.current.idField]) ?? selectKey(row.id));\n if (id === null) release();\n else setCreated({ id });\n },\n () => release(),\n );\n },\n [release],\n );\n\n const settle = React.useCallback(\n (result: CreatedOptionResult) => {\n if (mounted.current) {\n if (result.kind === 'fits') latest.current.onValue(result.value);\n else if (result.kind === 'does-not-fit')\n toast(\n t('relationPicker.createdNotFitting', {\n defaultValue: 'The record was created but does not fit this field',\n }),\n );\n else\n toast.error(\n t('relationPicker.createdNotSelected', {\n defaultValue: 'The record was created but could not be selected',\n }),\n );\n }\n release();\n },\n [release, t],\n );\n\n const create = React.useMemo<SelectCreate>(\n () => ({ pending, blocked, start }),\n [pending, blocked, start],\n );\n const reader =\n created === null || blocked ? null : (\n <CreatedOptionRead\n key={created.id}\n to={target}\n filter={createdOptionFilter({\n fixed: input.fixedFilters,\n idField: input.idField,\n id: created.id,\n searchDecl: input.searchDecl,\n searchContext: input.searchContext,\n })}\n scope={input.scope}\n {...(input.scopeField === undefined ? {} : { scopeField: input.scopeField })}\n by={input.by}\n idField={input.idField}\n onSettled={settle}\n />\n );\n return { create, reader };\n}\n\n/** A string field a typed search text may fill: declared plain, not system, not an enum. */\nfunction plainStringField(def: unknown): boolean {\n if (def === null || typeof def !== 'object') return false;\n const field = def as {\n readonly kind?: unknown;\n readonly system?: unknown;\n readonly opts?: {\n readonly system?: unknown;\n readonly enum?: unknown;\n readonly localized?: unknown;\n };\n };\n return (\n field.kind === 'string' &&\n field.system !== true &&\n field.opts?.system !== true &&\n field.opts?.enum === undefined &&\n field.opts?.localized !== true\n );\n}\n\nexport interface RelationCreateButtonProps {\n readonly to: string;\n readonly fieldName: string;\n readonly create: SelectCreate;\n /** The trusted `defaults` tier: the registry field's static `eq` literals (P6-31). */\n readonly seeds: Readonly<Record<string, unknown>> | undefined;\n /** The text typed into the select's search, if any: prefills the display field as user input. */\n readonly search?: string;\n /** Runs before the overlay opens: closes the popover, returns focus to the trigger. */\n readonly beforeOpen: () => void;\n readonly className?: string;\n readonly testId?: string;\n}\n\n/**\n * \"+ create\" (P6-29): the target's `quick.create` as a new overlay above the form. Drawn only when\n * the entry gate is open (P3 4.4: `operations.create`, `views.quick.create`, the host wired, the\n * `create` availability); undecided or denied draws nothing and reads nothing. Disabled while one\n * create of the select is pending.\n */\nexport function RelationCreateButton(props: RelationCreateButtonProps): React.ReactElement | null {\n const gate = useEntryGate();\n const { to } = props;\n if (props.create.blocked || gate(to, 'create').state !== 'open') return null;\n return <CreateButton {...props} />;\n}\n\nfunction CreateButton({\n to,\n fieldName,\n create,\n seeds,\n search,\n beforeOpen,\n className,\n testId,\n}: RelationCreateButtonProps): React.ReactElement {\n const app = useApp();\n const t = useOptionalT();\n const tid = useTestIds();\n const quick = useQuick();\n const label = t('relationPicker.create', { defaultValue: '+ Create' });\n return (\n <button\n type=\"button\"\n data-testid={testId ?? tid.relationCreate(to, fieldName)}\n disabled={create.pending}\n className={className}\n onClick={() => {\n const text = search?.trim() ?? '';\n const displayField = (\n app.registry.get(to) as { readonly displayField?: unknown } | undefined\n )?.displayField;\n const fields = (\n app.registry.get(to) as { readonly fields?: Record<string, unknown> } | undefined\n )?.fields;\n const prefill =\n text.length > 0 &&\n typeof displayField === 'string' &&\n fields !== undefined &&\n Object.hasOwn(fields, displayField) &&\n plainStringField(fields[displayField])\n ? { [displayField]: text }\n : undefined;\n create.start(() => {\n beforeOpen();\n return quick.create(to, {\n ...(seeds === undefined || Object.keys(seeds).length === 0 ? {} : { defaults: seeds }),\n ...(prefill === undefined ? {} : { input: prefill }),\n });\n });\n }}\n >\n {label}\n </button>\n );\n}\n"],"mappings":"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"}
|