From c289c35b510ef715e8de1c9d42081539a002a372 Mon Sep 17 00:00:00 2001 From: RitaDias Date: Wed, 18 Sep 2024 13:48:55 +0200 Subject: [PATCH 01/11] !TEMP(dev): add liveEdit to simple block --- dev/test-studio/schema/standard/portableText/simpleBlock.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/dev/test-studio/schema/standard/portableText/simpleBlock.tsx b/dev/test-studio/schema/standard/portableText/simpleBlock.tsx index 004854a671a..dc9dd52e3e0 100644 --- a/dev/test-studio/schema/standard/portableText/simpleBlock.tsx +++ b/dev/test-studio/schema/standard/portableText/simpleBlock.tsx @@ -31,6 +31,7 @@ const myStringType = defineArrayMember({ }) export default defineType({ + liveEdit: true, name: 'simpleBlock', title: 'Simple block', type: 'document', From 3030ff060e2a1e2a821374bbb8f8637e6b754948 Mon Sep 17 00:00:00 2001 From: RitaDias Date: Wed, 18 Sep 2024 13:49:17 +0200 Subject: [PATCH 02/11] refactor(sanity): make livedit drafts readOnly --- .../panes/document/DocumentPaneProvider.tsx | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/packages/sanity/src/structure/panes/document/DocumentPaneProvider.tsx b/packages/sanity/src/structure/panes/document/DocumentPaneProvider.tsx index f15f16fffcf..9c527a0ee6f 100644 --- a/packages/sanity/src/structure/panes/document/DocumentPaneProvider.tsx +++ b/packages/sanity/src/structure/panes/document/DocumentPaneProvider.tsx @@ -517,6 +517,9 @@ export const DocumentPaneProvider = memo((props: DocumentPaneProviderProps) => { const createActionDisabled = isNonExistent && !isActionEnabled(schemaType!, 'create') const reconnecting = connectionState === 'reconnecting' const isLocked = editState.transactionSyncLock?.enabled + // in cases where the document has drafts but the schema is live edit, + // there is a risk of data loss, so we disable editing in this case + const isLiveEditAndDraft = Boolean(liveEdit && editState.draft) return ( !ready || @@ -527,19 +530,22 @@ export const DocumentPaneProvider = memo((props: DocumentPaneProviderProps) => { reconnecting || isLocked || isDeleting || - isDeleted + isDeleted || + isLiveEditAndDraft ) }, [ - connectionState, - editState.transactionSyncLock, - isNonExistent, - isDeleted, - isDeleting, isPermissionsLoading, permissions?.granted, + schemaType, + isNonExistent, + connectionState, + editState.transactionSyncLock?.enabled, + editState.draft, + liveEdit, ready, revTime, - schemaType, + isDeleting, + isDeleted, ]) const formState = useFormState({ From 620294f5445c9a5518545a45e1c1af837f077c1a Mon Sep 17 00:00:00 2001 From: RitaDias Date: Wed, 18 Sep 2024 14:31:20 +0200 Subject: [PATCH 03/11] refactor(sanity): add banner explaining what needs to be done to get the live edit to work --- .../sanity/src/structure/i18n/resources.ts | 6 ++++ .../document/documentPanel/DocumentPanel.tsx | 6 ++++ .../banners/DraftLiveEditBanner.tsx | 33 +++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 packages/sanity/src/structure/panes/document/documentPanel/banners/DraftLiveEditBanner.tsx diff --git a/packages/sanity/src/structure/i18n/resources.ts b/packages/sanity/src/structure/i18n/resources.ts index 800fda3727d..a8b0f3b520c 100644 --- a/packages/sanity/src/structure/i18n/resources.ts +++ b/packages/sanity/src/structure/i18n/resources.ts @@ -95,6 +95,12 @@ const structureLocaleStrings = defineLocalesResources('structure', { 'banners.deleted-document-banner.text': 'This document has been deleted.', /** The text content for the deprecated document type banner */ 'banners.deprecated-document-type-banner.text': 'This document type has been deprecated.', + /** The text content for the live edit document when it's a draft on how to solve it */ + 'banners.live-edit-draft-banner.explanation': + 'Disable "live edit" in the schema to publish the draft. Once published, "live edit" can be reactivated.', + /** The text content for the live edit document when it's a draft */ + 'banners.live-edit-draft-banner.text': + 'This "live" document cannot be edited while a draft version of it exists.', /** The text for the permission check banner if the user only has one role, and it does not allow updating this document */ 'banners.permission-check-banner.missing-permission_create_one': 'Your role does not have permissions to create this document.', diff --git a/packages/sanity/src/structure/panes/document/documentPanel/DocumentPanel.tsx b/packages/sanity/src/structure/panes/document/documentPanel/DocumentPanel.tsx index ebc889cf801..dc88a2ded8f 100644 --- a/packages/sanity/src/structure/panes/document/documentPanel/DocumentPanel.tsx +++ b/packages/sanity/src/structure/panes/document/documentPanel/DocumentPanel.tsx @@ -4,6 +4,7 @@ import {ScrollContainer, useTimelineSelector, VirtualizerScrollInstanceProvider} import {css, styled} from 'styled-components' import {PaneContent, usePane, usePaneLayout} from '../../../components' +import {isLiveEditEnabled} from '../../../components/paneItem/helpers' import {useStructureTool} from '../../../useStructureTool' import {DocumentInspectorPanel} from '../documentInspector' import {InspectDialog} from '../inspectDialog' @@ -14,6 +15,7 @@ import { PermissionCheckBanner, ReferenceChangedBanner, } from './banners' +import {DraftLiveEditBanner} from './banners/DraftLiveEditBanner' import {FormView} from './documentViews' interface DocumentPanelProps { @@ -117,6 +119,8 @@ export const DocumentPanel = function DocumentPanel(props: DocumentPanelProps) { (state) => state.lastNonDeletedRevId, ) + const isLiveEdit = isLiveEditEnabled(schemaType) + // Scroll to top as `documentId` changes useEffect(() => { if (!documentScrollElement?.scrollTo) return @@ -150,6 +154,8 @@ export const DocumentPanel = function DocumentPanel(props: DocumentPanelProps) { scrollElement={documentScrollElement} containerElement={formContainerElement} > + {activeView.type === 'form' && isLiveEdit && ready && } + {activeView.type === 'form' && !isPermissionsLoading && ready && ( <> + + {t('banners.live-edit-draft-banner.text')} + + + {t('banners.live-edit-draft-banner.explanation')} + + + } + data-testid="live-edit-type-banner" + icon={ErrorOutlineIcon} + /> + ) +} From 46ab3ac976e96c289553346a021900a1dfb98e9c Mon Sep 17 00:00:00 2001 From: RitaDias Date: Thu, 19 Sep 2024 09:57:36 +0200 Subject: [PATCH 04/11] refactor(sanity): add publish button to banner --- .../sanity/src/structure/i18n/resources.ts | 7 ++-- .../banners/DraftLiveEditBanner.tsx | 37 +++++++++++++------ 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/packages/sanity/src/structure/i18n/resources.ts b/packages/sanity/src/structure/i18n/resources.ts index a8b0f3b520c..2c190bf26d9 100644 --- a/packages/sanity/src/structure/i18n/resources.ts +++ b/packages/sanity/src/structure/i18n/resources.ts @@ -95,12 +95,11 @@ const structureLocaleStrings = defineLocalesResources('structure', { 'banners.deleted-document-banner.text': 'This document has been deleted.', /** The text content for the deprecated document type banner */ 'banners.deprecated-document-type-banner.text': 'This document type has been deprecated.', - /** The text content for the live edit document when it's a draft on how to solve it */ - 'banners.live-edit-draft-banner.explanation': - 'Disable "live edit" in the schema to publish the draft. Once published, "live edit" can be reactivated.', /** The text content for the live edit document when it's a draft */ 'banners.live-edit-draft-banner.text': - 'This "live" document cannot be edited while a draft version of it exists.', + 'This live document cannot be edited while a draft version of it exists. Publish the draft in order to continue live editing it.', + /** The text for publish action for the draft banner */ + 'banners.live-edit-draft-banner.tooltip': 'Publish to continue editing', /** The text for the permission check banner if the user only has one role, and it does not allow updating this document */ 'banners.permission-check-banner.missing-permission_create_one': 'Your role does not have permissions to create this document.', diff --git a/packages/sanity/src/structure/panes/document/documentPanel/banners/DraftLiveEditBanner.tsx b/packages/sanity/src/structure/panes/document/documentPanel/banners/DraftLiveEditBanner.tsx index 0a36c024a1d..875cbf03385 100644 --- a/packages/sanity/src/structure/panes/document/documentPanel/banners/DraftLiveEditBanner.tsx +++ b/packages/sanity/src/structure/panes/document/documentPanel/banners/DraftLiveEditBanner.tsx @@ -1,14 +1,24 @@ import {ErrorOutlineIcon} from '@sanity/icons' -import {Stack, Text} from '@sanity/ui' -import {isDraftId, useTranslation} from 'sanity' +import {Flex, Stack, Text} from '@sanity/ui' +import {useCallback, useState} from 'react' +import {isDraftId, useDocumentOperation, useTranslation} from 'sanity' +import {Button} from '../../../../../ui-components' import {structureLocaleNamespace} from '../../../../i18n' import {useDocumentPane} from '../../useDocumentPane' import {Banner} from './Banner' export function DraftLiveEditBanner(): JSX.Element | null { - const {displayed} = useDocumentPane() + const {displayed, documentId} = useDocumentPane() const {t} = useTranslation(structureLocaleNamespace) + const [isPublishing, setPublishing] = useState(false) + + const {publish} = useDocumentOperation(documentId, displayed?._type || '') + + const handlePublish = useCallback(() => { + publish.execute() + setPublishing(true) + }, [publish]) if (displayed && displayed._id && !isDraftId(displayed._id)) { return null @@ -17,14 +27,19 @@ export function DraftLiveEditBanner(): JSX.Element | null { return ( - - {t('banners.live-edit-draft-banner.text')} - - - {t('banners.live-edit-draft-banner.explanation')} - - + + + + {t('banners.live-edit-draft-banner.text')} + + +