@elytracms/studio 0.0.91 → 0.0.93
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/convex/asset-alt-migration.test.ts +127 -0
- package/convex/asset-replace.test.ts +168 -0
- package/convex/asset-revalidate.test.ts +6 -6
- package/convex/assets.ts +41 -5
- package/convex/cms.ts +537 -177
- package/convex/contract-parity.test.ts +173 -19
- package/convex/delivery.ts +26 -13
- package/convex/document-revalidate.test.ts +17 -16
- package/convex/orphan-hydration.test.ts +116 -0
- package/convex/presence-cost.test.ts +89 -0
- package/convex/rail-write-parity.test.ts +17 -14
- package/convex/referenceMaintenance.ts +15 -15
- package/convex/schema.ts +70 -5
- package/convex/triggers.ts +21 -8
- package/convex/write-limits.ts +1 -1
- package/dist/components/ai/ai-chat-panel.js +33 -22
- package/dist/components/ai/ai-chat-panel.js.map +1 -1
- package/dist/components/ai/proposal-card.js +2 -1
- package/dist/components/ai/proposal-card.js.map +1 -1
- package/dist/components/ai/translate-document-action.d.ts +8 -2
- package/dist/components/ai/translate-document-action.js.map +1 -1
- package/dist/components/ai/translate-document-dialog.d.ts +1 -1
- package/dist/components/ai/translate-document-dialog.js +14 -8
- package/dist/components/ai/translate-document-dialog.js.map +1 -1
- package/dist/components/ai/translate-skipped.d.ts +19 -0
- package/dist/components/ai/translate-skipped.js +46 -0
- package/dist/components/ai/translate-skipped.js.map +1 -0
- package/dist/components/app-views/default-modules.d.ts +23 -6
- package/dist/components/app-views/default-modules.js +33 -14
- package/dist/components/app-views/default-modules.js.map +1 -1
- package/dist/components/assets/asset-detail.js +18 -8
- package/dist/components/assets/asset-detail.js.map +1 -1
- package/dist/components/assets/asset-metadata.d.ts +15 -4
- package/dist/components/assets/asset-metadata.js +15 -2
- package/dist/components/assets/asset-metadata.js.map +1 -1
- package/dist/components/assets/asset-search.js +4 -1
- package/dist/components/assets/asset-search.js.map +1 -1
- package/dist/components/assets/asset-selection.d.ts +0 -8
- package/dist/components/assets/asset-selection.js +4 -23
- package/dist/components/assets/asset-selection.js.map +1 -1
- package/dist/components/assets/asset-thumb.js +3 -2
- package/dist/components/assets/asset-thumb.js.map +1 -1
- package/dist/components/assets/assets-collection-view-source.d.ts +3 -3
- package/dist/components/assets/assets-collection-view-source.js +9 -5
- package/dist/components/assets/assets-collection-view-source.js.map +1 -1
- package/dist/components/assets/assets-store.d.ts +14 -0
- package/dist/components/assets/assets-store.js +23 -1
- package/dist/components/assets/assets-store.js.map +1 -1
- package/dist/components/assets/replace-file.d.ts +22 -0
- package/dist/components/assets/replace-file.js +59 -0
- package/dist/components/assets/replace-file.js.map +1 -0
- package/dist/components/builder/blocks-model.d.ts +14 -26
- package/dist/components/builder/blocks-model.js +35 -41
- package/dist/components/builder/blocks-model.js.map +1 -1
- package/dist/components/builder/blocks-panel.d.ts +7 -3
- package/dist/components/builder/blocks-panel.js +6 -5
- package/dist/components/builder/blocks-panel.js.map +1 -1
- package/dist/components/builder/builder-store.d.ts +126 -30
- package/dist/components/builder/builder-store.js +169 -67
- package/dist/components/builder/builder-store.js.map +1 -1
- package/dist/components/builder/canvas-body.d.ts +30 -0
- package/dist/components/builder/canvas-body.js +38 -0
- package/dist/components/builder/canvas-body.js.map +1 -0
- package/dist/components/builder/canvas-chrome-css.js +7 -0
- package/dist/components/builder/canvas-chrome-css.js.map +1 -1
- package/dist/components/builder/canvas-dnd.d.ts +7 -7
- package/dist/components/builder/canvas-dnd.js +5 -5
- package/dist/components/builder/canvas-dnd.js.map +1 -1
- package/dist/components/builder/canvas-render-context.d.ts +30 -22
- package/dist/components/builder/canvas-render-context.js +44 -44
- package/dist/components/builder/canvas-render-context.js.map +1 -1
- package/dist/components/builder/canvas-runs.d.ts +45 -0
- package/dist/components/builder/canvas-runs.js +51 -0
- package/dist/components/builder/canvas-runs.js.map +1 -0
- package/dist/components/builder/canvas.d.ts +5 -4
- package/dist/components/builder/canvas.js +34 -6
- package/dist/components/builder/canvas.js.map +1 -1
- package/dist/components/builder/clipboard-actions.d.ts +15 -0
- package/dist/components/builder/clipboard-actions.js +50 -13
- package/dist/components/builder/clipboard-actions.js.map +1 -1
- package/dist/components/builder/composition-field-editor.d.ts +10 -16
- package/dist/components/builder/composition-field-editor.js +30 -40
- package/dist/components/builder/composition-field-editor.js.map +1 -1
- package/dist/components/builder/composition-patches.d.ts +7 -0
- package/dist/components/builder/composition-patches.js +256 -0
- package/dist/components/builder/composition-patches.js.map +1 -0
- package/dist/components/builder/delete-key.d.ts +5 -0
- package/dist/components/builder/delete-key.js +4 -0
- package/dist/components/builder/delete-key.js.map +1 -1
- package/dist/components/builder/insert-context.d.ts +17 -25
- package/dist/components/builder/insert-context.js +45 -92
- package/dist/components/builder/insert-context.js.map +1 -1
- package/dist/components/builder/page-tree.d.ts +3 -3
- package/dist/components/builder/page-tree.js +3 -3
- package/dist/components/builder/page-tree.js.map +1 -1
- package/dist/components/builder/placement-refusal.d.ts +18 -0
- package/dist/components/builder/placement-refusal.js +46 -0
- package/dist/components/builder/placement-refusal.js.map +1 -0
- package/dist/components/builder/property-inspector.js +4 -0
- package/dist/components/builder/property-inspector.js.map +1 -1
- package/dist/components/builder/reuse-context.js +65 -26
- package/dist/components/builder/reuse-context.js.map +1 -1
- package/dist/components/builder/reuse.d.ts +79 -8
- package/dist/components/builder/reuse.js +71 -23
- package/dist/components/builder/reuse.js.map +1 -1
- package/dist/components/builder/run-inspector.d.ts +11 -0
- package/dist/components/builder/run-inspector.js +33 -0
- package/dist/components/builder/run-inspector.js.map +1 -0
- package/dist/components/cms/asset-field.d.ts +38 -1
- package/dist/components/cms/asset-field.js +182 -58
- package/dist/components/cms/asset-field.js.map +1 -1
- package/dist/components/cms/asset-picker-core.d.ts +16 -0
- package/dist/components/cms/asset-picker-core.js +20 -0
- package/dist/components/cms/asset-picker-core.js.map +1 -1
- package/dist/components/cms/asset-picker.js +12 -18
- package/dist/components/cms/asset-picker.js.map +1 -1
- package/dist/components/cms/bulk-actions.d.ts +4 -20
- package/dist/components/cms/bulk-actions.js +3 -24
- package/dist/components/cms/bulk-actions.js.map +1 -1
- package/dist/components/cms/cell-edit.d.ts +5 -5
- package/dist/components/cms/cell-edit.js.map +1 -1
- package/dist/components/cms/cell.js.map +1 -1
- package/dist/components/cms/cms-store.d.ts +87 -45
- package/dist/components/cms/cms-store.js +347 -203
- package/dist/components/cms/cms-store.js.map +1 -1
- package/dist/components/cms/collection-table.js +7 -2
- package/dist/components/cms/collection-table.js.map +1 -1
- package/dist/components/cms/commit-policy.d.ts +24 -0
- package/dist/components/cms/commit-policy.js +37 -0
- package/dist/components/cms/commit-policy.js.map +1 -0
- package/dist/components/cms/detail-editor.js +83 -137
- package/dist/components/cms/detail-editor.js.map +1 -1
- package/dist/components/cms/document-diff-view.d.ts +3 -1
- package/dist/components/cms/document-diff-view.js +12 -7
- package/dist/components/cms/document-diff-view.js.map +1 -1
- package/dist/components/cms/draft-commit.d.ts +70 -0
- package/dist/components/cms/draft-commit.js +82 -0
- package/dist/components/cms/draft-commit.js.map +1 -0
- package/dist/components/cms/duplicate-document.d.ts +11 -13
- package/dist/components/cms/duplicate-document.js +26 -34
- package/dist/components/cms/duplicate-document.js.map +1 -1
- package/dist/components/cms/field-anchors.d.ts +7 -4
- package/dist/components/cms/field-anchors.js +9 -7
- package/dist/components/cms/field-anchors.js.map +1 -1
- package/dist/components/cms/field-collaboration.d.ts +47 -0
- package/dist/components/cms/field-collaboration.js +87 -0
- package/dist/components/cms/field-collaboration.js.map +1 -0
- package/dist/components/cms/field-control-lib.d.ts +22 -1
- package/dist/components/cms/field-control-lib.js +33 -4
- package/dist/components/cms/field-control-lib.js.map +1 -1
- package/dist/components/cms/field-control.js +17 -14
- package/dist/components/cms/field-control.js.map +1 -1
- package/dist/components/cms/gate-validation.d.ts +21 -30
- package/dist/components/cms/gate-validation.js +11 -22
- package/dist/components/cms/gate-validation.js.map +1 -1
- package/dist/components/cms/object-array-field.js +4 -4
- package/dist/components/cms/object-array-field.js.map +1 -1
- package/dist/components/cms/prop-fields.d.ts +7 -2
- package/dist/components/cms/prop-fields.js +13 -6
- package/dist/components/cms/prop-fields.js.map +1 -1
- package/dist/components/cms/reference-confirm.js +10 -4
- package/dist/components/cms/reference-confirm.js.map +1 -1
- package/dist/components/cms/rich-text/embed-picker.d.ts +1 -1
- package/dist/components/cms/rich-text/embed-picker.js.map +1 -1
- package/dist/components/cms/rich-text/insert.d.ts +20 -9
- package/dist/components/cms/rich-text/insert.js +25 -17
- package/dist/components/cms/rich-text/insert.js.map +1 -1
- package/dist/components/cms/use-document-draft.d.ts +96 -0
- package/dist/components/cms/use-document-draft.js +283 -0
- package/dist/components/cms/use-document-draft.js.map +1 -0
- package/dist/components/cms/use-document-versions.js +2 -2
- package/dist/components/cms/use-document-versions.js.map +1 -1
- package/dist/components/cms/use-live-url.d.ts +6 -12
- package/dist/components/cms/use-live-url.js +16 -15
- package/dist/components/cms/use-live-url.js.map +1 -1
- package/dist/components/cms/use-publish-controller.d.ts +13 -18
- package/dist/components/cms/use-publish-controller.js +24 -41
- package/dist/components/cms/use-publish-controller.js.map +1 -1
- package/dist/components/cms/use-published-perspective.d.ts +2 -3
- package/dist/components/cms/use-published-perspective.js +4 -3
- package/dist/components/cms/use-published-perspective.js.map +1 -1
- package/dist/components/cms/versions-pane.js +8 -1
- package/dist/components/cms/versions-pane.js.map +1 -1
- package/dist/components/collection-view/cms-collection-view-source.js +24 -7
- package/dist/components/collection-view/cms-collection-view-source.js.map +1 -1
- package/dist/components/components/transfer-dialog.js +28 -23
- package/dist/components/components/transfer-dialog.js.map +1 -1
- package/dist/components/components/transfer.d.ts +31 -21
- package/dist/components/components/transfer.js +49 -35
- package/dist/components/components/transfer.js.map +1 -1
- package/dist/components/project-list.js.map +1 -1
- package/dist/components/project-session.d.ts +6 -3
- package/dist/components/project-session.js +14 -8
- package/dist/components/project-session.js.map +1 -1
- package/dist/components/project-switcher.js.map +1 -1
- package/dist/components/rail-view-source.js +2 -1
- package/dist/components/rail-view-source.js.map +1 -1
- package/dist/components/section-nav.js +1 -1
- package/dist/components/section-nav.js.map +1 -1
- package/dist/lib/ai/apply-content.js +56 -116
- package/dist/lib/ai/apply-content.js.map +1 -1
- package/dist/lib/ai/chat-context.d.ts +8 -0
- package/dist/lib/ai/chat-context.js +37 -6
- package/dist/lib/ai/chat-context.js.map +1 -1
- package/dist/lib/ai/chat-state.d.ts +14 -1
- package/dist/lib/ai/chat-state.js.map +1 -1
- package/dist/lib/ai/constraints.d.ts +20 -5
- package/dist/lib/ai/constraints.js +125 -33
- package/dist/lib/ai/constraints.js.map +1 -1
- package/dist/lib/ai/fake-provider.d.ts +16 -3
- package/dist/lib/ai/fake-provider.js +22 -6
- package/dist/lib/ai/fake-provider.js.map +1 -1
- package/dist/lib/ai/index.d.ts +2 -0
- package/dist/lib/ai/index.js +2 -0
- package/dist/lib/ai/index.js.map +1 -1
- package/dist/lib/ai/leash.d.ts +34 -0
- package/dist/lib/ai/leash.js +28 -0
- package/dist/lib/ai/leash.js.map +1 -0
- package/dist/lib/ai/provenance.d.ts +1 -1
- package/dist/lib/ai/provenance.js.map +1 -1
- package/dist/lib/ai/rich-text-input.d.ts +8 -8
- package/dist/lib/ai/rich-text-input.js +2 -1
- package/dist/lib/ai/rich-text-input.js.map +1 -1
- package/dist/lib/ai/rich-text-translate.d.ts +27 -4
- package/dist/lib/ai/rich-text-translate.js +28 -10
- package/dist/lib/ai/rich-text-translate.js.map +1 -1
- package/dist/lib/ai/shape.d.ts +13 -13
- package/dist/lib/ai/shape.js +69 -93
- package/dist/lib/ai/shape.js.map +1 -1
- package/dist/lib/ai/tools.d.ts +36 -41
- package/dist/lib/ai/tools.js +85 -87
- package/dist/lib/ai/tools.js.map +1 -1
- package/dist/lib/ai/translate-document.d.ts +39 -5
- package/dist/lib/ai/translate-document.js +160 -51
- package/dist/lib/ai/translate-document.js.map +1 -1
- package/dist/lib/ai/types.d.ts +34 -23
- package/dist/lib/ai/types.js.map +1 -1
- package/dist/lib/ai/update-fields.d.ts +21 -12
- package/dist/lib/ai/update-fields.js +118 -177
- package/dist/lib/ai/update-fields.js.map +1 -1
- package/dist/lib/ai/writer-form.d.ts +116 -0
- package/dist/lib/ai/writer-form.js +429 -0
- package/dist/lib/ai/writer-form.js.map +1 -0
- package/dist/lib/ai-current-document.d.ts +11 -11
- package/dist/lib/ai-current-document.js +4 -4
- package/dist/lib/ai-current-document.js.map +1 -1
- package/dist/lib/assets/upload.d.ts +31 -2
- package/dist/lib/assets/upload.js +61 -6
- package/dist/lib/assets/upload.js.map +1 -1
- package/dist/lib/clipboard/os-clipboard.d.ts +10 -2
- package/dist/lib/clipboard/os-clipboard.js +8 -4
- package/dist/lib/clipboard/os-clipboard.js.map +1 -1
- package/dist/lib/clipboard/paste-target.d.ts +18 -9
- package/dist/lib/clipboard/paste-target.js +8 -7
- package/dist/lib/clipboard/paste-target.js.map +1 -1
- package/dist/lib/cms/field-patch.d.ts +15 -0
- package/dist/lib/cms/field-patch.js +25 -0
- package/dist/lib/cms/field-patch.js.map +1 -0
- package/dist/lib/cms/published-documents.d.ts +1 -1
- package/dist/lib/cms/published-documents.js +1 -1
- package/dist/lib/cms/published-documents.js.map +1 -1
- package/dist/lib/cms-views/view-model.d.ts +3 -3
- package/dist/lib/collection-view/__fixtures__/document-writes.d.ts +6 -0
- package/dist/lib/collection-view/__fixtures__/document-writes.js +23 -0
- package/dist/lib/collection-view/__fixtures__/document-writes.js.map +1 -0
- package/dist/lib/collection-view/collection-view-source.d.ts +69 -6
- package/dist/lib/collection-view/collection-view-source.js.map +1 -1
- package/dist/lib/data/collection-content.d.ts +4 -13
- package/dist/lib/data/collection-content.js +11 -5
- package/dist/lib/data/collection-content.js.map +1 -1
- package/dist/lib/dnd/drop-rules.d.ts +25 -31
- package/dist/lib/dnd/drop-rules.js +53 -59
- package/dist/lib/dnd/drop-rules.js.map +1 -1
- package/dist/lib/engine-version.d.ts +1 -1
- package/dist/lib/engine-version.js +1 -1
- package/dist/lib/engine-version.js.map +1 -1
- package/dist/lib/i18n/messages.de.js +72 -15
- package/dist/lib/i18n/messages.de.js.map +1 -1
- package/dist/lib/i18n/messages.en.d.ts +61 -12
- package/dist/lib/i18n/messages.en.js +76 -16
- package/dist/lib/i18n/messages.en.js.map +1 -1
- package/dist/lib/operations/__fixtures__/write-document.d.ts +30 -0
- package/dist/lib/operations/__fixtures__/write-document.js +16 -0
- package/dist/lib/operations/__fixtures__/write-document.js.map +1 -0
- package/dist/lib/operations/cms-persistence.d.ts +124 -31
- package/dist/lib/operations/cms-persistence.js +447 -68
- package/dist/lib/operations/cms-persistence.js.map +1 -1
- package/dist/lib/operations/config-manifest-lookup.d.ts +35 -0
- package/dist/lib/operations/config-manifest-lookup.js +56 -0
- package/dist/lib/operations/config-manifest-lookup.js.map +1 -0
- package/dist/lib/operations/project-runtime-config.d.ts +39 -0
- package/dist/lib/operations/project-runtime-config.js +54 -0
- package/dist/lib/operations/project-runtime-config.js.map +1 -0
- package/dist/lib/operations/publish-with-revision.d.ts +64 -0
- package/dist/lib/operations/publish-with-revision.js +66 -0
- package/dist/lib/operations/publish-with-revision.js.map +1 -0
- package/dist/lib/operations/runtime-validator.d.ts +32 -0
- package/dist/lib/operations/runtime-validator.js +18 -0
- package/dist/lib/operations/runtime-validator.js.map +1 -0
- package/dist/lib/operations/session-hydration.d.ts +31 -14
- package/dist/lib/operations/session-hydration.js +12 -16
- package/dist/lib/operations/session-hydration.js.map +1 -1
- package/dist/lib/operations/studio-operations.d.ts +59 -2
- package/dist/lib/operations/studio-operations.js +76 -14
- package/dist/lib/operations/studio-operations.js.map +1 -1
- package/dist/lib/persistence/convex-adapter.d.ts +13 -5
- package/dist/lib/persistence/convex-adapter.js +189 -74
- package/dist/lib/persistence/convex-adapter.js.map +1 -1
- package/dist/lib/persistence/convex-client.d.ts +65 -5
- package/dist/lib/persistence/convex-client.js +106 -3
- package/dist/lib/persistence/convex-client.js.map +1 -1
- package/dist/lib/persistence/index.js +17 -18
- package/dist/lib/persistence/index.js.map +1 -1
- package/dist/lib/persona/labels.js +4 -1
- package/dist/lib/persona/labels.js.map +1 -1
- package/dist/lib/query/operations-query.d.ts +1 -1
- package/dist/lib/query/operations-query.js +1 -1
- package/dist/lib/query/operations-query.js.map +1 -1
- package/dist/lib/references/impact.d.ts +21 -15
- package/dist/lib/references/impact.js +13 -26
- package/dist/lib/references/impact.js.map +1 -1
- package/dist/lib/references/references-store.d.ts +9 -0
- package/dist/lib/references/references-store.js +24 -4
- package/dist/lib/references/references-store.js.map +1 -1
- package/dist/lib/routes/route-issues.d.ts +6 -6
- package/dist/lib/routes/route-issues.js +26 -80
- package/dist/lib/routes/route-issues.js.map +1 -1
- package/dist/lib/workspace/config-issues.js +2 -1
- package/dist/lib/workspace/config-issues.js.map +1 -1
- package/dist/lib/workspace/index.d.ts +31 -1
- package/dist/lib/workspace/index.js +64 -17
- package/dist/lib/workspace/index.js.map +1 -1
- package/dist/lib/workspace/switcher-source.d.ts +3 -3
- package/dist/lib/workspace/switcher-source.js.map +1 -1
- package/dist/lib/workspace/workspace-source.d.ts +2 -2
- package/dist/lib/workspace/workspace-source.js +2 -1
- package/dist/lib/workspace/workspace-source.js.map +1 -1
- package/package.json +3 -3
- package/dist/components/cms/cms-composition-validators.d.ts +0 -16
- package/dist/components/cms/cms-composition-validators.js +0 -133
- package/dist/components/cms/cms-composition-validators.js.map +0 -1
- package/dist/components/cms/publish-clean.d.ts +0 -28
- package/dist/components/cms/publish-clean.js +0 -38
- package/dist/components/cms/publish-clean.js.map +0 -1
- package/dist/components/cms/use-save-mode.d.ts +0 -35
- package/dist/components/cms/use-save-mode.js +0 -54
- package/dist/components/cms/use-save-mode.js.map +0 -1
- package/dist/lib/assets/asset-placements.d.ts +0 -28
- package/dist/lib/assets/asset-placements.js +0 -83
- package/dist/lib/assets/asset-placements.js.map +0 -1
- package/dist/lib/cms/document-gate.d.ts +0 -47
- package/dist/lib/cms/document-gate.js +0 -61
- package/dist/lib/cms/document-gate.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document-diff-view.js","sourceRoot":"","sources":["../../../src/components/cms/document-diff-view.tsx"],"names":[],"mappings":"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","sourcesContent":["import { createContext, useCallback, useContext, useMemo, useState } from 'react'\nimport type { ReactNode } from 'react'\nimport { Image as ImageIcon, RotateCcw } from 'lucide-react'\nimport type { BlockChange, ChangeKind, DocumentDiff, FieldChange, PropChange } from '@elytracms/core/content'\nimport { assetSubfieldsOf, isAssetNode, readAssetId, readDocumentRef } from '@elytracms/core/cms-core'\nimport type { CollectionDef, FieldDef, RestoreScope } from '@elytracms/core/cms-core'\nimport { Badge, Button, Code, Row, Spacer, Stack, Text } from '@elytracms/studio/ui'\nimport { translate } from '@elytracms/studio/lib/i18n'\nimport { localeChipLabel } from '@elytracms/studio/lib/locale'\nimport { cn } from '@elytracms/studio/lib/utils'\nimport { readDiffViewMode, storeDiffViewMode } from '@elytracms/studio/lib/diff-view-preference'\nimport type { DiffViewMode } from '@elytracms/studio/lib/diff-view-preference'\nimport { isDisplayableAssetUrl } from '@elytracms/studio/lib/assets'\nimport { useCollectionView } from '../collection-view/collection-view-context'\nimport { fieldLabel } from './cms-labels'\nimport { toRefArray } from './cell'\nimport { RichTextPreview, isRichTextValueEmpty } from './rich-text-preview'\nimport {\n DIFF_TRUNCATE_THRESHOLD,\n mergeWordDiff,\n richTextToText,\n truncateText,\n truncateTokensAroundChange,\n wordDiff,\n} from './version-compare-text'\nimport type { AnchoredExcerpt, MergedDiffToken, WordToken } from './version-compare-text'\n\n/**\n * The shared document-diff RENDERER (EC-317 change-list), extracted from\n * `VersionCompare` so a single renderer serves both the version-compare surface and\n * the EC-199 AI proposal review — never two diff renderers. It draws a `DocumentDiff`\n * ({@link diffDocuments}) as the calm change-list grouped BY FIELD: a descriptor lane,\n * before | after (or a unified lane), text as a prose diff, assets as thumbnails,\n * relations as titles, long values collapsed behind \"Show more\", zebra rows.\n *\n * It is display-only over an already-computed diff: the version chrome (version\n * pickers / steppers / restore-whole) stays in `VersionCompare`; the AI proposal card\n * feeds `diffDocuments(collection, emptyBefore, proposedAfter)` and omits `restore`.\n * The per-row restore affordance renders only when `restore.canRestore` is set, so the\n * AI review (a not-yet-saved proposal) shows a clean, restore-free diff.\n *\n * **Layout (EC-382).** One diff LOGIC, two presentations selected by `layout`:\n * `'grid'` (default) is the wide version-compare surface — a fixed descriptor lane\n * plus a unified/side-by-side value area. `'stacked'` is the sidebar-fit variant the\n * AI proposal card selects: each field is a full-width card (label header, then\n * `Current → Proposed` VERTICALLY) that reads at ~320px without a squished two-column\n * split. Only chrome + column arrangement branch on `layout`; grouping, word diffing,\n * and change detection are shared — never forked.\n *\n * Must be rendered under a `CollectionViewProvider` (the value renderers resolve\n * relation titles / asset thumbnails through `useCollectionView`).\n */\nexport type DiffLayout = 'grid' | 'stacked'\nexport interface DocumentDiffRestore {\n baseVersion: number\n canRestore: boolean\n busy: boolean\n onRestore: (scope: RestoreScope) => void\n}\n\nexport interface DocumentDiffViewProps {\n diff: DocumentDiff\n collection: CollectionDef\n /** Pre-rendered column captions (version-specific text stays with the caller). */\n columnHeaders: { unified: string; before: string; after: string }\n /** Per-row restore controls; omitted ⇒ a restore-free read-only diff (AI review). */\n restore?: DocumentDiffRestore\n /** Extra note appended to the change-count summary (e.g. a comparing-past hint). */\n summaryHint?: ReactNode\n /** Presentation variant (EC-382). Defaults to the wide `'grid'` compare layout. */\n layout?: DiffLayout\n}\n\nexport function DocumentDiffView({\n diff,\n collection,\n columnHeaders,\n restore,\n summaryHint,\n layout = 'grid',\n}: DocumentDiffViewProps) {\n const source = useCollectionView()\n\n // EC-317 — the unified/side-by-side toggle is a transient, personal-local view\n // preference: read once at mount, written back on every change.\n const [mode, setModeState] = useState<DiffViewMode>(() => readDiffViewMode())\n const setMode = useCallback((next: DiffViewMode) => {\n setModeState(next)\n storeDiffViewMode(next)\n }, [])\n\n // EC-317 — long-value truncation state: an `expandAll` flag plus per-row overrides.\n const [expandAll, setExpandAll] = useState(false)\n const [expandedRows, setExpandedRows] = useState<ReadonlySet<string>>(() => new Set())\n const toggleExpand = useCallback((id: string) => {\n setExpandedRows((prev) => {\n const next = new Set(prev)\n if (next.has(id)) next.delete(id)\n else next.add(id)\n return next\n })\n }, [])\n const isExpanded = useCallback((id: string) => expandAll || expandedRows.has(id), [expandAll, expandedRows])\n const toggleExpandAll = useCallback(() => {\n setExpandAll((prev) => {\n const next = !prev\n if (!next) setExpandedRows(new Set())\n return next\n })\n }, [])\n const captions = useMemo(\n () => ({ before: columnHeaders.before, after: columnHeaders.after }),\n [columnHeaders.before, columnHeaders.after],\n )\n const diffDisplay = useMemo<DiffDisplayState>(\n () => ({ mode, layout, captions, expandAll, isExpanded, toggleExpand }),\n [mode, layout, captions, expandAll, isExpanded, toggleExpand],\n )\n\n const fieldOrder = useMemo(() => new Map(collection.fields.map((f, i) => [f.name, i])), [collection])\n const fieldByName = useMemo(() => new Map(collection.fields.map((f) => [f.name, f])), [collection])\n const localeRank = useMemo(() => new Map(source.localeConfig.locales.map((l, i) => [l, i])), [source.localeConfig])\n const groups = useMemo(\n () => groupByField(diff.changes, fieldOrder, localeRank),\n [diff.changes, fieldOrder, localeRank],\n )\n const groupRows = useMemo(() => {\n let rowIndex = 0\n return groups.map((group) => {\n const zebraStart = rowIndex\n rowIndex += group.entries.length\n return { group, field: fieldByName.get(group.field), zebraStart }\n })\n }, [groups, fieldByName])\n\n const canRestore = restore?.canRestore ?? false\n const baseVersion = restore?.baseVersion ?? 0\n const busy = restore?.busy ?? false\n const restoreFn = useCallback(\n (scope: RestoreScope) => restore?.onRestore(scope),\n [restore],\n )\n\n const summary = (\n <Text size=\"xs\" tone=\"muted\" className=\"px-0.5\">\n {translate(diff.changes.length === 1 ? 'cms.version.changeSummary.one' : 'cms.version.changeSummary.other', {\n count: diff.changes.length,\n unchanged: diff.unchangedCount,\n })}\n {summaryHint}\n </Text>\n )\n const expandAllButton = (\n <Button variant=\"ghost\" size=\"sm\" onClick={toggleExpandAll}>\n {translate(expandAll ? 'cms.field.collapseAll' : 'cms.field.expandAll')}\n </Button>\n )\n\n // EC-382 — the sidebar-fit variant: no two-column split to toggle, so the\n // unified/side-by-side control is dropped; each field is a full-width card\n // that lays Current → Proposed out vertically.\n if (layout === 'stacked') {\n return (\n <DiffDisplayContext.Provider value={diffDisplay}>\n <Stack gap=\"2\">\n <Row gap=\"2\" align=\"center\" justify=\"between\" wrap className=\"px-0.5\">\n {summary}\n {expandAllButton}\n </Row>\n <Stack gap=\"2\" className=\"pb-1\">\n {groupRows.map(({ group, field }) => (\n <FieldGroup\n key={group.field}\n group={group}\n field={field}\n zebraStart={0}\n baseVersion={baseVersion}\n canRestore={canRestore}\n busy={busy}\n onRestore={restoreFn}\n />\n ))}\n </Stack>\n </Stack>\n </DiffDisplayContext.Provider>\n )\n }\n\n return (\n <>\n {/* EC-317 — the diff-layout toolbar: unified/side-by-side (persisted) + expand-all. */}\n <Row gap=\"2\" align=\"center\" justify=\"between\" wrap className=\"px-0.5\">\n <DiffViewToggle mode={mode} onChange={setMode} />\n {expandAllButton}\n </Row>\n\n {summary}\n\n <DiffDisplayContext.Provider value={diffDisplay}>\n <div className=\"pb-1\">\n <div className={cn(DIFF_ROW_GRID, 'px-2 pb-1.5')}>\n <Text size=\"xs\" tone=\"subtle\" className=\"uppercase tracking-wide\">\n {translate('cms.version.fieldColumnHeader')}\n </Text>\n {mode === 'unified' ? (\n <Text size=\"xs\" tone=\"subtle\" className=\"uppercase tracking-wide\">\n {columnHeaders.unified}\n </Text>\n ) : (\n <TwoCol\n before={\n <Text size=\"xs\" tone=\"subtle\" className=\"uppercase tracking-wide\">\n {columnHeaders.before}\n </Text>\n }\n after={\n <Text size=\"xs\" tone=\"subtle\" className=\"uppercase tracking-wide\">\n {columnHeaders.after}\n </Text>\n }\n />\n )}\n </div>\n {groupRows.map(({ group, field, zebraStart }) => (\n <FieldGroup\n key={group.field}\n group={group}\n field={field}\n zebraStart={zebraStart}\n baseVersion={baseVersion}\n canRestore={canRestore}\n busy={busy}\n onRestore={restoreFn}\n />\n ))}\n </div>\n </DiffDisplayContext.Provider>\n </>\n )\n}\n\n// --- EC-317 diff-display context (mode + truncation) ------------------------------\n\ninterface DiffDisplayState {\n mode: DiffViewMode\n /** EC-382 — the active presentation variant; value renderers branch on it. */\n layout: DiffLayout\n /** EC-382 — the Current/Proposed captions, shown inline per side in `stacked`. */\n captions: { before: string; after: string }\n expandAll: boolean\n isExpanded: (id: string) => boolean\n toggleExpand: (id: string) => void\n}\n\nconst DiffDisplayContext = createContext<DiffDisplayState | null>(null)\n\nfunction useDiffDisplay(): DiffDisplayState {\n const ctx = useContext(DiffDisplayContext)\n if (!ctx) throw new Error('useDiffDisplay must be rendered under the DocumentDiffView diff area')\n return ctx\n}\n\n/** Shared grid template so the descriptor lane + header captions line up. */\nconst DIFF_ROW_GRID = 'grid grid-cols-[7.5rem_1fr_1.75rem] items-start gap-x-4'\n\n/** A before | after grid with a clear central divider. */\nfunction TwoCol({ before, after, className }: { before: ReactNode; after: ReactNode; className?: string }) {\n return (\n <div className={cn('relative grid grid-cols-2 gap-x-8', className)}>\n <div className=\"pointer-events-none absolute inset-y-0 left-1/2 w-px -translate-x-1/2 bg-border\" aria-hidden />\n <div className=\"min-w-0 pr-1\">{before}</div>\n <div className=\"min-w-0 pl-1\">{after}</div>\n </div>\n )\n}\n\n/** Mode-aware value display (EC-317) / layout-aware in the EC-382 stacked variant. */\nfunction DiffColumns({ before, after, kind }: { before: ReactNode; after: ReactNode; kind: ChangeKind }) {\n const { mode, layout } = useDiffDisplay()\n if (layout === 'stacked') {\n return <StackedColumns before={before} after={after} kind={kind} />\n }\n if (mode === 'unified') {\n return (\n <Stack gap=\"1\">\n {kind !== 'added' ? <UnifiedLine tone=\"removed\">{before}</UnifiedLine> : null}\n {kind !== 'removed' ? <UnifiedLine tone=\"added\">{after}</UnifiedLine> : null}\n </Stack>\n )\n }\n return <TwoCol before={before} after={after} />\n}\n\n/**\n * EC-382 stacked value display: `Current` above `Proposed`, each captioned and\n * accented, full width — the sidebar-fit answer to the squished two-column split.\n * An `added` change shows only the proposed side; a `removed` change only current.\n */\nfunction StackedColumns({ before, after, kind }: { before: ReactNode; after: ReactNode; kind: ChangeKind }) {\n const { captions } = useDiffDisplay()\n return (\n <Stack gap=\"2\">\n {kind !== 'added' ? (\n <StackedSide caption={captions.before} tone=\"before\">\n {before}\n </StackedSide>\n ) : null}\n {kind !== 'removed' ? (\n <StackedSide caption={captions.after} tone=\"after\">\n {after}\n </StackedSide>\n ) : null}\n </Stack>\n )\n}\n\n/** One captioned side of a stacked change (EC-382). */\nfunction StackedSide({\n caption,\n tone,\n children,\n}: {\n caption: string\n tone: 'before' | 'after'\n children: ReactNode\n}) {\n return (\n <Stack gap=\"1\">\n <Text size=\"xs\" tone=\"subtle\" className=\"uppercase tracking-wide\">\n {caption}\n </Text>\n <div\n className={cn(\n 'min-w-0 border-l-2 pl-2.5',\n tone === 'before' ? 'border-border' : 'border-primary/60',\n )}\n >\n {children}\n </div>\n </Stack>\n )\n}\n\nfunction UnifiedLine({ tone, children }: { tone: 'removed' | 'added'; children: ReactNode }) {\n return (\n <Row\n gap=\"2\"\n align=\"start\"\n className={cn('rounded-sm px-1.5 py-1', tone === 'removed' ? 'bg-destructive/10' : 'bg-success/10')}\n >\n <Text\n size=\"xs\"\n mono\n aria-hidden\n className={cn('mt-0.5 shrink-0 select-none', tone === 'removed' ? 'text-destructive' : 'text-success')}\n >\n {tone === 'removed' ? '−' : '+'}\n </Text>\n <div className=\"min-w-0 flex-1\">{children}</div>\n </Row>\n )\n}\n\n/** Wraps truncatable content with its per-row \"Show more\"/\"Show less\" control. */\nfunction ExpandToggle({\n id,\n isLong,\n expanded,\n children,\n}: {\n id: string\n isLong: boolean\n expanded: boolean\n children: ReactNode\n}) {\n const { expandAll, toggleExpand } = useDiffDisplay()\n return (\n <div>\n {children}\n {isLong && !expandAll ? (\n <Button variant=\"link\" size=\"sm\" className=\"h-auto p-0 text-xs\" onClick={() => toggleExpand(id)}>\n {expanded ? translate('cms.version.showLess') : translate('cms.version.showMore')}\n </Button>\n ) : null}\n </div>\n )\n}\n\n/** The unified/side-by-side segmented toggle (EC-317). */\nfunction DiffViewToggle({ mode, onChange }: { mode: DiffViewMode; onChange: (mode: DiffViewMode) => void }) {\n return (\n <Row\n gap=\"px\"\n className=\"rounded-md bg-muted/50 p-0.5\"\n role=\"group\"\n aria-label={translate('cms.version.viewModeAriaLabel')}\n data-testid=\"diff-view-toggle\"\n >\n <DiffViewOption\n active={mode === 'sideBySide'}\n label={translate('cms.version.viewSideBySide')}\n onClick={() => onChange('sideBySide')}\n />\n <DiffViewOption\n active={mode === 'unified'}\n label={translate('cms.version.viewUnified')}\n onClick={() => onChange('unified')}\n />\n </Row>\n )\n}\n\nfunction DiffViewOption({ active, label, onClick }: { active: boolean; label: string; onClick: () => void }) {\n return (\n <button\n type=\"button\"\n aria-pressed={active}\n data-testid={`diff-view-option-${active ? 'active' : 'inactive'}`}\n onClick={onClick}\n className={cn(\n 'rounded-[5px] px-2.5 py-1 text-xs font-medium transition-colors',\n active ? 'bg-background text-foreground shadow-sm' : 'text-muted-foreground hover:text-foreground',\n )}\n >\n {label}\n </button>\n )\n}\n\ninterface FieldGroupData {\n field: string\n label: string\n type: FieldDef['type']\n entries: FieldChange[]\n}\n\n/** One field's diff rows (EC-317 grid rows / EC-382 stacked cards). */\nfunction FieldGroup({\n group,\n field,\n zebraStart,\n baseVersion,\n canRestore,\n busy,\n onRestore,\n}: {\n group: FieldGroupData\n field: FieldDef | undefined\n zebraStart: number\n baseVersion: number\n canRestore: boolean\n busy: boolean\n onRestore: (scope: RestoreScope) => void\n}) {\n const { layout } = useDiffDisplay()\n const label = field ? fieldLabel(field) : group.label\n const rows = group.entries.map((entry, i) => {\n const rowId = `${group.field}:${entry.locale ?? '_'}`\n const fieldRestore =\n canRestore && !entry.blocks ? (\n <RestoreIcon\n busy={busy}\n title={\n entry.locale\n ? translate('cms.version.restoreFieldLocale', {\n field: label,\n locale: localeChipLabel(entry.locale),\n version: baseVersion,\n })\n : translate('cms.version.restoreField', { field: label, version: baseVersion })\n }\n onClick={() => onRestore(fieldScope(entry))}\n />\n ) : null\n const descriptor = (\n <FieldDescriptor label={label} locale={entry.locale} kind={entry.kind} inline={layout === 'stacked'} />\n )\n const body = (\n <EntryBody\n change={entry}\n rowId={rowId}\n baseVersion={baseVersion}\n canRestore={canRestore}\n busy={busy}\n onRestore={onRestore}\n />\n )\n return layout === 'stacked' ? (\n <StackedFieldRow key={entry.locale ?? '__base__'} descriptor={descriptor} restore={fieldRestore}>\n {body}\n </StackedFieldRow>\n ) : (\n <FieldRow\n key={entry.locale ?? '__base__'}\n zebra={(zebraStart + i) % 2 === 1}\n descriptor={descriptor}\n restore={fieldRestore}\n >\n {body}\n </FieldRow>\n )\n })\n if (layout === 'stacked') return <>{rows}</>\n return <div className=\"border-t border-border/30\">{rows}</div>\n}\n\n/** The descriptor lane + value area, one grid row (EC-317). */\nfunction FieldRow({\n descriptor,\n restore,\n zebra,\n children,\n}: {\n descriptor: ReactNode\n restore: ReactNode\n zebra: boolean\n children: ReactNode\n}) {\n return (\n <div className={cn(DIFF_ROW_GRID, 'rounded-sm px-2 py-2.5', zebra && 'bg-muted/40')}>\n <div className=\"min-w-0\">{descriptor}</div>\n <div className=\"min-w-0\">{children}</div>\n <div className=\"flex justify-end\">{restore}</div>\n </div>\n )\n}\n\n/**\n * One field as a full-width card (EC-382 stacked variant): a label header\n * (descriptor + restore) over a full-width value area — no fixed lane to squeeze\n * the value at sidebar width.\n */\nfunction StackedFieldRow({\n descriptor,\n restore,\n children,\n}: {\n descriptor: ReactNode\n restore: ReactNode\n children: ReactNode\n}) {\n return (\n <div className=\"overflow-hidden rounded-lg border border-border/60 bg-card\">\n <Row gap=\"2\" align=\"center\" className=\"border-b border-border/50 bg-muted/30 px-3 py-2\">\n <div className=\"min-w-0 flex-1\">{descriptor}</div>\n {restore}\n </Row>\n <div className=\"px-3 py-2.5\">{children}</div>\n </div>\n )\n}\n\n/** The descriptor content (EC-317 stacked lane / EC-382 inline card header). */\nfunction FieldDescriptor({\n label,\n locale,\n kind,\n inline = false,\n}: {\n label: string\n locale?: string\n kind: ChangeKind\n inline?: boolean\n}) {\n const localeBadge = locale ? (\n <Badge variant=\"outline\" className=\"px-1 py-0 text-[0.6rem] uppercase tracking-wide text-muted-foreground\">\n {localeChipLabel(locale)}\n </Badge>\n ) : null\n if (inline) {\n return (\n <Row gap=\"2\" align=\"center\" wrap className=\"min-w-0\">\n <Text size=\"sm\" weight=\"semibold\" className=\"min-w-0 truncate\">\n {label}\n </Text>\n {localeBadge}\n <KindTag kind={kind} />\n </Row>\n )\n }\n return (\n <Stack gap=\"1\">\n <Text size=\"sm\" weight=\"medium\" className=\"min-w-0 truncate\">\n {label}\n </Text>\n <Row gap=\"1\" wrap>\n {localeBadge}\n <KindTag kind={kind} />\n </Row>\n </Stack>\n )\n}\n\nfunction EntryBody({\n change,\n rowId,\n baseVersion,\n canRestore,\n busy,\n onRestore,\n}: {\n change: FieldChange\n rowId: string\n baseVersion: number\n canRestore: boolean\n busy: boolean\n onRestore: (scope: RestoreScope) => void\n}) {\n const localeScope = change.locale !== undefined ? { locale: change.locale } : {}\n if (change.blocks) {\n return (\n <Stack gap=\"2\" className=\"mt-1\">\n {change.blocks.map((block) => (\n <BlockSection\n key={block.blockId}\n block={block}\n rowId={`${rowId}|block:${block.blockId}`}\n baseVersion={baseVersion}\n canRestore={canRestore}\n busy={busy}\n onRestore={() => onRestore({ kind: 'block', field: change.field, blockId: block.blockId, ...localeScope })}\n />\n ))}\n </Stack>\n )\n }\n if (change.type === 'richText') {\n const before = richTextToText(change.before)\n const after = richTextToText(change.after)\n if (before === after && before) return <MutedNote>{translate('cms.version.textUnchanged')}</MutedNote>\n // Both sides carry text → the word diff pinpoints the edit.\n if (before && after) return <WordDiffCols id={rowId} before={before} after={after} />\n // EC-379: one side is (textually) empty — a create proposal, a cleared body,\n // or structure-only content. Render the ACTUAL prose so the editor reviews\n // what they are approving (retires the blind \"Content changed.\" note).\n return (\n <DiffColumns\n kind={change.kind}\n before={<RichTextSide value={change.before} id={`${rowId}|before`} />}\n after={<RichTextSide value={change.after} id={`${rowId}|after`} />}\n />\n )\n }\n if (change.kind === 'changed' && typeof change.before === 'string' && typeof change.after === 'string') {\n return <WordDiffCols id={rowId} before={change.before} after={change.after} />\n }\n return (\n <DiffColumns\n kind={change.kind}\n before={<SideValue value={change.before} other={change.after} typeHint={change.type} id={`${rowId}|before`} />}\n after={<SideValue value={change.after} other={change.before} typeHint={change.type} id={`${rowId}|after`} />}\n />\n )\n}\n\nfunction BlockSection({\n block,\n rowId,\n baseVersion,\n canRestore,\n busy,\n onRestore,\n}: {\n block: BlockChange\n rowId: string\n baseVersion: number\n canRestore: boolean\n busy: boolean\n onRestore: () => void\n}) {\n const name = block.componentId.split('.').pop() ?? block.componentId\n return (\n <div className=\"overflow-hidden rounded-md border border-border/60\">\n <Row gap=\"2\" align=\"center\" className=\"border-b border-border/50 bg-muted/30 px-2 py-1.5\">\n <Text size=\"xs\" weight=\"semibold\" className=\"min-w-0 truncate\">\n {name}\n </Text>\n <Code tone=\"muted\">{block.componentId}</Code>\n <KindTag kind={block.kind} />\n <Spacer />\n {canRestore ? (\n <RestoreIcon\n busy={busy}\n title={translate('cms.version.restoreBlock', { version: baseVersion })}\n onClick={onRestore}\n />\n ) : null}\n </Row>\n <div className=\"px-2 py-2\">\n {block.props && block.props.length > 0 ? (\n <Stack gap=\"3\" className=\"border-l-2 border-border/50 pl-3\">\n {block.props.map((prop) => (\n <PropRow key={prop.name} prop={prop} rowId={`${rowId}|prop:${prop.name}`} />\n ))}\n </Stack>\n ) : null}\n {block.slotsChanged ? <MutedNote>{translate('cms.version.nestedContentChanged')}</MutedNote> : null}\n {block.kind !== 'changed' && !block.props?.length ? (\n <MutedNote>\n {block.kind === 'added' ? translate('cms.version.blockAdded') : translate('cms.version.blockRemoved')}\n </MutedNote>\n ) : null}\n </div>\n </div>\n )\n}\n\nfunction PropRow({ prop, rowId }: { prop: PropChange; rowId: string }) {\n const useWordDiff = prop.kind === 'changed' && typeof prop.before === 'string' && typeof prop.after === 'string'\n return (\n <div>\n <Text size=\"xs\" tone=\"subtle\" className=\"mb-0.5 block uppercase tracking-wide\">\n {prettyName(prop.name)}\n </Text>\n {useWordDiff ? (\n <WordDiffCols id={rowId} before={String(prop.before)} after={String(prop.after)} />\n ) : (\n <DiffColumns\n kind={prop.kind}\n before={<SideValue value={prop.before} other={prop.after} id={`${rowId}|before`} />}\n after={<SideValue value={prop.after} other={prop.before} id={`${rowId}|after`} />}\n />\n )}\n </div>\n )\n}\n\n/**\n * One side of a rich-text change (EC-379): rendered compact prose\n * ({@link RichTextPreview}), height-clamped behind the shared expand toggle for\n * long bodies, with the standard \"empty\" placeholder for an absent side.\n */\nfunction RichTextSide({ value, id }: { value: unknown; id: string }) {\n const { isExpanded } = useDiffDisplay()\n if (isRichTextValueEmpty(value)) {\n return (\n <Text size=\"sm\" tone=\"subtle\" className=\"italic\">\n {translate('cms.version.emptyValue')}\n </Text>\n )\n }\n const expanded = isExpanded(id)\n const isLong = richTextToText(value).length > DIFF_TRUNCATE_THRESHOLD\n return (\n <ExpandToggle id={id} isLong={isLong} expanded={expanded}>\n <div className={cn(!expanded && isLong && 'max-h-60 overflow-hidden')}>\n <RichTextPreview value={value} />\n </div>\n </ExpandToggle>\n )\n}\n\n/** One side of a non-text change — the value, or an \"empty\" placeholder. */\nfunction SideValue({\n value,\n other,\n typeHint,\n id,\n}: {\n value: unknown\n other?: unknown\n typeHint?: FieldDef['type']\n id: string\n}) {\n if (value === undefined || value === null || value === '') {\n return (\n <Text size=\"sm\" tone=\"subtle\" className=\"italic\">\n {translate('cms.version.emptyValue')}\n </Text>\n )\n }\n return <ValueView value={value} other={other} typeHint={typeHint} id={id} />\n}\n\n/** Read-only value display, dispatching on field type / self-describing value shape. */\nfunction ValueView({\n value,\n other,\n typeHint,\n id,\n}: {\n value: unknown\n other?: unknown\n typeHint?: FieldDef['type']\n id: string\n}) {\n const { isExpanded } = useDiffDisplay()\n if (typeHint === 'asset' || isAssetNode(value)) return <AssetValue value={value} />\n if (typeHint === 'relation' || readDocumentRef(value)) return <RelationValue value={value} other={other} />\n if (typeHint === 'richText')\n return (\n <Text size=\"sm\" className=\"whitespace-pre-wrap break-words\">\n {richTextToText(value) || translate('cms.version.richText')}\n </Text>\n )\n if (typeHint === 'boolean' || typeof value === 'boolean')\n return (\n <Text size=\"sm\" mono>\n {value === true ? translate('common.yes') : translate('common.no')}\n </Text>\n )\n if (typeHint === 'date')\n return (\n <Text size=\"sm\" mono>\n {String(value).slice(0, 10)}\n </Text>\n )\n if (typeof value === 'object')\n return (\n <Text size=\"sm\" tone=\"muted\">\n {Array.isArray(value)\n ? translate(value.length === 1 ? 'cms.version.itemCount.one' : 'cms.version.itemCount.other', {\n count: value.length,\n })\n : translate('cms.version.objectValue')}\n </Text>\n )\n const expanded = isExpanded(id)\n const { shown, isLong } = truncateText(String(value), expanded)\n return (\n <ExpandToggle id={id} isLong={isLong} expanded={expanded}>\n <Text size=\"sm\" className=\"whitespace-pre-wrap break-words\">\n {shown}\n </Text>\n </ExpandToggle>\n )\n}\n\nfunction RelationValue({ value, other }: { value: unknown; other?: unknown }) {\n const source = useCollectionView()\n const refs = toRefArray(value)\n if (refs.length === 0)\n return (\n <Text size=\"sm\" className=\"whitespace-pre-wrap break-words\">\n {String(value)}\n </Text>\n )\n const otherRefs = other !== undefined ? toRefArray(other) : []\n const label = refs\n .map((ref) => {\n const title = source.titleOf(ref)\n const collision = otherRefs.some((o) => o.id !== ref.id && source.titleOf(o) === title)\n return collision ? `${title} · ${ref.id}` : title\n })\n .join(', ')\n return <Text size=\"sm\">{label}</Text>\n}\n\n/** Asset-record-owned keys — resolved off the asset RECORD at render, not authored. */\nconst ASSET_RECORD_KEYS = new Set<string>([\n 'url', 'alt', 'width', 'height', 'focalPoint', 'contentType', 'mimeType',\n 'byteSize', 'storageKey', 'title', 'filename', 'meta', 'createdAt', 'updatedAt',\n])\n\nfunction authoredAssetSubfields(value: unknown): [string, unknown][] {\n return Object.entries(assetSubfieldsOf(value)).filter(([key]) => !ASSET_RECORD_KEYS.has(key))\n}\n\nfunction AssetValue({ value }: { value: unknown }) {\n const items = (Array.isArray(value) ? value : [value])\n .map((entry) => ({ id: readAssetId(entry), sub: authoredAssetSubfields(entry) }))\n .filter((a): a is { id: string; sub: [string, unknown][] } => a.id !== undefined)\n if (items.length === 0)\n return (\n <Text size=\"sm\" className=\"whitespace-pre-wrap break-words\">\n {String(value)}\n </Text>\n )\n return (\n <div className=\"flex flex-wrap gap-2\">\n {items.map(({ id, sub }, i) => (\n <div key={`${id}-${i}`} className=\"flex flex-col gap-1\">\n <AssetThumb id={id} />\n {sub.length > 0 ? (\n <Stack gap=\"1\" className=\"pl-0.5\">\n {sub.map(([key, val]) => (\n <Text key={key} size=\"xs\" tone=\"muted\" className=\"break-words\">\n <span className=\"uppercase tracking-wide text-muted-foreground/70\">{prettyName(key)}:</span>{' '}\n {typeof val === 'object' && val !== null\n ? translate('cms.version.objectValue')\n : String(val)}\n </Text>\n ))}\n </Stack>\n ) : null}\n </div>\n ))}\n </div>\n )\n}\n\n/** An asset as a thumbnail (image with a resolvable URL) or a labelled badge. */\nfunction AssetThumb({ id }: { id: string }) {\n const source = useCollectionView()\n const assetCollectionId = source.assetCollectionId ?? 'asset'\n const record = source.resolveAsset?.(id)\n const label = record?.title ?? record?.filename ?? source.titleOf({ collection: assetCollectionId, id })\n const isImage = record?.contentType?.startsWith('image/') ?? false\n const url = record?.url\n if (isImage && isDisplayableAssetUrl(url)) {\n return (\n <span className=\"inline-flex min-w-0 items-center gap-2\">\n <img\n src={url}\n alt={record?.alt ?? label}\n loading=\"lazy\"\n className=\"size-12 shrink-0 rounded border border-border bg-muted object-cover\"\n />\n <Text size=\"xs\" tone=\"muted\" className=\"min-w-0 truncate\">\n {label}\n </Text>\n </span>\n )\n }\n return (\n <Badge variant=\"outline\">\n <ImageIcon className=\"size-3\" /> {label}\n </Badge>\n )\n}\n\n// --- Prose word diff --------------------------------------------------------------\n\nconst isWordTokenChanged = (token: WordToken) => token.changed\nconst isMergedTokenChanged = (token: MergedDiffToken) => token.kind !== 'same'\n\nfunction WordDiffCols({ id, before, after }: { id: string; before: string; after: string }) {\n const { mode, layout, isExpanded, captions } = useDiffDisplay()\n const expanded = isExpanded(id)\n const wd = useMemo(() => wordDiff(before, after), [before, after])\n const merged = useMemo(() => mergeWordDiff(wd.before, wd.after), [wd])\n\n // EC-382: change-anchored truncation — the collapsed excerpt centers on the\n // FIRST edit (the EC-379 finding: an edit past the head threshold could hide\n // behind \"Show more\"). Applies to every layout/mode; only the arrangement varies.\n const beforeSlice = truncateTokensAroundChange(wd.before, expanded, isWordTokenChanged)\n const afterSlice = truncateTokensAroundChange(wd.after, expanded, isWordTokenChanged)\n\n if (layout === 'stacked') {\n const isLong = beforeSlice.isLong || afterSlice.isLong\n return (\n <ExpandToggle id={id} isLong={isLong} expanded={expanded}>\n <Stack gap=\"2\">\n <StackedSide caption={captions.before} tone=\"before\">\n <WordTokens excerpt={beforeSlice} side=\"before\" />\n </StackedSide>\n <StackedSide caption={captions.after} tone=\"after\">\n <WordTokens excerpt={afterSlice} side=\"after\" />\n </StackedSide>\n </Stack>\n </ExpandToggle>\n )\n }\n\n if (mode === 'unified') {\n const mergedSlice = truncateTokensAroundChange(merged, expanded, isMergedTokenChanged)\n return (\n <ExpandToggle id={id} isLong={mergedSlice.isLong} expanded={expanded}>\n <UnifiedWordTokens excerpt={mergedSlice} />\n </ExpandToggle>\n )\n }\n\n const isLong = beforeSlice.isLong || afterSlice.isLong\n return (\n <ExpandToggle id={id} isLong={isLong} expanded={expanded}>\n <TwoCol\n before={<WordTokens excerpt={beforeSlice} side=\"before\" />}\n after={<WordTokens excerpt={afterSlice} side=\"after\" />}\n />\n </ExpandToggle>\n )\n}\n\n/** A \"…\" standing in for the hidden context an anchored excerpt trimmed (EC-382). */\nfunction EllipsisMark() {\n return (\n <span aria-hidden className=\"select-none text-muted-foreground/60\">\n …{' '}\n </span>\n )\n}\n\nfunction WordTokens({ excerpt, side }: { excerpt: AnchoredExcerpt<WordToken>; side: 'before' | 'after' }) {\n return (\n <Text size=\"sm\" className=\"whitespace-pre-wrap break-words leading-relaxed\">\n {excerpt.leadingEllipsis ? <EllipsisMark /> : null}\n {excerpt.shown.map((token, i) =>\n token.changed ? (\n <mark\n key={i}\n className={cn(\n 'rounded-sm px-0.5',\n side === 'before'\n ? 'bg-destructive/15 text-destructive line-through decoration-destructive/40'\n : 'bg-success/20 text-foreground',\n )}\n >\n {token.text}\n </mark>\n ) : (\n <span key={i} className=\"text-muted-foreground\">\n {token.text}\n </span>\n ),\n )}\n {excerpt.trailingEllipsis ? <EllipsisMark /> : null}\n </Text>\n )\n}\n\nfunction UnifiedWordTokens({ excerpt }: { excerpt: AnchoredExcerpt<MergedDiffToken> }) {\n return (\n <Text size=\"sm\" className=\"whitespace-pre-wrap break-words leading-relaxed\">\n {excerpt.leadingEllipsis ? <EllipsisMark /> : null}\n {excerpt.shown.map((token, i) =>\n token.kind === 'same' ? (\n <span key={i} className=\"text-muted-foreground\">\n {token.text}\n </span>\n ) : (\n <mark\n key={i}\n className={cn(\n 'rounded-sm px-0.5',\n token.kind === 'removed'\n ? 'bg-destructive/15 text-destructive line-through decoration-destructive/40'\n : 'bg-success/20 text-foreground',\n )}\n >\n {token.text}\n </mark>\n ),\n )}\n {excerpt.trailingEllipsis ? <EllipsisMark /> : null}\n </Text>\n )\n}\n\n// --- Small shared bits ------------------------------------------------------------\n\nfunction KindTag({ kind }: { kind: FieldChange['kind'] }) {\n if (kind === 'changed') return null\n return (\n <Text size=\"xs\" tone=\"subtle\">\n · {kind === 'added' ? translate('cms.version.kindNew') : translate('cms.version.kindRemoved')}\n </Text>\n )\n}\n\nfunction RestoreIcon({ busy, title, onClick }: { busy: boolean; title: string; onClick: () => void }) {\n return (\n <Button variant=\"ghost\" size=\"icon-sm\" disabled={busy} title={title} aria-label={title} onClick={onClick}>\n <RotateCcw />\n </Button>\n )\n}\n\nfunction MutedNote({ children }: { children: ReactNode }) {\n return (\n <Text size=\"sm\" tone=\"muted\" className=\"italic\">\n {children}\n </Text>\n )\n}\n\nfunction fieldScope(change: FieldChange): RestoreScope {\n return { kind: 'field', field: change.field, ...(change.locale !== undefined ? { locale: change.locale } : {}) }\n}\n\n/** Group changes BY FIELD (a localized field's per-locale variants together). */\nfunction groupByField(\n changes: FieldChange[],\n fieldOrder: Map<string, number>,\n localeRank: Map<string, number>,\n): FieldGroupData[] {\n const map = new Map<string, FieldGroupData>()\n for (const change of changes) {\n let group = map.get(change.field)\n if (!group) {\n group = { field: change.field, label: change.label, type: change.type, entries: [] }\n map.set(change.field, group)\n }\n group.entries.push(change)\n }\n const groups = [...map.values()]\n groups.sort(\n (a, b) =>\n (fieldOrder.get(a.field) ?? Number.MAX_SAFE_INTEGER) - (fieldOrder.get(b.field) ?? Number.MAX_SAFE_INTEGER),\n )\n for (const group of groups) {\n group.entries.sort((a, b) => localeCompare(a.locale, b.locale, localeRank))\n }\n return groups\n}\n\nfunction localeCompare(a: string | undefined, b: string | undefined, rank: Map<string, number>): number {\n if (a === b) return 0\n if (a === undefined) return -1\n if (b === undefined) return 1\n return (rank.get(a) ?? 99) - (rank.get(b) ?? 99)\n}\n\n/** camelCase / snake prop name → a readable label. */\nfunction prettyName(name: string): string {\n const spaced = name.replace(/[_-]+/g, ' ').replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n return spaced.charAt(0).toUpperCase() + spaced.slice(1)\n}\n"]}
|
|
1
|
+
{"version":3,"file":"document-diff-view.js","sourceRoot":"","sources":["../../../src/components/cms/document-diff-view.tsx"],"names":[],"mappings":"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","sourcesContent":["import { createContext, useCallback, useContext, useMemo, useState } from 'react'\nimport type { ReactNode } from 'react'\nimport { Image as ImageIcon, RotateCcw } from 'lucide-react'\nimport type {\n BlockAncestor,\n BlockChange,\n ChangeKind,\n DocumentDiff,\n FieldChange,\n PropChange,\n} from '@elytracms/core/content'\nimport { ASSET_RECORD_KEYS, assetSubfieldsOf, isAssetNode, readAssetId, readDocumentRef } from '@elytracms/core/cms-core'\nimport type { CollectionDef, FieldDef, RestoreScope } from '@elytracms/core/cms-core'\nimport { Badge, Button, Code, Row, Spacer, Stack, Text } from '@elytracms/studio/ui'\nimport { translate } from '@elytracms/studio/lib/i18n'\nimport { localeChipLabel } from '@elytracms/studio/lib/locale'\nimport { cn } from '@elytracms/studio/lib/utils'\nimport { readDiffViewMode, storeDiffViewMode } from '@elytracms/studio/lib/diff-view-preference'\nimport type { DiffViewMode } from '@elytracms/studio/lib/diff-view-preference'\nimport { isDisplayableAssetUrl } from '@elytracms/studio/lib/assets'\nimport { useCollectionView } from '../collection-view/collection-view-context'\nimport { fieldLabel } from './cms-labels'\nimport { toRefArray } from './cell'\nimport { RichTextPreview, isRichTextValueEmpty } from './rich-text-preview'\nimport {\n DIFF_TRUNCATE_THRESHOLD,\n mergeWordDiff,\n richTextToText,\n truncateText,\n truncateTokensAroundChange,\n wordDiff,\n} from './version-compare-text'\nimport type { AnchoredExcerpt, MergedDiffToken, WordToken } from './version-compare-text'\n\n/**\n * The shared document-diff RENDERER (EC-317 change-list), extracted from\n * `VersionCompare` so a single renderer serves both the version-compare surface and\n * the EC-199 AI proposal review — never two diff renderers. It draws a `DocumentDiff`\n * ({@link diffDocuments}) as the calm change-list grouped BY FIELD: a descriptor lane,\n * before | after (or a unified lane), text as a prose diff, assets as thumbnails,\n * relations as titles, long values collapsed behind \"Show more\", zebra rows.\n *\n * It is display-only over an already-computed diff: the version chrome (version\n * pickers / steppers / restore-whole) stays in `VersionCompare`; the AI proposal card\n * feeds `diffDocuments(collection, emptyBefore, proposedAfter)` and omits `restore`.\n * The per-row restore affordance renders only when `restore.canRestore` is set, so the\n * AI review (a not-yet-saved proposal) shows a clean, restore-free diff.\n *\n * **Layout (EC-382).** One diff LOGIC, two presentations selected by `layout`:\n * `'grid'` (default) is the wide version-compare surface — a fixed descriptor lane\n * plus a unified/side-by-side value area. `'stacked'` is the sidebar-fit variant the\n * AI proposal card selects: each field is a full-width card (label header, then\n * `Current → Proposed` VERTICALLY) that reads at ~320px without a squished two-column\n * split. Only chrome + column arrangement branch on `layout`; grouping, word diffing,\n * and change detection are shared — never forked.\n *\n * Must be rendered under a `CollectionViewProvider` (the value renderers resolve\n * relation titles / asset thumbnails through `useCollectionView`).\n */\nexport type DiffLayout = 'grid' | 'stacked'\nexport interface DocumentDiffRestore {\n baseVersion: number\n canRestore: boolean\n busy: boolean\n onRestore: (scope: RestoreScope) => void\n}\n\nexport interface DocumentDiffViewProps {\n diff: DocumentDiff\n collection: CollectionDef\n /** Pre-rendered column captions (version-specific text stays with the caller). */\n columnHeaders: { unified: string; before: string; after: string }\n /** Per-row restore controls; omitted ⇒ a restore-free read-only diff (AI review). */\n restore?: DocumentDiffRestore\n /** Extra note appended to the change-count summary (e.g. a comparing-past hint). */\n summaryHint?: ReactNode\n /** Presentation variant (EC-382). Defaults to the wide `'grid'` compare layout. */\n layout?: DiffLayout\n}\n\nexport function DocumentDiffView({\n diff,\n collection,\n columnHeaders,\n restore,\n summaryHint,\n layout = 'grid',\n}: DocumentDiffViewProps) {\n const source = useCollectionView()\n\n // EC-317 — the unified/side-by-side toggle is a transient, personal-local view\n // preference: read once at mount, written back on every change.\n const [mode, setModeState] = useState<DiffViewMode>(() => readDiffViewMode())\n const setMode = useCallback((next: DiffViewMode) => {\n setModeState(next)\n storeDiffViewMode(next)\n }, [])\n\n // EC-317 — long-value truncation state: an `expandAll` flag plus per-row overrides.\n const [expandAll, setExpandAll] = useState(false)\n const [expandedRows, setExpandedRows] = useState<ReadonlySet<string>>(() => new Set())\n const toggleExpand = useCallback((id: string) => {\n setExpandedRows((prev) => {\n const next = new Set(prev)\n if (next.has(id)) next.delete(id)\n else next.add(id)\n return next\n })\n }, [])\n const isExpanded = useCallback((id: string) => expandAll || expandedRows.has(id), [expandAll, expandedRows])\n const toggleExpandAll = useCallback(() => {\n setExpandAll((prev) => {\n const next = !prev\n if (!next) setExpandedRows(new Set())\n return next\n })\n }, [])\n const captions = useMemo(\n () => ({ before: columnHeaders.before, after: columnHeaders.after }),\n [columnHeaders.before, columnHeaders.after],\n )\n const diffDisplay = useMemo<DiffDisplayState>(\n () => ({ mode, layout, captions, expandAll, isExpanded, toggleExpand }),\n [mode, layout, captions, expandAll, isExpanded, toggleExpand],\n )\n\n const fieldOrder = useMemo(() => new Map(collection.fields.map((f, i) => [f.name, i])), [collection])\n const fieldByName = useMemo(() => new Map(collection.fields.map((f) => [f.name, f])), [collection])\n const localeRank = useMemo(() => new Map(source.localeConfig.locales.map((l, i) => [l, i])), [source.localeConfig])\n const groups = useMemo(\n () => groupByField(diff.changes, fieldOrder, localeRank),\n [diff.changes, fieldOrder, localeRank],\n )\n const groupRows = useMemo(() => {\n let rowIndex = 0\n return groups.map((group) => {\n const zebraStart = rowIndex\n rowIndex += group.entries.length\n return { group, field: fieldByName.get(group.field), zebraStart }\n })\n }, [groups, fieldByName])\n\n const canRestore = restore?.canRestore ?? false\n const baseVersion = restore?.baseVersion ?? 0\n const busy = restore?.busy ?? false\n const restoreFn = useCallback(\n (scope: RestoreScope) => restore?.onRestore(scope),\n [restore],\n )\n\n const summary = (\n <Text size=\"xs\" tone=\"muted\" className=\"px-0.5\">\n {translate(diff.changes.length === 1 ? 'cms.version.changeSummary.one' : 'cms.version.changeSummary.other', {\n count: diff.changes.length,\n unchanged: diff.unchangedCount,\n })}\n {summaryHint}\n </Text>\n )\n const expandAllButton = (\n <Button variant=\"ghost\" size=\"sm\" onClick={toggleExpandAll}>\n {translate(expandAll ? 'cms.field.collapseAll' : 'cms.field.expandAll')}\n </Button>\n )\n\n // EC-382 — the sidebar-fit variant: no two-column split to toggle, so the\n // unified/side-by-side control is dropped; each field is a full-width card\n // that lays Current → Proposed out vertically.\n if (layout === 'stacked') {\n return (\n <DiffDisplayContext.Provider value={diffDisplay}>\n <Stack gap=\"2\">\n <Row gap=\"2\" align=\"center\" justify=\"between\" wrap className=\"px-0.5\">\n {summary}\n {expandAllButton}\n </Row>\n <Stack gap=\"2\" className=\"pb-1\">\n {groupRows.map(({ group, field }) => (\n <FieldGroup\n key={group.field}\n group={group}\n field={field}\n zebraStart={0}\n baseVersion={baseVersion}\n canRestore={canRestore}\n busy={busy}\n onRestore={restoreFn}\n />\n ))}\n </Stack>\n </Stack>\n </DiffDisplayContext.Provider>\n )\n }\n\n return (\n <>\n {/* EC-317 — the diff-layout toolbar: unified/side-by-side (persisted) + expand-all. */}\n <Row gap=\"2\" align=\"center\" justify=\"between\" wrap className=\"px-0.5\">\n <DiffViewToggle mode={mode} onChange={setMode} />\n {expandAllButton}\n </Row>\n\n {summary}\n\n <DiffDisplayContext.Provider value={diffDisplay}>\n <div className=\"pb-1\">\n <div className={cn(DIFF_ROW_GRID, 'px-2 pb-1.5')}>\n <Text size=\"xs\" tone=\"subtle\" className=\"uppercase tracking-wide\">\n {translate('cms.version.fieldColumnHeader')}\n </Text>\n {mode === 'unified' ? (\n <Text size=\"xs\" tone=\"subtle\" className=\"uppercase tracking-wide\">\n {columnHeaders.unified}\n </Text>\n ) : (\n <TwoCol\n before={\n <Text size=\"xs\" tone=\"subtle\" className=\"uppercase tracking-wide\">\n {columnHeaders.before}\n </Text>\n }\n after={\n <Text size=\"xs\" tone=\"subtle\" className=\"uppercase tracking-wide\">\n {columnHeaders.after}\n </Text>\n }\n />\n )}\n </div>\n {groupRows.map(({ group, field, zebraStart }) => (\n <FieldGroup\n key={group.field}\n group={group}\n field={field}\n zebraStart={zebraStart}\n baseVersion={baseVersion}\n canRestore={canRestore}\n busy={busy}\n onRestore={restoreFn}\n />\n ))}\n </div>\n </DiffDisplayContext.Provider>\n </>\n )\n}\n\n// --- EC-317 diff-display context (mode + truncation) ------------------------------\n\ninterface DiffDisplayState {\n mode: DiffViewMode\n /** EC-382 — the active presentation variant; value renderers branch on it. */\n layout: DiffLayout\n /** EC-382 — the Current/Proposed captions, shown inline per side in `stacked`. */\n captions: { before: string; after: string }\n expandAll: boolean\n isExpanded: (id: string) => boolean\n toggleExpand: (id: string) => void\n}\n\nconst DiffDisplayContext = createContext<DiffDisplayState | null>(null)\n\nfunction useDiffDisplay(): DiffDisplayState {\n const ctx = useContext(DiffDisplayContext)\n if (!ctx) throw new Error('useDiffDisplay must be rendered under the DocumentDiffView diff area')\n return ctx\n}\n\n/** Shared grid template so the descriptor lane + header captions line up. */\nconst DIFF_ROW_GRID = 'grid grid-cols-[7.5rem_1fr_1.75rem] items-start gap-x-4'\n\n/** A before | after grid with a clear central divider. */\nfunction TwoCol({ before, after, className }: { before: ReactNode; after: ReactNode; className?: string }) {\n return (\n <div className={cn('relative grid grid-cols-2 gap-x-8', className)}>\n <div className=\"pointer-events-none absolute inset-y-0 left-1/2 w-px -translate-x-1/2 bg-border\" aria-hidden />\n <div className=\"min-w-0 pr-1\">{before}</div>\n <div className=\"min-w-0 pl-1\">{after}</div>\n </div>\n )\n}\n\n/** Mode-aware value display (EC-317) / layout-aware in the EC-382 stacked variant. */\nfunction DiffColumns({ before, after, kind }: { before: ReactNode; after: ReactNode; kind: ChangeKind }) {\n const { mode, layout } = useDiffDisplay()\n if (layout === 'stacked') {\n return <StackedColumns before={before} after={after} kind={kind} />\n }\n if (mode === 'unified') {\n return (\n <Stack gap=\"1\">\n {kind !== 'added' ? <UnifiedLine tone=\"removed\">{before}</UnifiedLine> : null}\n {kind !== 'removed' ? <UnifiedLine tone=\"added\">{after}</UnifiedLine> : null}\n </Stack>\n )\n }\n return <TwoCol before={before} after={after} />\n}\n\n/**\n * EC-382 stacked value display: `Current` above `Proposed`, each captioned and\n * accented, full width — the sidebar-fit answer to the squished two-column split.\n * An `added` change shows only the proposed side; a `removed` change only current.\n */\nfunction StackedColumns({ before, after, kind }: { before: ReactNode; after: ReactNode; kind: ChangeKind }) {\n const { captions } = useDiffDisplay()\n return (\n <Stack gap=\"2\">\n {kind !== 'added' ? (\n <StackedSide caption={captions.before} tone=\"before\">\n {before}\n </StackedSide>\n ) : null}\n {kind !== 'removed' ? (\n <StackedSide caption={captions.after} tone=\"after\">\n {after}\n </StackedSide>\n ) : null}\n </Stack>\n )\n}\n\n/** One captioned side of a stacked change (EC-382). */\nfunction StackedSide({\n caption,\n tone,\n children,\n}: {\n caption: string\n tone: 'before' | 'after'\n children: ReactNode\n}) {\n return (\n <Stack gap=\"1\">\n <Text size=\"xs\" tone=\"subtle\" className=\"uppercase tracking-wide\">\n {caption}\n </Text>\n <div\n className={cn(\n 'min-w-0 border-l-2 pl-2.5',\n tone === 'before' ? 'border-border' : 'border-primary/60',\n )}\n >\n {children}\n </div>\n </Stack>\n )\n}\n\nfunction UnifiedLine({ tone, children }: { tone: 'removed' | 'added'; children: ReactNode }) {\n return (\n <Row\n gap=\"2\"\n align=\"start\"\n className={cn('rounded-sm px-1.5 py-1', tone === 'removed' ? 'bg-destructive/10' : 'bg-success/10')}\n >\n <Text\n size=\"xs\"\n mono\n aria-hidden\n className={cn('mt-0.5 shrink-0 select-none', tone === 'removed' ? 'text-destructive' : 'text-success')}\n >\n {tone === 'removed' ? '−' : '+'}\n </Text>\n <div className=\"min-w-0 flex-1\">{children}</div>\n </Row>\n )\n}\n\n/** Wraps truncatable content with its per-row \"Show more\"/\"Show less\" control. */\nfunction ExpandToggle({\n id,\n isLong,\n expanded,\n children,\n}: {\n id: string\n isLong: boolean\n expanded: boolean\n children: ReactNode\n}) {\n const { expandAll, toggleExpand } = useDiffDisplay()\n return (\n <div>\n {children}\n {isLong && !expandAll ? (\n <Button variant=\"link\" size=\"sm\" className=\"h-auto p-0 text-xs\" onClick={() => toggleExpand(id)}>\n {expanded ? translate('cms.version.showLess') : translate('cms.version.showMore')}\n </Button>\n ) : null}\n </div>\n )\n}\n\n/** The unified/side-by-side segmented toggle (EC-317). */\nfunction DiffViewToggle({ mode, onChange }: { mode: DiffViewMode; onChange: (mode: DiffViewMode) => void }) {\n return (\n <Row\n gap=\"px\"\n className=\"rounded-md bg-muted/50 p-0.5\"\n role=\"group\"\n aria-label={translate('cms.version.viewModeAriaLabel')}\n data-testid=\"diff-view-toggle\"\n >\n <DiffViewOption\n active={mode === 'sideBySide'}\n label={translate('cms.version.viewSideBySide')}\n onClick={() => onChange('sideBySide')}\n />\n <DiffViewOption\n active={mode === 'unified'}\n label={translate('cms.version.viewUnified')}\n onClick={() => onChange('unified')}\n />\n </Row>\n )\n}\n\nfunction DiffViewOption({ active, label, onClick }: { active: boolean; label: string; onClick: () => void }) {\n return (\n <button\n type=\"button\"\n aria-pressed={active}\n data-testid={`diff-view-option-${active ? 'active' : 'inactive'}`}\n onClick={onClick}\n className={cn(\n 'rounded-[5px] px-2.5 py-1 text-xs font-medium transition-colors',\n active ? 'bg-background text-foreground shadow-sm' : 'text-muted-foreground hover:text-foreground',\n )}\n >\n {label}\n </button>\n )\n}\n\ninterface FieldGroupData {\n field: string\n label: string\n type: FieldDef['type']\n entries: FieldChange[]\n}\n\n/** One field's diff rows (EC-317 grid rows / EC-382 stacked cards). */\nfunction FieldGroup({\n group,\n field,\n zebraStart,\n baseVersion,\n canRestore,\n busy,\n onRestore,\n}: {\n group: FieldGroupData\n field: FieldDef | undefined\n zebraStart: number\n baseVersion: number\n canRestore: boolean\n busy: boolean\n onRestore: (scope: RestoreScope) => void\n}) {\n const { layout } = useDiffDisplay()\n const label = field ? fieldLabel(field) : group.label\n const rows = group.entries.map((entry, i) => {\n const rowId = `${group.field}:${entry.locale ?? '_'}`\n const fieldRestore =\n canRestore && !entry.blocks ? (\n <RestoreIcon\n busy={busy}\n title={\n entry.locale\n ? translate('cms.version.restoreFieldLocale', {\n field: label,\n locale: localeChipLabel(entry.locale),\n version: baseVersion,\n })\n : translate('cms.version.restoreField', { field: label, version: baseVersion })\n }\n onClick={() => onRestore(fieldScope(entry))}\n />\n ) : null\n const descriptor = (\n <FieldDescriptor label={label} locale={entry.locale} kind={entry.kind} inline={layout === 'stacked'} />\n )\n const body = (\n <EntryBody\n change={entry}\n rowId={rowId}\n baseVersion={baseVersion}\n canRestore={canRestore}\n busy={busy}\n onRestore={onRestore}\n />\n )\n return layout === 'stacked' ? (\n <StackedFieldRow key={entry.locale ?? '__base__'} descriptor={descriptor} restore={fieldRestore}>\n {body}\n </StackedFieldRow>\n ) : (\n <FieldRow\n key={entry.locale ?? '__base__'}\n zebra={(zebraStart + i) % 2 === 1}\n descriptor={descriptor}\n restore={fieldRestore}\n >\n {body}\n </FieldRow>\n )\n })\n if (layout === 'stacked') return <>{rows}</>\n return <div className=\"border-t border-border/30\">{rows}</div>\n}\n\n/** The descriptor lane + value area, one grid row (EC-317). */\nfunction FieldRow({\n descriptor,\n restore,\n zebra,\n children,\n}: {\n descriptor: ReactNode\n restore: ReactNode\n zebra: boolean\n children: ReactNode\n}) {\n return (\n <div className={cn(DIFF_ROW_GRID, 'rounded-sm px-2 py-2.5', zebra && 'bg-muted/40')}>\n <div className=\"min-w-0\">{descriptor}</div>\n <div className=\"min-w-0\">{children}</div>\n <div className=\"flex justify-end\">{restore}</div>\n </div>\n )\n}\n\n/**\n * One field as a full-width card (EC-382 stacked variant): a label header\n * (descriptor + restore) over a full-width value area — no fixed lane to squeeze\n * the value at sidebar width.\n */\nfunction StackedFieldRow({\n descriptor,\n restore,\n children,\n}: {\n descriptor: ReactNode\n restore: ReactNode\n children: ReactNode\n}) {\n return (\n <div className=\"overflow-hidden rounded-lg border border-border/60 bg-card\">\n <Row gap=\"2\" align=\"center\" className=\"border-b border-border/50 bg-muted/30 px-3 py-2\">\n <div className=\"min-w-0 flex-1\">{descriptor}</div>\n {restore}\n </Row>\n <div className=\"px-3 py-2.5\">{children}</div>\n </div>\n )\n}\n\n/** The descriptor content (EC-317 stacked lane / EC-382 inline card header). */\nfunction FieldDescriptor({\n label,\n locale,\n kind,\n inline = false,\n}: {\n label: string\n locale?: string\n kind: ChangeKind\n inline?: boolean\n}) {\n const localeBadge = locale ? (\n <Badge variant=\"outline\" className=\"px-1 py-0 text-[0.6rem] uppercase tracking-wide text-muted-foreground\">\n {localeChipLabel(locale)}\n </Badge>\n ) : null\n if (inline) {\n return (\n <Row gap=\"2\" align=\"center\" wrap className=\"min-w-0\">\n <Text size=\"sm\" weight=\"semibold\" className=\"min-w-0 truncate\">\n {label}\n </Text>\n {localeBadge}\n <KindTag kind={kind} />\n </Row>\n )\n }\n return (\n <Stack gap=\"1\">\n <Text size=\"sm\" weight=\"medium\" className=\"min-w-0 truncate\">\n {label}\n </Text>\n <Row gap=\"1\" wrap>\n {localeBadge}\n <KindTag kind={kind} />\n </Row>\n </Stack>\n )\n}\n\nfunction EntryBody({\n change,\n rowId,\n baseVersion,\n canRestore,\n busy,\n onRestore,\n}: {\n change: FieldChange\n rowId: string\n baseVersion: number\n canRestore: boolean\n busy: boolean\n onRestore: (scope: RestoreScope) => void\n}) {\n const localeScope = change.locale !== undefined ? { locale: change.locale } : {}\n if (change.blocks) {\n return (\n <Stack gap=\"2\" className=\"mt-1\">\n {change.blocks.map((block) => (\n <BlockSection\n key={block.blockId}\n block={block}\n rowId={`${rowId}|block:${block.blockId}`}\n baseVersion={baseVersion}\n canRestore={canRestore}\n busy={busy}\n onRestore={() => onRestore({ kind: 'block', field: change.field, blockId: block.blockId, ...localeScope })}\n />\n ))}\n </Stack>\n )\n }\n if (change.type === 'richText') {\n const before = richTextToText(change.before)\n const after = richTextToText(change.after)\n if (before === after && before) return <MutedNote>{translate('cms.version.textUnchanged')}</MutedNote>\n // Both sides carry text → the word diff pinpoints the edit.\n if (before && after) return <WordDiffCols id={rowId} before={before} after={after} />\n // EC-379: one side is (textually) empty — a create proposal, a cleared body,\n // or structure-only content. Render the ACTUAL prose so the editor reviews\n // what they are approving (retires the blind \"Content changed.\" note).\n return (\n <DiffColumns\n kind={change.kind}\n before={<RichTextSide value={change.before} id={`${rowId}|before`} />}\n after={<RichTextSide value={change.after} id={`${rowId}|after`} />}\n />\n )\n }\n if (change.kind === 'changed' && typeof change.before === 'string' && typeof change.after === 'string') {\n return <WordDiffCols id={rowId} before={change.before} after={change.after} />\n }\n return (\n <DiffColumns\n kind={change.kind}\n before={<SideValue value={change.before} other={change.after} typeHint={change.type} id={`${rowId}|before`} />}\n after={<SideValue value={change.after} other={change.before} typeHint={change.type} id={`${rowId}|after`} />}\n />\n )\n}\n\nfunction BlockSection({\n block,\n rowId,\n baseVersion,\n canRestore,\n busy,\n onRestore,\n}: {\n block: BlockChange\n rowId: string\n baseVersion: number\n canRestore: boolean\n busy: boolean\n onRestore: () => void\n}) {\n const name = block.componentId.split('.').pop() ?? block.componentId\n // EC-593: a NESTED component (in prose, a slot, below a prop) is located; its restore is\n // its root's (the block restore scope addresses root blocks — a nested id would be a no-op).\n const nested = block.within !== undefined\n return (\n <div className=\"overflow-hidden rounded-md border border-border/60\" data-diff-block={block.blockId}>\n <Row gap=\"2\" align=\"center\" className=\"border-b border-border/50 bg-muted/30 px-2 py-1.5\">\n <Text size=\"xs\" weight=\"semibold\" className=\"min-w-0 truncate\">\n {name}\n </Text>\n <Code tone=\"muted\">{block.componentId}</Code>\n <KindTag kind={block.kind} />\n {nested ? <Text size=\"xs\" tone=\"muted\" className=\"min-w-0 truncate\">{nestedLocation(block.within!)}</Text> : null}\n <Spacer />\n {canRestore && !nested ? (\n <RestoreIcon\n busy={busy}\n title={translate('cms.version.restoreBlock', { version: baseVersion })}\n onClick={onRestore}\n />\n ) : null}\n </Row>\n <div className=\"px-2 py-2\">\n {block.props && block.props.length > 0 ? (\n <Stack gap=\"3\" className=\"border-l-2 border-border/50 pl-3\">\n {block.props.map((prop) => (\n <PropRow key={prop.name} prop={prop} rowId={`${rowId}|prop:${prop.name}`} />\n ))}\n </Stack>\n ) : null}\n {block.slotsChanged ? <MutedNote>{translate('cms.version.nestedContentChanged')}</MutedNote> : null}\n {block.kind !== 'changed' && !block.props?.length ? (\n <MutedNote>\n {block.kind === 'added' ? translate('cms.version.blockAdded') : translate('cms.version.blockRemoved')}\n </MutedNote>\n ) : null}\n </div>\n </div>\n )\n}\n\n/** Where a nested component sits: \"in the text\", or \"inside Section › Grid\". */\nexport function nestedLocation(within: readonly BlockAncestor[]): string {\n if (within.length === 0) return translate('cms.version.nestedInProse')\n const path = within.map((ancestor) => ancestor.componentId.split('.').pop() ?? ancestor.componentId).join(' › ')\n return translate('cms.version.nestedIn', { path })\n}\n\nfunction PropRow({ prop, rowId }: { prop: PropChange; rowId: string }) {\n const useWordDiff = prop.kind === 'changed' && typeof prop.before === 'string' && typeof prop.after === 'string'\n return (\n <div>\n <Text size=\"xs\" tone=\"subtle\" className=\"mb-0.5 block uppercase tracking-wide\">\n {prettyName(prop.name)}\n </Text>\n {useWordDiff ? (\n <WordDiffCols id={rowId} before={String(prop.before)} after={String(prop.after)} />\n ) : (\n <DiffColumns\n kind={prop.kind}\n before={<SideValue value={prop.before} other={prop.after} id={`${rowId}|before`} />}\n after={<SideValue value={prop.after} other={prop.before} id={`${rowId}|after`} />}\n />\n )}\n </div>\n )\n}\n\n/**\n * One side of a rich-text change (EC-379): rendered compact prose\n * ({@link RichTextPreview}), height-clamped behind the shared expand toggle for\n * long bodies, with the standard \"empty\" placeholder for an absent side.\n */\nfunction RichTextSide({ value, id }: { value: unknown; id: string }) {\n const { isExpanded } = useDiffDisplay()\n if (isRichTextValueEmpty(value)) {\n return (\n <Text size=\"sm\" tone=\"subtle\" className=\"italic\">\n {translate('cms.version.emptyValue')}\n </Text>\n )\n }\n const expanded = isExpanded(id)\n const isLong = richTextToText(value).length > DIFF_TRUNCATE_THRESHOLD\n return (\n <ExpandToggle id={id} isLong={isLong} expanded={expanded}>\n <div className={cn(!expanded && isLong && 'max-h-60 overflow-hidden')}>\n <RichTextPreview value={value} />\n </div>\n </ExpandToggle>\n )\n}\n\n/** One side of a non-text change — the value, or an \"empty\" placeholder. */\nfunction SideValue({\n value,\n other,\n typeHint,\n id,\n}: {\n value: unknown\n other?: unknown\n typeHint?: FieldDef['type']\n id: string\n}) {\n if (value === undefined || value === null || value === '') {\n return (\n <Text size=\"sm\" tone=\"subtle\" className=\"italic\">\n {translate('cms.version.emptyValue')}\n </Text>\n )\n }\n return <ValueView value={value} other={other} typeHint={typeHint} id={id} />\n}\n\n/** Read-only value display, dispatching on field type / self-describing value shape. */\nfunction ValueView({\n value,\n other,\n typeHint,\n id,\n}: {\n value: unknown\n other?: unknown\n typeHint?: FieldDef['type']\n id: string\n}) {\n const { isExpanded } = useDiffDisplay()\n if (typeHint === 'asset' || isAssetNode(value)) return <AssetValue value={value} />\n if (typeHint === 'relation' || readDocumentRef(value)) return <RelationValue value={value} other={other} />\n if (typeHint === 'richText')\n return (\n <Text size=\"sm\" className=\"whitespace-pre-wrap break-words\">\n {richTextToText(value) || translate('cms.version.richText')}\n </Text>\n )\n if (typeHint === 'boolean' || typeof value === 'boolean')\n return (\n <Text size=\"sm\" mono>\n {value === true ? translate('common.yes') : translate('common.no')}\n </Text>\n )\n if (typeHint === 'date')\n return (\n <Text size=\"sm\" mono>\n {String(value).slice(0, 10)}\n </Text>\n )\n if (typeof value === 'object')\n return (\n <Text size=\"sm\" tone=\"muted\">\n {Array.isArray(value)\n ? translate(value.length === 1 ? 'cms.version.itemCount.one' : 'cms.version.itemCount.other', {\n count: value.length,\n })\n : translate('cms.version.objectValue')}\n </Text>\n )\n const expanded = isExpanded(id)\n const { shown, isLong } = truncateText(String(value), expanded)\n return (\n <ExpandToggle id={id} isLong={isLong} expanded={expanded}>\n <Text size=\"sm\" className=\"whitespace-pre-wrap break-words\">\n {shown}\n </Text>\n </ExpandToggle>\n )\n}\n\nfunction RelationValue({ value, other }: { value: unknown; other?: unknown }) {\n const source = useCollectionView()\n const refs = toRefArray(value)\n if (refs.length === 0)\n return (\n <Text size=\"sm\" className=\"whitespace-pre-wrap break-words\">\n {String(value)}\n </Text>\n )\n const otherRefs = other !== undefined ? toRefArray(other) : []\n const label = refs\n .map((ref) => {\n const title = source.titleOf(ref)\n const collision = otherRefs.some((o) => o.id !== ref.id && source.titleOf(o) === title)\n return collision ? `${title} · ${ref.id}` : title\n })\n .join(', ')\n return <Text size=\"sm\">{label}</Text>\n}\n\nfunction authoredAssetSubfields(value: unknown): [string, unknown][] {\n return Object.entries(assetSubfieldsOf(value)).filter(([key]) => !ASSET_RECORD_KEYS.has(key))\n}\n\nfunction AssetValue({ value }: { value: unknown }) {\n const items = (Array.isArray(value) ? value : [value])\n .map((entry) => ({ id: readAssetId(entry), sub: authoredAssetSubfields(entry) }))\n .filter((a): a is { id: string; sub: [string, unknown][] } => a.id !== undefined)\n if (items.length === 0)\n return (\n <Text size=\"sm\" className=\"whitespace-pre-wrap break-words\">\n {String(value)}\n </Text>\n )\n return (\n <div className=\"flex flex-wrap gap-2\">\n {items.map(({ id, sub }, i) => (\n <div key={`${id}-${i}`} className=\"flex flex-col gap-1\">\n <AssetThumb id={id} />\n {sub.length > 0 ? (\n <Stack gap=\"1\" className=\"pl-0.5\">\n {sub.map(([key, val]) => (\n <Text key={key} size=\"xs\" tone=\"muted\" className=\"break-words\">\n <span className=\"uppercase tracking-wide text-muted-foreground/70\">{prettyName(key)}:</span>{' '}\n {typeof val === 'object' && val !== null\n ? translate('cms.version.objectValue')\n : String(val)}\n </Text>\n ))}\n </Stack>\n ) : null}\n </div>\n ))}\n </div>\n )\n}\n\n/** An asset as a thumbnail (image with a resolvable URL) or a labelled badge. */\nfunction AssetThumb({ id }: { id: string }) {\n const source = useCollectionView()\n const assetCollectionId = source.assetCollectionId ?? 'asset'\n const record = source.resolveAsset?.(id)\n const label = record?.title ?? record?.filename ?? source.titleOf({ collection: assetCollectionId, id })\n const isImage = record?.contentType?.startsWith('image/') ?? false\n const url = record?.url\n if (isImage && isDisplayableAssetUrl(url)) {\n return (\n <span className=\"inline-flex min-w-0 items-center gap-2\">\n <img\n src={url}\n alt={record?.alt ?? label}\n loading=\"lazy\"\n className=\"size-12 shrink-0 rounded border border-border bg-muted object-cover\"\n />\n <Text size=\"xs\" tone=\"muted\" className=\"min-w-0 truncate\">\n {label}\n </Text>\n </span>\n )\n }\n return (\n <Badge variant=\"outline\">\n <ImageIcon className=\"size-3\" /> {label}\n </Badge>\n )\n}\n\n// --- Prose word diff --------------------------------------------------------------\n\nconst isWordTokenChanged = (token: WordToken) => token.changed\nconst isMergedTokenChanged = (token: MergedDiffToken) => token.kind !== 'same'\n\nfunction WordDiffCols({ id, before, after }: { id: string; before: string; after: string }) {\n const { mode, layout, isExpanded, captions } = useDiffDisplay()\n const expanded = isExpanded(id)\n const wd = useMemo(() => wordDiff(before, after), [before, after])\n const merged = useMemo(() => mergeWordDiff(wd.before, wd.after), [wd])\n\n // EC-382: change-anchored truncation — the collapsed excerpt centers on the\n // FIRST edit (the EC-379 finding: an edit past the head threshold could hide\n // behind \"Show more\"). Applies to every layout/mode; only the arrangement varies.\n const beforeSlice = truncateTokensAroundChange(wd.before, expanded, isWordTokenChanged)\n const afterSlice = truncateTokensAroundChange(wd.after, expanded, isWordTokenChanged)\n\n if (layout === 'stacked') {\n const isLong = beforeSlice.isLong || afterSlice.isLong\n return (\n <ExpandToggle id={id} isLong={isLong} expanded={expanded}>\n <Stack gap=\"2\">\n <StackedSide caption={captions.before} tone=\"before\">\n <WordTokens excerpt={beforeSlice} side=\"before\" />\n </StackedSide>\n <StackedSide caption={captions.after} tone=\"after\">\n <WordTokens excerpt={afterSlice} side=\"after\" />\n </StackedSide>\n </Stack>\n </ExpandToggle>\n )\n }\n\n if (mode === 'unified') {\n const mergedSlice = truncateTokensAroundChange(merged, expanded, isMergedTokenChanged)\n return (\n <ExpandToggle id={id} isLong={mergedSlice.isLong} expanded={expanded}>\n <UnifiedWordTokens excerpt={mergedSlice} />\n </ExpandToggle>\n )\n }\n\n const isLong = beforeSlice.isLong || afterSlice.isLong\n return (\n <ExpandToggle id={id} isLong={isLong} expanded={expanded}>\n <TwoCol\n before={<WordTokens excerpt={beforeSlice} side=\"before\" />}\n after={<WordTokens excerpt={afterSlice} side=\"after\" />}\n />\n </ExpandToggle>\n )\n}\n\n/** A \"…\" standing in for the hidden context an anchored excerpt trimmed (EC-382). */\nfunction EllipsisMark() {\n return (\n <span aria-hidden className=\"select-none text-muted-foreground/60\">\n …{' '}\n </span>\n )\n}\n\nfunction WordTokens({ excerpt, side }: { excerpt: AnchoredExcerpt<WordToken>; side: 'before' | 'after' }) {\n return (\n <Text size=\"sm\" className=\"whitespace-pre-wrap break-words leading-relaxed\">\n {excerpt.leadingEllipsis ? <EllipsisMark /> : null}\n {excerpt.shown.map((token, i) =>\n token.changed ? (\n <mark\n key={i}\n className={cn(\n 'rounded-sm px-0.5',\n side === 'before'\n ? 'bg-destructive/15 text-destructive line-through decoration-destructive/40'\n : 'bg-success/20 text-foreground',\n )}\n >\n {token.text}\n </mark>\n ) : (\n <span key={i} className=\"text-muted-foreground\">\n {token.text}\n </span>\n ),\n )}\n {excerpt.trailingEllipsis ? <EllipsisMark /> : null}\n </Text>\n )\n}\n\nfunction UnifiedWordTokens({ excerpt }: { excerpt: AnchoredExcerpt<MergedDiffToken> }) {\n return (\n <Text size=\"sm\" className=\"whitespace-pre-wrap break-words leading-relaxed\">\n {excerpt.leadingEllipsis ? <EllipsisMark /> : null}\n {excerpt.shown.map((token, i) =>\n token.kind === 'same' ? (\n <span key={i} className=\"text-muted-foreground\">\n {token.text}\n </span>\n ) : (\n <mark\n key={i}\n className={cn(\n 'rounded-sm px-0.5',\n token.kind === 'removed'\n ? 'bg-destructive/15 text-destructive line-through decoration-destructive/40'\n : 'bg-success/20 text-foreground',\n )}\n >\n {token.text}\n </mark>\n ),\n )}\n {excerpt.trailingEllipsis ? <EllipsisMark /> : null}\n </Text>\n )\n}\n\n// --- Small shared bits ------------------------------------------------------------\n\nfunction KindTag({ kind }: { kind: FieldChange['kind'] }) {\n if (kind === 'changed') return null\n return (\n <Text size=\"xs\" tone=\"subtle\">\n · {kind === 'added' ? translate('cms.version.kindNew') : translate('cms.version.kindRemoved')}\n </Text>\n )\n}\n\nfunction RestoreIcon({ busy, title, onClick }: { busy: boolean; title: string; onClick: () => void }) {\n return (\n <Button variant=\"ghost\" size=\"icon-sm\" disabled={busy} title={title} aria-label={title} onClick={onClick}>\n <RotateCcw />\n </Button>\n )\n}\n\nfunction MutedNote({ children }: { children: ReactNode }) {\n return (\n <Text size=\"sm\" tone=\"muted\" className=\"italic\">\n {children}\n </Text>\n )\n}\n\nfunction fieldScope(change: FieldChange): RestoreScope {\n return { kind: 'field', field: change.field, ...(change.locale !== undefined ? { locale: change.locale } : {}) }\n}\n\n/** Group changes BY FIELD (a localized field's per-locale variants together). */\nfunction groupByField(\n changes: FieldChange[],\n fieldOrder: Map<string, number>,\n localeRank: Map<string, number>,\n): FieldGroupData[] {\n const map = new Map<string, FieldGroupData>()\n for (const change of changes) {\n let group = map.get(change.field)\n if (!group) {\n group = { field: change.field, label: change.label, type: change.type, entries: [] }\n map.set(change.field, group)\n }\n group.entries.push(change)\n }\n const groups = [...map.values()]\n groups.sort(\n (a, b) =>\n (fieldOrder.get(a.field) ?? Number.MAX_SAFE_INTEGER) - (fieldOrder.get(b.field) ?? Number.MAX_SAFE_INTEGER),\n )\n for (const group of groups) {\n group.entries.sort((a, b) => localeCompare(a.locale, b.locale, localeRank))\n }\n return groups\n}\n\nfunction localeCompare(a: string | undefined, b: string | undefined, rank: Map<string, number>): number {\n if (a === b) return 0\n if (a === undefined) return -1\n if (b === undefined) return 1\n return (rank.get(a) ?? 99) - (rank.get(b) ?? 99)\n}\n\n/** camelCase / snake prop name → a readable label. */\nfunction prettyName(name: string): string {\n const spaced = name.replace(/[_-]+/g, ' ').replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n return spaced.charAt(0).toUpperCase() + spaced.slice(1)\n}\n"]}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { ValuePath } from '@elytracms/core/cms-core';
|
|
2
|
+
import type { CommitPolicy } from './commit-policy.js';
|
|
3
|
+
/**
|
|
4
|
+
* EC-595 A2 — the editor's COMMIT-ON-QUIESCENCE core (pure, clock injected; the house
|
|
5
|
+
* pattern: no DOM, no React).
|
|
6
|
+
*
|
|
7
|
+
* The editor's draft changes per keystroke (live validation reads it); what is
|
|
8
|
+
* COMMITTED — handed to the persister as patches — follows each field's
|
|
9
|
+
* {@link CommitPolicy}. This core tracks the uncommitted positions and decides when
|
|
10
|
+
* each is committed:
|
|
11
|
+
*
|
|
12
|
+
* - an edit of a `change`-policy field commits at once;
|
|
13
|
+
* - an edit of the FOCUSED field waits for its blur, Enter (`blur-or-enter`) or idle
|
|
14
|
+
* pause (`blur-or-idle`, re-armed on every edit — {@link Scheduler});
|
|
15
|
+
* - an edit of a field that does NOT have focus (a derived value — the auto-slug
|
|
16
|
+
* following the title, fill-from-base) rides along with the focused field's next
|
|
17
|
+
* commit, or commits at once when no field has focus;
|
|
18
|
+
* - {@link DraftCommitter.commitAll} is the FORCED commit (publish, unmount, tab hide,
|
|
19
|
+
* duplicate, an AI proposal, transfer) — everything uncommitted, now.
|
|
20
|
+
*
|
|
21
|
+
* `commit` receives the positions; the caller builds the patches from its latest draft
|
|
22
|
+
* (the value AT commit time, so a committed value is never a stale keystroke).
|
|
23
|
+
*/
|
|
24
|
+
/** The injected clock: timers for the idle pause. */
|
|
25
|
+
export interface Scheduler {
|
|
26
|
+
setTimeout(callback: () => void, ms: number): unknown;
|
|
27
|
+
clearTimeout(handle: unknown): void;
|
|
28
|
+
}
|
|
29
|
+
/** The real clock (the editor's default). */
|
|
30
|
+
export declare const browserScheduler: Scheduler;
|
|
31
|
+
/** One uncommitted position and the field (by name) whose control wrote it. */
|
|
32
|
+
export interface UncommittedPosition {
|
|
33
|
+
readonly field: string;
|
|
34
|
+
readonly path: ValuePath;
|
|
35
|
+
/**
|
|
36
|
+
* The revision the user's view was at when they STARTED editing this position — the
|
|
37
|
+
* patch's base. A colleague's change of the same position that arrives (by
|
|
38
|
+
* subscription) while the user is still typing is therefore refused on that field at
|
|
39
|
+
* commit, never overwritten (EC-595 point 7: "local wins until flushed, then the
|
|
40
|
+
* per-path check decides").
|
|
41
|
+
*/
|
|
42
|
+
readonly base: number | undefined;
|
|
43
|
+
}
|
|
44
|
+
export interface DraftCommitter {
|
|
45
|
+
/** A field's control wrote `path`. */
|
|
46
|
+
edited(field: string, path: ValuePath): void;
|
|
47
|
+
/** Focus entered a field's control. */
|
|
48
|
+
focused(field: string): void;
|
|
49
|
+
/** Focus left a field's control (commits it and what rode along). */
|
|
50
|
+
blurred(field: string): void;
|
|
51
|
+
/** Enter in a single-line control (commits it). */
|
|
52
|
+
entered(field: string): void;
|
|
53
|
+
/** The forced commit: everything uncommitted, now. */
|
|
54
|
+
commitAll(): void;
|
|
55
|
+
/** The uncommitted positions (the editor overlays them on a rebased draft). */
|
|
56
|
+
uncommitted(): readonly UncommittedPosition[];
|
|
57
|
+
/** The field that has focus, if any. */
|
|
58
|
+
focusedField(): string | undefined;
|
|
59
|
+
/** Cancel the idle timers (unmount). */
|
|
60
|
+
dispose(): void;
|
|
61
|
+
}
|
|
62
|
+
export interface DraftCommitterOptions {
|
|
63
|
+
policyOf: (field: string) => CommitPolicy;
|
|
64
|
+
/** The revision the session's view is at now (captured as a position's base on its first edit). */
|
|
65
|
+
baseOf?: () => number | undefined;
|
|
66
|
+
commit: (positions: readonly UncommittedPosition[]) => void;
|
|
67
|
+
scheduler?: Scheduler;
|
|
68
|
+
idleMs?: number;
|
|
69
|
+
}
|
|
70
|
+
export declare function createDraftCommitter(options: DraftCommitterOptions): DraftCommitter;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { formatValuePath } from '@elytracms/core/cms-core';
|
|
2
|
+
import { IDLE_COMMIT_MS } from './commit-policy.js';
|
|
3
|
+
/** The real clock (the editor's default). */
|
|
4
|
+
export const browserScheduler = {
|
|
5
|
+
setTimeout: (callback, ms) => globalThis.setTimeout(callback, ms),
|
|
6
|
+
clearTimeout: (handle) => globalThis.clearTimeout(handle),
|
|
7
|
+
};
|
|
8
|
+
export function createDraftCommitter(options) {
|
|
9
|
+
const scheduler = options.scheduler ?? browserScheduler;
|
|
10
|
+
const idleMs = options.idleMs ?? IDLE_COMMIT_MS;
|
|
11
|
+
/** Uncommitted positions by path key (one per position — a re-edit keeps one entry). */
|
|
12
|
+
const pending = new Map();
|
|
13
|
+
const idleTimers = new Map();
|
|
14
|
+
let focus;
|
|
15
|
+
const cancelIdle = (field) => {
|
|
16
|
+
const handle = idleTimers.get(field);
|
|
17
|
+
if (handle !== undefined)
|
|
18
|
+
scheduler.clearTimeout(handle);
|
|
19
|
+
idleTimers.delete(field);
|
|
20
|
+
};
|
|
21
|
+
/** Commit `field`'s positions plus every position of a field that does not have focus. */
|
|
22
|
+
const commitField = (field) => {
|
|
23
|
+
cancelIdle(field);
|
|
24
|
+
const batch = [...pending.entries()].filter(([, position]) => position.field === field || position.field !== focus);
|
|
25
|
+
if (batch.length === 0)
|
|
26
|
+
return;
|
|
27
|
+
for (const [key] of batch)
|
|
28
|
+
pending.delete(key);
|
|
29
|
+
options.commit(batch.map(([, position]) => position));
|
|
30
|
+
};
|
|
31
|
+
return {
|
|
32
|
+
edited(field, path) {
|
|
33
|
+
const key = formatValuePath(path);
|
|
34
|
+
const previous = pending.get(key);
|
|
35
|
+
pending.set(key, { field, path, base: previous ? previous.base : options.baseOf?.() });
|
|
36
|
+
const policy = options.policyOf(field);
|
|
37
|
+
if (policy === 'change' || focus === undefined) {
|
|
38
|
+
commitField(field);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (focus !== field)
|
|
42
|
+
return; // rides along with the focused field's commit
|
|
43
|
+
if (policy === 'blur-or-idle') {
|
|
44
|
+
cancelIdle(field);
|
|
45
|
+
idleTimers.set(field, scheduler.setTimeout(() => {
|
|
46
|
+
idleTimers.delete(field);
|
|
47
|
+
commitField(field);
|
|
48
|
+
}, idleMs));
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
focused(field) {
|
|
52
|
+
if (focus !== undefined && focus !== field)
|
|
53
|
+
commitField(focus);
|
|
54
|
+
focus = field;
|
|
55
|
+
},
|
|
56
|
+
blurred(field) {
|
|
57
|
+
if (focus === field)
|
|
58
|
+
focus = undefined;
|
|
59
|
+
commitField(field);
|
|
60
|
+
},
|
|
61
|
+
entered(field) {
|
|
62
|
+
if (options.policyOf(field) === 'blur-or-enter')
|
|
63
|
+
commitField(field);
|
|
64
|
+
},
|
|
65
|
+
commitAll() {
|
|
66
|
+
for (const field of [...idleTimers.keys()])
|
|
67
|
+
cancelIdle(field);
|
|
68
|
+
if (pending.size === 0)
|
|
69
|
+
return;
|
|
70
|
+
const batch = [...pending.values()];
|
|
71
|
+
pending.clear();
|
|
72
|
+
options.commit(batch);
|
|
73
|
+
},
|
|
74
|
+
uncommitted: () => [...pending.values()],
|
|
75
|
+
focusedField: () => focus,
|
|
76
|
+
dispose() {
|
|
77
|
+
for (const field of [...idleTimers.keys()])
|
|
78
|
+
cancelIdle(field);
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=draft-commit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"draft-commit.js","sourceRoot":"","sources":["../../../src/components/cms/draft-commit.ts"],"names":[],"mappings":"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","sourcesContent":["import { formatValuePath } from '@elytracms/core/cms-core'\nimport type { ValuePath } from '@elytracms/core/cms-core'\nimport type { CommitPolicy } from './commit-policy'\nimport { IDLE_COMMIT_MS } from './commit-policy'\n\n/**\n * EC-595 A2 — the editor's COMMIT-ON-QUIESCENCE core (pure, clock injected; the house\n * pattern: no DOM, no React).\n *\n * The editor's draft changes per keystroke (live validation reads it); what is\n * COMMITTED — handed to the persister as patches — follows each field's\n * {@link CommitPolicy}. This core tracks the uncommitted positions and decides when\n * each is committed:\n *\n * - an edit of a `change`-policy field commits at once;\n * - an edit of the FOCUSED field waits for its blur, Enter (`blur-or-enter`) or idle\n * pause (`blur-or-idle`, re-armed on every edit — {@link Scheduler});\n * - an edit of a field that does NOT have focus (a derived value — the auto-slug\n * following the title, fill-from-base) rides along with the focused field's next\n * commit, or commits at once when no field has focus;\n * - {@link DraftCommitter.commitAll} is the FORCED commit (publish, unmount, tab hide,\n * duplicate, an AI proposal, transfer) — everything uncommitted, now.\n *\n * `commit` receives the positions; the caller builds the patches from its latest draft\n * (the value AT commit time, so a committed value is never a stale keystroke).\n */\n\n/** The injected clock: timers for the idle pause. */\nexport interface Scheduler {\n setTimeout(callback: () => void, ms: number): unknown\n clearTimeout(handle: unknown): void\n}\n\n/** The real clock (the editor's default). */\nexport const browserScheduler: Scheduler = {\n setTimeout: (callback, ms) => globalThis.setTimeout(callback, ms),\n clearTimeout: (handle) => globalThis.clearTimeout(handle as ReturnType<typeof setTimeout>),\n}\n\n/** One uncommitted position and the field (by name) whose control wrote it. */\nexport interface UncommittedPosition {\n readonly field: string\n readonly path: ValuePath\n /**\n * The revision the user's view was at when they STARTED editing this position — the\n * patch's base. A colleague's change of the same position that arrives (by\n * subscription) while the user is still typing is therefore refused on that field at\n * commit, never overwritten (EC-595 point 7: \"local wins until flushed, then the\n * per-path check decides\").\n */\n readonly base: number | undefined\n}\n\nexport interface DraftCommitter {\n /** A field's control wrote `path`. */\n edited(field: string, path: ValuePath): void\n /** Focus entered a field's control. */\n focused(field: string): void\n /** Focus left a field's control (commits it and what rode along). */\n blurred(field: string): void\n /** Enter in a single-line control (commits it). */\n entered(field: string): void\n /** The forced commit: everything uncommitted, now. */\n commitAll(): void\n /** The uncommitted positions (the editor overlays them on a rebased draft). */\n uncommitted(): readonly UncommittedPosition[]\n /** The field that has focus, if any. */\n focusedField(): string | undefined\n /** Cancel the idle timers (unmount). */\n dispose(): void\n}\n\nexport interface DraftCommitterOptions {\n policyOf: (field: string) => CommitPolicy\n /** The revision the session's view is at now (captured as a position's base on its first edit). */\n baseOf?: () => number | undefined\n commit: (positions: readonly UncommittedPosition[]) => void\n scheduler?: Scheduler\n idleMs?: number\n}\n\nexport function createDraftCommitter(options: DraftCommitterOptions): DraftCommitter {\n const scheduler = options.scheduler ?? browserScheduler\n const idleMs = options.idleMs ?? IDLE_COMMIT_MS\n /** Uncommitted positions by path key (one per position — a re-edit keeps one entry). */\n const pending = new Map<string, UncommittedPosition>()\n const idleTimers = new Map<string, unknown>()\n let focus: string | undefined\n\n const cancelIdle = (field: string) => {\n const handle = idleTimers.get(field)\n if (handle !== undefined) scheduler.clearTimeout(handle)\n idleTimers.delete(field)\n }\n\n /** Commit `field`'s positions plus every position of a field that does not have focus. */\n const commitField = (field: string) => {\n cancelIdle(field)\n const batch = [...pending.entries()].filter(\n ([, position]) => position.field === field || position.field !== focus,\n )\n if (batch.length === 0) return\n for (const [key] of batch) pending.delete(key)\n options.commit(batch.map(([, position]) => position))\n }\n\n return {\n edited(field, path) {\n const key = formatValuePath(path)\n const previous = pending.get(key)\n pending.set(key, { field, path, base: previous ? previous.base : options.baseOf?.() })\n const policy = options.policyOf(field)\n if (policy === 'change' || focus === undefined) {\n commitField(field)\n return\n }\n if (focus !== field) return // rides along with the focused field's commit\n if (policy === 'blur-or-idle') {\n cancelIdle(field)\n idleTimers.set(\n field,\n scheduler.setTimeout(() => {\n idleTimers.delete(field)\n commitField(field)\n }, idleMs),\n )\n }\n },\n focused(field) {\n if (focus !== undefined && focus !== field) commitField(focus)\n focus = field\n },\n blurred(field) {\n if (focus === field) focus = undefined\n commitField(field)\n },\n entered(field) {\n if (options.policyOf(field) === 'blur-or-enter') commitField(field)\n },\n commitAll() {\n for (const field of [...idleTimers.keys()]) cancelIdle(field)\n if (pending.size === 0) return\n const batch = [...pending.values()]\n pending.clear()\n options.commit(batch)\n },\n uncommitted: () => [...pending.values()],\n focusedField: () => focus,\n dispose() {\n for (const field of [...idleTimers.keys()]) cancelIdle(field)\n },\n }\n}\n"]}
|
|
@@ -28,19 +28,17 @@ export interface DeriveDuplicateInput {
|
|
|
28
28
|
export declare function deriveDuplicateDocument({ original, newId, schema, siblings, }: DeriveDuplicateInput): CmsDocument;
|
|
29
29
|
/**
|
|
30
30
|
* Duplicate `original` through a {@link CollectionViewSource} — the ONE dispatch
|
|
31
|
-
* both surfaces (list row menu, detail-editor header) share
|
|
32
|
-
* EXISTING write paths, never a parallel one (AD-17):
|
|
31
|
+
* both surfaces (list row menu, detail-editor header) share (EC-595 A2):
|
|
33
32
|
*
|
|
34
|
-
* 1.
|
|
35
|
-
*
|
|
36
|
-
* 2.
|
|
37
|
-
*
|
|
33
|
+
* 1. a fresh id from the session's injected factory (`writes.newId`, EC-578 — UUIDs, so
|
|
34
|
+
* two sessions duplicating at once can never mint the same id);
|
|
35
|
+
* 2. ONE whole-document create — insert-if-absent (`writes.insert` →
|
|
36
|
+
* `documents.replace` `{ ifAbsent: true }`), never an overwrite. (It used to be a
|
|
37
|
+
* blank `create()` followed by a whole-document save — two writes.)
|
|
38
38
|
*
|
|
39
|
-
* The session
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* gate) before dispatching — CMS collections only (owner call 2026-07-17;
|
|
44
|
-
* every primitive rail declares `duplicate: false`).
|
|
39
|
+
* The session shows the new row at once (the persister's optimistic view). Callers
|
|
40
|
+
* gate on the explicit `capabilities.duplicate` flag (the row-menu vocabulary / the
|
|
41
|
+
* header gate) before dispatching — CMS collections only (owner call 2026-07-17; every
|
|
42
|
+
* primitive rail declares `duplicate: false` and writes records, so `undefined`).
|
|
45
43
|
*/
|
|
46
|
-
export declare function duplicateFromSource(source: CollectionViewSource, original: CmsDocument): DocumentRef;
|
|
44
|
+
export declare function duplicateFromSource(source: CollectionViewSource, original: CmsDocument): DocumentRef | undefined;
|