@strapi/content-manager 5.0.0-beta.8 → 5.0.0-beta.9

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 (82) hide show
  1. package/dist/_chunks/{ComponentConfigurationPage-CuWgXugY.mjs → ComponentConfigurationPage-BMajAl1u.mjs} +3 -3
  2. package/dist/_chunks/{ComponentConfigurationPage-CuWgXugY.mjs.map → ComponentConfigurationPage-BMajAl1u.mjs.map} +1 -1
  3. package/dist/_chunks/{ComponentConfigurationPage-by0e_kNd.js → ComponentConfigurationPage-y_7iLdmB.js} +3 -3
  4. package/dist/_chunks/{ComponentConfigurationPage-by0e_kNd.js.map → ComponentConfigurationPage-y_7iLdmB.js.map} +1 -1
  5. package/dist/_chunks/{EditConfigurationPage-CqBeCPGH.js → EditConfigurationPage-CPVB8Uqc.js} +3 -3
  6. package/dist/_chunks/{EditConfigurationPage-CqBeCPGH.js.map → EditConfigurationPage-CPVB8Uqc.js.map} +1 -1
  7. package/dist/_chunks/{EditConfigurationPage-DbI4KMyz.mjs → EditConfigurationPage-CcOoD26O.mjs} +3 -3
  8. package/dist/_chunks/{EditConfigurationPage-DbI4KMyz.mjs.map → EditConfigurationPage-CcOoD26O.mjs.map} +1 -1
  9. package/dist/_chunks/{EditViewPage-ChgloMyO.js → EditViewPage-CTTDHKkQ.js} +3 -3
  10. package/dist/_chunks/{EditViewPage-ChgloMyO.js.map → EditViewPage-CTTDHKkQ.js.map} +1 -1
  11. package/dist/_chunks/{EditViewPage-dFPBya9U.mjs → EditViewPage-DWb0DE7R.mjs} +3 -3
  12. package/dist/_chunks/{EditViewPage-dFPBya9U.mjs.map → EditViewPage-DWb0DE7R.mjs.map} +1 -1
  13. package/dist/_chunks/{Field-dLk-vgLL.js → Field-C5Z1Ivdv.js} +3 -3
  14. package/dist/_chunks/{Field-dLk-vgLL.js.map → Field-C5Z1Ivdv.js.map} +1 -1
  15. package/dist/_chunks/{Field-C1nUKcdS.mjs → Field-DnStdvQw.mjs} +3 -3
  16. package/dist/_chunks/{Field-C1nUKcdS.mjs.map → Field-DnStdvQw.mjs.map} +1 -1
  17. package/dist/_chunks/{Form-CbXtmHC_.js → Form-B81OtW-k.js} +2 -2
  18. package/dist/_chunks/{Form-CbXtmHC_.js.map → Form-B81OtW-k.js.map} +1 -1
  19. package/dist/_chunks/{Form-DOlpi7Js.mjs → Form-DqGgE55Q.mjs} +2 -2
  20. package/dist/_chunks/{Form-DOlpi7Js.mjs.map → Form-DqGgE55Q.mjs.map} +1 -1
  21. package/dist/_chunks/{History-BjDfohBr.js → History-4NbOq2dX.js} +95 -13
  22. package/dist/_chunks/History-4NbOq2dX.js.map +1 -0
  23. package/dist/_chunks/{History-BFNUAiGc.mjs → History-DS6-HCYX.mjs} +95 -13
  24. package/dist/_chunks/History-DS6-HCYX.mjs.map +1 -0
  25. package/dist/_chunks/{ListConfigurationPage-IQBgWTaa.js → ListConfigurationPage-CpfstlYY.js} +2 -2
  26. package/dist/_chunks/{ListConfigurationPage-IQBgWTaa.js.map → ListConfigurationPage-CpfstlYY.js.map} +1 -1
  27. package/dist/_chunks/{ListConfigurationPage-DDi0KqFm.mjs → ListConfigurationPage-DQJJltko.mjs} +2 -2
  28. package/dist/_chunks/{ListConfigurationPage-DDi0KqFm.mjs.map → ListConfigurationPage-DQJJltko.mjs.map} +1 -1
  29. package/dist/_chunks/{ListViewPage-CZYGqlvF.js → ListViewPage-CA3I75m5.js} +16 -4
  30. package/dist/_chunks/ListViewPage-CA3I75m5.js.map +1 -0
  31. package/dist/_chunks/{ListViewPage-BPjljUsH.mjs → ListViewPage-nQrOQuVo.mjs} +17 -5
  32. package/dist/_chunks/ListViewPage-nQrOQuVo.mjs.map +1 -0
  33. package/dist/_chunks/{NoContentTypePage-DaWw67K-.mjs → NoContentTypePage-DbnHE22g.mjs} +2 -2
  34. package/dist/_chunks/{NoContentTypePage-DaWw67K-.mjs.map → NoContentTypePage-DbnHE22g.mjs.map} +1 -1
  35. package/dist/_chunks/{NoContentTypePage-BOAI6VZ1.js → NoContentTypePage-Dldu-_Mx.js} +2 -2
  36. package/dist/_chunks/{NoContentTypePage-BOAI6VZ1.js.map → NoContentTypePage-Dldu-_Mx.js.map} +1 -1
  37. package/dist/_chunks/{NoPermissionsPage-cYEtLc_e.js → NoPermissionsPage-CO2MK200.js} +2 -2
  38. package/dist/_chunks/{NoPermissionsPage-cYEtLc_e.js.map → NoPermissionsPage-CO2MK200.js.map} +1 -1
  39. package/dist/_chunks/{NoPermissionsPage-CZrJH00p.mjs → NoPermissionsPage-fOIkQM0v.mjs} +2 -2
  40. package/dist/_chunks/{NoPermissionsPage-CZrJH00p.mjs.map → NoPermissionsPage-fOIkQM0v.mjs.map} +1 -1
  41. package/dist/_chunks/{Relations-DTowyge2.mjs → Relations-BDRl99Ux.mjs} +4 -4
  42. package/dist/_chunks/{Relations-DTowyge2.mjs.map → Relations-BDRl99Ux.mjs.map} +1 -1
  43. package/dist/_chunks/{Relations-DU6B7irU.js → Relations-DG2jnOcr.js} +4 -4
  44. package/dist/_chunks/{Relations-DU6B7irU.js.map → Relations-DG2jnOcr.js.map} +1 -1
  45. package/dist/_chunks/{en-GCOTL6jR.mjs → en-Ux26r5pl.mjs} +5 -1
  46. package/dist/_chunks/{en-GCOTL6jR.mjs.map → en-Ux26r5pl.mjs.map} +1 -1
  47. package/dist/_chunks/{en-DTULi5-d.js → en-fbKQxLGn.js} +5 -1
  48. package/dist/_chunks/{en-DTULi5-d.js.map → en-fbKQxLGn.js.map} +1 -1
  49. package/dist/_chunks/{index-CCJeB7Rw.js → index-BZoNZMXL.js} +1290 -833
  50. package/dist/_chunks/index-BZoNZMXL.js.map +1 -0
  51. package/dist/_chunks/{index-BaGHmIir.mjs → index-Drt2DN7v.mjs} +1308 -851
  52. package/dist/_chunks/index-Drt2DN7v.mjs.map +1 -0
  53. package/dist/_chunks/{layout-BinjszSQ.mjs → layout-BzAbmoO6.mjs} +17 -12
  54. package/dist/_chunks/layout-BzAbmoO6.mjs.map +1 -0
  55. package/dist/_chunks/{layout-ni_L9kT1.js → layout-DEYBqgF1.js} +17 -12
  56. package/dist/_chunks/layout-DEYBqgF1.js.map +1 -0
  57. package/dist/_chunks/{relations-CeJAJc5I.js → relations-D0eZ4VWw.js} +2 -2
  58. package/dist/_chunks/{relations-CeJAJc5I.js.map → relations-D0eZ4VWw.js.map} +1 -1
  59. package/dist/_chunks/{relations-c91ji5eR.mjs → relations-D26zVRdi.mjs} +2 -2
  60. package/dist/_chunks/{relations-c91ji5eR.mjs.map → relations-D26zVRdi.mjs.map} +1 -1
  61. package/dist/admin/index.js +1 -1
  62. package/dist/admin/index.mjs +5 -5
  63. package/dist/admin/src/history/components/VersionInputRenderer.d.ts +1 -1
  64. package/dist/admin/src/hooks/useDocumentActions.d.ts +1 -1
  65. package/dist/admin/src/pages/ListView/components/BulkActions/PublishAction.d.ts +14 -0
  66. package/dist/server/index.js +15 -11
  67. package/dist/server/index.js.map +1 -1
  68. package/dist/server/index.mjs +15 -11
  69. package/dist/server/index.mjs.map +1 -1
  70. package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
  71. package/dist/server/src/controllers/single-types.d.ts.map +1 -1
  72. package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
  73. package/dist/server/src/services/utils/populate.d.ts.map +1 -1
  74. package/package.json +6 -6
  75. package/dist/_chunks/History-BFNUAiGc.mjs.map +0 -1
  76. package/dist/_chunks/History-BjDfohBr.js.map +0 -1
  77. package/dist/_chunks/ListViewPage-BPjljUsH.mjs.map +0 -1
  78. package/dist/_chunks/ListViewPage-CZYGqlvF.js.map +0 -1
  79. package/dist/_chunks/index-BaGHmIir.mjs.map +0 -1
  80. package/dist/_chunks/index-CCJeB7Rw.js.map +0 -1
  81. package/dist/_chunks/layout-BinjszSQ.mjs.map +0 -1
  82. package/dist/_chunks/layout-ni_L9kT1.js.map +0 -1
@@ -948,12 +948,13 @@ const useDocumentActions = () => {
948
948
  );
949
949
  const [discardDocument] = useDiscardDocumentMutation();
950
950
  const discard = React__namespace.useCallback(
951
- async ({ collectionType, model, documentId }) => {
951
+ async ({ collectionType, model, documentId, params }) => {
952
952
  try {
953
953
  const res = await discardDocument({
954
954
  collectionType,
955
955
  model,
956
- documentId
956
+ documentId,
957
+ params
957
958
  });
958
959
  if ("error" in res) {
959
960
  toggleNotification({
@@ -1285,7 +1286,7 @@ const useDocumentActions = () => {
1285
1286
  };
1286
1287
  };
1287
1288
  const ProtectedHistoryPage = React.lazy(
1288
- () => Promise.resolve().then(() => require("./History-BjDfohBr.js")).then((mod) => ({ default: mod.ProtectedHistoryPage }))
1289
+ () => Promise.resolve().then(() => require("./History-4NbOq2dX.js")).then((mod) => ({ default: mod.ProtectedHistoryPage }))
1289
1290
  );
1290
1291
  const routes$1 = [
1291
1292
  {
@@ -1298,31 +1299,31 @@ const routes$1 = [
1298
1299
  }
1299
1300
  ];
1300
1301
  const ProtectedEditViewPage = React.lazy(
1301
- () => Promise.resolve().then(() => require("./EditViewPage-ChgloMyO.js")).then((mod) => ({ default: mod.ProtectedEditViewPage }))
1302
+ () => Promise.resolve().then(() => require("./EditViewPage-CTTDHKkQ.js")).then((mod) => ({ default: mod.ProtectedEditViewPage }))
1302
1303
  );
1303
1304
  const ProtectedListViewPage = React.lazy(
1304
- () => Promise.resolve().then(() => require("./ListViewPage-CZYGqlvF.js")).then((mod) => ({ default: mod.ProtectedListViewPage }))
1305
+ () => Promise.resolve().then(() => require("./ListViewPage-CA3I75m5.js")).then((mod) => ({ default: mod.ProtectedListViewPage }))
1305
1306
  );
1306
1307
  const ProtectedListConfiguration = React.lazy(
1307
- () => Promise.resolve().then(() => require("./ListConfigurationPage-IQBgWTaa.js")).then((mod) => ({
1308
+ () => Promise.resolve().then(() => require("./ListConfigurationPage-CpfstlYY.js")).then((mod) => ({
1308
1309
  default: mod.ProtectedListConfiguration
1309
1310
  }))
1310
1311
  );
1311
1312
  const ProtectedEditConfigurationPage = React.lazy(
1312
- () => Promise.resolve().then(() => require("./EditConfigurationPage-CqBeCPGH.js")).then((mod) => ({
1313
+ () => Promise.resolve().then(() => require("./EditConfigurationPage-CPVB8Uqc.js")).then((mod) => ({
1313
1314
  default: mod.ProtectedEditConfigurationPage
1314
1315
  }))
1315
1316
  );
1316
1317
  const ProtectedComponentConfigurationPage = React.lazy(
1317
- () => Promise.resolve().then(() => require("./ComponentConfigurationPage-by0e_kNd.js")).then((mod) => ({
1318
+ () => Promise.resolve().then(() => require("./ComponentConfigurationPage-y_7iLdmB.js")).then((mod) => ({
1318
1319
  default: mod.ProtectedComponentConfigurationPage
1319
1320
  }))
1320
1321
  );
1321
1322
  const NoPermissions = React.lazy(
1322
- () => Promise.resolve().then(() => require("./NoPermissionsPage-cYEtLc_e.js")).then((mod) => ({ default: mod.NoPermissions }))
1323
+ () => Promise.resolve().then(() => require("./NoPermissionsPage-CO2MK200.js")).then((mod) => ({ default: mod.NoPermissions }))
1323
1324
  );
1324
1325
  const NoContentType = React.lazy(
1325
- () => Promise.resolve().then(() => require("./NoContentTypePage-BOAI6VZ1.js")).then((mod) => ({ default: mod.NoContentType }))
1326
+ () => Promise.resolve().then(() => require("./NoContentTypePage-Dldu-_Mx.js")).then((mod) => ({ default: mod.NoContentType }))
1326
1327
  );
1327
1328
  const CollectionTypePages = () => {
1328
1329
  const { collectionType } = reactRouterDom.useParams();
@@ -1666,7 +1667,7 @@ const DocumentActionModal = ({
1666
1667
  )
1667
1668
  ] });
1668
1669
  };
1669
- const PublishAction = ({
1670
+ const PublishAction$1 = ({
1670
1671
  activeTab,
1671
1672
  documentId,
1672
1673
  model,
@@ -1751,7 +1752,7 @@ const PublishAction = ({
1751
1752
  }
1752
1753
  };
1753
1754
  };
1754
- PublishAction.type = "publish";
1755
+ PublishAction$1.type = "publish";
1755
1756
  const UpdateAction = ({
1756
1757
  activeTab,
1757
1758
  documentId,
@@ -2057,7 +2058,7 @@ const StyledCrossCircle = styledComponents.styled(Icons.CrossCircle)`
2057
2058
  fill: currentColor;
2058
2059
  }
2059
2060
  `;
2060
- const DEFAULT_ACTIONS = [PublishAction, UpdateAction, UnpublishAction$1, DiscardAction];
2061
+ const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
2061
2062
  const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
2062
2063
  const RelativeTime = React__namespace.forwardRef(
2063
2064
  ({ timestamp, customIntervals = [], ...restProps }, forwardedRef) => {
@@ -2512,910 +2513,1366 @@ const Panel = React__namespace.forwardRef(({ children, title }, ref) => {
2512
2513
  }
2513
2514
  );
2514
2515
  });
2515
- const BulkActionsRenderer = () => {
2516
- const plugins = strapiAdmin.useStrapiApp("BulkActionsRenderer", (state) => state.plugins);
2517
- const { model, collectionType } = useDoc();
2518
- const { selectedRows } = strapiAdmin.useTable("BulkActionsRenderer", (state) => state);
2519
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 2, children: /* @__PURE__ */ jsxRuntime.jsx(
2520
- strapiAdmin.DescriptionComponentRenderer,
2521
- {
2522
- props: {
2523
- model,
2524
- collectionType,
2525
- documents: selectedRows
2526
- },
2527
- descriptions: plugins["content-manager"].apis.getBulkActions(),
2528
- children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsxRuntime.jsx(BulkActionAction, { ...action }, action.id))
2529
- }
2530
- ) });
2516
+ const HOOKS = {
2517
+ /**
2518
+ * Hook that allows to mutate the displayed headers of the list view table
2519
+ * @constant
2520
+ * @type {string}
2521
+ */
2522
+ INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
2523
+ /**
2524
+ * Hook that allows to mutate the CM's collection types links pre-set filters
2525
+ * @constant
2526
+ * @type {string}
2527
+ */
2528
+ MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
2529
+ /**
2530
+ * Hook that allows to mutate the CM's edit view layout
2531
+ * @constant
2532
+ * @type {string}
2533
+ */
2534
+ MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
2535
+ /**
2536
+ * Hook that allows to mutate the CM's single types links pre-set filters
2537
+ * @constant
2538
+ * @type {string}
2539
+ */
2540
+ MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
2531
2541
  };
2532
- const BulkActionAction = (action) => {
2533
- const [dialogId, setDialogId] = React__namespace.useState(null);
2542
+ const contentTypesApi = contentManagerApi.injectEndpoints({
2543
+ endpoints: (builder) => ({
2544
+ getContentTypeConfiguration: builder.query({
2545
+ query: (uid) => ({
2546
+ url: `/content-manager/content-types/${uid}/configuration`,
2547
+ method: "GET"
2548
+ }),
2549
+ transformResponse: (response) => response.data,
2550
+ providesTags: (_result, _error, uid) => [
2551
+ { type: "ContentTypesConfiguration", id: uid },
2552
+ { type: "ContentTypeSettings", id: "LIST" }
2553
+ ]
2554
+ }),
2555
+ getAllContentTypeSettings: builder.query({
2556
+ query: () => "/content-manager/content-types-settings",
2557
+ transformResponse: (response) => response.data,
2558
+ providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
2559
+ }),
2560
+ updateContentTypeConfiguration: builder.mutation({
2561
+ query: ({ uid, ...body }) => ({
2562
+ url: `/content-manager/content-types/${uid}/configuration`,
2563
+ method: "PUT",
2564
+ data: body
2565
+ }),
2566
+ transformResponse: (response) => response.data,
2567
+ invalidatesTags: (_result, _error, { uid }) => [
2568
+ { type: "ContentTypesConfiguration", id: uid },
2569
+ { type: "ContentTypeSettings", id: "LIST" },
2570
+ // Is this necessary?
2571
+ { type: "InitialData" }
2572
+ ]
2573
+ })
2574
+ })
2575
+ });
2576
+ const {
2577
+ useGetContentTypeConfigurationQuery,
2578
+ useGetAllContentTypeSettingsQuery,
2579
+ useUpdateContentTypeConfigurationMutation
2580
+ } = contentTypesApi;
2581
+ const checkIfAttributeIsDisplayable = (attribute) => {
2582
+ const { type } = attribute;
2583
+ if (type === "relation") {
2584
+ return !attribute.relation.toLowerCase().includes("morph");
2585
+ }
2586
+ return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
2587
+ };
2588
+ const getMainField = (attribute, mainFieldName, { schemas, components }) => {
2589
+ if (!mainFieldName) {
2590
+ return void 0;
2591
+ }
2592
+ const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
2593
+ // @ts-expect-error – `targetModel` does exist on the attribute for a relation.
2594
+ schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
2595
+ );
2596
+ return {
2597
+ name: mainFieldName,
2598
+ type: mainFieldType ?? "string"
2599
+ };
2600
+ };
2601
+ const DEFAULT_SETTINGS = {
2602
+ bulkable: false,
2603
+ filterable: false,
2604
+ searchable: false,
2605
+ pagination: false,
2606
+ defaultSortBy: "",
2607
+ defaultSortOrder: "asc",
2608
+ mainField: "id",
2609
+ pageSize: 10
2610
+ };
2611
+ const useDocumentLayout = (model) => {
2612
+ const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
2613
+ const [{ query }] = strapiAdmin.useQueryParams();
2614
+ const runHookWaterfall = strapiAdmin.useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
2534
2615
  const { toggleNotification } = strapiAdmin.useNotification();
2535
- const handleClick = (action2) => (e) => {
2536
- const { onClick, dialog, id } = action2;
2537
- if (onClick) {
2538
- onClick(e);
2616
+ const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
2617
+ const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
2618
+ const {
2619
+ data,
2620
+ isLoading: isLoadingConfigs,
2621
+ error,
2622
+ isFetching: isFetchingConfigs
2623
+ } = useGetContentTypeConfigurationQuery(model);
2624
+ const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
2625
+ React__namespace.useEffect(() => {
2626
+ if (error) {
2627
+ toggleNotification({
2628
+ type: "danger",
2629
+ message: formatAPIError(error)
2630
+ });
2539
2631
  }
2540
- if (dialog) {
2541
- switch (dialog.type) {
2542
- case "notification":
2543
- toggleNotification({
2544
- title: dialog.title,
2545
- message: dialog.content,
2546
- type: dialog.status,
2547
- timeout: dialog.timeout,
2548
- onClose: dialog.onClose
2549
- });
2550
- break;
2551
- case "dialog":
2552
- case "modal": {
2553
- e.preventDefault();
2554
- setDialogId(id);
2555
- }
2632
+ }, [error, formatAPIError, toggleNotification]);
2633
+ const editLayout = React__namespace.useMemo(
2634
+ () => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
2635
+ layout: [],
2636
+ components: {},
2637
+ metadatas: {},
2638
+ options: {},
2639
+ settings: DEFAULT_SETTINGS
2640
+ },
2641
+ [data, isLoading, schemas, schema, components]
2642
+ );
2643
+ const listLayout = React__namespace.useMemo(() => {
2644
+ return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
2645
+ layout: [],
2646
+ metadatas: {},
2647
+ options: {},
2648
+ settings: DEFAULT_SETTINGS
2649
+ };
2650
+ }, [data, isLoading, schemas, schema, components]);
2651
+ const { layout: edit } = React__namespace.useMemo(
2652
+ () => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
2653
+ layout: editLayout,
2654
+ query
2655
+ }),
2656
+ [editLayout, query, runHookWaterfall]
2657
+ );
2658
+ return {
2659
+ error,
2660
+ isLoading,
2661
+ edit,
2662
+ list: listLayout
2663
+ };
2664
+ };
2665
+ const useDocLayout = () => {
2666
+ const { model } = useDoc();
2667
+ return useDocumentLayout(model);
2668
+ };
2669
+ const formatEditLayout = (data, {
2670
+ schemas,
2671
+ schema,
2672
+ components
2673
+ }) => {
2674
+ let currentPanelIndex = 0;
2675
+ const panelledEditAttributes = convertEditLayoutToFieldLayouts(
2676
+ data.contentType.layouts.edit,
2677
+ schema?.attributes,
2678
+ data.contentType.metadatas,
2679
+ { configurations: data.components, schemas: components },
2680
+ schemas
2681
+ ).reduce((panels, row) => {
2682
+ if (row.some((field) => field.type === "dynamiczone")) {
2683
+ panels.push([row]);
2684
+ currentPanelIndex += 2;
2685
+ } else {
2686
+ if (!panels[currentPanelIndex]) {
2687
+ panels.push([]);
2556
2688
  }
2689
+ panels[currentPanelIndex].push(row);
2557
2690
  }
2558
- };
2559
- const handleClose = () => {
2560
- setDialogId(null);
2561
- if (action.dialog?.type === "modal" && action.dialog?.onClose) {
2562
- action.dialog.onClose();
2691
+ return panels;
2692
+ }, []);
2693
+ const componentEditAttributes = Object.entries(data.components).reduce(
2694
+ (acc, [uid, configuration]) => {
2695
+ acc[uid] = {
2696
+ layout: convertEditLayoutToFieldLayouts(
2697
+ configuration.layouts.edit,
2698
+ components[uid].attributes,
2699
+ configuration.metadatas
2700
+ ),
2701
+ settings: {
2702
+ ...configuration.settings,
2703
+ icon: components[uid].info.icon,
2704
+ displayName: components[uid].info.displayName
2705
+ }
2706
+ };
2707
+ return acc;
2708
+ },
2709
+ {}
2710
+ );
2711
+ const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
2712
+ (acc, [attribute, metadata]) => {
2713
+ return {
2714
+ ...acc,
2715
+ [attribute]: metadata.edit
2716
+ };
2717
+ },
2718
+ {}
2719
+ );
2720
+ return {
2721
+ layout: panelledEditAttributes,
2722
+ components: componentEditAttributes,
2723
+ metadatas: editMetadatas,
2724
+ settings: {
2725
+ ...data.contentType.settings,
2726
+ displayName: schema?.info.displayName
2727
+ },
2728
+ options: {
2729
+ ...schema?.options,
2730
+ ...schema?.pluginOptions,
2731
+ ...data.contentType.options
2563
2732
  }
2564
2733
  };
2565
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2566
- /* @__PURE__ */ jsxRuntime.jsx(
2567
- designSystem.Button,
2568
- {
2569
- disabled: action.disabled,
2570
- startIcon: action.icon,
2571
- variant: action.variant,
2572
- onClick: handleClick(action),
2573
- children: action.label
2574
- }
2575
- ),
2576
- action.dialog?.type === "dialog" ? /* @__PURE__ */ jsxRuntime.jsx(
2577
- BulkActionConfirmDialog,
2578
- {
2579
- ...action.dialog,
2580
- variant: action.variant,
2581
- isOpen: dialogId === action.id,
2582
- onClose: handleClose
2583
- }
2584
- ) : null,
2585
- action.dialog?.type === "modal" ? /* @__PURE__ */ jsxRuntime.jsx(
2586
- BulkActionModal,
2587
- {
2588
- ...action.dialog,
2589
- onModalClose: handleClose,
2590
- isOpen: dialogId === action.id
2734
+ };
2735
+ const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
2736
+ return rows.map(
2737
+ (row) => row.map((field) => {
2738
+ const attribute = attributes[field.name];
2739
+ if (!attribute) {
2740
+ return null;
2591
2741
  }
2592
- ) : null
2593
- ] });
2742
+ const { edit: metadata } = metadatas[field.name];
2743
+ const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
2744
+ return {
2745
+ attribute,
2746
+ disabled: !metadata.editable,
2747
+ hint: metadata.description,
2748
+ label: metadata.label ?? "",
2749
+ name: field.name,
2750
+ // @ts-expect-error – mainField does exist on the metadata for a relation.
2751
+ mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
2752
+ schemas,
2753
+ components: components?.schemas ?? {}
2754
+ }),
2755
+ placeholder: metadata.placeholder ?? "",
2756
+ required: attribute.required ?? false,
2757
+ size: field.size,
2758
+ unique: "unique" in attribute ? attribute.unique : false,
2759
+ visible: metadata.visible ?? true,
2760
+ type: attribute.type
2761
+ };
2762
+ }).filter((field) => field !== null)
2763
+ );
2594
2764
  };
2595
- const BulkActionConfirmDialog = ({
2596
- onClose,
2597
- onCancel,
2598
- onConfirm,
2599
- title,
2600
- content,
2601
- confirmButton,
2602
- isOpen,
2603
- variant = "secondary"
2765
+ const formatListLayout = (data, {
2766
+ schemas,
2767
+ schema,
2768
+ components
2604
2769
  }) => {
2605
- const { formatMessage } = reactIntl.useIntl();
2606
- const handleClose = async () => {
2607
- if (onCancel) {
2608
- await onCancel();
2770
+ const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
2771
+ (acc, [attribute, metadata]) => {
2772
+ return {
2773
+ ...acc,
2774
+ [attribute]: metadata.list
2775
+ };
2776
+ },
2777
+ {}
2778
+ );
2779
+ const listAttributes = convertListLayoutToFieldLayouts(
2780
+ data.contentType.layouts.list,
2781
+ schema?.attributes,
2782
+ listMetadatas,
2783
+ { configurations: data.components, schemas: components },
2784
+ schemas
2785
+ );
2786
+ return {
2787
+ layout: listAttributes,
2788
+ settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
2789
+ metadatas: listMetadatas,
2790
+ options: {
2791
+ ...schema?.options,
2792
+ ...schema?.pluginOptions,
2793
+ ...data.contentType.options
2609
2794
  }
2610
- onClose();
2611
2795
  };
2612
- const handleConfirm = async () => {
2613
- if (onConfirm) {
2614
- await onConfirm();
2796
+ };
2797
+ const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
2798
+ return columns.map((name) => {
2799
+ const attribute = attributes[name];
2800
+ if (!attribute) {
2801
+ return null;
2615
2802
  }
2616
- onClose();
2617
- };
2618
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog, { isOpen, title, onClose: handleClose, children: [
2619
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.DialogBody, { icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, {}), children: content }),
2620
- /* @__PURE__ */ jsxRuntime.jsx(
2621
- designSystem.DialogFooter,
2622
- {
2623
- startAction: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleClose, variant: "tertiary", children: formatMessage({
2624
- id: "app.components.Button.cancel",
2625
- defaultMessage: "Cancel"
2626
- }) }),
2627
- endAction: /* @__PURE__ */ jsxRuntime.jsx(
2628
- designSystem.Button,
2803
+ const metadata = metadatas[name];
2804
+ const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
2805
+ return {
2806
+ attribute,
2807
+ label: metadata.label ?? "",
2808
+ mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
2809
+ schemas,
2810
+ components: components?.schemas ?? {}
2811
+ }),
2812
+ name,
2813
+ searchable: metadata.searchable ?? true,
2814
+ sortable: metadata.sortable ?? true
2815
+ };
2816
+ }).filter((field) => field !== null);
2817
+ };
2818
+ const ConfirmBulkActionDialog = ({
2819
+ onToggleDialog,
2820
+ isOpen = false,
2821
+ dialogBody,
2822
+ endAction
2823
+ }) => {
2824
+ const { formatMessage } = reactIntl.useIntl();
2825
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2826
+ designSystem.Dialog,
2827
+ {
2828
+ onClose: onToggleDialog,
2829
+ title: formatMessage({
2830
+ id: "app.components.ConfirmDialog.title",
2831
+ defaultMessage: "Confirmation"
2832
+ }),
2833
+ isOpen,
2834
+ children: [
2835
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.DialogBody, { icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, {}), children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: dialogBody }) }),
2836
+ /* @__PURE__ */ jsxRuntime.jsx(
2837
+ designSystem.DialogFooter,
2629
2838
  {
2630
- onClick: handleConfirm,
2631
- variant: variant === "danger-light" ? variant : "secondary",
2632
- startIcon: variant === "danger-light" ? /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {}) : /* @__PURE__ */ jsxRuntime.jsx(Icons.Check, {}),
2633
- children: confirmButton ? confirmButton : formatMessage({
2634
- id: "app.components.Button.confirm",
2635
- defaultMessage: "Confirm"
2636
- })
2839
+ startAction: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: onToggleDialog, variant: "tertiary", children: formatMessage({
2840
+ id: "app.components.Button.cancel",
2841
+ defaultMessage: "Cancel"
2842
+ }) }),
2843
+ endAction
2637
2844
  }
2638
2845
  )
2639
- }
2640
- )
2641
- ] });
2846
+ ]
2847
+ }
2848
+ );
2642
2849
  };
2643
- const BulkActionModal = ({
2850
+ const BoldChunk$1 = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: chunks });
2851
+ const ConfirmDialogPublishAll = ({
2644
2852
  isOpen,
2645
- title,
2646
- onClose,
2647
- content: Content,
2648
- onModalClose
2853
+ onToggleDialog,
2854
+ isConfirmButtonLoading = false,
2855
+ onConfirm
2649
2856
  }) => {
2650
- const id = React__namespace.useId();
2651
- if (!isOpen) {
2652
- return null;
2653
- }
2654
- const handleClose = () => {
2655
- if (onClose) {
2656
- onClose();
2657
- }
2658
- onModalClose();
2659
- };
2660
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.ModalLayout, { borderRadius: "4px", overflow: "hidden", onClose: handleClose, labelledBy: id, children: [
2661
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.ModalHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", textColor: "neutral800", tag: "h2", id, children: title }) }),
2662
- /* @__PURE__ */ jsxRuntime.jsx(Content, { onClose: handleClose })
2663
- ] });
2664
- };
2665
- const DeleteAction = ({ documents, model }) => {
2666
2857
  const { formatMessage } = reactIntl.useIntl();
2667
- const { schema: contentType } = useDoc();
2668
- const selectRow = strapiAdmin.useTable("DeleteAction", (state) => state.selectRow);
2669
- const hasI18nEnabled = Boolean(contentType?.pluginOptions?.i18n);
2858
+ const selectedEntries = strapiAdmin.useTable("ConfirmDialogPublishAll", (state) => state.selectedRows);
2859
+ const { toggleNotification } = strapiAdmin.useNotification();
2860
+ const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler(getTranslation);
2861
+ const { model, schema } = useDoc();
2670
2862
  const [{ query }] = strapiAdmin.useQueryParams();
2671
- const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
2672
- const hasDeletePermission = useDocumentRBAC("deleteAction", (state) => state.canDelete);
2673
- const { deleteMany: bulkDeleteAction } = useDocumentActions();
2674
- const documentIds = documents.map(({ documentId }) => documentId);
2675
- const handleConfirmBulkDelete = async () => {
2676
- const res = await bulkDeleteAction({
2677
- documentIds,
2863
+ const {
2864
+ data: countDraftRelations = 0,
2865
+ isLoading,
2866
+ error
2867
+ } = useGetManyDraftRelationCountQuery(
2868
+ {
2678
2869
  model,
2679
- params
2680
- });
2681
- if (!("error" in res)) {
2682
- selectRow([]);
2870
+ documentIds: selectedEntries.map((entry) => entry.documentId),
2871
+ locale: query?.plugins?.i18n?.locale
2872
+ },
2873
+ {
2874
+ skip: selectedEntries.length === 0
2683
2875
  }
2684
- };
2685
- if (!hasDeletePermission)
2876
+ );
2877
+ React__namespace.useEffect(() => {
2878
+ if (error) {
2879
+ toggleNotification({ type: "danger", message: formatAPIError(error) });
2880
+ }
2881
+ }, [error, formatAPIError, toggleNotification]);
2882
+ if (error) {
2686
2883
  return null;
2687
- return {
2688
- variant: "danger-light",
2689
- label: formatMessage({ id: "global.delete", defaultMessage: "Delete" }),
2690
- dialog: {
2691
- type: "dialog",
2692
- title: formatMessage({
2693
- id: "app.components.ConfirmDialog.title",
2694
- defaultMessage: "Confirmation"
2695
- }),
2696
- content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
2697
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
2698
- id: "popUpWarning.bodyMessage.contentType.delete.all",
2699
- defaultMessage: "Are you sure you want to delete these entries?"
2700
- }) }),
2701
- hasI18nEnabled && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { textAlign: "center", padding: 3, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger500", children: formatMessage(
2884
+ }
2885
+ return /* @__PURE__ */ jsxRuntime.jsx(
2886
+ ConfirmBulkActionDialog,
2887
+ {
2888
+ isOpen: isOpen && !isLoading,
2889
+ onToggleDialog,
2890
+ dialogBody: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2891
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: [
2892
+ countDraftRelations > 0 && formatMessage(
2893
+ {
2894
+ id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
2895
+ defaultMessage: "<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. "
2896
+ },
2897
+ {
2898
+ b: BoldChunk$1,
2899
+ count: countDraftRelations,
2900
+ entities: selectedEntries.length
2901
+ }
2902
+ ),
2903
+ formatMessage({
2904
+ id: getTranslation("popUpWarning.bodyMessage.contentType.publish.all"),
2905
+ defaultMessage: "Are you sure you want to publish these entries?"
2906
+ })
2907
+ ] }),
2908
+ schema?.pluginOptions && "i18n" in schema.pluginOptions && schema?.pluginOptions.i18n && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger500", textAlign: "center", children: formatMessage(
2702
2909
  {
2703
- id: getTranslation("Settings.list.actions.deleteAdditionalInfos"),
2704
- defaultMessage: "This will delete the active locale versions <em>(from Internationalization)</em>"
2910
+ id: getTranslation("Settings.list.actions.publishAdditionalInfos"),
2911
+ defaultMessage: "This will publish the active locale versions <em>(from Internationalization)</em>"
2705
2912
  },
2706
2913
  {
2707
2914
  em: Emphasis
2708
2915
  }
2709
- ) }) })
2916
+ ) })
2710
2917
  ] }),
2711
- onConfirm: handleConfirmBulkDelete
2918
+ endAction: /* @__PURE__ */ jsxRuntime.jsx(
2919
+ designSystem.Button,
2920
+ {
2921
+ onClick: onConfirm,
2922
+ variant: "secondary",
2923
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Check, {}),
2924
+ loading: isConfirmButtonLoading,
2925
+ children: formatMessage({
2926
+ id: "app.utils.publish",
2927
+ defaultMessage: "Publish"
2928
+ })
2929
+ }
2930
+ )
2712
2931
  }
2713
- };
2932
+ );
2714
2933
  };
2715
- DeleteAction.type = "delete";
2716
- const UnpublishAction = ({ documents, model }) => {
2717
- const { formatMessage } = reactIntl.useIntl();
2718
- const { schema } = useDoc();
2719
- const selectRow = strapiAdmin.useTable("UnpublishAction", (state) => state.selectRow);
2720
- const hasPublishPermission = useDocumentRBAC("unpublishAction", (state) => state.canPublish);
2721
- const hasI18nEnabled = Boolean(schema?.pluginOptions?.i18n);
2722
- const hasDraftAndPublishEnabled = Boolean(schema?.options?.draftAndPublish);
2723
- const { unpublishMany: bulkUnpublishAction } = useDocumentActions();
2724
- const documentIds = documents.map(({ documentId }) => documentId);
2725
- const [{ query }] = strapiAdmin.useQueryParams();
2726
- const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
2727
- const handleConfirmBulkUnpublish = async () => {
2728
- const data = await bulkUnpublishAction({ documentIds, model, params });
2729
- if (!("error" in data)) {
2730
- selectRow([]);
2731
- }
2732
- };
2733
- const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published");
2734
- if (!showUnpublishButton)
2735
- return null;
2736
- return {
2737
- variant: "tertiary",
2738
- label: formatMessage({ id: "app.utils.unpublish", defaultMessage: "Unpublish" }),
2739
- dialog: {
2740
- type: "dialog",
2741
- title: formatMessage({
2742
- id: "app.components.ConfirmDialog.title",
2743
- defaultMessage: "Confirmation"
2744
- }),
2745
- content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
2746
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
2747
- id: "popUpWarning.bodyMessage.contentType.unpublish.all",
2748
- defaultMessage: "Are you sure you want to unpublish these entries?"
2749
- }) }),
2750
- hasI18nEnabled && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { textAlign: "center", padding: 3, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger500", children: formatMessage(
2934
+ const TypographyMaxWidth = styledComponents.styled(designSystem.Typography)`
2935
+ max-width: 300px;
2936
+ `;
2937
+ const formatErrorMessages = (errors, parentKey, formatMessage) => {
2938
+ const messages = [];
2939
+ Object.entries(errors).forEach(([key, value]) => {
2940
+ const currentKey = parentKey ? `${parentKey}.${key}` : key;
2941
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
2942
+ if ("id" in value && "defaultMessage" in value) {
2943
+ messages.push(
2944
+ formatMessage(
2945
+ {
2946
+ id: `${value.id}.withField`,
2947
+ defaultMessage: value.defaultMessage
2948
+ },
2949
+ { field: currentKey }
2950
+ )
2951
+ );
2952
+ } else {
2953
+ messages.push(...formatErrorMessages(value, currentKey, formatMessage));
2954
+ }
2955
+ } else {
2956
+ messages.push(
2957
+ formatMessage(
2751
2958
  {
2752
- id: getTranslation("Settings.list.actions.unpublishAdditionalInfos"),
2753
- defaultMessage: "This will unpublish the active locale versions <em>(from Internationalization)</em>"
2959
+ id: `${value}.withField`,
2960
+ defaultMessage: value
2754
2961
  },
2755
- {
2756
- em: Emphasis
2757
- }
2758
- ) }) })
2759
- ] }),
2760
- confirmButton: formatMessage({
2761
- id: "app.utils.unpublish",
2762
- defaultMessage: "Unpublish"
2763
- }),
2764
- onConfirm: handleConfirmBulkUnpublish
2962
+ { field: currentKey }
2963
+ )
2964
+ );
2765
2965
  }
2766
- };
2966
+ });
2967
+ return messages;
2767
2968
  };
2768
- UnpublishAction.type = "unpublish";
2769
- const Emphasis = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "semiBold", textColor: "danger500", children: chunks });
2770
- const DEFAULT_BULK_ACTIONS = [UnpublishAction, DeleteAction];
2771
- const AutoCloneFailureModalBody = ({ prohibitedFields }) => {
2969
+ const EntryValidationText = ({ validationErrors, status }) => {
2772
2970
  const { formatMessage } = reactIntl.useIntl();
2773
- const getDefaultErrorMessage = (reason) => {
2774
- switch (reason) {
2775
- case "relation":
2776
- return "Duplicating the relation could remove it from the original entry.";
2777
- case "unique":
2778
- return "Identical values in a unique field are not allowed";
2779
- default:
2780
- return reason;
2971
+ if (validationErrors) {
2972
+ const validationErrorsMessages = formatErrorMessages(validationErrors, "", formatMessage).join(
2973
+ " "
2974
+ );
2975
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
2976
+ /* @__PURE__ */ jsxRuntime.jsx(Icons.CrossCircle, { fill: "danger600" }),
2977
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tooltip, { description: validationErrorsMessages, children: /* @__PURE__ */ jsxRuntime.jsx(TypographyMaxWidth, { textColor: "danger600", variant: "omega", fontWeight: "semiBold", ellipsis: true, children: validationErrorsMessages }) })
2978
+ ] });
2979
+ }
2980
+ if (status === "published") {
2981
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
2982
+ /* @__PURE__ */ jsxRuntime.jsx(Icons.CheckCircle, { fill: "success600" }),
2983
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
2984
+ id: "content-manager.bulk-publish.already-published",
2985
+ defaultMessage: "Already Published"
2986
+ }) })
2987
+ ] });
2988
+ }
2989
+ if (status === "modified") {
2990
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
2991
+ /* @__PURE__ */ jsxRuntime.jsx(Icons.ArrowsCounterClockwise, { fill: "alternative600" }),
2992
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
2993
+ id: "content-manager.bulk-publish.modified",
2994
+ defaultMessage: "Ready to publish changes"
2995
+ }) })
2996
+ ] });
2997
+ }
2998
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
2999
+ /* @__PURE__ */ jsxRuntime.jsx(Icons.CheckCircle, { fill: "success600" }),
3000
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
3001
+ id: "app.utils.ready-to-publish",
3002
+ defaultMessage: "Ready to publish"
3003
+ }) })
3004
+ ] });
3005
+ };
3006
+ const TABLE_HEADERS = [
3007
+ { name: "id", label: "id" },
3008
+ { name: "name", label: "name" },
3009
+ { name: "status", label: "status" },
3010
+ { name: "publicationStatus", label: "Publication status" }
3011
+ ];
3012
+ const SelectedEntriesTableContent = ({
3013
+ isPublishing,
3014
+ rowsToDisplay = [],
3015
+ entriesToPublish = [],
3016
+ validationErrors = {}
3017
+ }) => {
3018
+ const { pathname } = reactRouterDom.useLocation();
3019
+ const { formatMessage } = reactIntl.useIntl();
3020
+ const {
3021
+ list: {
3022
+ settings: { mainField }
2781
3023
  }
2782
- };
2783
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2784
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", children: formatMessage({
2785
- id: getTranslation("containers.list.autoCloneModal.title"),
2786
- defaultMessage: "This entry can't be duplicated directly."
2787
- }) }),
2788
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 2, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", children: formatMessage({
2789
- id: getTranslation("containers.list.autoCloneModal.description"),
2790
- defaultMessage: "A new entry will be created with the same content, but you'll have to change the following fields to save it."
2791
- }) }) }),
2792
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { marginTop: 6, gap: 2, direction: "column", alignItems: "stretch", children: prohibitedFields.map(([fieldPath, reason]) => /* @__PURE__ */ jsxRuntime.jsxs(
2793
- designSystem.Flex,
2794
- {
2795
- direction: "column",
2796
- gap: 2,
2797
- alignItems: "flex-start",
2798
- borderColor: "neutral200",
2799
- hasRadius: true,
2800
- padding: 6,
2801
- children: [
2802
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "row", tag: "ol", children: fieldPath.map((pathSegment, index2) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { fontWeight: "semiBold", tag: "li", children: [
2803
- pathSegment,
2804
- index2 !== fieldPath.length - 1 && /* @__PURE__ */ jsxRuntime.jsx(
2805
- Icons.ChevronRight,
2806
- {
2807
- fill: "neutral500",
2808
- height: "0.8rem",
2809
- width: "0.8rem",
2810
- style: { margin: "0 0.8rem" }
2811
- }
2812
- )
2813
- ] }, index2)) }),
2814
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", textColor: "neutral600", children: formatMessage({
2815
- id: getTranslation(`containers.list.autoCloneModal.error.${reason}`),
2816
- defaultMessage: getDefaultErrorMessage(reason)
2817
- }) })
2818
- ]
2819
- },
2820
- fieldPath.join()
2821
- )) })
3024
+ } = useDocLayout();
3025
+ const shouldDisplayMainField = mainField != null && mainField !== "id";
3026
+ return /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Content, { children: [
3027
+ /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Head, { children: [
3028
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.HeaderCheckboxCell, {}),
3029
+ TABLE_HEADERS.filter((head) => head.name !== "name" || shouldDisplayMainField).map(
3030
+ (head) => /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.HeaderCell, { ...head }, head.name)
3031
+ )
3032
+ ] }),
3033
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Loading, {}),
3034
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Body, { children: rowsToDisplay.map((row, index2) => /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Row, { children: [
3035
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.CheckboxCell, { id: row.id }),
3036
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: row.id }) }),
3037
+ shouldDisplayMainField && /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: row[mainField] }) }),
3038
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(DocumentStatus, { status: row.status, maxWidth: "min-content" }) }),
3039
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: isPublishing && entriesToPublish.includes(row.documentId) ? /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
3040
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
3041
+ id: "content-manager.success.record.publishing",
3042
+ defaultMessage: "Publishing..."
3043
+ }) }),
3044
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Loader, { small: true })
3045
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(
3046
+ EntryValidationText,
3047
+ {
3048
+ validationErrors: validationErrors[row.documentId],
3049
+ status: row.status
3050
+ }
3051
+ ) }),
3052
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(
3053
+ designSystem.IconButton,
3054
+ {
3055
+ tag: reactRouterDom.Link,
3056
+ to: {
3057
+ pathname: `${pathname}/${row.documentId}`,
3058
+ search: row.locale && `?plugins[i18n][locale]=${row.locale}`
3059
+ },
3060
+ state: { from: pathname },
3061
+ label: formatMessage(
3062
+ { id: "app.component.HelperPluginTable.edit", defaultMessage: "Edit {target}" },
3063
+ {
3064
+ target: formatMessage(
3065
+ {
3066
+ id: "content-manager.components.ListViewHelperPluginTable.row-line",
3067
+ defaultMessage: "item line {number}"
3068
+ },
3069
+ { number: index2 + 1 }
3070
+ )
3071
+ }
3072
+ ),
3073
+ target: "_blank",
3074
+ marginLeft: "auto",
3075
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Pencil, {})
3076
+ }
3077
+ ) })
3078
+ ] }, row.id)) })
2822
3079
  ] });
2823
3080
  };
2824
- const TableActions = ({ document }) => {
3081
+ const BoldChunk = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: chunks });
3082
+ const SelectedEntriesModalContent = ({
3083
+ listViewSelectedEntries,
3084
+ toggleModal,
3085
+ setListViewSelectedDocuments,
3086
+ model
3087
+ }) => {
2825
3088
  const { formatMessage } = reactIntl.useIntl();
2826
- const { model, collectionType } = useDoc();
2827
- const plugins = strapiAdmin.useStrapiApp("TableActions", (state) => state.plugins);
2828
- const props = {
2829
- activeTab: null,
2830
- model,
2831
- documentId: document.documentId,
2832
- collectionType,
2833
- document
2834
- };
2835
- return /* @__PURE__ */ jsxRuntime.jsx(
2836
- strapiAdmin.DescriptionComponentRenderer,
3089
+ const { schema, components } = useContentTypeSchema(model);
3090
+ const documentIds = listViewSelectedEntries.map(({ documentId }) => documentId);
3091
+ const [{ query }] = strapiAdmin.useQueryParams();
3092
+ const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
3093
+ const { data, isLoading, isFetching, refetch } = useGetAllDocumentsQuery(
2837
3094
  {
2838
- props,
2839
- descriptions: plugins["content-manager"].apis.getDocumentActions(),
2840
- children: (actions2) => {
2841
- const tableRowActions = actions2.filter((action) => {
2842
- const positions = Array.isArray(action.position) ? action.position : [action.position];
2843
- return positions.includes("table-row");
2844
- });
2845
- return /* @__PURE__ */ jsxRuntime.jsx(
2846
- DocumentActionsMenu,
2847
- {
2848
- actions: tableRowActions,
2849
- label: formatMessage({
2850
- id: "content-manager.containers.list.table.row-actions",
2851
- defaultMessage: "Row action"
2852
- }),
2853
- variant: "ghost"
3095
+ model,
3096
+ params: {
3097
+ page: "1",
3098
+ pageSize: documentIds.length.toString(),
3099
+ sort: query.sort,
3100
+ filters: {
3101
+ documentId: {
3102
+ $in: documentIds
2854
3103
  }
2855
- );
3104
+ },
3105
+ locale: query.plugins?.i18n?.locale
2856
3106
  }
3107
+ },
3108
+ {
3109
+ selectFromResult: ({ data: data2, ...restRes }) => ({ data: data2?.results ?? [], ...restRes })
3110
+ }
3111
+ );
3112
+ const { rows, validationErrors } = React__namespace.useMemo(() => {
3113
+ if (data.length > 0 && schema) {
3114
+ const validate = createYupSchema(schema.attributes, components);
3115
+ const validationErrors2 = {};
3116
+ const rows2 = data.map((entry) => {
3117
+ try {
3118
+ validate.validateSync(entry, { abortEarly: false });
3119
+ return entry;
3120
+ } catch (e) {
3121
+ if (e instanceof yup.ValidationError) {
3122
+ validationErrors2[entry.documentId] = strapiAdmin.getYupValidationErrors(e);
3123
+ }
3124
+ return entry;
3125
+ }
3126
+ });
3127
+ return { rows: rows2, validationErrors: validationErrors2 };
2857
3128
  }
3129
+ return {
3130
+ rows: [],
3131
+ validationErrors: {}
3132
+ };
3133
+ }, [components, data, schema]);
3134
+ const [publishedCount, setPublishedCount] = React__namespace.useState(0);
3135
+ const [isDialogOpen, setIsDialogOpen] = React__namespace.useState(false);
3136
+ const { publishMany: bulkPublishAction } = useDocumentActions();
3137
+ const [, { isLoading: isSubmittingForm }] = usePublishManyDocumentsMutation();
3138
+ const selectedRows = strapiAdmin.useTable("publishAction", (state) => state.selectedRows);
3139
+ const selectedEntries = rows.filter(
3140
+ (entry) => selectedRows.some((selectedEntry) => selectedEntry.documentId === entry.documentId)
2858
3141
  );
3142
+ const entriesToPublish = selectedEntries.filter((entry) => !validationErrors[entry.documentId]).map((entry) => entry.documentId);
3143
+ const selectedEntriesWithErrorsCount = selectedEntries.filter(
3144
+ ({ documentId }) => validationErrors[documentId]
3145
+ ).length;
3146
+ const selectedEntriesPublished = selectedEntries.filter(
3147
+ ({ status }) => status === "published"
3148
+ ).length;
3149
+ const selectedEntriesWithNoErrorsCount = selectedEntries.length - selectedEntriesWithErrorsCount - selectedEntriesPublished;
3150
+ const toggleDialog = () => setIsDialogOpen((prev) => !prev);
3151
+ const handleConfirmBulkPublish = async () => {
3152
+ toggleDialog();
3153
+ const res = await bulkPublishAction({ model, documentIds: entriesToPublish, params });
3154
+ if (!("error" in res)) {
3155
+ setPublishedCount(res.count);
3156
+ const unpublishedEntries = rows.filter((row) => {
3157
+ return !entriesToPublish.includes(row.documentId);
3158
+ });
3159
+ setListViewSelectedDocuments(unpublishedEntries);
3160
+ }
3161
+ };
3162
+ const getFormattedCountMessage = () => {
3163
+ if (publishedCount) {
3164
+ return formatMessage(
3165
+ {
3166
+ id: getTranslation("containers.list.selectedEntriesModal.publishedCount"),
3167
+ defaultMessage: "<b>{publishedCount}</b> {publishedCount, plural, =0 {entries} one {entry} other {entries}} published. <b>{withErrorsCount}</b> {withErrorsCount, plural, =0 {entries} one {entry} other {entries}} waiting for action."
3168
+ },
3169
+ {
3170
+ publishedCount,
3171
+ withErrorsCount: selectedEntriesWithErrorsCount,
3172
+ b: BoldChunk
3173
+ }
3174
+ );
3175
+ }
3176
+ return formatMessage(
3177
+ {
3178
+ id: getTranslation("containers.list.selectedEntriesModal.selectedCount"),
3179
+ defaultMessage: "<b>{alreadyPublishedCount}</b> {alreadyPublishedCount, plural, =0 {entries} one {entry} other {entries}} already published. <b>{readyToPublishCount}</b> {readyToPublishCount, plural, =0 {entries} one {entry} other {entries}} ready to publish. <b>{withErrorsCount}</b> {withErrorsCount, plural, =0 {entries} one {entry} other {entries}} waiting for action."
3180
+ },
3181
+ {
3182
+ readyToPublishCount: selectedEntriesWithNoErrorsCount,
3183
+ withErrorsCount: selectedEntriesWithErrorsCount,
3184
+ alreadyPublishedCount: selectedEntriesPublished,
3185
+ b: BoldChunk
3186
+ }
3187
+ );
3188
+ };
3189
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3190
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.ModalBody, { children: [
3191
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: getFormattedCountMessage() }),
3192
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 5, children: /* @__PURE__ */ jsxRuntime.jsx(
3193
+ SelectedEntriesTableContent,
3194
+ {
3195
+ isPublishing: isSubmittingForm,
3196
+ rowsToDisplay: rows,
3197
+ entriesToPublish,
3198
+ validationErrors
3199
+ }
3200
+ ) })
3201
+ ] }),
3202
+ /* @__PURE__ */ jsxRuntime.jsx(
3203
+ designSystem.ModalFooter,
3204
+ {
3205
+ startActions: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: toggleModal, variant: "tertiary", children: formatMessage({
3206
+ id: "app.components.Button.cancel",
3207
+ defaultMessage: "Cancel"
3208
+ }) }),
3209
+ endActions: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
3210
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: refetch, variant: "tertiary", loading: isFetching, children: formatMessage({ id: "app.utils.refresh", defaultMessage: "Refresh" }) }),
3211
+ /* @__PURE__ */ jsxRuntime.jsx(
3212
+ designSystem.Button,
3213
+ {
3214
+ onClick: toggleDialog,
3215
+ disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount || selectedEntriesPublished === selectedEntries.length || isLoading,
3216
+ loading: isSubmittingForm,
3217
+ children: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" })
3218
+ }
3219
+ )
3220
+ ] })
3221
+ }
3222
+ ),
3223
+ /* @__PURE__ */ jsxRuntime.jsx(
3224
+ ConfirmDialogPublishAll,
3225
+ {
3226
+ isOpen: isDialogOpen,
3227
+ onToggleDialog: toggleDialog,
3228
+ isConfirmButtonLoading: isSubmittingForm,
3229
+ onConfirm: handleConfirmBulkPublish
3230
+ }
3231
+ )
3232
+ ] });
2859
3233
  };
2860
- const EditAction = ({ documentId }) => {
2861
- const navigate = reactRouterDom.useNavigate();
3234
+ const PublishAction = ({ documents, model }) => {
2862
3235
  const { formatMessage } = reactIntl.useIntl();
2863
- const { canRead } = useDocumentRBAC("EditAction", ({ canRead: canRead2 }) => ({ canRead: canRead2 }));
2864
- const { toggleNotification } = strapiAdmin.useNotification();
2865
- const [{ query }] = strapiAdmin.useQueryParams();
3236
+ const hasPublishPermission = useDocumentRBAC("unpublishAction", (state) => state.canPublish);
3237
+ const showPublishButton = hasPublishPermission && documents.some(({ status }) => status !== "published");
3238
+ const setListViewSelectedDocuments = strapiAdmin.useTable("publishAction", (state) => state.selectRow);
3239
+ const refetchList = () => {
3240
+ contentManagerApi.util.invalidateTags([{ type: "Document", id: `${model}_LIST` }]);
3241
+ };
3242
+ if (!showPublishButton)
3243
+ return null;
2866
3244
  return {
2867
- disabled: !canRead,
2868
- icon: /* @__PURE__ */ jsxRuntime.jsx(StyledPencil, {}),
2869
- label: formatMessage({
2870
- id: "content-manager.actions.edit.label",
2871
- defaultMessage: "Edit"
2872
- }),
2873
- position: "table-row",
2874
- onClick: async () => {
2875
- if (!documentId) {
2876
- console.error(
2877
- "You're trying to edit a document without an id, this is likely a bug with Strapi. Please open an issue."
2878
- );
2879
- toggleNotification({
2880
- message: formatMessage({
2881
- id: "content-manager.actions.edit.error",
2882
- defaultMessage: "An error occurred while trying to edit the document."
2883
- }),
2884
- type: "danger"
2885
- });
2886
- return;
3245
+ actionType: "publish",
3246
+ variant: "tertiary",
3247
+ label: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" }),
3248
+ dialog: {
3249
+ type: "modal",
3250
+ title: formatMessage({
3251
+ id: getTranslation("containers.ListPage.selectedEntriesModal.title"),
3252
+ defaultMessage: "Publish entries"
3253
+ }),
3254
+ content: ({ onClose }) => {
3255
+ return /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Root, { rows: documents, defaultSelectedRows: documents, headers: TABLE_HEADERS, children: /* @__PURE__ */ jsxRuntime.jsx(
3256
+ SelectedEntriesModalContent,
3257
+ {
3258
+ listViewSelectedEntries: documents,
3259
+ toggleModal: () => {
3260
+ onClose();
3261
+ refetchList();
3262
+ },
3263
+ setListViewSelectedDocuments,
3264
+ model
3265
+ }
3266
+ ) });
3267
+ },
3268
+ onClose: () => {
3269
+ refetchList();
2887
3270
  }
2888
- navigate({
2889
- pathname: documentId,
2890
- search: qs.stringify({
2891
- plugins: query.plugins
2892
- })
2893
- });
2894
3271
  }
2895
3272
  };
2896
3273
  };
2897
- EditAction.type = "edit";
2898
- const StyledPencil = styledComponents.styled(Icons.Pencil)`
2899
- path {
2900
- fill: currentColor;
2901
- }
2902
- `;
2903
- const CloneAction = ({ model, documentId }) => {
2904
- const navigate = reactRouterDom.useNavigate();
2905
- const { formatMessage } = reactIntl.useIntl();
2906
- const { canCreate } = useDocumentRBAC("CloneAction", ({ canCreate: canCreate2 }) => ({ canCreate: canCreate2 }));
2907
- const { toggleNotification } = strapiAdmin.useNotification();
2908
- const { autoClone } = useDocumentActions();
2909
- const [prohibitedFields, setProhibitedFields] = React__namespace.useState([]);
2910
- return {
2911
- disabled: !canCreate,
2912
- icon: /* @__PURE__ */ jsxRuntime.jsx(StyledDuplicate, {}),
2913
- label: formatMessage({
2914
- id: "content-manager.actions.clone.label",
2915
- defaultMessage: "Duplicate"
2916
- }),
2917
- position: "table-row",
2918
- onClick: async () => {
2919
- if (!documentId) {
2920
- console.error(
2921
- "You're trying to clone a document in the table without an id, this is likely a bug with Strapi. Please open an issue."
2922
- );
2923
- toggleNotification({
2924
- message: formatMessage({
2925
- id: "content-manager.actions.clone.error",
2926
- defaultMessage: "An error occurred while trying to clone the document."
2927
- }),
2928
- type: "danger"
2929
- });
2930
- return;
3274
+ const BulkActionsRenderer = () => {
3275
+ const plugins = strapiAdmin.useStrapiApp("BulkActionsRenderer", (state) => state.plugins);
3276
+ const { model, collectionType } = useDoc();
3277
+ const { selectedRows } = strapiAdmin.useTable("BulkActionsRenderer", (state) => state);
3278
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 2, children: /* @__PURE__ */ jsxRuntime.jsx(
3279
+ strapiAdmin.DescriptionComponentRenderer,
3280
+ {
3281
+ props: {
3282
+ model,
3283
+ collectionType,
3284
+ documents: selectedRows
3285
+ },
3286
+ descriptions: plugins["content-manager"].apis.getBulkActions(),
3287
+ children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsxRuntime.jsx(BulkActionAction, { ...action }, action.id))
3288
+ }
3289
+ ) });
3290
+ };
3291
+ const BulkActionAction = (action) => {
3292
+ const [dialogId, setDialogId] = React__namespace.useState(null);
3293
+ const { toggleNotification } = strapiAdmin.useNotification();
3294
+ const handleClick = (action2) => (e) => {
3295
+ const { onClick, dialog, id } = action2;
3296
+ if (onClick) {
3297
+ onClick(e);
3298
+ }
3299
+ if (dialog) {
3300
+ switch (dialog.type) {
3301
+ case "notification":
3302
+ toggleNotification({
3303
+ title: dialog.title,
3304
+ message: dialog.content,
3305
+ type: dialog.status,
3306
+ timeout: dialog.timeout,
3307
+ onClose: dialog.onClose
3308
+ });
3309
+ break;
3310
+ case "dialog":
3311
+ case "modal": {
3312
+ e.preventDefault();
3313
+ setDialogId(id);
3314
+ }
2931
3315
  }
2932
- const res = await autoClone({ model, sourceId: documentId });
2933
- if ("data" in res) {
2934
- navigate(res.data.documentId);
2935
- return true;
3316
+ }
3317
+ };
3318
+ const handleClose = () => {
3319
+ setDialogId(null);
3320
+ if (action.dialog?.type === "modal" && action.dialog?.onClose) {
3321
+ action.dialog.onClose();
3322
+ }
3323
+ };
3324
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3325
+ /* @__PURE__ */ jsxRuntime.jsx(
3326
+ designSystem.Button,
3327
+ {
3328
+ disabled: action.disabled,
3329
+ startIcon: action.icon,
3330
+ variant: action.variant,
3331
+ onClick: handleClick(action),
3332
+ children: action.label
2936
3333
  }
2937
- if (isBaseQueryError(res.error) && res.error.details && typeof res.error.details === "object" && "prohibitedFields" in res.error.details && Array.isArray(res.error.details.prohibitedFields)) {
2938
- const prohibitedFields2 = res.error.details.prohibitedFields;
2939
- setProhibitedFields(prohibitedFields2);
3334
+ ),
3335
+ action.dialog?.type === "dialog" ? /* @__PURE__ */ jsxRuntime.jsx(
3336
+ BulkActionConfirmDialog,
3337
+ {
3338
+ ...action.dialog,
3339
+ variant: action.variant,
3340
+ isOpen: dialogId === action.id,
3341
+ onClose: handleClose
2940
3342
  }
2941
- },
2942
- dialog: {
2943
- type: "modal",
2944
- title: formatMessage({
2945
- id: "content-manager.containers.list.autoCloneModal.header",
2946
- defaultMessage: "Duplicate"
2947
- }),
2948
- content: /* @__PURE__ */ jsxRuntime.jsx(AutoCloneFailureModalBody, { prohibitedFields }),
2949
- footer: ({ onClose }) => {
2950
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", children: [
2951
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
2952
- id: "cancel",
2953
- defaultMessage: "Cancel"
2954
- }) }),
2955
- /* @__PURE__ */ jsxRuntime.jsx(
2956
- designSystem.LinkButton,
2957
- {
2958
- tag: reactRouterDom.NavLink,
2959
- to: {
2960
- pathname: `clone/${documentId}`
2961
- },
2962
- children: formatMessage({
2963
- id: "content-manager.containers.list.autoCloneModal.create",
2964
- defaultMessage: "Create"
2965
- })
2966
- }
2967
- )
2968
- ] });
3343
+ ) : null,
3344
+ action.dialog?.type === "modal" ? /* @__PURE__ */ jsxRuntime.jsx(
3345
+ BulkActionModal,
3346
+ {
3347
+ ...action.dialog,
3348
+ onModalClose: handleClose,
3349
+ isOpen: dialogId === action.id
2969
3350
  }
2970
- }
2971
- };
3351
+ ) : null
3352
+ ] });
2972
3353
  };
2973
- CloneAction.type = "clone";
2974
- const StyledDuplicate = styledComponents.styled(Icons.Duplicate)`
2975
- path {
2976
- fill: currentColor;
2977
- }
2978
- `;
2979
- const DEFAULT_TABLE_ROW_ACTIONS = [EditAction, CloneAction];
2980
- class ContentManagerPlugin {
2981
- /**
2982
- * The following properties are the stored ones provided by any plugins registering with
2983
- * the content-manager. The function calls however, need to be called at runtime in the
2984
- * application, so instead we collate them and run them later with the complete list incl.
2985
- * ones already registered & the context of the view.
2986
- */
2987
- bulkActions = [...DEFAULT_BULK_ACTIONS];
2988
- documentActions = [
2989
- ...DEFAULT_ACTIONS,
2990
- ...DEFAULT_TABLE_ROW_ACTIONS,
2991
- ...DEFAULT_HEADER_ACTIONS,
2992
- HistoryAction
2993
- ];
2994
- editViewSidePanels = [ActionsPanel];
2995
- headerActions = [];
2996
- constructor() {
2997
- }
2998
- addEditViewSidePanel(panels) {
2999
- if (Array.isArray(panels)) {
3000
- this.editViewSidePanels = [...this.editViewSidePanels, ...panels];
3001
- } else if (typeof panels === "function") {
3002
- this.editViewSidePanels = panels(this.editViewSidePanels);
3003
- } else {
3004
- throw new Error(
3005
- `Expected the \`panels\` passed to \`addEditViewSidePanel\` to be an array or a function, but received ${getPrintableType(
3006
- panels
3007
- )}`
3008
- );
3354
+ const BulkActionConfirmDialog = ({
3355
+ onClose,
3356
+ onCancel,
3357
+ onConfirm,
3358
+ title,
3359
+ content,
3360
+ confirmButton,
3361
+ isOpen,
3362
+ variant = "secondary"
3363
+ }) => {
3364
+ const { formatMessage } = reactIntl.useIntl();
3365
+ const handleClose = async () => {
3366
+ if (onCancel) {
3367
+ await onCancel();
3009
3368
  }
3010
- }
3011
- addDocumentAction(actions2) {
3012
- if (Array.isArray(actions2)) {
3013
- this.documentActions = [...this.documentActions, ...actions2];
3014
- } else if (typeof actions2 === "function") {
3015
- this.documentActions = actions2(this.documentActions);
3016
- } else {
3017
- throw new Error(
3018
- `Expected the \`actions\` passed to \`addDocumentAction\` to be an array or a function, but received ${getPrintableType(
3019
- actions2
3020
- )}`
3021
- );
3369
+ onClose();
3370
+ };
3371
+ const handleConfirm = async () => {
3372
+ if (onConfirm) {
3373
+ await onConfirm();
3022
3374
  }
3375
+ onClose();
3376
+ };
3377
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog, { isOpen, title, onClose: handleClose, children: [
3378
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.DialogBody, { icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, {}), children: content }),
3379
+ /* @__PURE__ */ jsxRuntime.jsx(
3380
+ designSystem.DialogFooter,
3381
+ {
3382
+ startAction: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleClose, variant: "tertiary", children: formatMessage({
3383
+ id: "app.components.Button.cancel",
3384
+ defaultMessage: "Cancel"
3385
+ }) }),
3386
+ endAction: /* @__PURE__ */ jsxRuntime.jsx(
3387
+ designSystem.Button,
3388
+ {
3389
+ onClick: handleConfirm,
3390
+ variant: variant === "danger-light" ? variant : "secondary",
3391
+ startIcon: variant === "danger-light" ? /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {}) : /* @__PURE__ */ jsxRuntime.jsx(Icons.Check, {}),
3392
+ children: confirmButton ? confirmButton : formatMessage({
3393
+ id: "app.components.Button.confirm",
3394
+ defaultMessage: "Confirm"
3395
+ })
3396
+ }
3397
+ )
3398
+ }
3399
+ )
3400
+ ] });
3401
+ };
3402
+ const BulkActionModal = ({
3403
+ isOpen,
3404
+ title,
3405
+ onClose,
3406
+ content: Content,
3407
+ onModalClose
3408
+ }) => {
3409
+ const id = React__namespace.useId();
3410
+ if (!isOpen) {
3411
+ return null;
3023
3412
  }
3024
- addDocumentHeaderAction(actions2) {
3025
- if (Array.isArray(actions2)) {
3026
- this.headerActions = [...this.headerActions, ...actions2];
3027
- } else if (typeof actions2 === "function") {
3028
- this.headerActions = actions2(this.headerActions);
3029
- } else {
3030
- throw new Error(
3031
- `Expected the \`actions\` passed to \`addDocumentHeaderAction\` to be an array or a function, but received ${getPrintableType(
3032
- actions2
3033
- )}`
3034
- );
3413
+ const handleClose = () => {
3414
+ if (onClose) {
3415
+ onClose();
3035
3416
  }
3036
- }
3037
- addBulkAction(actions2) {
3038
- if (Array.isArray(actions2)) {
3039
- this.bulkActions = [...this.bulkActions, ...actions2];
3040
- } else if (typeof actions2 === "function") {
3041
- this.bulkActions = actions2(this.bulkActions);
3042
- } else {
3043
- throw new Error(
3044
- `Expected the \`actions\` passed to \`addBulkAction\` to be an array or a function, but received ${getPrintableType(
3045
- actions2
3046
- )}`
3047
- );
3048
- }
3049
- }
3050
- get config() {
3051
- return {
3052
- id: PLUGIN_ID,
3053
- name: "Content Manager",
3054
- injectionZones: INJECTION_ZONES,
3055
- apis: {
3056
- addBulkAction: this.addBulkAction.bind(this),
3057
- addDocumentAction: this.addDocumentAction.bind(this),
3058
- addDocumentHeaderAction: this.addDocumentHeaderAction.bind(this),
3059
- addEditViewSidePanel: this.addEditViewSidePanel.bind(this),
3060
- getBulkActions: () => this.bulkActions,
3061
- getDocumentActions: () => this.documentActions,
3062
- getEditViewSidePanels: () => this.editViewSidePanels,
3063
- getHeaderActions: () => this.headerActions
3064
- }
3065
- };
3066
- }
3067
- }
3068
- const getPrintableType = (value) => {
3069
- const nativeType = typeof value;
3070
- if (nativeType === "object") {
3071
- if (value === null)
3072
- return "null";
3073
- if (Array.isArray(value))
3074
- return "array";
3075
- if (value instanceof Object && value.constructor.name !== "Object") {
3076
- return value.constructor.name;
3077
- }
3078
- }
3079
- return nativeType;
3080
- };
3081
- const initialState = {
3082
- collectionTypeLinks: [],
3083
- components: [],
3084
- fieldSizes: {},
3085
- models: [],
3086
- singleTypeLinks: [],
3087
- isLoading: true
3417
+ onModalClose();
3418
+ };
3419
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.ModalLayout, { borderRadius: "4px", overflow: "hidden", onClose: handleClose, labelledBy: id, children: [
3420
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.ModalHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", textColor: "neutral800", tag: "h2", id, children: title }) }),
3421
+ /* @__PURE__ */ jsxRuntime.jsx(Content, { onClose: handleClose })
3422
+ ] });
3088
3423
  };
3089
- const appSlice = toolkit.createSlice({
3090
- name: "app",
3091
- initialState,
3092
- reducers: {
3093
- setInitialData(state, action) {
3094
- const {
3095
- authorizedCollectionTypeLinks,
3096
- authorizedSingleTypeLinks,
3097
- components,
3098
- contentTypeSchemas,
3099
- fieldSizes
3100
- } = action.payload;
3101
- state.collectionTypeLinks = authorizedCollectionTypeLinks.filter(
3102
- ({ isDisplayed }) => isDisplayed
3103
- );
3104
- state.singleTypeLinks = authorizedSingleTypeLinks.filter(({ isDisplayed }) => isDisplayed);
3105
- state.components = components;
3106
- state.models = contentTypeSchemas;
3107
- state.fieldSizes = fieldSizes;
3108
- state.isLoading = false;
3424
+ const DeleteAction = ({ documents, model }) => {
3425
+ const { formatMessage } = reactIntl.useIntl();
3426
+ const { schema: contentType } = useDoc();
3427
+ const selectRow = strapiAdmin.useTable("DeleteAction", (state) => state.selectRow);
3428
+ const hasI18nEnabled = Boolean(contentType?.pluginOptions?.i18n);
3429
+ const [{ query }] = strapiAdmin.useQueryParams();
3430
+ const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
3431
+ const hasDeletePermission = useDocumentRBAC("deleteAction", (state) => state.canDelete);
3432
+ const { deleteMany: bulkDeleteAction } = useDocumentActions();
3433
+ const documentIds = documents.map(({ documentId }) => documentId);
3434
+ const handleConfirmBulkDelete = async () => {
3435
+ const res = await bulkDeleteAction({
3436
+ documentIds,
3437
+ model,
3438
+ params
3439
+ });
3440
+ if (!("error" in res)) {
3441
+ selectRow([]);
3109
3442
  }
3110
- }
3111
- });
3112
- const { actions, reducer: reducer$1 } = appSlice;
3113
- const { setInitialData } = actions;
3114
- const reducer = toolkit.combineReducers({
3115
- app: reducer$1
3116
- });
3117
- const HOOKS = {
3118
- /**
3119
- * Hook that allows to mutate the displayed headers of the list view table
3120
- * @constant
3121
- * @type {string}
3122
- */
3123
- INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
3124
- /**
3125
- * Hook that allows to mutate the CM's collection types links pre-set filters
3126
- * @constant
3127
- * @type {string}
3128
- */
3129
- MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
3130
- /**
3131
- * Hook that allows to mutate the CM's edit view layout
3132
- * @constant
3133
- * @type {string}
3134
- */
3135
- MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
3136
- /**
3137
- * Hook that allows to mutate the CM's single types links pre-set filters
3138
- * @constant
3139
- * @type {string}
3140
- */
3141
- MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
3142
- };
3143
- const contentTypesApi = contentManagerApi.injectEndpoints({
3144
- endpoints: (builder) => ({
3145
- getContentTypeConfiguration: builder.query({
3146
- query: (uid) => ({
3147
- url: `/content-manager/content-types/${uid}/configuration`,
3148
- method: "GET"
3149
- }),
3150
- transformResponse: (response) => response.data,
3151
- providesTags: (_result, _error, uid) => [
3152
- { type: "ContentTypesConfiguration", id: uid },
3153
- { type: "ContentTypeSettings", id: "LIST" }
3154
- ]
3155
- }),
3156
- getAllContentTypeSettings: builder.query({
3157
- query: () => "/content-manager/content-types-settings",
3158
- transformResponse: (response) => response.data,
3159
- providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
3160
- }),
3161
- updateContentTypeConfiguration: builder.mutation({
3162
- query: ({ uid, ...body }) => ({
3163
- url: `/content-manager/content-types/${uid}/configuration`,
3164
- method: "PUT",
3165
- data: body
3166
- }),
3167
- transformResponse: (response) => response.data,
3168
- invalidatesTags: (_result, _error, { uid }) => [
3169
- { type: "ContentTypesConfiguration", id: uid },
3170
- { type: "ContentTypeSettings", id: "LIST" },
3171
- // Is this necessary?
3172
- { type: "InitialData" }
3173
- ]
3174
- })
3175
- })
3176
- });
3177
- const {
3178
- useGetContentTypeConfigurationQuery,
3179
- useGetAllContentTypeSettingsQuery,
3180
- useUpdateContentTypeConfigurationMutation
3181
- } = contentTypesApi;
3182
- const checkIfAttributeIsDisplayable = (attribute) => {
3183
- const { type } = attribute;
3184
- if (type === "relation") {
3185
- return !attribute.relation.toLowerCase().includes("morph");
3186
- }
3187
- return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
3188
- };
3189
- const getMainField = (attribute, mainFieldName, { schemas, components }) => {
3190
- if (!mainFieldName) {
3191
- return void 0;
3192
- }
3193
- const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
3194
- // @ts-expect-error – `targetModel` does exist on the attribute for a relation.
3195
- schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
3196
- );
3443
+ };
3444
+ if (!hasDeletePermission)
3445
+ return null;
3197
3446
  return {
3198
- name: mainFieldName,
3199
- type: mainFieldType ?? "string"
3447
+ variant: "danger-light",
3448
+ label: formatMessage({ id: "global.delete", defaultMessage: "Delete" }),
3449
+ dialog: {
3450
+ type: "dialog",
3451
+ title: formatMessage({
3452
+ id: "app.components.ConfirmDialog.title",
3453
+ defaultMessage: "Confirmation"
3454
+ }),
3455
+ content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
3456
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
3457
+ id: "popUpWarning.bodyMessage.contentType.delete.all",
3458
+ defaultMessage: "Are you sure you want to delete these entries?"
3459
+ }) }),
3460
+ hasI18nEnabled && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { textAlign: "center", padding: 3, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger500", children: formatMessage(
3461
+ {
3462
+ id: getTranslation("Settings.list.actions.deleteAdditionalInfos"),
3463
+ defaultMessage: "This will delete the active locale versions <em>(from Internationalization)</em>"
3464
+ },
3465
+ {
3466
+ em: Emphasis
3467
+ }
3468
+ ) }) })
3469
+ ] }),
3470
+ onConfirm: handleConfirmBulkDelete
3471
+ }
3200
3472
  };
3201
3473
  };
3202
- const DEFAULT_SETTINGS = {
3203
- bulkable: false,
3204
- filterable: false,
3205
- searchable: false,
3206
- pagination: false,
3207
- defaultSortBy: "",
3208
- defaultSortOrder: "asc",
3209
- mainField: "id",
3210
- pageSize: 10
3211
- };
3212
- const useDocumentLayout = (model) => {
3213
- const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
3214
- const [{ query }] = strapiAdmin.useQueryParams();
3215
- const runHookWaterfall = strapiAdmin.useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
3216
- const { toggleNotification } = strapiAdmin.useNotification();
3217
- const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
3218
- const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
3219
- const {
3220
- data,
3221
- isLoading: isLoadingConfigs,
3222
- error,
3223
- isFetching: isFetchingConfigs
3224
- } = useGetContentTypeConfigurationQuery(model);
3225
- const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
3226
- React__namespace.useEffect(() => {
3227
- if (error) {
3228
- toggleNotification({
3229
- type: "danger",
3230
- message: formatAPIError(error)
3231
- });
3232
- }
3233
- }, [error, formatAPIError, toggleNotification]);
3234
- const editLayout = React__namespace.useMemo(
3235
- () => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
3236
- layout: [],
3237
- components: {},
3238
- metadatas: {},
3239
- options: {},
3240
- settings: DEFAULT_SETTINGS
3241
- },
3242
- [data, isLoading, schemas, schema, components]
3243
- );
3244
- const listLayout = React__namespace.useMemo(() => {
3245
- return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
3246
- layout: [],
3247
- metadatas: {},
3248
- options: {},
3249
- settings: DEFAULT_SETTINGS
3250
- };
3251
- }, [data, isLoading, schemas, schema, components]);
3252
- const { layout: edit } = React__namespace.useMemo(
3253
- () => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
3254
- layout: editLayout,
3255
- query
3256
- }),
3257
- [editLayout, query, runHookWaterfall]
3258
- );
3474
+ DeleteAction.type = "delete";
3475
+ const UnpublishAction = ({ documents, model }) => {
3476
+ const { formatMessage } = reactIntl.useIntl();
3477
+ const { schema } = useDoc();
3478
+ const selectRow = strapiAdmin.useTable("UnpublishAction", (state) => state.selectRow);
3479
+ const hasPublishPermission = useDocumentRBAC("unpublishAction", (state) => state.canPublish);
3480
+ const hasI18nEnabled = Boolean(schema?.pluginOptions?.i18n);
3481
+ const hasDraftAndPublishEnabled = Boolean(schema?.options?.draftAndPublish);
3482
+ const { unpublishMany: bulkUnpublishAction } = useDocumentActions();
3483
+ const documentIds = documents.map(({ documentId }) => documentId);
3484
+ const [{ query }] = strapiAdmin.useQueryParams();
3485
+ const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
3486
+ const handleConfirmBulkUnpublish = async () => {
3487
+ const data = await bulkUnpublishAction({ documentIds, model, params });
3488
+ if (!("error" in data)) {
3489
+ selectRow([]);
3490
+ }
3491
+ };
3492
+ const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published" || entry.status === "modified");
3493
+ if (!showUnpublishButton)
3494
+ return null;
3259
3495
  return {
3260
- error,
3261
- isLoading,
3262
- edit,
3263
- list: listLayout
3496
+ variant: "tertiary",
3497
+ label: formatMessage({ id: "app.utils.unpublish", defaultMessage: "Unpublish" }),
3498
+ dialog: {
3499
+ type: "dialog",
3500
+ title: formatMessage({
3501
+ id: "app.components.ConfirmDialog.title",
3502
+ defaultMessage: "Confirmation"
3503
+ }),
3504
+ content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
3505
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
3506
+ id: "popUpWarning.bodyMessage.contentType.unpublish.all",
3507
+ defaultMessage: "Are you sure you want to unpublish these entries?"
3508
+ }) }),
3509
+ hasI18nEnabled && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { textAlign: "center", padding: 3, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger500", children: formatMessage(
3510
+ {
3511
+ id: getTranslation("Settings.list.actions.unpublishAdditionalInfos"),
3512
+ defaultMessage: "This will unpublish the active locale versions <em>(from Internationalization)</em>"
3513
+ },
3514
+ {
3515
+ em: Emphasis
3516
+ }
3517
+ ) }) })
3518
+ ] }),
3519
+ confirmButton: formatMessage({
3520
+ id: "app.utils.unpublish",
3521
+ defaultMessage: "Unpublish"
3522
+ }),
3523
+ onConfirm: handleConfirmBulkUnpublish
3524
+ }
3264
3525
  };
3265
3526
  };
3266
- const useDocLayout = () => {
3267
- const { model } = useDoc();
3268
- return useDocumentLayout(model);
3527
+ UnpublishAction.type = "unpublish";
3528
+ const Emphasis = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "semiBold", textColor: "danger500", children: chunks });
3529
+ const DEFAULT_BULK_ACTIONS = [PublishAction, UnpublishAction, DeleteAction];
3530
+ const AutoCloneFailureModalBody = ({ prohibitedFields }) => {
3531
+ const { formatMessage } = reactIntl.useIntl();
3532
+ const getDefaultErrorMessage = (reason) => {
3533
+ switch (reason) {
3534
+ case "relation":
3535
+ return "Duplicating the relation could remove it from the original entry.";
3536
+ case "unique":
3537
+ return "Identical values in a unique field are not allowed";
3538
+ default:
3539
+ return reason;
3540
+ }
3541
+ };
3542
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3543
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", children: formatMessage({
3544
+ id: getTranslation("containers.list.autoCloneModal.title"),
3545
+ defaultMessage: "This entry can't be duplicated directly."
3546
+ }) }),
3547
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 2, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", children: formatMessage({
3548
+ id: getTranslation("containers.list.autoCloneModal.description"),
3549
+ defaultMessage: "A new entry will be created with the same content, but you'll have to change the following fields to save it."
3550
+ }) }) }),
3551
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { marginTop: 6, gap: 2, direction: "column", alignItems: "stretch", children: prohibitedFields.map(([fieldPath, reason]) => /* @__PURE__ */ jsxRuntime.jsxs(
3552
+ designSystem.Flex,
3553
+ {
3554
+ direction: "column",
3555
+ gap: 2,
3556
+ alignItems: "flex-start",
3557
+ borderColor: "neutral200",
3558
+ hasRadius: true,
3559
+ padding: 6,
3560
+ children: [
3561
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "row", tag: "ol", children: fieldPath.map((pathSegment, index2) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { fontWeight: "semiBold", tag: "li", children: [
3562
+ pathSegment,
3563
+ index2 !== fieldPath.length - 1 && /* @__PURE__ */ jsxRuntime.jsx(
3564
+ Icons.ChevronRight,
3565
+ {
3566
+ fill: "neutral500",
3567
+ height: "0.8rem",
3568
+ width: "0.8rem",
3569
+ style: { margin: "0 0.8rem" }
3570
+ }
3571
+ )
3572
+ ] }, index2)) }),
3573
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", textColor: "neutral600", children: formatMessage({
3574
+ id: getTranslation(`containers.list.autoCloneModal.error.${reason}`),
3575
+ defaultMessage: getDefaultErrorMessage(reason)
3576
+ }) })
3577
+ ]
3578
+ },
3579
+ fieldPath.join()
3580
+ )) })
3581
+ ] });
3269
3582
  };
3270
- const formatEditLayout = (data, {
3271
- schemas,
3272
- schema,
3273
- components
3274
- }) => {
3275
- let currentPanelIndex = 0;
3276
- const panelledEditAttributes = convertEditLayoutToFieldLayouts(
3277
- data.contentType.layouts.edit,
3278
- schema?.attributes,
3279
- data.contentType.metadatas,
3280
- { configurations: data.components, schemas: components },
3281
- schemas
3282
- ).reduce((panels, row) => {
3283
- if (row.some((field) => field.type === "dynamiczone")) {
3284
- panels.push([row]);
3285
- currentPanelIndex += 2;
3286
- } else {
3287
- if (!panels[currentPanelIndex]) {
3288
- panels.push([]);
3583
+ const TableActions = ({ document }) => {
3584
+ const { formatMessage } = reactIntl.useIntl();
3585
+ const { model, collectionType } = useDoc();
3586
+ const plugins = strapiAdmin.useStrapiApp("TableActions", (state) => state.plugins);
3587
+ const props = {
3588
+ activeTab: null,
3589
+ model,
3590
+ documentId: document.documentId,
3591
+ collectionType,
3592
+ document
3593
+ };
3594
+ return /* @__PURE__ */ jsxRuntime.jsx(
3595
+ strapiAdmin.DescriptionComponentRenderer,
3596
+ {
3597
+ props,
3598
+ descriptions: plugins["content-manager"].apis.getDocumentActions(),
3599
+ children: (actions2) => {
3600
+ const tableRowActions = actions2.filter((action) => {
3601
+ const positions = Array.isArray(action.position) ? action.position : [action.position];
3602
+ return positions.includes("table-row");
3603
+ });
3604
+ return /* @__PURE__ */ jsxRuntime.jsx(
3605
+ DocumentActionsMenu,
3606
+ {
3607
+ actions: tableRowActions,
3608
+ label: formatMessage({
3609
+ id: "content-manager.containers.list.table.row-actions",
3610
+ defaultMessage: "Row action"
3611
+ }),
3612
+ variant: "ghost"
3613
+ }
3614
+ );
3289
3615
  }
3290
- panels[currentPanelIndex].push(row);
3291
3616
  }
3292
- return panels;
3293
- }, []);
3294
- const componentEditAttributes = Object.entries(data.components).reduce(
3295
- (acc, [uid, configuration]) => {
3296
- acc[uid] = {
3297
- layout: convertEditLayoutToFieldLayouts(
3298
- configuration.layouts.edit,
3299
- components[uid].attributes,
3300
- configuration.metadatas
3301
- ),
3302
- settings: {
3303
- ...configuration.settings,
3304
- icon: components[uid].info.icon,
3305
- displayName: components[uid].info.displayName
3306
- }
3307
- };
3308
- return acc;
3309
- },
3310
- {}
3311
- );
3312
- const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
3313
- (acc, [attribute, metadata]) => {
3314
- return {
3315
- ...acc,
3316
- [attribute]: metadata.edit
3317
- };
3318
- },
3319
- {}
3320
3617
  );
3618
+ };
3619
+ const EditAction = ({ documentId }) => {
3620
+ const navigate = reactRouterDom.useNavigate();
3621
+ const { formatMessage } = reactIntl.useIntl();
3622
+ const { canRead } = useDocumentRBAC("EditAction", ({ canRead: canRead2 }) => ({ canRead: canRead2 }));
3623
+ const { toggleNotification } = strapiAdmin.useNotification();
3624
+ const [{ query }] = strapiAdmin.useQueryParams();
3321
3625
  return {
3322
- layout: panelledEditAttributes,
3323
- components: componentEditAttributes,
3324
- metadatas: editMetadatas,
3325
- settings: {
3326
- ...data.contentType.settings,
3327
- displayName: schema?.info.displayName
3328
- },
3329
- options: {
3330
- ...schema?.options,
3331
- ...schema?.pluginOptions,
3332
- ...data.contentType.options
3626
+ disabled: !canRead,
3627
+ icon: /* @__PURE__ */ jsxRuntime.jsx(StyledPencil, {}),
3628
+ label: formatMessage({
3629
+ id: "content-manager.actions.edit.label",
3630
+ defaultMessage: "Edit"
3631
+ }),
3632
+ position: "table-row",
3633
+ onClick: async () => {
3634
+ if (!documentId) {
3635
+ console.error(
3636
+ "You're trying to edit a document without an id, this is likely a bug with Strapi. Please open an issue."
3637
+ );
3638
+ toggleNotification({
3639
+ message: formatMessage({
3640
+ id: "content-manager.actions.edit.error",
3641
+ defaultMessage: "An error occurred while trying to edit the document."
3642
+ }),
3643
+ type: "danger"
3644
+ });
3645
+ return;
3646
+ }
3647
+ navigate({
3648
+ pathname: documentId,
3649
+ search: qs.stringify({
3650
+ plugins: query.plugins
3651
+ })
3652
+ });
3333
3653
  }
3334
3654
  };
3335
3655
  };
3336
- const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
3337
- return rows.map(
3338
- (row) => row.map((field) => {
3339
- const attribute = attributes[field.name];
3340
- if (!attribute) {
3341
- return null;
3656
+ EditAction.type = "edit";
3657
+ const StyledPencil = styledComponents.styled(Icons.Pencil)`
3658
+ path {
3659
+ fill: currentColor;
3660
+ }
3661
+ `;
3662
+ const CloneAction = ({ model, documentId }) => {
3663
+ const navigate = reactRouterDom.useNavigate();
3664
+ const { formatMessage } = reactIntl.useIntl();
3665
+ const { canCreate } = useDocumentRBAC("CloneAction", ({ canCreate: canCreate2 }) => ({ canCreate: canCreate2 }));
3666
+ const { toggleNotification } = strapiAdmin.useNotification();
3667
+ const { autoClone } = useDocumentActions();
3668
+ const [prohibitedFields, setProhibitedFields] = React__namespace.useState([]);
3669
+ return {
3670
+ disabled: !canCreate,
3671
+ icon: /* @__PURE__ */ jsxRuntime.jsx(StyledDuplicate, {}),
3672
+ label: formatMessage({
3673
+ id: "content-manager.actions.clone.label",
3674
+ defaultMessage: "Duplicate"
3675
+ }),
3676
+ position: "table-row",
3677
+ onClick: async () => {
3678
+ if (!documentId) {
3679
+ console.error(
3680
+ "You're trying to clone a document in the table without an id, this is likely a bug with Strapi. Please open an issue."
3681
+ );
3682
+ toggleNotification({
3683
+ message: formatMessage({
3684
+ id: "content-manager.actions.clone.error",
3685
+ defaultMessage: "An error occurred while trying to clone the document."
3686
+ }),
3687
+ type: "danger"
3688
+ });
3689
+ return;
3690
+ }
3691
+ const res = await autoClone({ model, sourceId: documentId });
3692
+ if ("data" in res) {
3693
+ navigate(res.data.documentId);
3694
+ return true;
3695
+ }
3696
+ if (isBaseQueryError(res.error) && res.error.details && typeof res.error.details === "object" && "prohibitedFields" in res.error.details && Array.isArray(res.error.details.prohibitedFields)) {
3697
+ const prohibitedFields2 = res.error.details.prohibitedFields;
3698
+ setProhibitedFields(prohibitedFields2);
3342
3699
  }
3343
- const { edit: metadata } = metadatas[field.name];
3344
- const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
3345
- return {
3346
- attribute,
3347
- disabled: !metadata.editable,
3348
- hint: metadata.description,
3349
- label: metadata.label ?? "",
3350
- name: field.name,
3351
- // @ts-expect-error – mainField does exist on the metadata for a relation.
3352
- mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
3353
- schemas,
3354
- components: components?.schemas ?? {}
3355
- }),
3356
- placeholder: metadata.placeholder ?? "",
3357
- required: attribute.required ?? false,
3358
- size: field.size,
3359
- unique: "unique" in attribute ? attribute.unique : false,
3360
- visible: metadata.visible ?? true,
3361
- type: attribute.type
3362
- };
3363
- }).filter((field) => field !== null)
3364
- );
3365
- };
3366
- const formatListLayout = (data, {
3367
- schemas,
3368
- schema,
3369
- components
3370
- }) => {
3371
- const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
3372
- (acc, [attribute, metadata]) => {
3373
- return {
3374
- ...acc,
3375
- [attribute]: metadata.list
3376
- };
3377
3700
  },
3378
- {}
3379
- );
3380
- const listAttributes = convertListLayoutToFieldLayouts(
3381
- data.contentType.layouts.list,
3382
- schema?.attributes,
3383
- listMetadatas,
3384
- { configurations: data.components, schemas: components },
3385
- schemas
3386
- );
3387
- return {
3388
- layout: listAttributes,
3389
- settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
3390
- metadatas: listMetadatas,
3391
- options: {
3392
- ...schema?.options,
3393
- ...schema?.pluginOptions,
3394
- ...data.contentType.options
3701
+ dialog: {
3702
+ type: "modal",
3703
+ title: formatMessage({
3704
+ id: "content-manager.containers.list.autoCloneModal.header",
3705
+ defaultMessage: "Duplicate"
3706
+ }),
3707
+ content: /* @__PURE__ */ jsxRuntime.jsx(AutoCloneFailureModalBody, { prohibitedFields }),
3708
+ footer: ({ onClose }) => {
3709
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", children: [
3710
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
3711
+ id: "cancel",
3712
+ defaultMessage: "Cancel"
3713
+ }) }),
3714
+ /* @__PURE__ */ jsxRuntime.jsx(
3715
+ designSystem.LinkButton,
3716
+ {
3717
+ tag: reactRouterDom.NavLink,
3718
+ to: {
3719
+ pathname: `clone/${documentId}`
3720
+ },
3721
+ children: formatMessage({
3722
+ id: "content-manager.containers.list.autoCloneModal.create",
3723
+ defaultMessage: "Create"
3724
+ })
3725
+ }
3726
+ )
3727
+ ] });
3728
+ }
3395
3729
  }
3396
3730
  };
3397
3731
  };
3398
- const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
3399
- return columns.map((name) => {
3400
- const attribute = attributes[name];
3401
- if (!attribute) {
3402
- return null;
3732
+ CloneAction.type = "clone";
3733
+ const StyledDuplicate = styledComponents.styled(Icons.Duplicate)`
3734
+ path {
3735
+ fill: currentColor;
3736
+ }
3737
+ `;
3738
+ const DEFAULT_TABLE_ROW_ACTIONS = [EditAction, CloneAction];
3739
+ class ContentManagerPlugin {
3740
+ /**
3741
+ * The following properties are the stored ones provided by any plugins registering with
3742
+ * the content-manager. The function calls however, need to be called at runtime in the
3743
+ * application, so instead we collate them and run them later with the complete list incl.
3744
+ * ones already registered & the context of the view.
3745
+ */
3746
+ bulkActions = [...DEFAULT_BULK_ACTIONS];
3747
+ documentActions = [
3748
+ ...DEFAULT_ACTIONS,
3749
+ ...DEFAULT_TABLE_ROW_ACTIONS,
3750
+ ...DEFAULT_HEADER_ACTIONS,
3751
+ HistoryAction
3752
+ ];
3753
+ editViewSidePanels = [ActionsPanel];
3754
+ headerActions = [];
3755
+ constructor() {
3756
+ }
3757
+ addEditViewSidePanel(panels) {
3758
+ if (Array.isArray(panels)) {
3759
+ this.editViewSidePanels = [...this.editViewSidePanels, ...panels];
3760
+ } else if (typeof panels === "function") {
3761
+ this.editViewSidePanels = panels(this.editViewSidePanels);
3762
+ } else {
3763
+ throw new Error(
3764
+ `Expected the \`panels\` passed to \`addEditViewSidePanel\` to be an array or a function, but received ${getPrintableType(
3765
+ panels
3766
+ )}`
3767
+ );
3403
3768
  }
3404
- const metadata = metadatas[name];
3405
- const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
3769
+ }
3770
+ addDocumentAction(actions2) {
3771
+ if (Array.isArray(actions2)) {
3772
+ this.documentActions = [...this.documentActions, ...actions2];
3773
+ } else if (typeof actions2 === "function") {
3774
+ this.documentActions = actions2(this.documentActions);
3775
+ } else {
3776
+ throw new Error(
3777
+ `Expected the \`actions\` passed to \`addDocumentAction\` to be an array or a function, but received ${getPrintableType(
3778
+ actions2
3779
+ )}`
3780
+ );
3781
+ }
3782
+ }
3783
+ addDocumentHeaderAction(actions2) {
3784
+ if (Array.isArray(actions2)) {
3785
+ this.headerActions = [...this.headerActions, ...actions2];
3786
+ } else if (typeof actions2 === "function") {
3787
+ this.headerActions = actions2(this.headerActions);
3788
+ } else {
3789
+ throw new Error(
3790
+ `Expected the \`actions\` passed to \`addDocumentHeaderAction\` to be an array or a function, but received ${getPrintableType(
3791
+ actions2
3792
+ )}`
3793
+ );
3794
+ }
3795
+ }
3796
+ addBulkAction(actions2) {
3797
+ if (Array.isArray(actions2)) {
3798
+ this.bulkActions = [...this.bulkActions, ...actions2];
3799
+ } else if (typeof actions2 === "function") {
3800
+ this.bulkActions = actions2(this.bulkActions);
3801
+ } else {
3802
+ throw new Error(
3803
+ `Expected the \`actions\` passed to \`addBulkAction\` to be an array or a function, but received ${getPrintableType(
3804
+ actions2
3805
+ )}`
3806
+ );
3807
+ }
3808
+ }
3809
+ get config() {
3406
3810
  return {
3407
- attribute,
3408
- label: metadata.label ?? "",
3409
- mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
3410
- schemas,
3411
- components: components?.schemas ?? {}
3412
- }),
3413
- name,
3414
- searchable: metadata.searchable ?? true,
3415
- sortable: metadata.sortable ?? true
3811
+ id: PLUGIN_ID,
3812
+ name: "Content Manager",
3813
+ injectionZones: INJECTION_ZONES,
3814
+ apis: {
3815
+ addBulkAction: this.addBulkAction.bind(this),
3816
+ addDocumentAction: this.addDocumentAction.bind(this),
3817
+ addDocumentHeaderAction: this.addDocumentHeaderAction.bind(this),
3818
+ addEditViewSidePanel: this.addEditViewSidePanel.bind(this),
3819
+ getBulkActions: () => this.bulkActions,
3820
+ getDocumentActions: () => this.documentActions,
3821
+ getEditViewSidePanels: () => this.editViewSidePanels,
3822
+ getHeaderActions: () => this.headerActions
3823
+ }
3416
3824
  };
3417
- }).filter((field) => field !== null);
3825
+ }
3826
+ }
3827
+ const getPrintableType = (value) => {
3828
+ const nativeType = typeof value;
3829
+ if (nativeType === "object") {
3830
+ if (value === null)
3831
+ return "null";
3832
+ if (Array.isArray(value))
3833
+ return "array";
3834
+ if (value instanceof Object && value.constructor.name !== "Object") {
3835
+ return value.constructor.name;
3836
+ }
3837
+ }
3838
+ return nativeType;
3839
+ };
3840
+ const initialState = {
3841
+ collectionTypeLinks: [],
3842
+ components: [],
3843
+ fieldSizes: {},
3844
+ models: [],
3845
+ singleTypeLinks: [],
3846
+ isLoading: true
3418
3847
  };
3848
+ const appSlice = toolkit.createSlice({
3849
+ name: "app",
3850
+ initialState,
3851
+ reducers: {
3852
+ setInitialData(state, action) {
3853
+ const {
3854
+ authorizedCollectionTypeLinks,
3855
+ authorizedSingleTypeLinks,
3856
+ components,
3857
+ contentTypeSchemas,
3858
+ fieldSizes
3859
+ } = action.payload;
3860
+ state.collectionTypeLinks = authorizedCollectionTypeLinks.filter(
3861
+ ({ isDisplayed }) => isDisplayed
3862
+ );
3863
+ state.singleTypeLinks = authorizedSingleTypeLinks.filter(({ isDisplayed }) => isDisplayed);
3864
+ state.components = components;
3865
+ state.models = contentTypeSchemas;
3866
+ state.fieldSizes = fieldSizes;
3867
+ state.isLoading = false;
3868
+ }
3869
+ }
3870
+ });
3871
+ const { actions, reducer: reducer$1 } = appSlice;
3872
+ const { setInitialData } = actions;
3873
+ const reducer = toolkit.combineReducers({
3874
+ app: reducer$1
3875
+ });
3419
3876
  const index = {
3420
3877
  register(app) {
3421
3878
  const cm = new ContentManagerPlugin();
@@ -3430,7 +3887,7 @@ const index = {
3430
3887
  defaultMessage: "Content Manager"
3431
3888
  },
3432
3889
  permissions: [],
3433
- Component: () => Promise.resolve().then(() => require("./layout-ni_L9kT1.js")).then((mod) => ({ default: mod.Layout })),
3890
+ Component: () => Promise.resolve().then(() => require("./layout-DEYBqgF1.js")).then((mod) => ({ default: mod.Layout })),
3434
3891
  position: 1
3435
3892
  });
3436
3893
  app.registerPlugin(cm.config);
@@ -3438,7 +3895,7 @@ const index = {
3438
3895
  async registerTrads({ locales }) {
3439
3896
  const importedTrads = await Promise.all(
3440
3897
  locales.map((locale) => {
3441
- return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => Promise.resolve().then(() => require("./ar-BUUWXIYu.js")), "./translations/ca.json": () => Promise.resolve().then(() => require("./ca-Cmk45QO6.js")), "./translations/cs.json": () => Promise.resolve().then(() => require("./cs-CkJy6B2v.js")), "./translations/de.json": () => Promise.resolve().then(() => require("./de-CCEmbAah.js")), "./translations/en.json": () => Promise.resolve().then(() => require("./en-DTULi5-d.js")), "./translations/es.json": () => Promise.resolve().then(() => require("./es-EUonQTon.js")), "./translations/eu.json": () => Promise.resolve().then(() => require("./eu-VDH-3ovk.js")), "./translations/fr.json": () => Promise.resolve().then(() => require("./fr-B7kGGg3E.js")), "./translations/gu.json": () => Promise.resolve().then(() => require("./gu-BRmF601H.js")), "./translations/hi.json": () => Promise.resolve().then(() => require("./hi-CCJBptSq.js")), "./translations/hu.json": () => Promise.resolve().then(() => require("./hu-sNV_yLYy.js")), "./translations/id.json": () => Promise.resolve().then(() => require("./id-B5Ser98A.js")), "./translations/it.json": () => Promise.resolve().then(() => require("./it-DkBIs7vD.js")), "./translations/ja.json": () => Promise.resolve().then(() => require("./ja-CcFe8diO.js")), "./translations/ko.json": () => Promise.resolve().then(() => require("./ko-woFZPmLk.js")), "./translations/ml.json": () => Promise.resolve().then(() => require("./ml-C2W8N8k1.js")), "./translations/ms.json": () => Promise.resolve().then(() => require("./ms-BuFotyP_.js")), "./translations/nl.json": () => Promise.resolve().then(() => require("./nl-bbEOHChV.js")), "./translations/pl.json": () => Promise.resolve().then(() => require("./pl-uzwG-hk7.js")), "./translations/pt-BR.json": () => Promise.resolve().then(() => require("./pt-BR-BiOz37D9.js")), "./translations/pt.json": () => Promise.resolve().then(() => require("./pt-CeXQuq50.js")), "./translations/ru.json": () => Promise.resolve().then(() => require("./ru-BT3ybNny.js")), "./translations/sa.json": () => Promise.resolve().then(() => require("./sa-CcvkYInH.js")), "./translations/sk.json": () => Promise.resolve().then(() => require("./sk-CvY09Xjv.js")), "./translations/sv.json": () => Promise.resolve().then(() => require("./sv-MYDuzgvT.js")), "./translations/th.json": () => Promise.resolve().then(() => require("./th-D9_GfAjc.js")), "./translations/tr.json": () => Promise.resolve().then(() => require("./tr-D9UH-O_R.js")), "./translations/uk.json": () => Promise.resolve().then(() => require("./uk-C8EiqJY7.js")), "./translations/vi.json": () => Promise.resolve().then(() => require("./vi-CJlYDheJ.js")), "./translations/zh-Hans.json": () => Promise.resolve().then(() => require("./zh-Hans-9kOncHGw.js")), "./translations/zh.json": () => Promise.resolve().then(() => require("./zh-CQQfszqR.js")) }), `./translations/${locale}.json`).then(({ default: data }) => {
3898
+ return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => Promise.resolve().then(() => require("./ar-BUUWXIYu.js")), "./translations/ca.json": () => Promise.resolve().then(() => require("./ca-Cmk45QO6.js")), "./translations/cs.json": () => Promise.resolve().then(() => require("./cs-CkJy6B2v.js")), "./translations/de.json": () => Promise.resolve().then(() => require("./de-CCEmbAah.js")), "./translations/en.json": () => Promise.resolve().then(() => require("./en-fbKQxLGn.js")), "./translations/es.json": () => Promise.resolve().then(() => require("./es-EUonQTon.js")), "./translations/eu.json": () => Promise.resolve().then(() => require("./eu-VDH-3ovk.js")), "./translations/fr.json": () => Promise.resolve().then(() => require("./fr-B7kGGg3E.js")), "./translations/gu.json": () => Promise.resolve().then(() => require("./gu-BRmF601H.js")), "./translations/hi.json": () => Promise.resolve().then(() => require("./hi-CCJBptSq.js")), "./translations/hu.json": () => Promise.resolve().then(() => require("./hu-sNV_yLYy.js")), "./translations/id.json": () => Promise.resolve().then(() => require("./id-B5Ser98A.js")), "./translations/it.json": () => Promise.resolve().then(() => require("./it-DkBIs7vD.js")), "./translations/ja.json": () => Promise.resolve().then(() => require("./ja-CcFe8diO.js")), "./translations/ko.json": () => Promise.resolve().then(() => require("./ko-woFZPmLk.js")), "./translations/ml.json": () => Promise.resolve().then(() => require("./ml-C2W8N8k1.js")), "./translations/ms.json": () => Promise.resolve().then(() => require("./ms-BuFotyP_.js")), "./translations/nl.json": () => Promise.resolve().then(() => require("./nl-bbEOHChV.js")), "./translations/pl.json": () => Promise.resolve().then(() => require("./pl-uzwG-hk7.js")), "./translations/pt-BR.json": () => Promise.resolve().then(() => require("./pt-BR-BiOz37D9.js")), "./translations/pt.json": () => Promise.resolve().then(() => require("./pt-CeXQuq50.js")), "./translations/ru.json": () => Promise.resolve().then(() => require("./ru-BT3ybNny.js")), "./translations/sa.json": () => Promise.resolve().then(() => require("./sa-CcvkYInH.js")), "./translations/sk.json": () => Promise.resolve().then(() => require("./sk-CvY09Xjv.js")), "./translations/sv.json": () => Promise.resolve().then(() => require("./sv-MYDuzgvT.js")), "./translations/th.json": () => Promise.resolve().then(() => require("./th-D9_GfAjc.js")), "./translations/tr.json": () => Promise.resolve().then(() => require("./tr-D9UH-O_R.js")), "./translations/uk.json": () => Promise.resolve().then(() => require("./uk-C8EiqJY7.js")), "./translations/vi.json": () => Promise.resolve().then(() => require("./vi-CJlYDheJ.js")), "./translations/zh-Hans.json": () => Promise.resolve().then(() => require("./zh-Hans-9kOncHGw.js")), "./translations/zh.json": () => Promise.resolve().then(() => require("./zh-CQQfszqR.js")) }), `./translations/${locale}.json`).then(({ default: data }) => {
3442
3899
  return {
3443
3900
  data: prefixPluginTranslations(data, PLUGIN_ID),
3444
3901
  locale
@@ -3496,4 +3953,4 @@ exports.useGetAllDocumentsQuery = useGetAllDocumentsQuery;
3496
3953
  exports.useGetContentTypeConfigurationQuery = useGetContentTypeConfigurationQuery;
3497
3954
  exports.useGetInitialDataQuery = useGetInitialDataQuery;
3498
3955
  exports.useUpdateContentTypeConfigurationMutation = useUpdateContentTypeConfigurationMutation;
3499
- //# sourceMappingURL=index-CCJeB7Rw.js.map
3956
+ //# sourceMappingURL=index-BZoNZMXL.js.map