diff --git a/examples/getstarted/src/admin/preview/dummy-preview.jsx b/examples/getstarted/src/admin/preview/dummy-preview.jsx index cb12a2b45b..77eed27b75 100644 --- a/examples/getstarted/src/admin/preview/dummy-preview.jsx +++ b/examples/getstarted/src/admin/preview/dummy-preview.jsx @@ -1,4 +1,4 @@ -import React from 'react'; +import * as React from 'react'; import { useParams } from 'react-router-dom'; // @ts-ignore @@ -8,13 +8,27 @@ import { Grid, Flex, Typography, JSONInput } from '@strapi/design-system'; const PreviewComponent = () => { const { uid: model, documentId, locale, status, collectionType } = useParams(); - const { document } = useDocument({ + const { document, refetch } = useDocument({ model, documentId, params: { locale, status }, collectionType, }); + React.useEffect(() => { + const handleStrapiUpdate = (event) => { + if (event.data?.type === 'strapiUpdate') { + refetch(); + } + }; + + window.addEventListener('message', handleStrapiUpdate); + + return () => { + window.removeEventListener('message', handleStrapiUpdate); + }; + }, []); + return ( diff --git a/packages/core/content-manager/admin/src/content-manager.ts b/packages/core/content-manager/admin/src/content-manager.ts index d061ac08f7..002d658211 100644 --- a/packages/core/content-manager/admin/src/content-manager.ts +++ b/packages/core/content-manager/admin/src/content-manager.ts @@ -80,7 +80,9 @@ interface PanelComponent extends DescriptionComponent void; +} interface DocumentActionComponent extends DescriptionComponent { diff --git a/packages/core/content-manager/admin/src/hooks/useDocument.ts b/packages/core/content-manager/admin/src/hooks/useDocument.ts index 4ad8f2c5bf..41ef2541d5 100644 --- a/packages/core/content-manager/admin/src/hooks/useDocument.ts +++ b/packages/core/content-manager/admin/src/hooks/useDocument.ts @@ -63,6 +63,7 @@ type UseDocument = ( schema?: Schema; schemas?: Schema[]; hasError?: boolean; + refetch: () => void; validate: (document: Document) => null | FormErrors; /** * Get the document's title @@ -115,6 +116,7 @@ const useDocument: UseDocument = (args, opts) => { isLoading: isLoadingDocument, isFetching: isFetchingDocument, error, + refetch, } = useGetDocumentQuery(args, { ...opts, skip: (!args.documentId && args.collectionType !== SINGLE_TYPES) || opts?.skip, @@ -227,6 +229,7 @@ const useDocument: UseDocument = (args, opts) => { validate, getTitle, getInitialFormValues, + refetch, } satisfies ReturnType; }; diff --git a/packages/core/content-manager/admin/src/pages/EditView/components/DocumentActions.tsx b/packages/core/content-manager/admin/src/pages/EditView/components/DocumentActions.tsx index 3c6d2d3f15..4b35e7b818 100644 --- a/packages/core/content-manager/admin/src/pages/EditView/components/DocumentActions.tsx +++ b/packages/core/content-manager/admin/src/pages/EditView/components/DocumentActions.tsx @@ -516,6 +516,7 @@ const PublishAction: DocumentActionComponent = ({ collectionType, meta, document, + onPreview, }) => { const { schema } = useDoc(); const navigate = useNavigate(); @@ -678,6 +679,10 @@ const PublishAction: DocumentActionComponent = ({ } } finally { setSubmitting(false); + + if (onPreview) { + onPreview(); + } } }; @@ -755,6 +760,7 @@ const UpdateAction: DocumentActionComponent = ({ documentId, model, collectionType, + onPreview, }) => { const navigate = useNavigate(); const { toggleNotification } = useNotification(); @@ -867,6 +873,9 @@ const UpdateAction: DocumentActionComponent = ({ } } finally { setSubmitting(false); + if (onPreview) { + onPreview(); + } } }, [ clone, diff --git a/packages/core/content-manager/admin/src/preview/components/PreviewContent.tsx b/packages/core/content-manager/admin/src/preview/components/PreviewContent.tsx index b608a15a5f..5425505d53 100644 --- a/packages/core/content-manager/admin/src/preview/components/PreviewContent.tsx +++ b/packages/core/content-manager/admin/src/preview/components/PreviewContent.tsx @@ -1,89 +1,8 @@ -import * as React from 'react'; - -import { Box, Flex, IconButton } from '@strapi/design-system'; -import { ArrowLeft } from '@strapi/icons'; +import { Box } from '@strapi/design-system'; import { useIntl } from 'react-intl'; -import { styled } from 'styled-components'; -import { FormLayout } from '../../pages/EditView/components/FormLayout'; import { usePreviewContext } from '../pages/Preview'; -// TODO use ArrowLineLeft once it's available in the DS -const AnimatedArrow = styled(ArrowLeft)<{ isSideEditorOpen: boolean }>` - will-change: transform; - rotate: ${(props) => (props.isSideEditorOpen ? '0deg' : '180deg')}; - transition: rotate 0.2s ease-in-out; -`; - -const UnstablePreviewContent = () => { - const previewUrl = usePreviewContext('PreviewContent', (state) => state.url); - const layout = usePreviewContext('PreviewContent', (state) => state.layout); - - const { formatMessage } = useIntl(); - - const [isSideEditorOpen, setIsSideEditorOpen] = React.useState(true); - - return ( - - - - - - - setIsSideEditorOpen((prev) => !prev)} - position="absolute" - top={2} - left={2} - > - - - - - ); -}; - const PreviewContent = () => { const previewUrl = usePreviewContext('PreviewContent', (state) => state.url); @@ -112,4 +31,4 @@ const PreviewContent = () => { ); }; -export { PreviewContent, UnstablePreviewContent }; +export { PreviewContent }; diff --git a/packages/core/content-manager/admin/src/preview/components/PreviewHeader.tsx b/packages/core/content-manager/admin/src/preview/components/PreviewHeader.tsx index dc0f2d501e..f5a93534e4 100644 --- a/packages/core/content-manager/admin/src/preview/components/PreviewHeader.tsx +++ b/packages/core/content-manager/admin/src/preview/components/PreviewHeader.tsx @@ -156,6 +156,7 @@ const UnstablePreviewHeader = () => { const schema = usePreviewContext('PreviewHeader', (state) => state.schema); const meta = usePreviewContext('PreviewHeader', (state) => state.meta); const plugins = useStrapiApp('PreviewHeader', (state) => state.plugins); + const iframeRef = usePreviewContext('PreviewHeader', (state) => state.iframeRef); const [{ query }] = useQueryParams<{ status?: 'draft' | 'published'; @@ -176,13 +177,16 @@ const UnstablePreviewHeader = () => { }; const hasDraftAndPublish = schema.options?.draftAndPublish ?? false; - const props = { + const documentActionProps = { activeTab: query.status ?? null, collectionType: schema.kind === 'collectionType' ? 'collection-types' : 'single-types', model: schema.uid, documentId: document.documentId, document, meta, + onPreview: () => { + iframeRef?.current?.contentWindow?.postMessage({ type: 'strapiUpdate' }); + }, } satisfies DocumentActionProps; return ( @@ -227,7 +231,7 @@ const UnstablePreviewHeader = () => { ['meta']>; schema: NonNullable['schema']>; layout: EditLayout; + iframeRef?: React.RefObject; } const [PreviewProvider, usePreviewContext] = createContext('PreviewPage'); @@ -43,10 +47,19 @@ const [PreviewProvider, usePreviewContext] = createContext( * PreviewPage * -----------------------------------------------------------------------------------------------*/ +const AnimatedArrow = styled(ArrowLeft)<{ isSideEditorOpen: boolean }>` + will-change: transform; + rotate: ${(props) => (props.isSideEditorOpen ? '0deg' : '180deg')}; + transition: rotate 0.2s ease-in-out; +`; + const PreviewPage = () => { const location = useLocation(); const { formatMessage } = useIntl(); + const iframeRef = React.useRef(null); + const [isSideEditorOpen, setIsSideEditorOpen] = React.useState(true); + // Read all the necessary data from the URL to find the right preview URL const { slug: model, @@ -133,6 +146,8 @@ const PreviewPage = () => { return yupSchema.validateSync(values, { abortEarly: false }); }; + const previewUrl = previewUrlResponse.data.data.url; + return ( <> @@ -147,12 +162,13 @@ const PreviewPage = () => { )} { {window.strapi.future.isEnabled('unstablePreviewSideEditor') ? ( <> - + + + + + + + setIsSideEditorOpen((prev) => !prev)} + position="absolute" + top={2} + left={2} + > + + + + ) : ( <>