From c8a0f0a958281f9c63651d3c0d34008c40ccf2be Mon Sep 17 00:00:00 2001 From: Ash Date: Fri, 13 Sep 2024 15:06:04 +0100 Subject: [PATCH] refactor --- packages/sanity/src/core/bundles/util/util.ts | 8 ++-- .../context/comments/CommentsProvider.tsx | 8 +--- .../utils/getPreviewValueWithFallback.tsx | 4 +- .../item/SearchResultItemPreview.tsx | 4 +- .../search/contexts/search/SearchProvider.tsx | 4 +- .../__tests__/resolvePerspectives.test.ts | 42 ++++++++++++------- .../src/core/util/resolvePerspective.ts | 18 ++++++-- .../components/paneItem/PaneItemPreview.tsx | 3 +- .../structureTool/StructureTitle.tsx | 12 +++--- .../panes/document/DocumentPaneProvider.tsx | 5 +-- .../banners/ReferenceChangedBanner.tsx | 5 +-- .../document/inspectors/validation/index.ts | 7 +--- .../panes/documentList/listenSearchQuery.ts | 4 +- 13 files changed, 73 insertions(+), 51 deletions(-) diff --git a/packages/sanity/src/core/bundles/util/util.ts b/packages/sanity/src/core/bundles/util/util.ts index dd06aa276dc6..3a1804148be2 100644 --- a/packages/sanity/src/core/bundles/util/util.ts +++ b/packages/sanity/src/core/bundles/util/util.ts @@ -1,5 +1,5 @@ import {type BundleDocument} from '../../store/bundles/types' -import {getVersionFromId, isVersionId} from '../../util' +import {getVersionFromId, isVersionId, resolveBundlePerspective} from '../../util' /** * @beta @@ -22,11 +22,13 @@ export function getDocumentIsInPerspective( if (!perspective) return !isVersionId(documentId) - if (!perspective.startsWith('bundle.')) return false + const bundlePerspective = resolveBundlePerspective(perspective) + + if (typeof bundlePerspective === 'undefined') return false // perspective is `bundle.${bundleId}` if (bundleId === 'Published') return false - return bundleId === perspective.replace('bundle.', '') + return bundleId === bundlePerspective } export function versionDocumentExists( diff --git a/packages/sanity/src/core/comments/context/comments/CommentsProvider.tsx b/packages/sanity/src/core/comments/context/comments/CommentsProvider.tsx index 049d7abb1527..b7d69ad1f533 100644 --- a/packages/sanity/src/core/comments/context/comments/CommentsProvider.tsx +++ b/packages/sanity/src/core/comments/context/comments/CommentsProvider.tsx @@ -6,7 +6,7 @@ import {CommentsContext} from 'sanity/_singletons' import {useEditState, useSchema, useUserListWithPermissions} from '../../../hooks' import {useCurrentUser} from '../../../store' import {useAddonDataset, useWorkspace} from '../../../studio' -import {getPublishedId} from '../../../util' +import {getPublishedId, resolveBundlePerspective} from '../../../util' import { type CommentOperationsHookOptions, useCommentOperations, @@ -85,15 +85,11 @@ export const CommentsProvider = memo(function CommentsProvider(props: CommentsPr const [status, setStatus] = useState('open') const {client, createAddonDataset, isCreatingDataset} = useAddonDataset() - const bundlePerspective = perspective?.startsWith('bundle.') - ? perspective.split('bundle.').at(1) - : undefined - const editState = useEditState( getPublishedId(versionOrPublishedId), documentType, 'default', - bundlePerspective, + resolveBundlePerspective(perspective), ) const schemaType = useSchema().get(documentType) const currentUser = useCurrentUser() diff --git a/packages/sanity/src/core/preview/utils/getPreviewValueWithFallback.tsx b/packages/sanity/src/core/preview/utils/getPreviewValueWithFallback.tsx index ea1a9109c78b..ba4ca303e380 100644 --- a/packages/sanity/src/core/preview/utils/getPreviewValueWithFallback.tsx +++ b/packages/sanity/src/core/preview/utils/getPreviewValueWithFallback.tsx @@ -2,6 +2,8 @@ import {WarningOutlineIcon} from '@sanity/icons' import {type PreviewValue, type SanityDocument} from '@sanity/types' import {assignWith} from 'lodash' +import {resolveBundlePerspective} from '../../util' + const getMissingDocumentFallback = (item: SanityDocument) => ({ title: {item.title ? String(item.title) : 'Missing document'}, subtitle: {item.title ? `Missing document ID: ${item._id}` : `Document ID: ${item._id}`}, @@ -30,7 +32,7 @@ export const getPreviewValueWithFallback = ({ let snapshot: Partial | PreviewValue | null | undefined switch (true) { - case perspective?.startsWith('bundle.'): + case typeof resolveBundlePerspective(perspective) !== 'undefined': snapshot = version || draft || published break case perspective === 'published': diff --git a/packages/sanity/src/core/studio/components/navbar/search/components/searchResults/item/SearchResultItemPreview.tsx b/packages/sanity/src/core/studio/components/navbar/search/components/searchResults/item/SearchResultItemPreview.tsx index 1ca036847662..e8cb95844ed2 100644 --- a/packages/sanity/src/core/studio/components/navbar/search/components/searchResults/item/SearchResultItemPreview.tsx +++ b/packages/sanity/src/core/studio/components/navbar/search/components/searchResults/item/SearchResultItemPreview.tsx @@ -3,7 +3,7 @@ import {type SchemaType} from '@sanity/types' import {Badge, Box, Flex} from '@sanity/ui' import {useMemo} from 'react' import {useObservable} from 'react-rx' -import {getPublishedId} from 'sanity' +import {getPublishedId, resolveBundlePerspective} from 'sanity' import {styled} from 'styled-components' import {type GeneralPreviewLayoutKey} from '../../../../../../../components' @@ -59,7 +59,7 @@ export function SearchResultItemPreview({ schemaType, getPublishedId(documentId), '', - perspective?.startsWith('bundle.') ? perspective.split('bundle.').at(1) : undefined, + resolveBundlePerspective(perspective), ), [documentId, documentPreviewStore, perspective, schemaType], ) diff --git a/packages/sanity/src/core/studio/components/navbar/search/contexts/search/SearchProvider.tsx b/packages/sanity/src/core/studio/components/navbar/search/contexts/search/SearchProvider.tsx index 50efae294914..4905bb360fe1 100644 --- a/packages/sanity/src/core/studio/components/navbar/search/contexts/search/SearchProvider.tsx +++ b/packages/sanity/src/core/studio/components/navbar/search/contexts/search/SearchProvider.tsx @@ -8,7 +8,7 @@ import {type CommandListHandle} from '../../../../../../components' import {useSchema} from '../../../../../../hooks' import {type SearchTerms} from '../../../../../../search' import {useCurrentUser} from '../../../../../../store' -import {resolvePerspective} from '../../../../../../util/resolvePerspective' +import {resolvePerspectiveOptions} from '../../../../../../util/resolvePerspective' import {useSource} from '../../../../../source' import {SEARCH_LIMIT} from '../../constants' import {type RecentSearch} from '../../datastores/recentSearches' @@ -143,7 +143,7 @@ export function SearchProvider({children, fullscreen}: SearchProviderProps) { skipSortByScore: ordering.ignoreScore, ...(ordering.sort ? {sort: [ordering.sort]} : {}), cursor: cursor || undefined, - ...resolvePerspective(perspective, (perspectives, isSystemPerspective) => + ...resolvePerspectiveOptions(perspective, (perspectives, isSystemPerspective) => isSystemPerspective ? perspectives : perspectives.concat(DRAFTS_FOLDER), ), }, diff --git a/packages/sanity/src/core/util/__tests__/resolvePerspectives.test.ts b/packages/sanity/src/core/util/__tests__/resolvePerspectives.test.ts index 0bbbfe5a9993..812c2bf6df9b 100644 --- a/packages/sanity/src/core/util/__tests__/resolvePerspectives.test.ts +++ b/packages/sanity/src/core/util/__tests__/resolvePerspectives.test.ts @@ -1,25 +1,39 @@ import {describe, expect, it} from '@jest/globals' -import {resolvePerspective} from '../resolvePerspective' +import {resolveBundlePerspective, resolvePerspectiveOptions} from '../resolvePerspective' -describe('resolvePerspectives', () => { +describe('resolveBundlePerspective', () => { + it('returns the perspective with the `bundle.` prefix removed', () => { + expect(resolveBundlePerspective('bundle.x')).toBe('x') + }) + + it('returns `undefined` if the provided perspective has no `bundle.` prefix', () => { + expect(resolveBundlePerspective('x')).toBeUndefined() + }) + + it('returns `undefined` if no perspective is provided', () => { + expect(resolveBundlePerspective()).toBeUndefined() + }) +}) + +describe('resolvePerspectiveOptions', () => { it('includes the `bundlePerspective` property if a bundle is provided', () => { - expect(resolvePerspective('bundle.x')).toHaveProperty('bundlePerspective') - expect(resolvePerspective('bundle.x')).not.toHaveProperty('perspective') + expect(resolvePerspectiveOptions('bundle.x')).toHaveProperty('bundlePerspective') + expect(resolvePerspectiveOptions('bundle.x')).not.toHaveProperty('perspective') }) it('includes the `perspective` property if a system perspective is provided', () => { - expect(resolvePerspective('x')).toHaveProperty('perspective') - expect(resolvePerspective('x')).not.toHaveProperty('bundlePerspective') + expect(resolvePerspectiveOptions('x')).toHaveProperty('perspective') + expect(resolvePerspectiveOptions('x')).not.toHaveProperty('bundlePerspective') }) it(`removes the bundle prefix if it exists`, () => { - expect(resolvePerspective('bundle.x').bundlePerspective).toEqual('x') - expect(resolvePerspective('x').perspective).toEqual('x') + expect(resolvePerspectiveOptions('bundle.x').bundlePerspective).toEqual('x') + expect(resolvePerspectiveOptions('x').perspective).toEqual('x') }) it('allows the extracted perspectives to be transformed', () => { - expect(resolvePerspective('x', () => ['y'])).toEqual({ + expect(resolvePerspectiveOptions('x', () => ['y'])).toEqual({ perspective: 'y', }) }) @@ -27,12 +41,12 @@ describe('resolvePerspectives', () => { it('passes the perspective to the `transformPerspectives` function', () => { expect.assertions(2) - resolvePerspective('x', (perspectives) => { + resolvePerspectiveOptions('x', (perspectives) => { expect(perspectives).toEqual(['x']) return perspectives }) - resolvePerspective('bundle.x', (perspectives) => { + resolvePerspectiveOptions('bundle.x', (perspectives) => { expect(perspectives).toEqual(['x']) return perspectives }) @@ -41,19 +55,19 @@ describe('resolvePerspectives', () => { it('passes the perspective type to the `transformPerspectives` function', () => { expect.assertions(2) - resolvePerspective('x', (perspectives, isSystemPerspective) => { + resolvePerspectiveOptions('x', (perspectives, isSystemPerspective) => { expect(isSystemPerspective).toBe(true) return perspectives }) - resolvePerspective('bundle.x', (perspectives, isSystemPerspective) => { + resolvePerspectiveOptions('bundle.x', (perspectives, isSystemPerspective) => { expect(isSystemPerspective).toBe(false) return perspectives }) }) it('produces a correctly formatted list of perspectives', () => { - expect(resolvePerspective('x', (perspectives) => perspectives.concat('y'))).toEqual({ + expect(resolvePerspectiveOptions('x', (perspectives) => perspectives.concat('y'))).toEqual({ perspective: 'x,y', }) }) diff --git a/packages/sanity/src/core/util/resolvePerspective.ts b/packages/sanity/src/core/util/resolvePerspective.ts index dea5eef44175..d9587e157d83 100644 --- a/packages/sanity/src/core/util/resolvePerspective.ts +++ b/packages/sanity/src/core/util/resolvePerspective.ts @@ -1,11 +1,21 @@ +/** + * If the provided perspective has the `bundle.` prefix, return it with this + * prefix removed. + * + * @internal + */ +export function resolveBundlePerspective(perspective?: string): string | undefined { + return perspective?.split(/^bundle./).at(1) +} + /** * Given a system perspective, or a bundle name prefixed with `bundle.`, returns - * the provided `options` object with either `perspective` or `bundlePerspective` - * applied. + * an object with either `perspective` or `bundlePerspective` properties that + * may be submitted directly to Content Lake APIs. * * @internal */ -export function resolvePerspective( +export function resolvePerspectiveOptions( perspective: string | undefined, transformPerspectives: (perspectives: string[], isSystemPerspective: boolean) => string[] = ( perspectives, @@ -18,7 +28,7 @@ export function resolvePerspective( return {} } - const bundlePerspective = perspective.split(/^bundle./).at(1) + const bundlePerspective = resolveBundlePerspective(perspective) if (typeof bundlePerspective === 'string') { return { diff --git a/packages/sanity/src/structure/components/paneItem/PaneItemPreview.tsx b/packages/sanity/src/structure/components/paneItem/PaneItemPreview.tsx index ab7795b2a3cb..0a88a37db78d 100644 --- a/packages/sanity/src/structure/components/paneItem/PaneItemPreview.tsx +++ b/packages/sanity/src/structure/components/paneItem/PaneItemPreview.tsx @@ -13,6 +13,7 @@ import { getPreviewStateObservable, getPreviewValueWithFallback, isRecord, + resolveBundlePerspective, SanityDefaultPreview, } from 'sanity' import {styled} from 'styled-components' @@ -56,7 +57,7 @@ export function PaneItemPreview(props: PaneItemPreviewProps) { schemaType, value._id, title, - perspective?.startsWith('bundle.') ? perspective.split('bundle.').at(1) : undefined, + resolveBundlePerspective(perspective), ), [props.documentPreviewStore, schemaType, title, value._id, perspective], ) diff --git a/packages/sanity/src/structure/components/structureTool/StructureTitle.tsx b/packages/sanity/src/structure/components/structureTool/StructureTitle.tsx index ac93b3dc1947..2bb83344f826 100644 --- a/packages/sanity/src/structure/components/structureTool/StructureTitle.tsx +++ b/packages/sanity/src/structure/components/structureTool/StructureTitle.tsx @@ -1,6 +1,7 @@ import {type ObjectSchemaType} from '@sanity/types' import {useEffect} from 'react' import { + resolveBundlePerspective, unstable_useValuePreview as useValuePreview, useEditState, useSchema, @@ -26,11 +27,12 @@ const DocumentTitle = (props: {documentId: string; documentType: string}) => { const paneRouter = usePaneRouter() const perspective = paneRouter.perspective ?? router.stickyParams.perspective - const bundlePerspective = perspective?.startsWith('bundle.') - ? perspective.split('bundle.').at(1) - : undefined - - const editState = useEditState(documentId, documentType, 'default', bundlePerspective) + const editState = useEditState( + documentId, + documentType, + 'default', + resolveBundlePerspective(perspective), + ) const schema = useSchema() const {t} = useTranslation(structureLocaleNamespace) const isNewDocument = !editState?.published && !editState?.draft diff --git a/packages/sanity/src/structure/panes/document/DocumentPaneProvider.tsx b/packages/sanity/src/structure/panes/document/DocumentPaneProvider.tsx index c00dde3adfb9..9eaeb06a04b6 100644 --- a/packages/sanity/src/structure/panes/document/DocumentPaneProvider.tsx +++ b/packages/sanity/src/structure/panes/document/DocumentPaneProvider.tsx @@ -23,6 +23,7 @@ import { isVersionId, type OnPathFocusPayload, type PatchEvent, + resolveBundlePerspective, setAtPath, type StateTree, toMutationPatches, @@ -99,9 +100,7 @@ export const DocumentPaneProvider = memo((props: DocumentPaneProviderProps) => { const params = useUnique(paneRouter.params) || EMPTY_PARAMS const {perspective} = paneRouter - const bundlePerspective = perspective?.startsWith('bundle.') - ? perspective.split('bundle.').at(1) - : undefined + const bundlePerspective = resolveBundlePerspective(perspective) /* Version and the global perspective should match. * If user clicks on add document, and then switches to another version, he should click again on create document. diff --git a/packages/sanity/src/structure/panes/document/documentPanel/banners/ReferenceChangedBanner.tsx b/packages/sanity/src/structure/panes/document/documentPanel/banners/ReferenceChangedBanner.tsx index 07dbd1b2afbb..09d30b859630 100644 --- a/packages/sanity/src/structure/panes/document/documentPanel/banners/ReferenceChangedBanner.tsx +++ b/packages/sanity/src/structure/panes/document/documentPanel/banners/ReferenceChangedBanner.tsx @@ -9,6 +9,7 @@ import {debounceTime, map} from 'rxjs/operators' import { type DocumentAvailability, getPublishedId, + resolveBundlePerspective, useDocumentPreviewStore, useTranslation, } from 'sanity' @@ -44,9 +45,7 @@ export const ReferenceChangedBanner = memo(() => { }, [params?.parentRefPath]) const {t} = useTranslation(structureLocaleNamespace) - const bundlePerspective = perspective?.startsWith('bundle.') - ? perspective.split('bundle.').at(1) - : undefined + const bundlePerspective = resolveBundlePerspective(perspective) /** * Loads information regarding the reference field of the parent pane. This diff --git a/packages/sanity/src/structure/panes/document/inspectors/validation/index.ts b/packages/sanity/src/structure/panes/document/inspectors/validation/index.ts index 12f256456629..34e5edc51af5 100644 --- a/packages/sanity/src/structure/panes/document/inspectors/validation/index.ts +++ b/packages/sanity/src/structure/panes/document/inspectors/validation/index.ts @@ -7,6 +7,7 @@ import { type FormNodeValidation, isValidationError, isValidationWarning, + resolveBundlePerspective, useTranslation, useValidationStatus, } from 'sanity' @@ -20,14 +21,10 @@ function useMenuItem(props: DocumentInspectorUseMenuItemProps): DocumentInspecto const {t} = useTranslation('validation') const paneRouter = usePaneRouter() - const bundlePerspective = paneRouter.perspective?.startsWith('bundle.') - ? paneRouter.perspective.split('bundle.').at(1) - : undefined - const {validation: validationMarkers} = useValidationStatus( documentId, documentType, - bundlePerspective, + resolveBundlePerspective(paneRouter.perspective), ) const validation: FormNodeValidation[] = useMemo( diff --git a/packages/sanity/src/structure/panes/documentList/listenSearchQuery.ts b/packages/sanity/src/structure/panes/documentList/listenSearchQuery.ts index b7eec40db0fc..61a9791703d5 100644 --- a/packages/sanity/src/structure/panes/documentList/listenSearchQuery.ts +++ b/packages/sanity/src/structure/panes/documentList/listenSearchQuery.ts @@ -19,7 +19,7 @@ import { createSearch, DRAFTS_FOLDER, getSearchableTypes, - resolvePerspective, + resolvePerspectiveOptions, type SanityDocumentLike, type Schema, type SearchOptions, @@ -136,7 +136,7 @@ export function listenSearchQuery(options: ListenQueryOptions): Observable + ...resolvePerspectiveOptions(perspective, (perspectives, isSystemPerspective) => isSystemPerspective ? perspectives : perspectives.concat(DRAFTS_FOLDER), ), }