From 2cc93c797f028cc172e11499de8fa9a0725495dc Mon Sep 17 00:00:00 2001 From: Ash Date: Thu, 9 Jan 2025 10:23:53 +0000 Subject: [PATCH] feat(sanity): move `diffView` into `sanity` In my opinion, this functionality was better organised when it was isolated as a plugin. However, due to dependencies on `sanity/structure`, it was necessary to move it into that part of the codebase. Some things are now more heavy-handed, such as the way the "Compare Versions" document action is inserted. --- .../src/core/config/resolveDefaultPlugins.ts | 10 +---- .../sanity/src/core/diffView/i18n/index.ts | 27 ------------- .../src/core/diffView/i18n/resources.ts | 22 ----------- .../plugin/DiffViewDocumentLayout.tsx | 16 -------- .../sanity/src/core/diffView/plugin/index.ts | 33 ---------------- .../core/releases/hooks/usePerspective.tsx | 1 - .../src/core/releases/i18n/resources.ts | 2 - .../documentActions/CompareVersionsAction.tsx | 37 ------------------ .../releases/plugin/documentActions/index.ts | 2 - .../diffView/components/DialogLayout.ts | 0 .../diffView/components/DiffView.tsx | 2 +- .../diffView/components/DiffViewPane.tsx | 17 +++++--- .../components/PathSyncChannelSubscriber.ts | 0 .../diffView/components/Scroller.ts | 0 .../{core => structure}/diffView/constants.ts | 0 .../hooks/useCreatePathSyncChannel.ts | 0 .../diffView/hooks/useDiffViewRouter.ts | 2 +- .../diffView/hooks/useDiffViewState.ts | 36 +++++++++-------- .../diffView/hooks/usePathSyncChannel.ts | 2 +- .../diffView/hooks/useScrollMirror.tsx | 0 .../sanity/src/structure/diffView/index.ts | 1 + .../plugin/DiffViewDocumentLayout.tsx | 18 +++++++++ .../diffView/types/diffViewMode.ts | 0 .../diffView/types/pathSyncChannel.ts | 0 .../components/VersionModeHeader.tsx | 39 +++++++++---------- .../sanity/src/structure/i18n/resources.ts | 11 ++++++ .../structure/panes/document/DocumentPane.tsx | 9 +++-- .../panes/document/DocumentPaneProvider.tsx | 28 ++++++++++--- .../src/structure/panes/document/menuItems.ts | 13 ++++++- 29 files changed, 123 insertions(+), 205 deletions(-) delete mode 100644 packages/sanity/src/core/diffView/i18n/index.ts delete mode 100644 packages/sanity/src/core/diffView/i18n/resources.ts delete mode 100644 packages/sanity/src/core/diffView/plugin/DiffViewDocumentLayout.tsx delete mode 100644 packages/sanity/src/core/diffView/plugin/index.ts delete mode 100644 packages/sanity/src/core/releases/plugin/documentActions/CompareVersionsAction.tsx rename packages/sanity/src/{core => structure}/diffView/components/DialogLayout.ts (100%) rename packages/sanity/src/{core => structure}/diffView/components/DiffView.tsx (97%) rename packages/sanity/src/{core => structure}/diffView/components/DiffViewPane.tsx (90%) rename packages/sanity/src/{core => structure}/diffView/components/PathSyncChannelSubscriber.ts (100%) rename packages/sanity/src/{core => structure}/diffView/components/Scroller.ts (100%) rename packages/sanity/src/{core => structure}/diffView/constants.ts (100%) rename packages/sanity/src/{core => structure}/diffView/hooks/useCreatePathSyncChannel.ts (100%) rename packages/sanity/src/{core => structure}/diffView/hooks/useDiffViewRouter.ts (98%) rename packages/sanity/src/{core => structure}/diffView/hooks/useDiffViewState.ts (86%) rename packages/sanity/src/{core => structure}/diffView/hooks/usePathSyncChannel.ts (95%) rename packages/sanity/src/{core => structure}/diffView/hooks/useScrollMirror.tsx (100%) create mode 100644 packages/sanity/src/structure/diffView/index.ts create mode 100644 packages/sanity/src/structure/diffView/plugin/DiffViewDocumentLayout.tsx rename packages/sanity/src/{core => structure}/diffView/types/diffViewMode.ts (100%) rename packages/sanity/src/{core => structure}/diffView/types/pathSyncChannel.ts (100%) rename packages/sanity/src/{core => structure}/diffView/versionMode/components/VersionModeHeader.tsx (91%) diff --git a/packages/sanity/src/core/config/resolveDefaultPlugins.ts b/packages/sanity/src/core/config/resolveDefaultPlugins.ts index d76df99203f..7fb2e887263 100644 --- a/packages/sanity/src/core/config/resolveDefaultPlugins.ts +++ b/packages/sanity/src/core/config/resolveDefaultPlugins.ts @@ -1,6 +1,5 @@ import {comments} from '../comments/plugin' import {createIntegration} from '../create/createIntegrationPlugin' -import {diffView} from '../diffView/plugin' import {releases, RELEASES_NAME} from '../releases/plugin' import {DEFAULT_SCHEDULED_PUBLISH_PLUGIN_OPTIONS} from '../scheduledPublishing/constants' import {SCHEDULED_PUBLISHING_NAME, scheduledPublishing} from '../scheduledPublishing/plugin' @@ -12,14 +11,7 @@ import { type WorkspaceOptions, } from './types' -const defaultPlugins = [ - comments(), - tasks(), - scheduledPublishing(), - createIntegration(), - releases(), - diffView(), -] +const defaultPlugins = [comments(), tasks(), scheduledPublishing(), createIntegration(), releases()] export function getDefaultPlugins( options: DefaultPluginsWorkspaceOptions, diff --git a/packages/sanity/src/core/diffView/i18n/index.ts b/packages/sanity/src/core/diffView/i18n/index.ts deleted file mode 100644 index cd50af97ad6..00000000000 --- a/packages/sanity/src/core/diffView/i18n/index.ts +++ /dev/null @@ -1,27 +0,0 @@ -import {type LocaleResourceBundle} from '../../i18n' - -/** - * The locale namespace for the DiffView plugin. - * - * @public - */ -export const diffViewLocaleNamespace = 'diffView' as const - -/** - * The default locale bundle for the DiffView plugin, which is US English. - * - * @internal - */ -export const diffViewUsEnglishLocaleBundle: LocaleResourceBundle = { - locale: 'en-US', - namespace: diffViewLocaleNamespace, - resources: () => import('./resources'), -} - -/** - * The locale resource keys for the DiffView plugin. - * - * @alpha - * @hidden - */ -export type {DiffViewLocaleResourceKeys} from './resources' diff --git a/packages/sanity/src/core/diffView/i18n/resources.ts b/packages/sanity/src/core/diffView/i18n/resources.ts deleted file mode 100644 index 6d3cca17461..00000000000 --- a/packages/sanity/src/core/diffView/i18n/resources.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {defineLocalesResources} from '../../i18n' - -/** - * Defined locale strings for the DiffView plugin, in US English. - * - * @internal - */ -const diffViewLocaleStrings = defineLocalesResources('diffView', { - /** The title used when comparing versions of a document */ - 'compare-versions.title': 'Compare versions', - /** The string used to label draft documents */ - 'compare-versions.status.draft': 'Draft', - /** The string used to label published documents */ - 'compare-versions.status.published': 'Published', -}) - -/** - * @alpha - */ -export type DiffViewLocaleResourceKeys = keyof typeof diffViewLocaleStrings - -export default diffViewLocaleStrings diff --git a/packages/sanity/src/core/diffView/plugin/DiffViewDocumentLayout.tsx b/packages/sanity/src/core/diffView/plugin/DiffViewDocumentLayout.tsx deleted file mode 100644 index 69bdf231e3b..00000000000 --- a/packages/sanity/src/core/diffView/plugin/DiffViewDocumentLayout.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import {type ComponentType} from 'react' - -import {type DocumentLayoutProps} from '../../config' -import {DiffView} from '../components/DiffView' -import {useDiffViewState} from '../hooks/useDiffViewState' - -export const DiffViewDocumentLayout: ComponentType = (props) => { - const {state} = useDiffViewState() - - return ( - <> - {props.renderDefault(props)} - {state === 'ready' && } - - ) -} diff --git a/packages/sanity/src/core/diffView/plugin/index.ts b/packages/sanity/src/core/diffView/plugin/index.ts deleted file mode 100644 index 6c53bcb8261..00000000000 --- a/packages/sanity/src/core/diffView/plugin/index.ts +++ /dev/null @@ -1,33 +0,0 @@ -import {definePlugin} from '../../config' -import {diffViewUsEnglishLocaleBundle} from '../i18n' -import {DiffViewDocumentLayout} from './DiffViewDocumentLayout' - -/** - * @internal - */ -export const DIFF_VIEW_NAME = 'sanity/diffView' - -/** - * @internal - */ -export const DIFF_VIEW_TOOL_NAME = 'diffView' - -/** - * @internal - */ -export const DIFF_VIEW_INTENT = 'diffView' - -/** - * @internal - */ -export const diffView = definePlugin({ - name: DIFF_VIEW_NAME, - document: { - components: { - unstable_layout: DiffViewDocumentLayout, - }, - }, - i18n: { - bundles: [diffViewUsEnglishLocaleBundle], - }, -}) diff --git a/packages/sanity/src/core/releases/hooks/usePerspective.tsx b/packages/sanity/src/core/releases/hooks/usePerspective.tsx index d48dc92fb41..55edb4f7b60 100644 --- a/packages/sanity/src/core/releases/hooks/usePerspective.tsx +++ b/packages/sanity/src/core/releases/hooks/usePerspective.tsx @@ -74,7 +74,6 @@ export function usePerspective({ | ReleaseId | undefined - // TODO: When `perspectiveOverride` is set, exclusion should not have an effect. const excludedPerspectives = useMemo( () => excludedPerspectivesOverride ?? diff --git a/packages/sanity/src/core/releases/i18n/resources.ts b/packages/sanity/src/core/releases/i18n/resources.ts index eafb48ec6af..534eec982e9 100644 --- a/packages/sanity/src/core/releases/i18n/resources.ts +++ b/packages/sanity/src/core/releases/i18n/resources.ts @@ -12,8 +12,6 @@ const releasesLocaleStrings = { 'action.archive.tooltip': 'Unschedule this release to archive it', /** Action text for showing the archived releases */ 'action.archived': 'Archived', - /** Action text for comparing document versions */ - 'action.compare-versions': 'Compare versions', /** Action text for reverting a release by creating a new release */ 'action.create-revert-release': 'Stage in new release', /** Action text for deleting a release */ diff --git a/packages/sanity/src/core/releases/plugin/documentActions/CompareVersionsAction.tsx b/packages/sanity/src/core/releases/plugin/documentActions/CompareVersionsAction.tsx deleted file mode 100644 index 31e2a6d46e0..00000000000 --- a/packages/sanity/src/core/releases/plugin/documentActions/CompareVersionsAction.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import {TransferIcon} from '@sanity/icons' -import {useMemo} from 'react' - -import {type ActionComponent, type DocumentActionProps} from '../../../config' -import {useDiffViewRouter} from '../../../diffView/hooks/useDiffViewRouter' -import {useTranslation} from '../../../i18n' -import {usePerspective} from '../../hooks/usePerspective' -import {releasesLocaleNamespace} from '../../i18n' - -export const CompareVersionsAction: ActionComponent = ({type, version}) => { - const {t} = useTranslation(releasesLocaleNamespace) - const {navigateDiffView} = useDiffViewRouter() - const {perspectiveStack} = usePerspective() - const isEnabled = version !== null && perspectiveStack.length > 1 - - return useMemo( - () => ({ - icon: TransferIcon, - label: t('action.compare-versions'), - group: ['paneActions'], - disabled: !isEnabled, - onHandle: () => { - if (!isEnabled) { - return - } - navigateDiffView({ - mode: 'version', - nextDocument: { - type, - id: version._id, - }, - }) - }, - }), - [isEnabled, navigateDiffView, t, type, version?._id], - ) -} diff --git a/packages/sanity/src/core/releases/plugin/documentActions/index.ts b/packages/sanity/src/core/releases/plugin/documentActions/index.ts index 68c0cdf508b..7f4e1071785 100644 --- a/packages/sanity/src/core/releases/plugin/documentActions/index.ts +++ b/packages/sanity/src/core/releases/plugin/documentActions/index.ts @@ -1,6 +1,5 @@ import {type DocumentActionComponent} from '../../../config/document/actions' import {type DocumentActionsContext} from '../../../config/types' -import {CompareVersionsAction} from './CompareVersionsAction' import {DiscardVersionAction} from './DiscardVersionAction' import {UnpublishVersionAction} from './UnpublishVersionAction' @@ -15,6 +14,5 @@ export default function resolveDocumentActions( ...(context.versionType === 'version' ? duplicateAction.concat(DiscardVersionAction).concat(UnpublishVersionAction) : existingActions), - CompareVersionsAction, ] } diff --git a/packages/sanity/src/core/diffView/components/DialogLayout.ts b/packages/sanity/src/structure/diffView/components/DialogLayout.ts similarity index 100% rename from packages/sanity/src/core/diffView/components/DialogLayout.ts rename to packages/sanity/src/structure/diffView/components/DialogLayout.ts diff --git a/packages/sanity/src/core/diffView/components/DiffView.tsx b/packages/sanity/src/structure/diffView/components/DiffView.tsx similarity index 97% rename from packages/sanity/src/core/diffView/components/DiffView.tsx rename to packages/sanity/src/structure/diffView/components/DiffView.tsx index 19617bb9a38..4c68f3fc84e 100644 --- a/packages/sanity/src/core/diffView/components/DiffView.tsx +++ b/packages/sanity/src/structure/diffView/components/DiffView.tsx @@ -1,7 +1,7 @@ import {type ComponentType, useState} from 'react' +import {type DocumentLayoutProps} from 'sanity' import {Dialog} from '../../../ui-components/dialog/Dialog' -import {type DocumentLayoutProps} from '../../config/types' import {useCreatePathSyncChannel} from '../hooks/useCreatePathSyncChannel' import {useDiffViewRouter} from '../hooks/useDiffViewRouter' import {useDiffViewState} from '../hooks/useDiffViewState' diff --git a/packages/sanity/src/core/diffView/components/DiffViewPane.tsx b/packages/sanity/src/structure/diffView/components/DiffViewPane.tsx similarity index 90% rename from packages/sanity/src/core/diffView/components/DiffViewPane.tsx rename to packages/sanity/src/structure/diffView/components/DiffViewPane.tsx index 80ceabf3958..6129a2abc53 100644 --- a/packages/sanity/src/core/diffView/components/DiffViewPane.tsx +++ b/packages/sanity/src/structure/diffView/components/DiffViewPane.tsx @@ -1,14 +1,18 @@ import {BoundaryElementProvider, Box, Card, DialogProvider, PortalProvider} from '@sanity/ui' import {noop} from 'lodash' import {type CSSProperties, forwardRef, useRef, useState} from 'react' +import { + ChangeIndicatorsTracker, + getPublishedId, + getVersionFromId, + isDraftId, + useEditState, + VirtualizerScrollInstanceProvider, +} from 'sanity' import {ConnectorContext} from 'sanity/_singletons' -import {DocumentPaneProvider, FormViewComponent} from 'sanity/structure' import {styled} from 'styled-components' -import {ChangeIndicatorsTracker} from '../../changeIndicators/tracker' -import {VirtualizerScrollInstanceProvider} from '../../form/inputs/arrays/ArrayOfObjectsInput/List/VirtualizerScrollInstanceProvider' -import {useEditState} from '../../hooks/useEditState' -import {getPublishedId, getVersionFromId, isDraftId} from '../../util/draftUtils' +import {DocumentPaneProvider, FormViewComponent} from '../..' import {type PathSyncChannel} from '../types/pathSyncChannel' import {PathSyncChannelSubscriber} from './PathSyncChannelSubscriber' import {Scroller} from './Scroller' @@ -33,7 +37,7 @@ interface DiffViewPaneProps { // TODO: Switch off comments. Document inspectors cannot currently be shown inside the diff view. // TODO: Switch off references pane. It should be a hyperlink instead. export const DiffViewPane = forwardRef(function DiffViewPane( - {role, documentType, documentId, scrollElement, syncChannel, /*compareValue,*/ compareDocument}, + {role, documentType, documentId, scrollElement, syncChannel, compareDocument}, ref, ) { const paneId = ['diffView', role].join('.') @@ -103,6 +107,7 @@ export const DiffViewPane = forwardRef(functi paneKey={paneId} itemId={paneId} perspectiveOverride={version} + excludedPerspectivesOverride={[]} pane={{ id: paneId, type: 'document', diff --git a/packages/sanity/src/core/diffView/components/PathSyncChannelSubscriber.ts b/packages/sanity/src/structure/diffView/components/PathSyncChannelSubscriber.ts similarity index 100% rename from packages/sanity/src/core/diffView/components/PathSyncChannelSubscriber.ts rename to packages/sanity/src/structure/diffView/components/PathSyncChannelSubscriber.ts diff --git a/packages/sanity/src/core/diffView/components/Scroller.ts b/packages/sanity/src/structure/diffView/components/Scroller.ts similarity index 100% rename from packages/sanity/src/core/diffView/components/Scroller.ts rename to packages/sanity/src/structure/diffView/components/Scroller.ts diff --git a/packages/sanity/src/core/diffView/constants.ts b/packages/sanity/src/structure/diffView/constants.ts similarity index 100% rename from packages/sanity/src/core/diffView/constants.ts rename to packages/sanity/src/structure/diffView/constants.ts diff --git a/packages/sanity/src/core/diffView/hooks/useCreatePathSyncChannel.ts b/packages/sanity/src/structure/diffView/hooks/useCreatePathSyncChannel.ts similarity index 100% rename from packages/sanity/src/core/diffView/hooks/useCreatePathSyncChannel.ts rename to packages/sanity/src/structure/diffView/hooks/useCreatePathSyncChannel.ts diff --git a/packages/sanity/src/core/diffView/hooks/useDiffViewRouter.ts b/packages/sanity/src/structure/diffView/hooks/useDiffViewRouter.ts similarity index 98% rename from packages/sanity/src/core/diffView/hooks/useDiffViewRouter.ts rename to packages/sanity/src/structure/diffView/hooks/useDiffViewRouter.ts index e32e75007af..295f6ca39c1 100644 --- a/packages/sanity/src/core/diffView/hooks/useDiffViewRouter.ts +++ b/packages/sanity/src/structure/diffView/hooks/useDiffViewRouter.ts @@ -24,7 +24,7 @@ type NavigateDiffView = ( >, ) => void -interface DiffViewRouter { +export interface DiffViewRouter { navigateDiffView: NavigateDiffView exitDiffView: () => void } diff --git a/packages/sanity/src/core/diffView/hooks/useDiffViewState.ts b/packages/sanity/src/structure/diffView/hooks/useDiffViewState.ts similarity index 86% rename from packages/sanity/src/core/diffView/hooks/useDiffViewState.ts rename to packages/sanity/src/structure/diffView/hooks/useDiffViewState.ts index 5675d14867f..b17fbf49a35 100644 --- a/packages/sanity/src/core/diffView/hooks/useDiffViewState.ts +++ b/packages/sanity/src/structure/diffView/hooks/useDiffViewState.ts @@ -2,19 +2,18 @@ import {type SanityClient} from '@sanity/client' import {useEffect, useMemo} from 'react' import {useObservable} from 'react-rx' import {EMPTY, map, type Observable} from 'rxjs' -import {useRouter} from 'sanity/router' - -import {useClient} from '../../hooks/useClient' -import {usePerspective} from '../../releases/hooks/usePerspective' -import {DEFAULT_STUDIO_CLIENT_OPTIONS} from '../../studioClient' import { + DEFAULT_STUDIO_CLIENT_OPTIONS, getDraftId, getPublishedId, getVersionId, isSystemBundle, - isVersionId, type PublishedId, -} from '../../util/draftUtils' + useClient, + usePerspective, +} from 'sanity' +import {useRouter} from 'sanity/router' + import { DIFF_SEARCH_PARAM_SEPERATOR, DIFF_VIEW_NEXT_DOCUMENT_SEARCH_PARAMETER, @@ -62,9 +61,10 @@ export function useDiffViewState(): DiffViewState { const {perspectiveStack} = usePerspective() const client = useClient(DEFAULT_STUDIO_CLIENT_OPTIONS) - // ensure not `""` - // ensure not `null` - // ensure types are in schema + // TODO: Validate parameters. + // - Ensure not `""`. + // - Ensure not `null`. + // - Ensure types are present in schema. const [previousDocumentType, previousDocumentId] = ( searchParams.get(DIFF_VIEW_PREVIOUS_DOCUMENT_SEARCH_PARAMETER) ?? '' ).split(DIFF_SEARCH_PARAM_SEPERATOR) @@ -77,16 +77,15 @@ export function useDiffViewState(): DiffViewState { // will be inferred by finding the next existing document in the perspective stack. const shouldInferPreviousDocument = diffViewMode === 'version' && - searchParams.get(DIFF_VIEW_PREVIOUS_DOCUMENT_SEARCH_PARAMETER) === null && - isVersionId(nextDocumentId) + searchParams.get(DIFF_VIEW_PREVIOUS_DOCUMENT_SEARCH_PARAMETER) === null const inferPreviousDocument = useMemo(() => { if (!shouldInferPreviousDocument) { return EMPTY } - return getFirstExistentVersion({ - bundles: perspectiveStack.slice(1), + return findPrecedingVersion({ + bundles: perspectiveStack, publishedId: getPublishedId(nextDocumentId), client, }) @@ -99,6 +98,8 @@ export function useDiffViewState(): DiffViewState { return } + // TODO: Navigating like this once the previous document has been inferred causes a redundant + // browser history entry to be created, resulting in an unusual experience when navigating back. navigateDiffView({ mode: 'version', previousDocument: { @@ -144,12 +145,12 @@ export function useDiffViewState(): DiffViewState { } /** - * Find the first existing document id in the provided array of bundles. This can be used to find - * the id of the document that immediately precedes another when release layering is applied. + * Find the first existing document id that precedes the first entry in the provided array of + * bundles. * * This function implicitly includes draft and published documents. */ -function getFirstExistentVersion({ +function findPrecedingVersion({ bundles, publishedId, client, @@ -161,6 +162,7 @@ function getFirstExistentVersion({ const ids = bundles .flatMap((bundle) => (isSystemBundle(bundle) ? [] : getVersionId(publishedId, bundle))) .concat(getDraftId(publishedId), publishedId) + .slice(1) return client.observable .fetch( diff --git a/packages/sanity/src/core/diffView/hooks/usePathSyncChannel.ts b/packages/sanity/src/structure/diffView/hooks/usePathSyncChannel.ts similarity index 95% rename from packages/sanity/src/core/diffView/hooks/usePathSyncChannel.ts rename to packages/sanity/src/structure/diffView/hooks/usePathSyncChannel.ts index 745e61b71f6..e3fa322f2b5 100644 --- a/packages/sanity/src/core/diffView/hooks/usePathSyncChannel.ts +++ b/packages/sanity/src/structure/diffView/hooks/usePathSyncChannel.ts @@ -1,9 +1,9 @@ import {useCallback, useEffect, useMemo} from 'react' +import deepEquals from 'react-fast-compare' import {useObservable} from 'react-rx' import {distinctUntilChanged, filter, map} from 'rxjs' import {useDocumentPane} from 'sanity/structure' -import {deepEquals} from '../../validation/util/deepEquals' import {type PathSyncChannelProps, type PathSyncState} from '../types/pathSyncChannel' /** diff --git a/packages/sanity/src/core/diffView/hooks/useScrollMirror.tsx b/packages/sanity/src/structure/diffView/hooks/useScrollMirror.tsx similarity index 100% rename from packages/sanity/src/core/diffView/hooks/useScrollMirror.tsx rename to packages/sanity/src/structure/diffView/hooks/useScrollMirror.tsx diff --git a/packages/sanity/src/structure/diffView/index.ts b/packages/sanity/src/structure/diffView/index.ts new file mode 100644 index 00000000000..1bd699abb3e --- /dev/null +++ b/packages/sanity/src/structure/diffView/index.ts @@ -0,0 +1 @@ +export * from './hooks/useDiffViewRouter' diff --git a/packages/sanity/src/structure/diffView/plugin/DiffViewDocumentLayout.tsx b/packages/sanity/src/structure/diffView/plugin/DiffViewDocumentLayout.tsx new file mode 100644 index 00000000000..7638d3ad49c --- /dev/null +++ b/packages/sanity/src/structure/diffView/plugin/DiffViewDocumentLayout.tsx @@ -0,0 +1,18 @@ +import {type ComponentType, type PropsWithChildren} from 'react' +import {type DocumentLayoutProps} from 'sanity' + +import {DiffView} from '../components/DiffView' +import {useDiffViewState} from '../hooks/useDiffViewState' + +export const DiffViewDocumentLayout: ComponentType< + PropsWithChildren> +> = ({children, documentId}) => { + const {state} = useDiffViewState() + + return ( + <> + {children} + {state === 'ready' && } + + ) +} diff --git a/packages/sanity/src/core/diffView/types/diffViewMode.ts b/packages/sanity/src/structure/diffView/types/diffViewMode.ts similarity index 100% rename from packages/sanity/src/core/diffView/types/diffViewMode.ts rename to packages/sanity/src/structure/diffView/types/diffViewMode.ts diff --git a/packages/sanity/src/core/diffView/types/pathSyncChannel.ts b/packages/sanity/src/structure/diffView/types/pathSyncChannel.ts similarity index 100% rename from packages/sanity/src/core/diffView/types/pathSyncChannel.ts rename to packages/sanity/src/structure/diffView/types/pathSyncChannel.ts diff --git a/packages/sanity/src/core/diffView/versionMode/components/VersionModeHeader.tsx b/packages/sanity/src/structure/diffView/versionMode/components/VersionModeHeader.tsx similarity index 91% rename from packages/sanity/src/core/diffView/versionMode/components/VersionModeHeader.tsx rename to packages/sanity/src/structure/diffView/versionMode/components/VersionModeHeader.tsx index 676beed652a..2762bcad92c 100644 --- a/packages/sanity/src/core/diffView/versionMode/components/VersionModeHeader.tsx +++ b/packages/sanity/src/structure/diffView/versionMode/components/VersionModeHeader.tsx @@ -11,33 +11,32 @@ import { } from '@sanity/ui' import {type TFunction} from 'i18next' import {type ComponentProps, type ComponentType, useCallback, useMemo} from 'react' -import {styled} from 'styled-components' - -import {Button} from '../../../../ui-components/button/Button' -import {MenuButton} from '../../../../ui-components/menuButton/MenuButton' -import {type DocumentLayoutProps} from '../../../config/types' -import {useEditState} from '../../../hooks/useEditState' -import {useTranslation} from '../../../i18n/hooks/useTranslation' -import {ReleaseAvatar} from '../../../releases/components/ReleaseAvatar' -import {useDocumentVersions} from '../../../releases/hooks/useDocumentVersions' -import {isReleaseDocument, type ReleaseDocument} from '../../../releases/store/types' -import {getReleaseIdFromReleaseDocumentId} from '../../../releases/util/getReleaseIdFromReleaseDocumentId' -import {getReleaseTone} from '../../../releases/util/getReleaseTone' import { + type DocumentLayoutProps, formatRelativeLocalePublishDate, - isReleaseScheduledOrScheduling, -} from '../../../releases/util/util' -import { getDraftId, getPublishedId, + getReleaseIdFromReleaseDocumentId, + getReleaseTone, getVersionFromId, getVersionId, isDraftId, isPublishedId, -} from '../../../util/draftUtils' + isReleaseDocument, + isReleaseScheduledOrScheduling, + ReleaseAvatar, + type ReleaseDocument, + useDocumentVersions, + useEditState, + useTranslation, +} from 'sanity' +import {styled} from 'styled-components' + +import {Button} from '../../../../ui-components/button/Button' +import {MenuButton} from '../../../../ui-components/menuButton/MenuButton' +import {structureLocaleNamespace} from '../../../i18n' import {useDiffViewRouter} from '../../hooks/useDiffViewRouter' import {useDiffViewState} from '../../hooks/useDiffViewState' -import {diffViewLocaleNamespace} from '../../i18n' const VersionModeHeaderLayout = styled.header` display: grid; @@ -61,7 +60,7 @@ const VersionModeHeaderLayoutSection = styled.div` export const VersionModeHeader: ComponentType< {state: 'pending' | 'ready' | 'error'} & Pick > = ({documentId, state}) => { - const {t} = useTranslation(diffViewLocaleNamespace) + const {t} = useTranslation(structureLocaleNamespace) const {data: releases} = useDocumentVersions({documentId}) const {exitDiffView, navigateDiffView} = useDiffViewRouter() const {documents} = useDiffViewState() @@ -169,7 +168,7 @@ const VersionMenu: ComponentType = ({ }) => { const {published, draft} = useEditState(getPublishedId(document.id), document.type) const selected = useMemo(() => findRelease(document.id, releases), [document.id, releases]) - const {t} = useTranslation(diffViewLocaleNamespace) + const {t} = useTranslation(structureLocaleNamespace) return ( = ({ isSelected, documentId, }) => { - const {t} = useTranslation(diffViewLocaleNamespace) + const {t} = useTranslation(structureLocaleNamespace) const onClick = useCallback(() => { if (type === 'draft') { diff --git a/packages/sanity/src/structure/i18n/resources.ts b/packages/sanity/src/structure/i18n/resources.ts index 395b94f19d7..1d27280e262 100644 --- a/packages/sanity/src/structure/i18n/resources.ts +++ b/packages/sanity/src/structure/i18n/resources.ts @@ -160,6 +160,7 @@ const structureLocaleStrings = defineLocalesResources('structure', { 'buttons.split-pane-close-button.title': 'Close split pane', /** The title for the close group button on the split pane on the document panel header */ 'buttons.split-pane-close-group-button.title': 'Close pane group', + /** The label used in the changes inspector for the from selector */ 'changes.from.label': 'From', /* The label for the history tab in the changes inspector*/ @@ -168,6 +169,16 @@ const structureLocaleStrings = defineLocalesResources('structure', { 'changes.tab.review-changes': 'Review changes', /** The label used in the changes inspector for the to selector */ 'changes.to.label': 'To', + + /** The text for the "Compare versions" action for a document */ + 'compare-versions.menu-item.title': 'Compare versions', + /** The string used to label draft documents */ + 'compare-versions.status.draft': 'Draft', + /** The string used to label published documents */ + 'compare-versions.status.published': 'Published', + /** The title used when comparing versions of a document */ + 'compare-versions.title': 'Compare versions', + /** The text in the "Cancel" button in the confirm delete dialog that cancels the action and closes the dialog */ 'confirm-delete-dialog.cancel-button.text': 'Cancel', /** Used in `confirm-delete-dialog.cdr-summary.title` */ diff --git a/packages/sanity/src/structure/panes/document/DocumentPane.tsx b/packages/sanity/src/structure/panes/document/DocumentPane.tsx index 8ed1a8328dc..7dcc1e79b20 100644 --- a/packages/sanity/src/structure/panes/document/DocumentPane.tsx +++ b/packages/sanity/src/structure/panes/document/DocumentPane.tsx @@ -16,6 +16,7 @@ import { } from 'sanity' import {usePaneRouter} from '../../components' +import {DiffViewDocumentLayout} from '../../diffView/plugin/DiffViewDocumentLayout' import {structureLocaleNamespace} from '../../i18n' import {type DocumentPaneNode} from '../../types' import {ErrorPane} from '../error' @@ -145,9 +146,11 @@ function DocumentPaneInner(props: DocumentPaneProviderProps) { initialValueTemplateItems={templatePermissions} activePath={activePath} > - - - + + + + + ) diff --git a/packages/sanity/src/structure/panes/document/DocumentPaneProvider.tsx b/packages/sanity/src/structure/panes/document/DocumentPaneProvider.tsx index 2bbfc4b0117..6dd328f547d 100644 --- a/packages/sanity/src/structure/panes/document/DocumentPaneProvider.tsx +++ b/packages/sanity/src/structure/panes/document/DocumentPaneProvider.tsx @@ -53,6 +53,7 @@ import { import {DocumentPaneContext} from 'sanity/_singletons' import {usePaneRouter} from '../../components' +import {useDiffViewRouter} from '../../diffView/hooks/useDiffViewRouter' import {structureLocaleNamespace} from '../../i18n' import {type PaneMenuItem} from '../../types' import {useStructureTool} from '../../useStructureTool' @@ -145,6 +146,7 @@ export const DocumentPaneProvider = memo((props: DocumentPaneProviderProps) => { perspective.selectedPerspective, ]) + const diffViewRouter = useDiffViewRouter() const panePayload = useUnique(paneRouter.payload) const {templateName, templateParams} = useMemo( () => @@ -545,6 +547,17 @@ export const DocumentPaneProvider = memo((props: DocumentPaneProviderProps) => { return true } + if (item.action === 'compareVersions' && value) { + diffViewRouter.navigateDiffView({ + mode: 'version', + nextDocument: { + type: documentType, + id: value._id, + }, + }) + return true + } + if (typeof item.action === 'string' && item.action.startsWith(INSPECT_ACTION_PREFIX)) { const nextInspectorName = item.action.slice(INSPECT_ACTION_PREFIX.length) const nextInspector = inspectors.find((i) => i.name === nextInspectorName) @@ -562,16 +575,19 @@ export const DocumentPaneProvider = memo((props: DocumentPaneProviderProps) => { return false }, [ + previewUrl, + value, + telemetry, + pushToast, t, - closeInspector, + toggleLegacyInspect, handleHistoryOpen, - inspectorName, + diffViewRouter, + documentType, inspectors, + inspectorName, + closeInspector, openInspector, - previewUrl, - toggleLegacyInspect, - pushToast, - telemetry, ], ) diff --git a/packages/sanity/src/structure/panes/document/menuItems.ts b/packages/sanity/src/structure/panes/document/menuItems.ts index 850b5324809..a1c557a9ce7 100644 --- a/packages/sanity/src/structure/panes/document/menuItems.ts +++ b/packages/sanity/src/structure/panes/document/menuItems.ts @@ -1,4 +1,4 @@ -import {EarthAmericasIcon, JsonIcon, LinkIcon} from '@sanity/icons' +import {EarthAmericasIcon, JsonIcon, LinkIcon, TransferIcon} from '@sanity/icons' import {type DocumentInspector, type DocumentInspectorMenuItem, type TFunction} from 'sanity' import {type PaneMenuItem, type StructureToolFeatures} from '../../types' @@ -52,6 +52,16 @@ function getInspectItem({hasValue, t}: GetMenuItemsParams): PaneMenuItem { } } +function getCompareVersionsItem({hasValue, t}: GetMenuItemsParams): PaneMenuItem { + return { + action: 'compareVersions', + group: 'inspectors', + title: t('compare-versions.menu-item.title'), + icon: TransferIcon, + isDisabled: !hasValue, + } +} + export function getProductionPreviewItem({previewUrl, t}: GetMenuItemsParams): PaneMenuItem | null { if (!previewUrl) return null @@ -69,6 +79,7 @@ export function getMenuItems(params: GetMenuItemsParams): PaneMenuItem[] { const items = [ // Get production preview item getProductionPreviewItem(params), + getCompareVersionsItem(params), ].filter(Boolean) as PaneMenuItem[] return [