@strapi/content-releases 0.0.0-experimental.e5740babedd53cf5b6af99d74920b6b9ef1e4c11 → 0.0.0-experimental.e60ec1829240dae21c1e1d29076681c322288813

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 (110) hide show
  1. package/dist/_chunks/{App-HVXzE3i3.mjs → App-BsUSTHVD.mjs} +243 -213
  2. package/dist/_chunks/App-BsUSTHVD.mjs.map +1 -0
  3. package/dist/_chunks/{App-l62gIUTX.js → App-CXRpb2hi.js} +258 -228
  4. package/dist/_chunks/App-CXRpb2hi.js.map +1 -0
  5. package/dist/_chunks/{PurchaseContentReleases-YhAPgpG9.js → PurchaseContentReleases-Be3acS2L.js} +8 -7
  6. package/dist/_chunks/PurchaseContentReleases-Be3acS2L.js.map +1 -0
  7. package/dist/_chunks/{PurchaseContentReleases-Clm0iACO.mjs → PurchaseContentReleases-_MxP6-Dt.mjs} +9 -8
  8. package/dist/_chunks/PurchaseContentReleases-_MxP6-Dt.mjs.map +1 -0
  9. package/dist/_chunks/{en-RdapH-9X.mjs → en-B9Ur3VsE.mjs} +11 -2
  10. package/dist/_chunks/en-B9Ur3VsE.mjs.map +1 -0
  11. package/dist/_chunks/{en-faJDuv3q.js → en-DtFJ5ViE.js} +11 -2
  12. package/dist/_chunks/en-DtFJ5ViE.js.map +1 -0
  13. package/dist/_chunks/{index-ML_b3php.js → index-B6-lic1Q.js} +340 -113
  14. package/dist/_chunks/index-B6-lic1Q.js.map +1 -0
  15. package/dist/_chunks/{index-Ys87ROOe.mjs → index-DJLIZdZv.mjs} +339 -112
  16. package/dist/_chunks/index-DJLIZdZv.mjs.map +1 -0
  17. package/dist/admin/index.js +1 -15
  18. package/dist/admin/index.js.map +1 -1
  19. package/dist/admin/index.mjs +2 -16
  20. package/dist/admin/index.mjs.map +1 -1
  21. package/dist/admin/src/components/CMReleasesContainer.d.ts +22 -0
  22. package/dist/admin/src/components/RelativeTime.d.ts +28 -0
  23. package/dist/admin/src/components/ReleaseAction.d.ts +3 -0
  24. package/dist/admin/src/components/ReleaseActionMenu.d.ts +26 -0
  25. package/dist/admin/src/components/ReleaseActionOptions.d.ts +9 -0
  26. package/dist/admin/src/components/ReleaseListCell.d.ts +0 -0
  27. package/dist/admin/src/components/ReleaseModal.d.ts +16 -0
  28. package/dist/admin/src/constants.d.ts +58 -0
  29. package/dist/admin/src/index.d.ts +3 -0
  30. package/dist/admin/src/pages/App.d.ts +1 -0
  31. package/dist/admin/src/pages/PurchaseContentReleases.d.ts +2 -0
  32. package/dist/admin/src/pages/ReleaseDetailsPage.d.ts +2 -0
  33. package/dist/admin/src/pages/ReleasesPage.d.ts +8 -0
  34. package/dist/admin/src/pages/tests/mockReleaseDetailsPageData.d.ts +181 -0
  35. package/dist/admin/src/pages/tests/mockReleasesPageData.d.ts +39 -0
  36. package/dist/admin/src/pluginId.d.ts +1 -0
  37. package/dist/admin/src/services/axios.d.ts +29 -0
  38. package/dist/admin/src/services/release.d.ts +429 -0
  39. package/dist/admin/src/store/hooks.d.ts +7 -0
  40. package/dist/admin/src/utils/prefixPluginTranslations.d.ts +3 -0
  41. package/dist/admin/src/utils/time.d.ts +1 -0
  42. package/dist/server/index.js +152 -93
  43. package/dist/server/index.js.map +1 -1
  44. package/dist/server/index.mjs +153 -93
  45. package/dist/server/index.mjs.map +1 -1
  46. package/dist/server/src/bootstrap.d.ts +5 -0
  47. package/dist/server/src/bootstrap.d.ts.map +1 -0
  48. package/dist/server/src/constants.d.ts +12 -0
  49. package/dist/server/src/constants.d.ts.map +1 -0
  50. package/dist/server/src/content-types/index.d.ts +99 -0
  51. package/dist/server/src/content-types/index.d.ts.map +1 -0
  52. package/dist/server/src/content-types/release/index.d.ts +48 -0
  53. package/dist/server/src/content-types/release/index.d.ts.map +1 -0
  54. package/dist/server/src/content-types/release/schema.d.ts +47 -0
  55. package/dist/server/src/content-types/release/schema.d.ts.map +1 -0
  56. package/dist/server/src/content-types/release-action/index.d.ts +50 -0
  57. package/dist/server/src/content-types/release-action/index.d.ts.map +1 -0
  58. package/dist/server/src/content-types/release-action/schema.d.ts +49 -0
  59. package/dist/server/src/content-types/release-action/schema.d.ts.map +1 -0
  60. package/dist/server/src/controllers/index.d.ts +20 -0
  61. package/dist/server/src/controllers/index.d.ts.map +1 -0
  62. package/dist/server/src/controllers/release-action.d.ts +10 -0
  63. package/dist/server/src/controllers/release-action.d.ts.map +1 -0
  64. package/dist/server/src/controllers/release.d.ts +12 -0
  65. package/dist/server/src/controllers/release.d.ts.map +1 -0
  66. package/dist/server/src/controllers/validation/release-action.d.ts +8 -0
  67. package/dist/server/src/controllers/validation/release-action.d.ts.map +1 -0
  68. package/dist/server/src/controllers/validation/release.d.ts +2 -0
  69. package/dist/server/src/controllers/validation/release.d.ts.map +1 -0
  70. package/dist/server/src/destroy.d.ts +5 -0
  71. package/dist/server/src/destroy.d.ts.map +1 -0
  72. package/dist/server/src/index.d.ts +2096 -0
  73. package/dist/server/src/index.d.ts.map +1 -0
  74. package/dist/server/src/migrations/index.d.ts +13 -0
  75. package/dist/server/src/migrations/index.d.ts.map +1 -0
  76. package/dist/server/src/register.d.ts +5 -0
  77. package/dist/server/src/register.d.ts.map +1 -0
  78. package/dist/server/src/routes/index.d.ts +35 -0
  79. package/dist/server/src/routes/index.d.ts.map +1 -0
  80. package/dist/server/src/routes/release-action.d.ts +18 -0
  81. package/dist/server/src/routes/release-action.d.ts.map +1 -0
  82. package/dist/server/src/routes/release.d.ts +18 -0
  83. package/dist/server/src/routes/release.d.ts.map +1 -0
  84. package/dist/server/src/services/index.d.ts +1826 -0
  85. package/dist/server/src/services/index.d.ts.map +1 -0
  86. package/dist/server/src/services/release.d.ts +66 -0
  87. package/dist/server/src/services/release.d.ts.map +1 -0
  88. package/dist/server/src/services/scheduling.d.ts +18 -0
  89. package/dist/server/src/services/scheduling.d.ts.map +1 -0
  90. package/dist/server/src/services/validation.d.ts +18 -0
  91. package/dist/server/src/services/validation.d.ts.map +1 -0
  92. package/dist/server/src/utils/index.d.ts +14 -0
  93. package/dist/server/src/utils/index.d.ts.map +1 -0
  94. package/dist/shared/contracts/release-actions.d.ts +131 -0
  95. package/dist/shared/contracts/release-actions.d.ts.map +1 -0
  96. package/dist/shared/contracts/releases.d.ts +182 -0
  97. package/dist/shared/contracts/releases.d.ts.map +1 -0
  98. package/dist/shared/types.d.ts +24 -0
  99. package/dist/shared/types.d.ts.map +1 -0
  100. package/dist/shared/validation-schemas.d.ts +2 -0
  101. package/dist/shared/validation-schemas.d.ts.map +1 -0
  102. package/package.json +26 -31
  103. package/dist/_chunks/App-HVXzE3i3.mjs.map +0 -1
  104. package/dist/_chunks/App-l62gIUTX.js.map +0 -1
  105. package/dist/_chunks/PurchaseContentReleases-Clm0iACO.mjs.map +0 -1
  106. package/dist/_chunks/PurchaseContentReleases-YhAPgpG9.js.map +0 -1
  107. package/dist/_chunks/en-RdapH-9X.mjs.map +0 -1
  108. package/dist/_chunks/en-faJDuv3q.js.map +0 -1
  109. package/dist/_chunks/index-ML_b3php.js.map +0 -1
  110. package/dist/_chunks/index-Ys87ROOe.mjs.map +0 -1
@@ -1,11 +1,12 @@
1
1
  "use strict";
2
- const helperPlugin = require("@strapi/helper-plugin");
3
2
  const icons = require("@strapi/icons");
4
3
  const jsxRuntime = require("react/jsx-runtime");
5
4
  const React = require("react");
6
5
  const query = require("@reduxjs/toolkit/query");
6
+ const strapiAdmin = require("@strapi/admin/strapi-admin");
7
+ const strapiAdmin$1 = require("@strapi/content-manager/strapi-admin");
7
8
  const designSystem = require("@strapi/design-system");
8
- const v2 = require("@strapi/design-system/v2");
9
+ const symbols = require("@strapi/icons/symbols");
9
10
  const axios = require("axios");
10
11
  const formik = require("formik");
11
12
  const reactIntl = require("react-intl");
@@ -13,7 +14,6 @@ const reactRouterDom = require("react-router-dom");
13
14
  const yup = require("yup");
14
15
  const react = require("@reduxjs/toolkit/query/react");
15
16
  const styled = require("styled-components");
16
- const reactRedux = require("react-redux");
17
17
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
18
18
  function _interopNamespace(e) {
19
19
  if (e && e.__esModule)
@@ -125,7 +125,7 @@ const axiosBaseQuery = async ({
125
125
  config
126
126
  }) => {
127
127
  try {
128
- const { get, post, del, put } = helperPlugin.getFetchClient();
128
+ const { get, post, del, put } = strapiAdmin.getFetchClient();
129
129
  if (method === "POST") {
130
130
  const result2 = await post(url, data, config);
131
131
  return { data: result2.data };
@@ -159,7 +159,7 @@ const isAxiosError = (err) => {
159
159
  const releaseApi = react.createApi({
160
160
  reducerPath: pluginId,
161
161
  baseQuery: axiosBaseQuery,
162
- tagTypes: ["Release", "ReleaseAction"],
162
+ tagTypes: ["Release", "ReleaseAction", "EntriesInRelease"],
163
163
  endpoints: (build) => {
164
164
  return {
165
165
  getReleasesForEntry: build.query({
@@ -274,6 +274,20 @@ const releaseApi = react.createApi({
274
274
  { type: "ReleaseAction", id: "LIST" }
275
275
  ]
276
276
  }),
277
+ createManyReleaseActions: build.mutation({
278
+ query({ body, params }) {
279
+ return {
280
+ url: `/content-releases/${params.releaseId}/actions/bulk`,
281
+ method: "POST",
282
+ data: body
283
+ };
284
+ },
285
+ invalidatesTags: [
286
+ { type: "Release", id: "LIST" },
287
+ { type: "ReleaseAction", id: "LIST" },
288
+ { type: "EntriesInRelease" }
289
+ ]
290
+ }),
277
291
  updateReleaseAction: build.mutation({
278
292
  query({ body, params }) {
279
293
  return {
@@ -314,7 +328,8 @@ const releaseApi = react.createApi({
314
328
  invalidatesTags: (result, error, arg) => [
315
329
  { type: "Release", id: "LIST" },
316
330
  { type: "Release", id: arg.params.releaseId },
317
- { type: "ReleaseAction", id: "LIST" }
331
+ { type: "ReleaseAction", id: "LIST" },
332
+ { type: "EntriesInRelease" }
318
333
  ]
319
334
  }),
320
335
  publishRelease: build.mutation({
@@ -333,7 +348,22 @@ const releaseApi = react.createApi({
333
348
  method: "DELETE"
334
349
  };
335
350
  },
336
- invalidatesTags: () => [{ type: "Release", id: "LIST" }]
351
+ invalidatesTags: () => [{ type: "Release", id: "LIST" }, { type: "EntriesInRelease" }]
352
+ }),
353
+ getMappedEntriesInReleases: build.query({
354
+ query(params) {
355
+ return {
356
+ url: "/content-releases/mapEntriesToReleases",
357
+ method: "GET",
358
+ config: {
359
+ params
360
+ }
361
+ };
362
+ },
363
+ transformResponse(response) {
364
+ return response.data;
365
+ },
366
+ providesTags: [{ type: "EntriesInRelease" }]
337
367
  })
338
368
  };
339
369
  }
@@ -345,11 +375,13 @@ const {
345
375
  useGetReleaseActionsQuery,
346
376
  useCreateReleaseMutation,
347
377
  useCreateReleaseActionMutation,
378
+ useCreateManyReleaseActionsMutation,
348
379
  useUpdateReleaseMutation,
349
380
  useUpdateReleaseActionMutation,
350
381
  usePublishReleaseMutation,
351
382
  useDeleteReleaseActionMutation,
352
- useDeleteReleaseMutation
383
+ useDeleteReleaseMutation,
384
+ useGetMappedEntriesInReleasesQuery
353
385
  } = releaseApi;
354
386
  const getTimezoneOffset = (timezone, date) => {
355
387
  try {
@@ -367,16 +399,12 @@ const getTimezoneOffset = (timezone, date) => {
367
399
  return "";
368
400
  }
369
401
  };
370
- const useTypedDispatch = reactRedux.useDispatch;
371
- const useTypedSelector = reactRedux.useSelector;
372
- const StyledMenuItem = styled__default.default(v2.Menu.Item)`
402
+ const StyledMenuItem = styled__default.default(designSystem.Menu.Item)`
373
403
  &:hover {
374
404
  background: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}100`]};
375
405
 
376
406
  svg {
377
- path {
378
- fill: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}600`]};
379
- }
407
+ fill: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}600`]};
380
408
  }
381
409
 
382
410
  a {
@@ -385,9 +413,7 @@ const StyledMenuItem = styled__default.default(v2.Menu.Item)`
385
413
  }
386
414
 
387
415
  svg {
388
- path {
389
- fill: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}600`]};
390
- }
416
+ fill: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}600`]};
391
417
  }
392
418
 
393
419
  a {
@@ -405,9 +431,12 @@ const StyledIconButton = styled__default.default(designSystem.IconButton)`
405
431
  `;
406
432
  const DeleteReleaseActionItem = ({ releaseId, actionId }) => {
407
433
  const { formatMessage } = reactIntl.useIntl();
408
- const toggleNotification = helperPlugin.useNotification();
409
- const { formatAPIError } = helperPlugin.useAPIErrorHandler();
434
+ const { toggleNotification } = strapiAdmin.useNotification();
435
+ const { formatAPIError } = strapiAdmin.useAPIErrorHandler();
410
436
  const [deleteReleaseAction] = useDeleteReleaseActionMutation();
437
+ const {
438
+ allowedActions: { canDeleteAction }
439
+ } = strapiAdmin.useRBAC(PERMISSIONS);
411
440
  const handleDeleteAction = async () => {
412
441
  const response = await deleteReleaseAction({
413
442
  params: { releaseId, actionId }
@@ -425,24 +454,27 @@ const DeleteReleaseActionItem = ({ releaseId, actionId }) => {
425
454
  if ("error" in response) {
426
455
  if (axios.isAxiosError(response.error)) {
427
456
  toggleNotification({
428
- type: "warning",
457
+ type: "danger",
429
458
  message: formatAPIError(response.error)
430
459
  });
431
460
  } else {
432
461
  toggleNotification({
433
- type: "warning",
462
+ type: "danger",
434
463
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
435
464
  });
436
465
  }
437
466
  }
438
467
  };
439
- return /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.CheckPermissions, { permissions: PERMISSIONS.deleteAction, children: /* @__PURE__ */ jsxRuntime.jsx(StyledMenuItem, { variant: "danger", onSelect: handleDeleteAction, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
440
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Icon, { as: icons.Cross, width: 3, height: 3 }),
468
+ if (!canDeleteAction) {
469
+ return null;
470
+ }
471
+ return /* @__PURE__ */ jsxRuntime.jsx(StyledMenuItem, { variant: "danger", onSelect: handleDeleteAction, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
472
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Cross, { width: "1.6rem", height: "1.6rem" }),
441
473
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger600", variant: "omega", children: formatMessage({
442
474
  id: "content-releases.content-manager-edit-view.remove-from-release",
443
475
  defaultMessage: "Remove from release"
444
476
  }) })
445
- ] }) }) });
477
+ ] }) });
446
478
  };
447
479
  const ReleaseActionEntryLinkItem = ({
448
480
  contentTypeUid,
@@ -450,64 +482,66 @@ const ReleaseActionEntryLinkItem = ({
450
482
  locale
451
483
  }) => {
452
484
  const { formatMessage } = reactIntl.useIntl();
453
- const collectionTypePermissions = useTypedSelector(
454
- (state) => state.rbacProvider.collectionTypesRelatedPermissions
455
- );
456
- const updatePermissions = contentTypeUid ? collectionTypePermissions[contentTypeUid]?.["plugin::content-manager.explorer.update"] : [];
457
- const canUpdateEntryForLocale = Boolean(
458
- !locale || updatePermissions?.find(
459
- (permission) => permission.properties?.locales?.includes(locale)
460
- )
461
- );
485
+ const userPermissions = strapiAdmin.useAuth("ReleaseActionEntryLinkItem", (state) => state.permissions);
486
+ const canUpdateEntryForLocale = React__namespace.useMemo(() => {
487
+ const updatePermissions = userPermissions.find(
488
+ (permission) => permission.subject === contentTypeUid && permission.action === "plugin::content-manager.explorer.update"
489
+ );
490
+ if (!updatePermissions) {
491
+ return false;
492
+ }
493
+ return Boolean(!locale || updatePermissions.properties?.locales?.includes(locale));
494
+ }, [contentTypeUid, locale, userPermissions]);
495
+ const {
496
+ allowedActions: { canUpdate: canUpdateContentType }
497
+ } = strapiAdmin.useRBAC({
498
+ updateContentType: [
499
+ {
500
+ action: "plugin::content-manager.explorer.update",
501
+ subject: contentTypeUid
502
+ }
503
+ ]
504
+ });
505
+ if (!canUpdateContentType || !canUpdateEntryForLocale) {
506
+ return null;
507
+ }
462
508
  return /* @__PURE__ */ jsxRuntime.jsx(
463
- helperPlugin.CheckPermissions,
509
+ StyledMenuItem,
464
510
  {
465
- permissions: [
466
- {
467
- action: "plugin::content-manager.explorer.update",
468
- subject: contentTypeUid
469
- }
470
- ],
471
- children: canUpdateEntryForLocale && /* @__PURE__ */ jsxRuntime.jsx(StyledMenuItem, { children: /* @__PURE__ */ jsxRuntime.jsx(
472
- v2.Link,
473
- {
474
- as: reactRouterDom.NavLink,
475
- to: {
476
- pathname: `/content-manager/collection-types/${contentTypeUid}/${entryId}`,
477
- search: locale && `?plugins[i18n][locale]=${locale}`
478
- },
479
- startIcon: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Icon, { as: icons.Pencil, width: 3, height: 3 }),
480
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: formatMessage({
481
- id: "content-releases.content-manager-edit-view.edit-entry",
482
- defaultMessage: "Edit entry"
483
- }) })
484
- }
485
- ) })
511
+ forwardedAs: reactRouterDom.Link,
512
+ isLink: true,
513
+ to: {
514
+ pathname: `/content-manager/collection-types/${contentTypeUid}/${entryId}`,
515
+ search: locale && `?plugins[i18n][locale]=${locale}`
516
+ },
517
+ children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
518
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Pencil, { width: "1.6rem", height: "1.6rem" }),
519
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: formatMessage({
520
+ id: "content-releases.content-manager-edit-view.edit-entry",
521
+ defaultMessage: "Edit entry"
522
+ }) })
523
+ ] })
486
524
  }
487
525
  );
488
526
  };
489
527
  const EditReleaseItem = ({ releaseId }) => {
490
528
  const { formatMessage } = reactIntl.useIntl();
491
- return /* @__PURE__ */ jsxRuntime.jsx(StyledMenuItem, { children: /* @__PURE__ */ jsxRuntime.jsx(
492
- v2.Link,
493
- {
494
- href: `/admin/plugins/content-releases/${releaseId}`,
495
- startIcon: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Icon, { as: icons.Pencil, width: 3, height: 3 }),
496
- isExternal: false,
497
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: formatMessage({
498
- id: "content-releases.content-manager-edit-view.edit-release",
499
- defaultMessage: "Edit release"
500
- }) })
501
- }
502
- ) });
529
+ return /* @__PURE__ */ jsxRuntime.jsx(StyledMenuItem, { forwardedAs: reactRouterDom.Link, isLink: true, to: `/plugins/content-releases/${releaseId}`, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
530
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Pencil, { width: "1.6rem", height: "1.6rem" }),
531
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: formatMessage({
532
+ id: "content-releases.content-manager-edit-view.edit-release",
533
+ defaultMessage: "Edit release"
534
+ }) })
535
+ ] }) });
503
536
  };
504
537
  const Root = ({ children, hasTriggerBorder = false }) => {
505
538
  const { formatMessage } = reactIntl.useIntl();
539
+ const { allowedActions } = strapiAdmin.useRBAC(PERMISSIONS);
506
540
  return (
507
541
  // A user can access the dropdown if they have permissions to delete a release-action OR update a release
508
- /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.CheckPermissions, { permissions: [...PERMISSIONS.deleteAction, ...PERMISSIONS.update], children: /* @__PURE__ */ jsxRuntime.jsxs(v2.Menu.Root, { children: [
542
+ allowedActions.canDeleteAction || allowedActions.canUpdate ? /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Root, { children: [
509
543
  /* @__PURE__ */ jsxRuntime.jsx(
510
- v2.Menu.Trigger,
544
+ designSystem.Menu.Trigger,
511
545
  {
512
546
  as: hasTriggerBorder ? StyledIconButton : designSystem.IconButton,
513
547
  paddingLeft: 2,
@@ -519,8 +553,8 @@ const Root = ({ children, hasTriggerBorder = false }) => {
519
553
  icon: /* @__PURE__ */ jsxRuntime.jsx(icons.More, {})
520
554
  }
521
555
  ),
522
- /* @__PURE__ */ jsxRuntime.jsx(v2.Menu.Content, { top: 1, popoverPlacement: "bottom-end", children })
523
- ] }) })
556
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Menu.Content, { top: 1, popoverPlacement: "bottom-end", children })
557
+ ] }) : null
524
558
  );
525
559
  };
526
560
  const ReleaseActionMenu = {
@@ -652,14 +686,15 @@ const INITIAL_VALUES = {
652
686
  const NoReleases = () => {
653
687
  const { formatMessage } = reactIntl.useIntl();
654
688
  return /* @__PURE__ */ jsxRuntime.jsx(
655
- helperPlugin.NoContent,
689
+ designSystem.EmptyStateLayout,
656
690
  {
657
- content: {
691
+ icon: /* @__PURE__ */ jsxRuntime.jsx(symbols.EmptyDocuments, { width: "16rem" }),
692
+ content: formatMessage({
658
693
  id: "content-releases.content-manager-edit-view.add-to-release.no-releases-message",
659
694
  defaultMessage: "No available releases. Open the list of releases and create a new one from there."
660
- },
695
+ }),
661
696
  action: /* @__PURE__ */ jsxRuntime.jsx(
662
- v2.LinkButton,
697
+ designSystem.LinkButton,
663
698
  {
664
699
  to: {
665
700
  pathname: "/plugins/content-releases"
@@ -682,9 +717,10 @@ const AddActionToReleaseModal = ({
682
717
  }) => {
683
718
  const releaseHeaderId = React__namespace.useId();
684
719
  const { formatMessage } = reactIntl.useIntl();
685
- const toggleNotification = helperPlugin.useNotification();
686
- const { formatAPIError } = helperPlugin.useAPIErrorHandler();
687
- const { modifiedData } = helperPlugin.useCMEditViewDataManager();
720
+ const { toggleNotification } = strapiAdmin.useNotification();
721
+ const { formatAPIError } = strapiAdmin.useAPIErrorHandler();
722
+ const [{ query: query2 }] = strapiAdmin.useQueryParams();
723
+ const locale = query2.plugins?.i18n?.locale;
688
724
  const response = useGetReleasesForEntryQuery({
689
725
  contentTypeUid,
690
726
  entryId,
@@ -693,7 +729,6 @@ const AddActionToReleaseModal = ({
693
729
  const releases = response.data?.data;
694
730
  const [createReleaseAction, { isLoading }] = useCreateReleaseActionMutation();
695
731
  const handleSubmit = async (values) => {
696
- const locale = modifiedData.locale;
697
732
  const releaseActionEntry = {
698
733
  contentType: contentTypeUid,
699
734
  id: entryId,
@@ -717,12 +752,12 @@ const AddActionToReleaseModal = ({
717
752
  if ("error" in response2) {
718
753
  if (axios.isAxiosError(response2.error)) {
719
754
  toggleNotification({
720
- type: "warning",
755
+ type: "danger",
721
756
  message: formatAPIError(response2.error)
722
757
  });
723
758
  } else {
724
759
  toggleNotification({
725
- type: "warning",
760
+ type: "danger",
726
761
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
727
762
  });
728
763
  }
@@ -800,14 +835,18 @@ const AddActionToReleaseModal = ({
800
835
  const CMReleasesContainer = () => {
801
836
  const [isModalOpen, setIsModalOpen] = React__namespace.useState(false);
802
837
  const { formatMessage, formatDate, formatTime } = reactIntl.useIntl();
803
- const {
804
- isCreatingEntry,
805
- hasDraftAndPublish,
806
- initialData: { id: entryId },
807
- slug
808
- } = helperPlugin.useCMEditViewDataManager();
838
+ const { id, slug, collectionType } = reactRouterDom.useParams();
839
+ const isCreatingEntry = id === "create";
840
+ const entryId = parseInt(id, 10);
841
+ const { allowedActions } = strapiAdmin.useRBAC(PERMISSIONS);
842
+ const { canCreateAction, canRead: canMain, canDeleteAction } = allowedActions;
843
+ const { schema } = strapiAdmin$1.unstable_useDocument({
844
+ collectionType,
845
+ model: slug
846
+ });
847
+ const hasDraftAndPublish = schema?.options?.draftAndPublish;
809
848
  const contentTypeUid = slug;
810
- const canFetch = entryId != null && contentTypeUid != null;
849
+ const canFetch = id != null && contentTypeUid != null;
811
850
  const fetchParams = canFetch ? {
812
851
  contentTypeUid,
813
852
  entryId,
@@ -828,7 +867,10 @@ const CMReleasesContainer = () => {
828
867
  }
829
868
  return `success${shade}`;
830
869
  };
831
- return /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.CheckPermissions, { permissions: PERMISSIONS.main, children: /* @__PURE__ */ jsxRuntime.jsxs(
870
+ if (!canMain) {
871
+ return null;
872
+ }
873
+ return /* @__PURE__ */ jsxRuntime.jsxs(
832
874
  designSystem.Box,
833
875
  {
834
876
  as: "aside",
@@ -855,7 +897,7 @@ const CMReleasesContainer = () => {
855
897
  alignItems: "start",
856
898
  borderWidth: "1px",
857
899
  borderStyle: "solid",
858
- borderColor: getReleaseColorVariant(release.action.type, "200"),
900
+ borderColor: getReleaseColorVariant(release.actions[0].type, "200"),
859
901
  overflow: "hidden",
860
902
  hasRadius: true,
861
903
  children: [
@@ -866,26 +908,26 @@ const CMReleasesContainer = () => {
866
908
  paddingBottom: 3,
867
909
  paddingLeft: 4,
868
910
  paddingRight: 4,
869
- background: getReleaseColorVariant(release.action.type, "100"),
911
+ background: getReleaseColorVariant(release.actions[0].type, "100"),
870
912
  width: "100%",
871
913
  children: /* @__PURE__ */ jsxRuntime.jsx(
872
914
  designSystem.Typography,
873
915
  {
874
916
  fontSize: 1,
875
917
  variant: "pi",
876
- textColor: getReleaseColorVariant(release.action.type, "600"),
918
+ textColor: getReleaseColorVariant(release.actions[0].type, "600"),
877
919
  children: formatMessage(
878
920
  {
879
921
  id: "content-releases.content-manager-edit-view.list-releases.title",
880
922
  defaultMessage: "{isPublish, select, true {Will be published in} other {Will be unpublished in}}"
881
923
  },
882
- { isPublish: release.action.type === "publish" }
924
+ { isPublish: release.actions[0].type === "publish" }
883
925
  )
884
926
  }
885
927
  )
886
928
  }
887
929
  ),
888
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { padding: 4, direction: "column", gap: 2, width: "100%", alignItems: "flex-start", children: [
930
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { padding: 4, direction: "column", gap: 2, width: "100%", alignItems: "flex-start", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { padding: 4, direction: "column", gap: 2, width: "100%", alignItems: "flex-start", children: [
889
931
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontSize: 2, fontWeight: "bold", variant: "omega", textColor: "neutral700", children: release.name }),
890
932
  release.scheduledAt && release.timezone && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: formatMessage(
891
933
  {
@@ -909,23 +951,23 @@ const CMReleasesContainer = () => {
909
951
  )
910
952
  }
911
953
  ) }),
912
- /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.CheckPermissions, { permissions: PERMISSIONS.deleteAction, children: /* @__PURE__ */ jsxRuntime.jsxs(ReleaseActionMenu.Root, { hasTriggerBorder: true, children: [
954
+ canDeleteAction ? /* @__PURE__ */ jsxRuntime.jsxs(ReleaseActionMenu.Root, { hasTriggerBorder: true, children: [
913
955
  /* @__PURE__ */ jsxRuntime.jsx(ReleaseActionMenu.EditReleaseItem, { releaseId: release.id }),
914
956
  /* @__PURE__ */ jsxRuntime.jsx(
915
957
  ReleaseActionMenu.DeleteReleaseActionItem,
916
958
  {
917
959
  releaseId: release.id,
918
- actionId: release.action.id
960
+ actionId: release.actions[0].id
919
961
  }
920
962
  )
921
- ] }) })
922
- ] })
963
+ ] }) : null
964
+ ] }) })
923
965
  ]
924
966
  },
925
967
  release.id
926
968
  );
927
969
  }),
928
- /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.CheckPermissions, { permissions: PERMISSIONS.createAction, children: /* @__PURE__ */ jsxRuntime.jsx(
970
+ canCreateAction ? /* @__PURE__ */ jsxRuntime.jsx(
929
971
  designSystem.Button,
930
972
  {
931
973
  justifyContent: "center",
@@ -940,7 +982,7 @@ const CMReleasesContainer = () => {
940
982
  defaultMessage: "Add to release"
941
983
  })
942
984
  }
943
- ) })
985
+ ) : null
944
986
  ] }),
945
987
  isModalOpen && /* @__PURE__ */ jsxRuntime.jsx(
946
988
  AddActionToReleaseModal,
@@ -952,33 +994,218 @@ const CMReleasesContainer = () => {
952
994
  )
953
995
  ]
954
996
  }
955
- ) });
997
+ );
998
+ };
999
+ const getContentPermissions = (subject) => {
1000
+ const permissions = {
1001
+ publish: [
1002
+ {
1003
+ action: "plugin::content-manager.explorer.publish",
1004
+ subject,
1005
+ id: "",
1006
+ actionParameters: {},
1007
+ properties: {},
1008
+ conditions: []
1009
+ }
1010
+ ]
1011
+ };
1012
+ return permissions;
1013
+ };
1014
+ const ReleaseAction = ({ documentIds, model }) => {
1015
+ const { formatMessage } = reactIntl.useIntl();
1016
+ const { toggleNotification } = strapiAdmin.useNotification();
1017
+ const { formatAPIError } = strapiAdmin.useAPIErrorHandler();
1018
+ const [{ query: query2 }] = strapiAdmin.useQueryParams();
1019
+ const contentPermissions = getContentPermissions(model);
1020
+ const {
1021
+ allowedActions: { canPublish }
1022
+ } = strapiAdmin.useRBAC(contentPermissions);
1023
+ const {
1024
+ allowedActions: { canCreate }
1025
+ } = strapiAdmin.useRBAC(PERMISSIONS);
1026
+ const response = useGetReleasesQuery();
1027
+ const releases = response.data?.data;
1028
+ const [createManyReleaseActions, { isLoading }] = useCreateManyReleaseActionsMutation();
1029
+ const handleSubmit = async (values) => {
1030
+ const locale = query2.plugins?.i18n?.locale;
1031
+ const releaseActionEntries = documentIds.map(
1032
+ (id) => ({
1033
+ type: values.type,
1034
+ entry: {
1035
+ contentType: model,
1036
+ id,
1037
+ locale
1038
+ }
1039
+ })
1040
+ );
1041
+ const response2 = await createManyReleaseActions({
1042
+ body: releaseActionEntries,
1043
+ params: { releaseId: values.releaseId }
1044
+ });
1045
+ if ("data" in response2) {
1046
+ const notificationMessage = formatMessage(
1047
+ {
1048
+ id: "content-releases.content-manager-list-view.add-to-release.notification.success.message",
1049
+ defaultMessage: "{entriesAlreadyInRelease} out of {totalEntries} entries were already in the release."
1050
+ },
1051
+ {
1052
+ entriesAlreadyInRelease: response2.data.meta.entriesAlreadyInRelease,
1053
+ totalEntries: response2.data.meta.totalEntries
1054
+ }
1055
+ );
1056
+ const notification = {
1057
+ type: "success",
1058
+ title: formatMessage(
1059
+ {
1060
+ id: "content-releases.content-manager-list-view.add-to-release.notification.success.title",
1061
+ defaultMessage: "Successfully added to release."
1062
+ },
1063
+ {
1064
+ entriesAlreadyInRelease: response2.data.meta.entriesAlreadyInRelease,
1065
+ totalEntries: response2.data.meta.totalEntries
1066
+ }
1067
+ ),
1068
+ message: response2.data.meta.entriesAlreadyInRelease ? notificationMessage : ""
1069
+ };
1070
+ toggleNotification(notification);
1071
+ return true;
1072
+ }
1073
+ if ("error" in response2) {
1074
+ if (axios.isAxiosError(response2.error)) {
1075
+ toggleNotification({
1076
+ type: "warning",
1077
+ message: formatAPIError(response2.error)
1078
+ });
1079
+ } else {
1080
+ toggleNotification({
1081
+ type: "warning",
1082
+ message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
1083
+ });
1084
+ }
1085
+ }
1086
+ };
1087
+ if (!canCreate || !canPublish)
1088
+ return null;
1089
+ return {
1090
+ actionType: "release",
1091
+ variant: "tertiary",
1092
+ label: formatMessage({
1093
+ id: "content-manager-list-view.add-to-release",
1094
+ defaultMessage: "Add to Release"
1095
+ }),
1096
+ dialog: {
1097
+ type: "modal",
1098
+ title: formatMessage({
1099
+ id: "content-manager-list-view.add-to-release",
1100
+ defaultMessage: "Add to Release"
1101
+ }),
1102
+ content: ({ onClose }) => {
1103
+ return /* @__PURE__ */ jsxRuntime.jsx(
1104
+ formik.Formik,
1105
+ {
1106
+ onSubmit: async (values) => {
1107
+ const data = await handleSubmit(values);
1108
+ if (data) {
1109
+ return onClose();
1110
+ }
1111
+ },
1112
+ validationSchema: RELEASE_ACTION_FORM_SCHEMA,
1113
+ initialValues: INITIAL_VALUES,
1114
+ children: ({ values, setFieldValue }) => /* @__PURE__ */ jsxRuntime.jsxs(formik.Form, { children: [
1115
+ releases?.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(NoReleases, {}) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.ModalBody, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
1116
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingBottom: 6, children: /* @__PURE__ */ jsxRuntime.jsx(
1117
+ designSystem.SingleSelect,
1118
+ {
1119
+ required: true,
1120
+ label: formatMessage({
1121
+ id: "content-releases.content-manager-list-view.add-to-release.select-label",
1122
+ defaultMessage: "Select a release"
1123
+ }),
1124
+ placeholder: formatMessage({
1125
+ id: "content-releases.content-manager-list-view.add-to-release.select-placeholder",
1126
+ defaultMessage: "Select"
1127
+ }),
1128
+ onChange: (value) => setFieldValue("releaseId", value),
1129
+ value: values.releaseId,
1130
+ children: releases?.map((release) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: release.id, children: release.name }, release.id))
1131
+ }
1132
+ ) }),
1133
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.FieldLabel, { children: formatMessage({
1134
+ id: "content-releases.content-manager-list-view.add-to-release.action-type-label",
1135
+ defaultMessage: "What do you want to do with these entries?"
1136
+ }) }),
1137
+ /* @__PURE__ */ jsxRuntime.jsx(
1138
+ ReleaseActionOptions,
1139
+ {
1140
+ selected: values.type,
1141
+ handleChange: (e) => setFieldValue("type", e.target.value),
1142
+ name: "type"
1143
+ }
1144
+ )
1145
+ ] }) }),
1146
+ /* @__PURE__ */ jsxRuntime.jsx(
1147
+ designSystem.ModalFooter,
1148
+ {
1149
+ startActions: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: onClose, variant: "tertiary", name: "cancel", children: formatMessage({
1150
+ id: "content-releases.content-manager-list-view.add-to-release.cancel-button",
1151
+ defaultMessage: "Cancel"
1152
+ }) }),
1153
+ endActions: (
1154
+ /**
1155
+ * TODO: Ideally we would use isValid from Formik to disable the button, however currently it always returns true
1156
+ * for yup.string().required(), even when the value is falsy (including empty string)
1157
+ */
1158
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { type: "submit", disabled: !values.releaseId, loading: isLoading, children: formatMessage({
1159
+ id: "content-releases.content-manager-list-view.add-to-release.continue-button",
1160
+ defaultMessage: "Continue"
1161
+ }) })
1162
+ )
1163
+ }
1164
+ )
1165
+ ] })
1166
+ }
1167
+ );
1168
+ }
1169
+ }
1170
+ };
1171
+ };
1172
+ const prefixPluginTranslations = (trad, pluginId2) => {
1173
+ if (!pluginId2) {
1174
+ throw new TypeError("pluginId can't be empty");
1175
+ }
1176
+ return Object.keys(trad).reduce((acc, current) => {
1177
+ acc[`${pluginId2}.${current}`] = trad[current];
1178
+ return acc;
1179
+ }, {});
956
1180
  };
957
1181
  const admin = {
958
1182
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
959
1183
  register(app) {
1184
+ app.createHook("ContentReleases/pages/ReleaseDetails/add-locale-in-releases");
960
1185
  if (window.strapi.features.isEnabled("cms-content-releases")) {
961
1186
  app.addMenuLink({
962
- to: `/plugins/${pluginId}`,
1187
+ to: `plugins/${pluginId}`,
963
1188
  icon: icons.PaperPlane,
964
1189
  intlLabel: {
965
1190
  id: `${pluginId}.plugin.name`,
966
1191
  defaultMessage: "Releases"
967
1192
  },
968
- async Component() {
969
- const { App } = await Promise.resolve().then(() => require("./App-l62gIUTX.js"));
970
- return App;
971
- },
1193
+ Component: () => Promise.resolve().then(() => require("./App-CXRpb2hi.js")).then((mod) => ({ default: mod.App })),
972
1194
  permissions: PERMISSIONS.main
973
1195
  });
974
1196
  app.addMiddlewares([() => releaseApi.middleware]);
975
1197
  app.addReducers({
976
1198
  [releaseApi.reducerPath]: releaseApi.reducer
977
1199
  });
978
- app.injectContentManagerComponent("editView", "right-links", {
1200
+ app.getPlugin("content-manager").injectComponent("editView", "right-links", {
979
1201
  name: `${pluginId}-link`,
980
1202
  Component: CMReleasesContainer
981
1203
  });
1204
+ app.plugins["content-manager"].apis.addBulkAction((actions) => {
1205
+ const deleteActionIndex = actions.findIndex((action) => action.name === "DeleteAction");
1206
+ actions.splice(deleteActionIndex, 0, ReleaseAction);
1207
+ return actions;
1208
+ });
982
1209
  } else if (!window.strapi.features.isEnabled("cms-content-releases") && window.strapi?.flags?.promoteEE) {
983
1210
  app.addMenuLink({
984
1211
  to: `/plugins/purchase-content-releases`,
@@ -987,9 +1214,10 @@ const admin = {
987
1214
  id: `${pluginId}.plugin.name`,
988
1215
  defaultMessage: "Releases"
989
1216
  },
1217
+ permissions: [],
990
1218
  async Component() {
991
- const { PurchaseContentReleases } = await Promise.resolve().then(() => require("./PurchaseContentReleases-YhAPgpG9.js"));
992
- return PurchaseContentReleases;
1219
+ const { PurchaseContentReleases } = await Promise.resolve().then(() => require("./PurchaseContentReleases-Be3acS2L.js"));
1220
+ return { default: PurchaseContentReleases };
993
1221
  },
994
1222
  lockIcon: true
995
1223
  });
@@ -998,9 +1226,9 @@ const admin = {
998
1226
  async registerTrads({ locales }) {
999
1227
  const importedTrads = await Promise.all(
1000
1228
  locales.map((locale) => {
1001
- return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => Promise.resolve().then(() => require("./en-faJDuv3q.js")) }), `./translations/${locale}.json`).then(({ default: data }) => {
1229
+ return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => Promise.resolve().then(() => require("./en-DtFJ5ViE.js")) }), `./translations/${locale}.json`).then(({ default: data }) => {
1002
1230
  return {
1003
- data: helperPlugin.prefixPluginTranslations(data, "content-releases"),
1231
+ data: prefixPluginTranslations(data, "content-releases"),
1004
1232
  locale
1005
1233
  };
1006
1234
  }).catch(() => {
@@ -1028,7 +1256,6 @@ exports.useGetReleaseActionsQuery = useGetReleaseActionsQuery;
1028
1256
  exports.useGetReleaseQuery = useGetReleaseQuery;
1029
1257
  exports.useGetReleasesQuery = useGetReleasesQuery;
1030
1258
  exports.usePublishReleaseMutation = usePublishReleaseMutation;
1031
- exports.useTypedDispatch = useTypedDispatch;
1032
1259
  exports.useUpdateReleaseActionMutation = useUpdateReleaseActionMutation;
1033
1260
  exports.useUpdateReleaseMutation = useUpdateReleaseMutation;
1034
- //# sourceMappingURL=index-ML_b3php.js.map
1261
+ //# sourceMappingURL=index-B6-lic1Q.js.map