diff --git a/packages/sanity/src/core/studio/StudioLayout.tsx b/packages/sanity/src/core/studio/StudioLayout.tsx index 25497e6ffefa..4b3855f0f7ba 100644 --- a/packages/sanity/src/core/studio/StudioLayout.tsx +++ b/packages/sanity/src/core/studio/StudioLayout.tsx @@ -84,15 +84,19 @@ export function StudioLayout() { const mainTitle = title || startCase(name) if (activeToolName) { - return `${mainTitle} – ${startCase(activeToolName)}` + return `${startCase(activeToolName)} | ${mainTitle}` } return mainTitle }, [activeToolName, name, title]) useEffect(() => { + if (activeToolName === 'content') { + // Will be handled by sanity/src/desk/components/deskTool/DeskTitle.tsx + return + } document.title = documentTitle - }, [documentTitle]) + }, [documentTitle, activeToolName]) const handleSearchFullscreenOpenChange = useCallback((open: boolean) => { setSearchFullscreenOpen(open) diff --git a/packages/sanity/src/desk/components/deskTool/DeskTitle.tsx b/packages/sanity/src/desk/components/deskTool/DeskTitle.tsx new file mode 100644 index 000000000000..7de4d008d76d --- /dev/null +++ b/packages/sanity/src/desk/components/deskTool/DeskTitle.tsx @@ -0,0 +1,80 @@ +import React, {useEffect} from 'react' +import {ObjectSchemaType} from '@sanity/types' +import {Panes} from '../../structureResolvers' +import {useDeskTool} from '../../useDeskTool' +import {LOADING_PANE} from '../../constants' +import {DocumentPaneNode} from '../../types' +import {useEditState, useSchema, unstable_useValuePreview as useValuePreview} from 'sanity' + +interface DeskTitleProps { + resolvedPanes: Panes['resolvedPanes'] +} + +const DocumentTitle = (props: {title: string; documentId: string; documentType: string}) => { + const {title, documentId, documentType} = props + const editState = useEditState(documentId, documentType) + const schema = useSchema() + const isNewDocument = !editState?.published && !editState?.draft + const documentValue = editState?.draft || editState?.published + const schemaType = schema.get(documentType) as ObjectSchemaType | undefined + + const {value, isLoading: previewValueIsLoading} = useValuePreview({ + enabled: true, + schemaType, + value: documentValue, + }) + + const documentTitle = isNewDocument + ? `New ${schemaType?.title || schemaType?.name}` + : value?.title || 'Untitled' + + const settled = editState.ready && !previewValueIsLoading + + useEffect(() => { + if (!settled) return + // Set the title as the document title + document.title = `${documentTitle} ${title}` + }, [documentTitle, title, settled]) + + return null +} + +const NoDocumentTitle = (props: {title: string}) => { + const {title} = props + useEffect(() => { + // Set the title as the document title + document.title = title + }, [title]) + return null +} + +export const DeskTitle = (props: DeskTitleProps) => { + const {resolvedPanes} = props + const deskToolTitle = useDeskTool().structureContext.title + // Will show up to the first pane of type document. + const paneWithTypeDocumentIndex = resolvedPanes.findIndex((pane) => { + return pane !== LOADING_PANE && pane.type === 'document' + }) + const paneToShow = + paneWithTypeDocumentIndex > -1 + ? resolvedPanes[paneWithTypeDocumentIndex] + : resolvedPanes[resolvedPanes.length - 1] + + const paneTitle = `${ + paneToShow === LOADING_PANE ? '' : paneToShow?.title ?? '' + } | ${deskToolTitle}` + + if (!resolvedPanes?.length) return null + if (paneWithTypeDocumentIndex === -1) return + + const documentPane = resolvedPanes[paneWithTypeDocumentIndex] as DocumentPaneNode + if (documentPane.title) return + + return ( + + ) +} diff --git a/packages/sanity/src/desk/components/deskTool/DeskTool.tsx b/packages/sanity/src/desk/components/deskTool/DeskTool.tsx index 4a92be220e67..c81db16815ed 100644 --- a/packages/sanity/src/desk/components/deskTool/DeskTool.tsx +++ b/packages/sanity/src/desk/components/deskTool/DeskTool.tsx @@ -9,6 +9,7 @@ import {PaneNode} from '../../types' import {PaneLayout} from '../pane' import {useDeskTool} from '../../useDeskTool' import {NoDocumentTypesScreen} from './NoDocumentTypesScreen' +import {DeskTitle} from './DeskTitle' import {useSchema, _isCustomDocumentTypeDefinition} from 'sanity' import {useRouterState} from 'sanity/router' @@ -130,6 +131,7 @@ export const DeskTool = memo(function DeskTool({onPaneChange}: DeskToolProps) { )} +
) diff --git a/packages/sanity/src/desk/structureResolvers/useResolvedPanes.ts b/packages/sanity/src/desk/structureResolvers/useResolvedPanes.ts index fc56b0d856c7..088c3fcb82c4 100644 --- a/packages/sanity/src/desk/structureResolvers/useResolvedPanes.ts +++ b/packages/sanity/src/desk/structureResolvers/useResolvedPanes.ts @@ -22,7 +22,7 @@ interface PaneData { siblingIndex: number } -interface Panes { +export interface Panes { paneDataItems: PaneData[] routerPanes: RouterPanes resolvedPanes: (PaneNode | typeof LOADING_PANE)[]