diff --git a/packages/@sanity/types/src/schema/definition/type/common.ts b/packages/@sanity/types/src/schema/definition/type/common.ts index 5c3c3abc2b08..50e0dd902387 100644 --- a/packages/@sanity/types/src/schema/definition/type/common.ts +++ b/packages/@sanity/types/src/schema/definition/type/common.ts @@ -26,6 +26,8 @@ export type FieldGroupDefinition = { /** * Options for configuring how Sanity Create interfaces with the type or field. + * + * @public */ export interface SanityCreateOptions { /** Set to true to exclude a type or field from appearing in Sanity Create */ diff --git a/packages/sanity/src/core/create/createUtils.ts b/packages/sanity/src/core/create/createUtils.ts index a193124e61ce..b58f5dde28b7 100644 --- a/packages/sanity/src/core/create/createUtils.ts +++ b/packages/sanity/src/core/create/createUtils.ts @@ -1,11 +1,11 @@ -import {type SanityDocumentLike} from '@sanity/types' +import {type BaseSchemaTypeOptions, type SanityDocumentLike, type SchemaType} from '@sanity/types' import {type CreateLinkedSanityDocument, type CreateLinkMetadata} from './types' /** * @internal */ -export function getCreateLinkMetadata( +export function getSanityCreateLinkMetadata( doc: SanityDocumentLike | undefined, ): CreateLinkMetadata | undefined { return (doc as CreateLinkedSanityDocument | undefined)?._create @@ -14,13 +14,20 @@ export function getCreateLinkMetadata( /** * @internal */ -export function isCreateLinked(metadata: CreateLinkMetadata | undefined): boolean { +export function isSanityCreateLinked(metadata: CreateLinkMetadata | undefined): boolean { return metadata?.ejected === false } /** * @internal */ -export function isCreateLinkedDocument(doc: SanityDocumentLike | undefined): boolean { - return isCreateLinked(getCreateLinkMetadata(doc)) +export function isSanityCreateLinkedDocument(doc: SanityDocumentLike | undefined): boolean { + return isSanityCreateLinked(getSanityCreateLinkMetadata(doc)) +} + +/** + * @internal + */ +export function isSanityCreateExcludedType(schemaType: SchemaType): boolean { + return !!(schemaType?.type?.options as BaseSchemaTypeOptions | undefined)?.sanityCreate?.exclude } diff --git a/packages/sanity/src/core/create/start-in-create/StartInCreateAction.tsx b/packages/sanity/src/core/create/start-in-create/StartInCreateAction.tsx index 2d7b24939af7..d005f02d4719 100644 --- a/packages/sanity/src/core/create/start-in-create/StartInCreateAction.tsx +++ b/packages/sanity/src/core/create/start-in-create/StartInCreateAction.tsx @@ -1,4 +1,3 @@ -import {type BaseSchemaTypeOptions} from '@sanity/types' import {useCallback, useState} from 'react' import { @@ -9,6 +8,7 @@ import { import {useSchema} from '../../hooks' import {useTranslation} from '../../i18n' import {isStartInCreateAutoConfirmed, setStartInCreateAutoConfirm} from '../createStorage' +import {isSanityCreateExcludedType} from '../createUtils' import {createLocaleNamespace} from '../i18n' import {type AppIdCache} from '../studio-app/appIdCache' import {useStudioAppIdStore} from '../studio-app/useStudioAppIdStore' @@ -42,9 +42,7 @@ export function StartInCreateAction( const {t} = useTranslation(createLocaleNamespace) const schema = useSchema() const schemaType = schema.get(type) - const isExcludedByOption = (schemaType?.type?.options as BaseSchemaTypeOptions | undefined) - ?.sanityCreate?.exclude - + const isExcludedByOption = schemaType && isSanityCreateExcludedType(schemaType) const [isDialogOpen, setDialogOpen] = useState(false) const [isLinking, setLinking] = useState(false) const [autoConfirm, setAutoConfirm] = useState(() => isStartInCreateAutoConfirmed()) diff --git a/packages/sanity/src/core/create/start-in-create/StartInCreateDialog.tsx b/packages/sanity/src/core/create/start-in-create/StartInCreateDialog.tsx index e7a382c26de9..869f58737a38 100644 --- a/packages/sanity/src/core/create/start-in-create/StartInCreateDialog.tsx +++ b/packages/sanity/src/core/create/start-in-create/StartInCreateDialog.tsx @@ -6,11 +6,12 @@ import {Button} from '../../../ui-components' import {set, toMutationPatches} from '../../form' import {useDocumentOperation} from '../../hooks' import {useTranslation} from '../../i18n' -import {useCurrentUser, useUser} from '../../store' +import {useWorkspace} from '../../studio' import {CreateLearnMoreButton} from '../components/CreateLearnMoreButton' import {createLocaleNamespace} from '../i18n' import {type CreateLinkMetadata} from '../types' -import {useCreateLinkUrl} from '../useCreateDocumentUrl' +import {getCreateLinkUrl} from '../useCreateDocumentUrl' +import {useGlobalUserId} from '../useGlobalUserId' import {StartInCreateSvg} from './StartInCreateSvg' export const CREATE_LINK_TARGET = 'create' @@ -29,20 +30,22 @@ export function StartInCreateDialog(props: StartInCreateDialogProps) { const {t} = useTranslation(createLocaleNamespace) const checkboxId = useId() const [dontShowAgain, setDontShowAgain] = useState(false) + const toggleDontShowAgain = useCallback(() => setDontShowAgain((current) => !current), []) const {patch} = useDocumentOperation(publicId, type) const {push: pushToast} = useToast() - const currentUser = useCurrentUser() - const userId = currentUser?.id ?? '' - const [user] = useUser(userId) + const globalUserId = useGlobalUserId() + const workspace = useWorkspace() - const createUrl = useCreateLinkUrl({ + const createUrl = getCreateLinkUrl({ + projectId: workspace.projectId, appId, + workspaceName: workspace.name, documentType: type, docId: createLinkId, - globalUserId: user?.sanityUserId, + globalUserId: globalUserId, }) const startLinking = useCallback(() => { diff --git a/packages/sanity/src/core/create/useCreateDocumentUrl.ts b/packages/sanity/src/core/create/useCreateDocumentUrl.ts index b693b096e9d6..c2f8e4ffcda0 100644 --- a/packages/sanity/src/core/create/useCreateDocumentUrl.ts +++ b/packages/sanity/src/core/create/useCreateDocumentUrl.ts @@ -1,5 +1,3 @@ -import {useCurrentUser, useUser, useWorkspace} from 'sanity' - import {type CreateLinkMetadata} from './types' // @ts-expect-error: __SANITY_STAGING__ is a global env variable set by the vite config @@ -11,28 +9,25 @@ function getCreateBaseUrl(customHost?: string) { return `https://${host}/app/create` } -export function useCreateLinkUrl(args: { +export function getCreateLinkUrl(args: { docId: string documentType: string appId: string + projectId: string + workspaceName: string globalUserId: string | undefined }): string | undefined { - const workspace = useWorkspace() - const currentUser = useCurrentUser() - const userId = currentUser?.id ?? '' - const [user] = useUser(userId) - const globalUserId = user?.sanityUserId + const {docId, documentType, appId, projectId, workspaceName, globalUserId} = args if (!globalUserId) { return undefined } const params = new URLSearchParams() - - params.append('projectId', workspace.projectId) - params.append('applicationId', args.appId) - params.append('workspaceName', workspace.name) - params.append('documentType', args.documentType) - params.append('documentId', args.docId) + params.append('projectId', projectId) + params.append('applicationId', appId) + params.append('workspaceName', workspaceName) + params.append('documentType', documentType) + params.append('documentId', docId) return `${getCreateBaseUrl()}/studio-import/${globalUserId}?${params.toString()}` } diff --git a/packages/sanity/src/core/create/useGlobalUserId.ts b/packages/sanity/src/core/create/useGlobalUserId.ts new file mode 100644 index 000000000000..79830b4c26ff --- /dev/null +++ b/packages/sanity/src/core/create/useGlobalUserId.ts @@ -0,0 +1,9 @@ +import {useCurrentUser, useUser} from '../store' + +export function useGlobalUserId(): string | undefined { + const currentUser = useCurrentUser() + // userStore resolves null directly for empty string + const userId = currentUser?.id ?? '' + const [user] = useUser(userId) + return user?.sanityUserId +} diff --git a/packages/sanity/src/structure/panes/document/DocumentPaneProvider.tsx b/packages/sanity/src/structure/panes/document/DocumentPaneProvider.tsx index b6c3c852da78..4aeafcf9835e 100644 --- a/packages/sanity/src/structure/panes/document/DocumentPaneProvider.tsx +++ b/packages/sanity/src/structure/panes/document/DocumentPaneProvider.tsx @@ -20,7 +20,7 @@ import { getDraftId, getExpandOperations, getPublishedId, - isCreateLinkedDocument, + isSanityCreateLinkedDocument, type OnPathFocusPayload, type PatchEvent, setAtPath, @@ -512,7 +512,7 @@ export const DocumentPaneProvider = memo((props: DocumentPaneProviderProps) => { permission: requiredPermission, }) - const isCreateLinked = isCreateLinkedDocument(value) + const isCreateLinked = isSanityCreateLinkedDocument(value) const isNonExistent = !value?._id const readOnly = useMemo(() => { diff --git a/packages/sanity/src/structure/panes/document/document-layout/DocumentLayout.tsx b/packages/sanity/src/structure/panes/document/document-layout/DocumentLayout.tsx index 5d49b17f19ee..06a6de9f49e3 100644 --- a/packages/sanity/src/structure/panes/document/document-layout/DocumentLayout.tsx +++ b/packages/sanity/src/structure/panes/document/document-layout/DocumentLayout.tsx @@ -14,9 +14,9 @@ import { type DocumentInspectorMenuItem, FieldActionsProvider, FieldActionsResolver, - getCreateLinkMetadata, GetFormValueProvider, - isCreateLinked, + getSanityCreateLinkMetadata, + isSanityCreateLinked, useGlobalCopyPasteElementHandler, useSanityCreateConfig, useZIndex, @@ -89,7 +89,7 @@ export function DocumentLayout() { const zOffsets = useZIndex() const previewUrl = usePreviewUrl(value) - const createLinkMetadata = getCreateLinkMetadata(value) + const createLinkMetadata = getSanityCreateLinkMetadata(value) const CreateLinkedBanner = useSanityCreateConfig().components?.documentLinkedBanner const [rootElement, setRootElement] = useState(null) @@ -211,7 +211,7 @@ export function DocumentLayout() { > - {createLinkMetadata && isCreateLinked(createLinkMetadata) && CreateLinkedBanner && ( + {createLinkMetadata && isSanityCreateLinked(createLinkMetadata) && CreateLinkedBanner && ( diff --git a/packages/sanity/src/structure/panes/document/statusBar/DocumentStatusBar.tsx b/packages/sanity/src/structure/panes/document/statusBar/DocumentStatusBar.tsx index 69c03ac87413..93ff2f325c99 100644 --- a/packages/sanity/src/structure/panes/document/statusBar/DocumentStatusBar.tsx +++ b/packages/sanity/src/structure/panes/document/statusBar/DocumentStatusBar.tsx @@ -2,7 +2,7 @@ import {Flex} from '@sanity/ui' import {type Ref, useCallback, useState} from 'react' import { type CreateLinkMetadata, - isCreateLinked, + isSanityCreateLinked, useSanityCreateConfig, useTimelineSelector, } from 'sanity' @@ -45,7 +45,7 @@ export function DocumentStatusBar(props: DocumentStatusBarProps) { const shouldRender = editState?.ready && typeof collapsed === 'boolean' let actions: JSX.Element | null = null - if (createLinkMetadata && isCreateLinked(createLinkMetadata) && CreateLinkedActions) { + if (createLinkMetadata && isSanityCreateLinked(createLinkMetadata) && CreateLinkedActions) { actions = (