@strapi/content-releases 0.0.0-experimental.d8a676a242377cee820b59b21a05d47290d9ac73 → 0.0.0-experimental.defd8568ae03ef8d52f86e1f3541979f953c3941

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-p8aKBitd.js → App-C0DlH0im.js} +343 -323
  2. package/dist/_chunks/App-C0DlH0im.js.map +1 -0
  3. package/dist/_chunks/{App-bpzO2Ljh.mjs → App-O0ZO-S35.mjs} +328 -308
  4. package/dist/_chunks/App-O0ZO-S35.mjs.map +1 -0
  5. package/dist/_chunks/{PurchaseContentReleases-YhAPgpG9.js → PurchaseContentReleases-DAHdUpAA.js} +5 -5
  6. package/dist/_chunks/PurchaseContentReleases-DAHdUpAA.js.map +1 -0
  7. package/dist/_chunks/{PurchaseContentReleases-Clm0iACO.mjs → PurchaseContentReleases-Ex09YpKR.mjs} +6 -6
  8. package/dist/_chunks/PurchaseContentReleases-Ex09YpKR.mjs.map +1 -0
  9. package/dist/_chunks/{en-WuuhP6Bn.mjs → en-B9Ur3VsE.mjs} +11 -3
  10. package/dist/_chunks/en-B9Ur3VsE.mjs.map +1 -0
  11. package/dist/_chunks/{en-gcJJ5htG.js → en-DtFJ5ViE.js} +11 -3
  12. package/dist/_chunks/en-DtFJ5ViE.js.map +1 -0
  13. package/dist/_chunks/{index-AECgcaDa.mjs → index-DjDPK8kb.mjs} +337 -109
  14. package/dist/_chunks/index-DjDPK8kb.mjs.map +1 -0
  15. package/dist/_chunks/{index-fP3qoWZ4.js → index-DoZNNtsb.js} +340 -112
  16. package/dist/_chunks/index-DoZNNtsb.js.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 +358 -237
  43. package/dist/server/index.js.map +1 -1
  44. package/dist/server/index.mjs +359 -237
  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-bpzO2Ljh.mjs.map +0 -1
  104. package/dist/_chunks/App-p8aKBitd.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-WuuhP6Bn.mjs.map +0 -1
  108. package/dist/_chunks/en-gcJJ5htG.js.map +0 -1
  109. package/dist/_chunks/index-AECgcaDa.mjs.map +0 -1
  110. package/dist/_chunks/index-fP3qoWZ4.js.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
7
  const designSystem = require("@strapi/design-system");
8
- const v2 = require("@strapi/design-system/v2");
8
+ const symbols = require("@strapi/icons/symbols");
9
+ const strapiAdmin$1 = require("@strapi/plugin-content-manager/strapi-admin");
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 {
@@ -311,9 +325,11 @@ const releaseApi = react.createApi({
311
325
  method: "DELETE"
312
326
  };
313
327
  },
314
- invalidatesTags: [
328
+ invalidatesTags: (result, error, arg) => [
315
329
  { type: "Release", id: "LIST" },
316
- { type: "ReleaseAction", id: "LIST" }
330
+ { type: "Release", id: arg.params.releaseId },
331
+ { type: "ReleaseAction", id: "LIST" },
332
+ { type: "EntriesInRelease" }
317
333
  ]
318
334
  }),
319
335
  publishRelease: build.mutation({
@@ -332,7 +348,22 @@ const releaseApi = react.createApi({
332
348
  method: "DELETE"
333
349
  };
334
350
  },
335
- 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" }]
336
367
  })
337
368
  };
338
369
  }
@@ -344,11 +375,13 @@ const {
344
375
  useGetReleaseActionsQuery,
345
376
  useCreateReleaseMutation,
346
377
  useCreateReleaseActionMutation,
378
+ useCreateManyReleaseActionsMutation,
347
379
  useUpdateReleaseMutation,
348
380
  useUpdateReleaseActionMutation,
349
381
  usePublishReleaseMutation,
350
382
  useDeleteReleaseActionMutation,
351
- useDeleteReleaseMutation
383
+ useDeleteReleaseMutation,
384
+ useGetMappedEntriesInReleasesQuery
352
385
  } = releaseApi;
353
386
  const getTimezoneOffset = (timezone, date) => {
354
387
  try {
@@ -366,16 +399,12 @@ const getTimezoneOffset = (timezone, date) => {
366
399
  return "";
367
400
  }
368
401
  };
369
- const useTypedDispatch = reactRedux.useDispatch;
370
- const useTypedSelector = reactRedux.useSelector;
371
- const StyledMenuItem = styled__default.default(v2.Menu.Item)`
402
+ const StyledMenuItem = styled__default.default(designSystem.Menu.Item)`
372
403
  &:hover {
373
404
  background: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}100`]};
374
405
 
375
406
  svg {
376
- path {
377
- fill: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}600`]};
378
- }
407
+ fill: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}600`]};
379
408
  }
380
409
 
381
410
  a {
@@ -384,9 +413,7 @@ const StyledMenuItem = styled__default.default(v2.Menu.Item)`
384
413
  }
385
414
 
386
415
  svg {
387
- path {
388
- fill: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}600`]};
389
- }
416
+ fill: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}600`]};
390
417
  }
391
418
 
392
419
  a {
@@ -404,9 +431,12 @@ const StyledIconButton = styled__default.default(designSystem.IconButton)`
404
431
  `;
405
432
  const DeleteReleaseActionItem = ({ releaseId, actionId }) => {
406
433
  const { formatMessage } = reactIntl.useIntl();
407
- const toggleNotification = helperPlugin.useNotification();
408
- const { formatAPIError } = helperPlugin.useAPIErrorHandler();
434
+ const { toggleNotification } = strapiAdmin.useNotification();
435
+ const { formatAPIError } = strapiAdmin.useAPIErrorHandler();
409
436
  const [deleteReleaseAction] = useDeleteReleaseActionMutation();
437
+ const {
438
+ allowedActions: { canDeleteAction }
439
+ } = strapiAdmin.useRBAC(PERMISSIONS);
410
440
  const handleDeleteAction = async () => {
411
441
  const response = await deleteReleaseAction({
412
442
  params: { releaseId, actionId }
@@ -424,24 +454,27 @@ const DeleteReleaseActionItem = ({ releaseId, actionId }) => {
424
454
  if ("error" in response) {
425
455
  if (axios.isAxiosError(response.error)) {
426
456
  toggleNotification({
427
- type: "warning",
457
+ type: "danger",
428
458
  message: formatAPIError(response.error)
429
459
  });
430
460
  } else {
431
461
  toggleNotification({
432
- type: "warning",
462
+ type: "danger",
433
463
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
434
464
  });
435
465
  }
436
466
  }
437
467
  };
438
- 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: [
439
- /* @__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.2rem", height: "1.2rem" }),
440
473
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger600", variant: "omega", children: formatMessage({
441
474
  id: "content-releases.content-manager-edit-view.remove-from-release",
442
475
  defaultMessage: "Remove from release"
443
476
  }) })
444
- ] }) }) });
477
+ ] }) });
445
478
  };
446
479
  const ReleaseActionEntryLinkItem = ({
447
480
  contentTypeUid,
@@ -449,50 +482,53 @@ const ReleaseActionEntryLinkItem = ({
449
482
  locale
450
483
  }) => {
451
484
  const { formatMessage } = reactIntl.useIntl();
452
- const collectionTypePermissions = useTypedSelector(
453
- (state) => state.rbacProvider.collectionTypesRelatedPermissions
454
- );
455
- const updatePermissions = contentTypeUid ? collectionTypePermissions[contentTypeUid]?.["plugin::content-manager.explorer.update"] : [];
456
- const canUpdateEntryForLocale = Boolean(
457
- !locale || updatePermissions?.find(
458
- (permission) => permission.properties?.locales?.includes(locale)
459
- )
460
- );
461
- return /* @__PURE__ */ jsxRuntime.jsx(
462
- helperPlugin.CheckPermissions,
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
+ }
508
+ return /* @__PURE__ */ jsxRuntime.jsx(StyledMenuItem, { children: /* @__PURE__ */ jsxRuntime.jsx(
509
+ designSystem.Link,
463
510
  {
464
- permissions: [
465
- {
466
- action: "plugin::content-manager.explorer.update",
467
- subject: contentTypeUid
468
- }
469
- ],
470
- children: canUpdateEntryForLocale && /* @__PURE__ */ jsxRuntime.jsx(StyledMenuItem, { children: /* @__PURE__ */ jsxRuntime.jsx(
471
- v2.Link,
472
- {
473
- as: reactRouterDom.NavLink,
474
- to: {
475
- pathname: `/content-manager/collection-types/${contentTypeUid}/${entryId}`,
476
- search: locale && `?plugins[i18n][locale]=${locale}`
477
- },
478
- startIcon: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Icon, { as: icons.Pencil, width: 3, height: 3 }),
479
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: formatMessage({
480
- id: "content-releases.content-manager-edit-view.edit-entry",
481
- defaultMessage: "Edit entry"
482
- }) })
483
- }
484
- ) })
511
+ as: reactRouterDom.NavLink,
512
+ to: {
513
+ pathname: `/content-manager/collection-types/${contentTypeUid}/${entryId}`,
514
+ search: locale && `?plugins[i18n][locale]=${locale}`
515
+ },
516
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Pencil, { width: "1.2rem", height: "1.2rem" }),
517
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: formatMessage({
518
+ id: "content-releases.content-manager-edit-view.edit-entry",
519
+ defaultMessage: "Edit entry"
520
+ }) })
485
521
  }
486
- );
522
+ ) });
487
523
  };
488
524
  const EditReleaseItem = ({ releaseId }) => {
489
525
  const { formatMessage } = reactIntl.useIntl();
490
526
  return /* @__PURE__ */ jsxRuntime.jsx(StyledMenuItem, { children: /* @__PURE__ */ jsxRuntime.jsx(
491
- v2.Link,
527
+ designSystem.Link,
492
528
  {
493
- as: reactRouterDom.NavLink,
494
- to: `/plugins/content-releases/${releaseId}`,
495
- startIcon: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Icon, { as: icons.Pencil, width: 3, height: 3 }),
529
+ href: `/admin/plugins/content-releases/${releaseId}`,
530
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Pencil, { width: "1.2rem", height: "1.2rem" }),
531
+ isExternal: false,
496
532
  children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: formatMessage({
497
533
  id: "content-releases.content-manager-edit-view.edit-release",
498
534
  defaultMessage: "Edit release"
@@ -502,11 +538,12 @@ const EditReleaseItem = ({ releaseId }) => {
502
538
  };
503
539
  const Root = ({ children, hasTriggerBorder = false }) => {
504
540
  const { formatMessage } = reactIntl.useIntl();
541
+ const { allowedActions } = strapiAdmin.useRBAC(PERMISSIONS);
505
542
  return (
506
543
  // A user can access the dropdown if they have permissions to delete a release-action OR update a release
507
- /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.CheckPermissions, { permissions: [...PERMISSIONS.deleteAction, ...PERMISSIONS.update], children: /* @__PURE__ */ jsxRuntime.jsxs(v2.Menu.Root, { children: [
544
+ allowedActions.canDeleteAction || allowedActions.canUpdate ? /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Root, { children: [
508
545
  /* @__PURE__ */ jsxRuntime.jsx(
509
- v2.Menu.Trigger,
546
+ designSystem.Menu.Trigger,
510
547
  {
511
548
  as: hasTriggerBorder ? StyledIconButton : designSystem.IconButton,
512
549
  paddingLeft: 2,
@@ -518,8 +555,8 @@ const Root = ({ children, hasTriggerBorder = false }) => {
518
555
  icon: /* @__PURE__ */ jsxRuntime.jsx(icons.More, {})
519
556
  }
520
557
  ),
521
- /* @__PURE__ */ jsxRuntime.jsx(v2.Menu.Content, { top: 1, popoverPlacement: "bottom-end", children })
522
- ] }) })
558
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Menu.Content, { top: 1, popoverPlacement: "bottom-end", children })
559
+ ] }) : null
523
560
  );
524
561
  };
525
562
  const ReleaseActionMenu = {
@@ -651,14 +688,15 @@ const INITIAL_VALUES = {
651
688
  const NoReleases = () => {
652
689
  const { formatMessage } = reactIntl.useIntl();
653
690
  return /* @__PURE__ */ jsxRuntime.jsx(
654
- helperPlugin.NoContent,
691
+ designSystem.EmptyStateLayout,
655
692
  {
656
- content: {
693
+ icon: /* @__PURE__ */ jsxRuntime.jsx(symbols.EmptyDocuments, { width: "16rem" }),
694
+ content: formatMessage({
657
695
  id: "content-releases.content-manager-edit-view.add-to-release.no-releases-message",
658
696
  defaultMessage: "No available releases. Open the list of releases and create a new one from there."
659
- },
697
+ }),
660
698
  action: /* @__PURE__ */ jsxRuntime.jsx(
661
- v2.LinkButton,
699
+ designSystem.LinkButton,
662
700
  {
663
701
  to: {
664
702
  pathname: "/plugins/content-releases"
@@ -681,9 +719,10 @@ const AddActionToReleaseModal = ({
681
719
  }) => {
682
720
  const releaseHeaderId = React__namespace.useId();
683
721
  const { formatMessage } = reactIntl.useIntl();
684
- const toggleNotification = helperPlugin.useNotification();
685
- const { formatAPIError } = helperPlugin.useAPIErrorHandler();
686
- const { modifiedData } = helperPlugin.useCMEditViewDataManager();
722
+ const { toggleNotification } = strapiAdmin.useNotification();
723
+ const { formatAPIError } = strapiAdmin.useAPIErrorHandler();
724
+ const [{ query: query2 }] = strapiAdmin.useQueryParams();
725
+ const locale = query2.plugins?.i18n?.locale;
687
726
  const response = useGetReleasesForEntryQuery({
688
727
  contentTypeUid,
689
728
  entryId,
@@ -692,7 +731,6 @@ const AddActionToReleaseModal = ({
692
731
  const releases = response.data?.data;
693
732
  const [createReleaseAction, { isLoading }] = useCreateReleaseActionMutation();
694
733
  const handleSubmit = async (values) => {
695
- const locale = modifiedData.locale;
696
734
  const releaseActionEntry = {
697
735
  contentType: contentTypeUid,
698
736
  id: entryId,
@@ -716,12 +754,12 @@ const AddActionToReleaseModal = ({
716
754
  if ("error" in response2) {
717
755
  if (axios.isAxiosError(response2.error)) {
718
756
  toggleNotification({
719
- type: "warning",
757
+ type: "danger",
720
758
  message: formatAPIError(response2.error)
721
759
  });
722
760
  } else {
723
761
  toggleNotification({
724
- type: "warning",
762
+ type: "danger",
725
763
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
726
764
  });
727
765
  }
@@ -799,18 +837,20 @@ const AddActionToReleaseModal = ({
799
837
  const CMReleasesContainer = () => {
800
838
  const [isModalOpen, setIsModalOpen] = React__namespace.useState(false);
801
839
  const { formatMessage, formatDate, formatTime } = reactIntl.useIntl();
802
- const {
803
- isCreatingEntry,
804
- hasDraftAndPublish,
805
- initialData: { id: entryId },
806
- slug
807
- } = helperPlugin.useCMEditViewDataManager();
840
+ const { id, slug, collectionType } = reactRouterDom.useParams();
841
+ const isCreatingEntry = id === "create";
842
+ const { allowedActions } = strapiAdmin.useRBAC(PERMISSIONS);
843
+ const { canCreateAction, canRead: canMain, canDeleteAction } = allowedActions;
844
+ const { schema } = strapiAdmin$1.unstable_useDocument({
845
+ collectionType,
846
+ model: slug
847
+ });
848
+ const hasDraftAndPublish = schema?.options?.draftAndPublish;
808
849
  const contentTypeUid = slug;
809
- const IsSchedulingEnabled = window.strapi.future.isEnabled("contentReleasesScheduling");
810
- const canFetch = entryId != null && contentTypeUid != null;
850
+ const canFetch = id != null && contentTypeUid != null;
811
851
  const fetchParams = canFetch ? {
812
852
  contentTypeUid,
813
- entryId,
853
+ entryId: id,
814
854
  hasEntryAttached: true
815
855
  } : query.skipToken;
816
856
  const response = useGetReleasesForEntryQuery(fetchParams);
@@ -828,7 +868,10 @@ const CMReleasesContainer = () => {
828
868
  }
829
869
  return `success${shade}`;
830
870
  };
831
- return /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.CheckPermissions, { permissions: PERMISSIONS.main, children: /* @__PURE__ */ jsxRuntime.jsxs(
871
+ if (!canMain) {
872
+ return null;
873
+ }
874
+ return /* @__PURE__ */ jsxRuntime.jsxs(
832
875
  designSystem.Box,
833
876
  {
834
877
  as: "aside",
@@ -855,7 +898,7 @@ const CMReleasesContainer = () => {
855
898
  alignItems: "start",
856
899
  borderWidth: "1px",
857
900
  borderStyle: "solid",
858
- borderColor: getReleaseColorVariant(release.action.type, "200"),
901
+ borderColor: getReleaseColorVariant(release.actions[0].type, "200"),
859
902
  overflow: "hidden",
860
903
  hasRadius: true,
861
904
  children: [
@@ -866,28 +909,28 @@ const CMReleasesContainer = () => {
866
909
  paddingBottom: 3,
867
910
  paddingLeft: 4,
868
911
  paddingRight: 4,
869
- background: getReleaseColorVariant(release.action.type, "100"),
912
+ background: getReleaseColorVariant(release.actions[0].type, "100"),
870
913
  width: "100%",
871
914
  children: /* @__PURE__ */ jsxRuntime.jsx(
872
915
  designSystem.Typography,
873
916
  {
874
917
  fontSize: 1,
875
918
  variant: "pi",
876
- textColor: getReleaseColorVariant(release.action.type, "600"),
919
+ textColor: getReleaseColorVariant(release.actions[0].type, "600"),
877
920
  children: formatMessage(
878
921
  {
879
922
  id: "content-releases.content-manager-edit-view.list-releases.title",
880
923
  defaultMessage: "{isPublish, select, true {Will be published in} other {Will be unpublished in}}"
881
924
  },
882
- { isPublish: release.action.type === "publish" }
925
+ { isPublish: release.actions[0].type === "publish" }
883
926
  )
884
927
  }
885
928
  )
886
929
  }
887
930
  ),
888
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { padding: 4, direction: "column", gap: 2, width: "100%", alignItems: "flex-start", children: [
931
+ /* @__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
932
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontSize: 2, fontWeight: "bold", variant: "omega", textColor: "neutral700", children: release.name }),
890
- IsSchedulingEnabled && release.scheduledAt && release.timezone && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: formatMessage(
933
+ release.scheduledAt && release.timezone && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: formatMessage(
891
934
  {
892
935
  id: "content-releases.content-manager-edit-view.scheduled.date",
893
936
  defaultMessage: "{date} at {time} ({offset})"
@@ -909,23 +952,23 @@ const CMReleasesContainer = () => {
909
952
  )
910
953
  }
911
954
  ) }),
912
- /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.CheckPermissions, { permissions: PERMISSIONS.deleteAction, children: /* @__PURE__ */ jsxRuntime.jsxs(ReleaseActionMenu.Root, { hasTriggerBorder: true, children: [
955
+ canDeleteAction ? /* @__PURE__ */ jsxRuntime.jsxs(ReleaseActionMenu.Root, { hasTriggerBorder: true, children: [
913
956
  /* @__PURE__ */ jsxRuntime.jsx(ReleaseActionMenu.EditReleaseItem, { releaseId: release.id }),
914
957
  /* @__PURE__ */ jsxRuntime.jsx(
915
958
  ReleaseActionMenu.DeleteReleaseActionItem,
916
959
  {
917
960
  releaseId: release.id,
918
- actionId: release.action.id
961
+ actionId: release.actions[0].id
919
962
  }
920
963
  )
921
- ] }) })
922
- ] })
964
+ ] }) : null
965
+ ] }) })
923
966
  ]
924
967
  },
925
968
  release.id
926
969
  );
927
970
  }),
928
- /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.CheckPermissions, { permissions: PERMISSIONS.createAction, children: /* @__PURE__ */ jsxRuntime.jsx(
971
+ canCreateAction ? /* @__PURE__ */ jsxRuntime.jsx(
929
972
  designSystem.Button,
930
973
  {
931
974
  justifyContent: "center",
@@ -940,45 +983,230 @@ const CMReleasesContainer = () => {
940
983
  defaultMessage: "Add to release"
941
984
  })
942
985
  }
943
- ) })
986
+ ) : null
944
987
  ] }),
945
988
  isModalOpen && /* @__PURE__ */ jsxRuntime.jsx(
946
989
  AddActionToReleaseModal,
947
990
  {
948
991
  handleClose: toggleModal,
949
992
  contentTypeUid,
950
- entryId
993
+ entryId: id
951
994
  }
952
995
  )
953
996
  ]
954
997
  }
955
- ) });
998
+ );
999
+ };
1000
+ const getContentPermissions = (subject) => {
1001
+ const permissions = {
1002
+ publish: [
1003
+ {
1004
+ action: "plugin::content-manager.explorer.publish",
1005
+ subject,
1006
+ id: "",
1007
+ actionParameters: {},
1008
+ properties: {},
1009
+ conditions: []
1010
+ }
1011
+ ]
1012
+ };
1013
+ return permissions;
1014
+ };
1015
+ const ReleaseAction = ({ documentIds, model }) => {
1016
+ const { formatMessage } = reactIntl.useIntl();
1017
+ const { toggleNotification } = strapiAdmin.useNotification();
1018
+ const { formatAPIError } = strapiAdmin.useAPIErrorHandler();
1019
+ const [{ query: query2 }] = strapiAdmin.useQueryParams();
1020
+ const contentPermissions = getContentPermissions(model);
1021
+ const {
1022
+ allowedActions: { canPublish }
1023
+ } = strapiAdmin.useRBAC(contentPermissions);
1024
+ const {
1025
+ allowedActions: { canCreate }
1026
+ } = strapiAdmin.useRBAC(PERMISSIONS);
1027
+ const response = useGetReleasesQuery();
1028
+ const releases = response.data?.data;
1029
+ const [createManyReleaseActions, { isLoading }] = useCreateManyReleaseActionsMutation();
1030
+ const handleSubmit = async (values) => {
1031
+ const locale = query2.plugins?.i18n?.locale;
1032
+ const releaseActionEntries = documentIds.map(
1033
+ (id) => ({
1034
+ type: values.type,
1035
+ entry: {
1036
+ contentType: model,
1037
+ id,
1038
+ locale
1039
+ }
1040
+ })
1041
+ );
1042
+ const response2 = await createManyReleaseActions({
1043
+ body: releaseActionEntries,
1044
+ params: { releaseId: values.releaseId }
1045
+ });
1046
+ if ("data" in response2) {
1047
+ const notificationMessage = formatMessage(
1048
+ {
1049
+ id: "content-releases.content-manager-list-view.add-to-release.notification.success.message",
1050
+ defaultMessage: "{entriesAlreadyInRelease} out of {totalEntries} entries were already in the release."
1051
+ },
1052
+ {
1053
+ entriesAlreadyInRelease: response2.data.meta.entriesAlreadyInRelease,
1054
+ totalEntries: response2.data.meta.totalEntries
1055
+ }
1056
+ );
1057
+ const notification = {
1058
+ type: "success",
1059
+ title: formatMessage(
1060
+ {
1061
+ id: "content-releases.content-manager-list-view.add-to-release.notification.success.title",
1062
+ defaultMessage: "Successfully added to release."
1063
+ },
1064
+ {
1065
+ entriesAlreadyInRelease: response2.data.meta.entriesAlreadyInRelease,
1066
+ totalEntries: response2.data.meta.totalEntries
1067
+ }
1068
+ ),
1069
+ message: response2.data.meta.entriesAlreadyInRelease ? notificationMessage : ""
1070
+ };
1071
+ toggleNotification(notification);
1072
+ return true;
1073
+ }
1074
+ if ("error" in response2) {
1075
+ if (axios.isAxiosError(response2.error)) {
1076
+ toggleNotification({
1077
+ type: "warning",
1078
+ message: formatAPIError(response2.error)
1079
+ });
1080
+ } else {
1081
+ toggleNotification({
1082
+ type: "warning",
1083
+ message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
1084
+ });
1085
+ }
1086
+ }
1087
+ };
1088
+ if (!canCreate || !canPublish)
1089
+ return null;
1090
+ return {
1091
+ actionType: "release",
1092
+ variant: "tertiary",
1093
+ label: formatMessage({
1094
+ id: "content-manager-list-view.add-to-release",
1095
+ defaultMessage: "Add to Release"
1096
+ }),
1097
+ dialog: {
1098
+ type: "modal",
1099
+ title: formatMessage({
1100
+ id: "content-manager-list-view.add-to-release",
1101
+ defaultMessage: "Add to Release"
1102
+ }),
1103
+ content: ({ onClose }) => {
1104
+ return /* @__PURE__ */ jsxRuntime.jsx(
1105
+ formik.Formik,
1106
+ {
1107
+ onSubmit: async (values) => {
1108
+ const data = await handleSubmit(values);
1109
+ if (data) {
1110
+ return onClose();
1111
+ }
1112
+ },
1113
+ validationSchema: RELEASE_ACTION_FORM_SCHEMA,
1114
+ initialValues: INITIAL_VALUES,
1115
+ children: ({ values, setFieldValue }) => /* @__PURE__ */ jsxRuntime.jsxs(formik.Form, { children: [
1116
+ 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: [
1117
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingBottom: 6, children: /* @__PURE__ */ jsxRuntime.jsx(
1118
+ designSystem.SingleSelect,
1119
+ {
1120
+ required: true,
1121
+ label: formatMessage({
1122
+ id: "content-releases.content-manager-list-view.add-to-release.select-label",
1123
+ defaultMessage: "Select a release"
1124
+ }),
1125
+ placeholder: formatMessage({
1126
+ id: "content-releases.content-manager-list-view.add-to-release.select-placeholder",
1127
+ defaultMessage: "Select"
1128
+ }),
1129
+ onChange: (value) => setFieldValue("releaseId", value),
1130
+ value: values.releaseId,
1131
+ children: releases?.map((release) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: release.id, children: release.name }, release.id))
1132
+ }
1133
+ ) }),
1134
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.FieldLabel, { children: formatMessage({
1135
+ id: "content-releases.content-manager-list-view.add-to-release.action-type-label",
1136
+ defaultMessage: "What do you want to do with these entries?"
1137
+ }) }),
1138
+ /* @__PURE__ */ jsxRuntime.jsx(
1139
+ ReleaseActionOptions,
1140
+ {
1141
+ selected: values.type,
1142
+ handleChange: (e) => setFieldValue("type", e.target.value),
1143
+ name: "type"
1144
+ }
1145
+ )
1146
+ ] }) }),
1147
+ /* @__PURE__ */ jsxRuntime.jsx(
1148
+ designSystem.ModalFooter,
1149
+ {
1150
+ startActions: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: onClose, variant: "tertiary", name: "cancel", children: formatMessage({
1151
+ id: "content-releases.content-manager-list-view.add-to-release.cancel-button",
1152
+ defaultMessage: "Cancel"
1153
+ }) }),
1154
+ endActions: (
1155
+ /**
1156
+ * TODO: Ideally we would use isValid from Formik to disable the button, however currently it always returns true
1157
+ * for yup.string().required(), even when the value is falsy (including empty string)
1158
+ */
1159
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { type: "submit", disabled: !values.releaseId, loading: isLoading, children: formatMessage({
1160
+ id: "content-releases.content-manager-list-view.add-to-release.continue-button",
1161
+ defaultMessage: "Continue"
1162
+ }) })
1163
+ )
1164
+ }
1165
+ )
1166
+ ] })
1167
+ }
1168
+ );
1169
+ }
1170
+ }
1171
+ };
1172
+ };
1173
+ const prefixPluginTranslations = (trad, pluginId2) => {
1174
+ if (!pluginId2) {
1175
+ throw new TypeError("pluginId can't be empty");
1176
+ }
1177
+ return Object.keys(trad).reduce((acc, current) => {
1178
+ acc[`${pluginId2}.${current}`] = trad[current];
1179
+ return acc;
1180
+ }, {});
956
1181
  };
957
1182
  const admin = {
958
1183
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
959
1184
  register(app) {
1185
+ app.createHook("ContentReleases/pages/ReleaseDetails/add-locale-in-releases");
960
1186
  if (window.strapi.features.isEnabled("cms-content-releases")) {
961
1187
  app.addMenuLink({
962
- to: `/plugins/${pluginId}`,
1188
+ to: `plugins/${pluginId}`,
963
1189
  icon: icons.PaperPlane,
964
1190
  intlLabel: {
965
1191
  id: `${pluginId}.plugin.name`,
966
1192
  defaultMessage: "Releases"
967
1193
  },
968
- async Component() {
969
- const { App } = await Promise.resolve().then(() => require("./App-p8aKBitd.js"));
970
- return App;
971
- },
1194
+ Component: () => Promise.resolve().then(() => require("./App-C0DlH0im.js")).then((mod) => ({ default: mod.App })),
972
1195
  permissions: PERMISSIONS.main
973
1196
  });
974
1197
  app.addMiddlewares([() => releaseApi.middleware]);
975
1198
  app.addReducers({
976
1199
  [releaseApi.reducerPath]: releaseApi.reducer
977
1200
  });
978
- app.injectContentManagerComponent("editView", "right-links", {
1201
+ app.getPlugin("content-manager").injectComponent("editView", "right-links", {
979
1202
  name: `${pluginId}-link`,
980
1203
  Component: CMReleasesContainer
981
1204
  });
1205
+ app.plugins["content-manager"].apis.addBulkAction((actions) => {
1206
+ const deleteActionIndex = actions.findIndex((action) => action.name === "DeleteAction");
1207
+ actions.splice(deleteActionIndex, 0, ReleaseAction);
1208
+ return actions;
1209
+ });
982
1210
  } else if (!window.strapi.features.isEnabled("cms-content-releases") && window.strapi?.flags?.promoteEE) {
983
1211
  app.addMenuLink({
984
1212
  to: `/plugins/purchase-content-releases`,
@@ -987,9 +1215,10 @@ const admin = {
987
1215
  id: `${pluginId}.plugin.name`,
988
1216
  defaultMessage: "Releases"
989
1217
  },
1218
+ permissions: [],
990
1219
  async Component() {
991
- const { PurchaseContentReleases } = await Promise.resolve().then(() => require("./PurchaseContentReleases-YhAPgpG9.js"));
992
- return PurchaseContentReleases;
1220
+ const { PurchaseContentReleases } = await Promise.resolve().then(() => require("./PurchaseContentReleases-DAHdUpAA.js"));
1221
+ return { default: PurchaseContentReleases };
993
1222
  },
994
1223
  lockIcon: true
995
1224
  });
@@ -998,9 +1227,9 @@ const admin = {
998
1227
  async registerTrads({ locales }) {
999
1228
  const importedTrads = await Promise.all(
1000
1229
  locales.map((locale) => {
1001
- return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => Promise.resolve().then(() => require("./en-gcJJ5htG.js")) }), `./translations/${locale}.json`).then(({ default: data }) => {
1230
+ return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => Promise.resolve().then(() => require("./en-DtFJ5ViE.js")) }), `./translations/${locale}.json`).then(({ default: data }) => {
1002
1231
  return {
1003
- data: helperPlugin.prefixPluginTranslations(data, "content-releases"),
1232
+ data: prefixPluginTranslations(data, "content-releases"),
1004
1233
  locale
1005
1234
  };
1006
1235
  }).catch(() => {
@@ -1028,7 +1257,6 @@ exports.useGetReleaseActionsQuery = useGetReleaseActionsQuery;
1028
1257
  exports.useGetReleaseQuery = useGetReleaseQuery;
1029
1258
  exports.useGetReleasesQuery = useGetReleasesQuery;
1030
1259
  exports.usePublishReleaseMutation = usePublishReleaseMutation;
1031
- exports.useTypedDispatch = useTypedDispatch;
1032
1260
  exports.useUpdateReleaseActionMutation = useUpdateReleaseActionMutation;
1033
1261
  exports.useUpdateReleaseMutation = useUpdateReleaseMutation;
1034
- //# sourceMappingURL=index-fP3qoWZ4.js.map
1262
+ //# sourceMappingURL=index-DoZNNtsb.js.map