@strapi/content-releases 5.59.0 → 5.61.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.
@@ -48,8 +48,8 @@ const addColumnToTableHook = ({ displayedHeaders, layout })=>{
48
48
  id: 'content-releases.content-manager.list-view.releases.header',
49
49
  defaultMessage: 'To be released in'
50
50
  },
51
- cellFormatter: (props, _, { model })=>/*#__PURE__*/ jsxRuntime.jsx(ReleaseListCell, {
52
- ...props,
51
+ cellFormatter: (props, _header, { model })=>/*#__PURE__*/ jsxRuntime.jsx(ReleaseListCell, {
52
+ documentId: props.documentId,
53
53
  model: model
54
54
  })
55
55
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ReleaseListCell.js","sources":["../../../admin/src/components/ReleaseListCell.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useTable, useQueryParams } from '@strapi/admin/strapi-admin';\nimport { ListFieldLayout, ListLayout } from '@strapi/content-manager/strapi-admin';\nimport { Box, Popover, Typography, Button, Link } from '@strapi/design-system';\nimport { CaretDown } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\n\nimport { useGetMappedEntriesInReleasesQuery } from '../services/release';\n\nimport type { Modules, UID } from '@strapi/types';\n\n/* -------------------------------------------------------------------------------------------------\n * useReleasesList\n * -----------------------------------------------------------------------------------------------*/\ninterface QueryParams {\n plugins?: {\n i18n?: {\n locale: string;\n };\n };\n}\n\ntype DocumentRow = {\n id: string | number;\n documentId: Modules.Documents.ID;\n};\n\nconst isDocumentRow = (entry: { id: string | number }): entry is DocumentRow => {\n if ('documentId' in entry) {\n return typeof entry.documentId === 'string';\n }\n\n return false;\n};\n\nconst useReleasesList = (contentTypeUid: UID.ContentType, documentId: Modules.Documents.ID) => {\n const listViewData = useTable('ListView', (state) => state.rows);\n const documentIds = listViewData\n .filter((entry) => isDocumentRow(entry))\n .map((entry) => entry.documentId);\n const [{ query }] = useQueryParams();\n const locale = (query as QueryParams)?.plugins?.i18n?.locale || undefined;\n\n const response = useGetMappedEntriesInReleasesQuery(\n { contentTypeUid, documentIds, locale },\n { skip: !contentTypeUid || documentIds.length === 0 }\n );\n\n const mappedEntriesInReleases = response.data || {};\n\n return mappedEntriesInReleases?.[documentId] || [];\n};\n\n/* -------------------------------------------------------------------------------------------------\n * addColumnToTableHook\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AddColumnToTableHookArgs {\n layout: ListLayout;\n displayedHeaders: ListFieldLayout[];\n}\n\nconst addColumnToTableHook = ({ displayedHeaders, layout }: AddColumnToTableHookArgs) => {\n const { options } = layout;\n\n if (!options?.draftAndPublish) {\n return { displayedHeaders, layout };\n }\n\n return {\n displayedHeaders: [\n ...displayedHeaders,\n {\n searchable: false,\n sortable: false,\n name: 'releases',\n label: {\n id: 'content-releases.content-manager.list-view.releases.header',\n defaultMessage: 'To be released in',\n },\n cellFormatter: (\n props: Modules.Documents.AnyDocument,\n _: unknown,\n { model }: { model: UID.ContentType }\n ) => <ReleaseListCell {...props} model={model} />,\n },\n ],\n layout,\n };\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ReleaseListCell\n * -----------------------------------------------------------------------------------------------*/\n\ninterface ReleaseListCellProps extends Modules.Documents.AnyDocument {\n documentId: Modules.Documents.ID;\n model: UID.ContentType;\n}\n\nconst ReleaseListCell = ({ documentId, model }: ReleaseListCellProps) => {\n const releases = useReleasesList(model, documentId);\n const { formatMessage } = useIntl();\n\n return (\n <Popover.Root>\n <Popover.Trigger>\n <Button\n variant=\"ghost\"\n onClick={(e: React.MouseEvent<HTMLElement>) => e.stopPropagation()}\n // TODO: find a way in the DS to define the widht and height of the icon\n endIcon={releases.length > 0 ? <CaretDown width=\"1.2rem\" height=\"1.2rem\" /> : null}\n >\n <Typography\n style={{ maxWidth: '252px', cursor: 'pointer' }}\n textColor=\"neutral800\"\n fontWeight=\"regular\"\n >\n {releases.length > 0\n ? formatMessage(\n {\n id: 'content-releases.content-manager.list-view.releases-number',\n defaultMessage: '{number} {number, plural, one {release} other {releases}}',\n },\n {\n number: releases.length,\n }\n )\n : '-'}\n </Typography>\n </Button>\n </Popover.Trigger>\n <Popover.Content>\n <ul>\n {releases.map(({ id, name }) => (\n <Box key={id} padding={3} tag=\"li\">\n <Link href={`/admin/plugins/content-releases/${id}`} isExternal={false}>\n {name}\n </Link>\n </Box>\n ))}\n </ul>\n </Popover.Content>\n </Popover.Root>\n );\n};\n\nexport { ReleaseListCell, addColumnToTableHook };\nexport type { ReleaseListCellProps };\n"],"names":["isDocumentRow","entry","documentId","useReleasesList","contentTypeUid","listViewData","useTable","state","rows","documentIds","filter","map","query","useQueryParams","locale","plugins","i18n","undefined","response","useGetMappedEntriesInReleasesQuery","skip","length","mappedEntriesInReleases","data","addColumnToTableHook","displayedHeaders","layout","options","draftAndPublish","searchable","sortable","name","label","id","defaultMessage","cellFormatter","props","_","model","_jsx","ReleaseListCell","releases","formatMessage","useIntl","_jsxs","Popover","Root","Trigger","Button","variant","onClick","e","stopPropagation","endIcon","CaretDown","width","height","Typography","style","maxWidth","cursor","textColor","fontWeight","number","Content","ul","Box","padding","tag","Link","href","isExternal"],"mappings":"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"}
1
+ {"version":3,"file":"ReleaseListCell.js","sources":["../../../admin/src/components/ReleaseListCell.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useTable, useQueryParams } from '@strapi/admin/strapi-admin';\nimport { ListCellMeta, ListFieldLayout, ListLayout } from '@strapi/content-manager/strapi-admin';\nimport { Box, Popover, Typography, Button, Link } from '@strapi/design-system';\nimport { CaretDown } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\n\nimport { useGetMappedEntriesInReleasesQuery } from '../services/release';\n\nimport type { Modules, UID } from '@strapi/types';\n\n/* -------------------------------------------------------------------------------------------------\n * useReleasesList\n * -----------------------------------------------------------------------------------------------*/\ninterface QueryParams {\n plugins?: {\n i18n?: {\n locale: string;\n };\n };\n}\n\ntype DocumentRow = {\n id: string | number;\n documentId: Modules.Documents.ID;\n};\n\nconst isDocumentRow = (entry: { id: string | number }): entry is DocumentRow => {\n if ('documentId' in entry) {\n return typeof entry.documentId === 'string';\n }\n\n return false;\n};\n\nconst useReleasesList = (contentTypeUid: UID.ContentType, documentId: Modules.Documents.ID) => {\n const listViewData = useTable('ListView', (state) => state.rows);\n const documentIds = listViewData\n .filter((entry) => isDocumentRow(entry))\n .map((entry) => entry.documentId);\n const [{ query }] = useQueryParams();\n const locale = (query as QueryParams)?.plugins?.i18n?.locale || undefined;\n\n const response = useGetMappedEntriesInReleasesQuery(\n { contentTypeUid, documentIds, locale },\n { skip: !contentTypeUid || documentIds.length === 0 }\n );\n\n const mappedEntriesInReleases = response.data || {};\n\n return mappedEntriesInReleases?.[documentId] || [];\n};\n\n/* -------------------------------------------------------------------------------------------------\n * addColumnToTableHook\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AddColumnToTableHookArgs {\n layout: ListLayout;\n displayedHeaders: ListFieldLayout[];\n}\n\ntype CellFormatterArgs = Parameters<NonNullable<ListFieldLayout['cellFormatter']>>;\n\nconst addColumnToTableHook = ({ displayedHeaders, layout }: AddColumnToTableHookArgs) => {\n const { options } = layout;\n\n if (!options?.draftAndPublish) {\n return { displayedHeaders, layout };\n }\n\n return {\n displayedHeaders: [\n ...displayedHeaders,\n {\n searchable: false,\n sortable: false,\n name: 'releases',\n label: {\n id: 'content-releases.content-manager.list-view.releases.header',\n defaultMessage: 'To be released in',\n },\n cellFormatter: (\n props: CellFormatterArgs[0],\n _header: CellFormatterArgs[1],\n { model }: ListCellMeta\n ) => <ReleaseListCell documentId={props.documentId} model={model as UID.ContentType} />,\n },\n ],\n layout,\n };\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ReleaseListCell\n * -----------------------------------------------------------------------------------------------*/\n\ninterface ReleaseListCellProps {\n documentId: Modules.Documents.ID;\n model: UID.ContentType;\n}\n\nconst ReleaseListCell = ({ documentId, model }: ReleaseListCellProps) => {\n const releases = useReleasesList(model, documentId);\n const { formatMessage } = useIntl();\n\n return (\n <Popover.Root>\n <Popover.Trigger>\n <Button\n variant=\"ghost\"\n onClick={(e: React.MouseEvent<HTMLElement>) => e.stopPropagation()}\n // TODO: find a way in the DS to define the widht and height of the icon\n endIcon={releases.length > 0 ? <CaretDown width=\"1.2rem\" height=\"1.2rem\" /> : null}\n >\n <Typography\n style={{ maxWidth: '252px', cursor: 'pointer' }}\n textColor=\"neutral800\"\n fontWeight=\"regular\"\n >\n {releases.length > 0\n ? formatMessage(\n {\n id: 'content-releases.content-manager.list-view.releases-number',\n defaultMessage: '{number} {number, plural, one {release} other {releases}}',\n },\n {\n number: releases.length,\n }\n )\n : '-'}\n </Typography>\n </Button>\n </Popover.Trigger>\n <Popover.Content>\n <ul>\n {releases.map(({ id, name }) => (\n <Box key={id} padding={3} tag=\"li\">\n <Link href={`/admin/plugins/content-releases/${id}`} isExternal={false}>\n {name}\n </Link>\n </Box>\n ))}\n </ul>\n </Popover.Content>\n </Popover.Root>\n );\n};\n\nexport { ReleaseListCell, addColumnToTableHook };\nexport type { ReleaseListCellProps };\n"],"names":["isDocumentRow","entry","documentId","useReleasesList","contentTypeUid","listViewData","useTable","state","rows","documentIds","filter","map","query","useQueryParams","locale","plugins","i18n","undefined","response","useGetMappedEntriesInReleasesQuery","skip","length","mappedEntriesInReleases","data","addColumnToTableHook","displayedHeaders","layout","options","draftAndPublish","searchable","sortable","name","label","id","defaultMessage","cellFormatter","props","_header","model","_jsx","ReleaseListCell","releases","formatMessage","useIntl","_jsxs","Popover","Root","Trigger","Button","variant","onClick","e","stopPropagation","endIcon","CaretDown","width","height","Typography","style","maxWidth","cursor","textColor","fontWeight","number","Content","ul","Box","padding","tag","Link","href","isExternal"],"mappings":";;;;;;;;;;AA4BA,MAAMA,gBAAgB,CAACC,KAAAA,GAAAA;AACrB,IAAA,IAAI,gBAAgBA,KAAAA,EAAO;QACzB,OAAO,OAAOA,KAAAA,CAAMC,UAAU,KAAK,QAAA;AACrC,IAAA;IAEA,OAAO,KAAA;AACT,CAAA;AAEA,MAAMC,eAAAA,GAAkB,CAACC,cAAAA,EAAiCF,UAAAA,GAAAA;AACxD,IAAA,MAAMG,eAAeC,oBAAAA,CAAS,UAAA,EAAY,CAACC,KAAAA,GAAUA,MAAMC,IAAI,CAAA;AAC/D,IAAA,MAAMC,WAAAA,GAAcJ,YAAAA,CACjBK,MAAM,CAAC,CAACT,KAAAA,GAAUD,aAAAA,CAAcC,KAAAA,CAAAA,CAAAA,CAChCU,GAAG,CAAC,CAACV,KAAAA,GAAUA,MAAMC,UAAU,CAAA;AAClC,IAAA,MAAM,CAAC,EAAEU,KAAK,EAAE,CAAC,GAAGC,0BAAAA,EAAAA;AACpB,IAAA,MAAMC,MAAAA,GAAUF,KAAAA,EAAuBG,OAAAA,EAASC,MAAMF,MAAAA,IAAUG,SAAAA;AAEhE,IAAA,MAAMC,WAAWC,0CAAAA,CACf;AAAEf,QAAAA,cAAAA;AAAgBK,QAAAA,WAAAA;AAAaK,QAAAA;KAAO,EACtC;AAAEM,QAAAA,IAAAA,EAAM,CAAChB,cAAAA,IAAkBK,WAAAA,CAAYY,MAAM,KAAK;AAAE,KAAA,CAAA;AAGtD,IAAA,MAAMC,uBAAAA,GAA0BJ,QAAAA,CAASK,IAAI,IAAI,EAAC;AAElD,IAAA,OAAOD,uBAAAA,GAA0BpB,UAAAA,CAAW,IAAI,EAAE;AACpD,CAAA;AAaA,MAAMsB,uBAAuB,CAAC,EAAEC,gBAAgB,EAAEC,MAAM,EAA4B,GAAA;IAClF,MAAM,EAAEC,OAAO,EAAE,GAAGD,MAAAA;IAEpB,IAAI,CAACC,SAASC,eAAAA,EAAiB;QAC7B,OAAO;AAAEH,YAAAA,gBAAAA;AAAkBC,YAAAA;AAAO,SAAA;AACpC,IAAA;IAEA,OAAO;QACLD,gBAAAA,EAAkB;AACbA,YAAAA,GAAAA,gBAAAA;AACH,YAAA;gBACEI,UAAAA,EAAY,KAAA;gBACZC,QAAAA,EAAU,KAAA;gBACVC,IAAAA,EAAM,UAAA;gBACNC,KAAAA,EAAO;oBACLC,EAAAA,EAAI,4DAAA;oBACJC,cAAAA,EAAgB;AAClB,iBAAA;AACAC,gBAAAA,aAAAA,EAAe,CACbC,KAAAA,EACAC,OAAAA,EACA,EAAEC,KAAK,EAAgB,iBACpBC,cAAA,CAACC,eAAAA,EAAAA;AAAgBtC,wBAAAA,UAAAA,EAAYkC,MAAMlC,UAAU;wBAAEoC,KAAAA,EAAOA;;AAC7D;AACD,SAAA;AACDZ,QAAAA;AACF,KAAA;AACF;AAWA,MAAMc,kBAAkB,CAAC,EAAEtC,UAAU,EAAEoC,KAAK,EAAwB,GAAA;IAClE,MAAMG,QAAAA,GAAWtC,gBAAgBmC,KAAAA,EAAOpC,UAAAA,CAAAA;IACxC,MAAM,EAAEwC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;IAE1B,qBACEC,eAAA,CAACC,qBAAQC,IAAI,EAAA;;AACX,0BAAAP,cAAA,CAACM,qBAAQE,OAAO,EAAA;AACd,gBAAA,QAAA,gBAAAR,cAAA,CAACS,mBAAAA,EAAAA;oBACCC,OAAAA,EAAQ,OAAA;oBACRC,OAAAA,EAAS,CAACC,CAAAA,GAAqCA,CAAAA,CAAEC,eAAe,EAAA;;AAEhEC,oBAAAA,OAAAA,EAASZ,QAAAA,CAASpB,MAAM,GAAG,CAAA,iBAAIkB,cAAA,CAACe,eAAAA,EAAAA;wBAAUC,KAAAA,EAAM,QAAA;wBAASC,MAAAA,EAAO;AAAc,qBAAA,CAAA,GAAA,IAAA;AAE9E,oBAAA,QAAA,gBAAAjB,cAAA,CAACkB,uBAAAA,EAAAA;wBACCC,KAAAA,EAAO;4BAAEC,QAAAA,EAAU,OAAA;4BAASC,MAAAA,EAAQ;AAAU,yBAAA;wBAC9CC,SAAAA,EAAU,YAAA;wBACVC,UAAAA,EAAW,SAAA;kCAEVrB,QAAAA,CAASpB,MAAM,GAAG,CAAA,GACfqB,aAAAA,CACE;4BACET,EAAAA,EAAI,4DAAA;4BACJC,cAAAA,EAAgB;yBAClB,EACA;AACE6B,4BAAAA,MAAAA,EAAQtB,SAASpB;yBACnB,CAAA,GAEF;;;;AAIV,0BAAAkB,cAAA,CAACM,qBAAQmB,OAAO,EAAA;AACd,gBAAA,QAAA,gBAAAzB,cAAA,CAAC0B,IAAAA,EAAAA;8BACExB,QAAAA,CAAS9B,GAAG,CAAC,CAAC,EAAEsB,EAAE,EAAEF,IAAI,EAAE,iBACzBQ,cAAA,CAAC2B,gBAAAA,EAAAA;4BAAaC,OAAAA,EAAS,CAAA;4BAAGC,GAAAA,EAAI,IAAA;AAC5B,4BAAA,QAAA,gBAAA7B,cAAA,CAAC8B,iBAAAA,EAAAA;gCAAKC,IAAAA,EAAM,CAAC,gCAAgC,EAAErC,EAAAA,CAAAA,CAAI;gCAAEsC,UAAAA,EAAY,KAAA;AAC9DxC,gCAAAA,QAAAA,EAAAA;;AAFKE,yBAAAA,EAAAA,EAAAA,CAAAA;;;;;AAUtB;;;;;"}
@@ -46,8 +46,8 @@ const addColumnToTableHook = ({ displayedHeaders, layout })=>{
46
46
  id: 'content-releases.content-manager.list-view.releases.header',
47
47
  defaultMessage: 'To be released in'
48
48
  },
49
- cellFormatter: (props, _, { model })=>/*#__PURE__*/ jsx(ReleaseListCell, {
50
- ...props,
49
+ cellFormatter: (props, _header, { model })=>/*#__PURE__*/ jsx(ReleaseListCell, {
50
+ documentId: props.documentId,
51
51
  model: model
52
52
  })
53
53
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ReleaseListCell.mjs","sources":["../../../admin/src/components/ReleaseListCell.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useTable, useQueryParams } from '@strapi/admin/strapi-admin';\nimport { ListFieldLayout, ListLayout } from '@strapi/content-manager/strapi-admin';\nimport { Box, Popover, Typography, Button, Link } from '@strapi/design-system';\nimport { CaretDown } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\n\nimport { useGetMappedEntriesInReleasesQuery } from '../services/release';\n\nimport type { Modules, UID } from '@strapi/types';\n\n/* -------------------------------------------------------------------------------------------------\n * useReleasesList\n * -----------------------------------------------------------------------------------------------*/\ninterface QueryParams {\n plugins?: {\n i18n?: {\n locale: string;\n };\n };\n}\n\ntype DocumentRow = {\n id: string | number;\n documentId: Modules.Documents.ID;\n};\n\nconst isDocumentRow = (entry: { id: string | number }): entry is DocumentRow => {\n if ('documentId' in entry) {\n return typeof entry.documentId === 'string';\n }\n\n return false;\n};\n\nconst useReleasesList = (contentTypeUid: UID.ContentType, documentId: Modules.Documents.ID) => {\n const listViewData = useTable('ListView', (state) => state.rows);\n const documentIds = listViewData\n .filter((entry) => isDocumentRow(entry))\n .map((entry) => entry.documentId);\n const [{ query }] = useQueryParams();\n const locale = (query as QueryParams)?.plugins?.i18n?.locale || undefined;\n\n const response = useGetMappedEntriesInReleasesQuery(\n { contentTypeUid, documentIds, locale },\n { skip: !contentTypeUid || documentIds.length === 0 }\n );\n\n const mappedEntriesInReleases = response.data || {};\n\n return mappedEntriesInReleases?.[documentId] || [];\n};\n\n/* -------------------------------------------------------------------------------------------------\n * addColumnToTableHook\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AddColumnToTableHookArgs {\n layout: ListLayout;\n displayedHeaders: ListFieldLayout[];\n}\n\nconst addColumnToTableHook = ({ displayedHeaders, layout }: AddColumnToTableHookArgs) => {\n const { options } = layout;\n\n if (!options?.draftAndPublish) {\n return { displayedHeaders, layout };\n }\n\n return {\n displayedHeaders: [\n ...displayedHeaders,\n {\n searchable: false,\n sortable: false,\n name: 'releases',\n label: {\n id: 'content-releases.content-manager.list-view.releases.header',\n defaultMessage: 'To be released in',\n },\n cellFormatter: (\n props: Modules.Documents.AnyDocument,\n _: unknown,\n { model }: { model: UID.ContentType }\n ) => <ReleaseListCell {...props} model={model} />,\n },\n ],\n layout,\n };\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ReleaseListCell\n * -----------------------------------------------------------------------------------------------*/\n\ninterface ReleaseListCellProps extends Modules.Documents.AnyDocument {\n documentId: Modules.Documents.ID;\n model: UID.ContentType;\n}\n\nconst ReleaseListCell = ({ documentId, model }: ReleaseListCellProps) => {\n const releases = useReleasesList(model, documentId);\n const { formatMessage } = useIntl();\n\n return (\n <Popover.Root>\n <Popover.Trigger>\n <Button\n variant=\"ghost\"\n onClick={(e: React.MouseEvent<HTMLElement>) => e.stopPropagation()}\n // TODO: find a way in the DS to define the widht and height of the icon\n endIcon={releases.length > 0 ? <CaretDown width=\"1.2rem\" height=\"1.2rem\" /> : null}\n >\n <Typography\n style={{ maxWidth: '252px', cursor: 'pointer' }}\n textColor=\"neutral800\"\n fontWeight=\"regular\"\n >\n {releases.length > 0\n ? formatMessage(\n {\n id: 'content-releases.content-manager.list-view.releases-number',\n defaultMessage: '{number} {number, plural, one {release} other {releases}}',\n },\n {\n number: releases.length,\n }\n )\n : '-'}\n </Typography>\n </Button>\n </Popover.Trigger>\n <Popover.Content>\n <ul>\n {releases.map(({ id, name }) => (\n <Box key={id} padding={3} tag=\"li\">\n <Link href={`/admin/plugins/content-releases/${id}`} isExternal={false}>\n {name}\n </Link>\n </Box>\n ))}\n </ul>\n </Popover.Content>\n </Popover.Root>\n );\n};\n\nexport { ReleaseListCell, addColumnToTableHook };\nexport type { ReleaseListCellProps };\n"],"names":["isDocumentRow","entry","documentId","useReleasesList","contentTypeUid","listViewData","useTable","state","rows","documentIds","filter","map","query","useQueryParams","locale","plugins","i18n","undefined","response","useGetMappedEntriesInReleasesQuery","skip","length","mappedEntriesInReleases","data","addColumnToTableHook","displayedHeaders","layout","options","draftAndPublish","searchable","sortable","name","label","id","defaultMessage","cellFormatter","props","_","model","_jsx","ReleaseListCell","releases","formatMessage","useIntl","_jsxs","Popover","Root","Trigger","Button","variant","onClick","e","stopPropagation","endIcon","CaretDown","width","height","Typography","style","maxWidth","cursor","textColor","fontWeight","number","Content","ul","Box","padding","tag","Link","href","isExternal"],"mappings":"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"}
1
+ {"version":3,"file":"ReleaseListCell.mjs","sources":["../../../admin/src/components/ReleaseListCell.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useTable, useQueryParams } from '@strapi/admin/strapi-admin';\nimport { ListCellMeta, ListFieldLayout, ListLayout } from '@strapi/content-manager/strapi-admin';\nimport { Box, Popover, Typography, Button, Link } from '@strapi/design-system';\nimport { CaretDown } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\n\nimport { useGetMappedEntriesInReleasesQuery } from '../services/release';\n\nimport type { Modules, UID } from '@strapi/types';\n\n/* -------------------------------------------------------------------------------------------------\n * useReleasesList\n * -----------------------------------------------------------------------------------------------*/\ninterface QueryParams {\n plugins?: {\n i18n?: {\n locale: string;\n };\n };\n}\n\ntype DocumentRow = {\n id: string | number;\n documentId: Modules.Documents.ID;\n};\n\nconst isDocumentRow = (entry: { id: string | number }): entry is DocumentRow => {\n if ('documentId' in entry) {\n return typeof entry.documentId === 'string';\n }\n\n return false;\n};\n\nconst useReleasesList = (contentTypeUid: UID.ContentType, documentId: Modules.Documents.ID) => {\n const listViewData = useTable('ListView', (state) => state.rows);\n const documentIds = listViewData\n .filter((entry) => isDocumentRow(entry))\n .map((entry) => entry.documentId);\n const [{ query }] = useQueryParams();\n const locale = (query as QueryParams)?.plugins?.i18n?.locale || undefined;\n\n const response = useGetMappedEntriesInReleasesQuery(\n { contentTypeUid, documentIds, locale },\n { skip: !contentTypeUid || documentIds.length === 0 }\n );\n\n const mappedEntriesInReleases = response.data || {};\n\n return mappedEntriesInReleases?.[documentId] || [];\n};\n\n/* -------------------------------------------------------------------------------------------------\n * addColumnToTableHook\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AddColumnToTableHookArgs {\n layout: ListLayout;\n displayedHeaders: ListFieldLayout[];\n}\n\ntype CellFormatterArgs = Parameters<NonNullable<ListFieldLayout['cellFormatter']>>;\n\nconst addColumnToTableHook = ({ displayedHeaders, layout }: AddColumnToTableHookArgs) => {\n const { options } = layout;\n\n if (!options?.draftAndPublish) {\n return { displayedHeaders, layout };\n }\n\n return {\n displayedHeaders: [\n ...displayedHeaders,\n {\n searchable: false,\n sortable: false,\n name: 'releases',\n label: {\n id: 'content-releases.content-manager.list-view.releases.header',\n defaultMessage: 'To be released in',\n },\n cellFormatter: (\n props: CellFormatterArgs[0],\n _header: CellFormatterArgs[1],\n { model }: ListCellMeta\n ) => <ReleaseListCell documentId={props.documentId} model={model as UID.ContentType} />,\n },\n ],\n layout,\n };\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ReleaseListCell\n * -----------------------------------------------------------------------------------------------*/\n\ninterface ReleaseListCellProps {\n documentId: Modules.Documents.ID;\n model: UID.ContentType;\n}\n\nconst ReleaseListCell = ({ documentId, model }: ReleaseListCellProps) => {\n const releases = useReleasesList(model, documentId);\n const { formatMessage } = useIntl();\n\n return (\n <Popover.Root>\n <Popover.Trigger>\n <Button\n variant=\"ghost\"\n onClick={(e: React.MouseEvent<HTMLElement>) => e.stopPropagation()}\n // TODO: find a way in the DS to define the widht and height of the icon\n endIcon={releases.length > 0 ? <CaretDown width=\"1.2rem\" height=\"1.2rem\" /> : null}\n >\n <Typography\n style={{ maxWidth: '252px', cursor: 'pointer' }}\n textColor=\"neutral800\"\n fontWeight=\"regular\"\n >\n {releases.length > 0\n ? formatMessage(\n {\n id: 'content-releases.content-manager.list-view.releases-number',\n defaultMessage: '{number} {number, plural, one {release} other {releases}}',\n },\n {\n number: releases.length,\n }\n )\n : '-'}\n </Typography>\n </Button>\n </Popover.Trigger>\n <Popover.Content>\n <ul>\n {releases.map(({ id, name }) => (\n <Box key={id} padding={3} tag=\"li\">\n <Link href={`/admin/plugins/content-releases/${id}`} isExternal={false}>\n {name}\n </Link>\n </Box>\n ))}\n </ul>\n </Popover.Content>\n </Popover.Root>\n );\n};\n\nexport { ReleaseListCell, addColumnToTableHook };\nexport type { ReleaseListCellProps };\n"],"names":["isDocumentRow","entry","documentId","useReleasesList","contentTypeUid","listViewData","useTable","state","rows","documentIds","filter","map","query","useQueryParams","locale","plugins","i18n","undefined","response","useGetMappedEntriesInReleasesQuery","skip","length","mappedEntriesInReleases","data","addColumnToTableHook","displayedHeaders","layout","options","draftAndPublish","searchable","sortable","name","label","id","defaultMessage","cellFormatter","props","_header","model","_jsx","ReleaseListCell","releases","formatMessage","useIntl","_jsxs","Popover","Root","Trigger","Button","variant","onClick","e","stopPropagation","endIcon","CaretDown","width","height","Typography","style","maxWidth","cursor","textColor","fontWeight","number","Content","ul","Box","padding","tag","Link","href","isExternal"],"mappings":";;;;;;;;AA4BA,MAAMA,gBAAgB,CAACC,KAAAA,GAAAA;AACrB,IAAA,IAAI,gBAAgBA,KAAAA,EAAO;QACzB,OAAO,OAAOA,KAAAA,CAAMC,UAAU,KAAK,QAAA;AACrC,IAAA;IAEA,OAAO,KAAA;AACT,CAAA;AAEA,MAAMC,eAAAA,GAAkB,CAACC,cAAAA,EAAiCF,UAAAA,GAAAA;AACxD,IAAA,MAAMG,eAAeC,QAAAA,CAAS,UAAA,EAAY,CAACC,KAAAA,GAAUA,MAAMC,IAAI,CAAA;AAC/D,IAAA,MAAMC,WAAAA,GAAcJ,YAAAA,CACjBK,MAAM,CAAC,CAACT,KAAAA,GAAUD,aAAAA,CAAcC,KAAAA,CAAAA,CAAAA,CAChCU,GAAG,CAAC,CAACV,KAAAA,GAAUA,MAAMC,UAAU,CAAA;AAClC,IAAA,MAAM,CAAC,EAAEU,KAAK,EAAE,CAAC,GAAGC,cAAAA,EAAAA;AACpB,IAAA,MAAMC,MAAAA,GAAUF,KAAAA,EAAuBG,OAAAA,EAASC,MAAMF,MAAAA,IAAUG,SAAAA;AAEhE,IAAA,MAAMC,WAAWC,kCAAAA,CACf;AAAEf,QAAAA,cAAAA;AAAgBK,QAAAA,WAAAA;AAAaK,QAAAA;KAAO,EACtC;AAAEM,QAAAA,IAAAA,EAAM,CAAChB,cAAAA,IAAkBK,WAAAA,CAAYY,MAAM,KAAK;AAAE,KAAA,CAAA;AAGtD,IAAA,MAAMC,uBAAAA,GAA0BJ,QAAAA,CAASK,IAAI,IAAI,EAAC;AAElD,IAAA,OAAOD,uBAAAA,GAA0BpB,UAAAA,CAAW,IAAI,EAAE;AACpD,CAAA;AAaA,MAAMsB,uBAAuB,CAAC,EAAEC,gBAAgB,EAAEC,MAAM,EAA4B,GAAA;IAClF,MAAM,EAAEC,OAAO,EAAE,GAAGD,MAAAA;IAEpB,IAAI,CAACC,SAASC,eAAAA,EAAiB;QAC7B,OAAO;AAAEH,YAAAA,gBAAAA;AAAkBC,YAAAA;AAAO,SAAA;AACpC,IAAA;IAEA,OAAO;QACLD,gBAAAA,EAAkB;AACbA,YAAAA,GAAAA,gBAAAA;AACH,YAAA;gBACEI,UAAAA,EAAY,KAAA;gBACZC,QAAAA,EAAU,KAAA;gBACVC,IAAAA,EAAM,UAAA;gBACNC,KAAAA,EAAO;oBACLC,EAAAA,EAAI,4DAAA;oBACJC,cAAAA,EAAgB;AAClB,iBAAA;AACAC,gBAAAA,aAAAA,EAAe,CACbC,KAAAA,EACAC,OAAAA,EACA,EAAEC,KAAK,EAAgB,iBACpBC,GAAA,CAACC,eAAAA,EAAAA;AAAgBtC,wBAAAA,UAAAA,EAAYkC,MAAMlC,UAAU;wBAAEoC,KAAAA,EAAOA;;AAC7D;AACD,SAAA;AACDZ,QAAAA;AACF,KAAA;AACF;AAWA,MAAMc,kBAAkB,CAAC,EAAEtC,UAAU,EAAEoC,KAAK,EAAwB,GAAA;IAClE,MAAMG,QAAAA,GAAWtC,gBAAgBmC,KAAAA,EAAOpC,UAAAA,CAAAA;IACxC,MAAM,EAAEwC,aAAa,EAAE,GAAGC,OAAAA,EAAAA;IAE1B,qBACEC,IAAA,CAACC,QAAQC,IAAI,EAAA;;AACX,0BAAAP,GAAA,CAACM,QAAQE,OAAO,EAAA;AACd,gBAAA,QAAA,gBAAAR,GAAA,CAACS,MAAAA,EAAAA;oBACCC,OAAAA,EAAQ,OAAA;oBACRC,OAAAA,EAAS,CAACC,CAAAA,GAAqCA,CAAAA,CAAEC,eAAe,EAAA;;AAEhEC,oBAAAA,OAAAA,EAASZ,QAAAA,CAASpB,MAAM,GAAG,CAAA,iBAAIkB,GAAA,CAACe,SAAAA,EAAAA;wBAAUC,KAAAA,EAAM,QAAA;wBAASC,MAAAA,EAAO;AAAc,qBAAA,CAAA,GAAA,IAAA;AAE9E,oBAAA,QAAA,gBAAAjB,GAAA,CAACkB,UAAAA,EAAAA;wBACCC,KAAAA,EAAO;4BAAEC,QAAAA,EAAU,OAAA;4BAASC,MAAAA,EAAQ;AAAU,yBAAA;wBAC9CC,SAAAA,EAAU,YAAA;wBACVC,UAAAA,EAAW,SAAA;kCAEVrB,QAAAA,CAASpB,MAAM,GAAG,CAAA,GACfqB,aAAAA,CACE;4BACET,EAAAA,EAAI,4DAAA;4BACJC,cAAAA,EAAgB;yBAClB,EACA;AACE6B,4BAAAA,MAAAA,EAAQtB,SAASpB;yBACnB,CAAA,GAEF;;;;AAIV,0BAAAkB,GAAA,CAACM,QAAQmB,OAAO,EAAA;AACd,gBAAA,QAAA,gBAAAzB,GAAA,CAAC0B,IAAAA,EAAAA;8BACExB,QAAAA,CAAS9B,GAAG,CAAC,CAAC,EAAEsB,EAAE,EAAEF,IAAI,EAAE,iBACzBQ,GAAA,CAAC2B,GAAAA,EAAAA;4BAAaC,OAAAA,EAAS,CAAA;4BAAGC,GAAAA,EAAI,IAAA;AAC5B,4BAAA,QAAA,gBAAA7B,GAAA,CAAC8B,IAAAA,EAAAA;gCAAKC,IAAAA,EAAM,CAAC,gCAAgC,EAAErC,EAAAA,CAAAA,CAAI;gCAAEsC,UAAAA,EAAY,KAAA;AAC9DxC,gCAAAA,QAAAA,EAAAA;;AAFKE,yBAAAA,EAAAA,EAAAA,CAAAA;;;;;AAUtB;;;;"}
@@ -1,9 +1,10 @@
1
- import { ListFieldLayout, ListLayout } from '@strapi/content-manager/strapi-admin';
1
+ import { ListCellMeta, ListFieldLayout, ListLayout } from '@strapi/content-manager/strapi-admin';
2
2
  import type { Modules, UID } from '@strapi/types';
3
3
  interface AddColumnToTableHookArgs {
4
4
  layout: ListLayout;
5
5
  displayedHeaders: ListFieldLayout[];
6
6
  }
7
+ type CellFormatterArgs = Parameters<NonNullable<ListFieldLayout['cellFormatter']>>;
7
8
  declare const addColumnToTableHook: ({ displayedHeaders, layout }: AddColumnToTableHookArgs) => {
8
9
  displayedHeaders: (ListFieldLayout | {
9
10
  searchable: boolean;
@@ -13,13 +14,11 @@ declare const addColumnToTableHook: ({ displayedHeaders, layout }: AddColumnToTa
13
14
  id: string;
14
15
  defaultMessage: string;
15
16
  };
16
- cellFormatter: (props: Modules.Documents.AnyDocument, _: unknown, { model }: {
17
- model: UID.ContentType;
18
- }) => import("react/jsx-runtime").JSX.Element;
17
+ cellFormatter: (props: CellFormatterArgs[0], _header: CellFormatterArgs[1], { model }: ListCellMeta) => import("react/jsx-runtime").JSX.Element;
19
18
  })[];
20
19
  layout: ListLayout;
21
20
  };
22
- interface ReleaseListCellProps extends Modules.Documents.AnyDocument {
21
+ interface ReleaseListCellProps {
23
22
  documentId: Modules.Documents.ID;
24
23
  model: UID.ContentType;
25
24
  }
@@ -10,6 +10,9 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
10
 
11
11
  var isEqual__default = /*#__PURE__*/_interopDefault(isEqual);
12
12
 
13
+ // The core store saves content types as JSON: compare live attributes in that form, so values
14
+ // JSON drops (e.g. the `publishedAt.default` function) do not count as a change
15
+ const toPersistedForm = (attributes)=>JSON.parse(JSON.stringify(attributes ?? null));
13
16
  async function deleteActionsOnDisableDraftAndPublish({ oldContentTypes, contentTypes }) {
14
17
  if (!oldContentTypes) {
15
18
  return;
@@ -100,24 +103,32 @@ async function migrateIsValidAndStatusReleases() {
100
103
  }
101
104
  async function revalidateChangedContentTypes({ oldContentTypes, contentTypes }) {
102
105
  if (oldContentTypes !== undefined && oldContentTypes !== null && contentTypes !== undefined) {
103
- const contentTypesWithDraftAndPublish = Object.keys(oldContentTypes).filter((uid)=>oldContentTypes[uid]?.options?.draftAndPublish);
106
+ // Skip deleted content types: their model is gone, and `deleteActionsOnDeleteContentType`
107
+ // removes their actions
108
+ const contentTypesWithDraftAndPublish = Object.keys(oldContentTypes).filter((uid)=>oldContentTypes[uid]?.options?.draftAndPublish === true && contentTypes[uid] !== undefined);
104
109
  const releasesAffected = new Set();
105
- utils.async.map(contentTypesWithDraftAndPublish, async (contentTypeUID)=>{
110
+ await utils.async.map(contentTypesWithDraftAndPublish, async (contentTypeUID)=>{
106
111
  const oldContentType = oldContentTypes[contentTypeUID];
107
112
  const contentType = contentTypes[contentTypeUID];
108
113
  // If attributes have changed, we need to revalidate actions because maybe validations rules are different
109
- if (!isEqual__default.default(oldContentType?.attributes, contentType?.attributes)) {
114
+ if (!isEqual__default.default(toPersistedForm(oldContentType?.attributes), toPersistedForm(contentType?.attributes))) {
110
115
  const actions = await strapi.db.query(constants.RELEASE_ACTION_MODEL_UID).findMany({
111
116
  where: {
112
- contentType: contentTypeUID
117
+ contentType: contentTypeUID,
118
+ // Released releases keep their `done` status
119
+ release: {
120
+ releasedAt: {
121
+ $null: true
122
+ }
123
+ }
113
124
  },
114
125
  populate: {
115
- entry: true,
116
126
  release: true
117
127
  }
118
128
  });
119
129
  await utils.async.map(actions, async (action)=>{
120
- if (action.entry && action.release && action.type === 'publish') {
130
+ // Actions reference their entry by `entryDocumentId` and `locale`, not by a relation
131
+ if (action.release !== null && action.release !== undefined && action.type === 'publish') {
121
132
  const isEntryValid = await index.getDraftEntryValidStatus({
122
133
  contentType: contentTypeUID,
123
134
  documentId: action.entryDocumentId,
@@ -137,13 +148,12 @@ async function revalidateChangedContentTypes({ oldContentTypes, contentTypes })
137
148
  }
138
149
  });
139
150
  }
140
- }).then(()=>{
141
- // We need to update the status of the releases affected
142
- utils.async.map(releasesAffected, async (releaseId)=>{
143
- return index.getService('release', {
144
- strapi
145
- }).updateReleaseStatus(releaseId);
146
- });
151
+ });
152
+ // We need to update the status of the releases affected
153
+ await utils.async.map(releasesAffected, async (releaseId)=>{
154
+ return index.getService('release', {
155
+ strapi
156
+ }).updateReleaseStatus(releaseId);
147
157
  });
148
158
  }
149
159
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../server/src/migrations/index.ts"],"sourcesContent":["import type { Schema, UID } from '@strapi/types';\nimport { contentTypes as contentTypesUtils, async } from '@strapi/utils';\nimport isEqual from 'lodash/isEqual';\n\nimport { difference, keys } from 'lodash';\nimport { RELEASE_ACTION_MODEL_UID, RELEASE_MODEL_UID } from '../constants';\nimport { getDraftEntryValidStatus, getService } from '../utils';\nimport { Release } from '../../../shared/contracts/releases';\nimport { ReleaseAction } from '../../../shared/contracts/release-actions';\n\ninterface Input {\n oldContentTypes: Record<string, Schema.ContentType>;\n contentTypes: Record<string, Schema.ContentType>;\n}\n\nexport async function deleteActionsOnDisableDraftAndPublish({\n oldContentTypes,\n contentTypes,\n}: Input) {\n if (!oldContentTypes) {\n return;\n }\n\n for (const uid in contentTypes) {\n if (!oldContentTypes[uid]) {\n continue;\n }\n\n const oldContentType = oldContentTypes[uid];\n const contentType = contentTypes[uid];\n\n if (\n contentTypesUtils.hasDraftAndPublish(oldContentType) &&\n !contentTypesUtils.hasDraftAndPublish(contentType)\n ) {\n await strapi.db\n ?.queryBuilder(RELEASE_ACTION_MODEL_UID)\n .delete()\n .where({ contentType: uid })\n .execute();\n }\n }\n}\n\nexport async function deleteActionsOnDeleteContentType({ oldContentTypes, contentTypes }: Input) {\n const deletedContentTypes = difference(keys(oldContentTypes), keys(contentTypes)) ?? [];\n\n if (deletedContentTypes.length) {\n await async.map(deletedContentTypes, async (deletedContentTypeUID: unknown) => {\n return strapi.db\n ?.queryBuilder(RELEASE_ACTION_MODEL_UID)\n .delete()\n .where({ contentType: deletedContentTypeUID })\n .execute();\n });\n }\n}\n\nexport async function migrateIsValidAndStatusReleases() {\n const releasesWithoutStatus = (await strapi.db.query(RELEASE_MODEL_UID).findMany({\n where: {\n status: null,\n releasedAt: null,\n },\n populate: {\n actions: {\n populate: {\n entry: true,\n },\n },\n },\n })) as Release[];\n\n async.map(releasesWithoutStatus, async (release: Release) => {\n const actions = release.actions;\n\n const notValidatedActions = actions.filter((action) => action.isEntryValid === null);\n\n for (const action of notValidatedActions) {\n // We need to check the Action is related to a valid entry because we can't assume this is gonna be always the case\n // example: users could make changes directly to their database, or data could be lost\n if (action.entry) {\n const isEntryValid = getDraftEntryValidStatus(\n {\n contentType: action.contentType,\n documentId: action.entryDocumentId,\n locale: action.locale,\n },\n { strapi }\n );\n\n await strapi.db.query(RELEASE_ACTION_MODEL_UID).update({\n where: {\n id: action.id,\n },\n data: {\n isEntryValid,\n },\n });\n }\n }\n\n return getService('release', { strapi }).updateReleaseStatus(release.id);\n });\n\n const publishedReleases = await strapi.db.query(RELEASE_MODEL_UID).findMany({\n where: {\n status: null,\n releasedAt: {\n $notNull: true,\n },\n },\n });\n\n async.map(publishedReleases, async (release: Release) => {\n return strapi.db.query(RELEASE_MODEL_UID).update({\n where: {\n id: release.id,\n },\n data: {\n status: 'done',\n },\n });\n });\n}\n\nexport async function revalidateChangedContentTypes({ oldContentTypes, contentTypes }: Input) {\n if (oldContentTypes !== undefined && oldContentTypes !== null && contentTypes !== undefined) {\n const contentTypesWithDraftAndPublish = Object.keys(oldContentTypes).filter(\n (uid) => oldContentTypes[uid]?.options?.draftAndPublish\n );\n const releasesAffected = new Set();\n\n async\n .map(contentTypesWithDraftAndPublish, async (contentTypeUID: UID.ContentType) => {\n const oldContentType = oldContentTypes[contentTypeUID];\n const contentType = contentTypes[contentTypeUID];\n\n // If attributes have changed, we need to revalidate actions because maybe validations rules are different\n if (!isEqual(oldContentType?.attributes, contentType?.attributes)) {\n const actions = await strapi.db.query(RELEASE_ACTION_MODEL_UID).findMany({\n where: {\n contentType: contentTypeUID,\n },\n populate: {\n entry: true,\n release: true,\n },\n });\n\n await async.map(actions, async (action: ReleaseAction) => {\n if (action.entry && action.release && action.type === 'publish') {\n const isEntryValid = await getDraftEntryValidStatus(\n {\n contentType: contentTypeUID,\n documentId: action.entryDocumentId,\n locale: action.locale,\n },\n { strapi }\n );\n\n releasesAffected.add(action.release.id);\n\n await strapi.db.query(RELEASE_ACTION_MODEL_UID).update({\n where: {\n id: action.id,\n },\n data: {\n isEntryValid,\n },\n });\n }\n });\n }\n })\n .then(() => {\n // We need to update the status of the releases affected\n async.map(releasesAffected, async (releaseId: Release['id']) => {\n return getService('release', { strapi }).updateReleaseStatus(releaseId);\n });\n });\n }\n}\n\nexport async function disableContentTypeLocalized({ oldContentTypes, contentTypes }: Input) {\n if (!oldContentTypes) {\n return;\n }\n\n for (const uid in contentTypes) {\n if (!oldContentTypes[uid]) {\n continue;\n }\n\n const oldContentType = oldContentTypes[uid];\n const contentType = contentTypes[uid];\n\n // if i18N is disabled remove non default locales before sync\n if (\n strapi.localization.isLocalizedContentType(oldContentType) === true &&\n strapi.localization.isLocalizedContentType(contentType) === false\n ) {\n await strapi.db\n .queryBuilder(RELEASE_ACTION_MODEL_UID)\n .update({\n locale: null,\n })\n .where({ contentType: uid })\n .execute();\n }\n }\n}\n\nexport async function enableContentTypeLocalized({ oldContentTypes, contentTypes }: Input) {\n if (!oldContentTypes) {\n return;\n }\n\n for (const uid in contentTypes) {\n if (!oldContentTypes[uid]) {\n continue;\n }\n\n const oldContentType = oldContentTypes[uid];\n const contentType = contentTypes[uid];\n\n // if i18N is enabled remove non default locales before sync\n if (\n strapi.localization.isLocalizedContentType(oldContentType) === false &&\n strapi.localization.isLocalizedContentType(contentType) === true\n ) {\n const defaultLocale = await strapi.localization.getDefaultLocale();\n\n await strapi.db\n .queryBuilder(RELEASE_ACTION_MODEL_UID)\n .update({\n locale: defaultLocale,\n })\n .where({ contentType: uid })\n .execute();\n }\n }\n}\n"],"names":["deleteActionsOnDisableDraftAndPublish","oldContentTypes","contentTypes","uid","oldContentType","contentType","contentTypesUtils","hasDraftAndPublish","strapi","db","queryBuilder","RELEASE_ACTION_MODEL_UID","delete","where","execute","deleteActionsOnDeleteContentType","deletedContentTypes","difference","keys","length","async","map","deletedContentTypeUID","migrateIsValidAndStatusReleases","releasesWithoutStatus","query","RELEASE_MODEL_UID","findMany","status","releasedAt","populate","actions","entry","release","notValidatedActions","filter","action","isEntryValid","getDraftEntryValidStatus","documentId","entryDocumentId","locale","update","id","data","getService","updateReleaseStatus","publishedReleases","$notNull","revalidateChangedContentTypes","undefined","contentTypesWithDraftAndPublish","Object","options","draftAndPublish","releasesAffected","Set","contentTypeUID","isEqual","attributes","type","add","then","releaseId","disableContentTypeLocalized","localization","isLocalizedContentType","enableContentTypeLocalized","defaultLocale","getDefaultLocale"],"mappings":";;;;;;;;;;;;AAeO,eAAeA,qCAAAA,CAAsC,EAC1DC,eAAe,EACfC,YAAY,EACN,EAAA;AACN,IAAA,IAAI,CAACD,eAAAA,EAAiB;AACpB,QAAA;AACF,IAAA;IAEA,IAAK,MAAME,OAAOD,YAAAA,CAAc;AAC9B,QAAA,IAAI,CAACD,eAAe,CAACE,GAAAA,CAAI,EAAE;AACzB,YAAA;AACF,QAAA;QAEA,MAAMC,cAAAA,GAAiBH,eAAe,CAACE,GAAAA,CAAI;QAC3C,MAAME,WAAAA,GAAcH,YAAY,CAACC,GAAAA,CAAI;QAErC,IACEG,kBAAAA,CAAkBC,kBAAkB,CAACH,cAAAA,CAAAA,IACrC,CAACE,kBAAAA,CAAkBC,kBAAkB,CAACF,WAAAA,CAAAA,EACtC;AACA,YAAA,MAAMG,OAAOC,EAAE,EACXC,YAAAA,CAAaC,kCAAAA,CAAAA,CACdC,SACAC,KAAAA,CAAM;gBAAER,WAAAA,EAAaF;aAAI,CAAA,CACzBW,OAAAA,EAAAA;AACL,QAAA;AACF,IAAA;AACF;AAEO,eAAeC,gCAAAA,CAAiC,EAAEd,eAAe,EAAEC,YAAY,EAAS,EAAA;AAC7F,IAAA,MAAMc,sBAAsBC,YAAAA,CAAWC,MAAAA,CAAKjB,eAAAA,CAAAA,EAAkBiB,MAAAA,CAAKhB,kBAAkB,EAAE;IAEvF,IAAIc,mBAAAA,CAAoBG,MAAM,EAAE;AAC9B,QAAA,MAAMC,WAAAA,CAAMC,GAAG,CAACL,mBAAAA,EAAqB,OAAOM,qBAAAA,GAAAA;AAC1C,YAAA,OAAOd,OAAOC,EAAE,EACZC,YAAAA,CAAaC,kCAAAA,CAAAA,CACdC,SACAC,KAAAA,CAAM;gBAAER,WAAAA,EAAaiB;aAAsB,CAAA,CAC3CR,OAAAA,EAAAA;AACL,QAAA,CAAA,CAAA;AACF,IAAA;AACF;AAEO,eAAeS,+BAAAA,GAAAA;IACpB,MAAMC,qBAAAA,GAAyB,MAAMhB,MAAAA,CAAOC,EAAE,CAACgB,KAAK,CAACC,2BAAAA,CAAAA,CAAmBC,QAAQ,CAAC;QAC/Ed,KAAAA,EAAO;YACLe,MAAAA,EAAQ,IAAA;YACRC,UAAAA,EAAY;AACd,SAAA;QACAC,QAAAA,EAAU;YACRC,OAAAA,EAAS;gBACPD,QAAAA,EAAU;oBACRE,KAAAA,EAAO;AACT;AACF;AACF;AACF,KAAA,CAAA;IAEAZ,WAAAA,CAAMC,GAAG,CAACG,qBAAAA,EAAuB,OAAOS,OAAAA,GAAAA;QACtC,MAAMF,OAAAA,GAAUE,QAAQF,OAAO;QAE/B,MAAMG,mBAAAA,GAAsBH,QAAQI,MAAM,CAAC,CAACC,MAAAA,GAAWA,MAAAA,CAAOC,YAAY,KAAK,IAAA,CAAA;QAE/E,KAAK,MAAMD,UAAUF,mBAAAA,CAAqB;;;YAGxC,IAAIE,MAAAA,CAAOJ,KAAK,EAAE;AAChB,gBAAA,MAAMK,eAAeC,8BAAAA,CACnB;AACEjC,oBAAAA,WAAAA,EAAa+B,OAAO/B,WAAW;AAC/BkC,oBAAAA,UAAAA,EAAYH,OAAOI,eAAe;AAClCC,oBAAAA,MAAAA,EAAQL,OAAOK;iBACjB,EACA;AAAEjC,oBAAAA;AAAO,iBAAA,CAAA;AAGX,gBAAA,MAAMA,OAAOC,EAAE,CAACgB,KAAK,CAACd,kCAAAA,CAAAA,CAA0B+B,MAAM,CAAC;oBACrD7B,KAAAA,EAAO;AACL8B,wBAAAA,EAAAA,EAAIP,OAAOO;AACb,qBAAA;oBACAC,IAAAA,EAAM;AACJP,wBAAAA;AACF;AACF,iBAAA,CAAA;AACF,YAAA;AACF,QAAA;AAEA,QAAA,OAAOQ,iBAAW,SAAA,EAAW;AAAErC,YAAAA;SAAO,CAAA,CAAGsC,mBAAmB,CAACb,OAAAA,CAAQU,EAAE,CAAA;AACzE,IAAA,CAAA,CAAA;IAEA,MAAMI,iBAAAA,GAAoB,MAAMvC,MAAAA,CAAOC,EAAE,CAACgB,KAAK,CAACC,2BAAAA,CAAAA,CAAmBC,QAAQ,CAAC;QAC1Ed,KAAAA,EAAO;YACLe,MAAAA,EAAQ,IAAA;YACRC,UAAAA,EAAY;gBACVmB,QAAAA,EAAU;AACZ;AACF;AACF,KAAA,CAAA;IAEA5B,WAAAA,CAAMC,GAAG,CAAC0B,iBAAAA,EAAmB,OAAOd,OAAAA,GAAAA;AAClC,QAAA,OAAOzB,OAAOC,EAAE,CAACgB,KAAK,CAACC,2BAAAA,CAAAA,CAAmBgB,MAAM,CAAC;YAC/C7B,KAAAA,EAAO;AACL8B,gBAAAA,EAAAA,EAAIV,QAAQU;AACd,aAAA;YACAC,IAAAA,EAAM;gBACJhB,MAAAA,EAAQ;AACV;AACF,SAAA,CAAA;AACF,IAAA,CAAA,CAAA;AACF;AAEO,eAAeqB,6BAAAA,CAA8B,EAAEhD,eAAe,EAAEC,YAAY,EAAS,EAAA;AAC1F,IAAA,IAAID,eAAAA,KAAoBiD,SAAAA,IAAajD,eAAAA,KAAoB,IAAA,IAAQC,iBAAiBgD,SAAAA,EAAW;AAC3F,QAAA,MAAMC,+BAAAA,GAAkCC,MAAAA,CAAOlC,IAAI,CAACjB,eAAAA,CAAAA,CAAiBkC,MAAM,CACzE,CAAChC,GAAAA,GAAQF,eAAe,CAACE,GAAAA,CAAI,EAAEkD,OAAAA,EAASC,eAAAA,CAAAA;AAE1C,QAAA,MAAMC,mBAAmB,IAAIC,GAAAA,EAAAA;QAE7BpC,WAAAA,CACGC,GAAG,CAAC8B,+BAAAA,EAAiC,OAAOM,cAAAA,GAAAA;YAC3C,MAAMrD,cAAAA,GAAiBH,eAAe,CAACwD,cAAAA,CAAe;YACtD,MAAMpD,WAAAA,GAAcH,YAAY,CAACuD,cAAAA,CAAe;;AAGhD,YAAA,IAAI,CAACC,wBAAAA,CAAQtD,cAAAA,EAAgBuD,UAAAA,EAAYtD,aAAasD,UAAAA,CAAAA,EAAa;gBACjE,MAAM5B,OAAAA,GAAU,MAAMvB,MAAAA,CAAOC,EAAE,CAACgB,KAAK,CAACd,kCAAAA,CAAAA,CAA0BgB,QAAQ,CAAC;oBACvEd,KAAAA,EAAO;wBACLR,WAAAA,EAAaoD;AACf,qBAAA;oBACA3B,QAAAA,EAAU;wBACRE,KAAAA,EAAO,IAAA;wBACPC,OAAAA,EAAS;AACX;AACF,iBAAA,CAAA;AAEA,gBAAA,MAAMb,WAAAA,CAAMC,GAAG,CAACU,OAAAA,EAAS,OAAOK,MAAAA,GAAAA;oBAC9B,IAAIA,MAAAA,CAAOJ,KAAK,IAAII,MAAAA,CAAOH,OAAO,IAAIG,MAAAA,CAAOwB,IAAI,KAAK,SAAA,EAAW;wBAC/D,MAAMvB,YAAAA,GAAe,MAAMC,8BAAAA,CACzB;4BACEjC,WAAAA,EAAaoD,cAAAA;AACblB,4BAAAA,UAAAA,EAAYH,OAAOI,eAAe;AAClCC,4BAAAA,MAAAA,EAAQL,OAAOK;yBACjB,EACA;AAAEjC,4BAAAA;AAAO,yBAAA,CAAA;AAGX+C,wBAAAA,gBAAAA,CAAiBM,GAAG,CAACzB,MAAAA,CAAOH,OAAO,CAACU,EAAE,CAAA;AAEtC,wBAAA,MAAMnC,OAAOC,EAAE,CAACgB,KAAK,CAACd,kCAAAA,CAAAA,CAA0B+B,MAAM,CAAC;4BACrD7B,KAAAA,EAAO;AACL8B,gCAAAA,EAAAA,EAAIP,OAAOO;AACb,6BAAA;4BACAC,IAAAA,EAAM;AACJP,gCAAAA;AACF;AACF,yBAAA,CAAA;AACF,oBAAA;AACF,gBAAA,CAAA,CAAA;AACF,YAAA;AACF,QAAA,CAAA,CAAA,CACCyB,IAAI,CAAC,IAAA;;YAEJ1C,WAAAA,CAAMC,GAAG,CAACkC,gBAAAA,EAAkB,OAAOQ,SAAAA,GAAAA;AACjC,gBAAA,OAAOlB,iBAAW,SAAA,EAAW;AAAErC,oBAAAA;AAAO,iBAAA,CAAA,CAAGsC,mBAAmB,CAACiB,SAAAA,CAAAA;AAC/D,YAAA,CAAA,CAAA;AACF,QAAA,CAAA,CAAA;AACJ,IAAA;AACF;AAEO,eAAeC,2BAAAA,CAA4B,EAAE/D,eAAe,EAAEC,YAAY,EAAS,EAAA;AACxF,IAAA,IAAI,CAACD,eAAAA,EAAiB;AACpB,QAAA;AACF,IAAA;IAEA,IAAK,MAAME,OAAOD,YAAAA,CAAc;AAC9B,QAAA,IAAI,CAACD,eAAe,CAACE,GAAAA,CAAI,EAAE;AACzB,YAAA;AACF,QAAA;QAEA,MAAMC,cAAAA,GAAiBH,eAAe,CAACE,GAAAA,CAAI;QAC3C,MAAME,WAAAA,GAAcH,YAAY,CAACC,GAAAA,CAAI;;AAGrC,QAAA,IACEK,MAAAA,CAAOyD,YAAY,CAACC,sBAAsB,CAAC9D,cAAAA,CAAAA,KAAoB,IAAA,IAC/DI,MAAAA,CAAOyD,YAAY,CAACC,sBAAsB,CAAC7D,iBAAiB,KAAA,EAC5D;AACA,YAAA,MAAMG,OAAOC,EAAE,CACZC,YAAY,CAACC,kCAAAA,CAAAA,CACb+B,MAAM,CAAC;gBACND,MAAAA,EAAQ;AACV,aAAA,CAAA,CACC5B,KAAK,CAAC;gBAAER,WAAAA,EAAaF;AAAI,aAAA,CAAA,CACzBW,OAAO,EAAA;AACZ,QAAA;AACF,IAAA;AACF;AAEO,eAAeqD,0BAAAA,CAA2B,EAAElE,eAAe,EAAEC,YAAY,EAAS,EAAA;AACvF,IAAA,IAAI,CAACD,eAAAA,EAAiB;AACpB,QAAA;AACF,IAAA;IAEA,IAAK,MAAME,OAAOD,YAAAA,CAAc;AAC9B,QAAA,IAAI,CAACD,eAAe,CAACE,GAAAA,CAAI,EAAE;AACzB,YAAA;AACF,QAAA;QAEA,MAAMC,cAAAA,GAAiBH,eAAe,CAACE,GAAAA,CAAI;QAC3C,MAAME,WAAAA,GAAcH,YAAY,CAACC,GAAAA,CAAI;;AAGrC,QAAA,IACEK,MAAAA,CAAOyD,YAAY,CAACC,sBAAsB,CAAC9D,cAAAA,CAAAA,KAAoB,KAAA,IAC/DI,MAAAA,CAAOyD,YAAY,CAACC,sBAAsB,CAAC7D,iBAAiB,IAAA,EAC5D;AACA,YAAA,MAAM+D,aAAAA,GAAgB,MAAM5D,MAAAA,CAAOyD,YAAY,CAACI,gBAAgB,EAAA;AAEhE,YAAA,MAAM7D,OAAOC,EAAE,CACZC,YAAY,CAACC,kCAAAA,CAAAA,CACb+B,MAAM,CAAC;gBACND,MAAAA,EAAQ2B;AACV,aAAA,CAAA,CACCvD,KAAK,CAAC;gBAAER,WAAAA,EAAaF;AAAI,aAAA,CAAA,CACzBW,OAAO,EAAA;AACZ,QAAA;AACF,IAAA;AACF;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../server/src/migrations/index.ts"],"sourcesContent":["import type { Schema, UID } from '@strapi/types';\nimport { contentTypes as contentTypesUtils, async } from '@strapi/utils';\nimport isEqual from 'lodash/isEqual';\n\nimport { difference, keys } from 'lodash';\nimport { RELEASE_ACTION_MODEL_UID, RELEASE_MODEL_UID } from '../constants';\nimport { getDraftEntryValidStatus, getService } from '../utils';\nimport { Release } from '../../../shared/contracts/releases';\nimport { ReleaseAction } from '../../../shared/contracts/release-actions';\n\n// The core store saves content types as JSON: compare live attributes in that form, so values\n// JSON drops (e.g. the `publishedAt.default` function) do not count as a change\nconst toPersistedForm = (attributes: Schema.ContentType['attributes'] | undefined) =>\n JSON.parse(JSON.stringify(attributes ?? null));\n\ninterface Input {\n oldContentTypes: Record<string, Schema.ContentType>;\n contentTypes: Record<string, Schema.ContentType>;\n}\n\nexport async function deleteActionsOnDisableDraftAndPublish({\n oldContentTypes,\n contentTypes,\n}: Input) {\n if (!oldContentTypes) {\n return;\n }\n\n for (const uid in contentTypes) {\n if (!oldContentTypes[uid]) {\n continue;\n }\n\n const oldContentType = oldContentTypes[uid];\n const contentType = contentTypes[uid];\n\n if (\n contentTypesUtils.hasDraftAndPublish(oldContentType) &&\n !contentTypesUtils.hasDraftAndPublish(contentType)\n ) {\n await strapi.db\n ?.queryBuilder(RELEASE_ACTION_MODEL_UID)\n .delete()\n .where({ contentType: uid })\n .execute();\n }\n }\n}\n\nexport async function deleteActionsOnDeleteContentType({ oldContentTypes, contentTypes }: Input) {\n const deletedContentTypes = difference(keys(oldContentTypes), keys(contentTypes)) ?? [];\n\n if (deletedContentTypes.length) {\n await async.map(deletedContentTypes, async (deletedContentTypeUID: unknown) => {\n return strapi.db\n ?.queryBuilder(RELEASE_ACTION_MODEL_UID)\n .delete()\n .where({ contentType: deletedContentTypeUID })\n .execute();\n });\n }\n}\n\nexport async function migrateIsValidAndStatusReleases() {\n const releasesWithoutStatus = (await strapi.db.query(RELEASE_MODEL_UID).findMany({\n where: {\n status: null,\n releasedAt: null,\n },\n populate: {\n actions: {\n populate: {\n entry: true,\n },\n },\n },\n })) as Release[];\n\n async.map(releasesWithoutStatus, async (release: Release) => {\n const actions = release.actions;\n\n const notValidatedActions = actions.filter((action) => action.isEntryValid === null);\n\n for (const action of notValidatedActions) {\n // We need to check the Action is related to a valid entry because we can't assume this is gonna be always the case\n // example: users could make changes directly to their database, or data could be lost\n if (action.entry) {\n const isEntryValid = getDraftEntryValidStatus(\n {\n contentType: action.contentType,\n documentId: action.entryDocumentId,\n locale: action.locale,\n },\n { strapi }\n );\n\n await strapi.db.query(RELEASE_ACTION_MODEL_UID).update({\n where: {\n id: action.id,\n },\n data: {\n isEntryValid,\n },\n });\n }\n }\n\n return getService('release', { strapi }).updateReleaseStatus(release.id);\n });\n\n const publishedReleases = await strapi.db.query(RELEASE_MODEL_UID).findMany({\n where: {\n status: null,\n releasedAt: {\n $notNull: true,\n },\n },\n });\n\n async.map(publishedReleases, async (release: Release) => {\n return strapi.db.query(RELEASE_MODEL_UID).update({\n where: {\n id: release.id,\n },\n data: {\n status: 'done',\n },\n });\n });\n}\n\nexport async function revalidateChangedContentTypes({ oldContentTypes, contentTypes }: Input) {\n if (oldContentTypes !== undefined && oldContentTypes !== null && contentTypes !== undefined) {\n // Skip deleted content types: their model is gone, and `deleteActionsOnDeleteContentType`\n // removes their actions\n const contentTypesWithDraftAndPublish = Object.keys(oldContentTypes).filter(\n (uid) =>\n oldContentTypes[uid]?.options?.draftAndPublish === true && contentTypes[uid] !== undefined\n );\n const releasesAffected = new Set();\n\n await async.map(contentTypesWithDraftAndPublish, async (contentTypeUID: UID.ContentType) => {\n const oldContentType = oldContentTypes[contentTypeUID];\n const contentType = contentTypes[contentTypeUID];\n\n // If attributes have changed, we need to revalidate actions because maybe validations rules are different\n if (\n !isEqual(\n toPersistedForm(oldContentType?.attributes),\n toPersistedForm(contentType?.attributes)\n )\n ) {\n const actions = await strapi.db.query(RELEASE_ACTION_MODEL_UID).findMany({\n where: {\n contentType: contentTypeUID,\n // Released releases keep their `done` status\n release: {\n releasedAt: {\n $null: true,\n },\n },\n },\n populate: {\n release: true,\n },\n });\n\n await async.map(actions, async (action: ReleaseAction) => {\n // Actions reference their entry by `entryDocumentId` and `locale`, not by a relation\n if (\n action.release !== null &&\n action.release !== undefined &&\n action.type === 'publish'\n ) {\n const isEntryValid = await getDraftEntryValidStatus(\n {\n contentType: contentTypeUID,\n documentId: action.entryDocumentId,\n locale: action.locale,\n },\n { strapi }\n );\n\n releasesAffected.add(action.release.id);\n\n await strapi.db.query(RELEASE_ACTION_MODEL_UID).update({\n where: {\n id: action.id,\n },\n data: {\n isEntryValid,\n },\n });\n }\n });\n }\n });\n\n // We need to update the status of the releases affected\n await async.map(releasesAffected, async (releaseId: Release['id']) => {\n return getService('release', { strapi }).updateReleaseStatus(releaseId);\n });\n }\n}\n\nexport async function disableContentTypeLocalized({ oldContentTypes, contentTypes }: Input) {\n if (!oldContentTypes) {\n return;\n }\n\n for (const uid in contentTypes) {\n if (!oldContentTypes[uid]) {\n continue;\n }\n\n const oldContentType = oldContentTypes[uid];\n const contentType = contentTypes[uid];\n\n // if i18N is disabled remove non default locales before sync\n if (\n strapi.localization.isLocalizedContentType(oldContentType) === true &&\n strapi.localization.isLocalizedContentType(contentType) === false\n ) {\n await strapi.db\n .queryBuilder(RELEASE_ACTION_MODEL_UID)\n .update({\n locale: null,\n })\n .where({ contentType: uid })\n .execute();\n }\n }\n}\n\nexport async function enableContentTypeLocalized({ oldContentTypes, contentTypes }: Input) {\n if (!oldContentTypes) {\n return;\n }\n\n for (const uid in contentTypes) {\n if (!oldContentTypes[uid]) {\n continue;\n }\n\n const oldContentType = oldContentTypes[uid];\n const contentType = contentTypes[uid];\n\n // if i18N is enabled remove non default locales before sync\n if (\n strapi.localization.isLocalizedContentType(oldContentType) === false &&\n strapi.localization.isLocalizedContentType(contentType) === true\n ) {\n const defaultLocale = await strapi.localization.getDefaultLocale();\n\n await strapi.db\n .queryBuilder(RELEASE_ACTION_MODEL_UID)\n .update({\n locale: defaultLocale,\n })\n .where({ contentType: uid })\n .execute();\n }\n }\n}\n"],"names":["toPersistedForm","attributes","JSON","parse","stringify","deleteActionsOnDisableDraftAndPublish","oldContentTypes","contentTypes","uid","oldContentType","contentType","contentTypesUtils","hasDraftAndPublish","strapi","db","queryBuilder","RELEASE_ACTION_MODEL_UID","delete","where","execute","deleteActionsOnDeleteContentType","deletedContentTypes","difference","keys","length","async","map","deletedContentTypeUID","migrateIsValidAndStatusReleases","releasesWithoutStatus","query","RELEASE_MODEL_UID","findMany","status","releasedAt","populate","actions","entry","release","notValidatedActions","filter","action","isEntryValid","getDraftEntryValidStatus","documentId","entryDocumentId","locale","update","id","data","getService","updateReleaseStatus","publishedReleases","$notNull","revalidateChangedContentTypes","undefined","contentTypesWithDraftAndPublish","Object","options","draftAndPublish","releasesAffected","Set","contentTypeUID","isEqual","$null","type","add","releaseId","disableContentTypeLocalized","localization","isLocalizedContentType","enableContentTypeLocalized","defaultLocale","getDefaultLocale"],"mappings":"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"}
@@ -4,6 +4,9 @@ import { difference, keys } from 'lodash';
4
4
  import { RELEASE_ACTION_MODEL_UID, RELEASE_MODEL_UID } from '../constants.mjs';
5
5
  import { getDraftEntryValidStatus, getService } from '../utils/index.mjs';
6
6
 
7
+ // The core store saves content types as JSON: compare live attributes in that form, so values
8
+ // JSON drops (e.g. the `publishedAt.default` function) do not count as a change
9
+ const toPersistedForm = (attributes)=>JSON.parse(JSON.stringify(attributes ?? null));
7
10
  async function deleteActionsOnDisableDraftAndPublish({ oldContentTypes, contentTypes: contentTypes$1 }) {
8
11
  if (!oldContentTypes) {
9
12
  return;
@@ -94,24 +97,32 @@ async function migrateIsValidAndStatusReleases() {
94
97
  }
95
98
  async function revalidateChangedContentTypes({ oldContentTypes, contentTypes }) {
96
99
  if (oldContentTypes !== undefined && oldContentTypes !== null && contentTypes !== undefined) {
97
- const contentTypesWithDraftAndPublish = Object.keys(oldContentTypes).filter((uid)=>oldContentTypes[uid]?.options?.draftAndPublish);
100
+ // Skip deleted content types: their model is gone, and `deleteActionsOnDeleteContentType`
101
+ // removes their actions
102
+ const contentTypesWithDraftAndPublish = Object.keys(oldContentTypes).filter((uid)=>oldContentTypes[uid]?.options?.draftAndPublish === true && contentTypes[uid] !== undefined);
98
103
  const releasesAffected = new Set();
99
- async.map(contentTypesWithDraftAndPublish, async (contentTypeUID)=>{
104
+ await async.map(contentTypesWithDraftAndPublish, async (contentTypeUID)=>{
100
105
  const oldContentType = oldContentTypes[contentTypeUID];
101
106
  const contentType = contentTypes[contentTypeUID];
102
107
  // If attributes have changed, we need to revalidate actions because maybe validations rules are different
103
- if (!isEqual(oldContentType?.attributes, contentType?.attributes)) {
108
+ if (!isEqual(toPersistedForm(oldContentType?.attributes), toPersistedForm(contentType?.attributes))) {
104
109
  const actions = await strapi.db.query(RELEASE_ACTION_MODEL_UID).findMany({
105
110
  where: {
106
- contentType: contentTypeUID
111
+ contentType: contentTypeUID,
112
+ // Released releases keep their `done` status
113
+ release: {
114
+ releasedAt: {
115
+ $null: true
116
+ }
117
+ }
107
118
  },
108
119
  populate: {
109
- entry: true,
110
120
  release: true
111
121
  }
112
122
  });
113
123
  await async.map(actions, async (action)=>{
114
- if (action.entry && action.release && action.type === 'publish') {
124
+ // Actions reference their entry by `entryDocumentId` and `locale`, not by a relation
125
+ if (action.release !== null && action.release !== undefined && action.type === 'publish') {
115
126
  const isEntryValid = await getDraftEntryValidStatus({
116
127
  contentType: contentTypeUID,
117
128
  documentId: action.entryDocumentId,
@@ -131,13 +142,12 @@ async function revalidateChangedContentTypes({ oldContentTypes, contentTypes })
131
142
  }
132
143
  });
133
144
  }
134
- }).then(()=>{
135
- // We need to update the status of the releases affected
136
- async.map(releasesAffected, async (releaseId)=>{
137
- return getService('release', {
138
- strapi
139
- }).updateReleaseStatus(releaseId);
140
- });
145
+ });
146
+ // We need to update the status of the releases affected
147
+ await async.map(releasesAffected, async (releaseId)=>{
148
+ return getService('release', {
149
+ strapi
150
+ }).updateReleaseStatus(releaseId);
141
151
  });
142
152
  }
143
153
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../../../server/src/migrations/index.ts"],"sourcesContent":["import type { Schema, UID } from '@strapi/types';\nimport { contentTypes as contentTypesUtils, async } from '@strapi/utils';\nimport isEqual from 'lodash/isEqual';\n\nimport { difference, keys } from 'lodash';\nimport { RELEASE_ACTION_MODEL_UID, RELEASE_MODEL_UID } from '../constants';\nimport { getDraftEntryValidStatus, getService } from '../utils';\nimport { Release } from '../../../shared/contracts/releases';\nimport { ReleaseAction } from '../../../shared/contracts/release-actions';\n\ninterface Input {\n oldContentTypes: Record<string, Schema.ContentType>;\n contentTypes: Record<string, Schema.ContentType>;\n}\n\nexport async function deleteActionsOnDisableDraftAndPublish({\n oldContentTypes,\n contentTypes,\n}: Input) {\n if (!oldContentTypes) {\n return;\n }\n\n for (const uid in contentTypes) {\n if (!oldContentTypes[uid]) {\n continue;\n }\n\n const oldContentType = oldContentTypes[uid];\n const contentType = contentTypes[uid];\n\n if (\n contentTypesUtils.hasDraftAndPublish(oldContentType) &&\n !contentTypesUtils.hasDraftAndPublish(contentType)\n ) {\n await strapi.db\n ?.queryBuilder(RELEASE_ACTION_MODEL_UID)\n .delete()\n .where({ contentType: uid })\n .execute();\n }\n }\n}\n\nexport async function deleteActionsOnDeleteContentType({ oldContentTypes, contentTypes }: Input) {\n const deletedContentTypes = difference(keys(oldContentTypes), keys(contentTypes)) ?? [];\n\n if (deletedContentTypes.length) {\n await async.map(deletedContentTypes, async (deletedContentTypeUID: unknown) => {\n return strapi.db\n ?.queryBuilder(RELEASE_ACTION_MODEL_UID)\n .delete()\n .where({ contentType: deletedContentTypeUID })\n .execute();\n });\n }\n}\n\nexport async function migrateIsValidAndStatusReleases() {\n const releasesWithoutStatus = (await strapi.db.query(RELEASE_MODEL_UID).findMany({\n where: {\n status: null,\n releasedAt: null,\n },\n populate: {\n actions: {\n populate: {\n entry: true,\n },\n },\n },\n })) as Release[];\n\n async.map(releasesWithoutStatus, async (release: Release) => {\n const actions = release.actions;\n\n const notValidatedActions = actions.filter((action) => action.isEntryValid === null);\n\n for (const action of notValidatedActions) {\n // We need to check the Action is related to a valid entry because we can't assume this is gonna be always the case\n // example: users could make changes directly to their database, or data could be lost\n if (action.entry) {\n const isEntryValid = getDraftEntryValidStatus(\n {\n contentType: action.contentType,\n documentId: action.entryDocumentId,\n locale: action.locale,\n },\n { strapi }\n );\n\n await strapi.db.query(RELEASE_ACTION_MODEL_UID).update({\n where: {\n id: action.id,\n },\n data: {\n isEntryValid,\n },\n });\n }\n }\n\n return getService('release', { strapi }).updateReleaseStatus(release.id);\n });\n\n const publishedReleases = await strapi.db.query(RELEASE_MODEL_UID).findMany({\n where: {\n status: null,\n releasedAt: {\n $notNull: true,\n },\n },\n });\n\n async.map(publishedReleases, async (release: Release) => {\n return strapi.db.query(RELEASE_MODEL_UID).update({\n where: {\n id: release.id,\n },\n data: {\n status: 'done',\n },\n });\n });\n}\n\nexport async function revalidateChangedContentTypes({ oldContentTypes, contentTypes }: Input) {\n if (oldContentTypes !== undefined && oldContentTypes !== null && contentTypes !== undefined) {\n const contentTypesWithDraftAndPublish = Object.keys(oldContentTypes).filter(\n (uid) => oldContentTypes[uid]?.options?.draftAndPublish\n );\n const releasesAffected = new Set();\n\n async\n .map(contentTypesWithDraftAndPublish, async (contentTypeUID: UID.ContentType) => {\n const oldContentType = oldContentTypes[contentTypeUID];\n const contentType = contentTypes[contentTypeUID];\n\n // If attributes have changed, we need to revalidate actions because maybe validations rules are different\n if (!isEqual(oldContentType?.attributes, contentType?.attributes)) {\n const actions = await strapi.db.query(RELEASE_ACTION_MODEL_UID).findMany({\n where: {\n contentType: contentTypeUID,\n },\n populate: {\n entry: true,\n release: true,\n },\n });\n\n await async.map(actions, async (action: ReleaseAction) => {\n if (action.entry && action.release && action.type === 'publish') {\n const isEntryValid = await getDraftEntryValidStatus(\n {\n contentType: contentTypeUID,\n documentId: action.entryDocumentId,\n locale: action.locale,\n },\n { strapi }\n );\n\n releasesAffected.add(action.release.id);\n\n await strapi.db.query(RELEASE_ACTION_MODEL_UID).update({\n where: {\n id: action.id,\n },\n data: {\n isEntryValid,\n },\n });\n }\n });\n }\n })\n .then(() => {\n // We need to update the status of the releases affected\n async.map(releasesAffected, async (releaseId: Release['id']) => {\n return getService('release', { strapi }).updateReleaseStatus(releaseId);\n });\n });\n }\n}\n\nexport async function disableContentTypeLocalized({ oldContentTypes, contentTypes }: Input) {\n if (!oldContentTypes) {\n return;\n }\n\n for (const uid in contentTypes) {\n if (!oldContentTypes[uid]) {\n continue;\n }\n\n const oldContentType = oldContentTypes[uid];\n const contentType = contentTypes[uid];\n\n // if i18N is disabled remove non default locales before sync\n if (\n strapi.localization.isLocalizedContentType(oldContentType) === true &&\n strapi.localization.isLocalizedContentType(contentType) === false\n ) {\n await strapi.db\n .queryBuilder(RELEASE_ACTION_MODEL_UID)\n .update({\n locale: null,\n })\n .where({ contentType: uid })\n .execute();\n }\n }\n}\n\nexport async function enableContentTypeLocalized({ oldContentTypes, contentTypes }: Input) {\n if (!oldContentTypes) {\n return;\n }\n\n for (const uid in contentTypes) {\n if (!oldContentTypes[uid]) {\n continue;\n }\n\n const oldContentType = oldContentTypes[uid];\n const contentType = contentTypes[uid];\n\n // if i18N is enabled remove non default locales before sync\n if (\n strapi.localization.isLocalizedContentType(oldContentType) === false &&\n strapi.localization.isLocalizedContentType(contentType) === true\n ) {\n const defaultLocale = await strapi.localization.getDefaultLocale();\n\n await strapi.db\n .queryBuilder(RELEASE_ACTION_MODEL_UID)\n .update({\n locale: defaultLocale,\n })\n .where({ contentType: uid })\n .execute();\n }\n }\n}\n"],"names":["deleteActionsOnDisableDraftAndPublish","oldContentTypes","contentTypes","uid","oldContentType","contentType","contentTypesUtils","hasDraftAndPublish","strapi","db","queryBuilder","RELEASE_ACTION_MODEL_UID","delete","where","execute","deleteActionsOnDeleteContentType","deletedContentTypes","difference","keys","length","async","map","deletedContentTypeUID","migrateIsValidAndStatusReleases","releasesWithoutStatus","query","RELEASE_MODEL_UID","findMany","status","releasedAt","populate","actions","entry","release","notValidatedActions","filter","action","isEntryValid","getDraftEntryValidStatus","documentId","entryDocumentId","locale","update","id","data","getService","updateReleaseStatus","publishedReleases","$notNull","revalidateChangedContentTypes","undefined","contentTypesWithDraftAndPublish","Object","options","draftAndPublish","releasesAffected","Set","contentTypeUID","isEqual","attributes","type","add","then","releaseId","disableContentTypeLocalized","localization","isLocalizedContentType","enableContentTypeLocalized","defaultLocale","getDefaultLocale"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["../../../server/src/migrations/index.ts"],"sourcesContent":["import type { Schema, UID } from '@strapi/types';\nimport { contentTypes as contentTypesUtils, async } from '@strapi/utils';\nimport isEqual from 'lodash/isEqual';\n\nimport { difference, keys } from 'lodash';\nimport { RELEASE_ACTION_MODEL_UID, RELEASE_MODEL_UID } from '../constants';\nimport { getDraftEntryValidStatus, getService } from '../utils';\nimport { Release } from '../../../shared/contracts/releases';\nimport { ReleaseAction } from '../../../shared/contracts/release-actions';\n\n// The core store saves content types as JSON: compare live attributes in that form, so values\n// JSON drops (e.g. the `publishedAt.default` function) do not count as a change\nconst toPersistedForm = (attributes: Schema.ContentType['attributes'] | undefined) =>\n JSON.parse(JSON.stringify(attributes ?? null));\n\ninterface Input {\n oldContentTypes: Record<string, Schema.ContentType>;\n contentTypes: Record<string, Schema.ContentType>;\n}\n\nexport async function deleteActionsOnDisableDraftAndPublish({\n oldContentTypes,\n contentTypes,\n}: Input) {\n if (!oldContentTypes) {\n return;\n }\n\n for (const uid in contentTypes) {\n if (!oldContentTypes[uid]) {\n continue;\n }\n\n const oldContentType = oldContentTypes[uid];\n const contentType = contentTypes[uid];\n\n if (\n contentTypesUtils.hasDraftAndPublish(oldContentType) &&\n !contentTypesUtils.hasDraftAndPublish(contentType)\n ) {\n await strapi.db\n ?.queryBuilder(RELEASE_ACTION_MODEL_UID)\n .delete()\n .where({ contentType: uid })\n .execute();\n }\n }\n}\n\nexport async function deleteActionsOnDeleteContentType({ oldContentTypes, contentTypes }: Input) {\n const deletedContentTypes = difference(keys(oldContentTypes), keys(contentTypes)) ?? [];\n\n if (deletedContentTypes.length) {\n await async.map(deletedContentTypes, async (deletedContentTypeUID: unknown) => {\n return strapi.db\n ?.queryBuilder(RELEASE_ACTION_MODEL_UID)\n .delete()\n .where({ contentType: deletedContentTypeUID })\n .execute();\n });\n }\n}\n\nexport async function migrateIsValidAndStatusReleases() {\n const releasesWithoutStatus = (await strapi.db.query(RELEASE_MODEL_UID).findMany({\n where: {\n status: null,\n releasedAt: null,\n },\n populate: {\n actions: {\n populate: {\n entry: true,\n },\n },\n },\n })) as Release[];\n\n async.map(releasesWithoutStatus, async (release: Release) => {\n const actions = release.actions;\n\n const notValidatedActions = actions.filter((action) => action.isEntryValid === null);\n\n for (const action of notValidatedActions) {\n // We need to check the Action is related to a valid entry because we can't assume this is gonna be always the case\n // example: users could make changes directly to their database, or data could be lost\n if (action.entry) {\n const isEntryValid = getDraftEntryValidStatus(\n {\n contentType: action.contentType,\n documentId: action.entryDocumentId,\n locale: action.locale,\n },\n { strapi }\n );\n\n await strapi.db.query(RELEASE_ACTION_MODEL_UID).update({\n where: {\n id: action.id,\n },\n data: {\n isEntryValid,\n },\n });\n }\n }\n\n return getService('release', { strapi }).updateReleaseStatus(release.id);\n });\n\n const publishedReleases = await strapi.db.query(RELEASE_MODEL_UID).findMany({\n where: {\n status: null,\n releasedAt: {\n $notNull: true,\n },\n },\n });\n\n async.map(publishedReleases, async (release: Release) => {\n return strapi.db.query(RELEASE_MODEL_UID).update({\n where: {\n id: release.id,\n },\n data: {\n status: 'done',\n },\n });\n });\n}\n\nexport async function revalidateChangedContentTypes({ oldContentTypes, contentTypes }: Input) {\n if (oldContentTypes !== undefined && oldContentTypes !== null && contentTypes !== undefined) {\n // Skip deleted content types: their model is gone, and `deleteActionsOnDeleteContentType`\n // removes their actions\n const contentTypesWithDraftAndPublish = Object.keys(oldContentTypes).filter(\n (uid) =>\n oldContentTypes[uid]?.options?.draftAndPublish === true && contentTypes[uid] !== undefined\n );\n const releasesAffected = new Set();\n\n await async.map(contentTypesWithDraftAndPublish, async (contentTypeUID: UID.ContentType) => {\n const oldContentType = oldContentTypes[contentTypeUID];\n const contentType = contentTypes[contentTypeUID];\n\n // If attributes have changed, we need to revalidate actions because maybe validations rules are different\n if (\n !isEqual(\n toPersistedForm(oldContentType?.attributes),\n toPersistedForm(contentType?.attributes)\n )\n ) {\n const actions = await strapi.db.query(RELEASE_ACTION_MODEL_UID).findMany({\n where: {\n contentType: contentTypeUID,\n // Released releases keep their `done` status\n release: {\n releasedAt: {\n $null: true,\n },\n },\n },\n populate: {\n release: true,\n },\n });\n\n await async.map(actions, async (action: ReleaseAction) => {\n // Actions reference their entry by `entryDocumentId` and `locale`, not by a relation\n if (\n action.release !== null &&\n action.release !== undefined &&\n action.type === 'publish'\n ) {\n const isEntryValid = await getDraftEntryValidStatus(\n {\n contentType: contentTypeUID,\n documentId: action.entryDocumentId,\n locale: action.locale,\n },\n { strapi }\n );\n\n releasesAffected.add(action.release.id);\n\n await strapi.db.query(RELEASE_ACTION_MODEL_UID).update({\n where: {\n id: action.id,\n },\n data: {\n isEntryValid,\n },\n });\n }\n });\n }\n });\n\n // We need to update the status of the releases affected\n await async.map(releasesAffected, async (releaseId: Release['id']) => {\n return getService('release', { strapi }).updateReleaseStatus(releaseId);\n });\n }\n}\n\nexport async function disableContentTypeLocalized({ oldContentTypes, contentTypes }: Input) {\n if (!oldContentTypes) {\n return;\n }\n\n for (const uid in contentTypes) {\n if (!oldContentTypes[uid]) {\n continue;\n }\n\n const oldContentType = oldContentTypes[uid];\n const contentType = contentTypes[uid];\n\n // if i18N is disabled remove non default locales before sync\n if (\n strapi.localization.isLocalizedContentType(oldContentType) === true &&\n strapi.localization.isLocalizedContentType(contentType) === false\n ) {\n await strapi.db\n .queryBuilder(RELEASE_ACTION_MODEL_UID)\n .update({\n locale: null,\n })\n .where({ contentType: uid })\n .execute();\n }\n }\n}\n\nexport async function enableContentTypeLocalized({ oldContentTypes, contentTypes }: Input) {\n if (!oldContentTypes) {\n return;\n }\n\n for (const uid in contentTypes) {\n if (!oldContentTypes[uid]) {\n continue;\n }\n\n const oldContentType = oldContentTypes[uid];\n const contentType = contentTypes[uid];\n\n // if i18N is enabled remove non default locales before sync\n if (\n strapi.localization.isLocalizedContentType(oldContentType) === false &&\n strapi.localization.isLocalizedContentType(contentType) === true\n ) {\n const defaultLocale = await strapi.localization.getDefaultLocale();\n\n await strapi.db\n .queryBuilder(RELEASE_ACTION_MODEL_UID)\n .update({\n locale: defaultLocale,\n })\n .where({ contentType: uid })\n .execute();\n }\n }\n}\n"],"names":["toPersistedForm","attributes","JSON","parse","stringify","deleteActionsOnDisableDraftAndPublish","oldContentTypes","contentTypes","uid","oldContentType","contentType","contentTypesUtils","hasDraftAndPublish","strapi","db","queryBuilder","RELEASE_ACTION_MODEL_UID","delete","where","execute","deleteActionsOnDeleteContentType","deletedContentTypes","difference","keys","length","async","map","deletedContentTypeUID","migrateIsValidAndStatusReleases","releasesWithoutStatus","query","RELEASE_MODEL_UID","findMany","status","releasedAt","populate","actions","entry","release","notValidatedActions","filter","action","isEntryValid","getDraftEntryValidStatus","documentId","entryDocumentId","locale","update","id","data","getService","updateReleaseStatus","publishedReleases","$notNull","revalidateChangedContentTypes","undefined","contentTypesWithDraftAndPublish","Object","options","draftAndPublish","releasesAffected","Set","contentTypeUID","isEqual","$null","type","add","releaseId","disableContentTypeLocalized","localization","isLocalizedContentType","enableContentTypeLocalized","defaultLocale","getDefaultLocale"],"mappings":"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"}
@@ -52,10 +52,8 @@ const createReleaseActionService = ({ strapi })=>{
52
52
  const { validateEntryData, validateUniqueEntry } = index.getService('release-validation', {
53
53
  strapi
54
54
  });
55
- await Promise.all([
56
- validateEntryData(action.contentType, action.entryDocumentId),
57
- validateUniqueEntry(releaseId, action)
58
- ]);
55
+ validateEntryData(action.contentType, action.entryDocumentId);
56
+ await validateUniqueEntry(releaseId, action);
59
57
  // If we are adding a singleType, we need to append the documentId of that singleType
60
58
  const model = strapi.contentType(action.contentType);
61
59
  if (model.kind === 'singleType') {