@elytracms/studio 0.0.41 → 0.0.43
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/components/assets/asset-detail.js +1 -1
- package/dist/components/assets/asset-detail.js.map +1 -1
- package/dist/components/assets/assets-module.js +19 -6
- package/dist/components/assets/assets-module.js.map +1 -1
- package/dist/components/assets/assets-store.d.ts +2 -1
- package/dist/components/assets/assets-store.js +4 -8
- package/dist/components/assets/assets-store.js.map +1 -1
- package/dist/components/assets/assets-view-preference.d.ts +0 -8
- package/dist/components/assets/assets-view-preference.js +12 -13
- package/dist/components/assets/assets-view-preference.js.map +1 -1
- package/dist/components/auth-context.d.ts +2 -1
- package/dist/components/auth-context.js +6 -8
- package/dist/components/auth-context.js.map +1 -1
- package/dist/components/builder/builder-store.d.ts +2 -2
- package/dist/components/builder/builder-store.js +4 -8
- package/dist/components/builder/builder-store.js.map +1 -1
- package/dist/components/builder/canvas.js +16 -2
- package/dist/components/builder/canvas.js.map +1 -1
- package/dist/components/cms/bulk-actions.js +2 -1
- package/dist/components/cms/bulk-actions.js.map +1 -1
- package/dist/components/cms/cell-edit.js +2 -1
- package/dist/components/cms/cell-edit.js.map +1 -1
- package/dist/components/cms/cms-composition-validators.d.ts +25 -0
- package/dist/components/cms/cms-composition-validators.js +75 -0
- package/dist/components/cms/cms-composition-validators.js.map +1 -0
- package/dist/components/cms/cms-labels.d.ts +15 -0
- package/dist/components/cms/cms-labels.js +27 -0
- package/dist/components/cms/cms-labels.js.map +1 -0
- package/dist/components/cms/cms-store.d.ts +23 -10
- package/dist/components/cms/cms-store.js +78 -154
- package/dist/components/cms/cms-store.js.map +1 -1
- package/dist/components/cms/collection-table.js +1 -1
- package/dist/components/cms/collection-table.js.map +1 -1
- package/dist/components/cms/detail-editor.js +67 -67
- package/dist/components/cms/detail-editor.js.map +1 -1
- package/dist/components/cms/details-pane.d.ts +11 -21
- package/dist/components/cms/details-pane.js +14 -31
- package/dist/components/cms/details-pane.js.map +1 -1
- package/dist/components/cms/discard-draft.d.ts +18 -0
- package/dist/components/cms/discard-draft.js +18 -0
- package/dist/components/cms/discard-draft.js.map +1 -1
- package/dist/components/cms/document-editor-context.d.ts +2 -1
- package/dist/components/cms/document-editor-context.js +4 -9
- package/dist/components/cms/document-editor-context.js.map +1 -1
- package/dist/components/cms/document-ref-utils.d.ts +33 -0
- package/dist/components/cms/document-ref-utils.js +47 -0
- package/dist/components/cms/document-ref-utils.js.map +1 -0
- package/dist/components/cms/document-url-path.d.ts +39 -0
- package/dist/components/cms/document-url-path.js +60 -0
- package/dist/components/cms/document-url-path.js.map +1 -0
- package/dist/components/cms/field-control.js +19 -13
- package/dist/components/cms/field-control.js.map +1 -1
- package/dist/components/cms/issues-pane.js +1 -1
- package/dist/components/cms/issues-pane.js.map +1 -1
- package/dist/components/cms/rich-text/block-commands.d.ts +36 -0
- package/dist/components/cms/rich-text/block-commands.js +47 -0
- package/dist/components/cms/rich-text/block-commands.js.map +1 -0
- package/dist/components/cms/rich-text/slash-command.js +25 -8
- package/dist/components/cms/rich-text/slash-command.js.map +1 -1
- package/dist/components/cms/rich-text/toolbar.js +3 -2
- package/dist/components/cms/rich-text/toolbar.js.map +1 -1
- package/dist/components/cms/version-compare.js +1 -1
- package/dist/components/cms/version-compare.js.map +1 -1
- package/dist/components/cms/versions-model.d.ts +31 -0
- package/dist/components/cms/versions-model.js +30 -0
- package/dist/components/cms/versions-model.js.map +1 -1
- package/dist/components/cms/view-bar.js +9 -6
- package/dist/components/cms/view-bar.js.map +1 -1
- package/dist/components/collab/collab-context.d.ts +2 -1
- package/dist/components/collab/collab-context.js +4 -8
- package/dist/components/collab/collab-context.js.map +1 -1
- package/dist/components/collection-view/collection-view-context.d.ts +9 -1
- package/dist/components/collection-view/collection-view-context.js +4 -9
- package/dist/components/collection-view/collection-view-context.js.map +1 -1
- package/dist/components/components/component-detail.js +2 -5
- package/dist/components/components/component-detail.js.map +1 -1
- package/dist/components/components/component-preview.js +8 -4
- package/dist/components/components/component-preview.js.map +1 -1
- package/dist/components/components/registry-browser.js +24 -5
- package/dist/components/components/registry-browser.js.map +1 -1
- package/dist/components/components/transfer-dialog.d.ts +10 -0
- package/dist/components/components/transfer-dialog.js +24 -8
- package/dist/components/components/transfer-dialog.js.map +1 -1
- package/dist/components/delivery-health-banner.d.ts +12 -6
- package/dist/components/delivery-health-banner.js +27 -29
- package/dist/components/delivery-health-banner.js.map +1 -1
- package/dist/components/dev-login-badge.d.ts +0 -2
- package/dist/components/dev-login-badge.js +1 -3
- package/dist/components/dev-login-badge.js.map +1 -1
- package/dist/components/inspector/inspector-sidebar.js +20 -3
- package/dist/components/inspector/inspector-sidebar.js.map +1 -1
- package/dist/components/playground-badge.d.ts +0 -2
- package/dist/components/playground-badge.js +0 -2
- package/dist/components/playground-badge.js.map +1 -1
- package/dist/components/project-list.js +2 -6
- package/dist/components/project-list.js.map +1 -1
- package/dist/components/project-session.d.ts +6 -2
- package/dist/components/project-session.js +32 -83
- package/dist/components/project-session.js.map +1 -1
- package/dist/components/project-switcher.js +2 -6
- package/dist/components/project-switcher.js.map +1 -1
- package/dist/components/redirects/redirects-store.d.ts +2 -1
- package/dist/components/redirects/redirects-store.js +4 -8
- package/dist/components/redirects/redirects-store.js.map +1 -1
- package/dist/components/studio-context.d.ts +2 -1
- package/dist/components/studio-context.js +4 -8
- package/dist/components/studio-context.js.map +1 -1
- package/dist/components/studio-shell.js +1 -1
- package/dist/components/studio-shell.js.map +1 -1
- package/dist/components/theme-context.d.ts +2 -1
- package/dist/components/theme-context.js +4 -8
- package/dist/components/theme-context.js.map +1 -1
- package/dist/components/use-hydration-phase.d.ts +65 -0
- package/dist/components/use-hydration-phase.js +64 -0
- package/dist/components/use-hydration-phase.js.map +1 -0
- package/dist/components/users/users-store.d.ts +2 -1
- package/dist/components/users/users-store.js +4 -8
- package/dist/components/users/users-store.js.map +1 -1
- package/dist/components/workspace-projects.d.ts +14 -0
- package/dist/components/workspace-projects.js +21 -0
- package/dist/components/workspace-projects.js.map +1 -1
- package/dist/lib/data/data-store.d.ts +2 -1
- package/dist/lib/data/data-store.js +4 -8
- package/dist/lib/data/data-store.js.map +1 -1
- package/dist/lib/delivery/instant-publish.d.ts +9 -13
- package/dist/lib/delivery/instant-publish.js +0 -7
- package/dist/lib/delivery/instant-publish.js.map +1 -1
- package/dist/lib/diff-view-preference.js +4 -4
- package/dist/lib/diff-view-preference.js.map +1 -1
- package/dist/lib/i18n/messages.en.js +7 -5
- package/dist/lib/i18n/messages.en.js.map +1 -1
- package/dist/lib/local-preference.d.ts +37 -0
- package/dist/lib/local-preference.js +36 -0
- package/dist/lib/local-preference.js.map +1 -1
- package/dist/lib/persistence/convex-adapter.d.ts +3 -1
- package/dist/lib/persistence/convex-adapter.js +20 -0
- package/dist/lib/persistence/convex-adapter.js.map +1 -1
- package/dist/lib/rail.js +7 -6
- package/dist/lib/rail.js.map +1 -1
- package/dist/lib/required-context.d.ts +24 -0
- package/dist/lib/required-context.js +28 -0
- package/dist/lib/required-context.js.map +1 -0
- package/dist/lib/theme.js +11 -4
- package/dist/lib/theme.js.map +1 -1
- package/dist/ui/index.d.ts +1 -0
- package/dist/ui/index.js +1 -0
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/segmented-control.d.ts +46 -0
- package/dist/ui/segmented-control.js +13 -0
- package/dist/ui/segmented-control.js.map +1 -0
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection-table.js","sourceRoot":"","sources":["../../../src/components/cms/collection-table.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Link, STUDIO_PROJECT_ROUTE, studioPath, useNavigate } from '@elytracms/studio/router'\nimport {\n ArrowDown,\n ArrowUp,\n CornerDownRight,\n Download,\n Eye,\n EyeOff,\n ExternalLink,\n MoreHorizontal,\n Pencil,\n Plus,\n Trash2,\n Upload,\n} from 'lucide-react'\nimport { useMemo, useState } from 'react'\nimport type { ReactNode } from 'react'\nimport type { CmsDocument, CollectionDef, DocumentUrl, FieldDef, Locale, LocaleConfig } from '@elytracms/core/cms-core'\nimport {\n orderHierarchically,\n resolveDocumentForLocale,\n resolveDocumentTitle,\n validateCollectionShape,\n} from '@elytracms/core/cms-core'\nimport {\n Button,\n Code,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n Row,\n Separator,\n Spacer,\n Stack,\n Text,\n} from '@elytracms/studio/ui'\nimport { cn } from '@elytracms/studio/lib/utils'\nimport { localizedLabel, translate } from '@elytracms/studio/lib/i18n'\nimport { LocaleSwitcher, resolveDisplayedValue } from '@elytracms/studio/lib/locale'\nimport {\n EMPTY_SELECTION,\n STATE_FIELD,\n applyViewState,\n clearSelection,\n primaryColumn,\n selectAll,\n toggleRow,\n visibleColumns,\n visibleSelection,\n} from '@elytracms/studio/lib/cms-views'\nimport type { SelectionState, ViewSort } from '@elytracms/studio/lib/cms-views'\nimport { cellEditKind, cellKey } from './cell-edit'\nimport { FallbackChip } from './cell'\nimport { EditableCell } from './editable-cell'\nimport { useCellEdit } from './use-cell-edit'\nimport { ImportDialog } from './import-export'\nimport { AssetThumb, useAssetRecord } from '../assets/asset-thumb'\nimport { fieldLabel } from './cms-store'\nimport { cmsIssueLabel } from '@elytracms/studio/lib/persona/labels'\nimport { TriangleAlert } from 'lucide-react'\nimport type { BulkAction, BulkReport, BulkSetField } from './bulk-actions'\nimport { BulkBar, BulkReportPanel } from './bulk-bar'\nimport { rowActionsFor } from './row-actions'\nimport type { RowAction } from './row-actions'\nimport {\n CHECKBOX_COLUMN_WIDTH_REM,\n PRIMARY_COLUMN_WIDTH_REM,\n ROW_ACTIONS_COLUMN_WIDTH_REM,\n STATE_COLUMN_WIDTH_REM,\n URL_COLUMN_WIDTH_REM,\n columnWidthRem,\n} from './column-width'\nimport { ReferenceConfirmDialog } from './reference-confirm'\nimport { FilterControl } from './filter-builder'\nimport { DisplayMenu, ViewTabs } from './view-bar'\nimport { DocStateBadge } from './doc-state'\nimport { useSetBreadcrumb } from '../breadcrumb-context'\nimport { useCmsCollectionViewSource } from '../collection-view/cms-collection-view-source'\nimport { CollectionViewProvider, useCollectionView } from '../collection-view/collection-view-context'\n\nexport function CollectionTable({ projectId, collectionId }: { projectId: string; collectionId: string }) {\n // AD-19: render over the portable CollectionViewSource, not `useCms()` directly,\n // so the SAME list surface serves the users rail (EC-240), redirects (EC-303), …\n const source = useCmsCollectionViewSource(collectionId)\n\n if (!source) {\n return (\n <div className=\"grid h-full place-items-center p-8\">\n <Text tone=\"muted\">\n Unknown collection <Code tone=\"muted\">{collectionId}</Code>.\n </Text>\n </div>\n )\n }\n\n // Keyed per collection so selection/report state never leaks across collections.\n return (\n <CollectionViewProvider source={source}>\n <LoadedCollectionTable key={collectionId} projectId={projectId} />\n </CollectionViewProvider>\n )\n}\n\n/**\n * The portable list surface (AD-19). Renders entirely over the ambient\n * {@link useCollectionView} source — no `useCms`, no `CmsProvider` required — so\n * any rail (the users rail, redirects, …) reuses it by wrapping it in a\n * {@link CollectionViewProvider} over its own source. `CollectionTable` is just\n * the CMS entry point that builds a CMS source and mounts this.\n */\nexport function LoadedCollectionTable({\n projectId,\n toolbarExtra,\n}: {\n projectId: string\n /**\n * A rail-owned action rendered at the tail of the header toolbar (EC-319) —\n * e.g. the assets rail's Upload button + grid/list toggle. Absent for every\n * other rail today (users, redirects, CMS), so their toolbar is unchanged.\n */\n toolbarExtra?: ReactNode\n}) {\n const source = useCollectionView()\n const collection = source.schema\n const navigate = useNavigate()\n const collectionId = source.collectionId\n // EC-214: the collection is the active record — the global header breadcrumb\n // names it, replacing the per-view title heading.\n useSetBreadcrumb([{ label: localizedLabel(collection.form?.label, collectionId) }])\n const [importOpen, setImportOpen] = useState(false)\n const [selection, setSelection] = useState<SelectionState>(EMPTY_SELECTION)\n const [bulkBusy, setBulkBusy] = useState(false)\n const [bulkReport, setBulkReport] = useState<BulkReport | null>(null)\n // EC-173: bulk unpublish/delete go through the reference-aware confirmation\n // with a snapshot of the selection taken when the action was raised.\n const [pendingBulk, setPendingBulk] = useState<{\n action: 'unpublish' | 'delete'\n targets: { collection: string; id: string }[]\n } | null>(null)\n\n // The working view state (EC-169): filters + sort + columns, possibly dirty\n // against the active saved view. The table renders exactly this state.\n const viewState = source.viewState()\n // EC-213: the title/link column is the first visible column; the rest follow\n // in the view's column order. No separate primary-column selector.\n const primary = primaryColumn(collection, viewState)\n const columns = visibleColumns(collection, viewState).filter((name) => name !== primary)\n const primaryFieldDef = collection.fields.find((f) => f.name === primary)\n\n const docs = source.documents()\n\n // EC-274/EC-284: collection-shape drift (a singleton with > 1 document; later\n // duplicate/unknown/unfilled aliases). When the data has drifted from the lens's\n // expected shape the studio shows this list instead of skipping — surfacing the\n // conflicts here as a \"for review\" banner so an editor resolves them without a\n // developer (keep/delete the outliers), after which the lens applies again.\n const shapeIssues = useMemo(() => validateCollectionShape(collection, docs), [collection, docs])\n\n // EC-216 + EC-205 (\"live = published\"): each routable document's LIVE URL,\n // derived from the PUBLISHED pool (never draft rows), memoised inside the\n // source. `null` when the collection is not routable → the column is hidden.\n const urlByDocId = source.publishing?.liveUrls?.() ?? null\n\n const visibleDocs = useMemo(\n // EC-224: the `$state` filter/sort sources published-ness from the version\n // POINTER (`source.publishing.isPublished`), not a flat `state` field.\n () =>\n applyViewState(collection, docs, source.localeConfig, viewState, (doc) =>\n source.publishing?.isPublished({ collection: doc.collection, id: doc.id }) ?? false,\n ).docs,\n [collection, docs, source.localeConfig, viewState, source.publishing],\n )\n\n // EC-218: a collection with a `parent` self-relation can render as a nested\n // tree (parents above their children, indented). Tree mode reorders the\n // already-filtered rows depth-first — filters/sort still order siblings.\n const hierarchical = source.capabilities.hierarchy\n const [treeMode, setTreeMode] = useState(hierarchical)\n const treeRows = useMemo(\n () => (hierarchical && treeMode ? orderHierarchically(visibleDocs) : null),\n [hierarchical, treeMode, visibleDocs],\n )\n const orderedDocs = treeRows ? treeRows.map((row) => row.doc) : visibleDocs\n const depthById = useMemo(\n () => (treeRows ? new Map(treeRows.map((row) => [row.doc.id, row.depth])) : undefined),\n [treeRows],\n )\n\n // EC-246a header derivations. The count reads with the collection's own noun\n // (pluralized via the config labels), not a bare number or the generic kind.\n const pluralLabel = localizedLabel(collection.form?.label, `${collectionId}s`)\n const singularLabel = localizedLabel(collection.form?.labelSingular, collectionId)\n const countLabel =\n visibleDocs.length === docs.length\n ? translate('cms.list.count', {\n count: docs.length,\n noun: docs.length === 1 ? singularLabel : pluralLabel,\n })\n : translate('cms.list.countFiltered', {\n visible: visibleDocs.length,\n total: docs.length,\n noun: pluralLabel,\n })\n\n // EC-246d: New creates an empty draft and opens its editor directly — no\n // interstitial modal, for pages or any other collection. Id is auto-generated;\n // the slug/title (and, for pages, the parent) are typed in the form, and a\n // missing/duplicate slug surfaces as a Publish-gating issue, never blocks the\n // draft. Routes are config-sourced (EC-207), so nothing else is written here.\n const isPageCollection = collectionId === 'page'\n // Creation is a capability (a credential rail like users mints identities via\n // sign-up, not here), and the detail route is rail-owned (never the CMS route).\n const canCreate = source.capabilities.create && source.detailPath !== undefined\n const handleNew = () => {\n const ref = source.create()\n const splat = source.detailPath?.(ref.id)\n if (splat === undefined) return\n navigate({ to: STUDIO_PROJECT_ROUTE, params: { projectId, _splat: splat } })\n }\n const visibleIds = orderedDocs.map((doc) => doc.id)\n // Selection is always read against the current view — rows the filters hid\n // are never silently included in a bulk action.\n const selectedIds = visibleSelection(selection, visibleIds)\n // EC-316: the right-edge row menu is a capability-gated column — a rail with\n // no detail surface AND no publish/remove capability offers nothing (users\n // rail today has remove, so this is rarely empty; kept honest for AD-19).\n const hasRowActions = source.detailPath !== undefined || source.capabilities.publish || source.capabilities.remove\n\n function toggleSort(field: string) {\n source.setViewState((prev) => {\n const sort: ViewSort | null =\n prev.sort?.field !== field\n ? { field, dir: 'asc' }\n : prev.sort.dir === 'asc'\n ? { field, dir: 'desc' }\n : null\n return { ...prev, sort }\n })\n }\n\n function raiseBulk(action: BulkAction) {\n if (action === 'publish') {\n void handleBulk(action, [...selectedIds])\n return\n }\n // Set-field is composed + raised through the bulk bar's own panel\n // (onSetField), never this state-action path.\n if (action === 'set-field') return\n // Unpublish/delete first enumerate inbound references (EC-173): the\n // dialog shows the aggregate \"N documents, M references will break\".\n setPendingBulk({\n action,\n targets: selectedIds.map((id) => ({ collection: collectionId, id })),\n })\n }\n\n // EC-316: the row `⋮` menu dispatches through the SAME machinery as the\n // toolbar's bulk actions — one document is just a selection of one — so\n // there is exactly one write path for publish/unpublish/delete, never a\n // parallel one. `open` is the row menu's own affordance (the primary-column\n // link already offers it; this is the keyboard/menu-driven equivalent).\n function handleRowAction(action: RowAction, doc: CmsDocument) {\n if (action === 'open') {\n const splat = source.detailPath?.(doc.id)\n if (splat === undefined) return\n navigate({ to: STUDIO_PROJECT_ROUTE, params: { projectId, _splat: splat } })\n return\n }\n if (action === 'publish') {\n void handleBulk(action, [doc.id])\n return\n }\n // unpublish/delete: the same reference-aware confirmation the bulk bar\n // raises, scoped to this one document.\n setPendingBulk({ action, targets: [{ collection: collectionId, id: doc.id }] })\n }\n\n async function handleBulk(action: BulkAction, acted: readonly string[], setField?: BulkSetField) {\n if (!source.bulk) return\n setBulkBusy(true)\n try {\n const report = await source.bulk([...acted], action, setField)\n setBulkReport(report)\n // Succeeded items deselect; failed items stay selected for a retry.\n const actedSet = new Set(acted)\n const failed = new Set(report.results.filter((r) => !r.ok).map((r) => r.ref.id))\n setSelection((prev) => ({\n ids: prev.ids.filter((id) => !actedSet.has(id) || failed.has(id)),\n anchorId: null,\n }))\n } finally {\n setBulkBusy(false)\n }\n }\n\n function exportJson() {\n const data = JSON.stringify(source.documents(), null, 2)\n const blob = new Blob([data], { type: 'application/json' })\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = `${collectionId}.json`\n a.click()\n URL.revokeObjectURL(url)\n }\n\n return (\n <div className=\"flex h-full min-h-0 flex-col\">\n {/* Header (EC-246a redesign). One toolbar: identity + refine on the left,\n lens + actions on the right; a transient filter bar drops below only\n while refining. The header breadcrumb (EC-214) names the collection —\n no title here. Locale is a lens; column/layout config lives behind the\n far-right Display control; shared views are config-as-code (EC-246b). */}\n <div className=\"shrink-0 border-b border-border px-4 py-3 sm:px-6\">\n <Row gap=\"2\" wrap>\n {/* Left — which view (only when >1), then the transient refine. */}\n <ViewTabs />\n {/* Transient ad-hoc refine — a chip beside the view tabs, editor in a\n popover (EC-246b); the chip's ✕ clears it, so no separate Reset. */}\n <FilterControl collection={collection} />\n {/* The working-set count is the RESULT of the view + filter above, so it\n reads last, set off by a divider and sized like its neighbours. */}\n <Separator orientation=\"vertical\" className=\"h-5 self-center\" />\n <Text\n as=\"span\"\n size=\"xs\"\n tone=\"muted\"\n className=\"whitespace-nowrap tabular-nums\"\n data-testid=\"collection-count\"\n >\n {countLabel}\n </Text>\n\n <Spacer />\n\n {/* Right — the ambient locale lens (EC-176; hidden for single-locale AND\n for a non-localized rail like users), then display config + write actions. */}\n {source.capabilities.locales ? <LocaleSwitcher /> : null}\n <DisplayMenu\n collection={collection}\n hierarchical={hierarchical}\n treeMode={treeMode}\n onToggleTree={setTreeMode}\n />\n {canCreate ? (\n <Button size=\"sm\" onClick={handleNew} data-testid=\"new-document\">\n <Plus /> {isPageCollection ? translate('cms.list.newPage') : translate('cms.list.new')}\n </Button>\n ) : null}\n {/* EC-213: import/export fold into one action menu, off the header.\n AD-19: a capability — absent on credential rails (users), so identity\n records are never dumped to / loaded from raw JSON. */}\n {source.capabilities.importExport ? (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"outline\"\n size=\"icon-sm\"\n aria-label={translate('cms.list.moreActions')}\n data-testid=\"collection-actions\"\n >\n <MoreHorizontal />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onClick={() => setImportOpen(true)} data-testid=\"action-import\">\n <Upload /> {translate('cms.list.import')}\n </DropdownMenuItem>\n <DropdownMenuItem\n onClick={exportJson}\n disabled={docs.length === 0}\n data-testid=\"action-export\"\n >\n <Download /> {translate('cms.list.export')}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n ) : null}\n {toolbarExtra}\n </Row>\n </div>\n\n {/* Bulk actions over the selection (EC-169) */}\n <BulkBar\n collection={collection}\n count={selectedIds.length}\n busy={bulkBusy}\n onAction={raiseBulk}\n onSetField={(setField) => void handleBulk('set-field', [...selectedIds], setField)}\n onClear={() => setSelection(clearSelection())}\n />\n {bulkReport ? (\n <BulkReportPanel report={bulkReport} onDismiss={() => setBulkReport(null)} />\n ) : null}\n\n {/* Reference-aware bulk unpublish/delete confirmation (EC-173). */}\n {pendingBulk !== null ? (\n <ReferenceConfirmDialog\n projectId={projectId}\n action={pendingBulk.action}\n targets={pendingBulk.targets}\n open\n busy={bulkBusy}\n onOpenChange={(open) => {\n if (!open) setPendingBulk(null)\n }}\n onConfirm={() => {\n const { action, targets } = pendingBulk\n setPendingBulk(null)\n void handleBulk(\n action,\n targets.map((target) => target.id),\n )\n }}\n />\n ) : null}\n\n {/* EC-274/EC-284: \"for review\" lane — the collection has drifted from its\n lens's expected shape; surface each conflict so an editor can resolve it. */}\n {shapeIssues.length > 0 ? (\n <div\n className=\"shrink-0 border-b border-warning/30 bg-warning/10 px-4 py-2 sm:px-6\"\n data-testid=\"shape-review-banner\"\n >\n <Stack gap=\"1\">\n {shapeIssues.map((issue, i) => (\n <Row key={`${issue.code}:${i}`} gap=\"2\" align=\"start\">\n <TriangleAlert className=\"mt-0.5 size-3.5 shrink-0 text-warning\" aria-hidden />\n <Stack gap=\"none\" className=\"min-w-0\">\n <Text size=\"xs\" weight=\"semibold\" tone=\"default\" title={issue.code}>\n {translate('cms.list.forReview')} · {cmsIssueLabel(issue.code)}\n </Text>\n <Text size=\"xs\" tone=\"muted\">\n {issue.message}\n </Text>\n </Stack>\n </Row>\n ))}\n </Stack>\n </div>\n ) : null}\n\n {/* Table */}\n <div className=\"min-h-0 flex-1 overflow-auto\">\n {docs.length === 0 ? (\n <div className=\"grid h-full place-items-center p-8\">\n <Stack gap=\"2\" align=\"center\" className=\"text-center\">\n <Text tone=\"muted\">{translate('cms.list.emptyNone', { noun: pluralLabel.toLowerCase() })}</Text>\n {canCreate ? (\n <Button size=\"sm\" onClick={handleNew}>\n <Plus />{' '}\n {isPageCollection\n ? translate('cms.list.newPage')\n : translate('cms.list.newNamed', {\n noun: localizedLabel(collection.form?.labelSingular, 'document'),\n })}\n </Button>\n ) : null}\n </Stack>\n </div>\n ) : visibleDocs.length === 0 ? (\n <div className=\"grid h-full place-items-center p-8\">\n <Text tone=\"muted\" data-testid=\"empty-filtered\">\n {translate('cms.list.emptyFiltered')}\n </Text>\n </div>\n ) : (\n <DocumentsGrid\n projectId={projectId}\n collection={collection}\n primary={primary}\n primaryFieldDef={primaryFieldDef}\n columns={columns}\n sortedDocs={orderedDocs}\n depthById={depthById}\n urlByDocId={urlByDocId}\n sort={viewState.sort}\n onSort={toggleSort}\n selectedIds={selectedIds}\n onToggleRow={(id, shift) =>\n setSelection((prev) => toggleRow(prev, visibleIds, id, shift))\n }\n onToggleAll={() =>\n setSelection(\n selectedIds.length === visibleIds.length && visibleIds.length > 0\n ? clearSelection()\n : selectAll(visibleIds),\n )\n }\n hasRowActions={hasRowActions}\n onRowAction={handleRowAction}\n />\n )}\n </div>\n\n {source.capabilities.importExport ? (\n <ImportDialog collectionId={collectionId} open={importOpen} onOpenChange={setImportOpen} />\n ) : null}\n </div>\n )\n}\n\n/**\n * The documents table with inline cell editing (EC-168). Cells edit in place\n * (text/number/boolean/select/date) or open pickers (relation/asset); each\n * commit is one operations command via the cell-edit controller, with\n * rollback + inline cell errors on rejection. Row checkboxes (EC-169) live in\n * their own column, so selection clicks never collide with cell editing.\n */\nfunction DocumentsGrid({\n projectId,\n collection,\n primary,\n primaryFieldDef,\n columns,\n sortedDocs,\n depthById,\n urlByDocId,\n sort,\n onSort,\n selectedIds,\n onToggleRow,\n onToggleAll,\n hasRowActions,\n onRowAction,\n}: {\n projectId: string\n collection: CollectionDef\n primary: string\n primaryFieldDef: FieldDef | undefined\n columns: string[]\n sortedDocs: CmsDocument[]\n /** EC-218: nesting depth per doc id when rendering the hierarchy (tree mode). */\n depthById?: Map<string, number>\n /** EC-216: each routable doc's derived URL; `null` hides the URL column. */\n urlByDocId?: Map<string, DocumentUrl> | null\n sort: ViewSort | null\n onSort: (field: string) => void\n selectedIds: readonly string[]\n onToggleRow: (id: string, shift: boolean) => void\n onToggleAll: () => void\n /** EC-316: whether the right-edge row `⋮` menu has anything to offer at all. */\n hasRowActions: boolean\n onRowAction: (action: RowAction, doc: CmsDocument) => void\n}) {\n const source = useCollectionView()\n const collectionId = collection.id\n const fieldByName = (name: string) => collection.fields.find((f) => f.name === name)\n // Inline editing is a capability: a read-only rail yields no editable cells.\n const editableFields = source.capabilities.inlineEdit\n ? columns.filter((name) => {\n const field = fieldByName(name)\n return field ? cellEditKind(field, source.isFieldReadOnly(field)) !== 'none' : false\n })\n : []\n const cellEdit = useCellEdit({ collection, docs: sortedDocs, editableFields })\n const selected = new Set(selectedIds)\n const allSelected = sortedDocs.length > 0 && selectedIds.length === sortedDocs.length\n\n return (\n <div ref={cellEdit.containerRef}>\n {/* EC-316: `table-fixed` + an explicit `<colgroup>` fix every column's\n width from the SCHEMA alone, before any row renders. Under the\n browser's default `table-layout: auto` a cell's INTRINSIC content\n width feeds back into its column — so swapping a cell's rendered\n value for its inline editor (a wider `<input>`) reflowed the whole\n grid. Fixed layout makes a column's width immune to its cells'\n content; `columnWidthRem` only sets relative proportions, so the\n grid still scales naturally with the container (never with a cell). */}\n <table className=\"w-full table-fixed border-collapse text-sm\">\n <colgroup>\n <col style={{ width: `${CHECKBOX_COLUMN_WIDTH_REM}rem` }} />\n <col style={{ width: `${PRIMARY_COLUMN_WIDTH_REM}rem` }} />\n {columns.map((name) => (\n <col key={name} style={{ width: `${columnWidthRem(fieldByName(name))}rem` }} />\n ))}\n <col style={{ width: `${STATE_COLUMN_WIDTH_REM}rem` }} />\n {urlByDocId ? <col style={{ width: `${URL_COLUMN_WIDTH_REM}rem` }} /> : null}\n {hasRowActions ? <col style={{ width: `${ROW_ACTIONS_COLUMN_WIDTH_REM}rem` }} /> : null}\n </colgroup>\n <thead className=\"sticky top-0 z-10 bg-background\">\n <tr className=\"border-b border-border\">\n <th className=\"px-3 py-2 text-left\">\n <SelectionCheckbox\n checked={allSelected}\n indeterminate={selectedIds.length > 0 && !allSelected}\n label={translate('cms.list.selectAll')}\n testId=\"select-all\"\n onToggle={() => onToggleAll()}\n />\n </th>\n <HeaderCell\n field={primary}\n label={primaryFieldDef ? fieldLabel(primaryFieldDef) : translate('cms.list.column.title')}\n sort={sort}\n onSort={onSort}\n />\n {columns.map((name) => {\n const field = fieldByName(name)\n return field ? (\n <HeaderCell key={name} field={name} label={fieldLabel(field)} sort={sort} onSort={onSort} />\n ) : null\n })}\n <HeaderCell field={STATE_FIELD} label={translate('cms.list.column.state')} sort={sort} onSort={onSort} />\n {/* EC-216: derived URL — not a field, so not sortable. */}\n {urlByDocId ? (\n <th className=\"px-3 py-2 text-left text-xs font-semibold text-muted-foreground\">{translate('cms.list.column.url')}</th>\n ) : null}\n {hasRowActions ? (\n <th className=\"px-2 py-2 text-right\">\n <span className=\"sr-only\">{translate('cms.list.rowActionsColumnLabel')}</span>\n </th>\n ) : null}\n </tr>\n </thead>\n <tbody>\n {sortedDocs.map((doc) => (\n <tr\n key={doc.id}\n className={cn(\n 'group border-b border-border/60 hover:bg-muted/40',\n selected.has(doc.id) && 'bg-primary/5',\n )}\n >\n <td className=\"px-3 py-2 align-middle\">\n <SelectionCheckbox\n checked={selected.has(doc.id)}\n label={translate('cms.list.selectRow', { id: doc.id })}\n testId={`select-row-${doc.id}`}\n onToggle={(shift) => onToggleRow(doc.id, shift)}\n />\n </td>\n <td className=\"px-3 py-2 align-middle\">\n <PrimaryCell\n projectId={projectId}\n collection={collection}\n doc={doc}\n primary={primary}\n depth={depthById?.get(doc.id) ?? 0}\n locale={source.activeLocale}\n config={source.localeConfig}\n detailPath={source.detailPath}\n />\n </td>\n {columns.map((name) => {\n const field = fieldByName(name)\n const coord = { docId: doc.id, field: name }\n const key = cellKey(coord)\n return (\n <td key={name} className=\"px-3 py-2 align-middle\">\n {field ? (\n <EditableCell\n collection={collection}\n doc={doc}\n field={field}\n editing={cellEdit.activeKey === key}\n busy={cellEdit.busyKey === key}\n errorMessage={cellEdit.errorOf(key)}\n onStartEdit={() => cellEdit.start(coord)}\n onCancel={() => cellEdit.cancel(coord)}\n onCommit={(value, advance) => cellEdit.commit(coord, value, advance)}\n />\n ) : null}\n </td>\n )\n })}\n <td className=\"px-3 py-2 align-middle\">\n <DocStateBadge\n published={\n source.publishing?.isPublished({ collection: collectionId, id: doc.id }) ?? false\n }\n />\n </td>\n {urlByDocId ? (\n <td className=\"px-3 py-2 align-middle\">\n <UrlCell url={urlByDocId.get(doc.id)} />\n </td>\n ) : null}\n {hasRowActions ? (\n <td className=\"px-2 py-2 text-right align-middle\">\n <RowActionsMenu\n doc={doc}\n published={source.publishing?.isPublished({ collection: collectionId, id: doc.id }) ?? false}\n hasDetailPath={source.detailPath !== undefined}\n onAction={(action) => onRowAction(action, doc)}\n />\n </td>\n ) : null}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )\n}\n\n/**\n * The right-edge row `⋮` menu (EC-316): the SAME action vocabulary as the\n * toolbar's bulk actions (`rowActionsFor`), gated by the SAME capabilities —\n * so it degrades exactly like the rest of the list for a rail without\n * publish/remove (AD-19). Renders nothing when the gate leaves zero actions.\n */\nfunction RowActionsMenu({\n doc,\n published,\n hasDetailPath,\n onAction,\n}: {\n doc: CmsDocument\n published: boolean\n hasDetailPath: boolean\n onAction: (action: RowAction) => void\n}) {\n const source = useCollectionView()\n const actions = rowActionsFor({ capabilities: source.capabilities, hasDetailPath, published })\n if (actions.length === 0) return null\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-label={translate('cms.list.rowActionsLabel', { id: doc.id })}\n data-testid={`row-actions-${doc.id}`}\n >\n <MoreHorizontal />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {actions.map((action) => (\n <RowActionItem key={action} action={action} onSelect={() => onAction(action)} />\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n\nfunction RowActionItem({ action, onSelect }: { action: RowAction; onSelect: () => void }) {\n switch (action) {\n case 'open':\n return (\n <DropdownMenuItem onClick={onSelect} data-testid=\"row-action-open\">\n <Pencil /> {translate('cms.list.rowAction.open')}\n </DropdownMenuItem>\n )\n case 'publish':\n return (\n <DropdownMenuItem onClick={onSelect} data-testid=\"row-action-publish\">\n <Eye /> {translate('cms.list.bulk.publish')}\n </DropdownMenuItem>\n )\n case 'unpublish':\n return (\n <DropdownMenuItem onClick={onSelect} data-testid=\"row-action-unpublish\">\n <EyeOff /> {translate('cms.list.bulk.unpublish')}\n </DropdownMenuItem>\n )\n case 'delete':\n return (\n <DropdownMenuItem\n variant=\"destructive\"\n onClick={onSelect}\n data-testid=\"row-action-delete\"\n >\n <Trash2 /> {translate('common.delete')}\n </DropdownMenuItem>\n )\n }\n}\n\n/**\n * A selection checkbox (row or select-all). Its own column and focus target —\n * it never participates in the cell-edit keyboard flow. Shift-click selects\n * the anchor→row range (the mousedown guard stops text selection).\n */\nfunction SelectionCheckbox({\n checked,\n indeterminate = false,\n label,\n testId,\n onToggle,\n}: {\n checked: boolean\n indeterminate?: boolean\n label: string\n testId: string\n onToggle: (shift: boolean) => void\n}) {\n return (\n <input\n ref={(el) => {\n if (el) el.indeterminate = indeterminate && !checked\n }}\n type=\"checkbox\"\n className=\"size-4 cursor-pointer accent-primary align-middle\"\n checked={checked}\n readOnly\n aria-label={label}\n data-testid={testId}\n onClick={(event) => onToggle(event.shiftKey)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n event.preventDefault()\n onToggle(event.shiftKey)\n }\n }}\n onMouseDown={(event) => {\n if (event.shiftKey) event.preventDefault()\n }}\n />\n )\n}\n\nfunction HeaderCell({\n field,\n label,\n sort,\n onSort,\n}: {\n field: string\n label: string\n sort: ViewSort | null\n onSort: (field: string) => void\n}) {\n const active = sort?.field === field\n return (\n <th className=\"px-3 py-2 text-left text-xs font-semibold text-muted-foreground\">\n <button type=\"button\" onClick={() => onSort(field)} className=\"inline-flex items-center gap-1 hover:text-foreground\">\n {label}\n {active ? (\n sort!.dir === 'asc' ? (\n <ArrowUp className=\"size-3\" />\n ) : (\n <ArrowDown className=\"size-3\" />\n )\n ) : null}\n </button>\n </th>\n )\n}\n\n/**\n * The primary (title) column cell: the document link, resolved in the\n * ambient active locale with a visible fallback chip when the shown title is\n * untranslated (EC-176).\n */\nfunction PrimaryCell({\n projectId,\n collection,\n doc,\n primary,\n depth = 0,\n locale,\n config,\n detailPath,\n}: {\n projectId: string\n collection: CollectionDef\n doc: CmsDocument\n primary: string\n /** EC-218: nesting depth in the hierarchy (tree mode) — indents the title. */\n depth?: number\n locale: Locale\n config: LocaleConfig\n /** Rail-owned detail route splat (AD-19); absent ⇒ the rail has no detail surface. */\n detailPath?: (id: string) => string\n}) {\n // EC-242: the title cell renders the document identity (resolveDocumentTitle) —\n // a string `titleField` or a function pattern — over the fallback-resolved\n // values, NOT the raw `primary` column value. The untranslated-title chip applies\n // only to a field-backed title (a function pattern has no single source field).\n const title = resolveDocumentTitle(\n collection,\n resolveDocumentForLocale(collection, doc, locale, config),\n doc.id,\n )\n const fallback =\n typeof collection.titleField === 'function'\n ? null\n : resolveDisplayedValue(collection, doc, primary, locale, config).fallback\n const splat = detailPath?.(doc.id)\n return (\n <Row gap=\"2\" align=\"center\" className=\"min-w-0\" style={{ paddingLeft: depth * 20 }}>\n {depth > 0 ? (\n <CornerDownRight className=\"size-3.5 shrink-0 text-muted-foreground\" aria-hidden />\n ) : null}\n {/* 0.0.39: assets get a leading, fixed-size preview in the filename column —\n an image thumbnail (object-cover) for image assets, the file-type placeholder\n otherwise. Fixed box, so it never reflows the EC-316 fixed column widths. */}\n {collection.kind === 'asset' ? <AssetThumbCell assetId={doc.id} alt={title} /> : null}\n {splat !== undefined ? (\n <Link\n to={STUDIO_PROJECT_ROUTE}\n params={{ projectId, _splat: splat }}\n className=\"truncate font-medium text-foreground hover:text-primary hover:underline\"\n >\n {title}\n </Link>\n ) : (\n <Text as=\"span\" className=\"truncate font-medium text-foreground\">\n {title}\n </Text>\n )}\n <FallbackChip fallback={fallback} testId={`cell-fallback-${doc.id}-${primary}`} />\n </Row>\n )\n}\n\n/**\n * The leading asset preview in the filename column (0.0.39). Resolves the asset\n * record from the ambient library and renders {@link AssetThumb} — an image preview\n * for image assets, the file-type placeholder for the rest. Mounted only for\n * `kind:'asset'` collections (which are always under an `<AssetsProvider>`), so the\n * `useAssetRecord` hook is never called on a rail without a library.\n */\nfunction AssetThumbCell({ assetId, alt }: { assetId: string; alt: string }) {\n const record = useAssetRecord(assetId)\n return <AssetThumb record={record} alt={alt} className=\"size-8 shrink-0\" />\n}\n\n/**\n * The read-only URL column cell (EC-216): the document's LIVE (published) path,\n * linking to the absolute live URL when a `frontendUrl` is configured. Only\n * published documents have a `url` here (the URL is derived from the published\n * pool, EC-205), so an unpublished document — having no live page — shows a dash.\n * The URL is always derived, never stored.\n */\nfunction UrlCell({ url }: { url?: DocumentUrl }) {\n if (!url) {\n return (\n <Text size=\"xs\" tone=\"subtle\">\n —\n </Text>\n )\n }\n if (url.href) {\n return (\n <a\n href={url.href}\n target=\"_blank\"\n rel=\"noreferrer\"\n title={url.href}\n className=\"inline-flex max-w-[18rem] items-center gap-1 text-xs text-muted-foreground transition-colors hover:text-foreground\"\n >\n <span className=\"truncate\">{url.path}</span>\n <ExternalLink className=\"size-3 shrink-0\" aria-hidden />\n </a>\n )\n }\n return (\n <Text size=\"xs\" tone=\"muted\" className=\"max-w-[18rem] truncate\" title={url.path}>\n {url.path}\n </Text>\n )\n}\n\nexport type { FieldDef }\n"]}
|
|
1
|
+
{"version":3,"file":"collection-table.js","sourceRoot":"","sources":["../../../src/components/cms/collection-table.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Link, STUDIO_PROJECT_ROUTE, studioPath, useNavigate } from '@elytracms/studio/router'\nimport {\n ArrowDown,\n ArrowUp,\n CornerDownRight,\n Download,\n Eye,\n EyeOff,\n ExternalLink,\n MoreHorizontal,\n Pencil,\n Plus,\n Trash2,\n Upload,\n} from 'lucide-react'\nimport { useMemo, useState } from 'react'\nimport type { ReactNode } from 'react'\nimport type { CmsDocument, CollectionDef, DocumentUrl, FieldDef, Locale, LocaleConfig } from '@elytracms/core/cms-core'\nimport {\n orderHierarchically,\n resolveDocumentForLocale,\n resolveDocumentTitle,\n validateCollectionShape,\n} from '@elytracms/core/cms-core'\nimport {\n Button,\n Code,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n Row,\n Separator,\n Spacer,\n Stack,\n Text,\n} from '@elytracms/studio/ui'\nimport { cn } from '@elytracms/studio/lib/utils'\nimport { localizedLabel, translate } from '@elytracms/studio/lib/i18n'\nimport { LocaleSwitcher, resolveDisplayedValue } from '@elytracms/studio/lib/locale'\nimport {\n EMPTY_SELECTION,\n STATE_FIELD,\n applyViewState,\n clearSelection,\n primaryColumn,\n selectAll,\n toggleRow,\n visibleColumns,\n visibleSelection,\n} from '@elytracms/studio/lib/cms-views'\nimport type { SelectionState, ViewSort } from '@elytracms/studio/lib/cms-views'\nimport { cellEditKind, cellKey } from './cell-edit'\nimport { FallbackChip } from './cell'\nimport { EditableCell } from './editable-cell'\nimport { useCellEdit } from './use-cell-edit'\nimport { ImportDialog } from './import-export'\nimport { AssetThumb, useAssetRecord } from '../assets/asset-thumb'\nimport { fieldLabel } from './cms-labels'\nimport { cmsIssueLabel } from '@elytracms/studio/lib/persona/labels'\nimport { TriangleAlert } from 'lucide-react'\nimport type { BulkAction, BulkReport, BulkSetField } from './bulk-actions'\nimport { BulkBar, BulkReportPanel } from './bulk-bar'\nimport { rowActionsFor } from './row-actions'\nimport type { RowAction } from './row-actions'\nimport {\n CHECKBOX_COLUMN_WIDTH_REM,\n PRIMARY_COLUMN_WIDTH_REM,\n ROW_ACTIONS_COLUMN_WIDTH_REM,\n STATE_COLUMN_WIDTH_REM,\n URL_COLUMN_WIDTH_REM,\n columnWidthRem,\n} from './column-width'\nimport { ReferenceConfirmDialog } from './reference-confirm'\nimport { FilterControl } from './filter-builder'\nimport { DisplayMenu, ViewTabs } from './view-bar'\nimport { DocStateBadge } from './doc-state'\nimport { useSetBreadcrumb } from '../breadcrumb-context'\nimport { useCmsCollectionViewSource } from '../collection-view/cms-collection-view-source'\nimport { CollectionViewProvider, useCollectionView } from '../collection-view/collection-view-context'\n\nexport function CollectionTable({ projectId, collectionId }: { projectId: string; collectionId: string }) {\n // AD-19: render over the portable CollectionViewSource, not `useCms()` directly,\n // so the SAME list surface serves the users rail (EC-240), redirects (EC-303), …\n const source = useCmsCollectionViewSource(collectionId)\n\n if (!source) {\n return (\n <div className=\"grid h-full place-items-center p-8\">\n <Text tone=\"muted\">\n Unknown collection <Code tone=\"muted\">{collectionId}</Code>.\n </Text>\n </div>\n )\n }\n\n // Keyed per collection so selection/report state never leaks across collections.\n return (\n <CollectionViewProvider source={source}>\n <LoadedCollectionTable key={collectionId} projectId={projectId} />\n </CollectionViewProvider>\n )\n}\n\n/**\n * The portable list surface (AD-19). Renders entirely over the ambient\n * {@link useCollectionView} source — no `useCms`, no `CmsProvider` required — so\n * any rail (the users rail, redirects, …) reuses it by wrapping it in a\n * {@link CollectionViewProvider} over its own source. `CollectionTable` is just\n * the CMS entry point that builds a CMS source and mounts this.\n */\nexport function LoadedCollectionTable({\n projectId,\n toolbarExtra,\n}: {\n projectId: string\n /**\n * A rail-owned action rendered at the tail of the header toolbar (EC-319) —\n * e.g. the assets rail's Upload button + grid/list toggle. Absent for every\n * other rail today (users, redirects, CMS), so their toolbar is unchanged.\n */\n toolbarExtra?: ReactNode\n}) {\n const source = useCollectionView()\n const collection = source.schema\n const navigate = useNavigate()\n const collectionId = source.collectionId\n // EC-214: the collection is the active record — the global header breadcrumb\n // names it, replacing the per-view title heading.\n useSetBreadcrumb([{ label: localizedLabel(collection.form?.label, collectionId) }])\n const [importOpen, setImportOpen] = useState(false)\n const [selection, setSelection] = useState<SelectionState>(EMPTY_SELECTION)\n const [bulkBusy, setBulkBusy] = useState(false)\n const [bulkReport, setBulkReport] = useState<BulkReport | null>(null)\n // EC-173: bulk unpublish/delete go through the reference-aware confirmation\n // with a snapshot of the selection taken when the action was raised.\n const [pendingBulk, setPendingBulk] = useState<{\n action: 'unpublish' | 'delete'\n targets: { collection: string; id: string }[]\n } | null>(null)\n\n // The working view state (EC-169): filters + sort + columns, possibly dirty\n // against the active saved view. The table renders exactly this state.\n const viewState = source.viewState()\n // EC-213: the title/link column is the first visible column; the rest follow\n // in the view's column order. No separate primary-column selector.\n const primary = primaryColumn(collection, viewState)\n const columns = visibleColumns(collection, viewState).filter((name) => name !== primary)\n const primaryFieldDef = collection.fields.find((f) => f.name === primary)\n\n const docs = source.documents()\n\n // EC-274/EC-284: collection-shape drift (a singleton with > 1 document; later\n // duplicate/unknown/unfilled aliases). When the data has drifted from the lens's\n // expected shape the studio shows this list instead of skipping — surfacing the\n // conflicts here as a \"for review\" banner so an editor resolves them without a\n // developer (keep/delete the outliers), after which the lens applies again.\n const shapeIssues = useMemo(() => validateCollectionShape(collection, docs), [collection, docs])\n\n // EC-216 + EC-205 (\"live = published\"): each routable document's LIVE URL,\n // derived from the PUBLISHED pool (never draft rows), memoised inside the\n // source. `null` when the collection is not routable → the column is hidden.\n const urlByDocId = source.publishing?.liveUrls?.() ?? null\n\n const visibleDocs = useMemo(\n // EC-224: the `$state` filter/sort sources published-ness from the version\n // POINTER (`source.publishing.isPublished`), not a flat `state` field.\n () =>\n applyViewState(collection, docs, source.localeConfig, viewState, (doc) =>\n source.publishing?.isPublished({ collection: doc.collection, id: doc.id }) ?? false,\n ).docs,\n [collection, docs, source.localeConfig, viewState, source.publishing],\n )\n\n // EC-218: a collection with a `parent` self-relation can render as a nested\n // tree (parents above their children, indented). Tree mode reorders the\n // already-filtered rows depth-first — filters/sort still order siblings.\n const hierarchical = source.capabilities.hierarchy\n const [treeMode, setTreeMode] = useState(hierarchical)\n const treeRows = useMemo(\n () => (hierarchical && treeMode ? orderHierarchically(visibleDocs) : null),\n [hierarchical, treeMode, visibleDocs],\n )\n const orderedDocs = treeRows ? treeRows.map((row) => row.doc) : visibleDocs\n const depthById = useMemo(\n () => (treeRows ? new Map(treeRows.map((row) => [row.doc.id, row.depth])) : undefined),\n [treeRows],\n )\n\n // EC-246a header derivations. The count reads with the collection's own noun\n // (pluralized via the config labels), not a bare number or the generic kind.\n const pluralLabel = localizedLabel(collection.form?.label, `${collectionId}s`)\n const singularLabel = localizedLabel(collection.form?.labelSingular, collectionId)\n const countLabel =\n visibleDocs.length === docs.length\n ? translate('cms.list.count', {\n count: docs.length,\n noun: docs.length === 1 ? singularLabel : pluralLabel,\n })\n : translate('cms.list.countFiltered', {\n visible: visibleDocs.length,\n total: docs.length,\n noun: pluralLabel,\n })\n\n // EC-246d: New creates an empty draft and opens its editor directly — no\n // interstitial modal, for pages or any other collection. Id is auto-generated;\n // the slug/title (and, for pages, the parent) are typed in the form, and a\n // missing/duplicate slug surfaces as a Publish-gating issue, never blocks the\n // draft. Routes are config-sourced (EC-207), so nothing else is written here.\n const isPageCollection = collectionId === 'page'\n // Creation is a capability (a credential rail like users mints identities via\n // sign-up, not here), and the detail route is rail-owned (never the CMS route).\n const canCreate = source.capabilities.create && source.detailPath !== undefined\n const handleNew = () => {\n const ref = source.create()\n const splat = source.detailPath?.(ref.id)\n if (splat === undefined) return\n navigate({ to: STUDIO_PROJECT_ROUTE, params: { projectId, _splat: splat } })\n }\n const visibleIds = orderedDocs.map((doc) => doc.id)\n // Selection is always read against the current view — rows the filters hid\n // are never silently included in a bulk action.\n const selectedIds = visibleSelection(selection, visibleIds)\n // EC-316: the right-edge row menu is a capability-gated column — a rail with\n // no detail surface AND no publish/remove capability offers nothing (users\n // rail today has remove, so this is rarely empty; kept honest for AD-19).\n const hasRowActions = source.detailPath !== undefined || source.capabilities.publish || source.capabilities.remove\n\n function toggleSort(field: string) {\n source.setViewState((prev) => {\n const sort: ViewSort | null =\n prev.sort?.field !== field\n ? { field, dir: 'asc' }\n : prev.sort.dir === 'asc'\n ? { field, dir: 'desc' }\n : null\n return { ...prev, sort }\n })\n }\n\n function raiseBulk(action: BulkAction) {\n if (action === 'publish') {\n void handleBulk(action, [...selectedIds])\n return\n }\n // Set-field is composed + raised through the bulk bar's own panel\n // (onSetField), never this state-action path.\n if (action === 'set-field') return\n // Unpublish/delete first enumerate inbound references (EC-173): the\n // dialog shows the aggregate \"N documents, M references will break\".\n setPendingBulk({\n action,\n targets: selectedIds.map((id) => ({ collection: collectionId, id })),\n })\n }\n\n // EC-316: the row `⋮` menu dispatches through the SAME machinery as the\n // toolbar's bulk actions — one document is just a selection of one — so\n // there is exactly one write path for publish/unpublish/delete, never a\n // parallel one. `open` is the row menu's own affordance (the primary-column\n // link already offers it; this is the keyboard/menu-driven equivalent).\n function handleRowAction(action: RowAction, doc: CmsDocument) {\n if (action === 'open') {\n const splat = source.detailPath?.(doc.id)\n if (splat === undefined) return\n navigate({ to: STUDIO_PROJECT_ROUTE, params: { projectId, _splat: splat } })\n return\n }\n if (action === 'publish') {\n void handleBulk(action, [doc.id])\n return\n }\n // unpublish/delete: the same reference-aware confirmation the bulk bar\n // raises, scoped to this one document.\n setPendingBulk({ action, targets: [{ collection: collectionId, id: doc.id }] })\n }\n\n async function handleBulk(action: BulkAction, acted: readonly string[], setField?: BulkSetField) {\n if (!source.bulk) return\n setBulkBusy(true)\n try {\n const report = await source.bulk([...acted], action, setField)\n setBulkReport(report)\n // Succeeded items deselect; failed items stay selected for a retry.\n const actedSet = new Set(acted)\n const failed = new Set(report.results.filter((r) => !r.ok).map((r) => r.ref.id))\n setSelection((prev) => ({\n ids: prev.ids.filter((id) => !actedSet.has(id) || failed.has(id)),\n anchorId: null,\n }))\n } finally {\n setBulkBusy(false)\n }\n }\n\n function exportJson() {\n const data = JSON.stringify(source.documents(), null, 2)\n const blob = new Blob([data], { type: 'application/json' })\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = `${collectionId}.json`\n a.click()\n URL.revokeObjectURL(url)\n }\n\n return (\n <div className=\"flex h-full min-h-0 flex-col\">\n {/* Header (EC-246a redesign). One toolbar: identity + refine on the left,\n lens + actions on the right; a transient filter bar drops below only\n while refining. The header breadcrumb (EC-214) names the collection —\n no title here. Locale is a lens; column/layout config lives behind the\n far-right Display control; shared views are config-as-code (EC-246b). */}\n <div className=\"shrink-0 border-b border-border px-4 py-3 sm:px-6\">\n <Row gap=\"2\" wrap>\n {/* Left — which view (only when >1), then the transient refine. */}\n <ViewTabs />\n {/* Transient ad-hoc refine — a chip beside the view tabs, editor in a\n popover (EC-246b); the chip's ✕ clears it, so no separate Reset. */}\n <FilterControl collection={collection} />\n {/* The working-set count is the RESULT of the view + filter above, so it\n reads last, set off by a divider and sized like its neighbours. */}\n <Separator orientation=\"vertical\" className=\"h-5 self-center\" />\n <Text\n as=\"span\"\n size=\"xs\"\n tone=\"muted\"\n className=\"whitespace-nowrap tabular-nums\"\n data-testid=\"collection-count\"\n >\n {countLabel}\n </Text>\n\n <Spacer />\n\n {/* Right — the ambient locale lens (EC-176; hidden for single-locale AND\n for a non-localized rail like users), then display config + write actions. */}\n {source.capabilities.locales ? <LocaleSwitcher /> : null}\n <DisplayMenu\n collection={collection}\n hierarchical={hierarchical}\n treeMode={treeMode}\n onToggleTree={setTreeMode}\n />\n {canCreate ? (\n <Button size=\"sm\" onClick={handleNew} data-testid=\"new-document\">\n <Plus /> {isPageCollection ? translate('cms.list.newPage') : translate('cms.list.new')}\n </Button>\n ) : null}\n {/* EC-213: import/export fold into one action menu, off the header.\n AD-19: a capability — absent on credential rails (users), so identity\n records are never dumped to / loaded from raw JSON. */}\n {source.capabilities.importExport ? (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"outline\"\n size=\"icon-sm\"\n aria-label={translate('cms.list.moreActions')}\n data-testid=\"collection-actions\"\n >\n <MoreHorizontal />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onClick={() => setImportOpen(true)} data-testid=\"action-import\">\n <Upload /> {translate('cms.list.import')}\n </DropdownMenuItem>\n <DropdownMenuItem\n onClick={exportJson}\n disabled={docs.length === 0}\n data-testid=\"action-export\"\n >\n <Download /> {translate('cms.list.export')}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n ) : null}\n {toolbarExtra}\n </Row>\n </div>\n\n {/* Bulk actions over the selection (EC-169) */}\n <BulkBar\n collection={collection}\n count={selectedIds.length}\n busy={bulkBusy}\n onAction={raiseBulk}\n onSetField={(setField) => void handleBulk('set-field', [...selectedIds], setField)}\n onClear={() => setSelection(clearSelection())}\n />\n {bulkReport ? (\n <BulkReportPanel report={bulkReport} onDismiss={() => setBulkReport(null)} />\n ) : null}\n\n {/* Reference-aware bulk unpublish/delete confirmation (EC-173). */}\n {pendingBulk !== null ? (\n <ReferenceConfirmDialog\n projectId={projectId}\n action={pendingBulk.action}\n targets={pendingBulk.targets}\n open\n busy={bulkBusy}\n onOpenChange={(open) => {\n if (!open) setPendingBulk(null)\n }}\n onConfirm={() => {\n const { action, targets } = pendingBulk\n setPendingBulk(null)\n void handleBulk(\n action,\n targets.map((target) => target.id),\n )\n }}\n />\n ) : null}\n\n {/* EC-274/EC-284: \"for review\" lane — the collection has drifted from its\n lens's expected shape; surface each conflict so an editor can resolve it. */}\n {shapeIssues.length > 0 ? (\n <div\n className=\"shrink-0 border-b border-warning/30 bg-warning/10 px-4 py-2 sm:px-6\"\n data-testid=\"shape-review-banner\"\n >\n <Stack gap=\"1\">\n {shapeIssues.map((issue, i) => (\n <Row key={`${issue.code}:${i}`} gap=\"2\" align=\"start\">\n <TriangleAlert className=\"mt-0.5 size-3.5 shrink-0 text-warning\" aria-hidden />\n <Stack gap=\"none\" className=\"min-w-0\">\n <Text size=\"xs\" weight=\"semibold\" tone=\"default\" title={issue.code}>\n {translate('cms.list.forReview')} · {cmsIssueLabel(issue.code)}\n </Text>\n <Text size=\"xs\" tone=\"muted\">\n {issue.message}\n </Text>\n </Stack>\n </Row>\n ))}\n </Stack>\n </div>\n ) : null}\n\n {/* Table */}\n <div className=\"min-h-0 flex-1 overflow-auto\">\n {docs.length === 0 ? (\n <div className=\"grid h-full place-items-center p-8\">\n <Stack gap=\"2\" align=\"center\" className=\"text-center\">\n <Text tone=\"muted\">{translate('cms.list.emptyNone', { noun: pluralLabel.toLowerCase() })}</Text>\n {canCreate ? (\n <Button size=\"sm\" onClick={handleNew}>\n <Plus />{' '}\n {isPageCollection\n ? translate('cms.list.newPage')\n : translate('cms.list.newNamed', {\n noun: localizedLabel(collection.form?.labelSingular, 'document'),\n })}\n </Button>\n ) : null}\n </Stack>\n </div>\n ) : visibleDocs.length === 0 ? (\n <div className=\"grid h-full place-items-center p-8\">\n <Text tone=\"muted\" data-testid=\"empty-filtered\">\n {translate('cms.list.emptyFiltered')}\n </Text>\n </div>\n ) : (\n <DocumentsGrid\n projectId={projectId}\n collection={collection}\n primary={primary}\n primaryFieldDef={primaryFieldDef}\n columns={columns}\n sortedDocs={orderedDocs}\n depthById={depthById}\n urlByDocId={urlByDocId}\n sort={viewState.sort}\n onSort={toggleSort}\n selectedIds={selectedIds}\n onToggleRow={(id, shift) =>\n setSelection((prev) => toggleRow(prev, visibleIds, id, shift))\n }\n onToggleAll={() =>\n setSelection(\n selectedIds.length === visibleIds.length && visibleIds.length > 0\n ? clearSelection()\n : selectAll(visibleIds),\n )\n }\n hasRowActions={hasRowActions}\n onRowAction={handleRowAction}\n />\n )}\n </div>\n\n {source.capabilities.importExport ? (\n <ImportDialog collectionId={collectionId} open={importOpen} onOpenChange={setImportOpen} />\n ) : null}\n </div>\n )\n}\n\n/**\n * The documents table with inline cell editing (EC-168). Cells edit in place\n * (text/number/boolean/select/date) or open pickers (relation/asset); each\n * commit is one operations command via the cell-edit controller, with\n * rollback + inline cell errors on rejection. Row checkboxes (EC-169) live in\n * their own column, so selection clicks never collide with cell editing.\n */\nfunction DocumentsGrid({\n projectId,\n collection,\n primary,\n primaryFieldDef,\n columns,\n sortedDocs,\n depthById,\n urlByDocId,\n sort,\n onSort,\n selectedIds,\n onToggleRow,\n onToggleAll,\n hasRowActions,\n onRowAction,\n}: {\n projectId: string\n collection: CollectionDef\n primary: string\n primaryFieldDef: FieldDef | undefined\n columns: string[]\n sortedDocs: CmsDocument[]\n /** EC-218: nesting depth per doc id when rendering the hierarchy (tree mode). */\n depthById?: Map<string, number>\n /** EC-216: each routable doc's derived URL; `null` hides the URL column. */\n urlByDocId?: Map<string, DocumentUrl> | null\n sort: ViewSort | null\n onSort: (field: string) => void\n selectedIds: readonly string[]\n onToggleRow: (id: string, shift: boolean) => void\n onToggleAll: () => void\n /** EC-316: whether the right-edge row `⋮` menu has anything to offer at all. */\n hasRowActions: boolean\n onRowAction: (action: RowAction, doc: CmsDocument) => void\n}) {\n const source = useCollectionView()\n const collectionId = collection.id\n const fieldByName = (name: string) => collection.fields.find((f) => f.name === name)\n // Inline editing is a capability: a read-only rail yields no editable cells.\n const editableFields = source.capabilities.inlineEdit\n ? columns.filter((name) => {\n const field = fieldByName(name)\n return field ? cellEditKind(field, source.isFieldReadOnly(field)) !== 'none' : false\n })\n : []\n const cellEdit = useCellEdit({ collection, docs: sortedDocs, editableFields })\n const selected = new Set(selectedIds)\n const allSelected = sortedDocs.length > 0 && selectedIds.length === sortedDocs.length\n\n return (\n <div ref={cellEdit.containerRef}>\n {/* EC-316: `table-fixed` + an explicit `<colgroup>` fix every column's\n width from the SCHEMA alone, before any row renders. Under the\n browser's default `table-layout: auto` a cell's INTRINSIC content\n width feeds back into its column — so swapping a cell's rendered\n value for its inline editor (a wider `<input>`) reflowed the whole\n grid. Fixed layout makes a column's width immune to its cells'\n content; `columnWidthRem` only sets relative proportions, so the\n grid still scales naturally with the container (never with a cell). */}\n <table className=\"w-full table-fixed border-collapse text-sm\">\n <colgroup>\n <col style={{ width: `${CHECKBOX_COLUMN_WIDTH_REM}rem` }} />\n <col style={{ width: `${PRIMARY_COLUMN_WIDTH_REM}rem` }} />\n {columns.map((name) => (\n <col key={name} style={{ width: `${columnWidthRem(fieldByName(name))}rem` }} />\n ))}\n <col style={{ width: `${STATE_COLUMN_WIDTH_REM}rem` }} />\n {urlByDocId ? <col style={{ width: `${URL_COLUMN_WIDTH_REM}rem` }} /> : null}\n {hasRowActions ? <col style={{ width: `${ROW_ACTIONS_COLUMN_WIDTH_REM}rem` }} /> : null}\n </colgroup>\n <thead className=\"sticky top-0 z-10 bg-background\">\n <tr className=\"border-b border-border\">\n <th className=\"px-3 py-2 text-left\">\n <SelectionCheckbox\n checked={allSelected}\n indeterminate={selectedIds.length > 0 && !allSelected}\n label={translate('cms.list.selectAll')}\n testId=\"select-all\"\n onToggle={() => onToggleAll()}\n />\n </th>\n <HeaderCell\n field={primary}\n label={primaryFieldDef ? fieldLabel(primaryFieldDef) : translate('cms.list.column.title')}\n sort={sort}\n onSort={onSort}\n />\n {columns.map((name) => {\n const field = fieldByName(name)\n return field ? (\n <HeaderCell key={name} field={name} label={fieldLabel(field)} sort={sort} onSort={onSort} />\n ) : null\n })}\n <HeaderCell field={STATE_FIELD} label={translate('cms.list.column.state')} sort={sort} onSort={onSort} />\n {/* EC-216: derived URL — not a field, so not sortable. */}\n {urlByDocId ? (\n <th className=\"px-3 py-2 text-left text-xs font-semibold text-muted-foreground\">{translate('cms.list.column.url')}</th>\n ) : null}\n {hasRowActions ? (\n <th className=\"px-2 py-2 text-right\">\n <span className=\"sr-only\">{translate('cms.list.rowActionsColumnLabel')}</span>\n </th>\n ) : null}\n </tr>\n </thead>\n <tbody>\n {sortedDocs.map((doc) => (\n <tr\n key={doc.id}\n className={cn(\n 'group border-b border-border/60 hover:bg-muted/40',\n selected.has(doc.id) && 'bg-primary/5',\n )}\n >\n <td className=\"px-3 py-2 align-middle\">\n <SelectionCheckbox\n checked={selected.has(doc.id)}\n label={translate('cms.list.selectRow', { id: doc.id })}\n testId={`select-row-${doc.id}`}\n onToggle={(shift) => onToggleRow(doc.id, shift)}\n />\n </td>\n <td className=\"px-3 py-2 align-middle\">\n <PrimaryCell\n projectId={projectId}\n collection={collection}\n doc={doc}\n primary={primary}\n depth={depthById?.get(doc.id) ?? 0}\n locale={source.activeLocale}\n config={source.localeConfig}\n detailPath={source.detailPath}\n />\n </td>\n {columns.map((name) => {\n const field = fieldByName(name)\n const coord = { docId: doc.id, field: name }\n const key = cellKey(coord)\n return (\n <td key={name} className=\"px-3 py-2 align-middle\">\n {field ? (\n <EditableCell\n collection={collection}\n doc={doc}\n field={field}\n editing={cellEdit.activeKey === key}\n busy={cellEdit.busyKey === key}\n errorMessage={cellEdit.errorOf(key)}\n onStartEdit={() => cellEdit.start(coord)}\n onCancel={() => cellEdit.cancel(coord)}\n onCommit={(value, advance) => cellEdit.commit(coord, value, advance)}\n />\n ) : null}\n </td>\n )\n })}\n <td className=\"px-3 py-2 align-middle\">\n <DocStateBadge\n published={\n source.publishing?.isPublished({ collection: collectionId, id: doc.id }) ?? false\n }\n />\n </td>\n {urlByDocId ? (\n <td className=\"px-3 py-2 align-middle\">\n <UrlCell url={urlByDocId.get(doc.id)} />\n </td>\n ) : null}\n {hasRowActions ? (\n <td className=\"px-2 py-2 text-right align-middle\">\n <RowActionsMenu\n doc={doc}\n published={source.publishing?.isPublished({ collection: collectionId, id: doc.id }) ?? false}\n hasDetailPath={source.detailPath !== undefined}\n onAction={(action) => onRowAction(action, doc)}\n />\n </td>\n ) : null}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )\n}\n\n/**\n * The right-edge row `⋮` menu (EC-316): the SAME action vocabulary as the\n * toolbar's bulk actions (`rowActionsFor`), gated by the SAME capabilities —\n * so it degrades exactly like the rest of the list for a rail without\n * publish/remove (AD-19). Renders nothing when the gate leaves zero actions.\n */\nfunction RowActionsMenu({\n doc,\n published,\n hasDetailPath,\n onAction,\n}: {\n doc: CmsDocument\n published: boolean\n hasDetailPath: boolean\n onAction: (action: RowAction) => void\n}) {\n const source = useCollectionView()\n const actions = rowActionsFor({ capabilities: source.capabilities, hasDetailPath, published })\n if (actions.length === 0) return null\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-label={translate('cms.list.rowActionsLabel', { id: doc.id })}\n data-testid={`row-actions-${doc.id}`}\n >\n <MoreHorizontal />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {actions.map((action) => (\n <RowActionItem key={action} action={action} onSelect={() => onAction(action)} />\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n\nfunction RowActionItem({ action, onSelect }: { action: RowAction; onSelect: () => void }) {\n switch (action) {\n case 'open':\n return (\n <DropdownMenuItem onClick={onSelect} data-testid=\"row-action-open\">\n <Pencil /> {translate('cms.list.rowAction.open')}\n </DropdownMenuItem>\n )\n case 'publish':\n return (\n <DropdownMenuItem onClick={onSelect} data-testid=\"row-action-publish\">\n <Eye /> {translate('cms.list.bulk.publish')}\n </DropdownMenuItem>\n )\n case 'unpublish':\n return (\n <DropdownMenuItem onClick={onSelect} data-testid=\"row-action-unpublish\">\n <EyeOff /> {translate('cms.list.bulk.unpublish')}\n </DropdownMenuItem>\n )\n case 'delete':\n return (\n <DropdownMenuItem\n variant=\"destructive\"\n onClick={onSelect}\n data-testid=\"row-action-delete\"\n >\n <Trash2 /> {translate('common.delete')}\n </DropdownMenuItem>\n )\n }\n}\n\n/**\n * A selection checkbox (row or select-all). Its own column and focus target —\n * it never participates in the cell-edit keyboard flow. Shift-click selects\n * the anchor→row range (the mousedown guard stops text selection).\n */\nfunction SelectionCheckbox({\n checked,\n indeterminate = false,\n label,\n testId,\n onToggle,\n}: {\n checked: boolean\n indeterminate?: boolean\n label: string\n testId: string\n onToggle: (shift: boolean) => void\n}) {\n return (\n <input\n ref={(el) => {\n if (el) el.indeterminate = indeterminate && !checked\n }}\n type=\"checkbox\"\n className=\"size-4 cursor-pointer accent-primary align-middle\"\n checked={checked}\n readOnly\n aria-label={label}\n data-testid={testId}\n onClick={(event) => onToggle(event.shiftKey)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n event.preventDefault()\n onToggle(event.shiftKey)\n }\n }}\n onMouseDown={(event) => {\n if (event.shiftKey) event.preventDefault()\n }}\n />\n )\n}\n\nfunction HeaderCell({\n field,\n label,\n sort,\n onSort,\n}: {\n field: string\n label: string\n sort: ViewSort | null\n onSort: (field: string) => void\n}) {\n const active = sort?.field === field\n return (\n <th className=\"px-3 py-2 text-left text-xs font-semibold text-muted-foreground\">\n <button type=\"button\" onClick={() => onSort(field)} className=\"inline-flex items-center gap-1 hover:text-foreground\">\n {label}\n {active ? (\n sort!.dir === 'asc' ? (\n <ArrowUp className=\"size-3\" />\n ) : (\n <ArrowDown className=\"size-3\" />\n )\n ) : null}\n </button>\n </th>\n )\n}\n\n/**\n * The primary (title) column cell: the document link, resolved in the\n * ambient active locale with a visible fallback chip when the shown title is\n * untranslated (EC-176).\n */\nfunction PrimaryCell({\n projectId,\n collection,\n doc,\n primary,\n depth = 0,\n locale,\n config,\n detailPath,\n}: {\n projectId: string\n collection: CollectionDef\n doc: CmsDocument\n primary: string\n /** EC-218: nesting depth in the hierarchy (tree mode) — indents the title. */\n depth?: number\n locale: Locale\n config: LocaleConfig\n /** Rail-owned detail route splat (AD-19); absent ⇒ the rail has no detail surface. */\n detailPath?: (id: string) => string\n}) {\n // EC-242: the title cell renders the document identity (resolveDocumentTitle) —\n // a string `titleField` or a function pattern — over the fallback-resolved\n // values, NOT the raw `primary` column value. The untranslated-title chip applies\n // only to a field-backed title (a function pattern has no single source field).\n const title = resolveDocumentTitle(\n collection,\n resolveDocumentForLocale(collection, doc, locale, config),\n doc.id,\n )\n const fallback =\n typeof collection.titleField === 'function'\n ? null\n : resolveDisplayedValue(collection, doc, primary, locale, config).fallback\n const splat = detailPath?.(doc.id)\n return (\n <Row gap=\"2\" align=\"center\" className=\"min-w-0\" style={{ paddingLeft: depth * 20 }}>\n {depth > 0 ? (\n <CornerDownRight className=\"size-3.5 shrink-0 text-muted-foreground\" aria-hidden />\n ) : null}\n {/* 0.0.39: assets get a leading, fixed-size preview in the filename column —\n an image thumbnail (object-cover) for image assets, the file-type placeholder\n otherwise. Fixed box, so it never reflows the EC-316 fixed column widths. */}\n {collection.kind === 'asset' ? <AssetThumbCell assetId={doc.id} alt={title} /> : null}\n {splat !== undefined ? (\n <Link\n to={STUDIO_PROJECT_ROUTE}\n params={{ projectId, _splat: splat }}\n className=\"truncate font-medium text-foreground hover:text-primary hover:underline\"\n >\n {title}\n </Link>\n ) : (\n <Text as=\"span\" className=\"truncate font-medium text-foreground\">\n {title}\n </Text>\n )}\n <FallbackChip fallback={fallback} testId={`cell-fallback-${doc.id}-${primary}`} />\n </Row>\n )\n}\n\n/**\n * The leading asset preview in the filename column (0.0.39). Resolves the asset\n * record from the ambient library and renders {@link AssetThumb} — an image preview\n * for image assets, the file-type placeholder for the rest. Mounted only for\n * `kind:'asset'` collections (which are always under an `<AssetsProvider>`), so the\n * `useAssetRecord` hook is never called on a rail without a library.\n */\nfunction AssetThumbCell({ assetId, alt }: { assetId: string; alt: string }) {\n const record = useAssetRecord(assetId)\n return <AssetThumb record={record} alt={alt} className=\"size-8 shrink-0\" />\n}\n\n/**\n * The read-only URL column cell (EC-216): the document's LIVE (published) path,\n * linking to the absolute live URL when a `frontendUrl` is configured. Only\n * published documents have a `url` here (the URL is derived from the published\n * pool, EC-205), so an unpublished document — having no live page — shows a dash.\n * The URL is always derived, never stored.\n */\nfunction UrlCell({ url }: { url?: DocumentUrl }) {\n if (!url) {\n return (\n <Text size=\"xs\" tone=\"subtle\">\n —\n </Text>\n )\n }\n if (url.href) {\n return (\n <a\n href={url.href}\n target=\"_blank\"\n rel=\"noreferrer\"\n title={url.href}\n className=\"inline-flex max-w-[18rem] items-center gap-1 text-xs text-muted-foreground transition-colors hover:text-foreground\"\n >\n <span className=\"truncate\">{url.path}</span>\n <ExternalLink className=\"size-3 shrink-0\" aria-hidden />\n </a>\n )\n }\n return (\n <Text size=\"xs\" tone=\"muted\" className=\"max-w-[18rem] truncate\" title={url.path}>\n {url.path}\n </Text>\n )\n}\n\nexport type { FieldDef }\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { Link, STUDIO_PROJECT_ROUTE, studioPath, useNavigate } from '@elytracms/studio/router';
|
|
3
|
-
import { Check, ChevronDown, CircleAlert, CircleCheck,
|
|
3
|
+
import { Check, ChevronDown, CircleAlert, CircleCheck, Eye, EyeOff, GitCompareArrows, History, Loader2, Lock, MoreHorizontal, RotateCcw, Save, Tag, Trash2, X, } from 'lucide-react';
|
|
4
4
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
5
5
|
import { FIELD_WIDTH_SPANS, SIDEBAR_FIELD_GROUP, clearHiddenValues, documentKey, groupOrder, groupSectionOf, hasAliases, hiddenGroupNames, isBlocksField, isFieldHidden, isFieldLocalized, isSingleton, resolveDocumentForLocale, resolveDocumentTitle, resolveField, sidebarFields, tabDescriptorOf, tabOrder, titleFieldOf, staticFieldHidden, urlForDocument, } from '@elytracms/core/cms-core';
|
|
6
6
|
import { blockRootsOf } from '@elytracms/core/project-graph';
|
|
@@ -18,7 +18,7 @@ import { FieldControl } from './field-control';
|
|
|
18
18
|
// EC-322: the lazy-wrapped page builder — the heavy canvas subtree code-splits out
|
|
19
19
|
// of the detail-view critical path and downloads only when a `blocks` field opens.
|
|
20
20
|
import { CompositionFieldEditor } from '../builder/composition-field-editor-lazy';
|
|
21
|
-
import { fieldLabel } from './cms-
|
|
21
|
+
import { fieldLabel } from './cms-labels';
|
|
22
22
|
import { useCmsCollectionViewSource } from '../collection-view/cms-collection-view-source';
|
|
23
23
|
import { CollectionViewProvider, useCollectionView } from '../collection-view/collection-view-context';
|
|
24
24
|
import { resolveFieldAccess } from '@elytracms/studio/lib/collection-view/collection-view-source';
|
|
@@ -33,9 +33,11 @@ import { VersionsPane } from './versions-pane';
|
|
|
33
33
|
// critical path and loads only when the Compare tab opens.
|
|
34
34
|
import { VersionCompare } from './version-compare-lazy';
|
|
35
35
|
import { useDocumentVersionsQuery } from './use-document-versions';
|
|
36
|
-
import { discardDraftStatus } from './discard-draft';
|
|
36
|
+
import { discardDraftStatus, flushDirtyDraft } from './discard-draft';
|
|
37
|
+
import { derivePublishedSnapshot, publishedVersionSnapshot } from './versions-model';
|
|
37
38
|
import { IssuesPane } from './issues-pane';
|
|
38
39
|
import { DetailsPane } from './details-pane';
|
|
40
|
+
import { DocumentUrlPath } from './document-url-path';
|
|
39
41
|
// 0.0.41: selection-driven embed inspector. Both modules are deliberately TipTap-free
|
|
40
42
|
// so the editor runtime stays behind rich-text/lazy (EC-322) — see their doc comments.
|
|
41
43
|
import { EmbedInspectorProvider } from './rich-text/embed-inspector-context';
|
|
@@ -118,58 +120,43 @@ function EditorBody({ projectId, collection, doc, focusPath, }) {
|
|
|
118
120
|
// meaningful when the document is published.
|
|
119
121
|
const published = source.publishing?.isPublished(ref) ?? false;
|
|
120
122
|
const [perspective, setPerspective] = useState('draft');
|
|
121
|
-
const [publishedSnapshot, setPublishedSnapshot] = useState({ status: 'loading' });
|
|
122
123
|
// Snap back to Draft if the document is unpublished while viewing Published.
|
|
123
124
|
useEffect(() => {
|
|
124
125
|
if (!published)
|
|
125
126
|
setPerspective('draft');
|
|
126
127
|
}, [published]);
|
|
127
|
-
//
|
|
128
|
-
//
|
|
129
|
-
//
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
}, [perspective, ref, loadVersions]);
|
|
128
|
+
// EC-316/EC-325 — "Discard changes" gating AND the Published-perspective
|
|
129
|
+
// snapshot share ONE query (AD-17: the one operations-backed cache,
|
|
130
|
+
// `use-document-versions.ts` — no raw `source.versioning.load` call
|
|
131
|
+
// anywhere in this component). Both need exactly the same
|
|
132
|
+
// `versions`/`publishedVersion` shape, so a second bespoke fetch on
|
|
133
|
+
// perspective switch would just re-read what this already has. Gated the
|
|
134
|
+
// same way the Discard-draft menu item always was: a publishing + versioned
|
|
135
|
+
// rail AND a published document (never a wasted fetch on e.g. the users
|
|
136
|
+
// rail or a never-published draft) — in every real `CollectionViewSource`
|
|
137
|
+
// `capabilities.publish`/`capabilities.versions` are set identically, so
|
|
138
|
+
// this is also exactly when the Published perspective is reachable.
|
|
139
|
+
const canDiscard = canPublish && canVersions;
|
|
140
|
+
const { versionsQuery, versionKey } = useDocumentVersionsQuery(ref, {
|
|
141
|
+
enabled: canDiscard && published,
|
|
142
|
+
});
|
|
143
|
+
const versionsView = versionsQuery.data ?? null;
|
|
144
|
+
const publishedVersionNumber = versionsView?.publishedVersion;
|
|
145
|
+
const publishedSnapshotDoc = publishedVersionSnapshot(versionsView);
|
|
146
|
+
// The Published-perspective snapshot (EC-226), derived from the query
|
|
147
|
+
// above — no second fetch, and `derivePublishedSnapshot` guards a
|
|
148
|
+
// disabled/not-yet-resolved query by reading as 'loading' (never a false
|
|
149
|
+
// 'missing').
|
|
150
|
+
const publishedSnapshot = derivePublishedSnapshot(versionsView);
|
|
151
151
|
// The whole fieldset is read-only when viewing Published. The form/canvas
|
|
152
152
|
// render the pinned snapshot ONLY once it has loaded — never the draft, which
|
|
153
153
|
// must not be presented as published; until then the body shows a placeholder.
|
|
154
154
|
const viewReadOnly = perspective === 'published';
|
|
155
155
|
const viewDoc = viewReadOnly && publishedSnapshot.status === 'ready' ? publishedSnapshot.doc : draft;
|
|
156
156
|
const publishedPending = viewReadOnly && publishedSnapshot.status !== 'ready';
|
|
157
|
-
// EC-316 — "Discard changes": revert the draft to exactly the published
|
|
158
|
-
// content. Only meaningful for a publishing + versioned rail AND a published
|
|
159
|
-
// document, so the history query is gated off otherwise (never a wasted
|
|
160
|
-
// fetch on e.g. the users rail or a never-published draft).
|
|
161
|
-
const canDiscard = canPublish && canVersions;
|
|
162
|
-
const { versionsQuery: discardVersionsQuery, versionKey: discardVersionKey } = useDocumentVersionsQuery(ref, {
|
|
163
|
-
enabled: canDiscard && published,
|
|
164
|
-
});
|
|
165
157
|
const discardCache = useOperationCache();
|
|
166
158
|
const [discardConfirm, setDiscardConfirm] = useState(false);
|
|
167
159
|
const [discardBusy, setDiscardBusy] = useState(false);
|
|
168
|
-
const discardView = discardVersionsQuery.data ?? null;
|
|
169
|
-
const publishedVersionNumber = discardView?.publishedVersion;
|
|
170
|
-
const publishedSnapshotForDiscard = publishedVersionNumber !== undefined
|
|
171
|
-
? discardView?.versions.find((v) => v.version === publishedVersionNumber)?.snapshot
|
|
172
|
-
: undefined;
|
|
173
160
|
// One pure decision (tested in discard-draft.test.ts): hidden / disabled-
|
|
174
161
|
// with-reason / ready. Its semantic equality is the SAME comparator the
|
|
175
162
|
// Versions pane's publish gate uses, so the two never contradict (EC-298).
|
|
@@ -177,7 +164,7 @@ function EditorBody({ projectId, collection, doc, focusPath, }) {
|
|
|
177
164
|
canDiscard,
|
|
178
165
|
published,
|
|
179
166
|
viewReadOnly,
|
|
180
|
-
publishedSnapshot:
|
|
167
|
+
publishedSnapshot: publishedSnapshotDoc,
|
|
181
168
|
collection,
|
|
182
169
|
draft,
|
|
183
170
|
});
|
|
@@ -196,10 +183,15 @@ function EditorBody({ projectId, collection, doc, focusPath, }) {
|
|
|
196
183
|
return;
|
|
197
184
|
setDiscardBusy(true);
|
|
198
185
|
try {
|
|
186
|
+
// EC-325: flush a dirty in-memory buffer FIRST, mirroring the Versions
|
|
187
|
+
// pane's/Compare view's own restores — `documents.restore` snapshots
|
|
188
|
+
// whatever is currently PERSISTED, so an edit still sitting in the
|
|
189
|
+
// autosave debounce window would otherwise be silently unrecoverable.
|
|
190
|
+
flushDirtyDraft({ dirty, save });
|
|
199
191
|
const restored = await source.versioning?.restore(ref, publishedVersionNumber, { kind: 'all' });
|
|
200
192
|
if (restored)
|
|
201
193
|
replaceDraft(restored);
|
|
202
|
-
await discardCache.invalidate(
|
|
194
|
+
await discardCache.invalidate(versionKey);
|
|
203
195
|
}
|
|
204
196
|
finally {
|
|
205
197
|
setDiscardBusy(false);
|
|
@@ -486,25 +478,23 @@ function EditorBody({ projectId, collection, doc, focusPath, }) {
|
|
|
486
478
|
// memoized: its render closes over per-render edit state (draft, highlight,
|
|
487
479
|
// field errors) via `renderFieldRow`, and the inspector re-renders with the rest
|
|
488
480
|
// of the editor anyway, so a stable pane identity would buy nothing here.
|
|
489
|
-
// 0.0.
|
|
490
|
-
//
|
|
491
|
-
// A cheap synchronous accessor, resolved on every render (NOT frozen in a
|
|
492
|
-
// with a static dep — the same first-paint-empty-routes trap the SlugField
|
|
493
|
-
// removed: routes arrive after the workspace/config loads).
|
|
481
|
+
// 0.0.42 (round 3): whether a deployment route addresses this collection — gates the
|
|
482
|
+
// header's composed-URL row (which carries the live-page affordance, EC-315 hybrid
|
|
483
|
+
// split). A cheap synchronous accessor, resolved on every render (NOT frozen in a
|
|
484
|
+
// `useMemo` with a static dep — the same first-paint-empty-routes trap the SlugField
|
|
485
|
+
// fix removed: routes arrive after the workspace/config loads).
|
|
494
486
|
const routableCollection = resolveDeploymentRoutes().some((route) => route.document?.collection === collection.id);
|
|
495
|
-
|
|
487
|
+
// The composed URL moved OUT of this pane and up to the header (round 3): a lone URL
|
|
488
|
+
// row on an otherwise-empty pane looked odd. So the Details pane exists only for slots
|
|
489
|
+
// and/or sidebar fields — never merely because the collection is routable (that would
|
|
490
|
+
// resurrect the empty-pane problem). A routable page keeps its pane via its slug
|
|
491
|
+
// sidebar field; a routable collection with neither has no pane (URL is in the header).
|
|
492
|
+
const detailsPane = hasAliases(collection) || visibleSidebarFields.length > 0
|
|
496
493
|
? {
|
|
497
494
|
id: 'details',
|
|
498
495
|
label: translate('cms.editor.detailsPane'),
|
|
499
496
|
icon: _jsx(Tag, { className: "size-3.5" }),
|
|
500
|
-
render: () => (_jsx(DetailsPane, { collection: collection, doc: draft, siblings: source.documents(), readOnly: viewReadOnly, fields: visibleSidebarFields, renderField: renderFieldRow,
|
|
501
|
-
? {
|
|
502
|
-
projectId,
|
|
503
|
-
routes: resolveDeploymentRoutes(),
|
|
504
|
-
localeConfig: source.localeConfig,
|
|
505
|
-
locale,
|
|
506
|
-
}
|
|
507
|
-
: undefined, onAliasChange: (alias) => setDraft((d) => {
|
|
497
|
+
render: () => (_jsx(DetailsPane, { collection: collection, doc: draft, siblings: source.documents(), readOnly: viewReadOnly, fields: visibleSidebarFields, renderField: renderFieldRow, onAliasChange: (alias) => setDraft((d) => {
|
|
508
498
|
const next = { ...d };
|
|
509
499
|
if (alias === undefined)
|
|
510
500
|
delete next.alias;
|
|
@@ -655,10 +645,24 @@ function EditorBody({ projectId, collection, doc, focusPath, }) {
|
|
|
655
645
|
localeConfig: source.localeConfig,
|
|
656
646
|
}, collection, published, { siblings: [...publishedDocs.byId.values()], locale });
|
|
657
647
|
}, [publishedDocs, collection, doc.id, locale, source.localeConfig]);
|
|
658
|
-
//
|
|
659
|
-
//
|
|
660
|
-
//
|
|
661
|
-
//
|
|
648
|
+
// 0.0.42 (round 3): the composed URL row lives in the header under the title; its
|
|
649
|
+
// LEAF segment carries the open-live affordance, mirroring the retired "View live"
|
|
650
|
+
// button's gating EXACTLY. `href` present (published + frontendUrl) → the leaf opens
|
|
651
|
+
// the live page in a new tab; absent → a muted, non-interactive icon with the same
|
|
652
|
+
// reason tooltip (loading / publish-first / set-frontendUrl). The draft-derived path
|
|
653
|
+
// itself still updates as you type — only the OPEN-live action is published-gated, so
|
|
654
|
+
// the draft/live distinction is preserved.
|
|
655
|
+
const headerLive = routableCollection
|
|
656
|
+
? liveUrl?.href
|
|
657
|
+
? { href: liveUrl.href, title: translate('cms.editor.openLiveUrl', { path: liveUrl.path }) }
|
|
658
|
+
: {
|
|
659
|
+
title: publishedDocs.status === 'loading'
|
|
660
|
+
? translate('cms.editor.loadingLiveUrl')
|
|
661
|
+
: !published
|
|
662
|
+
? translate('cms.editor.publishToViewLive')
|
|
663
|
+
: translate('cms.editor.setFrontendUrlHint'),
|
|
664
|
+
}
|
|
665
|
+
: undefined;
|
|
662
666
|
// EC-240: hide the tab bar when there is nothing to navigate — a single content
|
|
663
667
|
// tab with no References/Compare (the users rail). When framework tabs ARE
|
|
664
668
|
// present we KEEP the content tab(s) so there is always a way back to the form;
|
|
@@ -696,7 +700,7 @@ function EditorBody({ projectId, collection, doc, focusPath, }) {
|
|
|
696
700
|
setCompareBase,
|
|
697
701
|
setCompareTarget,
|
|
698
702
|
exitCompare,
|
|
699
|
-
}, children: _jsx(EmbedInspectorProvider, { value: embedInspectorApi, children: _jsxs("div", { className: cn('flex h-full min-h-0 flex-col', viewReadOnly && 'bg-info/[0.04]'), children: [_jsxs("div", { className: "shrink-0 border-b border-border px-4 py-3 sm:px-6", children: [_jsxs(Row, { gap: "3", children: [_jsxs(Row, { gap: "2", align: "center", className: "min-w-0", children: [_jsx(Heading, { level: 1, size: "h2", className: "truncate", children: singleton ? localizedLabel(collection.form?.label, collection.id) : title || doc.id }), singleton ? null : _jsx(FallbackChip, { fallback: titleFallback, testId: "doc-title-fallback" })] }), _jsx(Spacer, {}), _jsx(Text, { size: "xs", tone: "muted", className: "whitespace-nowrap", "data-testid": "autosave-status", children: source.lastError
|
|
703
|
+
}, children: _jsx(EmbedInspectorProvider, { value: embedInspectorApi, children: _jsxs("div", { className: cn('flex h-full min-h-0 flex-col', viewReadOnly && 'bg-info/[0.04]'), children: [_jsxs("div", { className: "shrink-0 border-b border-border px-4 py-3 sm:px-6", children: [_jsxs(Row, { gap: "3", align: "start", children: [_jsxs(Stack, { gap: "1", className: "min-w-0", children: [_jsxs(Row, { gap: "2", align: "center", className: "min-w-0", children: [_jsx(Heading, { level: 1, size: "h2", className: "truncate", children: singleton ? localizedLabel(collection.form?.label, collection.id) : title || doc.id }), singleton ? null : _jsx(FallbackChip, { fallback: titleFallback, testId: "doc-title-fallback" })] }), routableCollection ? (_jsx(DocumentUrlPath, { projectId: projectId, collection: collection, doc: draft, siblings: source.documents(), routes: resolveDeploymentRoutes(), localeConfig: source.localeConfig, locale: locale, live: headerLive })) : null] }), _jsx(Spacer, {}), _jsx(Text, { size: "xs", tone: "muted", className: "whitespace-nowrap", "data-testid": "autosave-status", children: source.lastError
|
|
700
704
|
? translate('cms.editor.saveFailed')
|
|
701
705
|
: explicitSave
|
|
702
706
|
? dirty
|
|
@@ -704,11 +708,7 @@ function EditorBody({ projectId, collection, doc, focusPath, }) {
|
|
|
704
708
|
: translate('cms.editor.saved')
|
|
705
709
|
: dirty
|
|
706
710
|
? translate('cms.editor.saving')
|
|
707
|
-
: translate('cms.editor.saved') }), canPublish ? _jsx(DocStateBadge, { published: published }) : null,
|
|
708
|
-
? translate('cms.editor.loadingLiveUrl')
|
|
709
|
-
: !published
|
|
710
|
-
? translate('cms.editor.publishToViewLive')
|
|
711
|
-
: translate('cms.editor.setFrontendUrlHint'), children: [_jsx(ExternalLink, {}), " ", translate('cms.editor.viewLive')] }))) : null, canPublish ? (_jsxs(Row, { gap: "px", align: "center", children: [_jsx(Button, { size: "sm", onClick: handlePublish, disabled: publishDisabled, title: publishTitle, className: canPublishClose ? 'rounded-r-none' : undefined, "data-testid": "doc-publish", children: publishButtonLabel }), canPublishClose ? (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { size: "sm", disabled: publishDisabled, "aria-label": translate('cms.editor.publishActions'), "data-testid": "doc-publish-actions", className: "rounded-l-none border-l border-primary-foreground/25 px-1.5", children: _jsx(ChevronDown, { className: "size-3.5" }) }) }), _jsx(DropdownMenuContent, { align: "end", children: _jsxs(DropdownMenuItem, { onClick: handlePublishAndClose, "data-testid": "doc-publish-and-close", children: [_jsx(Save, {}), " ", translate('cms.editor.publishAndClose')] }) })] })) : null] })) : null, explicitSave ? (_jsxs(Button, { size: "sm", onClick: save, disabled: !dirty, "data-testid": "doc-save", children: [_jsx(Check, {}), " ", translate('common.save')] })) : null, published || !singleton ? (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "outline", size: "icon-sm", "aria-label": translate('cms.editor.moreActions'), children: _jsx(MoreHorizontal, {}) }) }), _jsxs(DropdownMenuContent, { align: "end", children: [discardStatus !== 'hidden' ? (_jsxs(DropdownMenuItem, { "data-testid": "doc-discard-draft", disabled: discardStatus !== 'ready', title: discardDisabledReason, onClick: () => setDiscardConfirm(true), children: [_jsx(RotateCcw, {}), " ", translate('cms.editor.discardDraft')] })) : null, published ? (_jsxs(DropdownMenuItem, { onClick: () => setConfirmAction('unpublish'), children: [_jsx(EyeOff, {}), " ", translate('cms.editor.unpublish')] })) : null, singleton ? null : (_jsxs(DropdownMenuItem, { "data-testid": "doc-delete", className: "text-destructive", onClick: () => setConfirmAction('delete'), children: [_jsx(Trash2, {}), " ", translate('common.delete')] }))] })] })) : null] }), showLensRow ? (_jsxs(Row, { gap: "3", className: "mt-3", wrap: true, children: [_jsxs(Row, { gap: "1", align: "center", children: [showContentTabs ? tabs.map((tab) => renderContentTab(tab)) : null, showReferences ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "mx-1 h-4 w-px bg-border", "aria-hidden": true }), renderContentTab(REFERENCES_TAB)] })) : null, compare ? (_jsxs("span", { className: cn('inline-flex items-center gap-1 rounded-md px-2.5 py-1 text-xs font-medium transition-colors', activeTab === COMPARE_TAB
|
|
711
|
+
: translate('cms.editor.saved') }), canPublish ? _jsx(DocStateBadge, { published: published }) : null, canPublish ? (_jsxs(Row, { gap: "px", align: "center", children: [_jsx(Button, { size: "sm", onClick: handlePublish, disabled: publishDisabled, title: publishTitle, className: canPublishClose ? 'rounded-r-none' : undefined, "data-testid": "doc-publish", children: publishButtonLabel }), canPublishClose ? (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { size: "sm", disabled: publishDisabled, "aria-label": translate('cms.editor.publishActions'), "data-testid": "doc-publish-actions", className: "rounded-l-none border-l border-primary-foreground/25 px-1.5", children: _jsx(ChevronDown, { className: "size-3.5" }) }) }), _jsx(DropdownMenuContent, { align: "end", children: _jsxs(DropdownMenuItem, { onClick: handlePublishAndClose, "data-testid": "doc-publish-and-close", children: [_jsx(Save, {}), " ", translate('cms.editor.publishAndClose')] }) })] })) : null] })) : null, explicitSave ? (_jsxs(Button, { size: "sm", onClick: save, disabled: !dirty, "data-testid": "doc-save", children: [_jsx(Check, {}), " ", translate('common.save')] })) : null, published || !singleton ? (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "outline", size: "icon-sm", "aria-label": translate('cms.editor.moreActions'), children: _jsx(MoreHorizontal, {}) }) }), _jsxs(DropdownMenuContent, { align: "end", children: [discardStatus !== 'hidden' ? (_jsxs(DropdownMenuItem, { "data-testid": "doc-discard-draft", disabled: discardStatus !== 'ready', title: discardDisabledReason, onClick: () => setDiscardConfirm(true), children: [_jsx(RotateCcw, {}), " ", translate('cms.editor.discardDraft')] })) : null, published ? (_jsxs(DropdownMenuItem, { onClick: () => setConfirmAction('unpublish'), children: [_jsx(EyeOff, {}), " ", translate('cms.editor.unpublish')] })) : null, singleton ? null : (_jsxs(DropdownMenuItem, { "data-testid": "doc-delete", className: "text-destructive", onClick: () => setConfirmAction('delete'), children: [_jsx(Trash2, {}), " ", translate('common.delete')] }))] })] })) : null] }), showLensRow ? (_jsxs(Row, { gap: "3", className: "mt-3", wrap: true, children: [_jsxs(Row, { gap: "1", align: "center", children: [showContentTabs ? tabs.map((tab) => renderContentTab(tab)) : null, showReferences ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "mx-1 h-4 w-px bg-border", "aria-hidden": true }), renderContentTab(REFERENCES_TAB)] })) : null, compare ? (_jsxs("span", { className: cn('inline-flex items-center gap-1 rounded-md px-2.5 py-1 text-xs font-medium transition-colors', activeTab === COMPARE_TAB
|
|
712
712
|
? 'bg-accent text-accent-foreground'
|
|
713
713
|
: 'text-muted-foreground hover:bg-muted'), children: [_jsxs("button", { type: "button", onClick: () => setActiveTab(COMPARE_TAB), "aria-pressed": activeTab === COMPARE_TAB, className: "inline-flex items-center gap-1", children: [_jsx(GitCompareArrows, { className: "size-3", "aria-hidden": true }), " ", translate('cms.version.compare')] }), _jsx("button", { type: "button", onClick: exitCompare, "aria-label": translate('cms.version.closeCompare'), className: "ml-0.5 rounded p-0.5 hover:bg-background/40", children: _jsx(X, { className: "size-3" }) })] })) : null] }), _jsx(Spacer, {}), canLocales ? _jsx(LocaleSwitcher, {}) : null, canPublish ? (_jsxs(Row, { gap: "px", className: "rounded-md bg-muted/60 p-0.5", children: [_jsx(PerspectiveButton, { label: translate('cms.editor.draftState'), active: perspective === 'draft', onClick: () => setPerspective('draft') }), _jsx(PerspectiveButton, { label: translate('cms.editor.publishedState'), active: perspective === 'published', accent: "info", disabled: !published, title: published ? undefined : translate('cms.editor.publishToViewPublished'), onClick: () => setPerspective('published') })] })) : null] })) : null] }), viewReadOnly ? (_jsxs(Row, { gap: "2", className: "shrink-0 border-b border-info/30 bg-info/10 px-4 py-1.5 text-info sm:px-6", "data-testid": "published-view-banner", children: [_jsx(Lock, { className: "size-3.5 shrink-0", "aria-hidden": true }), _jsx(Text, { size: "xs", className: "text-info", children: translate('cms.editor.publishedReadOnlyBanner') }), _jsx(Spacer, {}), _jsx("button", { type: "button", onClick: () => setPerspective('draft'), className: "text-xs font-medium underline-offset-2 hover:underline", children: translate('cms.editor.switchToDraft') })] })) : null, publishedPending ? (_jsx("div", { className: "grid min-h-0 flex-1 place-items-center p-8", children: _jsx(Text, { size: "sm", tone: "muted", children: publishedSnapshot.status === 'loading'
|
|
714
714
|
? translate('cms.editor.loadingPublishedVersion')
|