@elytracms/studio 0.0.9 → 0.0.11
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/cms/cms-store.js +10 -2
- package/dist/components/cms/cms-store.js.map +1 -1
- package/dist/components/cms/detail-editor.js +95 -37
- package/dist/components/cms/detail-editor.js.map +1 -1
- package/dist/components/cms/details-pane.d.ts +29 -0
- package/dist/components/cms/details-pane.js +29 -0
- package/dist/components/cms/details-pane.js.map +1 -0
- package/dist/components/cms/field-control.js +6 -1
- package/dist/components/cms/field-control.js.map +1 -1
- package/dist/components/inspector/inspector-sidebar.d.ts +8 -1
- package/dist/components/inspector/inspector-sidebar.js +9 -3
- package/dist/components/inspector/inspector-sidebar.js.map +1 -1
- package/dist/lib/operations/cms-persistence.d.ts +7 -2
- package/dist/lib/operations/cms-persistence.js +6 -2
- package/dist/lib/operations/cms-persistence.js.map +1 -1
- package/dist/lib/persona/labels.js +2 -0
- package/dist/lib/persona/labels.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detail-editor.js","sourceRoot":"","sources":["../../../src/components/cms/detail-editor.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Link, STUDIO_PROJECT_ROUTE, studioPath, useNavigate } from '@elytracms/studio/router'\nimport {\n CircleAlert,\n CircleCheck,\n ExternalLink,\n Eye,\n EyeOff,\n History,\n Languages,\n Loader2,\n Lock,\n MoreHorizontal,\n Trash2,\n} from 'lucide-react'\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport {\n documentKey,\n isBlocksField,\n isFieldLocalized,\n isSingleton,\n resolveField,\n urlForDocument,\n} from '@elytracms/core/cms-core'\nimport type { CmsDocument, CollectionDef, FieldDef, Locale, LocaleConfig } from '@elytracms/core/cms-core'\nimport {\n Badge,\n Button,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n Field,\n Heading,\n Panel,\n PanelHeader,\n Row,\n Spacer,\n Stack,\n Text,\n toast,\n} from '@elytracms/studio/ui'\nimport { cn } from '@elytracms/studio/lib/utils'\nimport {\n LocaleSwitcher,\n displayedFieldFallback,\n hasLocaleVariant,\n localeChipLabel,\n setStudioLocale,\n} from '@elytracms/studio/lib/locale'\nimport { parseDocumentFieldPath } from '@elytracms/studio/lib/references'\nimport type { ReferenceAction } from '@elytracms/studio/lib/references'\nimport { FallbackChip, fallbackTitle } from './cell'\nimport { FieldControl } from './field-control'\nimport { CompositionFieldEditor } from '../builder/composition-field-editor'\nimport { fieldLabel, useCms } from './cms-store'\nimport { DocStateBadge } from './doc-state'\nimport { ReferenceConfirmDialog } from './reference-confirm'\nimport { ReferencesPanel } from '../references/references-panel'\nimport { InspectorSidebar } from '../inspector/inspector-sidebar'\nimport type { InspectorPane } from '../inspector/inspector-sidebar'\nimport { DocumentEditorProvider } from './document-editor-context'\nimport { VersionsPane } from './versions-pane'\nimport { IssuesPane } from './issues-pane'\nimport { AliasSelector } from './alias-selector'\nimport { useSetBreadcrumb } from '../breadcrumb-context'\nimport type { BreadcrumbItem } from '../breadcrumb-context'\nimport { resolveDeploymentFrontendUrl, resolveDeploymentRoutes } from '@elytracms/studio/lib/workspace'\nimport { usePublishedDocuments } from '@elytracms/studio/lib/cms/published-documents'\n\nexport function DetailEditor({\n projectId,\n collectionId,\n documentId,\n focusPath,\n}: {\n projectId: string\n collectionId: string\n documentId: string\n /** Reference-index field path (`?field=`, EC-172): highlight + scroll to the exact field. */\n focusPath?: string\n}) {\n const cms = useCms()\n const collection = cms.getCollection(collectionId)\n const doc = cms.getDocument({ collection: collectionId, id: documentId })\n\n // EC-274: singleton opening is owned by `SingletonGate` (it resolves the lone\n // document and materializes it). The detail editor just renders the document it\n // is given by id — singletons need no special case here.\n if (!collection || !doc) {\n return (\n <div className=\"grid h-full place-items-center p-8\">\n <Stack gap=\"3\" align=\"center\" className=\"text-center\">\n <Heading level={2} size=\"h2\">\n Document not found\n </Heading>\n <Link\n to={STUDIO_PROJECT_ROUTE}\n params={{ projectId, _splat: studioPath.cmsCollection(collectionId) }}\n className=\"text-sm text-primary hover:underline\"\n >\n Back to {collectionId}\n </Link>\n </Stack>\n </div>\n )\n }\n\n return (\n <EditorBody\n key={`${collectionId}/${documentId}`}\n projectId={projectId}\n collection={collection}\n doc={doc}\n focusPath={focusPath}\n />\n )\n}\n\n/** The loaded state of a document's pinned published snapshot (EC-226). */\ntype PublishedSnapshot =\n | { status: 'loading' }\n | { status: 'ready'; doc: CmsDocument }\n | { status: 'missing' }\n\nfunction EditorBody({\n projectId,\n collection,\n doc,\n focusPath,\n}: {\n projectId: string\n collection: CollectionDef\n doc: CmsDocument\n focusPath?: string\n}) {\n const cms = useCms()\n const navigate = useNavigate()\n // EC-217: a singleton collection has no list — there is nowhere to go \"back\"\n // to, and its one document is fixed (never deleted). The header drops the\n // back-crumb/id line and the Delete action accordingly.\n const singleton = isSingleton(collection)\n const [draft, setDraft] = useState<CmsDocument>(() => structuredClone(doc))\n // The studio's ambient active locale (EC-176): the form displays and edits\n // exactly this locale — switched via the shared LocaleSwitcher, never per field.\n const locale = cms.activeLocale\n // Bumped when a version restore replaces the draft out-of-band, to remount the\n // (uncontrolled) canvas editor from the restored value (EC-224).\n const [restoreNonce, setRestoreNonce] = useState(0)\n // EC-173: unpublish/delete go through the reference-aware confirmation.\n const [confirmAction, setConfirmAction] = useState<ReferenceAction | null>(null)\n // Stable so the document-editor context value (EC-224) doesn't churn each render.\n const ref = useMemo(() => ({ collection: collection.id, id: doc.id }), [collection.id, doc.id])\n const confirmTargets = useMemo(\n () => [{ collection: collection.id, id: doc.id }],\n [collection.id, doc.id],\n )\n\n // EC-226: the draft/published VIEW perspective. Draft = the editable working\n // draft; Published = the pinned published snapshot, rendered read-only. Only\n // meaningful when the document is published.\n const published = cms.isPublished(ref)\n const [perspective, setPerspective] = useState<'draft' | 'published'>('draft')\n const [publishedSnapshot, setPublishedSnapshot] = useState<PublishedSnapshot>({ status: 'loading' })\n // Snap back to Draft if the document is unpublished while viewing Published.\n useEffect(() => {\n if (!published) setPerspective('draft')\n }, [published])\n // Load the pinned published snapshot when viewing Published (fresh each switch,\n // so it reflects the current pin after a re-publish). `loadDocumentVersions` is\n // a stable callback, so this only re-runs on a perspective/ref change.\n const loadVersions = cms.loadDocumentVersions\n useEffect(() => {\n if (perspective !== 'published') return\n let cancelled = false\n setPublishedSnapshot({ status: 'loading' })\n void (async () => {\n const view = await loadVersions(ref)\n if (cancelled) return\n const pinned =\n view.publishedVersion !== undefined\n ? view.versions.find((v) => v.version === view.publishedVersion)?.snapshot\n : undefined\n setPublishedSnapshot(pinned ? { status: 'ready', doc: pinned } : { status: 'missing' })\n })()\n return () => {\n cancelled = true\n }\n }, [perspective, ref, loadVersions])\n\n // The whole fieldset is read-only when viewing Published. The form/canvas\n // render the pinned snapshot ONLY once it has loaded — never the draft, which\n // must not be presented as published; until then the body shows a placeholder.\n const viewReadOnly = perspective === 'published'\n const viewDoc =\n viewReadOnly && publishedSnapshot.status === 'ready' ? publishedSnapshot.doc : draft\n const publishedPending = viewReadOnly && publishedSnapshot.status !== 'ready'\n\n const dirty = JSON.stringify(draft) !== JSON.stringify(doc)\n const issues = useMemo(() => cms.validate(draft), [cms, draft])\n const errorCount = issues.filter((i) => i.severity === 'error').length\n const hasErrors = errorCount > 0\n\n // --- Autosave (EC-225) -----------------------------------------------------\n // The draft persists automatically 1s after the last edit; there is no manual\n // Save button. Refs let the unmount flush read the latest values without\n // re-subscribing the effects.\n const draftRef = useRef(draft)\n draftRef.current = draft\n const dirtyRef = useRef(dirty)\n dirtyRef.current = dirty\n const cmsRef = useRef(cms)\n cmsRef.current = cms\n\n useEffect(() => {\n if (!dirty) return\n const timer = window.setTimeout(() => cmsRef.current.saveDocument(draftRef.current), 1000)\n return () => window.clearTimeout(timer)\n }, [dirty, draft])\n\n // Flush a still-pending edit on unmount (navigating away inside the debounce\n // window) so nothing is lost. Unmount-only — refs carry the latest state.\n useEffect(\n () => () => {\n if (dirtyRef.current) cmsRef.current.saveDocument(draftRef.current)\n },\n [],\n )\n const errorsByField = useMemo(() => {\n const map = new Map<string, string>()\n for (const issue of issues) {\n // validateDocument populates meta.field for field-level issues (works for\n // both `values` and `localized/<locale>` paths, unlike positional indexing).\n const field = issue.meta?.field\n if (typeof field === 'string' && !map.has(field)) map.set(field, issue.message)\n }\n return map\n }, [issues])\n\n const tabs = collection.form?.tabs ?? ['main']\n // EC-269: References gets its own dedicated, visibility-gated tab — it mounts\n // (and loads) only when selected, and unmounts on leave, so normal editing\n // never triggers reference fetching. Appended after the collection's content tabs.\n const REFERENCES_TAB = 'references'\n const editorTabs = [...tabs, REFERENCES_TAB]\n const [activeTab, setActiveTab] = useState(tabs[0]!)\n const tabFields = collection.fields.filter((f) => (f.form?.tab ?? tabs[0]) === activeTab && !f.form?.hidden)\n const groups = groupFields(tabFields, collection)\n // EC-188 (AD-12): a composition (`blocks`) field is a special content feature,\n // not a field-row — it takes over its tab with the full page-builder canvas.\n // Convention: such a field lives on its own dedicated fieldset tab.\n const canvasField = tabFields.find(isBlocksField)\n\n const [highlightedField, setHighlightedField] = useState<string | null>(null)\n // Focus a field by name: switch to its tab (and locale, when given), scroll the\n // control into view, and ring-highlight it. Shared by the reference deep-link\n // (`focusPath`, EC-172) and the Issues pane's jump-to-field (EC-283).\n const focusTimersRef = useRef<number[]>([])\n const focusField = useCallback(\n (fieldName: string, localeHint?: string) => {\n const field = collection.fields.find((f) => f.name === fieldName)\n if (!field) return\n const fieldTabs = collection.form?.tabs ?? ['main']\n setActiveTab(field.form?.tab ?? fieldTabs[0]!)\n if (localeHint !== undefined && cms.localeConfig.locales.includes(localeHint)) {\n setStudioLocale(localeHint)\n }\n setHighlightedField(field.name)\n // Clear any timers from a prior jump so back-to-back jumps don't fight.\n focusTimersRef.current.forEach((t) => window.clearTimeout(t))\n const scrollTimer = window.setTimeout(() => {\n // Some controls (relation/asset pickers) don't render the input id —\n // the field label (`htmlFor`) is always present.\n const control =\n document.getElementById(`f-${field.name}`) ??\n document.querySelector(`label[for=\"${CSS.escape(`f-${field.name}`)}\"]`)\n control?.scrollIntoView({ block: 'center', behavior: 'smooth' })\n }, 60)\n const clearTimer = window.setTimeout(() => setHighlightedField(null), 3200)\n focusTimersRef.current = [scrollTimer, clearTimer]\n },\n [collection, cms.localeConfig],\n )\n useEffect(() => () => focusTimersRef.current.forEach((t) => window.clearTimeout(t)), [])\n\n // Reference deep links (EC-172): `?field=<index path>` pinpoints the exact field.\n useEffect(() => {\n if (!focusPath) return\n const parsed = parseDocumentFieldPath(focusPath)\n if (!parsed) return\n focusField(parsed.field, parsed.locale)\n }, [focusPath, focusField])\n\n function getValue(field: FieldDef): unknown {\n // EC-226: read from the active VIEW (the draft, or the pinned published\n // snapshot when viewing Published) — never directly from `draft`.\n if (isFieldLocalized(collection, field.name)) {\n // Display the explicit variant when it exists, else the EC-018 fallback\n // value — labeled as such by the field's fallback marker (EC-176), so a\n // German view shows the English text visibly, never an unexplained blank.\n const explicit = viewDoc.localized?.[locale]?.[field.name]\n if (explicit !== undefined) return explicit\n return resolveField(collection, viewDoc, field.name, locale, cms.localeConfig).value\n }\n return viewDoc.values[field.name]\n }\n\n function setValue(field: FieldDef, value: unknown) {\n setDraft((d) => {\n if (isFieldLocalized(collection, field.name)) {\n const perLocale = { ...(d.localized?.[locale] ?? {}) }\n if (value === undefined) delete perLocale[field.name]\n else perLocale[field.name] = value\n return { ...d, localized: { ...d.localized, [locale]: perLocale } }\n }\n const values = { ...d.values }\n if (value === undefined) delete values[field.name]\n else values[field.name] = value\n return { ...d, values }\n })\n }\n\n function save() {\n cms.saveDocument(draft)\n }\n\n // EC-224: a version restore swaps the working draft for an older snapshot; the\n // open editor adopts it so the form/canvas re-render from the restored content\n // (the operation already persisted it, so it lands clean/non-dirty).\n function replaceDraft(next: CmsDocument) {\n setDraft(next)\n // The canvas editor is uncontrolled after mount (it builds its graph once and\n // lifts edits OUT). A restore replaces the draft from outside, so bump the\n // nonce to REMOUNT the canvas from the restored value — otherwise it keeps the\n // pre-restore tree and the next edit would clobber the restore.\n setRestoreNonce((n) => n + 1)\n }\n\n // The frame-owned `Versions` pane (EC-224) — appended after any view-supplied\n // pane (the canvas's `Properties`). One instance feeds both the form view's\n // sidebar and the canvas view's sidebar.\n const versionsPane = useMemo<InspectorPane>(\n () => ({\n id: 'versions',\n label: 'Versions',\n icon: <History className=\"size-3.5\" />,\n render: () => <VersionsPane />,\n }),\n [],\n )\n // The frame-owned `Issues` pane (EC-283) — the document-scoped validation\n // surface that replaces the always-on footer band. The tab carries a count\n // badge (error- vs warning-toned) so a non-zero count is discoverable from\n // any tab; document-level issues (e.g. EC-260 nesting-depth) live only here.\n const issuesPane = useMemo<InspectorPane>(\n () => ({\n id: 'issues',\n label: 'Issues',\n icon: <CircleAlert className=\"size-3.5\" />,\n badge:\n issues.length === 0 ? undefined : (\n <Badge\n variant={errorCount > 0 ? 'error' : 'warning'}\n className=\"px-1.5 py-0 leading-none\"\n >\n {issues.length}\n </Badge>\n ),\n render: () => (\n <IssuesPane issues={issues} collection={collection} onJumpToField={focusField} />\n ),\n }),\n [issues, errorCount, collection, focusField],\n )\n const trailingPanes = useMemo(\n () => [versionsPane, issuesPane],\n [versionsPane, issuesPane],\n )\n\n // EC-268: the Publish button is its own indicator — pending while the publish\n // round-trips, a brief success, and an error toast if it rejects at transport.\n const [publishState, setPublishState] = useState<'idle' | 'pending' | 'success'>('idle')\n\n async function handlePublish() {\n // Capture the latest edit before the snapshot in case Publish is clicked\n // inside the autosave debounce window; the serial persister queue runs the\n // upsert before the publish so the snapshot is the saved draft (EC-225).\n if (dirty) save()\n // Publish snapshots the draft as a version and pins it (EC-224). The live\n // row stays a continuous draft — published-ness is the version pointer\n // (`cms.isPublished`). Pre-gated by `disabled={hasErrors}`; the optimistic\n // flip reconciles against the backend (EC-225), so a logical rejection the\n // gate doesn't cover (schema divergence) self-corrects the badge. A hard\n // failure (transport) rejects the flush — surface it loudly (EC-268).\n setPublishState('pending')\n try {\n await cms.publishDocument(ref)\n setPublishState('success')\n setTimeout(() => setPublishState('idle'), 1800)\n } catch (error) {\n setPublishState('idle')\n toast.error(error instanceof Error ? `Publish failed: ${error.message}` : 'Publish failed.')\n }\n }\n\n function handleConfirmedAction() {\n if (confirmAction === 'unpublish') {\n setConfirmAction(null)\n void cms.unpublishDocument(ref)\n return\n }\n if (confirmAction === 'delete') {\n setConfirmAction(null)\n cms.deleteDocument(ref)\n void navigate({\n to: STUDIO_PROJECT_ROUTE,\n params: { projectId, _splat: studioPath.cmsCollection(collection.id) },\n })\n }\n }\n\n // While the published snapshot is pending, don't derive the title from the\n // draft (it must not read as the published title) — fall back to the id.\n const title = publishedPending ? '' : primaryTitle(viewDoc, collection, locale, cms.localeConfig)\n const titleFallback = publishedPending\n ? null\n : displayedFieldFallback(\n collection,\n viewDoc,\n collection.titleField ?? 'title',\n locale,\n cms.localeConfig,\n )\n\n // EC-214: the document is the active record — contribute the collection (a\n // link back to its list) and the document title to the global header\n // breadcrumb, replacing the editor's own back-link + collection/id line. A\n // singleton has no list, so it contributes a single, non-linked crumb. The\n // title tracks the live draft so a rename updates the crumb immediately.\n const breadcrumbItems = useMemo<BreadcrumbItem[]>(() => {\n const collectionLabel = collection.form?.label ?? collection.id\n if (singleton) return [{ label: collectionLabel }]\n const docTitle = primaryTitle(draft, collection, locale, cms.localeConfig) || doc.id\n return [\n {\n label: collectionLabel,\n to: STUDIO_PROJECT_ROUTE,\n params: { projectId, _splat: studioPath.cmsCollection(collection.id) },\n },\n { label: docTitle },\n ]\n }, [singleton, collection, draft, locale, cms.localeConfig, doc.id, projectId])\n useSetBreadcrumb(breadcrumbItems)\n\n // EC-205/EC-216: the LIVE URL derives strictly from PUBLISHED data — the\n // document's pinned published snapshot and its published ancestors — never the\n // draft (an unpublished slug/parent edit must not leak into the live URL). The\n // pool is exactly what the live site serves, so a published doc resolves to the\n // URL visitors actually get; `undefined` until the doc is published (and the\n // pool has loaded). The collection being routable gates the disabled hint below.\n const publishedDocs = usePublishedDocuments(cms.projectId, collection.id)\n const routableCollection = useMemo(\n () => resolveDeploymentRoutes().some((route) => route.document?.collection === collection.id),\n [collection.id],\n )\n const liveUrl = useMemo(() => {\n const published = publishedDocs.byId.get(doc.id)\n if (!published) return undefined\n return urlForDocument(\n {\n routes: resolveDeploymentRoutes(),\n frontendUrl: resolveDeploymentFrontendUrl(),\n localeConfig: cms.localeConfig,\n },\n collection,\n published,\n { siblings: [...publishedDocs.byId.values()], locale },\n )\n }, [publishedDocs, collection, doc.id, locale, cms.localeConfig])\n\n return (\n <DocumentEditorProvider\n value={{\n projectId,\n collection,\n docRef: ref,\n draft,\n dirty,\n hasErrors,\n viewReadOnly,\n save,\n replaceDraft,\n }}\n >\n <div className={cn('flex h-full min-h-0 flex-col', viewReadOnly && 'bg-info/[0.04]')}>\n {/* Header — the back-link + collection/id line moved into the global\n breadcrumb (EC-214); this keeps only the record title + actions. */}\n <div className=\"shrink-0 border-b border-border px-4 py-3 sm:px-6\">\n <Row gap=\"3\">\n <Row gap=\"2\" align=\"center\" className=\"min-w-0\">\n <Heading level={1} size=\"h2\" className=\"truncate\">\n {singleton ? collection.form?.label ?? collection.id : title || doc.id}\n </Heading>\n {singleton ? null : <FallbackChip fallback={titleFallback} testId=\"doc-title-fallback\" />}\n </Row>\n <Spacer />\n {/* Autosave status (EC-225) — replaces the manual Save button. */}\n <Text size=\"xs\" tone=\"muted\" className=\"whitespace-nowrap\" data-testid=\"autosave-status\">\n {cms.persistError ? 'Save failed' : dirty ? 'Saving…' : 'Saved'}\n </Text>\n <DocStateBadge published={cms.isPublished(ref)} />\n {/* EC-216: open the document's live URL. Enabled once published with a\n configured frontendUrl; otherwise a disabled hint explains why. */}\n {/* EC-216 + EC-205: open the document's LIVE (published) URL. Enabled\n only once the published snapshot exists and a frontendUrl is set;\n otherwise a disabled hint explains why. Hidden for non-routable\n collections (e.g. singletons). */}\n {routableCollection ? (\n liveUrl?.href ? (\n <Button asChild variant=\"outline\" size=\"sm\" title={`Open ${liveUrl.path}`}>\n <a href={liveUrl.href} target=\"_blank\" rel=\"noreferrer\" data-testid=\"view-live\">\n <ExternalLink /> View live\n </a>\n </Button>\n ) : (\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled\n data-testid=\"view-live-disabled\"\n title={\n publishedDocs.status === 'loading'\n ? 'Loading the live URL…'\n : !cms.isPublished(ref)\n ? 'Publish to view the live page'\n : 'Set frontendUrl in elytra.config.ts to enable'\n }\n >\n <ExternalLink /> View live\n </Button>\n )\n ) : null}\n <Button\n size=\"sm\"\n onClick={() => void handlePublish()}\n disabled={hasErrors || viewReadOnly || publishState === 'pending'}\n title={\n viewReadOnly\n ? 'Switch to Draft to publish'\n : hasErrors\n ? `Fix ${errorCount} ${errorCount === 1 ? 'issue' : 'issues'} to publish`\n : undefined\n }\n >\n {publishState === 'pending' ? (\n <>\n <Loader2 className=\"animate-spin\" /> Publishing…\n </>\n ) : publishState === 'success' ? (\n <>\n <CircleCheck /> Published\n </>\n ) : (\n <>\n <Eye /> Publish\n </>\n )}\n </Button>\n {/* EC-217: a singleton is never deleted; with nothing else to show\n (an unpublished singleton) the actions menu is omitted entirely. */}\n {cms.isPublished(ref) || !singleton ? (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" size=\"icon-sm\" aria-label=\"More actions\">\n <MoreHorizontal />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {cms.isPublished(ref) ? (\n <DropdownMenuItem onClick={() => setConfirmAction('unpublish')}>\n <EyeOff /> Unpublish\n </DropdownMenuItem>\n ) : null}\n {singleton ? null : (\n <DropdownMenuItem\n data-testid=\"doc-delete\"\n className=\"text-destructive\"\n onClick={() => setConfirmAction('delete')}\n >\n <Trash2 /> Delete\n </DropdownMenuItem>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n ) : null}\n </Row>\n\n {/* Ambient locale switcher (EC-176, supersedes the per-document EC-076 one) + tabs (EC-073)\n + the Draft/Published view perspective (EC-226). */}\n <Row gap=\"3\" className=\"mt-3\" wrap>\n <LocaleSwitcher />\n <Row gap=\"1\">\n {editorTabs.map((tab) => (\n <button\n key={tab}\n type=\"button\"\n aria-pressed={tab === activeTab}\n onClick={() => setActiveTab(tab)}\n className={cn(\n 'rounded-md px-2.5 py-1 text-xs font-medium capitalize transition-colors',\n tab === activeTab ? 'bg-accent text-accent-foreground' : 'text-muted-foreground hover:bg-muted',\n )}\n >\n {tab}\n </button>\n ))}\n </Row>\n {/* EC-284: slot assignment (collections that declare aliases). Sits with\n the locale/tabs chrome since it is identity, not a content field. */}\n <AliasSelector\n collection={collection}\n doc={draft}\n siblings={cms.documentsOf(collection.id)}\n readOnly={viewReadOnly}\n onChange={(alias) =>\n setDraft((d) => {\n const next = { ...d }\n if (alias === undefined) delete next.alias\n else next.alias = alias\n return next\n })\n }\n />\n <Spacer />\n <Row gap=\"px\" className=\"rounded-md bg-muted/60 p-0.5\">\n <PerspectiveButton\n label=\"Draft\"\n active={perspective === 'draft'}\n onClick={() => setPerspective('draft')}\n />\n <PerspectiveButton\n label=\"Published\"\n active={perspective === 'published'}\n accent=\"info\"\n disabled={!published}\n title={published ? undefined : 'Publish this document to view its published version'}\n onClick={() => setPerspective('published')}\n />\n </Row>\n </Row>\n </div>\n\n {/* EC-214: an unmistakable banner whenever the read-only Published snapshot\n is in view — disabled controls + a footer notice alone read as too\n subtle. Paired with the tinted surface and the accented toggle. */}\n {viewReadOnly ? (\n <Row\n gap=\"2\"\n className=\"shrink-0 border-b border-info/30 bg-info/10 px-4 py-1.5 text-info sm:px-6\"\n data-testid=\"published-view-banner\"\n >\n <Lock className=\"size-3.5 shrink-0\" aria-hidden />\n <Text size=\"xs\" className=\"text-info\">\n Viewing the published version — read-only.\n </Text>\n <Spacer />\n <button\n type=\"button\"\n onClick={() => setPerspective('draft')}\n className=\"text-xs font-medium underline-offset-2 hover:underline\"\n >\n Switch to Draft\n </button>\n </Row>\n ) : null}\n\n {/* Body — a blocks field takes over the body with the page-builder canvas\n (which carries its own inspector sidebar, EC-188/EC-224); otherwise the\n field form sits beside the shared inspector sidebar (Versions). In\n Published view the snapshot must load before rendering — the draft is\n never shown as published (EC-226). */}\n {publishedPending ? (\n <div className=\"grid min-h-0 flex-1 place-items-center p-8\">\n <Text size=\"sm\" tone=\"muted\">\n {publishedSnapshot.status === 'loading'\n ? 'Loading the published version…'\n : 'No published version found for this document.'}\n </Text>\n </div>\n ) : canvasField ? (\n <div className=\"min-h-0 flex-1 overflow-hidden\">\n <CompositionFieldEditor\n key={`${canvasField.name}:${restoreNonce}:${perspective}`}\n field={canvasField}\n value={getValue(canvasField)}\n onChange={(v) => setValue(canvasField, v)}\n readOnly={viewReadOnly || cms.isFieldReadOnly(collection.id, canvasField)}\n trailingPanes={trailingPanes}\n />\n </div>\n ) : activeTab === REFERENCES_TAB ? (\n // EC-269: mounted only while this tab is active → reference data loads on\n // demand and is torn down on leave (no fetching during normal editing).\n <div className=\"flex min-h-0 flex-1 overflow-hidden\">\n <div className=\"min-h-0 flex-1 overflow-auto p-4 sm:p-6\">\n <div className=\"mx-auto w-full max-w-2xl\">\n <ReferencesPanel\n projectId={projectId}\n source={{ type: 'document', id: documentKey(ref) }}\n target={{ type: 'document', id: documentKey(ref) }}\n />\n </div>\n </div>\n </div>\n ) : (\n <div className=\"flex min-h-0 flex-1 overflow-hidden\">\n <div className=\"min-h-0 flex-1 overflow-auto p-4 sm:p-6\">\n <div className=\"mx-auto w-full max-w-2xl\">\n <Stack gap=\"6\">\n {groups.map((group) => (\n <Panel key={group.name}>\n <PanelHeader>\n <Text size=\"sm\" weight=\"semibold\" className=\"capitalize\">\n {group.name}\n </Text>\n </PanelHeader>\n <Stack gap=\"4\" className=\"p-4\">\n {group.fields.map((field) => {\n // Field-level read-only (the Lock badge) vs the view-level\n // read-only (Published perspective) — the control honors both.\n const fieldLevelReadOnly = cms.isFieldReadOnly(collection.id, field)\n const fieldReadOnly = viewReadOnly || fieldLevelReadOnly\n const localized = isFieldLocalized(collection, field.name)\n // Fallback visibility (EC-176): the control DISPLAYS the\n // fallback value, and this marker says so on the exact field.\n const fallback = localized\n ? displayedFieldFallback(collection, viewDoc, field.name, locale, cms.localeConfig)\n : null\n // The variant was created in this editing session (the\n // saved document doesn't have it yet): editing a\n // fallback-shown value is an explicit translation act. Moot\n // (and hidden) while viewing the read-only published snapshot.\n const newlyTranslated =\n !viewReadOnly &&\n localized &&\n hasLocaleVariant(draft, field.name, locale) &&\n !hasLocaleVariant(doc, field.name, locale)\n return (\n <Field\n key={field.name}\n className={cn(\n 'rounded-md transition-shadow',\n highlightedField === field.name &&\n 'bg-primary/5 p-2 ring-2 ring-primary/70',\n )}\n label={\n <Row gap=\"2\">\n <span>{fieldLabel(field)}</span>\n {field.validation?.required ? <span className=\"text-destructive\">*</span> : null}\n {localized ? <Badge variant=\"outline\">{locale}</Badge> : null}\n {fallback ? (\n <Badge\n variant=\"warning\"\n title={fallbackTitle(fallback)}\n data-testid={`field-fallback-${field.name}`}\n >\n showing {localeChipLabel(fallback.sourceLocale)}\n </Badge>\n ) : null}\n {newlyTranslated ? (\n <Badge variant=\"success\" data-testid={`field-translated-${field.name}`}>\n <Languages className=\"size-3\" /> translated to {localeChipLabel(locale)}\n </Badge>\n ) : null}\n {fieldLevelReadOnly ? (\n <Badge variant=\"outline\">\n <Lock className=\"size-3\" /> read-only\n </Badge>\n ) : null}\n <Spacer />\n </Row>\n }\n htmlFor={`f-${field.name}`}\n hint={\n fallback ? (\n <>\n Showing the {localeChipLabel(fallback.sourceLocale)} (fallback) value —\n edit to translate to {localeChipLabel(locale)}. Clearing the{' '}\n {localeChipLabel(locale)} text falls back again.\n </>\n ) : (\n field.form?.description\n )\n }\n error={fieldReadOnly ? undefined : errorsByField.get(field.name)}\n >\n <FieldControl\n id={`f-${field.name}`}\n field={field}\n value={getValue(field)}\n onChange={(v) => setValue(field, v)}\n readOnly={fieldReadOnly}\n />\n </Field>\n )\n })}\n </Stack>\n </Panel>\n ))}\n </Stack>\n </div>\n </div>\n <InspectorSidebar\n panes={trailingPanes}\n className=\"w-[320px] shrink-0 border-l border-border\"\n />\n </div>\n )}\n\n {/* EC-283: the always-on validation footer is retired. Validation now lives\n in the document-scoped `Issues` inspector pane (full list + jump-to-field,\n count badge on its tab), field issues stay inline, and the Publish button\n gates on errors. Read-only is announced by the top banner (EC-214). */}\n\n {/* Reference-aware unpublish/delete confirmation (EC-173). */}\n {confirmAction !== null ? (\n <ReferenceConfirmDialog\n projectId={projectId}\n action={confirmAction}\n targets={confirmTargets}\n open\n onOpenChange={(open) => {\n if (!open) setConfirmAction(null)\n }}\n onConfirm={handleConfirmedAction}\n />\n ) : null}\n </div>\n </DocumentEditorProvider>\n )\n}\n\n/**\n * A segmented-control button for the Draft/Published view toggle (EC-226). The\n * `accent` variant (EC-214) gives the active Published segment a distinct info\n * treatment, so the read-only mode is obvious at the control itself.\n */\nfunction PerspectiveButton({\n label,\n active,\n accent,\n disabled,\n title,\n onClick,\n}: {\n label: string\n active: boolean\n accent?: 'info'\n disabled?: boolean\n title?: string\n onClick: () => void\n}) {\n return (\n <button\n type=\"button\"\n aria-pressed={active}\n disabled={disabled}\n title={title}\n onClick={onClick}\n className={cn(\n 'rounded px-2.5 py-1 text-xs font-medium transition-colors disabled:opacity-40',\n active\n ? accent === 'info'\n ? 'bg-info text-info-foreground shadow-sm'\n : 'bg-background text-foreground shadow-sm'\n : 'text-muted-foreground hover:text-foreground',\n )}\n >\n {label}\n </button>\n )\n}\n\ninterface FieldGroup {\n name: string\n fields: FieldDef[]\n}\n\nfunction groupFields(fields: FieldDef[], collection: CollectionDef): FieldGroup[] {\n const order = collection.form?.groups ?? []\n const byGroup = new Map<string, FieldDef[]>()\n for (const field of fields) {\n const group = field.form?.group ?? 'fields'\n if (!byGroup.has(group)) byGroup.set(group, [])\n byGroup.get(group)!.push(field)\n }\n const names = [...byGroup.keys()].sort((a, b) => {\n const ia = order.indexOf(a)\n const ib = order.indexOf(b)\n return (ia < 0 ? 99 : ia) - (ib < 0 ? 99 : ib)\n })\n return names.map((name) => ({\n name,\n fields: byGroup.get(name)!.sort((a, b) => (a.form?.order ?? 99) - (b.form?.order ?? 99)),\n }))\n}\n\nfunction primaryTitle(\n doc: CmsDocument,\n collection: CollectionDef,\n locale: Locale,\n config: LocaleConfig,\n): string {\n const { value } = resolveField(collection, doc, collection.titleField ?? 'title', locale, config)\n return typeof value === 'string' ? value : ''\n}\n"]}
|
|
1
|
+
{"version":3,"file":"detail-editor.js","sourceRoot":"","sources":["../../../src/components/cms/detail-editor.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Link, STUDIO_PROJECT_ROUTE, studioPath, useNavigate } from '@elytracms/studio/router'\nimport {\n CircleAlert,\n CircleCheck,\n ExternalLink,\n Eye,\n EyeOff,\n History,\n Languages,\n Loader2,\n Lock,\n MoreHorizontal,\n Tag,\n Trash2,\n} from 'lucide-react'\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport {\n SIDEBAR_FIELD_GROUP,\n documentKey,\n hasAliases,\n isBlocksField,\n isFieldHidden,\n isFieldLocalized,\n isSingleton,\n resolveField,\n sidebarFields,\n staticFieldHidden,\n urlForDocument,\n} from '@elytracms/core/cms-core'\nimport type { CmsDocument, CollectionDef, FieldDef, Locale, LocaleConfig } from '@elytracms/core/cms-core'\nimport {\n Badge,\n Button,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n Field,\n Heading,\n Panel,\n PanelHeader,\n Row,\n Spacer,\n Stack,\n Text,\n toast,\n} from '@elytracms/studio/ui'\nimport { cn } from '@elytracms/studio/lib/utils'\nimport {\n LocaleSwitcher,\n displayedFieldFallback,\n hasLocaleVariant,\n localeChipLabel,\n setStudioLocale,\n} from '@elytracms/studio/lib/locale'\nimport { parseDocumentFieldPath } from '@elytracms/studio/lib/references'\nimport type { ReferenceAction } from '@elytracms/studio/lib/references'\nimport { FallbackChip, fallbackTitle } from './cell'\nimport { FieldControl } from './field-control'\nimport { CompositionFieldEditor } from '../builder/composition-field-editor'\nimport { fieldLabel, useCms } from './cms-store'\nimport { DocStateBadge } from './doc-state'\nimport { ReferenceConfirmDialog } from './reference-confirm'\nimport { ReferencesPanel } from '../references/references-panel'\nimport { InspectorSidebar } from '../inspector/inspector-sidebar'\nimport type { InspectorPane } from '../inspector/inspector-sidebar'\nimport { DocumentEditorProvider } from './document-editor-context'\nimport { VersionsPane } from './versions-pane'\nimport { IssuesPane } from './issues-pane'\nimport { DetailsPane } from './details-pane'\nimport { useSetBreadcrumb } from '../breadcrumb-context'\nimport type { BreadcrumbItem } from '../breadcrumb-context'\nimport { resolveDeploymentFrontendUrl, resolveDeploymentRoutes } from '@elytracms/studio/lib/workspace'\nimport { usePublishedDocuments } from '@elytracms/studio/lib/cms/published-documents'\n\nexport function DetailEditor({\n projectId,\n collectionId,\n documentId,\n focusPath,\n}: {\n projectId: string\n collectionId: string\n documentId: string\n /** Reference-index field path (`?field=`, EC-172): highlight + scroll to the exact field. */\n focusPath?: string\n}) {\n const cms = useCms()\n const collection = cms.getCollection(collectionId)\n const doc = cms.getDocument({ collection: collectionId, id: documentId })\n\n // EC-274: singleton opening is owned by `SingletonGate` (it resolves the lone\n // document and materializes it). The detail editor just renders the document it\n // is given by id — singletons need no special case here.\n if (!collection || !doc) {\n return (\n <div className=\"grid h-full place-items-center p-8\">\n <Stack gap=\"3\" align=\"center\" className=\"text-center\">\n <Heading level={2} size=\"h2\">\n Document not found\n </Heading>\n <Link\n to={STUDIO_PROJECT_ROUTE}\n params={{ projectId, _splat: studioPath.cmsCollection(collectionId) }}\n className=\"text-sm text-primary hover:underline\"\n >\n Back to {collectionId}\n </Link>\n </Stack>\n </div>\n )\n }\n\n return (\n <EditorBody\n key={`${collectionId}/${documentId}`}\n projectId={projectId}\n collection={collection}\n doc={doc}\n focusPath={focusPath}\n />\n )\n}\n\n/** The loaded state of a document's pinned published snapshot (EC-226). */\ntype PublishedSnapshot =\n | { status: 'loading' }\n | { status: 'ready'; doc: CmsDocument }\n | { status: 'missing' }\n\nfunction EditorBody({\n projectId,\n collection,\n doc,\n focusPath,\n}: {\n projectId: string\n collection: CollectionDef\n doc: CmsDocument\n focusPath?: string\n}) {\n const cms = useCms()\n const navigate = useNavigate()\n // EC-217: a singleton collection has no list — there is nowhere to go \"back\"\n // to, and its one document is fixed (never deleted). The header drops the\n // back-crumb/id line and the Delete action accordingly.\n const singleton = isSingleton(collection)\n const [draft, setDraft] = useState<CmsDocument>(() => structuredClone(doc))\n // The studio's ambient active locale (EC-176): the form displays and edits\n // exactly this locale — switched via the shared LocaleSwitcher, never per field.\n const locale = cms.activeLocale\n // Bumped when a version restore replaces the draft out-of-band, to remount the\n // (uncontrolled) canvas editor from the restored value (EC-224).\n const [restoreNonce, setRestoreNonce] = useState(0)\n // EC-173: unpublish/delete go through the reference-aware confirmation.\n const [confirmAction, setConfirmAction] = useState<ReferenceAction | null>(null)\n // Stable so the document-editor context value (EC-224) doesn't churn each render.\n const ref = useMemo(() => ({ collection: collection.id, id: doc.id }), [collection.id, doc.id])\n const confirmTargets = useMemo(\n () => [{ collection: collection.id, id: doc.id }],\n [collection.id, doc.id],\n )\n\n // EC-226: the draft/published VIEW perspective. Draft = the editable working\n // draft; Published = the pinned published snapshot, rendered read-only. Only\n // meaningful when the document is published.\n const published = cms.isPublished(ref)\n const [perspective, setPerspective] = useState<'draft' | 'published'>('draft')\n const [publishedSnapshot, setPublishedSnapshot] = useState<PublishedSnapshot>({ status: 'loading' })\n // Snap back to Draft if the document is unpublished while viewing Published.\n useEffect(() => {\n if (!published) setPerspective('draft')\n }, [published])\n // Load the pinned published snapshot when viewing Published (fresh each switch,\n // so it reflects the current pin after a re-publish). `loadDocumentVersions` is\n // a stable callback, so this only re-runs on a perspective/ref change.\n const loadVersions = cms.loadDocumentVersions\n useEffect(() => {\n if (perspective !== 'published') return\n let cancelled = false\n setPublishedSnapshot({ status: 'loading' })\n void (async () => {\n const view = await loadVersions(ref)\n if (cancelled) return\n const pinned =\n view.publishedVersion !== undefined\n ? view.versions.find((v) => v.version === view.publishedVersion)?.snapshot\n : undefined\n setPublishedSnapshot(pinned ? { status: 'ready', doc: pinned } : { status: 'missing' })\n })()\n return () => {\n cancelled = true\n }\n }, [perspective, ref, loadVersions])\n\n // The whole fieldset is read-only when viewing Published. The form/canvas\n // render the pinned snapshot ONLY once it has loaded — never the draft, which\n // must not be presented as published; until then the body shows a placeholder.\n const viewReadOnly = perspective === 'published'\n const viewDoc =\n viewReadOnly && publishedSnapshot.status === 'ready' ? publishedSnapshot.doc : draft\n const publishedPending = viewReadOnly && publishedSnapshot.status !== 'ready'\n\n const dirty = JSON.stringify(draft) !== JSON.stringify(doc)\n const issues = useMemo(() => cms.validate(draft), [cms, draft])\n const errorCount = issues.filter((i) => i.severity === 'error').length\n const hasErrors = errorCount > 0\n\n // --- Autosave (EC-225) -----------------------------------------------------\n // The draft persists automatically 1s after the last edit; there is no manual\n // Save button. Refs let the unmount flush read the latest values without\n // re-subscribing the effects.\n const draftRef = useRef(draft)\n draftRef.current = draft\n const dirtyRef = useRef(dirty)\n dirtyRef.current = dirty\n const cmsRef = useRef(cms)\n cmsRef.current = cms\n\n useEffect(() => {\n if (!dirty) return\n const timer = window.setTimeout(() => cmsRef.current.saveDocument(draftRef.current), 1000)\n return () => window.clearTimeout(timer)\n }, [dirty, draft])\n\n // Flush a still-pending edit on unmount (navigating away inside the debounce\n // window) so nothing is lost. Unmount-only — refs carry the latest state.\n useEffect(\n () => () => {\n if (dirtyRef.current) cmsRef.current.saveDocument(draftRef.current)\n },\n [],\n )\n const errorsByField = useMemo(() => {\n const map = new Map<string, string>()\n for (const issue of issues) {\n // validateDocument populates meta.field for field-level issues (works for\n // both `values` and `localized/<locale>` paths, unlike positional indexing).\n const field = issue.meta?.field\n if (typeof field === 'string' && !map.has(field)) map.set(field, issue.message)\n }\n return map\n }, [issues])\n\n const tabs = collection.form?.tabs ?? ['main']\n // EC-269: References gets its own dedicated, visibility-gated tab — it mounts\n // (and loads) only when selected, and unmounts on leave, so normal editing\n // never triggers reference fetching. Appended after the collection's content tabs.\n const REFERENCES_TAB = 'references'\n const editorTabs = [...tabs, REFERENCES_TAB]\n const [activeTab, setActiveTab] = useState(tabs[0]!)\n // EC-285: the reserved `sidebar` group is document-level metadata (slug, author…)\n // — it renders in the Details inspector pane, not as a content tab, so it is\n // excluded from the tab fields here and collected once below.\n const sidebarFieldDefs = useMemo(() => sidebarFields(collection), [collection])\n // EC-273: only STATICALLY hidden fields (`hidden: true`) are structurally\n // excluded here; a conditionally (predicate) hidden field stays in the tab and\n // is evaluated per-render against the current values (it may show or hide as the\n // editor types).\n const tabFields = collection.fields.filter(\n (f) =>\n (f.form?.tab ?? tabs[0]) === activeTab &&\n !staticFieldHidden(f) &&\n f.form?.group !== SIDEBAR_FIELD_GROUP,\n )\n const groups = groupFields(tabFields, collection)\n // EC-188 (AD-12): a composition (`blocks`) field is a special content feature,\n // not a field-row — it takes over its tab with the full page-builder canvas.\n // Convention: such a field lives on its own dedicated fieldset tab.\n const canvasField = tabFields.find(isBlocksField)\n\n const [highlightedField, setHighlightedField] = useState<string | null>(null)\n // EC-285: the form-path inspector's active pane, controlled so a jump to a\n // `sidebar`-group field can open the Details pane (where it renders). Undefined\n // = uncontrolled (the sidebar defaults to its first pane).\n const [inspectorPaneId, setInspectorPaneId] = useState<string>()\n // Focus a field by name: switch to its tab (and locale, when given), scroll the\n // control into view, and ring-highlight it. Shared by the reference deep-link\n // (`focusPath`, EC-172) and the Issues pane's jump-to-field (EC-283).\n const focusTimersRef = useRef<number[]>([])\n const focusField = useCallback(\n (fieldName: string, localeHint?: string) => {\n const field = collection.fields.find((f) => f.name === fieldName)\n if (!field) return\n // EC-285: a `sidebar`-group field renders in the Details inspector pane, not\n // a content tab — open that pane instead of switching tabs.\n if (field.form?.group === SIDEBAR_FIELD_GROUP) {\n setInspectorPaneId('details')\n } else {\n const fieldTabs = collection.form?.tabs ?? ['main']\n setActiveTab(field.form?.tab ?? fieldTabs[0]!)\n }\n if (localeHint !== undefined && cms.localeConfig.locales.includes(localeHint)) {\n setStudioLocale(localeHint)\n }\n setHighlightedField(field.name)\n // Clear any timers from a prior jump so back-to-back jumps don't fight.\n focusTimersRef.current.forEach((t) => window.clearTimeout(t))\n const scrollTimer = window.setTimeout(() => {\n // Some controls (relation/asset pickers) don't render the input id —\n // the field label (`htmlFor`) is always present.\n const control =\n document.getElementById(`f-${field.name}`) ??\n document.querySelector(`label[for=\"${CSS.escape(`f-${field.name}`)}\"]`)\n control?.scrollIntoView({ block: 'center', behavior: 'smooth' })\n }, 60)\n const clearTimer = window.setTimeout(() => setHighlightedField(null), 3200)\n focusTimersRef.current = [scrollTimer, clearTimer]\n },\n [collection, cms.localeConfig],\n )\n useEffect(() => () => focusTimersRef.current.forEach((t) => window.clearTimeout(t)), [])\n\n // Reference deep links (EC-172): `?field=<index path>` pinpoints the exact field.\n useEffect(() => {\n if (!focusPath) return\n const parsed = parseDocumentFieldPath(focusPath)\n if (!parsed) return\n focusField(parsed.field, parsed.locale)\n }, [focusPath, focusField])\n\n function getValue(field: FieldDef): unknown {\n // EC-226: read from the active VIEW (the draft, or the pinned published\n // snapshot when viewing Published) — never directly from `draft`.\n if (isFieldLocalized(collection, field.name)) {\n // Display the explicit variant when it exists, else the EC-018 fallback\n // value — labeled as such by the field's fallback marker (EC-176), so a\n // German view shows the English text visibly, never an unexplained blank.\n const explicit = viewDoc.localized?.[locale]?.[field.name]\n if (explicit !== undefined) return explicit\n return resolveField(collection, viewDoc, field.name, locale, cms.localeConfig).value\n }\n return viewDoc.values[field.name]\n }\n\n function setValue(field: FieldDef, value: unknown) {\n setDraft((d) => {\n if (isFieldLocalized(collection, field.name)) {\n const perLocale = { ...(d.localized?.[locale] ?? {}) }\n if (value === undefined) delete perLocale[field.name]\n else perLocale[field.name] = value\n return { ...d, localized: { ...d.localized, [locale]: perLocale } }\n }\n const values = { ...d.values }\n if (value === undefined) delete values[field.name]\n else values[field.name] = value\n return { ...d, values }\n })\n }\n\n // EC-273: conditional-visibility context — the draft's values for the active\n // locale, against which a field's `hidden(values)` predicate is evaluated. A\n // hidden field's row is omitted (and it is not validated). Recomputed as the\n // draft changes, so a field shows/hides live as the editor types.\n const conditionValues = { ...draft.values, ...(draft.localized?.[locale] ?? {}) }\n const isHidden = (field: FieldDef) => isFieldHidden(field, { values: conditionValues })\n const visibleSidebarFields = sidebarFieldDefs.filter((f) => !isHidden(f))\n\n // One document field row (label + fallback/translation/read-only badges + the\n // control), shared by the content groups and the EC-285 Details pane so a\n // sidebar field renders identically — same control, validation, localization,\n // and EC-283 highlight/jump target — wherever it surfaces. Returns null when the\n // field is conditionally hidden (EC-273).\n function renderFieldRow(field: FieldDef) {\n if (isHidden(field)) return null\n // Field-level read-only (the Lock badge) vs the view-level read-only\n // (Published perspective) — the control honors both.\n const fieldLevelReadOnly = cms.isFieldReadOnly(collection.id, field)\n const fieldReadOnly = viewReadOnly || fieldLevelReadOnly\n const localized = isFieldLocalized(collection, field.name)\n // Fallback visibility (EC-176): the control DISPLAYS the fallback value, and\n // this marker says so on the exact field.\n const fallback = localized\n ? displayedFieldFallback(collection, viewDoc, field.name, locale, cms.localeConfig)\n : null\n // The variant was created in this editing session (the saved document doesn't\n // have it yet): editing a fallback-shown value is an explicit translation act.\n // Moot (and hidden) while viewing the read-only published snapshot.\n const newlyTranslated =\n !viewReadOnly &&\n localized &&\n hasLocaleVariant(draft, field.name, locale) &&\n !hasLocaleVariant(doc, field.name, locale)\n return (\n <Field\n key={field.name}\n className={cn(\n 'rounded-md transition-shadow',\n highlightedField === field.name && 'bg-primary/5 p-2 ring-2 ring-primary/70',\n )}\n label={\n <Row gap=\"2\">\n <span>{fieldLabel(field)}</span>\n {field.validation?.required ? <span className=\"text-destructive\">*</span> : null}\n {localized ? <Badge variant=\"outline\">{locale}</Badge> : null}\n {fallback ? (\n <Badge\n variant=\"warning\"\n title={fallbackTitle(fallback)}\n data-testid={`field-fallback-${field.name}`}\n >\n showing {localeChipLabel(fallback.sourceLocale)}\n </Badge>\n ) : null}\n {newlyTranslated ? (\n <Badge variant=\"success\" data-testid={`field-translated-${field.name}`}>\n <Languages className=\"size-3\" /> translated to {localeChipLabel(locale)}\n </Badge>\n ) : null}\n {fieldLevelReadOnly ? (\n <Badge variant=\"outline\">\n <Lock className=\"size-3\" /> read-only\n </Badge>\n ) : null}\n <Spacer />\n </Row>\n }\n htmlFor={`f-${field.name}`}\n hint={\n fallback ? (\n <>\n Showing the {localeChipLabel(fallback.sourceLocale)} (fallback) value — edit to\n translate to {localeChipLabel(locale)}. Clearing the {localeChipLabel(locale)} text\n falls back again.\n </>\n ) : (\n field.form?.description\n )\n }\n error={fieldReadOnly ? undefined : errorsByField.get(field.name)}\n >\n <FieldControl\n id={`f-${field.name}`}\n field={field}\n value={getValue(field)}\n onChange={(v) => setValue(field, v)}\n readOnly={fieldReadOnly}\n />\n </Field>\n )\n }\n\n function save() {\n cms.saveDocument(draft)\n }\n\n // EC-224: a version restore swaps the working draft for an older snapshot; the\n // open editor adopts it so the form/canvas re-render from the restored content\n // (the operation already persisted it, so it lands clean/non-dirty).\n function replaceDraft(next: CmsDocument) {\n setDraft(next)\n // The canvas editor is uncontrolled after mount (it builds its graph once and\n // lifts edits OUT). A restore replaces the draft from outside, so bump the\n // nonce to REMOUNT the canvas from the restored value — otherwise it keeps the\n // pre-restore tree and the next edit would clobber the restore.\n setRestoreNonce((n) => n + 1)\n }\n\n // The frame-owned `Versions` pane (EC-224) — appended after any view-supplied\n // pane (the canvas's `Properties`). One instance feeds both the form view's\n // sidebar and the canvas view's sidebar.\n const versionsPane = useMemo<InspectorPane>(\n () => ({\n id: 'versions',\n label: 'Versions',\n icon: <History className=\"size-3.5\" />,\n render: () => <VersionsPane />,\n }),\n [],\n )\n // The frame-owned `Issues` pane (EC-283) — the document-scoped validation\n // surface that replaces the always-on footer band. The tab carries a count\n // badge (error- vs warning-toned) so a non-zero count is discoverable from\n // any tab; document-level issues (e.g. EC-260 nesting-depth) live only here.\n const issuesPane = useMemo<InspectorPane>(\n () => ({\n id: 'issues',\n label: 'Issues',\n icon: <CircleAlert className=\"size-3.5\" />,\n badge:\n issues.length === 0 ? undefined : (\n <Badge\n variant={errorCount > 0 ? 'error' : 'warning'}\n className=\"px-1.5 py-0 leading-none\"\n >\n {issues.length}\n </Badge>\n ),\n render: () => (\n <IssuesPane issues={issues} collection={collection} onJumpToField={focusField} />\n ),\n }),\n [issues, errorCount, collection, focusField],\n )\n // EC-284 + EC-285: the document-metadata pane — slot assignment (EC-284) and/or\n // the document-level `sidebar`-group fields (EC-285). Present only when the\n // collection has either, so it never adds an empty tab elsewhere. First in the\n // order, so a slotted / sidebar-bearing document opens straight to it. Not\n // memoized: its render closes over per-render edit state (draft, highlight,\n // field errors) via `renderFieldRow`, and the inspector re-renders with the rest\n // of the editor anyway, so a stable pane identity would buy nothing here.\n const detailsPane: InspectorPane | null =\n hasAliases(collection) || visibleSidebarFields.length > 0\n ? {\n id: 'details',\n label: 'Details',\n icon: <Tag className=\"size-3.5\" />,\n render: () => (\n <DetailsPane\n collection={collection}\n doc={draft}\n siblings={cms.documentsOf(collection.id)}\n readOnly={viewReadOnly}\n fields={visibleSidebarFields}\n renderField={renderFieldRow}\n onAliasChange={(alias) =>\n setDraft((d) => {\n const next = { ...d }\n if (alias === undefined) delete next.alias\n else next.alias = alias\n return next\n })\n }\n />\n ),\n }\n : null\n const trailingPanes = detailsPane\n ? [detailsPane, versionsPane, issuesPane]\n : [versionsPane, issuesPane]\n\n // EC-268: the Publish button is its own indicator — pending while the publish\n // round-trips, a brief success, and an error toast if it rejects at transport.\n const [publishState, setPublishState] = useState<'idle' | 'pending' | 'success'>('idle')\n\n async function handlePublish() {\n // Capture the latest edit before the snapshot in case Publish is clicked\n // inside the autosave debounce window; the serial persister queue runs the\n // upsert before the publish so the snapshot is the saved draft (EC-225).\n if (dirty) save()\n // Publish snapshots the draft as a version and pins it (EC-224). The live\n // row stays a continuous draft — published-ness is the version pointer\n // (`cms.isPublished`). Pre-gated by `disabled={hasErrors}`; the optimistic\n // flip reconciles against the backend (EC-225), so a logical rejection the\n // gate doesn't cover (schema divergence) self-corrects the badge. A hard\n // failure (transport) rejects the flush — surface it loudly (EC-268).\n setPublishState('pending')\n try {\n await cms.publishDocument(ref)\n setPublishState('success')\n setTimeout(() => setPublishState('idle'), 1800)\n } catch (error) {\n setPublishState('idle')\n toast.error(error instanceof Error ? `Publish failed: ${error.message}` : 'Publish failed.')\n }\n }\n\n function handleConfirmedAction() {\n if (confirmAction === 'unpublish') {\n setConfirmAction(null)\n void cms.unpublishDocument(ref)\n return\n }\n if (confirmAction === 'delete') {\n setConfirmAction(null)\n cms.deleteDocument(ref)\n void navigate({\n to: STUDIO_PROJECT_ROUTE,\n params: { projectId, _splat: studioPath.cmsCollection(collection.id) },\n })\n }\n }\n\n // While the published snapshot is pending, don't derive the title from the\n // draft (it must not read as the published title) — fall back to the id.\n const title = publishedPending ? '' : primaryTitle(viewDoc, collection, locale, cms.localeConfig)\n const titleFallback = publishedPending\n ? null\n : displayedFieldFallback(\n collection,\n viewDoc,\n collection.titleField ?? 'title',\n locale,\n cms.localeConfig,\n )\n\n // EC-214: the document is the active record — contribute the collection (a\n // link back to its list) and the document title to the global header\n // breadcrumb, replacing the editor's own back-link + collection/id line. A\n // singleton has no list, so it contributes a single, non-linked crumb. The\n // title tracks the live draft so a rename updates the crumb immediately.\n const breadcrumbItems = useMemo<BreadcrumbItem[]>(() => {\n const collectionLabel = collection.form?.label ?? collection.id\n if (singleton) return [{ label: collectionLabel }]\n const docTitle = primaryTitle(draft, collection, locale, cms.localeConfig) || doc.id\n return [\n {\n label: collectionLabel,\n to: STUDIO_PROJECT_ROUTE,\n params: { projectId, _splat: studioPath.cmsCollection(collection.id) },\n },\n { label: docTitle },\n ]\n }, [singleton, collection, draft, locale, cms.localeConfig, doc.id, projectId])\n useSetBreadcrumb(breadcrumbItems)\n\n // EC-205/EC-216: the LIVE URL derives strictly from PUBLISHED data — the\n // document's pinned published snapshot and its published ancestors — never the\n // draft (an unpublished slug/parent edit must not leak into the live URL). The\n // pool is exactly what the live site serves, so a published doc resolves to the\n // URL visitors actually get; `undefined` until the doc is published (and the\n // pool has loaded). The collection being routable gates the disabled hint below.\n const publishedDocs = usePublishedDocuments(cms.projectId, collection.id)\n const routableCollection = useMemo(\n () => resolveDeploymentRoutes().some((route) => route.document?.collection === collection.id),\n [collection.id],\n )\n const liveUrl = useMemo(() => {\n const published = publishedDocs.byId.get(doc.id)\n if (!published) return undefined\n return urlForDocument(\n {\n routes: resolveDeploymentRoutes(),\n frontendUrl: resolveDeploymentFrontendUrl(),\n localeConfig: cms.localeConfig,\n },\n collection,\n published,\n { siblings: [...publishedDocs.byId.values()], locale },\n )\n }, [publishedDocs, collection, doc.id, locale, cms.localeConfig])\n\n return (\n <DocumentEditorProvider\n value={{\n projectId,\n collection,\n docRef: ref,\n draft,\n dirty,\n hasErrors,\n viewReadOnly,\n save,\n replaceDraft,\n }}\n >\n <div className={cn('flex h-full min-h-0 flex-col', viewReadOnly && 'bg-info/[0.04]')}>\n {/* Header — the back-link + collection/id line moved into the global\n breadcrumb (EC-214); this keeps only the record title + actions. */}\n <div className=\"shrink-0 border-b border-border px-4 py-3 sm:px-6\">\n <Row gap=\"3\">\n <Row gap=\"2\" align=\"center\" className=\"min-w-0\">\n <Heading level={1} size=\"h2\" className=\"truncate\">\n {singleton ? collection.form?.label ?? collection.id : title || doc.id}\n </Heading>\n {singleton ? null : <FallbackChip fallback={titleFallback} testId=\"doc-title-fallback\" />}\n </Row>\n <Spacer />\n {/* Autosave status (EC-225) — replaces the manual Save button. */}\n <Text size=\"xs\" tone=\"muted\" className=\"whitespace-nowrap\" data-testid=\"autosave-status\">\n {cms.persistError ? 'Save failed' : dirty ? 'Saving…' : 'Saved'}\n </Text>\n <DocStateBadge published={cms.isPublished(ref)} />\n {/* EC-216: open the document's live URL. Enabled once published with a\n configured frontendUrl; otherwise a disabled hint explains why. */}\n {/* EC-216 + EC-205: open the document's LIVE (published) URL. Enabled\n only once the published snapshot exists and a frontendUrl is set;\n otherwise a disabled hint explains why. Hidden for non-routable\n collections (e.g. singletons). */}\n {routableCollection ? (\n liveUrl?.href ? (\n <Button asChild variant=\"outline\" size=\"sm\" title={`Open ${liveUrl.path}`}>\n <a href={liveUrl.href} target=\"_blank\" rel=\"noreferrer\" data-testid=\"view-live\">\n <ExternalLink /> View live\n </a>\n </Button>\n ) : (\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled\n data-testid=\"view-live-disabled\"\n title={\n publishedDocs.status === 'loading'\n ? 'Loading the live URL…'\n : !cms.isPublished(ref)\n ? 'Publish to view the live page'\n : 'Set frontendUrl in elytra.config.ts to enable'\n }\n >\n <ExternalLink /> View live\n </Button>\n )\n ) : null}\n <Button\n size=\"sm\"\n onClick={() => void handlePublish()}\n disabled={hasErrors || viewReadOnly || publishState === 'pending'}\n title={\n viewReadOnly\n ? 'Switch to Draft to publish'\n : hasErrors\n ? `Fix ${errorCount} ${errorCount === 1 ? 'issue' : 'issues'} to publish`\n : undefined\n }\n >\n {publishState === 'pending' ? (\n <>\n <Loader2 className=\"animate-spin\" /> Publishing…\n </>\n ) : publishState === 'success' ? (\n <>\n <CircleCheck /> Published\n </>\n ) : (\n <>\n <Eye /> Publish\n </>\n )}\n </Button>\n {/* EC-217: a singleton is never deleted; with nothing else to show\n (an unpublished singleton) the actions menu is omitted entirely. */}\n {cms.isPublished(ref) || !singleton ? (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" size=\"icon-sm\" aria-label=\"More actions\">\n <MoreHorizontal />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {cms.isPublished(ref) ? (\n <DropdownMenuItem onClick={() => setConfirmAction('unpublish')}>\n <EyeOff /> Unpublish\n </DropdownMenuItem>\n ) : null}\n {singleton ? null : (\n <DropdownMenuItem\n data-testid=\"doc-delete\"\n className=\"text-destructive\"\n onClick={() => setConfirmAction('delete')}\n >\n <Trash2 /> Delete\n </DropdownMenuItem>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n ) : null}\n </Row>\n\n {/* Ambient locale switcher (EC-176, supersedes the per-document EC-076 one) + tabs (EC-073)\n + the Draft/Published view perspective (EC-226). */}\n <Row gap=\"3\" className=\"mt-3\" wrap>\n <LocaleSwitcher />\n <Row gap=\"1\">\n {editorTabs.map((tab) => (\n <button\n key={tab}\n type=\"button\"\n aria-pressed={tab === activeTab}\n onClick={() => setActiveTab(tab)}\n className={cn(\n 'rounded-md px-2.5 py-1 text-xs font-medium capitalize transition-colors',\n tab === activeTab ? 'bg-accent text-accent-foreground' : 'text-muted-foreground hover:bg-muted',\n )}\n >\n {tab}\n </button>\n ))}\n </Row>\n <Spacer />\n <Row gap=\"px\" className=\"rounded-md bg-muted/60 p-0.5\">\n <PerspectiveButton\n label=\"Draft\"\n active={perspective === 'draft'}\n onClick={() => setPerspective('draft')}\n />\n <PerspectiveButton\n label=\"Published\"\n active={perspective === 'published'}\n accent=\"info\"\n disabled={!published}\n title={published ? undefined : 'Publish this document to view its published version'}\n onClick={() => setPerspective('published')}\n />\n </Row>\n </Row>\n </div>\n\n {/* EC-214: an unmistakable banner whenever the read-only Published snapshot\n is in view — disabled controls + a footer notice alone read as too\n subtle. Paired with the tinted surface and the accented toggle. */}\n {viewReadOnly ? (\n <Row\n gap=\"2\"\n className=\"shrink-0 border-b border-info/30 bg-info/10 px-4 py-1.5 text-info sm:px-6\"\n data-testid=\"published-view-banner\"\n >\n <Lock className=\"size-3.5 shrink-0\" aria-hidden />\n <Text size=\"xs\" className=\"text-info\">\n Viewing the published version — read-only.\n </Text>\n <Spacer />\n <button\n type=\"button\"\n onClick={() => setPerspective('draft')}\n className=\"text-xs font-medium underline-offset-2 hover:underline\"\n >\n Switch to Draft\n </button>\n </Row>\n ) : null}\n\n {/* Body — a blocks field takes over the body with the page-builder canvas\n (which carries its own inspector sidebar, EC-188/EC-224); otherwise the\n field form sits beside the shared inspector sidebar (Versions). In\n Published view the snapshot must load before rendering — the draft is\n never shown as published (EC-226). */}\n {publishedPending ? (\n <div className=\"grid min-h-0 flex-1 place-items-center p-8\">\n <Text size=\"sm\" tone=\"muted\">\n {publishedSnapshot.status === 'loading'\n ? 'Loading the published version…'\n : 'No published version found for this document.'}\n </Text>\n </div>\n ) : canvasField ? (\n <div className=\"min-h-0 flex-1 overflow-hidden\">\n <CompositionFieldEditor\n key={`${canvasField.name}:${restoreNonce}:${perspective}`}\n field={canvasField}\n value={getValue(canvasField)}\n onChange={(v) => setValue(canvasField, v)}\n readOnly={viewReadOnly || cms.isFieldReadOnly(collection.id, canvasField)}\n trailingPanes={trailingPanes}\n />\n </div>\n ) : activeTab === REFERENCES_TAB ? (\n // EC-269: mounted only while this tab is active → reference data loads on\n // demand and is torn down on leave (no fetching during normal editing).\n <div className=\"flex min-h-0 flex-1 overflow-hidden\">\n <div className=\"min-h-0 flex-1 overflow-auto p-4 sm:p-6\">\n <div className=\"mx-auto w-full max-w-2xl\">\n <ReferencesPanel\n projectId={projectId}\n source={{ type: 'document', id: documentKey(ref) }}\n target={{ type: 'document', id: documentKey(ref) }}\n />\n </div>\n </div>\n </div>\n ) : (\n <div className=\"flex min-h-0 flex-1 overflow-hidden\">\n <div className=\"min-h-0 flex-1 overflow-auto p-4 sm:p-6\">\n <div className=\"mx-auto w-full max-w-2xl\">\n <Stack gap=\"6\">\n {groups.map((group) => {\n // EC-273: drop a fieldset whose every field is conditionally hidden,\n // so the form never shows an empty panel header.\n const visible = group.fields.filter((f) => !isHidden(f))\n if (visible.length === 0) return null\n return (\n <Panel key={group.name}>\n <PanelHeader>\n <Text size=\"sm\" weight=\"semibold\" className=\"capitalize\">\n {group.name}\n </Text>\n </PanelHeader>\n <Stack gap=\"4\" className=\"p-4\">\n {visible.map(renderFieldRow)}\n </Stack>\n </Panel>\n )\n })}\n </Stack>\n </div>\n </div>\n <InspectorSidebar\n panes={trailingPanes}\n activeId={inspectorPaneId}\n onActiveChange={setInspectorPaneId}\n className=\"w-[320px] shrink-0 border-l border-border\"\n />\n </div>\n )}\n\n {/* EC-283: the always-on validation footer is retired. Validation now lives\n in the document-scoped `Issues` inspector pane (full list + jump-to-field,\n count badge on its tab), field issues stay inline, and the Publish button\n gates on errors. Read-only is announced by the top banner (EC-214). */}\n\n {/* Reference-aware unpublish/delete confirmation (EC-173). */}\n {confirmAction !== null ? (\n <ReferenceConfirmDialog\n projectId={projectId}\n action={confirmAction}\n targets={confirmTargets}\n open\n onOpenChange={(open) => {\n if (!open) setConfirmAction(null)\n }}\n onConfirm={handleConfirmedAction}\n />\n ) : null}\n </div>\n </DocumentEditorProvider>\n )\n}\n\n/**\n * A segmented-control button for the Draft/Published view toggle (EC-226). The\n * `accent` variant (EC-214) gives the active Published segment a distinct info\n * treatment, so the read-only mode is obvious at the control itself.\n */\nfunction PerspectiveButton({\n label,\n active,\n accent,\n disabled,\n title,\n onClick,\n}: {\n label: string\n active: boolean\n accent?: 'info'\n disabled?: boolean\n title?: string\n onClick: () => void\n}) {\n return (\n <button\n type=\"button\"\n aria-pressed={active}\n disabled={disabled}\n title={title}\n onClick={onClick}\n className={cn(\n 'rounded px-2.5 py-1 text-xs font-medium transition-colors disabled:opacity-40',\n active\n ? accent === 'info'\n ? 'bg-info text-info-foreground shadow-sm'\n : 'bg-background text-foreground shadow-sm'\n : 'text-muted-foreground hover:text-foreground',\n )}\n >\n {label}\n </button>\n )\n}\n\ninterface FieldGroup {\n name: string\n fields: FieldDef[]\n}\n\nfunction groupFields(fields: FieldDef[], collection: CollectionDef): FieldGroup[] {\n const order = collection.form?.groups ?? []\n const byGroup = new Map<string, FieldDef[]>()\n for (const field of fields) {\n const group = field.form?.group ?? 'fields'\n if (!byGroup.has(group)) byGroup.set(group, [])\n byGroup.get(group)!.push(field)\n }\n const names = [...byGroup.keys()].sort((a, b) => {\n const ia = order.indexOf(a)\n const ib = order.indexOf(b)\n return (ia < 0 ? 99 : ia) - (ib < 0 ? 99 : ib)\n })\n return names.map((name) => ({\n name,\n fields: byGroup.get(name)!.sort((a, b) => (a.form?.order ?? 99) - (b.form?.order ?? 99)),\n }))\n}\n\nfunction primaryTitle(\n doc: CmsDocument,\n collection: CollectionDef,\n locale: Locale,\n config: LocaleConfig,\n): string {\n const { value } = resolveField(collection, doc, collection.titleField ?? 'title', locale, config)\n return typeof value === 'string' ? value : ''\n}\n"]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { CmsDocument, CollectionDef, FieldDef } from '@elytracms/core/cms-core';
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* EC-284 + EC-285 — document-level metadata pane (the right inspector). Two
|
|
5
|
+
* optional regions:
|
|
6
|
+
*
|
|
7
|
+
* 1. **Slot** (EC-284): a stable, named handle the site uses to find this document
|
|
8
|
+
* (the main menu, the footer menu…) instead of which exact entry it is — shown
|
|
9
|
+
* only when the collection declares alias slots.
|
|
10
|
+
* 2. **Sidebar fields** (EC-285): the document's `sidebar`-group fields (slug,
|
|
11
|
+
* author, publish date…) — document-level properties an editor sets *about* the
|
|
12
|
+
* document rather than as body content. Rendered via the detail editor's own
|
|
13
|
+
* field-row renderer, so they behave identically to a content field.
|
|
14
|
+
*
|
|
15
|
+
* Both are identity/metadata, not content, so they live here — off the content
|
|
16
|
+
* tabs. The empty state shows only when there is neither a slot nor a sidebar field.
|
|
17
|
+
*/
|
|
18
|
+
export declare function DetailsPane({ collection, doc, siblings, readOnly, fields, renderField, onAliasChange, }: {
|
|
19
|
+
collection: CollectionDef;
|
|
20
|
+
doc: CmsDocument;
|
|
21
|
+
/** The other documents in this collection (to show which slots are taken). */
|
|
22
|
+
siblings: readonly CmsDocument[];
|
|
23
|
+
readOnly?: boolean;
|
|
24
|
+
/** The collection's `sidebar`-group fields, in order (EC-285). */
|
|
25
|
+
fields: readonly FieldDef[];
|
|
26
|
+
/** Render one field row — shared with the content groups so behaviour matches. */
|
|
27
|
+
renderField: (field: FieldDef) => ReactNode;
|
|
28
|
+
onAliasChange: (alias: string | undefined) => void;
|
|
29
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { declaredAliases } from '@elytracms/core/cms-core';
|
|
3
|
+
import { Select, Separator, Stack, Text } from '@elytracms/studio/ui';
|
|
4
|
+
/**
|
|
5
|
+
* EC-284 + EC-285 — document-level metadata pane (the right inspector). Two
|
|
6
|
+
* optional regions:
|
|
7
|
+
*
|
|
8
|
+
* 1. **Slot** (EC-284): a stable, named handle the site uses to find this document
|
|
9
|
+
* (the main menu, the footer menu…) instead of which exact entry it is — shown
|
|
10
|
+
* only when the collection declares alias slots.
|
|
11
|
+
* 2. **Sidebar fields** (EC-285): the document's `sidebar`-group fields (slug,
|
|
12
|
+
* author, publish date…) — document-level properties an editor sets *about* the
|
|
13
|
+
* document rather than as body content. Rendered via the detail editor's own
|
|
14
|
+
* field-row renderer, so they behave identically to a content field.
|
|
15
|
+
*
|
|
16
|
+
* Both are identity/metadata, not content, so they live here — off the content
|
|
17
|
+
* tabs. The empty state shows only when there is neither a slot nor a sidebar field.
|
|
18
|
+
*/
|
|
19
|
+
export function DetailsPane({ collection, doc, siblings, readOnly, fields, renderField, onAliasChange, }) {
|
|
20
|
+
const slots = declaredAliases(collection);
|
|
21
|
+
const hasSlots = slots.length > 0;
|
|
22
|
+
const hasFields = fields.length > 0;
|
|
23
|
+
return (_jsxs(Stack, { gap: "4", className: "p-3", children: [hasSlots ? (_jsxs(Stack, { gap: "1", children: [_jsx(Text, { size: "xs", weight: "semibold", children: "Slot" }), _jsxs(Select, { value: doc.alias ?? '', disabled: readOnly, "aria-label": "Slot", "data-testid": "alias-select", onChange: (e) => onAliasChange(e.target.value === '' ? undefined : e.target.value), children: [_jsx("option", { value: "", children: "\u2014 No slot \u2014" }), slots.map((slot) => {
|
|
24
|
+
const takenByOther = siblings.some((s) => s.id !== doc.id && s.alias === slot);
|
|
25
|
+
const blocked = takenByOther && doc.alias !== slot;
|
|
26
|
+
return (_jsxs("option", { value: slot, disabled: blocked, children: [slot, blocked ? ' — in use' : ''] }, slot));
|
|
27
|
+
})] }), _jsx(Text, { size: "xs", tone: "muted", children: "A stable name the site uses to find this document (e.g. the main menu), instead of which exact entry it is. One document per slot." })] })) : null, hasSlots && hasFields ? _jsx(Separator, {}) : null, hasFields ? _jsx(Stack, { gap: "4", children: fields.map(renderField) }) : null, !hasSlots && !hasFields ? (_jsx(Text, { size: "xs", tone: "muted", children: "No document properties to set." })) : null] }));
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=details-pane.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"details-pane.js","sourceRoot":"","sources":["../../../src/components/cms/details-pane.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAG1D,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAA;AAErE;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,WAAW,CAAC,EAC1B,UAAU,EACV,GAAG,EACH,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,WAAW,EACX,aAAa,GAYd;IACC,MAAM,KAAK,GAAG,eAAe,CAAC,UAAU,CAAC,CAAA;IACzC,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAA;IACjC,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAA;IAEnC,OAAO,CACL,MAAC,KAAK,IAAC,GAAG,EAAC,GAAG,EAAC,SAAS,EAAC,KAAK,aAC3B,QAAQ,CAAC,CAAC,CAAC,CACV,MAAC,KAAK,IAAC,GAAG,EAAC,GAAG,aACZ,KAAC,IAAI,IAAC,IAAI,EAAC,IAAI,EAAC,MAAM,EAAC,UAAU,qBAE1B,EACP,MAAC,MAAM,IACL,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,EAAE,EACtB,QAAQ,EAAE,QAAQ,gBACP,MAAM,iBACL,cAAc,EAC1B,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,aAElF,iBAAQ,KAAK,EAAC,EAAE,sCAAqB,EACpC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;gCAClB,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,CAAA;gCAC9E,MAAM,OAAO,GAAG,YAAY,IAAI,GAAG,CAAC,KAAK,KAAK,IAAI,CAAA;gCAClD,OAAO,CACL,kBAAmB,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,aAC9C,IAAI,EACJ,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,KAFhB,IAAI,CAGR,CACV,CAAA;4BACH,CAAC,CAAC,IACK,EACT,KAAC,IAAI,IAAC,IAAI,EAAC,IAAI,EAAC,IAAI,EAAC,OAAO,mJAGrB,IACD,CACT,CAAC,CAAC,CAAC,IAAI,EAEP,QAAQ,IAAI,SAAS,CAAC,CAAC,CAAC,KAAC,SAAS,KAAG,CAAC,CAAC,CAAC,IAAI,EAE5C,SAAS,CAAC,CAAC,CAAC,KAAC,KAAK,IAAC,GAAG,EAAC,GAAG,YAAE,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,GAAS,CAAC,CAAC,CAAC,IAAI,EAEnE,CAAC,QAAQ,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CACzB,KAAC,IAAI,IAAC,IAAI,EAAC,IAAI,EAAC,IAAI,EAAC,OAAO,+CAErB,CACR,CAAC,CAAC,CAAC,IAAI,IACF,CACT,CAAA;AACH,CAAC","sourcesContent":["import { declaredAliases } from '@elytracms/core/cms-core'\nimport type { CmsDocument, CollectionDef, FieldDef } from '@elytracms/core/cms-core'\nimport type { ReactNode } from 'react'\nimport { Select, Separator, Stack, Text } from '@elytracms/studio/ui'\n\n/**\n * EC-284 + EC-285 — document-level metadata pane (the right inspector). Two\n * optional regions:\n *\n * 1. **Slot** (EC-284): a stable, named handle the site uses to find this document\n * (the main menu, the footer menu…) instead of which exact entry it is — shown\n * only when the collection declares alias slots.\n * 2. **Sidebar fields** (EC-285): the document's `sidebar`-group fields (slug,\n * author, publish date…) — document-level properties an editor sets *about* the\n * document rather than as body content. Rendered via the detail editor's own\n * field-row renderer, so they behave identically to a content field.\n *\n * Both are identity/metadata, not content, so they live here — off the content\n * tabs. The empty state shows only when there is neither a slot nor a sidebar field.\n */\nexport function DetailsPane({\n collection,\n doc,\n siblings,\n readOnly,\n fields,\n renderField,\n onAliasChange,\n}: {\n collection: CollectionDef\n doc: CmsDocument\n /** The other documents in this collection (to show which slots are taken). */\n siblings: readonly CmsDocument[]\n readOnly?: boolean\n /** The collection's `sidebar`-group fields, in order (EC-285). */\n fields: readonly FieldDef[]\n /** Render one field row — shared with the content groups so behaviour matches. */\n renderField: (field: FieldDef) => ReactNode\n onAliasChange: (alias: string | undefined) => void\n}) {\n const slots = declaredAliases(collection)\n const hasSlots = slots.length > 0\n const hasFields = fields.length > 0\n\n return (\n <Stack gap=\"4\" className=\"p-3\">\n {hasSlots ? (\n <Stack gap=\"1\">\n <Text size=\"xs\" weight=\"semibold\">\n Slot\n </Text>\n <Select\n value={doc.alias ?? ''}\n disabled={readOnly}\n aria-label=\"Slot\"\n data-testid=\"alias-select\"\n onChange={(e) => onAliasChange(e.target.value === '' ? undefined : e.target.value)}\n >\n <option value=\"\">— No slot —</option>\n {slots.map((slot) => {\n const takenByOther = siblings.some((s) => s.id !== doc.id && s.alias === slot)\n const blocked = takenByOther && doc.alias !== slot\n return (\n <option key={slot} value={slot} disabled={blocked}>\n {slot}\n {blocked ? ' — in use' : ''}\n </option>\n )\n })}\n </Select>\n <Text size=\"xs\" tone=\"muted\">\n A stable name the site uses to find this document (e.g. the main menu),\n instead of which exact entry it is. One document per slot.\n </Text>\n </Stack>\n ) : null}\n\n {hasSlots && hasFields ? <Separator /> : null}\n\n {hasFields ? <Stack gap=\"4\">{fields.map(renderField)}</Stack> : null}\n\n {!hasSlots && !hasFields ? (\n <Text size=\"xs\" tone=\"muted\">\n No document properties to set.\n </Text>\n ) : null}\n </Stack>\n )\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { ChevronDown, ChevronUp, Image, Link2, Pencil, Plus, Trash2, X } from 'lucide-react';
|
|
3
3
|
import { useMemo, useRef, useState } from 'react';
|
|
4
|
-
import { descendantIds, parentRelationField } from '@elytracms/core/cms-core';
|
|
4
|
+
import { descendantIds, isFieldHidden, parentRelationField } from '@elytracms/core/cms-core';
|
|
5
5
|
import { Badge, Button, Card, Code, Field, Input, Row, Select, Spacer, Stack, Text } from '@elytracms/studio/ui';
|
|
6
6
|
import { applyAssetSelection, assetIdsOf, singleAssetIdOf } from '../assets/asset-selection';
|
|
7
7
|
import { fieldLabel, useCms } from './cms-store';
|
|
@@ -50,6 +50,11 @@ function asRecord(value) {
|
|
|
50
50
|
*/
|
|
51
51
|
function ObjectItemForm({ fields, value, onChange, readOnly, idPrefix, }) {
|
|
52
52
|
return (_jsx(Stack, { gap: "3", className: "mt-2", children: fields.map((sub) => {
|
|
53
|
+
// EC-273: a conditionally-hidden subfield (its predicate keys off the item's
|
|
54
|
+
// own sibling values) is omitted — e.g. a discriminated link's `href` shows
|
|
55
|
+
// only when `linkType === 'href'`. Re-evaluated as the item is edited.
|
|
56
|
+
if (isFieldHidden(sub, { values: value }))
|
|
57
|
+
return null;
|
|
53
58
|
const subId = `${idPrefix}-${sub.name}`;
|
|
54
59
|
return (_jsx(Field, { htmlFor: subId, hint: sub.form?.description, label: _jsxs(Row, { gap: "2", children: [_jsx("span", { children: fieldLabel(sub) }), sub.validation?.required ? _jsx("span", { className: "text-destructive", children: "*" }) : null] }), children: _jsx(FieldControl, { id: subId, field: sub, value: value[sub.name], readOnly: readOnly, onChange: (next) => {
|
|
55
60
|
const updated = { ...value };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field-control.js","sourceRoot":"","sources":["../../../src/components/cms/field-control.tsx"],"names":[],"mappings":"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","sourcesContent":["import { ChevronDown, ChevronUp, Image, Link2, Pencil, Plus, Trash2, X } from 'lucide-react'\nimport { useMemo, useRef, useState } from 'react'\nimport type {\n AssetFieldDef,\n DocumentRef,\n FieldDef,\n ObjectFieldDef,\n RelationFieldDef,\n} from '@elytracms/core/cms-core'\nimport { descendantIds, parentRelationField } from '@elytracms/core/cms-core'\nimport { Badge, Button, Card, Code, Field, Input, Row, Select, Spacer, Stack, Text } from '@elytracms/studio/ui'\nimport { applyAssetSelection, assetIdsOf, singleAssetIdOf } from '../assets/asset-selection'\nimport { fieldLabel, useCms } from './cms-store'\nimport { useOptionalDocumentEditor } from './document-editor-context'\nimport { toRefArray } from './cell'\nimport { RelationPicker } from './relation-picker'\nimport { AssetPicker } from './asset-picker'\n\nexport function FieldControl({\n field,\n value,\n onChange,\n readOnly,\n id,\n}: {\n field: FieldDef\n value: unknown\n onChange: (value: unknown) => void\n readOnly: boolean\n id: string\n}) {\n switch (field.type) {\n case 'boolean':\n return (\n <label className=\"flex h-8 items-center gap-2 text-sm\">\n <input\n id={id}\n type=\"checkbox\"\n checked={value === true}\n disabled={readOnly}\n onChange={(e) => onChange(e.target.checked)}\n className=\"size-4 accent-primary disabled:opacity-50\"\n />\n <Text size=\"sm\" tone=\"muted\">\n {value === true ? 'true' : 'false'}\n </Text>\n </label>\n )\n case 'number':\n return (\n <Input\n id={id}\n type=\"number\"\n disabled={readOnly}\n value={typeof value === 'number' ? value : ''}\n onChange={(e) => onChange(e.target.value === '' ? undefined : Number(e.target.value))}\n />\n )\n case 'date':\n return (\n <Input\n id={id}\n type=\"date\"\n disabled={readOnly}\n value={typeof value === 'string' ? value.slice(0, 10) : ''}\n onChange={(e) => onChange(e.target.value ? `${e.target.value}T00:00:00.000Z` : undefined)}\n />\n )\n case 'select':\n if (field.multiple) {\n const selected = Array.isArray(value) ? (value as string[]) : []\n return (\n <Row gap=\"2\" wrap>\n {field.options.map((opt) => {\n const on = selected.includes(opt.value)\n return (\n <label key={opt.value} className=\"flex items-center gap-1.5 text-sm\">\n <input\n type=\"checkbox\"\n checked={on}\n disabled={readOnly}\n onChange={() =>\n onChange(\n on ? selected.filter((v) => v !== opt.value) : [...selected, opt.value],\n )\n }\n className=\"size-4 accent-primary\"\n />\n {opt.label ?? opt.value}\n </label>\n )\n })}\n </Row>\n )\n }\n return (\n <Select\n id={id}\n disabled={readOnly}\n value={typeof value === 'string' ? value : ''}\n onChange={(e) => onChange(e.target.value || undefined)}\n >\n <option value=\"\">—</option>\n {field.options.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label ?? opt.value}\n </option>\n ))}\n </Select>\n )\n case 'richText':\n return (\n <textarea\n id={id}\n rows={4}\n disabled={readOnly}\n value={typeof value === 'string' ? value : ''}\n onChange={(e) => onChange(e.target.value || undefined)}\n className=\"flex w-full rounded-md border border-input bg-background px-2.5 py-1.5 font-mono text-xs text-foreground shadow-sm focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/40 outline-none disabled:opacity-50\"\n />\n )\n case 'relation':\n return <RelationField field={field} value={value} onChange={onChange} readOnly={readOnly} />\n case 'asset':\n return <AssetField field={field} value={value} onChange={onChange} readOnly={readOnly} />\n case 'object':\n return <ObjectField field={field} value={value} onChange={onChange} readOnly={readOnly} id={id} />\n default:\n return (\n <Input\n id={id}\n disabled={readOnly}\n value={typeof value === 'string' ? value : ''}\n onChange={(e) => onChange(e.target.value || undefined)}\n />\n )\n }\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {}\n}\n\n/**\n * The nested subfield form for one object item (EC-253). Reuses {@link FieldControl}\n * recursively, so any subfield type — including a nested object/repeater — works for\n * free. Writing a subfield merges it back into the item and bubbles the new item up.\n */\nfunction ObjectItemForm({\n fields,\n value,\n onChange,\n readOnly,\n idPrefix,\n}: {\n fields: readonly FieldDef[]\n value: Record<string, unknown>\n onChange: (value: Record<string, unknown>) => void\n readOnly: boolean\n idPrefix: string\n}) {\n return (\n <Stack gap=\"3\" className=\"mt-2\">\n {fields.map((sub) => {\n const subId = `${idPrefix}-${sub.name}`\n return (\n <Field\n key={sub.name}\n htmlFor={subId}\n hint={sub.form?.description}\n label={\n <Row gap=\"2\">\n <span>{fieldLabel(sub)}</span>\n {sub.validation?.required ? <span className=\"text-destructive\">*</span> : null}\n </Row>\n }\n >\n <FieldControl\n id={subId}\n field={sub}\n value={value[sub.name]}\n readOnly={readOnly}\n onChange={(next) => {\n const updated = { ...value }\n if (next === undefined) delete updated[sub.name]\n else updated[sub.name] = next\n onChange(updated)\n }}\n />\n </Field>\n )\n })}\n </Stack>\n )\n}\n\n/**\n * Object / repeater field control (EC-253). `cardinality: 'one'` renders a single\n * nested form in a card; `'many'` renders an add/remove/reorder list of item cards.\n * Editing happens entirely inside the shared field form — no canvas escape (unlike\n * `blocks`), so props and document fields share this control.\n */\nfunction ObjectField({\n field,\n value,\n onChange,\n readOnly,\n id,\n}: {\n field: ObjectFieldDef\n value: unknown\n onChange: (value: unknown) => void\n readOnly: boolean\n id: string\n}) {\n if (field.cardinality !== 'many') {\n return (\n <Card className=\"p-3\">\n <ObjectItemForm\n fields={field.fields}\n value={asRecord(value)}\n readOnly={readOnly}\n idPrefix={id}\n onChange={onChange}\n />\n </Card>\n )\n }\n\n const items = Array.isArray(value) ? (value as Record<string, unknown>[]) : []\n // Stable React keys for the value-only items (they carry no intrinsic id). Index\n // keys would mis-associate a row's child/DOM state (an open relation/asset picker,\n // focus) when rows are reordered or removed; we keep a parallel id list in lockstep\n // with structural ops, reconciled by length when the array is replaced wholesale\n // (e.g. switching documents). Edits keep the keys — only structure changes them.\n const seq = useRef(0)\n const keysRef = useRef<number[]>([])\n if (keysRef.current.length !== items.length) {\n keysRef.current = items.map((_, i) => keysRef.current[i] ?? seq.current++)\n }\n const keys = keysRef.current\n const commit = (nextItems: Record<string, unknown>[], nextKeys: number[]) => {\n keysRef.current = nextKeys\n onChange(nextItems)\n }\n const move = (from: number, to: number) => {\n const nextItems = items.slice()\n const [movedItem] = nextItems.splice(from, 1)\n const nextKeys = keys.slice()\n const [movedKey] = nextKeys.splice(from, 1)\n if (movedItem && movedKey !== undefined) {\n nextItems.splice(to, 0, movedItem)\n nextKeys.splice(to, 0, movedKey)\n }\n commit(nextItems, nextKeys)\n }\n const removeAt = (i: number) =>\n commit(items.filter((_, j) => j !== i), keys.filter((_, j) => j !== i))\n const addItem = () => {\n const seed: Record<string, unknown> = {}\n for (const sub of field.fields) if (sub.default !== undefined) seed[sub.name] = sub.default\n commit([...items, seed], [...keys, seq.current++])\n }\n const setItem = (i: number, updated: Record<string, unknown>) => {\n const nextItems = items.slice()\n nextItems[i] = updated\n commit(nextItems, keys)\n }\n\n return (\n <Stack gap=\"2\">\n {items.length === 0 ? (\n <Text size=\"sm\" tone=\"subtle\">\n No items\n </Text>\n ) : (\n items.map((item, i) => (\n <Card key={keys[i]} className=\"p-3\">\n <Row gap=\"2\">\n <Text size=\"sm\" tone=\"muted\">\n #{i + 1}\n </Text>\n <Spacer />\n {!readOnly ? (\n <Row gap=\"1\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n aria-label=\"Move up\"\n disabled={i === 0}\n onClick={() => move(i, i - 1)}\n >\n <ChevronUp className=\"size-3\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n aria-label=\"Move down\"\n disabled={i === items.length - 1}\n onClick={() => move(i, i + 1)}\n >\n <ChevronDown className=\"size-3\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n aria-label=\"Remove item\"\n onClick={() => removeAt(i)}\n >\n <Trash2 className=\"size-3\" />\n </Button>\n </Row>\n ) : null}\n </Row>\n <ObjectItemForm\n fields={field.fields}\n value={asRecord(item)}\n readOnly={readOnly}\n idPrefix={`${id}-${i}`}\n onChange={(updated) => setItem(i, updated)}\n />\n </Card>\n ))\n )}\n {!readOnly ? (\n <Button variant=\"outline\" size=\"sm\" onClick={addItem}>\n <Plus className=\"size-3\" /> Add item\n </Button>\n ) : null}\n </Stack>\n )\n}\n\nfunction RelationField({\n field,\n value,\n onChange,\n readOnly,\n}: {\n field: RelationFieldDef\n value: unknown\n onChange: (value: unknown) => void\n readOnly: boolean\n}) {\n const cms = useCms()\n const editor = useOptionalDocumentEditor()\n const [open, setOpen] = useState(false)\n const refs = toRefArray(value)\n\n // EC-218: for the editing document's `parent` self-relation, exclude the\n // document itself and its descendants from the picker — choosing one would make\n // the page its own ancestor (a cycle). Only applies to the parent field of a\n // hierarchical collection; ordinary relations (and other self-relations) are\n // unrestricted. validateDocument is the backstop where this context is absent.\n const excludeIds = useMemo<Set<string> | undefined>(() => {\n if (!editor || field.target !== editor.collection.id) return undefined\n if (parentRelationField(editor.collection)?.name !== field.name) return undefined\n const ids = descendantIds(editor.docRef.id, cms.documentsOf(editor.collection.id))\n ids.add(editor.docRef.id)\n return ids\n }, [editor, field.target, field.name, cms])\n\n function apply(next: DocumentRef[]) {\n onChange(field.cardinality === 'many' ? next : (next[0] ?? undefined))\n }\n\n return (\n <Row gap=\"2\" wrap>\n {refs.map((ref, i) => (\n <Badge key={`${ref.id}-${i}`} variant=\"info\">\n <Link2 className=\"size-3\" /> {cms.titleOf(ref)}\n {!readOnly ? (\n <button\n type=\"button\"\n aria-label=\"Remove\"\n onClick={() => apply(refs.filter((r) => r.id !== ref.id))}\n className=\"ml-1 hover:text-destructive\"\n >\n <X className=\"size-3\" />\n </button>\n ) : null}\n </Badge>\n ))}\n {!readOnly ? (\n <Button variant=\"outline\" size=\"sm\" onClick={() => setOpen(true)}>\n <Pencil /> {refs.length > 0 ? 'Change' : 'Pick'}\n </Button>\n ) : null}\n <RelationPicker\n targetCollection={field.target}\n cardinality={field.cardinality}\n value={refs}\n open={open}\n onOpenChange={setOpen}\n onChange={apply}\n excludeIds={excludeIds}\n />\n </Row>\n )\n}\n\nfunction AssetField({\n field,\n value,\n onChange,\n readOnly,\n}: {\n field: AssetFieldDef\n value: unknown\n onChange: (value: unknown) => void\n readOnly: boolean\n}) {\n const cms = useCms()\n const [open, setOpen] = useState(false)\n const assetCollectionId = cms.collections.find((c) => c.kind === 'asset')?.id ?? 'asset'\n const many = field.cardinality === 'many'\n const ids = many ? assetIdsOf(value) : []\n const single = !many ? singleAssetIdOf(value) : null\n\n return (\n <Row gap=\"2\" wrap>\n {many ? (\n ids.length > 0 ? (\n ids.map((aid, i) => (\n <Badge key={`${aid}-${i}`} variant=\"outline\">\n <Image className=\"size-3\" /> {cms.titleOf({ collection: assetCollectionId, id: aid })}\n {!readOnly ? (\n <button\n type=\"button\"\n aria-label=\"Remove\"\n onClick={() => onChange(ids.filter((x) => x !== aid))}\n className=\"ml-1 hover:text-destructive\"\n >\n <X className=\"size-3\" />\n </button>\n ) : null}\n </Badge>\n ))\n ) : (\n <Text size=\"sm\" tone=\"subtle\">\n No assets\n </Text>\n )\n ) : single ? (\n <Badge variant=\"outline\">\n <Image className=\"size-3\" /> {cms.titleOf({ collection: assetCollectionId, id: single })}\n </Badge>\n ) : (\n <Text size=\"sm\" tone=\"subtle\">\n No asset\n </Text>\n )}\n <Spacer />\n {field.accept && field.accept.length > 0 ? (\n <Code tone=\"muted\">accepts {field.accept.join(', ')}</Code>\n ) : null}\n {!readOnly ? (\n <Button variant=\"outline\" size=\"sm\" onClick={() => setOpen(true)}>\n <Pencil /> {many ? 'Add' : single ? 'Change' : 'Pick'}\n </Button>\n ) : null}\n <AssetPicker\n value={single}\n open={open}\n onOpenChange={setOpen}\n onChange={(next) => onChange(applyAssetSelection(value, next, field.cardinality))}\n />\n </Row>\n )\n}\n"]}
|
|
1
|
+
{"version":3,"file":"field-control.js","sourceRoot":"","sources":["../../../src/components/cms/field-control.tsx"],"names":[],"mappings":"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","sourcesContent":["import { ChevronDown, ChevronUp, Image, Link2, Pencil, Plus, Trash2, X } from 'lucide-react'\nimport { useMemo, useRef, useState } from 'react'\nimport type {\n AssetFieldDef,\n DocumentRef,\n FieldDef,\n ObjectFieldDef,\n RelationFieldDef,\n} from '@elytracms/core/cms-core'\nimport { descendantIds, isFieldHidden, parentRelationField } from '@elytracms/core/cms-core'\nimport { Badge, Button, Card, Code, Field, Input, Row, Select, Spacer, Stack, Text } from '@elytracms/studio/ui'\nimport { applyAssetSelection, assetIdsOf, singleAssetIdOf } from '../assets/asset-selection'\nimport { fieldLabel, useCms } from './cms-store'\nimport { useOptionalDocumentEditor } from './document-editor-context'\nimport { toRefArray } from './cell'\nimport { RelationPicker } from './relation-picker'\nimport { AssetPicker } from './asset-picker'\n\nexport function FieldControl({\n field,\n value,\n onChange,\n readOnly,\n id,\n}: {\n field: FieldDef\n value: unknown\n onChange: (value: unknown) => void\n readOnly: boolean\n id: string\n}) {\n switch (field.type) {\n case 'boolean':\n return (\n <label className=\"flex h-8 items-center gap-2 text-sm\">\n <input\n id={id}\n type=\"checkbox\"\n checked={value === true}\n disabled={readOnly}\n onChange={(e) => onChange(e.target.checked)}\n className=\"size-4 accent-primary disabled:opacity-50\"\n />\n <Text size=\"sm\" tone=\"muted\">\n {value === true ? 'true' : 'false'}\n </Text>\n </label>\n )\n case 'number':\n return (\n <Input\n id={id}\n type=\"number\"\n disabled={readOnly}\n value={typeof value === 'number' ? value : ''}\n onChange={(e) => onChange(e.target.value === '' ? undefined : Number(e.target.value))}\n />\n )\n case 'date':\n return (\n <Input\n id={id}\n type=\"date\"\n disabled={readOnly}\n value={typeof value === 'string' ? value.slice(0, 10) : ''}\n onChange={(e) => onChange(e.target.value ? `${e.target.value}T00:00:00.000Z` : undefined)}\n />\n )\n case 'select':\n if (field.multiple) {\n const selected = Array.isArray(value) ? (value as string[]) : []\n return (\n <Row gap=\"2\" wrap>\n {field.options.map((opt) => {\n const on = selected.includes(opt.value)\n return (\n <label key={opt.value} className=\"flex items-center gap-1.5 text-sm\">\n <input\n type=\"checkbox\"\n checked={on}\n disabled={readOnly}\n onChange={() =>\n onChange(\n on ? selected.filter((v) => v !== opt.value) : [...selected, opt.value],\n )\n }\n className=\"size-4 accent-primary\"\n />\n {opt.label ?? opt.value}\n </label>\n )\n })}\n </Row>\n )\n }\n return (\n <Select\n id={id}\n disabled={readOnly}\n value={typeof value === 'string' ? value : ''}\n onChange={(e) => onChange(e.target.value || undefined)}\n >\n <option value=\"\">—</option>\n {field.options.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label ?? opt.value}\n </option>\n ))}\n </Select>\n )\n case 'richText':\n return (\n <textarea\n id={id}\n rows={4}\n disabled={readOnly}\n value={typeof value === 'string' ? value : ''}\n onChange={(e) => onChange(e.target.value || undefined)}\n className=\"flex w-full rounded-md border border-input bg-background px-2.5 py-1.5 font-mono text-xs text-foreground shadow-sm focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/40 outline-none disabled:opacity-50\"\n />\n )\n case 'relation':\n return <RelationField field={field} value={value} onChange={onChange} readOnly={readOnly} />\n case 'asset':\n return <AssetField field={field} value={value} onChange={onChange} readOnly={readOnly} />\n case 'object':\n return <ObjectField field={field} value={value} onChange={onChange} readOnly={readOnly} id={id} />\n default:\n return (\n <Input\n id={id}\n disabled={readOnly}\n value={typeof value === 'string' ? value : ''}\n onChange={(e) => onChange(e.target.value || undefined)}\n />\n )\n }\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {}\n}\n\n/**\n * The nested subfield form for one object item (EC-253). Reuses {@link FieldControl}\n * recursively, so any subfield type — including a nested object/repeater — works for\n * free. Writing a subfield merges it back into the item and bubbles the new item up.\n */\nfunction ObjectItemForm({\n fields,\n value,\n onChange,\n readOnly,\n idPrefix,\n}: {\n fields: readonly FieldDef[]\n value: Record<string, unknown>\n onChange: (value: Record<string, unknown>) => void\n readOnly: boolean\n idPrefix: string\n}) {\n return (\n <Stack gap=\"3\" className=\"mt-2\">\n {fields.map((sub) => {\n // EC-273: a conditionally-hidden subfield (its predicate keys off the item's\n // own sibling values) is omitted — e.g. a discriminated link's `href` shows\n // only when `linkType === 'href'`. Re-evaluated as the item is edited.\n if (isFieldHidden(sub, { values: value })) return null\n const subId = `${idPrefix}-${sub.name}`\n return (\n <Field\n key={sub.name}\n htmlFor={subId}\n hint={sub.form?.description}\n label={\n <Row gap=\"2\">\n <span>{fieldLabel(sub)}</span>\n {sub.validation?.required ? <span className=\"text-destructive\">*</span> : null}\n </Row>\n }\n >\n <FieldControl\n id={subId}\n field={sub}\n value={value[sub.name]}\n readOnly={readOnly}\n onChange={(next) => {\n const updated = { ...value }\n if (next === undefined) delete updated[sub.name]\n else updated[sub.name] = next\n onChange(updated)\n }}\n />\n </Field>\n )\n })}\n </Stack>\n )\n}\n\n/**\n * Object / repeater field control (EC-253). `cardinality: 'one'` renders a single\n * nested form in a card; `'many'` renders an add/remove/reorder list of item cards.\n * Editing happens entirely inside the shared field form — no canvas escape (unlike\n * `blocks`), so props and document fields share this control.\n */\nfunction ObjectField({\n field,\n value,\n onChange,\n readOnly,\n id,\n}: {\n field: ObjectFieldDef\n value: unknown\n onChange: (value: unknown) => void\n readOnly: boolean\n id: string\n}) {\n if (field.cardinality !== 'many') {\n return (\n <Card className=\"p-3\">\n <ObjectItemForm\n fields={field.fields}\n value={asRecord(value)}\n readOnly={readOnly}\n idPrefix={id}\n onChange={onChange}\n />\n </Card>\n )\n }\n\n const items = Array.isArray(value) ? (value as Record<string, unknown>[]) : []\n // Stable React keys for the value-only items (they carry no intrinsic id). Index\n // keys would mis-associate a row's child/DOM state (an open relation/asset picker,\n // focus) when rows are reordered or removed; we keep a parallel id list in lockstep\n // with structural ops, reconciled by length when the array is replaced wholesale\n // (e.g. switching documents). Edits keep the keys — only structure changes them.\n const seq = useRef(0)\n const keysRef = useRef<number[]>([])\n if (keysRef.current.length !== items.length) {\n keysRef.current = items.map((_, i) => keysRef.current[i] ?? seq.current++)\n }\n const keys = keysRef.current\n const commit = (nextItems: Record<string, unknown>[], nextKeys: number[]) => {\n keysRef.current = nextKeys\n onChange(nextItems)\n }\n const move = (from: number, to: number) => {\n const nextItems = items.slice()\n const [movedItem] = nextItems.splice(from, 1)\n const nextKeys = keys.slice()\n const [movedKey] = nextKeys.splice(from, 1)\n if (movedItem && movedKey !== undefined) {\n nextItems.splice(to, 0, movedItem)\n nextKeys.splice(to, 0, movedKey)\n }\n commit(nextItems, nextKeys)\n }\n const removeAt = (i: number) =>\n commit(items.filter((_, j) => j !== i), keys.filter((_, j) => j !== i))\n const addItem = () => {\n const seed: Record<string, unknown> = {}\n for (const sub of field.fields) if (sub.default !== undefined) seed[sub.name] = sub.default\n commit([...items, seed], [...keys, seq.current++])\n }\n const setItem = (i: number, updated: Record<string, unknown>) => {\n const nextItems = items.slice()\n nextItems[i] = updated\n commit(nextItems, keys)\n }\n\n return (\n <Stack gap=\"2\">\n {items.length === 0 ? (\n <Text size=\"sm\" tone=\"subtle\">\n No items\n </Text>\n ) : (\n items.map((item, i) => (\n <Card key={keys[i]} className=\"p-3\">\n <Row gap=\"2\">\n <Text size=\"sm\" tone=\"muted\">\n #{i + 1}\n </Text>\n <Spacer />\n {!readOnly ? (\n <Row gap=\"1\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n aria-label=\"Move up\"\n disabled={i === 0}\n onClick={() => move(i, i - 1)}\n >\n <ChevronUp className=\"size-3\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n aria-label=\"Move down\"\n disabled={i === items.length - 1}\n onClick={() => move(i, i + 1)}\n >\n <ChevronDown className=\"size-3\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n aria-label=\"Remove item\"\n onClick={() => removeAt(i)}\n >\n <Trash2 className=\"size-3\" />\n </Button>\n </Row>\n ) : null}\n </Row>\n <ObjectItemForm\n fields={field.fields}\n value={asRecord(item)}\n readOnly={readOnly}\n idPrefix={`${id}-${i}`}\n onChange={(updated) => setItem(i, updated)}\n />\n </Card>\n ))\n )}\n {!readOnly ? (\n <Button variant=\"outline\" size=\"sm\" onClick={addItem}>\n <Plus className=\"size-3\" /> Add item\n </Button>\n ) : null}\n </Stack>\n )\n}\n\nfunction RelationField({\n field,\n value,\n onChange,\n readOnly,\n}: {\n field: RelationFieldDef\n value: unknown\n onChange: (value: unknown) => void\n readOnly: boolean\n}) {\n const cms = useCms()\n const editor = useOptionalDocumentEditor()\n const [open, setOpen] = useState(false)\n const refs = toRefArray(value)\n\n // EC-218: for the editing document's `parent` self-relation, exclude the\n // document itself and its descendants from the picker — choosing one would make\n // the page its own ancestor (a cycle). Only applies to the parent field of a\n // hierarchical collection; ordinary relations (and other self-relations) are\n // unrestricted. validateDocument is the backstop where this context is absent.\n const excludeIds = useMemo<Set<string> | undefined>(() => {\n if (!editor || field.target !== editor.collection.id) return undefined\n if (parentRelationField(editor.collection)?.name !== field.name) return undefined\n const ids = descendantIds(editor.docRef.id, cms.documentsOf(editor.collection.id))\n ids.add(editor.docRef.id)\n return ids\n }, [editor, field.target, field.name, cms])\n\n function apply(next: DocumentRef[]) {\n onChange(field.cardinality === 'many' ? next : (next[0] ?? undefined))\n }\n\n return (\n <Row gap=\"2\" wrap>\n {refs.map((ref, i) => (\n <Badge key={`${ref.id}-${i}`} variant=\"info\">\n <Link2 className=\"size-3\" /> {cms.titleOf(ref)}\n {!readOnly ? (\n <button\n type=\"button\"\n aria-label=\"Remove\"\n onClick={() => apply(refs.filter((r) => r.id !== ref.id))}\n className=\"ml-1 hover:text-destructive\"\n >\n <X className=\"size-3\" />\n </button>\n ) : null}\n </Badge>\n ))}\n {!readOnly ? (\n <Button variant=\"outline\" size=\"sm\" onClick={() => setOpen(true)}>\n <Pencil /> {refs.length > 0 ? 'Change' : 'Pick'}\n </Button>\n ) : null}\n <RelationPicker\n targetCollection={field.target}\n cardinality={field.cardinality}\n value={refs}\n open={open}\n onOpenChange={setOpen}\n onChange={apply}\n excludeIds={excludeIds}\n />\n </Row>\n )\n}\n\nfunction AssetField({\n field,\n value,\n onChange,\n readOnly,\n}: {\n field: AssetFieldDef\n value: unknown\n onChange: (value: unknown) => void\n readOnly: boolean\n}) {\n const cms = useCms()\n const [open, setOpen] = useState(false)\n const assetCollectionId = cms.collections.find((c) => c.kind === 'asset')?.id ?? 'asset'\n const many = field.cardinality === 'many'\n const ids = many ? assetIdsOf(value) : []\n const single = !many ? singleAssetIdOf(value) : null\n\n return (\n <Row gap=\"2\" wrap>\n {many ? (\n ids.length > 0 ? (\n ids.map((aid, i) => (\n <Badge key={`${aid}-${i}`} variant=\"outline\">\n <Image className=\"size-3\" /> {cms.titleOf({ collection: assetCollectionId, id: aid })}\n {!readOnly ? (\n <button\n type=\"button\"\n aria-label=\"Remove\"\n onClick={() => onChange(ids.filter((x) => x !== aid))}\n className=\"ml-1 hover:text-destructive\"\n >\n <X className=\"size-3\" />\n </button>\n ) : null}\n </Badge>\n ))\n ) : (\n <Text size=\"sm\" tone=\"subtle\">\n No assets\n </Text>\n )\n ) : single ? (\n <Badge variant=\"outline\">\n <Image className=\"size-3\" /> {cms.titleOf({ collection: assetCollectionId, id: single })}\n </Badge>\n ) : (\n <Text size=\"sm\" tone=\"subtle\">\n No asset\n </Text>\n )}\n <Spacer />\n {field.accept && field.accept.length > 0 ? (\n <Code tone=\"muted\">accepts {field.accept.join(', ')}</Code>\n ) : null}\n {!readOnly ? (\n <Button variant=\"outline\" size=\"sm\" onClick={() => setOpen(true)}>\n <Pencil /> {many ? 'Add' : single ? 'Change' : 'Pick'}\n </Button>\n ) : null}\n <AssetPicker\n value={single}\n open={open}\n onOpenChange={setOpen}\n onChange={(next) => onChange(applyAssetSelection(value, next, field.cardinality))}\n />\n </Row>\n )\n}\n"]}
|
|
@@ -22,7 +22,14 @@ export interface InspectorPane {
|
|
|
22
22
|
badge?: ReactNode;
|
|
23
23
|
render: () => ReactNode;
|
|
24
24
|
}
|
|
25
|
-
export declare function InspectorSidebar({ panes, className, }: {
|
|
25
|
+
export declare function InspectorSidebar({ panes, className, activeId: controlledId, onActiveChange, }: {
|
|
26
26
|
panes: readonly InspectorPane[];
|
|
27
27
|
className?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Optionally control which pane is shown (EC-285): the document editor drives
|
|
30
|
+
* this to open the `Details` pane when a jump-to-field targets a sidebar field.
|
|
31
|
+
* Uncontrolled (internal state) when omitted.
|
|
32
|
+
*/
|
|
33
|
+
activeId?: string;
|
|
34
|
+
onActiveChange?: (id: string) => void;
|
|
28
35
|
}): import("react").JSX.Element | null;
|