diff --git a/packages/sanity/src/core/canvas/actions/useCanvasCompanionDoc.ts b/packages/sanity/src/core/canvas/actions/useCanvasCompanionDoc.ts index 8e81e3ad6d2..e089cd582c9 100644 --- a/packages/sanity/src/core/canvas/actions/useCanvasCompanionDoc.ts +++ b/packages/sanity/src/core/canvas/actions/useCanvasCompanionDoc.ts @@ -22,5 +22,10 @@ export const useCanvasCompanionDoc = (documentId: string) => { () => companionDocs?.data.find((companion) => companion?.studioDocumentId === documentId), [companionDocs, documentId], ) - return {isLinked: Boolean(companionDoc), companionDoc, loading: companionDocs?.loading} + return { + isLinked: Boolean(companionDoc), + isLockedByCanvas: companionDoc ? !companionDoc.isStudioDocumentEditable : false, + companionDoc, + loading: companionDocs?.loading, + } } diff --git a/packages/sanity/src/core/canvas/store/createCanvasCompanionDocsStore.ts b/packages/sanity/src/core/canvas/store/createCanvasCompanionDocsStore.ts index b916f4db798..8f6375efa36 100644 --- a/packages/sanity/src/core/canvas/store/createCanvasCompanionDocsStore.ts +++ b/packages/sanity/src/core/canvas/store/createCanvasCompanionDocsStore.ts @@ -53,7 +53,7 @@ const getCompanionDocs = memoize( const getCompanionDoc$ = (id: string) => client.observable .fetch( - `*[_id == $id][0]{ _id, canvasDocumentId, studioDocumentId}`, + `*[_id == $id][0]{ _id, canvasDocumentId, studioDocumentId, isStudioDocumentEditable}`, {id}, {tag: 'canvas.companion-docs'}, ) diff --git a/packages/sanity/src/core/canvas/types.ts b/packages/sanity/src/core/canvas/types.ts index cb3b9cde6e9..f11cf2ad14f 100644 --- a/packages/sanity/src/core/canvas/types.ts +++ b/packages/sanity/src/core/canvas/types.ts @@ -2,6 +2,7 @@ export interface CompanionDoc { _id: string canvasDocumentId: string studioDocumentId: string + isStudioDocumentEditable?: boolean } export interface CanvasDiff { diff --git a/packages/sanity/src/core/form/useDocumentForm.ts b/packages/sanity/src/core/form/useDocumentForm.ts index 8fb4175886d..cab623e6a14 100644 --- a/packages/sanity/src/core/form/useDocumentForm.ts +++ b/packages/sanity/src/core/form/useDocumentForm.ts @@ -325,7 +325,7 @@ export function useDocumentForm(options: DocumentFormOptions): DocumentFormValue : false, [selectedPerspective], ) - const {isLinked} = useCanvasCompanionDoc(value._id) + const {isLockedByCanvas} = useCanvasCompanionDoc(value._id) // eslint-disable-next-line complexity const readOnly = useMemo(() => { @@ -374,7 +374,7 @@ export function useDocumentForm(options: DocumentFormOptions): DocumentFormValue const isReadOnly = !ready || - isLinked || + isLockedByCanvas || hasNoPermission || updateActionDisabled || createActionDisabled || @@ -389,7 +389,7 @@ export function useDocumentForm(options: DocumentFormOptions): DocumentFormValue return Boolean(readOnlyProp) }, [ isPermissionsLoading, - isLinked, + isLockedByCanvas, permissions?.granted, schemaType, isNonExistent, diff --git a/packages/sanity/src/structure/i18n/resources.ts b/packages/sanity/src/structure/i18n/resources.ts index 12f230c372a..7cdcde9ad5a 100644 --- a/packages/sanity/src/structure/i18n/resources.ts +++ b/packages/sanity/src/structure/i18n/resources.ts @@ -240,9 +240,15 @@ const structureLocaleStrings = defineLocalesResources('structure', { 'buttons.split-pane-close-button.title': 'Close split pane', /** The title for the close group button on the split pane on the document panel header */ 'buttons.split-pane-close-group-button.title': 'Close pane group', - /** The text for the canvas linked banner action button */ 'canvas.banner.edit-in-canvas-action': 'Edit in Canvas', + /** The text for the canvas linked banner when the document in editable mode*/ + 'canvas.banner.editable.linked-text': 'This document can be edited in Canvas.', + /** The description for the canvas linked banner popover in editable mode*/ + 'canvas.banner.editable.popover-description': + 'Canvas lets you write freely, then update content in Studio without manual field-by-field copying.', + /** The heading for the canvas linked banner popover in editable mode*/ + 'canvas.banner.editable.popover-heading': 'Free-form writing', /** The text for the canvas linked banner when the document is a draft */ 'canvas.banner.linked-text.draft': 'This draft document is linked to Canvas', /** The text for the canvas linked banner when the document is a live document */ diff --git a/packages/sanity/src/structure/panes/document/documentPanel/banners/CanvasLinkedBanner.tsx b/packages/sanity/src/structure/panes/document/documentPanel/banners/CanvasLinkedBanner.tsx index 32d637c5bb8..a594a921cad 100644 --- a/packages/sanity/src/structure/panes/document/documentPanel/banners/CanvasLinkedBanner.tsx +++ b/packages/sanity/src/structure/panes/document/documentPanel/banners/CanvasLinkedBanner.tsx @@ -26,11 +26,26 @@ const CANVAS_IMAGE_URL = 'https://cdn.sanity.io/images/pyrmmpch/production/b47224e2f3a7d1747e43b9da1ac31739250e628b-632x376.png' const CANVAS_APP_NAME = 'Canvas' -const CanvasPopoverContent = ({onClose}: {onClose: () => void}) => { + +const CanvasPopoverContent = ({ + onClose, + isLockedByCanvas, +}: { + onClose: () => void + isLockedByCanvas: boolean +}) => { const {t} = useTranslation(structureLocaleNamespace) const ref = useRef(null) useClickOutsideEvent(onClose, () => [ref.current]) + const popoverHeading = isLockedByCanvas + ? t('canvas.banner.popover-heading') + : t('canvas.banner.editable.popover-heading') + + const popoverDescription = isLockedByCanvas + ? t('canvas.banner.popover-description') + : t('canvas.banner.editable.popover-description') + return ( @@ -45,10 +60,10 @@ const CanvasPopoverContent = ({onClose}: {onClose: () => void}) => { - {t('canvas.banner.popover-heading')} + {popoverHeading} - {t('canvas.banner.popover-description')} + {popoverDescription} @@ -72,11 +87,23 @@ const CanvasLinkedBannerContent = ({documentId}: {documentId: string}) => { const {t} = useTranslation(structureLocaleNamespace) const [open, setOpen] = useState(false) const documentVariantType = getDocumentVariantType(documentId) + const {isLockedByCanvas} = useCanvasCompanionDoc(documentId) + const variantText = useMemo(() => { - if (documentVariantType === 'published') return t('canvas.banner.linked-text.published') - if (documentVariantType === 'draft') return t('canvas.banner.linked-text.draft') + if (!isLockedByCanvas) { + return t('canvas.banner.editable.linked-text') + } + + if (documentVariantType === 'published') { + return t('canvas.banner.linked-text.published') + } + + if (documentVariantType === 'draft') { + return t('canvas.banner.linked-text.draft') + } + return t('canvas.banner.linked-text.version') - }, [documentVariantType, t]) + }, [documentVariantType, isLockedByCanvas, t]) const togglePopover = useCallback(() => setOpen((prev) => !prev), []) const onClose = useCallback(() => setOpen(false), []) @@ -91,7 +118,7 @@ const CanvasLinkedBannerContent = ({documentId}: {documentId: string}) => { tone="default" portal placement="bottom-start" - content={} + content={} >