@strapi/content-manager 5.14.0 → 5.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/dist/admin/history/components/VersionHeader.js +6 -0
  2. package/dist/admin/history/components/VersionHeader.js.map +1 -1
  3. package/dist/admin/history/components/VersionHeader.mjs +7 -1
  4. package/dist/admin/history/components/VersionHeader.mjs.map +1 -1
  5. package/dist/admin/pages/EditView/components/DocumentActions.js +24 -7
  6. package/dist/admin/pages/EditView/components/DocumentActions.js.map +1 -1
  7. package/dist/admin/pages/EditView/components/DocumentActions.mjs +24 -7
  8. package/dist/admin/pages/EditView/components/DocumentActions.mjs.map +1 -1
  9. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksToolbar.js +19 -33
  10. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksToolbar.js.map +1 -1
  11. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksToolbar.mjs +19 -33
  12. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksToolbar.mjs.map +1 -1
  13. package/dist/admin/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.js +2 -1
  14. package/dist/admin/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.js.map +1 -1
  15. package/dist/admin/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.mjs +2 -1
  16. package/dist/admin/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.mjs.map +1 -1
  17. package/dist/admin/translations/en.json.js +1 -0
  18. package/dist/admin/translations/en.json.js.map +1 -1
  19. package/dist/admin/translations/en.json.mjs +1 -0
  20. package/dist/admin/translations/en.json.mjs.map +1 -1
  21. package/dist/server/history/services/lifecycles.js +3 -0
  22. package/dist/server/history/services/lifecycles.js.map +1 -1
  23. package/dist/server/history/services/lifecycles.mjs +3 -0
  24. package/dist/server/history/services/lifecycles.mjs.map +1 -1
  25. package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
  26. package/package.json +6 -6
@@ -1 +1 @@
1
- {"version":3,"file":"ConfirmBulkActionDialog.js","sources":["../../../../../../admin/src/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n useTable,\n useNotification,\n useAPIErrorHandler,\n useQueryParams,\n} from '@strapi/admin/strapi-admin';\nimport { Button, Flex, Dialog, Typography } from '@strapi/design-system';\nimport { Check, WarningCircle } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\n\nimport { useDoc } from '../../../../hooks/useDocument';\nimport { useGetManyDraftRelationCountQuery } from '../../../../services/documents';\nimport { getTranslation } from '../../../../utils/translations';\n\nimport { Emphasis } from './Actions';\n\ninterface ConfirmBulkActionDialogProps {\n endAction: React.ReactNode;\n onToggleDialog: () => void;\n isOpen?: boolean;\n dialogBody: React.ReactNode;\n}\n\nconst ConfirmBulkActionDialog = ({\n onToggleDialog,\n isOpen = false,\n dialogBody,\n endAction,\n}: ConfirmBulkActionDialogProps) => {\n const { formatMessage } = useIntl();\n\n return (\n <Dialog.Root open={isOpen}>\n <Dialog.Content>\n <Dialog.Header>\n {formatMessage({\n id: 'app.components.ConfirmDialog.title',\n defaultMessage: 'Confirmation',\n })}\n </Dialog.Header>\n <Dialog.Body>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={2}>\n <Flex justifyContent=\"center\">\n <WarningCircle width=\"24px\" height=\"24px\" fill=\"danger600\" />\n </Flex>\n {dialogBody}\n </Flex>\n </Dialog.Body>\n <Dialog.Footer>\n <Dialog.Cancel>\n <Button fullWidth onClick={onToggleDialog} variant=\"tertiary\">\n {formatMessage({\n id: 'app.components.Button.cancel',\n defaultMessage: 'Cancel',\n })}\n </Button>\n </Dialog.Cancel>\n {endAction}\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * BoldChunk\n * -----------------------------------------------------------------------------------------------*/\n\nconst BoldChunk = (chunks: React.ReactNode) => <Typography fontWeight=\"bold\">{chunks}</Typography>;\n\n/* -------------------------------------------------------------------------------------------------\n * ConfirmDialogPublishAll\n * -----------------------------------------------------------------------------------------------*/\n\ninterface ConfirmDialogPublishAllProps\n extends Pick<ConfirmBulkActionDialogProps, 'isOpen' | 'onToggleDialog'> {\n isConfirmButtonLoading?: boolean;\n onConfirm: () => void;\n}\n\nconst ConfirmDialogPublishAll = ({\n isOpen,\n onToggleDialog,\n isConfirmButtonLoading = false,\n onConfirm,\n}: ConfirmDialogPublishAllProps) => {\n const { formatMessage } = useIntl();\n const selectedEntries = useTable('ConfirmDialogPublishAll', (state) => state.selectedRows);\n const { toggleNotification } = useNotification();\n const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler(getTranslation);\n const { model, schema } = useDoc();\n const [{ query }] = useQueryParams<{\n plugins?: {\n i18n?: {\n locale?: string;\n };\n };\n }>();\n\n // TODO skipping this for now as there is a bug with the draft relation count that will be worked on separately\n // see RFC \"Count draft relations\" in Notion\n const enableDraftRelationsCount = false;\n\n const {\n data: countDraftRelations = 0,\n isLoading,\n error,\n } = useGetManyDraftRelationCountQuery(\n {\n model,\n documentIds: selectedEntries.map((entry) => entry.documentId),\n locale: query?.plugins?.i18n?.locale,\n },\n {\n skip: !enableDraftRelationsCount || selectedEntries.length === 0,\n }\n );\n\n React.useEffect(() => {\n if (error) {\n toggleNotification({ type: 'danger', message: formatAPIError(error) });\n }\n }, [error, formatAPIError, toggleNotification]);\n\n if (error) {\n return null;\n }\n\n return (\n <ConfirmBulkActionDialog\n isOpen={isOpen && !isLoading}\n onToggleDialog={onToggleDialog}\n dialogBody={\n <>\n <Typography id=\"confirm-description\" textAlign=\"center\">\n {countDraftRelations > 0 &&\n formatMessage(\n {\n id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),\n defaultMessage:\n '<b>{count} {count, plural, one { relation } other { relations } } out of {entities} { entities, plural, one { entry } other { entries } } {count, plural, one { is } other { are } }</b> not published yet and might lead to unexpected behavior. ',\n },\n {\n b: BoldChunk,\n count: countDraftRelations,\n entities: selectedEntries.length,\n }\n )}\n {formatMessage({\n id: getTranslation('popUpWarning.bodyMessage.contentType.publish.all'),\n defaultMessage: 'Are you sure you want to publish these entries?',\n })}\n </Typography>\n {schema?.pluginOptions &&\n 'i18n' in schema.pluginOptions &&\n schema?.pluginOptions.i18n && (\n <Typography textColor=\"danger500\" textAlign=\"center\">\n {formatMessage(\n {\n id: getTranslation('Settings.list.actions.publishAdditionalInfos'),\n defaultMessage:\n 'This will publish the active locale versions <em>(from Internationalization)</em>',\n },\n {\n em: Emphasis,\n }\n )}\n </Typography>\n )}\n </>\n }\n endAction={\n <Button\n onClick={onConfirm}\n variant=\"secondary\"\n startIcon={<Check />}\n loading={isConfirmButtonLoading}\n >\n {formatMessage({\n id: 'app.utils.publish',\n defaultMessage: 'Publish',\n })}\n </Button>\n }\n />\n );\n};\n\nexport { ConfirmDialogPublishAll, ConfirmBulkActionDialog };\nexport type { ConfirmDialogPublishAllProps, ConfirmBulkActionDialogProps };\n"],"names":["ConfirmBulkActionDialog","onToggleDialog","isOpen","dialogBody","endAction","formatMessage","useIntl","_jsx","Dialog","Root","open","_jsxs","Content","Header","id","defaultMessage","Body","Flex","direction","alignItems","gap","justifyContent","WarningCircle","width","height","fill","Footer","Cancel","Button","fullWidth","onClick","variant","BoldChunk","chunks","Typography","fontWeight","ConfirmDialogPublishAll","isConfirmButtonLoading","onConfirm","selectedEntries","useTable","state","selectedRows","toggleNotification","useNotification","_unstableFormatAPIError","formatAPIError","useAPIErrorHandler","getTranslation","model","schema","useDoc","query","useQueryParams","enableDraftRelationsCount","data","countDraftRelations","isLoading","error","useGetManyDraftRelationCountQuery","documentIds","map","entry","documentId","locale","plugins","i18n","skip","React","useEffect","type","message","_Fragment","textAlign","b","count","entities","length","pluginOptions","textColor","em","Emphasis","startIcon","Check","loading"],"mappings":"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"}
1
+ {"version":3,"file":"ConfirmBulkActionDialog.js","sources":["../../../../../../admin/src/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n useTable,\n useNotification,\n useAPIErrorHandler,\n useQueryParams,\n} from '@strapi/admin/strapi-admin';\nimport { Button, Flex, Dialog, Typography } from '@strapi/design-system';\nimport { Check, WarningCircle } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\n\nimport { useDoc } from '../../../../hooks/useDocument';\nimport { useGetManyDraftRelationCountQuery } from '../../../../services/documents';\nimport { getTranslation } from '../../../../utils/translations';\n\nimport { Emphasis } from './Actions';\n\ninterface ConfirmBulkActionDialogProps {\n endAction: React.ReactNode;\n onToggleDialog: () => void;\n isOpen?: boolean;\n dialogBody: React.ReactNode;\n}\n\nconst ConfirmBulkActionDialog = ({\n onToggleDialog,\n isOpen = false,\n dialogBody,\n endAction,\n}: ConfirmBulkActionDialogProps) => {\n const { formatMessage } = useIntl();\n\n return (\n <Dialog.Root open={isOpen}>\n <Dialog.Content>\n <Dialog.Header>\n {formatMessage({\n id: 'app.components.ConfirmDialog.title',\n defaultMessage: 'Confirmation',\n })}\n </Dialog.Header>\n <Dialog.Body>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={2}>\n <Flex justifyContent=\"center\">\n <WarningCircle width=\"24px\" height=\"24px\" fill=\"danger600\" />\n </Flex>\n {dialogBody}\n </Flex>\n </Dialog.Body>\n <Dialog.Footer>\n <Dialog.Cancel>\n <Button width={'50%'} onClick={onToggleDialog} variant=\"tertiary\">\n {formatMessage({\n id: 'app.components.Button.cancel',\n defaultMessage: 'Cancel',\n })}\n </Button>\n </Dialog.Cancel>\n {endAction}\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * BoldChunk\n * -----------------------------------------------------------------------------------------------*/\n\nconst BoldChunk = (chunks: React.ReactNode) => <Typography fontWeight=\"bold\">{chunks}</Typography>;\n\n/* -------------------------------------------------------------------------------------------------\n * ConfirmDialogPublishAll\n * -----------------------------------------------------------------------------------------------*/\n\ninterface ConfirmDialogPublishAllProps\n extends Pick<ConfirmBulkActionDialogProps, 'isOpen' | 'onToggleDialog'> {\n isConfirmButtonLoading?: boolean;\n onConfirm: () => void;\n}\n\nconst ConfirmDialogPublishAll = ({\n isOpen,\n onToggleDialog,\n isConfirmButtonLoading = false,\n onConfirm,\n}: ConfirmDialogPublishAllProps) => {\n const { formatMessage } = useIntl();\n const selectedEntries = useTable('ConfirmDialogPublishAll', (state) => state.selectedRows);\n const { toggleNotification } = useNotification();\n const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler(getTranslation);\n const { model, schema } = useDoc();\n const [{ query }] = useQueryParams<{\n plugins?: {\n i18n?: {\n locale?: string;\n };\n };\n }>();\n\n // TODO skipping this for now as there is a bug with the draft relation count that will be worked on separately\n // see RFC \"Count draft relations\" in Notion\n const enableDraftRelationsCount = false;\n\n const {\n data: countDraftRelations = 0,\n isLoading,\n error,\n } = useGetManyDraftRelationCountQuery(\n {\n model,\n documentIds: selectedEntries.map((entry) => entry.documentId),\n locale: query?.plugins?.i18n?.locale,\n },\n {\n skip: !enableDraftRelationsCount || selectedEntries.length === 0,\n }\n );\n\n React.useEffect(() => {\n if (error) {\n toggleNotification({ type: 'danger', message: formatAPIError(error) });\n }\n }, [error, formatAPIError, toggleNotification]);\n\n if (error) {\n return null;\n }\n\n return (\n <ConfirmBulkActionDialog\n isOpen={isOpen && !isLoading}\n onToggleDialog={onToggleDialog}\n dialogBody={\n <>\n <Typography id=\"confirm-description\" textAlign=\"center\">\n {countDraftRelations > 0 &&\n formatMessage(\n {\n id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),\n defaultMessage:\n '<b>{count} {count, plural, one { relation } other { relations } } out of {entities} { entities, plural, one { entry } other { entries } } {count, plural, one { is } other { are } }</b> not published yet and might lead to unexpected behavior. ',\n },\n {\n b: BoldChunk,\n count: countDraftRelations,\n entities: selectedEntries.length,\n }\n )}\n {formatMessage({\n id: getTranslation('popUpWarning.bodyMessage.contentType.publish.all'),\n defaultMessage: 'Are you sure you want to publish these entries?',\n })}\n </Typography>\n {schema?.pluginOptions &&\n 'i18n' in schema.pluginOptions &&\n schema?.pluginOptions.i18n && (\n <Typography textColor=\"danger500\" textAlign=\"center\">\n {formatMessage(\n {\n id: getTranslation('Settings.list.actions.publishAdditionalInfos'),\n defaultMessage:\n 'This will publish the active locale versions <em>(from Internationalization)</em>',\n },\n {\n em: Emphasis,\n }\n )}\n </Typography>\n )}\n </>\n }\n endAction={\n <Button\n width={'50%'}\n onClick={onConfirm}\n variant=\"secondary\"\n startIcon={<Check />}\n loading={isConfirmButtonLoading}\n >\n {formatMessage({\n id: 'app.utils.publish',\n defaultMessage: 'Publish',\n })}\n </Button>\n }\n />\n );\n};\n\nexport { ConfirmDialogPublishAll, ConfirmBulkActionDialog };\nexport type { ConfirmDialogPublishAllProps, ConfirmBulkActionDialogProps };\n"],"names":["ConfirmBulkActionDialog","onToggleDialog","isOpen","dialogBody","endAction","formatMessage","useIntl","_jsx","Dialog","Root","open","_jsxs","Content","Header","id","defaultMessage","Body","Flex","direction","alignItems","gap","justifyContent","WarningCircle","width","height","fill","Footer","Cancel","Button","onClick","variant","BoldChunk","chunks","Typography","fontWeight","ConfirmDialogPublishAll","isConfirmButtonLoading","onConfirm","selectedEntries","useTable","state","selectedRows","toggleNotification","useNotification","_unstableFormatAPIError","formatAPIError","useAPIErrorHandler","getTranslation","model","schema","useDoc","query","useQueryParams","enableDraftRelationsCount","data","countDraftRelations","isLoading","error","useGetManyDraftRelationCountQuery","documentIds","map","entry","documentId","locale","plugins","i18n","skip","React","useEffect","type","message","_Fragment","textAlign","b","count","entities","length","pluginOptions","textColor","em","Emphasis","startIcon","Check","loading"],"mappings":"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"}
@@ -43,7 +43,7 @@ const ConfirmBulkActionDialog = ({ onToggleDialog, isOpen = false, dialogBody, e
43
43
  children: [
44
44
  /*#__PURE__*/ jsx(Dialog.Cancel, {
45
45
  children: /*#__PURE__*/ jsx(Button, {
46
- fullWidth: true,
46
+ width: '50%',
47
47
  onClick: onToggleDialog,
48
48
  variant: "tertiary",
49
49
  children: formatMessage({
@@ -133,6 +133,7 @@ const ConfirmDialogPublishAll = ({ isOpen, onToggleDialog, isConfirmButtonLoadin
133
133
  ]
134
134
  }),
135
135
  endAction: /*#__PURE__*/ jsx(Button, {
136
+ width: '50%',
136
137
  onClick: onConfirm,
137
138
  variant: "secondary",
138
139
  startIcon: /*#__PURE__*/ jsx(Check, {}),
@@ -1 +1 @@
1
- {"version":3,"file":"ConfirmBulkActionDialog.mjs","sources":["../../../../../../admin/src/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n useTable,\n useNotification,\n useAPIErrorHandler,\n useQueryParams,\n} from '@strapi/admin/strapi-admin';\nimport { Button, Flex, Dialog, Typography } from '@strapi/design-system';\nimport { Check, WarningCircle } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\n\nimport { useDoc } from '../../../../hooks/useDocument';\nimport { useGetManyDraftRelationCountQuery } from '../../../../services/documents';\nimport { getTranslation } from '../../../../utils/translations';\n\nimport { Emphasis } from './Actions';\n\ninterface ConfirmBulkActionDialogProps {\n endAction: React.ReactNode;\n onToggleDialog: () => void;\n isOpen?: boolean;\n dialogBody: React.ReactNode;\n}\n\nconst ConfirmBulkActionDialog = ({\n onToggleDialog,\n isOpen = false,\n dialogBody,\n endAction,\n}: ConfirmBulkActionDialogProps) => {\n const { formatMessage } = useIntl();\n\n return (\n <Dialog.Root open={isOpen}>\n <Dialog.Content>\n <Dialog.Header>\n {formatMessage({\n id: 'app.components.ConfirmDialog.title',\n defaultMessage: 'Confirmation',\n })}\n </Dialog.Header>\n <Dialog.Body>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={2}>\n <Flex justifyContent=\"center\">\n <WarningCircle width=\"24px\" height=\"24px\" fill=\"danger600\" />\n </Flex>\n {dialogBody}\n </Flex>\n </Dialog.Body>\n <Dialog.Footer>\n <Dialog.Cancel>\n <Button fullWidth onClick={onToggleDialog} variant=\"tertiary\">\n {formatMessage({\n id: 'app.components.Button.cancel',\n defaultMessage: 'Cancel',\n })}\n </Button>\n </Dialog.Cancel>\n {endAction}\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * BoldChunk\n * -----------------------------------------------------------------------------------------------*/\n\nconst BoldChunk = (chunks: React.ReactNode) => <Typography fontWeight=\"bold\">{chunks}</Typography>;\n\n/* -------------------------------------------------------------------------------------------------\n * ConfirmDialogPublishAll\n * -----------------------------------------------------------------------------------------------*/\n\ninterface ConfirmDialogPublishAllProps\n extends Pick<ConfirmBulkActionDialogProps, 'isOpen' | 'onToggleDialog'> {\n isConfirmButtonLoading?: boolean;\n onConfirm: () => void;\n}\n\nconst ConfirmDialogPublishAll = ({\n isOpen,\n onToggleDialog,\n isConfirmButtonLoading = false,\n onConfirm,\n}: ConfirmDialogPublishAllProps) => {\n const { formatMessage } = useIntl();\n const selectedEntries = useTable('ConfirmDialogPublishAll', (state) => state.selectedRows);\n const { toggleNotification } = useNotification();\n const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler(getTranslation);\n const { model, schema } = useDoc();\n const [{ query }] = useQueryParams<{\n plugins?: {\n i18n?: {\n locale?: string;\n };\n };\n }>();\n\n // TODO skipping this for now as there is a bug with the draft relation count that will be worked on separately\n // see RFC \"Count draft relations\" in Notion\n const enableDraftRelationsCount = false;\n\n const {\n data: countDraftRelations = 0,\n isLoading,\n error,\n } = useGetManyDraftRelationCountQuery(\n {\n model,\n documentIds: selectedEntries.map((entry) => entry.documentId),\n locale: query?.plugins?.i18n?.locale,\n },\n {\n skip: !enableDraftRelationsCount || selectedEntries.length === 0,\n }\n );\n\n React.useEffect(() => {\n if (error) {\n toggleNotification({ type: 'danger', message: formatAPIError(error) });\n }\n }, [error, formatAPIError, toggleNotification]);\n\n if (error) {\n return null;\n }\n\n return (\n <ConfirmBulkActionDialog\n isOpen={isOpen && !isLoading}\n onToggleDialog={onToggleDialog}\n dialogBody={\n <>\n <Typography id=\"confirm-description\" textAlign=\"center\">\n {countDraftRelations > 0 &&\n formatMessage(\n {\n id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),\n defaultMessage:\n '<b>{count} {count, plural, one { relation } other { relations } } out of {entities} { entities, plural, one { entry } other { entries } } {count, plural, one { is } other { are } }</b> not published yet and might lead to unexpected behavior. ',\n },\n {\n b: BoldChunk,\n count: countDraftRelations,\n entities: selectedEntries.length,\n }\n )}\n {formatMessage({\n id: getTranslation('popUpWarning.bodyMessage.contentType.publish.all'),\n defaultMessage: 'Are you sure you want to publish these entries?',\n })}\n </Typography>\n {schema?.pluginOptions &&\n 'i18n' in schema.pluginOptions &&\n schema?.pluginOptions.i18n && (\n <Typography textColor=\"danger500\" textAlign=\"center\">\n {formatMessage(\n {\n id: getTranslation('Settings.list.actions.publishAdditionalInfos'),\n defaultMessage:\n 'This will publish the active locale versions <em>(from Internationalization)</em>',\n },\n {\n em: Emphasis,\n }\n )}\n </Typography>\n )}\n </>\n }\n endAction={\n <Button\n onClick={onConfirm}\n variant=\"secondary\"\n startIcon={<Check />}\n loading={isConfirmButtonLoading}\n >\n {formatMessage({\n id: 'app.utils.publish',\n defaultMessage: 'Publish',\n })}\n </Button>\n }\n />\n );\n};\n\nexport { ConfirmDialogPublishAll, ConfirmBulkActionDialog };\nexport type { ConfirmDialogPublishAllProps, ConfirmBulkActionDialogProps };\n"],"names":["ConfirmBulkActionDialog","onToggleDialog","isOpen","dialogBody","endAction","formatMessage","useIntl","_jsx","Dialog","Root","open","_jsxs","Content","Header","id","defaultMessage","Body","Flex","direction","alignItems","gap","justifyContent","WarningCircle","width","height","fill","Footer","Cancel","Button","fullWidth","onClick","variant","BoldChunk","chunks","Typography","fontWeight","ConfirmDialogPublishAll","isConfirmButtonLoading","onConfirm","selectedEntries","useTable","state","selectedRows","toggleNotification","useNotification","_unstableFormatAPIError","formatAPIError","useAPIErrorHandler","getTranslation","model","schema","useDoc","query","useQueryParams","enableDraftRelationsCount","data","countDraftRelations","isLoading","error","useGetManyDraftRelationCountQuery","documentIds","map","entry","documentId","locale","plugins","i18n","skip","React","useEffect","type","message","_Fragment","textAlign","b","count","entities","length","pluginOptions","textColor","em","Emphasis","startIcon","Check","loading"],"mappings":"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"}
1
+ {"version":3,"file":"ConfirmBulkActionDialog.mjs","sources":["../../../../../../admin/src/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n useTable,\n useNotification,\n useAPIErrorHandler,\n useQueryParams,\n} from '@strapi/admin/strapi-admin';\nimport { Button, Flex, Dialog, Typography } from '@strapi/design-system';\nimport { Check, WarningCircle } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\n\nimport { useDoc } from '../../../../hooks/useDocument';\nimport { useGetManyDraftRelationCountQuery } from '../../../../services/documents';\nimport { getTranslation } from '../../../../utils/translations';\n\nimport { Emphasis } from './Actions';\n\ninterface ConfirmBulkActionDialogProps {\n endAction: React.ReactNode;\n onToggleDialog: () => void;\n isOpen?: boolean;\n dialogBody: React.ReactNode;\n}\n\nconst ConfirmBulkActionDialog = ({\n onToggleDialog,\n isOpen = false,\n dialogBody,\n endAction,\n}: ConfirmBulkActionDialogProps) => {\n const { formatMessage } = useIntl();\n\n return (\n <Dialog.Root open={isOpen}>\n <Dialog.Content>\n <Dialog.Header>\n {formatMessage({\n id: 'app.components.ConfirmDialog.title',\n defaultMessage: 'Confirmation',\n })}\n </Dialog.Header>\n <Dialog.Body>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={2}>\n <Flex justifyContent=\"center\">\n <WarningCircle width=\"24px\" height=\"24px\" fill=\"danger600\" />\n </Flex>\n {dialogBody}\n </Flex>\n </Dialog.Body>\n <Dialog.Footer>\n <Dialog.Cancel>\n <Button width={'50%'} onClick={onToggleDialog} variant=\"tertiary\">\n {formatMessage({\n id: 'app.components.Button.cancel',\n defaultMessage: 'Cancel',\n })}\n </Button>\n </Dialog.Cancel>\n {endAction}\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * BoldChunk\n * -----------------------------------------------------------------------------------------------*/\n\nconst BoldChunk = (chunks: React.ReactNode) => <Typography fontWeight=\"bold\">{chunks}</Typography>;\n\n/* -------------------------------------------------------------------------------------------------\n * ConfirmDialogPublishAll\n * -----------------------------------------------------------------------------------------------*/\n\ninterface ConfirmDialogPublishAllProps\n extends Pick<ConfirmBulkActionDialogProps, 'isOpen' | 'onToggleDialog'> {\n isConfirmButtonLoading?: boolean;\n onConfirm: () => void;\n}\n\nconst ConfirmDialogPublishAll = ({\n isOpen,\n onToggleDialog,\n isConfirmButtonLoading = false,\n onConfirm,\n}: ConfirmDialogPublishAllProps) => {\n const { formatMessage } = useIntl();\n const selectedEntries = useTable('ConfirmDialogPublishAll', (state) => state.selectedRows);\n const { toggleNotification } = useNotification();\n const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler(getTranslation);\n const { model, schema } = useDoc();\n const [{ query }] = useQueryParams<{\n plugins?: {\n i18n?: {\n locale?: string;\n };\n };\n }>();\n\n // TODO skipping this for now as there is a bug with the draft relation count that will be worked on separately\n // see RFC \"Count draft relations\" in Notion\n const enableDraftRelationsCount = false;\n\n const {\n data: countDraftRelations = 0,\n isLoading,\n error,\n } = useGetManyDraftRelationCountQuery(\n {\n model,\n documentIds: selectedEntries.map((entry) => entry.documentId),\n locale: query?.plugins?.i18n?.locale,\n },\n {\n skip: !enableDraftRelationsCount || selectedEntries.length === 0,\n }\n );\n\n React.useEffect(() => {\n if (error) {\n toggleNotification({ type: 'danger', message: formatAPIError(error) });\n }\n }, [error, formatAPIError, toggleNotification]);\n\n if (error) {\n return null;\n }\n\n return (\n <ConfirmBulkActionDialog\n isOpen={isOpen && !isLoading}\n onToggleDialog={onToggleDialog}\n dialogBody={\n <>\n <Typography id=\"confirm-description\" textAlign=\"center\">\n {countDraftRelations > 0 &&\n formatMessage(\n {\n id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),\n defaultMessage:\n '<b>{count} {count, plural, one { relation } other { relations } } out of {entities} { entities, plural, one { entry } other { entries } } {count, plural, one { is } other { are } }</b> not published yet and might lead to unexpected behavior. ',\n },\n {\n b: BoldChunk,\n count: countDraftRelations,\n entities: selectedEntries.length,\n }\n )}\n {formatMessage({\n id: getTranslation('popUpWarning.bodyMessage.contentType.publish.all'),\n defaultMessage: 'Are you sure you want to publish these entries?',\n })}\n </Typography>\n {schema?.pluginOptions &&\n 'i18n' in schema.pluginOptions &&\n schema?.pluginOptions.i18n && (\n <Typography textColor=\"danger500\" textAlign=\"center\">\n {formatMessage(\n {\n id: getTranslation('Settings.list.actions.publishAdditionalInfos'),\n defaultMessage:\n 'This will publish the active locale versions <em>(from Internationalization)</em>',\n },\n {\n em: Emphasis,\n }\n )}\n </Typography>\n )}\n </>\n }\n endAction={\n <Button\n width={'50%'}\n onClick={onConfirm}\n variant=\"secondary\"\n startIcon={<Check />}\n loading={isConfirmButtonLoading}\n >\n {formatMessage({\n id: 'app.utils.publish',\n defaultMessage: 'Publish',\n })}\n </Button>\n }\n />\n );\n};\n\nexport { ConfirmDialogPublishAll, ConfirmBulkActionDialog };\nexport type { ConfirmDialogPublishAllProps, ConfirmBulkActionDialogProps };\n"],"names":["ConfirmBulkActionDialog","onToggleDialog","isOpen","dialogBody","endAction","formatMessage","useIntl","_jsx","Dialog","Root","open","_jsxs","Content","Header","id","defaultMessage","Body","Flex","direction","alignItems","gap","justifyContent","WarningCircle","width","height","fill","Footer","Cancel","Button","onClick","variant","BoldChunk","chunks","Typography","fontWeight","ConfirmDialogPublishAll","isConfirmButtonLoading","onConfirm","selectedEntries","useTable","state","selectedRows","toggleNotification","useNotification","_unstableFormatAPIError","formatAPIError","useAPIErrorHandler","getTranslation","model","schema","useDoc","query","useQueryParams","enableDraftRelationsCount","data","countDraftRelations","isLoading","error","useGetManyDraftRelationCountQuery","documentIds","map","entry","documentId","locale","plugins","i18n","skip","React","useEffect","type","message","_Fragment","textAlign","b","count","entities","length","pluginOptions","textColor","em","Emphasis","startIcon","Check","loading"],"mappings":"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"}
@@ -306,6 +306,7 @@ var en = {
306
306
  "history.restore.success.message": "A past version of the content was restored.",
307
307
  "history.restore.error.message": "Could not restore version.",
308
308
  "validation.error": "There are validation errors in your document. Please fix them before saving.",
309
+ "validation.error.unreadable-required-field": "Your current permissions prevent access to certain required fields. Please request access from an administrator to proceed.",
309
310
  "bulk-publish.edit": "Edit",
310
311
  "widget.last-edited.title": "Last edited entries",
311
312
  "widget.last-edited.single-type": "Single-Type",
@@ -1 +1 @@
1
- {"version":3,"file":"en.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"en.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -302,6 +302,7 @@ var en = {
302
302
  "history.restore.success.message": "A past version of the content was restored.",
303
303
  "history.restore.error.message": "Could not restore version.",
304
304
  "validation.error": "There are validation errors in your document. Please fix them before saving.",
305
+ "validation.error.unreadable-required-field": "Your current permissions prevent access to certain required fields. Please request access from an administrator to proceed.",
305
306
  "bulk-publish.edit": "Edit",
306
307
  "widget.last-edited.title": "Last edited entries",
307
308
  "widget.last-edited.single-type": "Single-Type",
@@ -1 +1 @@
1
- {"version":3,"file":"en.json.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"en.json.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -64,12 +64,15 @@ const createLifecyclesService = ({ strapi: strapi1 })=>{
64
64
  const serviceUtils = utils.createServiceUtils({
65
65
  strapi: strapi1
66
66
  });
67
+ const { persistTablesWithPrefix } = strapi1.service('admin::persist-tables');
67
68
  return {
68
69
  async bootstrap () {
69
70
  // Prevent initializing the service twice
70
71
  if (state.isInitialized) {
71
72
  return;
72
73
  }
74
+ // Avoid data loss in case users temporarily don't have a license
75
+ await persistTablesWithPrefix('strapi_history_versions');
73
76
  strapi1.documents.use(async (context, next)=>{
74
77
  const result = await next();
75
78
  if (!shouldCreateHistoryVersion(context)) {
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycles.js","sources":["../../../../server/src/history/services/lifecycles.ts"],"sourcesContent":["import type { Core, Modules, UID } from '@strapi/types';\nimport { contentTypes } from '@strapi/utils';\n\nimport { omit, castArray } from 'lodash/fp';\n\nimport { scheduleJob } from 'node-schedule';\n\nimport { getService } from '../utils';\nimport { FIELDS_TO_IGNORE, HISTORY_VERSION_UID } from '../constants';\n\nimport type { CreateHistoryVersion } from '../../../../shared/contracts/history-versions';\nimport { createServiceUtils } from './utils';\n\n/**\n * Filters out actions that should not create a history version.\n */\nconst shouldCreateHistoryVersion = (\n context: Modules.Documents.Middleware.Context\n): context is Modules.Documents.Middleware.Context & {\n action: 'create' | 'update' | 'clone' | 'publish' | 'unpublish' | 'discardDraft';\n contentType: UID.CollectionType;\n} => {\n // Ignore requests that are not related to the content manager\n if (!strapi.requestContext.get()?.request.url.startsWith('/content-manager')) {\n return false;\n }\n\n // NOTE: cannot do type narrowing with array includes\n if (\n context.action !== 'create' &&\n context.action !== 'update' &&\n context.action !== 'clone' &&\n context.action !== 'publish' &&\n context.action !== 'unpublish' &&\n context.action !== 'discardDraft'\n ) {\n return false;\n }\n\n /**\n * When a document is published, the draft version of the document is also updated.\n * It creates confusion for users because they see two history versions each publish action.\n * To avoid this, we silence the update action during a publish request,\n * so that they only see the published version of the document in the history.\n */\n if (\n context.action === 'update' &&\n strapi.requestContext.get()?.request.url.endsWith('/actions/publish')\n ) {\n return false;\n }\n\n // Ignore content types not created by the user\n if (!context.contentType.uid.startsWith('api::')) {\n return false;\n }\n\n return true;\n};\n\n/**\n * Returns the content type schema (and its components schemas).\n * Used to determine if changes were made in the content type builder since a history version was created.\n * And therefore which fields can be restored and which cannot.\n */\nconst getSchemas = (uid: UID.CollectionType) => {\n const attributesSchema = strapi.getModel(uid).attributes;\n\n // TODO: Handle nested components\n const componentsSchemas = Object.keys(attributesSchema).reduce(\n (currentComponentSchemas, key) => {\n const fieldSchema = attributesSchema[key];\n\n if (fieldSchema.type === 'component') {\n const componentSchema = strapi.getModel(fieldSchema.component).attributes;\n return {\n ...currentComponentSchemas,\n [fieldSchema.component]: componentSchema,\n };\n }\n\n // Ignore anything that's not a component\n return currentComponentSchemas;\n },\n {} as CreateHistoryVersion['componentsSchemas']\n );\n\n return {\n schema: omit(FIELDS_TO_IGNORE, attributesSchema) as CreateHistoryVersion['schema'],\n componentsSchemas,\n };\n};\n\nconst createLifecyclesService = ({ strapi }: { strapi: Core.Strapi }) => {\n const state: {\n deleteExpiredJob: ReturnType<typeof scheduleJob> | null;\n isInitialized: boolean;\n } = {\n deleteExpiredJob: null,\n isInitialized: false,\n };\n\n const serviceUtils = createServiceUtils({ strapi });\n\n return {\n async bootstrap() {\n // Prevent initializing the service twice\n if (state.isInitialized) {\n return;\n }\n\n strapi.documents.use(async (context, next) => {\n const result = (await next()) as any;\n\n if (!shouldCreateHistoryVersion(context)) {\n return result;\n }\n\n // On create/clone actions, the documentId is not available before creating the action is executed\n const documentId =\n context.action === 'create' || context.action === 'clone'\n ? result.documentId\n : context.params.documentId;\n\n // Apply default locale if not available in the request\n const defaultLocale = await serviceUtils.getDefaultLocale();\n const locales = castArray(context.params?.locale || defaultLocale);\n if (!locales.length) {\n return result;\n }\n\n // All schemas related to the content type\n const uid = context.contentType.uid;\n const schemas = getSchemas(uid);\n const model = strapi.getModel(uid);\n\n const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);\n\n // Find all affected entries\n const localeEntries = await strapi.db.query(uid).findMany({\n where: {\n documentId,\n ...(isLocalizedContentType ? { locale: { $in: locales } } : {}),\n ...(contentTypes.hasDraftAndPublish(strapi.contentTypes[uid])\n ? { publishedAt: null }\n : {}),\n },\n populate: serviceUtils.getDeepPopulate(uid, true /* use database syntax */),\n });\n\n await strapi.db.transaction(async ({ onCommit }) => {\n // .createVersion() is executed asynchronously,\n // onCommit prevents creating a history version\n // when the transaction has already been committed\n onCommit(async () => {\n for (const entry of localeEntries) {\n const status = await serviceUtils.getVersionStatus(uid, entry);\n\n await getService(strapi, 'history').createVersion({\n contentType: uid,\n data: omit(FIELDS_TO_IGNORE, entry) as Modules.Documents.AnyDocument,\n relatedDocumentId: documentId,\n locale: entry.locale,\n status,\n ...schemas,\n });\n }\n });\n });\n\n return result;\n });\n\n // Schedule a job to delete expired history versions every day at midnight\n state.deleteExpiredJob = scheduleJob('historyDaily', '0 0 * * *', () => {\n const retentionDaysInMilliseconds = serviceUtils.getRetentionDays() * 24 * 60 * 60 * 1000;\n const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);\n\n strapi.db\n .query(HISTORY_VERSION_UID)\n .deleteMany({\n where: {\n created_at: {\n $lt: expirationDate,\n },\n },\n })\n .catch((error) => {\n if (error instanceof Error) {\n strapi.log.error('Error deleting expired history versions', error.message);\n }\n });\n });\n\n state.isInitialized = true;\n },\n\n async destroy() {\n if (state.deleteExpiredJob) {\n state.deleteExpiredJob.cancel();\n }\n },\n };\n};\n\nexport { createLifecyclesService };\n"],"names":["shouldCreateHistoryVersion","context","strapi","requestContext","get","request","url","startsWith","action","endsWith","contentType","uid","getSchemas","attributesSchema","getModel","attributes","componentsSchemas","Object","keys","reduce","currentComponentSchemas","key","fieldSchema","type","componentSchema","component","schema","omit","FIELDS_TO_IGNORE","createLifecyclesService","state","deleteExpiredJob","isInitialized","serviceUtils","createServiceUtils","bootstrap","documents","use","next","result","documentId","params","defaultLocale","getDefaultLocale","locales","castArray","locale","length","schemas","model","isLocalizedContentType","localeEntries","db","query","findMany","where","$in","contentTypes","hasDraftAndPublish","publishedAt","populate","getDeepPopulate","transaction","onCommit","entry","status","getVersionStatus","getService","createVersion","data","relatedDocumentId","scheduleJob","retentionDaysInMilliseconds","getRetentionDays","expirationDate","Date","now","HISTORY_VERSION_UID","deleteMany","created_at","$lt","catch","error","Error","log","message","destroy","cancel"],"mappings":"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"}
1
+ {"version":3,"file":"lifecycles.js","sources":["../../../../server/src/history/services/lifecycles.ts"],"sourcesContent":["import type { Core, Modules, UID } from '@strapi/types';\nimport { contentTypes } from '@strapi/utils';\n\nimport { omit, castArray } from 'lodash/fp';\n\nimport { scheduleJob } from 'node-schedule';\n\nimport { getService } from '../utils';\nimport { FIELDS_TO_IGNORE, HISTORY_VERSION_UID } from '../constants';\n\nimport type { CreateHistoryVersion } from '../../../../shared/contracts/history-versions';\nimport { createServiceUtils } from './utils';\n\n/**\n * Filters out actions that should not create a history version.\n */\nconst shouldCreateHistoryVersion = (\n context: Modules.Documents.Middleware.Context\n): context is Modules.Documents.Middleware.Context & {\n action: 'create' | 'update' | 'clone' | 'publish' | 'unpublish' | 'discardDraft';\n contentType: UID.CollectionType;\n} => {\n // Ignore requests that are not related to the content manager\n if (!strapi.requestContext.get()?.request.url.startsWith('/content-manager')) {\n return false;\n }\n\n // NOTE: cannot do type narrowing with array includes\n if (\n context.action !== 'create' &&\n context.action !== 'update' &&\n context.action !== 'clone' &&\n context.action !== 'publish' &&\n context.action !== 'unpublish' &&\n context.action !== 'discardDraft'\n ) {\n return false;\n }\n\n /**\n * When a document is published, the draft version of the document is also updated.\n * It creates confusion for users because they see two history versions each publish action.\n * To avoid this, we silence the update action during a publish request,\n * so that they only see the published version of the document in the history.\n */\n if (\n context.action === 'update' &&\n strapi.requestContext.get()?.request.url.endsWith('/actions/publish')\n ) {\n return false;\n }\n\n // Ignore content types not created by the user\n if (!context.contentType.uid.startsWith('api::')) {\n return false;\n }\n\n return true;\n};\n\n/**\n * Returns the content type schema (and its components schemas).\n * Used to determine if changes were made in the content type builder since a history version was created.\n * And therefore which fields can be restored and which cannot.\n */\nconst getSchemas = (uid: UID.CollectionType) => {\n const attributesSchema = strapi.getModel(uid).attributes;\n\n // TODO: Handle nested components\n const componentsSchemas = Object.keys(attributesSchema).reduce(\n (currentComponentSchemas, key) => {\n const fieldSchema = attributesSchema[key];\n\n if (fieldSchema.type === 'component') {\n const componentSchema = strapi.getModel(fieldSchema.component).attributes;\n return {\n ...currentComponentSchemas,\n [fieldSchema.component]: componentSchema,\n };\n }\n\n // Ignore anything that's not a component\n return currentComponentSchemas;\n },\n {} as CreateHistoryVersion['componentsSchemas']\n );\n\n return {\n schema: omit(FIELDS_TO_IGNORE, attributesSchema) as CreateHistoryVersion['schema'],\n componentsSchemas,\n };\n};\n\nconst createLifecyclesService = ({ strapi }: { strapi: Core.Strapi }) => {\n const state: {\n deleteExpiredJob: ReturnType<typeof scheduleJob> | null;\n isInitialized: boolean;\n } = {\n deleteExpiredJob: null,\n isInitialized: false,\n };\n\n const serviceUtils = createServiceUtils({ strapi });\n const { persistTablesWithPrefix } = strapi.service('admin::persist-tables');\n\n return {\n async bootstrap() {\n // Prevent initializing the service twice\n if (state.isInitialized) {\n return;\n }\n\n // Avoid data loss in case users temporarily don't have a license\n await persistTablesWithPrefix('strapi_history_versions');\n\n strapi.documents.use(async (context, next) => {\n const result = (await next()) as any;\n\n if (!shouldCreateHistoryVersion(context)) {\n return result;\n }\n\n // On create/clone actions, the documentId is not available before creating the action is executed\n const documentId =\n context.action === 'create' || context.action === 'clone'\n ? result.documentId\n : context.params.documentId;\n\n // Apply default locale if not available in the request\n const defaultLocale = await serviceUtils.getDefaultLocale();\n const locales = castArray(context.params?.locale || defaultLocale);\n if (!locales.length) {\n return result;\n }\n\n // All schemas related to the content type\n const uid = context.contentType.uid;\n const schemas = getSchemas(uid);\n const model = strapi.getModel(uid);\n\n const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);\n\n // Find all affected entries\n const localeEntries = await strapi.db.query(uid).findMany({\n where: {\n documentId,\n ...(isLocalizedContentType ? { locale: { $in: locales } } : {}),\n ...(contentTypes.hasDraftAndPublish(strapi.contentTypes[uid])\n ? { publishedAt: null }\n : {}),\n },\n populate: serviceUtils.getDeepPopulate(uid, true /* use database syntax */),\n });\n\n await strapi.db.transaction(async ({ onCommit }) => {\n // .createVersion() is executed asynchronously,\n // onCommit prevents creating a history version\n // when the transaction has already been committed\n onCommit(async () => {\n for (const entry of localeEntries) {\n const status = await serviceUtils.getVersionStatus(uid, entry);\n\n await getService(strapi, 'history').createVersion({\n contentType: uid,\n data: omit(FIELDS_TO_IGNORE, entry) as Modules.Documents.AnyDocument,\n relatedDocumentId: documentId,\n locale: entry.locale,\n status,\n ...schemas,\n });\n }\n });\n });\n\n return result;\n });\n\n // Schedule a job to delete expired history versions every day at midnight\n state.deleteExpiredJob = scheduleJob('historyDaily', '0 0 * * *', () => {\n const retentionDaysInMilliseconds = serviceUtils.getRetentionDays() * 24 * 60 * 60 * 1000;\n const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);\n\n strapi.db\n .query(HISTORY_VERSION_UID)\n .deleteMany({\n where: {\n created_at: {\n $lt: expirationDate,\n },\n },\n })\n .catch((error) => {\n if (error instanceof Error) {\n strapi.log.error('Error deleting expired history versions', error.message);\n }\n });\n });\n\n state.isInitialized = true;\n },\n\n async destroy() {\n if (state.deleteExpiredJob) {\n state.deleteExpiredJob.cancel();\n }\n },\n };\n};\n\nexport { createLifecyclesService };\n"],"names":["shouldCreateHistoryVersion","context","strapi","requestContext","get","request","url","startsWith","action","endsWith","contentType","uid","getSchemas","attributesSchema","getModel","attributes","componentsSchemas","Object","keys","reduce","currentComponentSchemas","key","fieldSchema","type","componentSchema","component","schema","omit","FIELDS_TO_IGNORE","createLifecyclesService","state","deleteExpiredJob","isInitialized","serviceUtils","createServiceUtils","persistTablesWithPrefix","service","bootstrap","documents","use","next","result","documentId","params","defaultLocale","getDefaultLocale","locales","castArray","locale","length","schemas","model","isLocalizedContentType","localeEntries","db","query","findMany","where","$in","contentTypes","hasDraftAndPublish","publishedAt","populate","getDeepPopulate","transaction","onCommit","entry","status","getVersionStatus","getService","createVersion","data","relatedDocumentId","scheduleJob","retentionDaysInMilliseconds","getRetentionDays","expirationDate","Date","now","HISTORY_VERSION_UID","deleteMany","created_at","$lt","catch","error","Error","log","message","destroy","cancel"],"mappings":"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"}
@@ -62,12 +62,15 @@ const createLifecyclesService = ({ strapi: strapi1 })=>{
62
62
  const serviceUtils = createServiceUtils({
63
63
  strapi: strapi1
64
64
  });
65
+ const { persistTablesWithPrefix } = strapi1.service('admin::persist-tables');
65
66
  return {
66
67
  async bootstrap () {
67
68
  // Prevent initializing the service twice
68
69
  if (state.isInitialized) {
69
70
  return;
70
71
  }
72
+ // Avoid data loss in case users temporarily don't have a license
73
+ await persistTablesWithPrefix('strapi_history_versions');
71
74
  strapi1.documents.use(async (context, next)=>{
72
75
  const result = await next();
73
76
  if (!shouldCreateHistoryVersion(context)) {
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycles.mjs","sources":["../../../../server/src/history/services/lifecycles.ts"],"sourcesContent":["import type { Core, Modules, UID } from '@strapi/types';\nimport { contentTypes } from '@strapi/utils';\n\nimport { omit, castArray } from 'lodash/fp';\n\nimport { scheduleJob } from 'node-schedule';\n\nimport { getService } from '../utils';\nimport { FIELDS_TO_IGNORE, HISTORY_VERSION_UID } from '../constants';\n\nimport type { CreateHistoryVersion } from '../../../../shared/contracts/history-versions';\nimport { createServiceUtils } from './utils';\n\n/**\n * Filters out actions that should not create a history version.\n */\nconst shouldCreateHistoryVersion = (\n context: Modules.Documents.Middleware.Context\n): context is Modules.Documents.Middleware.Context & {\n action: 'create' | 'update' | 'clone' | 'publish' | 'unpublish' | 'discardDraft';\n contentType: UID.CollectionType;\n} => {\n // Ignore requests that are not related to the content manager\n if (!strapi.requestContext.get()?.request.url.startsWith('/content-manager')) {\n return false;\n }\n\n // NOTE: cannot do type narrowing with array includes\n if (\n context.action !== 'create' &&\n context.action !== 'update' &&\n context.action !== 'clone' &&\n context.action !== 'publish' &&\n context.action !== 'unpublish' &&\n context.action !== 'discardDraft'\n ) {\n return false;\n }\n\n /**\n * When a document is published, the draft version of the document is also updated.\n * It creates confusion for users because they see two history versions each publish action.\n * To avoid this, we silence the update action during a publish request,\n * so that they only see the published version of the document in the history.\n */\n if (\n context.action === 'update' &&\n strapi.requestContext.get()?.request.url.endsWith('/actions/publish')\n ) {\n return false;\n }\n\n // Ignore content types not created by the user\n if (!context.contentType.uid.startsWith('api::')) {\n return false;\n }\n\n return true;\n};\n\n/**\n * Returns the content type schema (and its components schemas).\n * Used to determine if changes were made in the content type builder since a history version was created.\n * And therefore which fields can be restored and which cannot.\n */\nconst getSchemas = (uid: UID.CollectionType) => {\n const attributesSchema = strapi.getModel(uid).attributes;\n\n // TODO: Handle nested components\n const componentsSchemas = Object.keys(attributesSchema).reduce(\n (currentComponentSchemas, key) => {\n const fieldSchema = attributesSchema[key];\n\n if (fieldSchema.type === 'component') {\n const componentSchema = strapi.getModel(fieldSchema.component).attributes;\n return {\n ...currentComponentSchemas,\n [fieldSchema.component]: componentSchema,\n };\n }\n\n // Ignore anything that's not a component\n return currentComponentSchemas;\n },\n {} as CreateHistoryVersion['componentsSchemas']\n );\n\n return {\n schema: omit(FIELDS_TO_IGNORE, attributesSchema) as CreateHistoryVersion['schema'],\n componentsSchemas,\n };\n};\n\nconst createLifecyclesService = ({ strapi }: { strapi: Core.Strapi }) => {\n const state: {\n deleteExpiredJob: ReturnType<typeof scheduleJob> | null;\n isInitialized: boolean;\n } = {\n deleteExpiredJob: null,\n isInitialized: false,\n };\n\n const serviceUtils = createServiceUtils({ strapi });\n\n return {\n async bootstrap() {\n // Prevent initializing the service twice\n if (state.isInitialized) {\n return;\n }\n\n strapi.documents.use(async (context, next) => {\n const result = (await next()) as any;\n\n if (!shouldCreateHistoryVersion(context)) {\n return result;\n }\n\n // On create/clone actions, the documentId is not available before creating the action is executed\n const documentId =\n context.action === 'create' || context.action === 'clone'\n ? result.documentId\n : context.params.documentId;\n\n // Apply default locale if not available in the request\n const defaultLocale = await serviceUtils.getDefaultLocale();\n const locales = castArray(context.params?.locale || defaultLocale);\n if (!locales.length) {\n return result;\n }\n\n // All schemas related to the content type\n const uid = context.contentType.uid;\n const schemas = getSchemas(uid);\n const model = strapi.getModel(uid);\n\n const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);\n\n // Find all affected entries\n const localeEntries = await strapi.db.query(uid).findMany({\n where: {\n documentId,\n ...(isLocalizedContentType ? { locale: { $in: locales } } : {}),\n ...(contentTypes.hasDraftAndPublish(strapi.contentTypes[uid])\n ? { publishedAt: null }\n : {}),\n },\n populate: serviceUtils.getDeepPopulate(uid, true /* use database syntax */),\n });\n\n await strapi.db.transaction(async ({ onCommit }) => {\n // .createVersion() is executed asynchronously,\n // onCommit prevents creating a history version\n // when the transaction has already been committed\n onCommit(async () => {\n for (const entry of localeEntries) {\n const status = await serviceUtils.getVersionStatus(uid, entry);\n\n await getService(strapi, 'history').createVersion({\n contentType: uid,\n data: omit(FIELDS_TO_IGNORE, entry) as Modules.Documents.AnyDocument,\n relatedDocumentId: documentId,\n locale: entry.locale,\n status,\n ...schemas,\n });\n }\n });\n });\n\n return result;\n });\n\n // Schedule a job to delete expired history versions every day at midnight\n state.deleteExpiredJob = scheduleJob('historyDaily', '0 0 * * *', () => {\n const retentionDaysInMilliseconds = serviceUtils.getRetentionDays() * 24 * 60 * 60 * 1000;\n const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);\n\n strapi.db\n .query(HISTORY_VERSION_UID)\n .deleteMany({\n where: {\n created_at: {\n $lt: expirationDate,\n },\n },\n })\n .catch((error) => {\n if (error instanceof Error) {\n strapi.log.error('Error deleting expired history versions', error.message);\n }\n });\n });\n\n state.isInitialized = true;\n },\n\n async destroy() {\n if (state.deleteExpiredJob) {\n state.deleteExpiredJob.cancel();\n }\n },\n };\n};\n\nexport { createLifecyclesService };\n"],"names":["shouldCreateHistoryVersion","context","strapi","requestContext","get","request","url","startsWith","action","endsWith","contentType","uid","getSchemas","attributesSchema","getModel","attributes","componentsSchemas","Object","keys","reduce","currentComponentSchemas","key","fieldSchema","type","componentSchema","component","schema","omit","FIELDS_TO_IGNORE","createLifecyclesService","state","deleteExpiredJob","isInitialized","serviceUtils","createServiceUtils","bootstrap","documents","use","next","result","documentId","params","defaultLocale","getDefaultLocale","locales","castArray","locale","length","schemas","model","isLocalizedContentType","localeEntries","db","query","findMany","where","$in","contentTypes","hasDraftAndPublish","publishedAt","populate","getDeepPopulate","transaction","onCommit","entry","status","getVersionStatus","getService","createVersion","data","relatedDocumentId","scheduleJob","retentionDaysInMilliseconds","getRetentionDays","expirationDate","Date","now","HISTORY_VERSION_UID","deleteMany","created_at","$lt","catch","error","Error","log","message","destroy","cancel"],"mappings":"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"}
1
+ {"version":3,"file":"lifecycles.mjs","sources":["../../../../server/src/history/services/lifecycles.ts"],"sourcesContent":["import type { Core, Modules, UID } from '@strapi/types';\nimport { contentTypes } from '@strapi/utils';\n\nimport { omit, castArray } from 'lodash/fp';\n\nimport { scheduleJob } from 'node-schedule';\n\nimport { getService } from '../utils';\nimport { FIELDS_TO_IGNORE, HISTORY_VERSION_UID } from '../constants';\n\nimport type { CreateHistoryVersion } from '../../../../shared/contracts/history-versions';\nimport { createServiceUtils } from './utils';\n\n/**\n * Filters out actions that should not create a history version.\n */\nconst shouldCreateHistoryVersion = (\n context: Modules.Documents.Middleware.Context\n): context is Modules.Documents.Middleware.Context & {\n action: 'create' | 'update' | 'clone' | 'publish' | 'unpublish' | 'discardDraft';\n contentType: UID.CollectionType;\n} => {\n // Ignore requests that are not related to the content manager\n if (!strapi.requestContext.get()?.request.url.startsWith('/content-manager')) {\n return false;\n }\n\n // NOTE: cannot do type narrowing with array includes\n if (\n context.action !== 'create' &&\n context.action !== 'update' &&\n context.action !== 'clone' &&\n context.action !== 'publish' &&\n context.action !== 'unpublish' &&\n context.action !== 'discardDraft'\n ) {\n return false;\n }\n\n /**\n * When a document is published, the draft version of the document is also updated.\n * It creates confusion for users because they see two history versions each publish action.\n * To avoid this, we silence the update action during a publish request,\n * so that they only see the published version of the document in the history.\n */\n if (\n context.action === 'update' &&\n strapi.requestContext.get()?.request.url.endsWith('/actions/publish')\n ) {\n return false;\n }\n\n // Ignore content types not created by the user\n if (!context.contentType.uid.startsWith('api::')) {\n return false;\n }\n\n return true;\n};\n\n/**\n * Returns the content type schema (and its components schemas).\n * Used to determine if changes were made in the content type builder since a history version was created.\n * And therefore which fields can be restored and which cannot.\n */\nconst getSchemas = (uid: UID.CollectionType) => {\n const attributesSchema = strapi.getModel(uid).attributes;\n\n // TODO: Handle nested components\n const componentsSchemas = Object.keys(attributesSchema).reduce(\n (currentComponentSchemas, key) => {\n const fieldSchema = attributesSchema[key];\n\n if (fieldSchema.type === 'component') {\n const componentSchema = strapi.getModel(fieldSchema.component).attributes;\n return {\n ...currentComponentSchemas,\n [fieldSchema.component]: componentSchema,\n };\n }\n\n // Ignore anything that's not a component\n return currentComponentSchemas;\n },\n {} as CreateHistoryVersion['componentsSchemas']\n );\n\n return {\n schema: omit(FIELDS_TO_IGNORE, attributesSchema) as CreateHistoryVersion['schema'],\n componentsSchemas,\n };\n};\n\nconst createLifecyclesService = ({ strapi }: { strapi: Core.Strapi }) => {\n const state: {\n deleteExpiredJob: ReturnType<typeof scheduleJob> | null;\n isInitialized: boolean;\n } = {\n deleteExpiredJob: null,\n isInitialized: false,\n };\n\n const serviceUtils = createServiceUtils({ strapi });\n const { persistTablesWithPrefix } = strapi.service('admin::persist-tables');\n\n return {\n async bootstrap() {\n // Prevent initializing the service twice\n if (state.isInitialized) {\n return;\n }\n\n // Avoid data loss in case users temporarily don't have a license\n await persistTablesWithPrefix('strapi_history_versions');\n\n strapi.documents.use(async (context, next) => {\n const result = (await next()) as any;\n\n if (!shouldCreateHistoryVersion(context)) {\n return result;\n }\n\n // On create/clone actions, the documentId is not available before creating the action is executed\n const documentId =\n context.action === 'create' || context.action === 'clone'\n ? result.documentId\n : context.params.documentId;\n\n // Apply default locale if not available in the request\n const defaultLocale = await serviceUtils.getDefaultLocale();\n const locales = castArray(context.params?.locale || defaultLocale);\n if (!locales.length) {\n return result;\n }\n\n // All schemas related to the content type\n const uid = context.contentType.uid;\n const schemas = getSchemas(uid);\n const model = strapi.getModel(uid);\n\n const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);\n\n // Find all affected entries\n const localeEntries = await strapi.db.query(uid).findMany({\n where: {\n documentId,\n ...(isLocalizedContentType ? { locale: { $in: locales } } : {}),\n ...(contentTypes.hasDraftAndPublish(strapi.contentTypes[uid])\n ? { publishedAt: null }\n : {}),\n },\n populate: serviceUtils.getDeepPopulate(uid, true /* use database syntax */),\n });\n\n await strapi.db.transaction(async ({ onCommit }) => {\n // .createVersion() is executed asynchronously,\n // onCommit prevents creating a history version\n // when the transaction has already been committed\n onCommit(async () => {\n for (const entry of localeEntries) {\n const status = await serviceUtils.getVersionStatus(uid, entry);\n\n await getService(strapi, 'history').createVersion({\n contentType: uid,\n data: omit(FIELDS_TO_IGNORE, entry) as Modules.Documents.AnyDocument,\n relatedDocumentId: documentId,\n locale: entry.locale,\n status,\n ...schemas,\n });\n }\n });\n });\n\n return result;\n });\n\n // Schedule a job to delete expired history versions every day at midnight\n state.deleteExpiredJob = scheduleJob('historyDaily', '0 0 * * *', () => {\n const retentionDaysInMilliseconds = serviceUtils.getRetentionDays() * 24 * 60 * 60 * 1000;\n const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);\n\n strapi.db\n .query(HISTORY_VERSION_UID)\n .deleteMany({\n where: {\n created_at: {\n $lt: expirationDate,\n },\n },\n })\n .catch((error) => {\n if (error instanceof Error) {\n strapi.log.error('Error deleting expired history versions', error.message);\n }\n });\n });\n\n state.isInitialized = true;\n },\n\n async destroy() {\n if (state.deleteExpiredJob) {\n state.deleteExpiredJob.cancel();\n }\n },\n };\n};\n\nexport { createLifecyclesService };\n"],"names":["shouldCreateHistoryVersion","context","strapi","requestContext","get","request","url","startsWith","action","endsWith","contentType","uid","getSchemas","attributesSchema","getModel","attributes","componentsSchemas","Object","keys","reduce","currentComponentSchemas","key","fieldSchema","type","componentSchema","component","schema","omit","FIELDS_TO_IGNORE","createLifecyclesService","state","deleteExpiredJob","isInitialized","serviceUtils","createServiceUtils","persistTablesWithPrefix","service","bootstrap","documents","use","next","result","documentId","params","defaultLocale","getDefaultLocale","locales","castArray","locale","length","schemas","model","isLocalizedContentType","localeEntries","db","query","findMany","where","$in","contentTypes","hasDraftAndPublish","publishedAt","populate","getDeepPopulate","transaction","onCommit","entry","status","getVersionStatus","getService","createVersion","data","relatedDocumentId","scheduleJob","retentionDaysInMilliseconds","getRetentionDays","expirationDate","Date","now","HISTORY_VERSION_UID","deleteMany","created_at","$lt","catch","error","Error","log","message","destroy","cancel"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycles.d.ts","sourceRoot":"","sources":["../../../../../server/src/history/services/lifecycles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAgB,MAAM,eAAe,CAAC;AA6FxD,QAAA,MAAM,uBAAuB,eAAgB;IAAE,MAAM,EAAE,KAAK,MAAM,CAAA;CAAE;;;CA8GnE,CAAC;AAEF,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
1
+ {"version":3,"file":"lifecycles.d.ts","sourceRoot":"","sources":["../../../../../server/src/history/services/lifecycles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAgB,MAAM,eAAe,CAAC;AA6FxD,QAAA,MAAM,uBAAuB,eAAgB;IAAE,MAAM,EAAE,KAAK,MAAM,CAAA;CAAE;;;CAkHnE,CAAC;AAEF,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strapi/content-manager",
3
- "version": "5.14.0",
3
+ "version": "5.15.0",
4
4
  "description": "A powerful UI to easily manage your data.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -66,14 +66,14 @@
66
66
  "@sindresorhus/slugify": "1.1.0",
67
67
  "@strapi/design-system": "2.0.0-rc.24",
68
68
  "@strapi/icons": "2.0.0-rc.24",
69
- "@strapi/types": "5.14.0",
70
- "@strapi/utils": "5.14.0",
69
+ "@strapi/types": "5.15.0",
70
+ "@strapi/utils": "5.15.0",
71
71
  "codemirror5": "npm:codemirror@^5.65.11",
72
72
  "date-fns": "2.30.0",
73
73
  "fractional-indexing": "3.2.0",
74
74
  "highlight.js": "^10.4.1",
75
75
  "immer": "9.0.21",
76
- "koa": "2.15.4",
76
+ "koa": "2.16.1",
77
77
  "lodash": "4.17.21",
78
78
  "markdown-it": "^13.0.2",
79
79
  "markdown-it-abbr": "^1.0.4",
@@ -102,8 +102,8 @@
102
102
  "yup": "0.32.9"
103
103
  },
104
104
  "devDependencies": {
105
- "@strapi/admin": "5.14.0",
106
- "@strapi/database": "5.14.0",
105
+ "@strapi/admin": "5.15.0",
106
+ "@strapi/database": "5.15.0",
107
107
  "@testing-library/react": "15.0.7",
108
108
  "@types/jest": "29.5.2",
109
109
  "@types/lodash": "^4.14.191",