Skip to content

Commit

Permalink
feat(sanity): export useReferringDocuments and mark as beta
Browse files Browse the repository at this point in the history
  • Loading branch information
bjoerge committed Dec 17, 2024
1 parent 1fa5db6 commit a62ffd9
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import {type ReactElement} from 'react'
import {useReferringDocuments} from '../hooks/useReferringDocuments'
import {type DocumentStore} from '../store'

const EMPTY: never[] = []

/**
* @internal
* @deprecated - Will be removed in 4.0.0, use the `useReferringDocuments(<documentId>)` hook instead
Expand All @@ -19,5 +21,5 @@ export function WithReferringDocuments({
documentStore?: DocumentStore
id: string
}) {
return children(useReferringDocuments(id))
return children(useReferringDocuments(id, EMPTY))
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {useMemo} from 'react'

import {Dialog} from '../../../../../ui-components'
import {LoadingBlock} from '../../../../components/loadingBlock'
import {useReferringDocuments} from '../../../../hooks/useReferringDocuments'
import {useLegacyReferringDocuments} from '../../../../hooks/useReferringDocuments'
import {useTranslation} from '../../../../i18n'
import {AssetUsageList} from './AssetUsageList'
import {ConfirmMessage} from './ConfirmMessage'
Expand All @@ -25,7 +25,7 @@ export function AssetDeleteDialog({
onClose,
onDelete,
}: UsageDialogProps) {
const {isLoading, referringDocuments} = useReferringDocuments(asset._id)
const {isLoading, referringDocuments} = useLegacyReferringDocuments(asset._id)

const publishedDocuments = useMemo(() => {
const drafts = referringDocuments.reduce<string[]>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {useMemo} from 'react'

import {Dialog} from '../../../../../ui-components'
import {LoadingBlock} from '../../../../components/loadingBlock'
import {useReferringDocuments} from '../../../../hooks/useReferringDocuments'
import {useLegacyReferringDocuments} from '../../../../hooks/useReferringDocuments'
import {useTranslation} from '../../../../i18n'
import {AssetUsageList} from './AssetUsageList'

Expand All @@ -14,7 +14,7 @@ export interface UsageDialogProps {
}

export function AssetUsageDialog({asset, assetType, onClose}: UsageDialogProps) {
const {isLoading, referringDocuments} = useReferringDocuments(asset._id)
const {isLoading, referringDocuments} = useLegacyReferringDocuments(asset._id)

const publishedDocuments = useMemo(() => {
const drafts = referringDocuments.reduce<string[]>(
Expand Down
1 change: 1 addition & 0 deletions packages/sanity/src/core/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export * from './useGlobalCopyPasteElementHandler'
export * from './useListFormat'
export * from './useNumberFormat'
export * from './useProjectId'
export {type DocumentField, useReferringDocuments} from './useReferringDocuments'
export * from './useRelativeTime'
export * from './useSchema'
export * from './useSyncState'
Expand Down
56 changes: 47 additions & 9 deletions packages/sanity/src/core/hooks/useReferringDocuments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,75 @@ import {map, startWith} from 'rxjs/operators'

import {useDocumentStore} from '../store'

interface ReferringDocumentsState {
interface ReferringDocumentsState<Doc> {
isLoading: boolean
referringDocuments: SanityDocument[]
referringDocuments: Doc[]
}
/** @beta */
export type DocumentField = Exclude<keyof SanityDocument, number>

const INITIAL_STATE: ReferringDocumentsState = {referringDocuments: [], isLoading: true}
const INITIAL_STATE: ReferringDocumentsState<never> = {referringDocuments: [], isLoading: true}
const DEFAULT_FIELDS: DocumentField[] = ['_id', '_type']

/**
* @internal
* @param id - the id to search for referring documents for
* @beta
* Subscribe to a live-updating list document referring to the document of the passed ID
* A new list of document will be emitted every time a document refers or no longer refers to the document of the given ID
*
* ## Gotcha
* The returned list of referring documents is not extensive, will only return the 101 first documents.
*
* ## Gotcha
* For every component that calls this hook, a new listener connection will be made to the backed.
*
* Make sure call this hook sparingly
* @param id - id of document to search for referring documents for
* @param fields - which fields to return for each document (defaults to _id and _type). Pass an empty array to return full documents
*/
export function useReferringDocuments(id: string): ReferringDocumentsState {
export function useReferringDocuments<DocumentType extends SanityDocument>(
id: string,
fields: DocumentField[] = DEFAULT_FIELDS,
) {
const documentStore = useDocumentStore()

const projection = useMemo(() => {
return fields.length === 0 ? '' : fields.join(',')
}, [fields])

const observable = useMemo(
() =>
documentStore
.listenQuery(
'*[references($docId)] [0...101]',
`*[references($docId)] [0...101]${projection}`,
{docId: id},
{tag: 'use-referring-documents'},
)
.pipe(
map(
(docs: SanityDocument[]): ReferringDocumentsState => ({
(docs: DocumentType[]): ReferringDocumentsState<DocumentType> => ({
referringDocuments: docs,
isLoading: false,
}),
),
startWith(INITIAL_STATE),
),
[documentStore, id],
[documentStore, id, projection],
)
return useObservable(observable, INITIAL_STATE)
}

const EMPTY_FIELDS: never[] = []
/**
* Kept for backwards compat
* - useReferringDocuments(id) will select `{_id, _type}` from returned documents,
* - while this hook will return full documents
*
* Internal callers of this hook should migrate over to useReferringDocuments
* @deprecated - replaced by useReferringDocuments(id) but kept for backwards compatibility
* @internal
* @param id - id of document to search for referring documents for
*/
// eslint-disable-next-line camelcase
export function useLegacyReferringDocuments(id: string): ReferringDocumentsState<SanityDocument> {
return useReferringDocuments(id, EMPTY_FIELDS)
}
1 change: 0 additions & 1 deletion packages/sanity/src/structure/useStructureTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {type StructureToolContextValue} from './types'
/** @internal */
export function useStructureTool(): StructureToolContextValue {
const structureTool = useContext(StructureToolContext)

if (!structureTool) throw new Error(`StructureTool: missing context value`)

return structureTool
Expand Down

0 comments on commit a62ffd9

Please sign in to comment.