UNPKG

strapi-plugin-preview-button

Version:

A plugin for Strapi CMS that adds a preview button and live view button to the content manager edit view.

253 lines (252 loc) 9.45 kB
import { jsx, jsxs, Fragment } from "react/jsx-runtime"; import * as React from "react"; import { g as useQueryParams, k as useNotification, i as useDoc, r as useDocumentRBAC, e as useDocumentLayout, b as Page, F as Form, A as createYupSchema, H as Header, B as getTranslation, E as Panels, G as Blocker, u as useRBAC, D as DocumentRBAC, S as SINGLE_TYPES, P as PERMISSIONS } from "./index-DX9HaYlZ.mjs"; import { Main, Tabs, Grid, Flex, Box } from "@strapi/design-system"; import { useIntl } from "react-intl"; import { useLocation, useParams } from "react-router-dom"; import { styled } from "styled-components"; import { a as useLazyComponents, f as createDefaultForm, t as transformDocument, g as MemoizedInputRenderer } from "./Field-hD0Y00Mt-8YPhpk8A.mjs"; const useOnce = (effect) => React.useEffect(effect, emptyDeps); const emptyDeps = []; const FormLayout = ({ layout }) => { const { formatMessage } = useIntl(); const { model } = useDoc(); return /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: layout.map((panel, index) => { if (panel.some((row) => row.some((field) => field.type === "dynamiczone"))) { const [row] = panel; const [field] = row; const fieldWithTranslatedLabel = { ...field, label: formatMessage({ id: `content-manager.content-types.${model}.${field.name}`, defaultMessage: field.label }) }; return /* @__PURE__ */ jsx(Grid.Root, { gap: 4, children: /* @__PURE__ */ jsx(Grid.Item, { col: 12, s: 12, xs: 12, direction: "column", alignItems: "stretch", children: /* @__PURE__ */ jsx(MemoizedInputRenderer, { ...fieldWithTranslatedLabel }) }) }, field.name); } return /* @__PURE__ */ jsx( Box, { hasRadius: true, background: "neutral0", shadow: "tableShadow", paddingLeft: 6, paddingRight: 6, paddingTop: 6, paddingBottom: 6, borderColor: "neutral150", children: /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: panel.map((row, gridRowIndex) => /* @__PURE__ */ jsx(Grid.Root, { gap: 4, children: row.map(({ size, ...field }) => { const fieldWithTranslatedLabel = { ...field, label: formatMessage({ id: `content-manager.content-types.${model}.${field.name}`, defaultMessage: field.label }) }; return /* @__PURE__ */ jsx( Grid.Item, { col: size, s: 12, xs: 12, direction: "column", alignItems: "stretch", children: /* @__PURE__ */ jsx(MemoizedInputRenderer, { ...fieldWithTranslatedLabel }) }, field.name ); }) }, gridRowIndex)) }) }, index ); }) }); }; const EditViewPage = () => { const location = useLocation(); const [ { query: { status } }, setQuery ] = useQueryParams({ status: "draft" }); const { formatMessage } = useIntl(); const { toggleNotification } = useNotification(); const { document, meta, isLoading: isLoadingDocument, schema, components, collectionType, id, model, hasError } = useDoc(); const hasDraftAndPublished = schema?.options?.draftAndPublish ?? false; useOnce(() => { if (location?.state && "error" in location.state) { toggleNotification({ type: "danger", message: location.state.error, timeout: 5e3 }); } }); const isLoadingActionsRBAC = useDocumentRBAC("EditViewPage", (state) => state.isLoading); const isSingleType = collectionType === SINGLE_TYPES; const isCreatingDocument = !id && !isSingleType; const { isLoading: isLoadingLayout, edit: { layout, settings: { mainField } } } = useDocumentLayout(model); const { isLazyLoading } = useLazyComponents([]); const isLoading = isLoadingActionsRBAC || isLoadingDocument || isLoadingLayout || isLazyLoading; const initialValues = React.useMemo(() => { if (!document && !isCreatingDocument && !isSingleType || !schema) { return void 0; } const form = document?.id ? document : createDefaultForm(schema, components); return transformDocument(schema, components)(form); }, [document, isCreatingDocument, isSingleType, schema, components]); if (hasError) { return /* @__PURE__ */ jsx(Page.Error, {}); } if (isLoading && !document?.documentId) { return /* @__PURE__ */ jsx(Page.Loading, {}); } if (!initialValues) { return /* @__PURE__ */ jsx(Page.Error, {}); } const handleTabChange = (status2) => { if (status2 === "published" || status2 === "draft") { setQuery({ status: status2 }, "push", true); } }; let documentTitle = "Untitled"; if (mainField !== "id" && document?.[mainField]) { documentTitle = document[mainField]; } else if (isSingleType && schema?.info.displayName) { documentTitle = schema.info.displayName; } const validateSync = (values, options) => { const yupSchema = createYupSchema(schema?.attributes, components, { status, ...options }); return yupSchema.validateSync(values, { abortEarly: false }); }; return /* @__PURE__ */ jsxs(Main, { paddingLeft: 10, paddingRight: 10, children: [ /* @__PURE__ */ jsx(Page.Title, { children: documentTitle }), /* @__PURE__ */ jsx( Form, { disabled: hasDraftAndPublished && status === "published", initialValues, method: isCreatingDocument ? "POST" : "PUT", validate: (values, options) => { const yupSchema = createYupSchema(schema?.attributes, components, { status, ...options }); return yupSchema.validate(values, { abortEarly: false }); }, initialErrors: location?.state?.forceValidation ? validateSync(initialValues, {}) : {}, children: ({ resetForm }) => /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx( Header, { isCreating: isCreatingDocument, status: hasDraftAndPublished ? getDocumentStatus(document, meta) : void 0, title: documentTitle } ), /* @__PURE__ */ jsxs(Tabs.Root, { variant: "simple", value: status, onValueChange: handleTabChange, children: [ /* @__PURE__ */ jsx( Tabs.List, { "aria-label": formatMessage({ id: getTranslation("containers.edit.tabs.label"), defaultMessage: "Document status" }), children: hasDraftAndPublished ? /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx(StatusTab, { value: "draft", children: formatMessage({ id: getTranslation("containers.edit.tabs.draft"), defaultMessage: "draft" }) }), /* @__PURE__ */ jsx( StatusTab, { disabled: !meta || meta.availableStatus.length === 0, value: "published", children: formatMessage({ id: getTranslation("containers.edit.tabs.published"), defaultMessage: "published" }) } ) ] }) : null } ), /* @__PURE__ */ jsxs(Grid.Root, { paddingTop: 8, gap: 4, children: [ /* @__PURE__ */ jsxs(Grid.Item, { col: 9, s: 12, direction: "column", alignItems: "stretch", children: [ /* @__PURE__ */ jsx(Tabs.Content, { value: "draft", children: /* @__PURE__ */ jsx(FormLayout, { layout }) }), /* @__PURE__ */ jsx(Tabs.Content, { value: "published", children: /* @__PURE__ */ jsx(FormLayout, { layout }) }) ] }), /* @__PURE__ */ jsx(Grid.Item, { col: 3, s: 12, direction: "column", alignItems: "stretch", children: /* @__PURE__ */ jsx(Panels, {}) }) ] }) ] }), /* @__PURE__ */ jsx( Blocker, { onProceed: resetForm } ) ] }) } ) ] }); }; const StatusTab = styled(Tabs.Trigger)` text-transform: uppercase; `; const getDocumentStatus = (document, meta) => { const docStatus = document?.status; const statuses = meta?.availableStatus ?? []; if (!docStatus) { return "draft"; } if (docStatus === "draft" && statuses.find((doc) => doc.publishedAt !== null)) { return "published"; } return docStatus; }; const ProtectedEditViewPage = () => { const { slug = "" } = useParams(); const { permissions = [], isLoading, error } = useRBAC( PERMISSIONS.map((action) => ({ action, subject: slug })) ); if (isLoading) { return /* @__PURE__ */ jsx(Page.Loading, {}); } if (error || !slug) { return /* @__PURE__ */ jsx(Page.Error, {}); } return /* @__PURE__ */ jsx(Page.Protect, { permissions, children: ({ permissions: permissions2 }) => /* @__PURE__ */ jsx(DocumentRBAC, { permissions: permissions2, children: /* @__PURE__ */ jsx(EditViewPage, {}) }) }); }; export { EditViewPage, ProtectedEditViewPage, getDocumentStatus };