import { useTypedSelector } from "./chunk-VE2D6HMA.js"; import { DocumentRBAC, DynamicZone, MemoizedBlocksInput, MemoizedComponentInput, MemoizedUIDInput, MemoizedWysiwyg, NotAllowedInput, PERMISSIONS, getDisplayName, getRelationLabel, useDocumentRBAC, useDynamicZone, useFieldHint, useLazyComponents } from "./chunk-GXKJFURG.js"; import { DocumentStatus, RelativeTime } from "./chunk-7FUKGPNR.js"; import "./chunk-NAZM6EA4.js"; import { COLLECTION_TYPES, buildValidParams, prepareTempKeys, removeFieldsThatDontExistOnSchema, useDoc, useDocLayout, useDocument, useDocumentLayout, useGetContentTypeConfigurationQuery } from "./chunk-UATNJIHQ.js"; import { contentManagerApi } from "./chunk-P4VL3IHZ.js"; import "./chunk-HIZVCZYI.js"; import "./chunk-6LY4MOO2.js"; import "./chunk-QF6GPHA4.js"; import "./chunk-SYWYLB7I.js"; import "./chunk-S3HPKOXW.js"; import "./chunk-JRLAXHTE.js"; import "./chunk-E4IFZ6ZT.js"; import "./chunk-QLEKUQKW.js"; import "./chunk-4J3VOWQV.js"; import "./chunk-PFI4R5WA.js"; import "./chunk-B3BGMYGX.js"; import "./chunk-W6ICJ5TB.js"; import "./chunk-IHYIPMY2.js"; import "./chunk-UWHSN2C7.js"; import "./chunk-ERK7O2GM.js"; import "./chunk-FCIM6RNO.js"; import "./chunk-J33IXKN4.js"; import { ConfirmDialog } from "./chunk-NP53ZCXD.js"; import "./chunk-KFLQQE5L.js"; import "./chunk-ED4XR3VQ.js"; import "./chunk-MBK4V2X7.js"; import "./chunk-5ESYXDTN.js"; import "./chunk-K65KIEAL.js"; import "./chunk-B7ZLODDO.js"; import "./chunk-PW7XKCYO.js"; import "./chunk-RMBEU7DO.js"; import "./chunk-RI2W2UZ6.js"; import "./chunk-IY256CNP.js"; import "./chunk-IFOFBKTA.js"; import "./chunk-XLSIZGJF.js"; import "./chunk-EGNP2T5O.js"; import { useTracking } from "./chunk-GSN7U3BK.js"; import "./chunk-T3B5F2LV.js"; import "./chunk-YXDCVYVT.js"; import "./chunk-QIJGNK42.js"; import "./chunk-7PUJSL55.js"; import "./chunk-C2ZJTFO7.js"; import "./chunk-C75BZXCZ.js"; import "./chunk-APGTER6B.js"; import "./chunk-ZM6TT53G.js"; import { MemoizedInputRenderer } from "./chunk-6AXVGFVQ.js"; import { Form, useField, useForm } from "./chunk-BFLP6DBI.js"; import { useRBAC } from "./chunk-CMLQV3Z2.js"; import "./chunk-D4WYVNVM.js"; import "./chunk-MMOBCIZG.js"; import "./chunk-IGCTEXRF.js"; import { Layouts } from "./chunk-TIVRAWTC.js"; import "./chunk-PQINNV4N.js"; import "./chunk-VYSYYPOB.js"; import { Page } from "./chunk-5CAWUBTQ.js"; import { useQueryParams, useStrapiApp } from "./chunk-W2TBR6J3.js"; import "./chunk-QEGMJR7H.js"; import { require_lib, require_pipe } from "./chunk-LCL5TIBZ.js"; import "./chunk-WOQNBAGN.js"; import "./chunk-BHLYCXQ7.js"; import { createContext } from "./chunk-76QM3EFM.js"; import "./chunk-CE4VABH2.js"; import "./chunk-5VODLFKF.js"; import { useNotification } from "./chunk-N55RVBRV.js"; import { Alert, Box, Button, Dialog, Divider, Field, Flex, FocusTrap, Grid, Link as Link2, Main, Portal$1, TooltipImpl, Typography, useIntl } from "./chunk-7XB6XSWQ.js"; import "./chunk-5ZC4PE57.js"; import { Link, NavLink, Navigate, useNavigate, useParams } from "./chunk-TUXTO2Z5.js"; import "./chunk-FOD4ENRR.js"; import { ForwardRef$3, ForwardRef$5j } from "./chunk-WRD5KPDH.js"; import { require_jsx_runtime } from "./chunk-NIAJZ5MX.js"; import { dt } from "./chunk-ACIMPXWY.js"; import { require_react } from "./chunk-MADUDGYZ.js"; import { __toESM } from "./chunk-PLDDJCW6.js"; // node_modules/@strapi/content-manager/dist/admin/history/pages/History.mjs var import_jsx_runtime5 = __toESM(require_jsx_runtime(), 1); var React4 = __toESM(require_react(), 1); var import_qs3 = __toESM(require_lib(), 1); // node_modules/@strapi/content-manager/dist/admin/history/components/VersionContent.mjs var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1); var React2 = __toESM(require_react(), 1); var import_pipe = __toESM(require_pipe(), 1); // node_modules/@strapi/content-manager/dist/admin/history/components/VersionInputRenderer.mjs var import_jsx_runtime = __toESM(require_jsx_runtime(), 1); var React = __toESM(require_react(), 1); var StyledAlert = dt(Alert).attrs({ closeLabel: "Close", onClose: () => { }, shadow: "none" })` button { display: none; } `; var LinkEllipsis = dt(Link2)` display: block; & > span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block; } `; var CustomRelationInput = (props) => { const { formatMessage } = useIntl(); const field = useField(props.name); let formattedFieldValue; if (field) { formattedFieldValue = Array.isArray(field.value) ? { results: field.value, meta: { missingCount: 0 } } : field.value; } if (!formattedFieldValue || formattedFieldValue.results.length === 0 && formattedFieldValue.meta.missingCount === 0) { return (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [ (0, import_jsx_runtime.jsx)(Field.Label, { action: props.labelAction, children: props.label }), (0, import_jsx_runtime.jsx)(Box, { marginTop: 1, children: (0, import_jsx_runtime.jsx)(StyledAlert, { variant: "default", children: formatMessage({ id: "content-manager.history.content.no-relations", defaultMessage: "No relations." }) }) }) ] }); } const { results, meta } = formattedFieldValue; return (0, import_jsx_runtime.jsxs)(Box, { children: [ (0, import_jsx_runtime.jsx)(Field.Label, { children: props.label }), results.length > 0 && (0, import_jsx_runtime.jsx)(Flex, { direction: "column", gap: 2, marginTop: 1, alignItems: "stretch", children: results.map((relationData) => { const { targetModel } = props.attribute; const href = `../${COLLECTION_TYPES}/${targetModel}/${relationData.documentId}`; const label = getRelationLabel(relationData, props.mainField); const isAdminUserRelation = targetModel === "admin::user"; return (0, import_jsx_runtime.jsxs)(Flex, { paddingTop: 2, paddingBottom: 2, paddingLeft: 4, paddingRight: 4, hasRadius: true, borderColor: "neutral200", background: "neutral150", justifyContent: "space-between", children: [ (0, import_jsx_runtime.jsx)(Box, { minWidth: 0, paddingTop: 1, paddingBottom: 1, paddingRight: 4, children: (0, import_jsx_runtime.jsx)(TooltipImpl, { label, children: isAdminUserRelation ? (0, import_jsx_runtime.jsx)(Typography, { children: label }) : (0, import_jsx_runtime.jsx)(LinkEllipsis, { tag: NavLink, to: href, children: label }) }) }), (0, import_jsx_runtime.jsx)(DocumentStatus, { status: relationData.status }) ] }, relationData.documentId ?? relationData.id); }) }), meta.missingCount > 0 && /* @ts-expect-error – we dont need closeLabel */ (0, import_jsx_runtime.jsx)(StyledAlert, { marginTop: 1, variant: "warning", title: formatMessage({ id: "content-manager.history.content.missing-relations.title", defaultMessage: "{number, plural, =1 {Missing relation} other {{number} missing relations}}" }, { number: meta.missingCount }), children: formatMessage({ id: "content-manager.history.content.missing-relations.message", defaultMessage: "{number, plural, =1 {It has} other {They have}} been deleted and can't be restored." }, { number: meta.missingCount }) }) ] }); }; var createInitialValuesForPath = (keyPath, value) => { const keys = keyPath.split("."); const root = {}; let node = root; keys.forEach((key, index) => { if (key === "__proto__" || key === "constructor") return; if (index === keys.length - 1) { node[key] = value; } else { node[key] = node[key] || {}; } node = node[key]; }); return root; }; var CustomMediaInput = (props) => { const { value } = useField(props.name); const results = (value == null ? void 0 : value.results) ?? []; const meta = (value == null ? void 0 : value.meta) ?? { missingCount: 0 }; const { formatMessage } = useIntl(); const fields = useStrapiApp("CustomMediaInput", (state) => state.fields); const MediaLibrary = fields.media; return (0, import_jsx_runtime.jsxs)(Flex, { direction: "column", gap: 2, alignItems: "stretch", children: [ (0, import_jsx_runtime.jsx)(Form, { method: "PUT", disabled: true, initialValues: createInitialValuesForPath(props.name, results), children: (0, import_jsx_runtime.jsx)(MediaLibrary, { ...props, disabled: true, multiple: results.length > 1 }) }), meta.missingCount > 0 && (0, import_jsx_runtime.jsx)(StyledAlert, { variant: "warning", closeLabel: "Close", onClose: () => { }, title: formatMessage({ id: "content-manager.history.content.missing-assets.title", defaultMessage: "{number, plural, =1 {Missing asset} other {{number} missing assets}}" }, { number: meta.missingCount }), children: formatMessage({ id: "content-manager.history.content.missing-assets.message", defaultMessage: "{number, plural, =1 {It has} other {They have}} been deleted in the Media Library and can't be restored." }, { number: meta.missingCount }) }) ] }); }; var getLabelAction = (labelAction) => { if (!React.isValidElement(labelAction)) { return labelAction; } const labelActionTitleId = labelAction.props.title.id; if (labelActionTitleId === "i18n.Field.localized") { return React.cloneElement(labelAction, { ...labelAction.props, title: { id: "history.content.localized", defaultMessage: "This value is specific to this locale. If you restore this version, the content will not be replaced for other locales." } }); } if (labelActionTitleId === "i18n.Field.not-localized") { return React.cloneElement(labelAction, { ...labelAction.props, title: { id: "history.content.not-localized", defaultMessage: "This value is common to all locales. If you restore this version and save the changes, the content will be replaced for all locales." } }); } return labelAction; }; var VersionInputRenderer = ({ visible, hint: providedHint, shouldIgnoreRBAC = false, labelAction, ...props }) => { const customLabelAction = getLabelAction(labelAction); const { formatMessage } = useIntl(); const version = useHistoryContext("VersionContent", (state) => state.selectedVersion); const configuration = useHistoryContext("VersionContent", (state) => state.configuration); const fieldSizes = useTypedSelector((state) => state["content-manager"].app.fieldSizes); const { id, components } = useDoc(); const isFormDisabled = useForm("InputRenderer", (state) => state.disabled); const isInDynamicZone = useDynamicZone("isInDynamicZone", (state) => state.isInDynamicZone); const canCreateFields = useDocumentRBAC("InputRenderer", (rbac) => rbac.canCreateFields); const canReadFields = useDocumentRBAC("InputRenderer", (rbac) => rbac.canReadFields); const canUpdateFields = useDocumentRBAC("InputRenderer", (rbac) => rbac.canUpdateFields); const canUserAction = useDocumentRBAC("InputRenderer", (rbac) => rbac.canUserAction); const editableFields = id ? canUpdateFields : canCreateFields; const readableFields = id ? canReadFields : canCreateFields; const canUserReadField = canUserAction(props.name, readableFields, props.type); const canUserEditField = canUserAction(props.name, editableFields, props.type); const fields = useStrapiApp("InputRenderer", (app) => app.fields); const { lazyComponentStore } = useLazyComponents(attributeHasCustomFieldProperty(props.attribute) ? [ props.attribute.customField ] : void 0); const hint = useFieldHint(providedHint, props.attribute); const { edit: { components: componentsLayout } } = useDocLayout(); if (!visible) { return null; } if (!shouldIgnoreRBAC && !canUserReadField && !isInDynamicZone) { return (0, import_jsx_runtime.jsx)(NotAllowedInput, { hint, ...props }); } const fieldIsDisabled = !canUserEditField && !isInDynamicZone || props.disabled || isFormDisabled; const addedAttributes = version.meta.unknownAttributes.added; if (Object.keys(addedAttributes).includes(props.name)) { return (0, import_jsx_runtime.jsxs)(Flex, { direction: "column", alignItems: "flex-start", gap: 1, children: [ (0, import_jsx_runtime.jsx)(Field.Label, { children: props.label }), (0, import_jsx_runtime.jsx)(StyledAlert, { width: "100%", closeLabel: "Close", onClose: () => { }, variant: "warning", title: formatMessage({ id: "content-manager.history.content.new-field.title", defaultMessage: "New field" }), children: formatMessage({ id: "content-manager.history.content.new-field.message", defaultMessage: "This field didn't exist when this version was saved. If you restore this version, it will be empty." }) }) ] }); } if (attributeHasCustomFieldProperty(props.attribute)) { const CustomInput = lazyComponentStore[props.attribute.customField]; if (CustomInput) { return (0, import_jsx_runtime.jsx)(CustomInput, { ...props, // @ts-expect-error – TODO: fix this type error in the useLazyComponents hook. hint, labelAction: customLabelAction, disabled: fieldIsDisabled }); } return (0, import_jsx_runtime.jsx)(MemoizedInputRenderer, { ...props, hint, labelAction: customLabelAction, // @ts-expect-error – this workaround lets us display that the custom field is missing. type: props.attribute.customField, disabled: fieldIsDisabled }); } if (props.type === "media") { return (0, import_jsx_runtime.jsx)(CustomMediaInput, { ...props, labelAction: customLabelAction, disabled: fieldIsDisabled }); } const addedInputTypes = Object.keys(fields); if (!attributeHasCustomFieldProperty(props.attribute) && addedInputTypes.includes(props.type)) { const CustomInput = fields[props.type]; return (0, import_jsx_runtime.jsx)(CustomInput, { ...props, // @ts-expect-error – TODO: fix this type error in the useLibrary hook. hint, labelAction: customLabelAction, disabled: fieldIsDisabled }); } switch (props.type) { case "blocks": return (0, import_jsx_runtime.jsx)(MemoizedBlocksInput, { ...props, hint, type: props.type, disabled: fieldIsDisabled }); case "component": const { layout } = componentsLayout[props.attribute.component]; const [remainingFieldsLayout] = getRemaingFieldsLayout({ layout: [ layout ], metadatas: configuration.components[props.attribute.component].metadatas, fieldSizes, schemaAttributes: components[props.attribute.component].attributes }); return (0, import_jsx_runtime.jsx)(MemoizedComponentInput, { ...props, layout: [ ...layout, ...remainingFieldsLayout || [] ], hint, labelAction: customLabelAction, disabled: fieldIsDisabled, children: (inputProps) => (0, import_jsx_runtime.jsx)(VersionInputRenderer, { ...inputProps, shouldIgnoreRBAC: true }) }); case "dynamiczone": return (0, import_jsx_runtime.jsx)(DynamicZone, { ...props, hint, labelAction: customLabelAction, disabled: fieldIsDisabled, children: (inputProps) => (0, import_jsx_runtime.jsx)(VersionInputRenderer, { ...inputProps, shouldIgnoreRBAC: true }) }); case "relation": return (0, import_jsx_runtime.jsx)(CustomRelationInput, { ...props, hint, labelAction: customLabelAction, disabled: fieldIsDisabled }); case "richtext": return (0, import_jsx_runtime.jsx)(MemoizedWysiwyg, { ...props, hint, type: props.type, labelAction: customLabelAction, disabled: fieldIsDisabled }); case "uid": return (0, import_jsx_runtime.jsx)(MemoizedUIDInput, { ...props, hint, type: props.type, labelAction: customLabelAction, disabled: fieldIsDisabled }); case "enumeration": return (0, import_jsx_runtime.jsx)(MemoizedInputRenderer, { ...props, hint, labelAction: customLabelAction, options: props.attribute.enum.map((value) => ({ value })), // @ts-expect-error – Temp workaround so we don't forget custom-fields don't work! type: props.customField ? "custom-field" : props.type, disabled: fieldIsDisabled }); default: const { unique: _unique, mainField: _mainField, ...restProps } = props; return (0, import_jsx_runtime.jsx)(MemoizedInputRenderer, { ...restProps, hint, labelAction: customLabelAction, // @ts-expect-error – Temp workaround so we don't forget custom-fields don't work! type: props.customField ? "custom-field" : props.type, disabled: fieldIsDisabled }); } }; var attributeHasCustomFieldProperty = (attribute) => "customField" in attribute && typeof attribute.customField === "string"; // node_modules/@strapi/content-manager/dist/admin/history/components/VersionContent.mjs var createLayoutFromFields = (fields) => { return fields.reduce((rows, field) => { if (field.type === "dynamiczone") { rows.push([ field ]); return rows; } if (!rows[rows.length - 1]) { rows.push([]); } rows[rows.length - 1].push(field); return rows; }, []).map((row) => [ row ]); }; function getRemaingFieldsLayout({ layout, metadatas, schemaAttributes, fieldSizes }) { const fieldsInLayout = layout.flatMap((panel) => panel.flatMap((row) => row.flatMap((field) => field.name))); const remainingFields = Object.entries(metadatas).reduce((currentRemainingFields, [name, field]) => { if (!fieldsInLayout.includes(name) && field.edit.visible === true) { const attribute = schemaAttributes[name]; currentRemainingFields.push({ attribute, type: attribute.type, visible: true, disabled: true, label: field.edit.label || name, name, size: fieldSizes[attribute.type].default ?? 12 }); } return currentRemainingFields; }, []); return createLayoutFromFields(remainingFields); } var FormPanel = ({ panel }) => { if (panel.some((row) => row.some((field) => field.type === "dynamiczone"))) { const [row] = panel; const [field] = row; return (0, import_jsx_runtime2.jsx)(Grid.Root, { gap: 4, children: (0, import_jsx_runtime2.jsx)(Grid.Item, { col: 12, s: 12, xs: 12, direction: "column", alignItems: "stretch", children: (0, import_jsx_runtime2.jsx)(VersionInputRenderer, { ...field }) }) }, field.name); } return (0, import_jsx_runtime2.jsx)(Box, { hasRadius: true, background: "neutral0", shadow: "tableShadow", paddingLeft: 6, paddingRight: 6, paddingTop: 6, paddingBottom: 6, borderColor: "neutral150", children: (0, import_jsx_runtime2.jsx)(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: panel.map((row, gridRowIndex) => (0, import_jsx_runtime2.jsx)(Grid.Root, { gap: 4, children: row.map(({ size, ...field }) => { return (0, import_jsx_runtime2.jsx)(Grid.Item, { col: size, s: 12, xs: 12, direction: "column", alignItems: "stretch", children: (0, import_jsx_runtime2.jsx)(VersionInputRenderer, { ...field }) }, field.name); }) }, gridRowIndex)) }) }); }; var VersionContent = () => { const { formatMessage } = useIntl(); const { fieldSizes } = useTypedSelector((state) => state["content-manager"].app); const version = useHistoryContext("VersionContent", (state) => state.selectedVersion); const layout = useHistoryContext("VersionContent", (state) => state.layout); const configuration = useHistoryContext("VersionContent", (state) => state.configuration); const schema = useHistoryContext("VersionContent", (state) => state.schema); const removedAttributes = version.meta.unknownAttributes.removed; const removedAttributesAsFields = Object.entries(removedAttributes).map(([attributeName, attribute]) => { const field = { attribute, shouldIgnoreRBAC: true, type: attribute.type, visible: true, disabled: true, label: attributeName, name: attributeName, size: fieldSizes[attribute.type].default ?? 12 }; return field; }); const unknownFieldsLayout = createLayoutFromFields(removedAttributesAsFields); const remainingFieldsLayout = getRemaingFieldsLayout({ metadatas: configuration.contentType.metadatas, layout, schemaAttributes: schema.attributes, fieldSizes }); const { components } = useDoc(); const transformedData = React2.useMemo(() => { const transform = (schemaAttributes, components2 = {}) => (document) => { const schema2 = { attributes: schemaAttributes }; const transformations = (0, import_pipe.default)(removeFieldsThatDontExistOnSchema(schema2), prepareTempKeys(schema2, components2)); return transformations(document); }; return transform(version.schema, components)(version.data); }, [ components, version.data, version.schema ]); return (0, import_jsx_runtime2.jsxs)(Layouts.Content, { children: [ (0, import_jsx_runtime2.jsx)(Box, { paddingBottom: 8, children: (0, import_jsx_runtime2.jsx)(Form, { disabled: true, method: "PUT", initialValues: transformedData, children: (0, import_jsx_runtime2.jsx)(Flex, { direction: "column", alignItems: "stretch", gap: 6, position: "relative", children: [ ...layout, ...remainingFieldsLayout ].map((panel, index) => { return (0, import_jsx_runtime2.jsx)(FormPanel, { panel }, index); }) }) }) }), removedAttributesAsFields.length > 0 && (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [ (0, import_jsx_runtime2.jsx)(Divider, {}), (0, import_jsx_runtime2.jsxs)(Box, { paddingTop: 8, children: [ (0, import_jsx_runtime2.jsxs)(Flex, { direction: "column", alignItems: "flex-start", paddingBottom: 6, gap: 1, children: [ (0, import_jsx_runtime2.jsx)(Typography, { variant: "delta", children: formatMessage({ id: "content-manager.history.content.unknown-fields.title", defaultMessage: "Unknown fields" }) }), (0, import_jsx_runtime2.jsx)(Typography, { variant: "pi", children: formatMessage({ id: "content-manager.history.content.unknown-fields.message", defaultMessage: "These fields have been deleted or renamed in the Content-Type Builder. These fields will not be restored." }, { b: (chunks) => (0, import_jsx_runtime2.jsx)(Typography, { variant: "pi", fontWeight: "bold", children: chunks }) }) }) ] }), (0, import_jsx_runtime2.jsx)(Form, { disabled: true, method: "PUT", initialValues: version.data, children: (0, import_jsx_runtime2.jsx)(Flex, { direction: "column", alignItems: "stretch", gap: 6, position: "relative", children: unknownFieldsLayout.map((panel, index) => { return (0, import_jsx_runtime2.jsx)(FormPanel, { panel }, index); }) }) }) ] }) ] }) ] }); }; // node_modules/@strapi/content-manager/dist/admin/history/components/VersionHeader.mjs var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1); var React3 = __toESM(require_react(), 1); var import_qs = __toESM(require_lib(), 1); // node_modules/@strapi/content-manager/dist/admin/history/services/historyVersion.mjs var historyVersionsApi = contentManagerApi.injectEndpoints({ endpoints: (builder) => ({ getHistoryVersions: builder.query({ query(params) { return { url: `/content-manager/history-versions`, method: "GET", config: { params } }; }, providesTags: [ "HistoryVersion" ] }), restoreVersion: builder.mutation({ query({ params, body }) { return { url: `/content-manager/history-versions/${params.versionId}/restore`, method: "PUT", data: body }; }, invalidatesTags: (_res, _error, { documentId, collectionType, params }) => { return [ "HistoryVersion", { type: "Document", id: collectionType === COLLECTION_TYPES ? `${params.contentType}_${documentId}` : params.contentType } ]; } }) }) }); var { useGetHistoryVersionsQuery, useRestoreVersionMutation } = historyVersionsApi; // node_modules/@strapi/content-manager/dist/admin/history/components/VersionHeader.mjs var VersionHeader = ({ headerId }) => { var _a; const [isConfirmDialogOpen, setIsConfirmDialogOpen] = React3.useState(false); const navigate = useNavigate(); const { formatMessage, formatDate } = useIntl(); const { trackUsage } = useTracking(); const { toggleNotification } = useNotification(); const [{ query }] = useQueryParams(); const { collectionType, slug } = useParams(); const [restoreVersion, { isLoading }] = useRestoreVersionMutation(); const { allowedActions } = useRBAC(PERMISSIONS.map((action) => ({ action, subject: slug }))); const version = useHistoryContext("VersionHeader", (state) => state.selectedVersion); const mainField = useHistoryContext("VersionHeader", (state) => state.mainField); const schema = useHistoryContext("VersionHeader", (state) => state.schema); const isCurrentVersion = useHistoryContext("VersionHeader", (state) => state.page === 1 && state.versions.data[0].id === state.selectedVersion.id); const mainFieldValue = version.data[mainField]; const getNextNavigation = () => { const pluginsQueryParams = (0, import_qs.stringify)({ plugins: query.plugins }, { encode: false }); return { pathname: "..", search: pluginsQueryParams }; }; const handleRestore = async () => { try { const response = await restoreVersion({ documentId: version.relatedDocumentId, collectionType, params: { versionId: version.id, contentType: version.contentType }, body: { contentType: version.contentType } }); if ("data" in response) { navigate(getNextNavigation(), { relative: "path" }); toggleNotification({ type: "success", title: formatMessage({ id: "content-manager.restore.success.title", defaultMessage: "Version restored." }), message: formatMessage({ id: "content-manager.restore.success.message", defaultMessage: "A past version of the content was restored." }) }); trackUsage("didRestoreHistoryVersion"); } if ("error" in response) { toggleNotification({ type: "danger", message: formatMessage({ id: "content-manager.history.restore.error.message", defaultMessage: "Could not restore version." }) }); } } catch (error) { toggleNotification({ type: "danger", message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" }) }); } }; return (0, import_jsx_runtime3.jsxs)(Dialog.Root, { open: isConfirmDialogOpen, onOpenChange: setIsConfirmDialogOpen, children: [ (0, import_jsx_runtime3.jsx)(Layouts.BaseHeader, { id: headerId, title: formatDate(new Date(version.createdAt), { year: "numeric", month: "numeric", day: "numeric", hour: "numeric", minute: "numeric" }), subtitle: (0, import_jsx_runtime3.jsx)(Typography, { variant: "epsilon", textColor: "neutral600", children: formatMessage({ id: "content-manager.history.version.subtitle", defaultMessage: "{hasLocale, select, true {{subtitle}, in {locale}} other {{subtitle}}}" }, { hasLocale: Boolean(version.locale), subtitle: `${mainFieldValue || ""} (${schema.info.singularName})`.trim(), locale: (_a = version.locale) == null ? void 0 : _a.name }) }), navigationAction: (0, import_jsx_runtime3.jsx)(Link2, { startIcon: (0, import_jsx_runtime3.jsx)(ForwardRef$5j, {}), tag: NavLink, to: getNextNavigation(), relative: "path", isExternal: false, children: formatMessage({ id: "global.back", defaultMessage: "Back" }) }), sticky: false, primaryAction: (0, import_jsx_runtime3.jsx)(Dialog.Trigger, { children: (0, import_jsx_runtime3.jsx)(Button, { disabled: !allowedActions.canUpdate || isCurrentVersion, onClick: () => { setIsConfirmDialogOpen(true); }, children: formatMessage({ id: "content-manager.history.restore.confirm.button", defaultMessage: "Restore" }) }) }) }), (0, import_jsx_runtime3.jsx)(ConfirmDialog, { onConfirm: handleRestore, endAction: (0, import_jsx_runtime3.jsx)(Button, { variant: "secondary", onClick: handleRestore, loading: isLoading, children: formatMessage({ id: "content-manager.history.restore.confirm.button", defaultMessage: "Restore" }) }), children: (0, import_jsx_runtime3.jsxs)(Flex, { direction: "column", alignItems: "center", justifyContent: "center", gap: 2, textAlign: "center", children: [ (0, import_jsx_runtime3.jsx)(Flex, { justifyContent: "center", children: (0, import_jsx_runtime3.jsx)(ForwardRef$3, { width: "24px", height: "24px", fill: "danger600" }) }), (0, import_jsx_runtime3.jsx)(Typography, { children: formatMessage({ id: "content-manager.history.restore.confirm.title", defaultMessage: "Are you sure you want to restore this version?" }) }), (0, import_jsx_runtime3.jsx)(Typography, { children: formatMessage({ id: "content-manager.history.restore.confirm.message", defaultMessage: "{isDraft, select, true {The restored content will override your draft.} other {The restored content won't be published, it will override the draft and be saved as pending changes. You'll be able to publish the changes at anytime.}}" }, { isDraft: version.status === "draft" }) }) ] }) }) ] }); }; // node_modules/@strapi/content-manager/dist/admin/history/components/VersionsList.mjs var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1); var import_react = __toESM(require_react(), 1); var import_qs2 = __toESM(require_lib(), 1); var BlueText = (children) => (0, import_jsx_runtime4.jsx)(Typography, { textColor: "primary600", variant: "pi", children }); var VersionCard = ({ version, isCurrent }) => { const { formatDate, formatMessage } = useIntl(); const [{ query }] = useQueryParams(); const isActive = query.id === version.id.toString(); const author = version.createdBy && getDisplayName(version.createdBy); return (0, import_jsx_runtime4.jsxs)(Flex, { direction: "column", alignItems: "flex-start", gap: 3, hasRadius: true, borderWidth: "1px", borderStyle: "solid", borderColor: isActive ? "primary600" : "neutral200", color: "neutral800", padding: 5, tag: Link, to: `?${(0, import_qs2.stringify)({ ...query, id: version.id })}`, style: { textDecoration: "none" }, children: [ (0, import_jsx_runtime4.jsxs)(Flex, { direction: "column", gap: 1, alignItems: "flex-start", children: [ (0, import_jsx_runtime4.jsx)(Typography, { tag: "h3", fontWeight: "semiBold", children: formatDate(version.createdAt, { day: "numeric", month: "numeric", year: "numeric", hour: "2-digit", minute: "2-digit" }) }), (0, import_jsx_runtime4.jsx)(Typography, { tag: "p", variant: "pi", textColor: "neutral600", children: formatMessage({ id: "content-manager.history.sidebar.versionDescription", defaultMessage: "{distanceToNow}{isAnonymous, select, true {} other { by {author}}}{isCurrent, select, true { (current)} other {}}" }, { distanceToNow: (0, import_jsx_runtime4.jsx)(RelativeTime, { timestamp: new Date(version.createdAt) }), author, isAnonymous: !Boolean(version.createdBy), isCurrent, b: BlueText }) }) ] }), version.status && (0, import_jsx_runtime4.jsx)(DocumentStatus, { status: version.status, size: "XS" }) ] }); }; var PaginationButton = ({ page, children }) => { const [{ query }] = useQueryParams(); const { id: _id, ...queryRest } = query; return (0, import_jsx_runtime4.jsx)(Link, { to: { search: (0, import_qs2.stringify)({ ...queryRest, page }) }, style: { textDecoration: "none" }, children: (0, import_jsx_runtime4.jsx)(Typography, { variant: "omega", textColor: "primary600", children }) }); }; var VersionsList = () => { const { formatMessage } = useIntl(); const { versions, page } = useHistoryContext("VersionsList", (state) => ({ versions: state.versions, page: state.page })); return (0, import_jsx_runtime4.jsxs)(Flex, { shrink: 0, direction: "column", alignItems: "stretch", width: "320px", height: "100vh", background: "neutral0", borderColor: "neutral200", borderWidth: "0 0 0 1px", borderStyle: "solid", tag: "aside", children: [ (0, import_jsx_runtime4.jsxs)(Flex, { direction: "row", justifyContent: "space-between", padding: 4, borderColor: "neutral200", borderWidth: "0 0 1px", borderStyle: "solid", tag: "header", children: [ (0, import_jsx_runtime4.jsx)(Typography, { tag: "h2", variant: "omega", fontWeight: "semiBold", children: formatMessage({ id: "content-manager.history.sidebar.title", defaultMessage: "Versions" }) }), (0, import_jsx_runtime4.jsx)(Box, { background: "neutral150", hasRadius: true, padding: 1, children: (0, import_jsx_runtime4.jsx)(Typography, { variant: "sigma", textColor: "neutral600", children: versions.meta.pagination.total }) }) ] }), (0, import_jsx_runtime4.jsxs)(Box, { flex: 1, overflow: "auto", children: [ versions.meta.pagination.page > 1 && (0, import_jsx_runtime4.jsx)(Box, { paddingTop: 4, textAlign: "center", children: (0, import_jsx_runtime4.jsx)(PaginationButton, { page: page - 1, children: formatMessage({ id: "content-manager.history.sidebar.show-newer", defaultMessage: "Show newer versions" }) }) }), (0, import_jsx_runtime4.jsx)(Flex, { direction: "column", gap: 3, padding: 4, tag: "ul", alignItems: "stretch", children: versions.data.map((version, index) => (0, import_jsx_runtime4.jsx)("li", { "aria-label": formatMessage({ id: "content-manager.history.sidebar.title.version-card.aria-label", defaultMessage: "Version card" }), children: (0, import_jsx_runtime4.jsx)(VersionCard, { version, isCurrent: page === 1 && index === 0 }) }, version.id)) }), versions.meta.pagination.page < versions.meta.pagination.pageCount && (0, import_jsx_runtime4.jsx)(Box, { paddingBottom: 4, textAlign: "center", children: (0, import_jsx_runtime4.jsx)(PaginationButton, { page: page + 1, children: formatMessage({ id: "content-manager.history.sidebar.show-older", defaultMessage: "Show older versions" }) }) }) ] }) ] }); }; // node_modules/@strapi/content-manager/dist/admin/history/pages/History.mjs var [HistoryProvider, useHistoryContext] = createContext("HistoryPage"); var HistoryPage = () => { var _a, _b, _c, _d, _e, _f; const headerId = React4.useId(); const { formatMessage } = useIntl(); const { slug, id: documentId, collectionType } = useParams(); const { isLoading: isLoadingDocument, schema } = useDocument({ collectionType, model: slug }); const { isLoading: isLoadingLayout, edit: { layout, settings: { displayName, mainField } } } = useDocumentLayout(slug); const { data: configuration, isLoading: isLoadingConfiguration } = useGetContentTypeConfigurationQuery(slug); const [{ query }] = useQueryParams(); const { id: selectedVersionId, ...queryWithoutId } = query; const validQueryParamsWithoutId = buildValidParams(queryWithoutId); const page = validQueryParamsWithoutId.page ? Number(validQueryParamsWithoutId.page) : 1; const versionsResponse = useGetHistoryVersionsQuery({ contentType: slug, ...documentId ? { documentId } : {}, // Omit id since it's not needed by the endpoint and caused extra refetches ...validQueryParamsWithoutId }, { refetchOnMountOrArgChange: true }); const initialRequestId = React4.useRef(versionsResponse.requestId); const isStaleRequest = versionsResponse.requestId === initialRequestId.current; if (!slug || collectionType === COLLECTION_TYPES && !documentId) { return (0, import_jsx_runtime5.jsx)(Navigate, { to: "/content-manager" }); } if (isLoadingDocument || isLoadingLayout || versionsResponse.isFetching || isStaleRequest || isLoadingConfiguration) { return (0, import_jsx_runtime5.jsx)(Page.Loading, {}); } if (!versionsResponse.isError && !((_b = (_a = versionsResponse.data) == null ? void 0 : _a.data) == null ? void 0 : _b.length)) { return (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children: (0, import_jsx_runtime5.jsx)(Page.NoData, { action: (0, import_jsx_runtime5.jsx)(Link2, { tag: NavLink, to: `/content-manager/${collectionType}/${slug}${documentId ? `/${documentId}` : ""}`, children: formatMessage({ id: "global.back", defaultMessage: "Back" }) }) }) }); } if (((_d = (_c = versionsResponse.data) == null ? void 0 : _c.data) == null ? void 0 : _d.length) && !selectedVersionId) { return (0, import_jsx_runtime5.jsx)(Navigate, { to: { search: (0, import_qs3.stringify)({ ...query, id: versionsResponse.data.data[0].id }) }, replace: true }); } const selectedVersion = (_f = (_e = versionsResponse.data) == null ? void 0 : _e.data) == null ? void 0 : _f.find((version) => version.id.toString() === selectedVersionId); if (versionsResponse.isError || !layout || !schema || !selectedVersion || !configuration || // This should not happen as it's covered by versionsResponse.isError, but we need it for TS versionsResponse.data.error) { return (0, import_jsx_runtime5.jsx)(Page.Error, {}); } return (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [ (0, import_jsx_runtime5.jsx)(Page.Title, { children: formatMessage({ id: "content-manager.history.page-title", defaultMessage: "{contentType} history" }, { contentType: displayName }) }), (0, import_jsx_runtime5.jsx)(HistoryProvider, { contentType: slug, id: documentId, schema, layout, configuration, selectedVersion, versions: versionsResponse.data, page, mainField, children: (0, import_jsx_runtime5.jsxs)(Flex, { direction: "row", alignItems: "flex-start", children: [ (0, import_jsx_runtime5.jsxs)(Main, { grow: 1, height: "100vh", background: "neutral100", paddingBottom: 6, overflow: "auto", labelledBy: headerId, children: [ (0, import_jsx_runtime5.jsx)(VersionHeader, { headerId }), (0, import_jsx_runtime5.jsx)(VersionContent, {}) ] }), (0, import_jsx_runtime5.jsx)(VersionsList, {}) ] }) }) ] }); }; var ProtectedHistoryPageImpl = () => { const { slug } = useParams(); const { permissions = [], isLoading, error } = useRBAC(PERMISSIONS.map((action) => ({ action, subject: slug }))); if (isLoading) { return (0, import_jsx_runtime5.jsx)(Page.Loading, {}); } if (error || !slug) { return (0, import_jsx_runtime5.jsx)(Box, { height: "100vh", width: "100vw", position: "fixed", top: 0, left: 0, zIndex: 2, background: "neutral0", children: (0, import_jsx_runtime5.jsx)(Page.Error, {}) }); } return (0, import_jsx_runtime5.jsx)(Box, { height: "100vh", width: "100vw", position: "fixed", top: 0, left: 0, zIndex: 2, background: "neutral0", children: (0, import_jsx_runtime5.jsx)(Page.Protect, { permissions, children: ({ permissions: permissions2 }) => (0, import_jsx_runtime5.jsx)(DocumentRBAC, { permissions: permissions2, children: (0, import_jsx_runtime5.jsx)(HistoryPage, {}) }) }) }); }; var ProtectedHistoryPage = () => { return (0, import_jsx_runtime5.jsx)(Portal$1, { children: (0, import_jsx_runtime5.jsx)(FocusTrap, { children: (0, import_jsx_runtime5.jsx)(ProtectedHistoryPageImpl, {}) }) }); }; export { HistoryProvider, ProtectedHistoryPage, useHistoryContext }; //# sourceMappingURL=History-UKPXPR4M.js.map