Skip to content

Commit

Permalink
feat(sanity): move perspective resolution to resolvePerspective fun…
Browse files Browse the repository at this point in the history
…ction
  • Loading branch information
juice49 committed Sep 13, 2024
1 parent d774601 commit 90c00e2
Show file tree
Hide file tree
Showing 14 changed files with 154 additions and 54 deletions.
8 changes: 5 additions & 3 deletions packages/sanity/src/core/bundles/util/util.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {type BundleDocument} from '../../store/bundles/types'
import {getVersionFromId, isVersionId} from '../../util'
import {getVersionFromId, isVersionId, resolveBundlePerspective} from '../../util'

/**
* @beta
Expand All @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -85,15 +85,11 @@ export const CommentsProvider = memo(function CommentsProvider(props: CommentsPr
const [status, setStatus] = useState<CommentStatus>('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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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: <em>{item.title ? String(item.title) : 'Missing document'}</em>,
subtitle: <em>{item.title ? `Missing document ID: ${item._id}` : `Document ID: ${item._id}`}</em>,
Expand Down Expand Up @@ -30,7 +32,7 @@ export const getPreviewValueWithFallback = ({
let snapshot: Partial<SanityDocument> | PreviewValue | null | undefined

switch (true) {
case perspective?.startsWith('bundle.'):
case typeof resolveBundlePerspective(perspective) !== 'undefined':
snapshot = version || draft || published
break
case perspective === 'published':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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],
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {type CommandListHandle} from '../../../../../../components'
import {useSchema} from '../../../../../../hooks'
import {type SearchTerms} from '../../../../../../search'
import {useCurrentUser} from '../../../../../../store'
import {resolvePerspectiveOptions} from '../../../../../../util/resolvePerspective'
import {useSource} from '../../../../../source'
import {SEARCH_LIMIT} from '../../constants'
import {type RecentSearch} from '../../datastores/recentSearches'
Expand Down Expand Up @@ -142,10 +143,9 @@ export function SearchProvider({children, fullscreen}: SearchProviderProps) {
skipSortByScore: ordering.ignoreScore,
...(ordering.sort ? {sort: [ordering.sort]} : {}),
cursor: cursor || undefined,
perspective: omitBundlePerspective(perspective),
bundlePerspective: perspective?.startsWith('bundle.')
? [perspective.split('bundle.').at(1), DRAFTS_FOLDER].join(',')
: undefined,
...resolvePerspectiveOptions(perspective, (perspectives, isSystemPerspective) =>
isSystemPerspective ? perspectives : perspectives.concat(DRAFTS_FOLDER),
),
},
terms: {
...terms,
Expand Down Expand Up @@ -204,11 +204,3 @@ export function SearchProvider({children, fullscreen}: SearchProviderProps) {

return <SearchContext.Provider value={value}>{children}</SearchContext.Provider>
}

function omitBundlePerspective(perspective: string | undefined): string | undefined {
if (perspective?.startsWith('bundle.')) {
return undefined
}

return perspective
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import {describe, expect, it} from '@jest/globals'

import {resolveBundlePerspective, resolvePerspectiveOptions} from '../resolvePerspective'

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(resolvePerspectiveOptions('bundle.x')).toHaveProperty('bundlePerspective')
expect(resolvePerspectiveOptions('bundle.x')).not.toHaveProperty('perspective')
})

it('includes the `perspective` property if a system perspective is provided', () => {
expect(resolvePerspectiveOptions('x')).toHaveProperty('perspective')
expect(resolvePerspectiveOptions('x')).not.toHaveProperty('bundlePerspective')
})

it(`removes the bundle prefix if it exists`, () => {
expect(resolvePerspectiveOptions('bundle.x').bundlePerspective).toEqual('x')
expect(resolvePerspectiveOptions('x').perspective).toEqual('x')
})

it('allows the extracted perspectives to be transformed', () => {
expect(resolvePerspectiveOptions('x', () => ['y'])).toEqual({
perspective: 'y',
})
})

it('passes the perspective to the `transformPerspectives` function', () => {
expect.assertions(2)

resolvePerspectiveOptions('x', (perspectives) => {
expect(perspectives).toEqual(['x'])
return perspectives
})

resolvePerspectiveOptions('bundle.x', (perspectives) => {
expect(perspectives).toEqual(['x'])
return perspectives
})
})

it('passes the perspective type to the `transformPerspectives` function', () => {
expect.assertions(2)

resolvePerspectiveOptions('x', (perspectives, isSystemPerspective) => {
expect(isSystemPerspective).toBe(true)
return perspectives
})

resolvePerspectiveOptions('bundle.x', (perspectives, isSystemPerspective) => {
expect(isSystemPerspective).toBe(false)
return perspectives
})
})

it('produces a correctly formatted list of perspectives', () => {
expect(resolvePerspectiveOptions('x', (perspectives) => perspectives.concat('y'))).toEqual({
perspective: 'x,y',
})
})
})
1 change: 1 addition & 0 deletions packages/sanity/src/core/util/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export * from './isString'
export * from './isTruthy'
export * from './PartialExcept'
export * from './resizeObserver'
export * from './resolvePerspective'
export * from './schemaUtils'
export * from './searchUtils'
export * from './supportsTouch'
Expand Down
42 changes: 42 additions & 0 deletions packages/sanity/src/core/util/resolvePerspective.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* If the provided perspective has the `bundle.` prefix, returns 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
* an object with either `perspective` or `bundlePerspective` properties that
* may be submitted directly to Content Lake APIs.
*
* @internal
*/
export function resolvePerspectiveOptions(
perspective: string | undefined,
transformPerspectives: (perspectives: string[], isSystemPerspective: boolean) => string[] = (
perspectives,
) => perspectives,
):
| {perspective: string; bundlePerspective?: never}
| {perspective?: never; bundlePerspective: string}
| Record<PropertyKey, never> {
if (typeof perspective === 'undefined') {
return {}
}

const bundlePerspective = resolveBundlePerspective(perspective)

if (typeof bundlePerspective === 'string') {
return {
bundlePerspective: transformPerspectives([bundlePerspective], false).join(','),
}
}

return {
perspective: transformPerspectives([perspective], true).join(','),
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
getPreviewStateObservable,
getPreviewValueWithFallback,
isRecord,
resolveBundlePerspective,
SanityDefaultPreview,
} from 'sanity'
import {styled} from 'styled-components'
Expand Down Expand Up @@ -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],
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {type ObjectSchemaType} from '@sanity/types'
import {useEffect} from 'react'
import {
resolveBundlePerspective,
unstable_useValuePreview as useValuePreview,
useEditState,
useSchema,
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
isVersionId,
type OnPathFocusPayload,
type PatchEvent,
resolveBundlePerspective,
setAtPath,
type StateTree,
toMutationPatches,
Expand Down Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {debounceTime, map} from 'rxjs/operators'
import {
type DocumentAvailability,
getPublishedId,
resolveBundlePerspective,
useDocumentPreviewStore,
useTranslation,
} from 'sanity'
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
type FormNodeValidation,
isValidationError,
isValidationWarning,
resolveBundlePerspective,
useTranslation,
useValidationStatus,
} from 'sanity'
Expand All @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ import {
createSearch,
DRAFTS_FOLDER,
getSearchableTypes,
resolvePerspectiveOptions,
type SanityDocumentLike,
type Schema,
type SearchOptions,
} from 'sanity'

import {getExtendedProjection} from '../../structureBuilder/util/getExtendedProjection'
Expand Down Expand Up @@ -128,16 +130,15 @@ export function listenSearchQuery(options: ListenQueryOptions): Observable<Sanit
types,
}

const searchOptions = {
const searchOptions: SearchOptions = {
__unstable_extendedProjection: extendedProjection,
comments: [`findability-source: ${searchQuery ? 'list-query' : 'list'}`],
limit,
perspective: omitBundlePerspective(perspective),
bundlePerspective: perspective?.startsWith('bundle.')
? [perspective.split('bundle.').at(1), DRAFTS_FOLDER].join(',')
: undefined,
skipSortByScore: true,
sort: sortBy,
...resolvePerspectiveOptions(perspective, (perspectives, isSystemPerspective) =>
isSystemPerspective ? perspectives : perspectives.concat(DRAFTS_FOLDER),
),
}

return search(searchTerms, searchOptions).pipe(
Expand All @@ -160,11 +161,3 @@ export function listenSearchQuery(options: ListenQueryOptions): Observable<Sanit
}),
)
}

function omitBundlePerspective(perspective: string | undefined): string | undefined {
if (perspective?.startsWith('bundle.')) {
return undefined
}

return perspective
}

0 comments on commit 90c00e2

Please sign in to comment.