@strapi/content-releases 5.0.0-beta.1 → 5.0.0-beta.11

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 (109) hide show
  1. package/dist/_chunks/{App-1LckaIGY.js → App-B5UOQWbt.js} +375 -368
  2. package/dist/_chunks/App-B5UOQWbt.js.map +1 -0
  3. package/dist/_chunks/{App-X01LBg5V.mjs → App-DcXlnXrr.mjs} +371 -363
  4. package/dist/_chunks/App-DcXlnXrr.mjs.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/SettingsPage-ped5WZ6Q.js +40 -0
  10. package/dist/_chunks/SettingsPage-ped5WZ6Q.js.map +1 -0
  11. package/dist/_chunks/SettingsPage-w5dOMAtL.mjs +40 -0
  12. package/dist/_chunks/SettingsPage-w5dOMAtL.mjs.map +1 -0
  13. package/dist/_chunks/{en-faJDuv3q.js → en-aH5E5UNw.js} +12 -2
  14. package/dist/_chunks/en-aH5E5UNw.js.map +1 -0
  15. package/dist/_chunks/{en-RdapH-9X.mjs → en-ahPQUZv2.mjs} +12 -2
  16. package/dist/_chunks/en-ahPQUZv2.mjs.map +1 -0
  17. package/dist/_chunks/{index-cYWov2wa.js → index-BgID5UQ7.js} +549 -525
  18. package/dist/_chunks/index-BgID5UQ7.js.map +1 -0
  19. package/dist/_chunks/{index-OD9AlD-6.mjs → index-LUuvped4.mjs} +551 -525
  20. package/dist/_chunks/index-LUuvped4.mjs.map +1 -0
  21. package/dist/admin/index.js +1 -1
  22. package/dist/admin/index.mjs +2 -2
  23. package/dist/admin/src/components/ReleaseAction.d.ts +3 -0
  24. package/dist/admin/src/components/ReleaseActionMenu.d.ts +3 -3
  25. package/dist/admin/src/components/ReleaseActionModal.d.ts +24 -0
  26. package/dist/admin/src/components/ReleaseListCell.d.ts +0 -0
  27. package/dist/admin/src/components/ReleaseModal.d.ts +3 -2
  28. package/dist/admin/src/components/ReleasesPanel.d.ts +3 -0
  29. package/dist/admin/src/pages/SettingsPage.d.ts +1 -0
  30. package/dist/admin/src/services/release.d.ts +51 -313
  31. package/dist/admin/src/utils/api.d.ts +6 -0
  32. package/dist/server/index.js +824 -579
  33. package/dist/server/index.js.map +1 -1
  34. package/dist/server/index.mjs +825 -580
  35. package/dist/server/index.mjs.map +1 -1
  36. package/dist/server/src/bootstrap.d.ts +1 -1
  37. package/dist/server/src/bootstrap.d.ts.map +1 -1
  38. package/dist/server/src/constants.d.ts +11 -2
  39. package/dist/server/src/constants.d.ts.map +1 -1
  40. package/dist/server/src/content-types/index.d.ts +3 -5
  41. package/dist/server/src/content-types/index.d.ts.map +1 -1
  42. package/dist/server/src/content-types/release-action/index.d.ts +3 -5
  43. package/dist/server/src/content-types/release-action/index.d.ts.map +1 -1
  44. package/dist/server/src/content-types/release-action/schema.d.ts +3 -5
  45. package/dist/server/src/content-types/release-action/schema.d.ts.map +1 -1
  46. package/dist/server/src/controllers/index.d.ts +6 -2
  47. package/dist/server/src/controllers/index.d.ts.map +1 -1
  48. package/dist/server/src/controllers/release-action.d.ts +0 -1
  49. package/dist/server/src/controllers/release-action.d.ts.map +1 -1
  50. package/dist/server/src/controllers/release.d.ts +7 -1
  51. package/dist/server/src/controllers/release.d.ts.map +1 -1
  52. package/dist/server/src/controllers/settings.d.ts +11 -0
  53. package/dist/server/src/controllers/settings.d.ts.map +1 -0
  54. package/dist/server/src/controllers/validation/release-action.d.ts +7 -1
  55. package/dist/server/src/controllers/validation/release-action.d.ts.map +1 -1
  56. package/dist/server/src/controllers/validation/release.d.ts +1 -0
  57. package/dist/server/src/controllers/validation/release.d.ts.map +1 -1
  58. package/dist/server/src/controllers/validation/settings.d.ts +2 -0
  59. package/dist/server/src/controllers/validation/settings.d.ts.map +1 -0
  60. package/dist/server/src/destroy.d.ts +1 -1
  61. package/dist/server/src/destroy.d.ts.map +1 -1
  62. package/dist/server/src/index.d.ts +73 -57
  63. package/dist/server/src/index.d.ts.map +1 -1
  64. package/dist/server/src/middlewares/documents.d.ts +6 -0
  65. package/dist/server/src/middlewares/documents.d.ts.map +1 -0
  66. package/dist/server/src/migrations/database/5.0.0-document-id-in-actions.d.ts +9 -0
  67. package/dist/server/src/migrations/database/5.0.0-document-id-in-actions.d.ts.map +1 -0
  68. package/dist/server/src/migrations/index.d.ts.map +1 -1
  69. package/dist/server/src/register.d.ts +1 -1
  70. package/dist/server/src/register.d.ts.map +1 -1
  71. package/dist/server/src/routes/index.d.ts +16 -0
  72. package/dist/server/src/routes/index.d.ts.map +1 -1
  73. package/dist/server/src/routes/release-action.d.ts.map +1 -1
  74. package/dist/server/src/routes/release.d.ts.map +1 -1
  75. package/dist/server/src/routes/settings.d.ts +18 -0
  76. package/dist/server/src/routes/settings.d.ts.map +1 -0
  77. package/dist/server/src/services/index.d.ts +41 -41
  78. package/dist/server/src/services/index.d.ts.map +1 -1
  79. package/dist/server/src/services/release-action.d.ts +36 -0
  80. package/dist/server/src/services/release-action.d.ts.map +1 -0
  81. package/dist/server/src/services/release.d.ts +7 -42
  82. package/dist/server/src/services/release.d.ts.map +1 -1
  83. package/dist/server/src/services/scheduling.d.ts +1 -1
  84. package/dist/server/src/services/scheduling.d.ts.map +1 -1
  85. package/dist/server/src/services/settings.d.ts +13 -0
  86. package/dist/server/src/services/settings.d.ts.map +1 -0
  87. package/dist/server/src/services/validation.d.ts +2 -2
  88. package/dist/server/src/services/validation.d.ts.map +1 -1
  89. package/dist/server/src/utils/index.d.ts +33 -12
  90. package/dist/server/src/utils/index.d.ts.map +1 -1
  91. package/dist/shared/contracts/release-actions.d.ts +6 -5
  92. package/dist/shared/contracts/release-actions.d.ts.map +1 -1
  93. package/dist/shared/contracts/releases.d.ts +23 -6
  94. package/dist/shared/contracts/releases.d.ts.map +1 -1
  95. package/dist/shared/contracts/settings.d.ts +39 -0
  96. package/dist/shared/contracts/settings.d.ts.map +1 -0
  97. package/dist/shared/validation-schemas.d.ts +1 -0
  98. package/dist/shared/validation-schemas.d.ts.map +1 -1
  99. package/package.json +19 -18
  100. package/dist/_chunks/App-1LckaIGY.js.map +0 -1
  101. package/dist/_chunks/App-X01LBg5V.mjs.map +0 -1
  102. package/dist/_chunks/PurchaseContentReleases-Clm0iACO.mjs.map +0 -1
  103. package/dist/_chunks/PurchaseContentReleases-YhAPgpG9.js.map +0 -1
  104. package/dist/_chunks/en-RdapH-9X.mjs.map +0 -1
  105. package/dist/_chunks/en-faJDuv3q.js.map +0 -1
  106. package/dist/_chunks/index-OD9AlD-6.mjs.map +0 -1
  107. package/dist/_chunks/index-cYWov2wa.js.map +0 -1
  108. package/dist/admin/src/components/CMReleasesContainer.d.ts +0 -1
  109. package/dist/admin/src/services/axios.d.ts +0 -29
@@ -1,19 +1,16 @@
1
1
  "use strict";
2
2
  const icons = require("@strapi/icons");
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
- const React = require("react");
5
- const query = require("@reduxjs/toolkit/query");
6
4
  const strapiAdmin = require("@strapi/admin/strapi-admin");
5
+ const strapiAdmin$1 = require("@strapi/content-manager/strapi-admin");
7
6
  const designSystem = require("@strapi/design-system");
8
- const v2 = require("@strapi/design-system/v2");
9
- const axios = require("axios");
7
+ const symbols = require("@strapi/icons/symbols");
10
8
  const formik = require("formik");
11
9
  const reactIntl = require("react-intl");
12
10
  const reactRouterDom = require("react-router-dom");
13
11
  const yup = require("yup");
14
- const react = require("@reduxjs/toolkit/query/react");
15
- const styled = require("styled-components");
16
- const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
12
+ const styledComponents = require("styled-components");
13
+ const React = require("react");
17
14
  function _interopNamespace(e) {
18
15
  if (e && e.__esModule)
19
16
  return e;
@@ -32,9 +29,8 @@ function _interopNamespace(e) {
32
29
  n.default = e;
33
30
  return Object.freeze(n);
34
31
  }
35
- const React__namespace = /* @__PURE__ */ _interopNamespace(React);
36
32
  const yup__namespace = /* @__PURE__ */ _interopNamespace(yup);
37
- const styled__default = /* @__PURE__ */ _interopDefault(styled);
33
+ const React__namespace = /* @__PURE__ */ _interopNamespace(React);
38
34
  const __variableDynamicImportRuntimeHelper = (glob, path) => {
39
35
  const v = glob[path];
40
36
  if (v) {
@@ -116,55 +112,41 @@ const PERMISSIONS = {
116
112
  }
117
113
  ]
118
114
  };
119
- const pluginId = "content-releases";
120
- const axiosBaseQuery = async ({
121
- url,
122
- method,
123
- data,
124
- config
125
- }) => {
126
- try {
127
- const { get, post, del, put } = strapiAdmin.getFetchClient();
128
- if (method === "POST") {
129
- const result2 = await post(url, data, config);
130
- return { data: result2.data };
131
- }
132
- if (method === "DELETE") {
133
- const result2 = await del(url, config);
134
- return { data: result2.data };
135
- }
136
- if (method === "PUT") {
137
- const result2 = await put(url, data, config);
138
- return { data: result2.data };
115
+ const releaseApi = strapiAdmin.adminApi.enhanceEndpoints({
116
+ addTagTypes: ["Release", "ReleaseAction", "EntriesInRelease"],
117
+ endpoints: {
118
+ updateDocument: {
119
+ invalidatesTags: [
120
+ { type: "Release", id: "LIST" },
121
+ { type: "ReleaseAction", id: "LIST" }
122
+ ]
123
+ },
124
+ deleteDocument: {
125
+ invalidatesTags: [
126
+ { type: "Release", id: "LIST" },
127
+ { type: "ReleaseAction", id: "LIST" }
128
+ ]
129
+ },
130
+ deleteManyDocuments: {
131
+ invalidatesTags: [
132
+ { type: "Release", id: "LIST" },
133
+ { type: "ReleaseAction", id: "LIST" }
134
+ ]
135
+ },
136
+ discardDocument: {
137
+ invalidatesTags: [
138
+ { type: "Release", id: "LIST" },
139
+ { type: "ReleaseAction", id: "LIST" }
140
+ ]
139
141
  }
140
- const result = await get(url, config);
141
- return { data: result.data };
142
- } catch (error) {
143
- const err = error;
144
- return {
145
- error: {
146
- status: err.response?.status,
147
- code: err.code,
148
- response: {
149
- data: err.response?.data
150
- }
151
- }
152
- };
153
142
  }
154
- };
155
- const isAxiosError = (err) => {
156
- return typeof err === "object" && err !== null && "response" in err && typeof err.response === "object" && err.response !== null && "data" in err.response;
157
- };
158
- const releaseApi = react.createApi({
159
- reducerPath: pluginId,
160
- baseQuery: axiosBaseQuery,
161
- tagTypes: ["Release", "ReleaseAction"],
143
+ }).injectEndpoints({
162
144
  endpoints: (build) => {
163
145
  return {
164
146
  getReleasesForEntry: build.query({
165
147
  query(params) {
166
148
  return {
167
- url: "/content-releases",
149
+ url: "/content-releases/getByDocumentAttached",
168
150
  method: "GET",
169
151
  config: {
170
152
  params
@@ -273,6 +255,20 @@ const releaseApi = react.createApi({
273
255
  { type: "ReleaseAction", id: "LIST" }
274
256
  ]
275
257
  }),
258
+ createManyReleaseActions: build.mutation({
259
+ query({ body, params }) {
260
+ return {
261
+ url: `/content-releases/${params.releaseId}/actions/bulk`,
262
+ method: "POST",
263
+ data: body
264
+ };
265
+ },
266
+ invalidatesTags: [
267
+ { type: "Release", id: "LIST" },
268
+ { type: "ReleaseAction", id: "LIST" },
269
+ { type: "EntriesInRelease" }
270
+ ]
271
+ }),
276
272
  updateReleaseAction: build.mutation({
277
273
  query({ body, params }) {
278
274
  return {
@@ -282,19 +278,23 @@ const releaseApi = react.createApi({
282
278
  };
283
279
  },
284
280
  invalidatesTags: () => [{ type: "ReleaseAction", id: "LIST" }],
285
- async onQueryStarted({ body, params, query: query2, actionPath }, { dispatch, queryFulfilled }) {
281
+ async onQueryStarted({ body, params, query, actionPath }, { dispatch, queryFulfilled }) {
286
282
  const paramsWithoutActionId = {
287
283
  releaseId: params.releaseId,
288
- ...query2
284
+ ...query
289
285
  };
290
286
  const patchResult = dispatch(
291
- releaseApi.util.updateQueryData("getReleaseActions", paramsWithoutActionId, (draft) => {
292
- const [key, index] = actionPath;
293
- const action = draft.data[key][index];
294
- if (action) {
295
- action.type = body.type;
287
+ releaseApi.util.updateQueryData(
288
+ "getReleaseActions",
289
+ paramsWithoutActionId,
290
+ (draft) => {
291
+ const [key, index] = actionPath;
292
+ const action = draft.data[key][index];
293
+ if (action) {
294
+ action.type = body.type;
295
+ }
296
296
  }
297
- })
297
+ )
298
298
  );
299
299
  try {
300
300
  await queryFulfilled;
@@ -313,7 +313,8 @@ const releaseApi = react.createApi({
313
313
  invalidatesTags: (result, error, arg) => [
314
314
  { type: "Release", id: "LIST" },
315
315
  { type: "Release", id: arg.params.releaseId },
316
- { type: "ReleaseAction", id: "LIST" }
316
+ { type: "ReleaseAction", id: "LIST" },
317
+ { type: "EntriesInRelease" }
317
318
  ]
318
319
  }),
319
320
  publishRelease: build.mutation({
@@ -332,7 +333,22 @@ const releaseApi = react.createApi({
332
333
  method: "DELETE"
333
334
  };
334
335
  },
335
- invalidatesTags: () => [{ type: "Release", id: "LIST" }]
336
+ invalidatesTags: () => [{ type: "Release", id: "LIST" }, { type: "EntriesInRelease" }]
337
+ }),
338
+ getMappedEntriesInReleases: build.query({
339
+ query(params) {
340
+ return {
341
+ url: "/content-releases/mapEntriesToReleases",
342
+ method: "GET",
343
+ config: {
344
+ params
345
+ }
346
+ };
347
+ },
348
+ transformResponse(response) {
349
+ return response.data;
350
+ },
351
+ providesTags: [{ type: "EntriesInRelease" }]
336
352
  })
337
353
  };
338
354
  }
@@ -344,209 +360,25 @@ const {
344
360
  useGetReleaseActionsQuery,
345
361
  useCreateReleaseMutation,
346
362
  useCreateReleaseActionMutation,
363
+ useCreateManyReleaseActionsMutation,
347
364
  useUpdateReleaseMutation,
348
365
  useUpdateReleaseActionMutation,
349
366
  usePublishReleaseMutation,
350
367
  useDeleteReleaseActionMutation,
351
- useDeleteReleaseMutation
368
+ useDeleteReleaseMutation,
369
+ useGetMappedEntriesInReleasesQuery
352
370
  } = releaseApi;
353
- const getTimezoneOffset = (timezone, date) => {
354
- try {
355
- const offsetPart = new Intl.DateTimeFormat("en", {
356
- timeZone: timezone,
357
- timeZoneName: "longOffset"
358
- }).formatToParts(date).find((part) => part.type === "timeZoneName");
359
- const offset = offsetPart ? offsetPart.value : "";
360
- let utcOffset = offset.replace("GMT", "UTC");
361
- if (!utcOffset.includes("+") && !utcOffset.includes("-")) {
362
- utcOffset = `${utcOffset}+00:00`;
363
- }
364
- return utcOffset;
365
- } catch (error) {
366
- return "";
367
- }
368
- };
369
- const StyledMenuItem = styled__default.default(v2.Menu.Item)`
370
- &:hover {
371
- background: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}100`]};
372
-
373
- svg {
374
- path {
375
- fill: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}600`]};
376
- }
377
- }
378
-
379
- a {
380
- color: ${({ theme }) => theme.colors.neutral800};
381
- }
382
- }
383
-
384
- svg {
385
- path {
386
- fill: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}600`]};
387
- }
388
- }
389
-
390
- a {
391
- color: ${({ theme }) => theme.colors.neutral800};
392
- }
393
-
394
- span,
395
- a {
396
- width: 100%;
397
- }
398
- `;
399
- const StyledIconButton = styled__default.default(designSystem.IconButton)`
400
- /* Setting this style inline with borderColor will not apply the style */
401
- border: ${({ theme }) => `1px solid ${theme.colors.neutral200}`};
402
- `;
403
- const DeleteReleaseActionItem = ({ releaseId, actionId }) => {
404
- const { formatMessage } = reactIntl.useIntl();
405
- const { toggleNotification } = strapiAdmin.useNotification();
406
- const { formatAPIError } = strapiAdmin.useAPIErrorHandler();
407
- const [deleteReleaseAction] = useDeleteReleaseActionMutation();
408
- const {
409
- allowedActions: { canDeleteAction }
410
- } = strapiAdmin.useRBAC(PERMISSIONS);
411
- const handleDeleteAction = async () => {
412
- const response = await deleteReleaseAction({
413
- params: { releaseId, actionId }
414
- });
415
- if ("data" in response) {
416
- toggleNotification({
417
- type: "success",
418
- message: formatMessage({
419
- id: "content-releases.content-manager-edit-view.remove-from-release.notification.success",
420
- defaultMessage: "Entry removed from release"
421
- })
422
- });
423
- return;
424
- }
425
- if ("error" in response) {
426
- if (axios.isAxiosError(response.error)) {
427
- toggleNotification({
428
- type: "danger",
429
- message: formatAPIError(response.error)
430
- });
431
- } else {
432
- toggleNotification({
433
- type: "danger",
434
- message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
435
- });
436
- }
437
- }
438
- };
439
- if (!canDeleteAction) {
440
- return null;
441
- }
442
- return /* @__PURE__ */ jsxRuntime.jsx(StyledMenuItem, { variant: "danger", onSelect: handleDeleteAction, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
443
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Icon, { as: icons.Cross, width: 3, height: 3 }),
444
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger600", variant: "omega", children: formatMessage({
445
- id: "content-releases.content-manager-edit-view.remove-from-release",
446
- defaultMessage: "Remove from release"
447
- }) })
448
- ] }) });
449
- };
450
- const ReleaseActionEntryLinkItem = ({
451
- contentTypeUid,
452
- entryId,
453
- locale
454
- }) => {
455
- const { formatMessage } = reactIntl.useIntl();
456
- const userPermissions = strapiAdmin.useAuth("ReleaseActionEntryLinkItem", (state) => state.permissions);
457
- const canUpdateEntryForLocale = React__namespace.useMemo(() => {
458
- const updatePermissions = userPermissions.find(
459
- (permission) => permission.subject === contentTypeUid && permission.action === "plugin::content-manager.explorer.update"
460
- );
461
- if (!updatePermissions) {
462
- return false;
463
- }
464
- return Boolean(!locale || updatePermissions.properties?.locales?.includes(locale));
465
- }, [contentTypeUid, locale, userPermissions]);
466
- const {
467
- allowedActions: { canUpdateContentType }
468
- } = strapiAdmin.useRBAC({
469
- updateContentType: [
470
- {
471
- action: "plugin::content-manager.explorer.update",
472
- subject: contentTypeUid
473
- }
474
- ]
475
- });
476
- if (!canUpdateContentType || !canUpdateEntryForLocale) {
477
- return null;
478
- }
479
- return /* @__PURE__ */ jsxRuntime.jsx(StyledMenuItem, { children: /* @__PURE__ */ jsxRuntime.jsx(
480
- v2.Link,
481
- {
482
- as: reactRouterDom.NavLink,
483
- to: {
484
- pathname: `/content-manager/collection-types/${contentTypeUid}/${entryId}`,
485
- search: locale && `?plugins[i18n][locale]=${locale}`
486
- },
487
- startIcon: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Icon, { as: icons.Pencil, width: 3, height: 3 }),
488
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: formatMessage({
489
- id: "content-releases.content-manager-edit-view.edit-entry",
490
- defaultMessage: "Edit entry"
491
- }) })
492
- }
493
- ) });
494
- };
495
- const EditReleaseItem = ({ releaseId }) => {
496
- const { formatMessage } = reactIntl.useIntl();
497
- return /* @__PURE__ */ jsxRuntime.jsx(StyledMenuItem, { children: /* @__PURE__ */ jsxRuntime.jsx(
498
- v2.Link,
499
- {
500
- href: `/admin/plugins/content-releases/${releaseId}`,
501
- startIcon: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Icon, { as: icons.Pencil, width: 3, height: 3 }),
502
- isExternal: false,
503
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: formatMessage({
504
- id: "content-releases.content-manager-edit-view.edit-release",
505
- defaultMessage: "Edit release"
506
- }) })
507
- }
508
- ) });
509
- };
510
- const Root = ({ children, hasTriggerBorder = false }) => {
511
- const { formatMessage } = reactIntl.useIntl();
512
- const { allowedActions } = strapiAdmin.useRBAC(PERMISSIONS);
513
- return (
514
- // A user can access the dropdown if they have permissions to delete a release-action OR update a release
515
- allowedActions.canDeleteAction || allowedActions.canUpdate ? /* @__PURE__ */ jsxRuntime.jsxs(v2.Menu.Root, { children: [
516
- /* @__PURE__ */ jsxRuntime.jsx(
517
- v2.Menu.Trigger,
518
- {
519
- as: hasTriggerBorder ? StyledIconButton : designSystem.IconButton,
520
- paddingLeft: 2,
521
- paddingRight: 2,
522
- "aria-label": formatMessage({
523
- id: "content-releases.content-manager-edit-view.release-action-menu",
524
- defaultMessage: "Release action options"
525
- }),
526
- icon: /* @__PURE__ */ jsxRuntime.jsx(icons.More, {})
527
- }
528
- ),
529
- /* @__PURE__ */ jsxRuntime.jsx(v2.Menu.Content, { top: 1, popoverPlacement: "bottom-end", children })
530
- ] }) : null
531
- );
532
- };
533
- const ReleaseActionMenu = {
534
- Root,
535
- EditReleaseItem,
536
- DeleteReleaseActionItem,
537
- ReleaseActionEntryLinkItem
538
- };
539
371
  const getBorderLeftRadiusValue = (actionType) => {
540
372
  return actionType === "publish" ? 1 : 0;
541
373
  };
542
374
  const getBorderRightRadiusValue = (actionType) => {
543
375
  return actionType === "publish" ? 0 : 1;
544
376
  };
545
- const FieldWrapper = styled__default.default(designSystem.Field)`
546
- border-top-left-radius: ${({ actionType, theme }) => theme.spaces[getBorderLeftRadiusValue(actionType)]};
547
- border-bottom-left-radius: ${({ actionType, theme }) => theme.spaces[getBorderLeftRadiusValue(actionType)]};
548
- border-top-right-radius: ${({ actionType, theme }) => theme.spaces[getBorderRightRadiusValue(actionType)]};
549
- border-bottom-right-radius: ${({ actionType, theme }) => theme.spaces[getBorderRightRadiusValue(actionType)]};
377
+ const FieldWrapper = styledComponents.styled(designSystem.Field.Root)`
378
+ border-top-left-radius: ${({ $actionType, theme }) => theme.spaces[getBorderLeftRadiusValue($actionType)]};
379
+ border-bottom-left-radius: ${({ $actionType, theme }) => theme.spaces[getBorderLeftRadiusValue($actionType)]};
380
+ border-top-right-radius: ${({ $actionType, theme }) => theme.spaces[getBorderRightRadiusValue($actionType)]};
381
+ border-bottom-right-radius: ${({ $actionType, theme }) => theme.spaces[getBorderRightRadiusValue($actionType)]};
550
382
 
551
383
  > label {
552
384
  color: inherit;
@@ -557,14 +389,14 @@ const FieldWrapper = styled__default.default(designSystem.Field)`
557
389
  }
558
390
 
559
391
  &[data-checked='true'] {
560
- color: ${({ theme, actionType }) => actionType === "publish" ? theme.colors.primary700 : theme.colors.danger600};
561
- background-color: ${({ theme, actionType }) => actionType === "publish" ? theme.colors.primary100 : theme.colors.danger100};
562
- border-color: ${({ theme, actionType }) => actionType === "publish" ? theme.colors.primary700 : theme.colors.danger600};
392
+ color: ${({ theme, $actionType }) => $actionType === "publish" ? theme.colors.primary700 : theme.colors.danger600};
393
+ background-color: ${({ theme, $actionType }) => $actionType === "publish" ? theme.colors.primary100 : theme.colors.danger100};
394
+ border-color: ${({ theme, $actionType }) => $actionType === "publish" ? theme.colors.primary700 : theme.colors.danger600};
563
395
  }
564
396
 
565
397
  &[data-checked='false'] {
566
- border-left: ${({ actionType }) => actionType === "unpublish" && "none"};
567
- border-right: ${({ actionType }) => actionType === "publish" && "none"};
398
+ border-left: ${({ $actionType }) => $actionType === "unpublish" && "none"};
399
+ border-right: ${({ $actionType }) => $actionType === "publish" && "none"};
568
400
  }
569
401
 
570
402
  &[data-checked='false'][data-disabled='false']:hover {
@@ -593,7 +425,7 @@ const ActionOption = ({
593
425
  return /* @__PURE__ */ jsxRuntime.jsx(
594
426
  FieldWrapper,
595
427
  {
596
- actionType,
428
+ $actionType: actionType,
597
429
  background: "primary0",
598
430
  borderColor: "neutral200",
599
431
  color: selected === actionType ? "primary600" : "neutral600",
@@ -601,12 +433,11 @@ const ActionOption = ({
601
433
  cursor: "pointer",
602
434
  "data-checked": selected === actionType,
603
435
  "data-disabled": disabled && selected !== actionType,
604
- children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.FieldLabel, { htmlFor: `${name}-${actionType}`, children: [
436
+ children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Label, { children: [
605
437
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { children: /* @__PURE__ */ jsxRuntime.jsx(
606
- designSystem.FieldInput,
438
+ designSystem.Field.Input,
607
439
  {
608
440
  type: "radio",
609
- id: `${name}-${actionType}`,
610
441
  name,
611
442
  checked: selected === actionType,
612
443
  onChange: handleChange,
@@ -661,72 +492,270 @@ const NoReleases = () => {
661
492
  return /* @__PURE__ */ jsxRuntime.jsx(
662
493
  designSystem.EmptyStateLayout,
663
494
  {
664
- icon: /* @__PURE__ */ jsxRuntime.jsx(icons.EmptyDocuments, { width: "10rem" }),
495
+ icon: /* @__PURE__ */ jsxRuntime.jsx(symbols.EmptyDocuments, { width: "16rem" }),
665
496
  content: formatMessage({
666
497
  id: "content-releases.content-manager-edit-view.add-to-release.no-releases-message",
667
498
  defaultMessage: "No available releases. Open the list of releases and create a new one from there."
668
499
  }),
669
500
  action: /* @__PURE__ */ jsxRuntime.jsx(
670
- v2.LinkButton,
501
+ designSystem.LinkButton,
671
502
  {
672
503
  to: {
673
504
  pathname: "/plugins/content-releases"
674
505
  },
675
- as: reactRouterDom.Link,
506
+ tag: reactRouterDom.Link,
676
507
  variant: "secondary",
677
508
  children: formatMessage({
678
509
  id: "content-releases.content-manager-edit-view.add-to-release.redirect-button",
679
510
  defaultMessage: "Open the list of releases"
680
511
  })
681
512
  }
682
- )
513
+ ),
514
+ shadow: "none"
683
515
  }
684
516
  );
685
517
  };
686
518
  const AddActionToReleaseModal = ({
687
- handleClose,
688
- contentTypeUid,
689
- entryId
519
+ contentType,
520
+ documentId,
521
+ onInputChange,
522
+ values
690
523
  }) => {
691
- const releaseHeaderId = React__namespace.useId();
692
524
  const { formatMessage } = reactIntl.useIntl();
693
- const { toggleNotification } = strapiAdmin.useNotification();
694
- const { formatAPIError } = strapiAdmin.useAPIErrorHandler();
695
- const [{ query: query2 }] = strapiAdmin.useQueryParams();
696
- const locale = query2.plugins?.i18n?.locale;
525
+ const [{ query }] = strapiAdmin.useQueryParams();
526
+ const locale = query.plugins?.i18n?.locale;
697
527
  const response = useGetReleasesForEntryQuery({
698
- contentTypeUid,
699
- entryId,
700
- hasEntryAttached: false
528
+ contentType,
529
+ entryDocumentId: documentId,
530
+ hasEntryAttached: false,
531
+ locale
701
532
  });
702
533
  const releases = response.data?.data;
534
+ if (releases?.length === 0) {
535
+ return /* @__PURE__ */ jsxRuntime.jsx(NoReleases, {});
536
+ }
537
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
538
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingBottom: 6, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { required: true, children: [
539
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
540
+ id: "content-releases.content-manager-edit-view.add-to-release.select-label",
541
+ defaultMessage: "Select a release"
542
+ }) }),
543
+ /* @__PURE__ */ jsxRuntime.jsx(
544
+ designSystem.SingleSelect,
545
+ {
546
+ required: true,
547
+ placeholder: formatMessage({
548
+ id: "content-releases.content-manager-edit-view.add-to-release.select-placeholder",
549
+ defaultMessage: "Select"
550
+ }),
551
+ name: "releaseId",
552
+ onChange: (value) => onInputChange("releaseId", value),
553
+ value: values.releaseId,
554
+ children: releases?.map((release) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: release.id, children: release.name }, release.id))
555
+ }
556
+ )
557
+ ] }) }),
558
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
559
+ id: "content-releases.content-manager-edit-view.add-to-release.action-type-label",
560
+ defaultMessage: "What do you want to do with this entry?"
561
+ }) }),
562
+ /* @__PURE__ */ jsxRuntime.jsx(
563
+ ReleaseActionOptions,
564
+ {
565
+ selected: values.type,
566
+ handleChange: (e) => onInputChange("type", e.target.value),
567
+ name: "type"
568
+ }
569
+ )
570
+ ] });
571
+ };
572
+ const ReleaseActionModalForm = ({
573
+ documentId,
574
+ model,
575
+ collectionType
576
+ }) => {
577
+ const { formatMessage } = reactIntl.useIntl();
578
+ const { allowedActions } = strapiAdmin.useRBAC(PERMISSIONS);
579
+ const { canCreateAction } = allowedActions;
703
580
  const [createReleaseAction, { isLoading }] = useCreateReleaseActionMutation();
704
- const handleSubmit = async (values) => {
705
- const releaseActionEntry = {
706
- contentType: contentTypeUid,
707
- id: entryId,
708
- locale
709
- };
710
- const response2 = await createReleaseAction({
711
- body: { type: values.type, entry: releaseActionEntry },
712
- params: { releaseId: values.releaseId }
581
+ const { toggleNotification } = strapiAdmin.useNotification();
582
+ const { formatAPIError } = strapiAdmin.useAPIErrorHandler();
583
+ const [{ query }] = strapiAdmin.useQueryParams();
584
+ const locale = query.plugins?.i18n?.locale;
585
+ const handleSubmit = async (e, onClose) => {
586
+ try {
587
+ await formik$1.handleSubmit(e);
588
+ onClose();
589
+ } catch (error) {
590
+ if (strapiAdmin.isFetchError(error)) {
591
+ toggleNotification({
592
+ type: "danger",
593
+ message: formatAPIError(error)
594
+ });
595
+ } else {
596
+ toggleNotification({
597
+ type: "danger",
598
+ message: formatMessage({
599
+ id: "notification.error",
600
+ defaultMessage: "An error occurred"
601
+ })
602
+ });
603
+ }
604
+ }
605
+ };
606
+ const formik$1 = formik.useFormik({
607
+ initialValues: INITIAL_VALUES,
608
+ validationSchema: RELEASE_ACTION_FORM_SCHEMA,
609
+ onSubmit: async (values) => {
610
+ if (collectionType === "collection-types" && !documentId) {
611
+ throw new Error("Document id is required");
612
+ }
613
+ const response = await createReleaseAction({
614
+ body: {
615
+ type: values.type,
616
+ contentType: model,
617
+ entryDocumentId: documentId,
618
+ locale
619
+ },
620
+ params: { releaseId: values.releaseId }
621
+ });
622
+ if ("data" in response) {
623
+ toggleNotification({
624
+ type: "success",
625
+ message: formatMessage({
626
+ id: "content-releases.content-manager-edit-view.add-to-release.notification.success",
627
+ defaultMessage: "Entry added to release"
628
+ })
629
+ });
630
+ return;
631
+ }
632
+ if ("error" in response) {
633
+ throw response.error;
634
+ }
635
+ }
636
+ });
637
+ const {
638
+ edit: { options }
639
+ } = strapiAdmin$1.unstable_useDocumentLayout(model);
640
+ if (!window.strapi.isEE || !options?.draftAndPublish || !canCreateAction) {
641
+ return null;
642
+ }
643
+ if (collectionType === "collection-types" && (!documentId || documentId === "create")) {
644
+ return null;
645
+ }
646
+ return {
647
+ label: formatMessage({
648
+ id: "content-releases.content-manager-edit-view.add-to-release",
649
+ defaultMessage: "Add to release"
650
+ }),
651
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Cursor, {}),
652
+ position: ["panel", "table-row"],
653
+ dialog: {
654
+ type: "modal",
655
+ title: formatMessage({
656
+ id: "content-releases.content-manager-edit-view.add-to-release",
657
+ defaultMessage: "Add to release"
658
+ }),
659
+ content: /* @__PURE__ */ jsxRuntime.jsx(
660
+ AddActionToReleaseModal,
661
+ {
662
+ contentType: model,
663
+ documentId,
664
+ onInputChange: formik$1.setFieldValue,
665
+ values: formik$1.values
666
+ }
667
+ ),
668
+ footer: ({ onClose }) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
669
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: onClose, variant: "tertiary", name: "cancel", children: formatMessage({
670
+ id: "content-releases.content-manager-edit-view.add-to-release.cancel-button",
671
+ defaultMessage: "Cancel"
672
+ }) }),
673
+ /* @__PURE__ */ jsxRuntime.jsx(
674
+ designSystem.Button,
675
+ {
676
+ type: "submit",
677
+ onClick: (e) => handleSubmit(e, onClose),
678
+ disabled: !formik$1.values.releaseId,
679
+ loading: isLoading,
680
+ children: formatMessage({
681
+ id: "content-releases.content-manager-edit-view.add-to-release.continue-button",
682
+ defaultMessage: "Continue"
683
+ })
684
+ }
685
+ )
686
+ ] })
687
+ }
688
+ };
689
+ };
690
+ const getTimezoneOffset = (timezone, date) => {
691
+ try {
692
+ const offsetPart = new Intl.DateTimeFormat("en", {
693
+ timeZone: timezone,
694
+ timeZoneName: "longOffset"
695
+ }).formatToParts(date).find((part) => part.type === "timeZoneName");
696
+ const offset = offsetPart ? offsetPart.value : "";
697
+ let utcOffset = offset.replace("GMT", "UTC");
698
+ if (!utcOffset.includes("+") && !utcOffset.includes("-")) {
699
+ utcOffset = `${utcOffset}+00:00`;
700
+ }
701
+ return utcOffset;
702
+ } catch (error) {
703
+ return "";
704
+ }
705
+ };
706
+ const StyledMenuItem = styledComponents.styled(designSystem.Menu.Item)`
707
+ &:hover {
708
+ background: ${({ theme, $variant = "neutral" }) => theme.colors[`${$variant}100`]};
709
+
710
+ svg {
711
+ fill: ${({ theme, $variant = "neutral" }) => theme.colors[`${$variant}600`]};
712
+ }
713
+
714
+ a {
715
+ color: ${({ theme }) => theme.colors.neutral800};
716
+ }
717
+ }
718
+
719
+ svg {
720
+ color: ${({ theme, $variant = "neutral" }) => theme.colors[`${$variant}500`]};
721
+ }
722
+
723
+ span {
724
+ color: ${({ theme, $variant = "neutral" }) => theme.colors[`${$variant}800`]};
725
+ }
726
+
727
+ span,
728
+ a {
729
+ width: 100%;
730
+ }
731
+ `;
732
+ const DeleteReleaseActionItem = ({ releaseId, actionId }) => {
733
+ const { formatMessage } = reactIntl.useIntl();
734
+ const { toggleNotification } = strapiAdmin.useNotification();
735
+ const { formatAPIError } = strapiAdmin.useAPIErrorHandler();
736
+ const [deleteReleaseAction] = useDeleteReleaseActionMutation();
737
+ const {
738
+ allowedActions: { canDeleteAction }
739
+ } = strapiAdmin.useRBAC(PERMISSIONS);
740
+ const handleDeleteAction = async () => {
741
+ const response = await deleteReleaseAction({
742
+ params: { releaseId, actionId }
713
743
  });
714
- if ("data" in response2) {
744
+ if ("data" in response) {
715
745
  toggleNotification({
716
746
  type: "success",
717
747
  message: formatMessage({
718
- id: "content-releases.content-manager-edit-view.add-to-release.notification.success",
719
- defaultMessage: "Entry added to release"
748
+ id: "content-releases.content-manager-edit-view.remove-from-release.notification.success",
749
+ defaultMessage: "Entry removed from release"
720
750
  })
721
751
  });
722
- handleClose();
723
752
  return;
724
753
  }
725
- if ("error" in response2) {
726
- if (axios.isAxiosError(response2.error)) {
754
+ if ("error" in response) {
755
+ if (strapiAdmin.isFetchError(response.error)) {
727
756
  toggleNotification({
728
757
  type: "danger",
729
- message: formatAPIError(response2.error)
758
+ message: formatAPIError(response.error)
730
759
  });
731
760
  } else {
732
761
  toggleNotification({
@@ -736,239 +765,216 @@ const AddActionToReleaseModal = ({
736
765
  }
737
766
  }
738
767
  };
739
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.ModalLayout, { onClose: handleClose, labelledBy: releaseHeaderId, children: [
740
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.ModalHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: releaseHeaderId, fontWeight: "bold", textColor: "neutral800", children: formatMessage({
741
- id: "content-releases.content-manager-edit-view.add-to-release",
742
- defaultMessage: "Add to release"
743
- }) }) }),
744
- /* @__PURE__ */ jsxRuntime.jsx(
745
- formik.Formik,
768
+ if (!canDeleteAction) {
769
+ return null;
770
+ }
771
+ return /* @__PURE__ */ jsxRuntime.jsx(StyledMenuItem, { $variant: "danger", onSelect: handleDeleteAction, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
772
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Cross, { width: "1.6rem", height: "1.6rem" }),
773
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger600", variant: "omega", children: formatMessage({
774
+ id: "content-releases.content-manager-edit-view.remove-from-release",
775
+ defaultMessage: "Remove from release"
776
+ }) })
777
+ ] }) });
778
+ };
779
+ const ReleaseActionEntryLinkItem = ({
780
+ contentTypeUid,
781
+ documentId,
782
+ locale
783
+ }) => {
784
+ const { formatMessage } = reactIntl.useIntl();
785
+ const userPermissions = strapiAdmin.useAuth("ReleaseActionEntryLinkItem", (state) => state.permissions);
786
+ const canUpdateEntryForLocale = React__namespace.useMemo(() => {
787
+ const updatePermissions = userPermissions.find(
788
+ (permission) => permission.subject === contentTypeUid && permission.action === "plugin::content-manager.explorer.update"
789
+ );
790
+ if (!updatePermissions) {
791
+ return false;
792
+ }
793
+ return Boolean(!locale || updatePermissions.properties?.locales?.includes(locale));
794
+ }, [contentTypeUid, locale, userPermissions]);
795
+ const {
796
+ allowedActions: { canUpdate: canUpdateContentType }
797
+ } = strapiAdmin.useRBAC({
798
+ updateContentType: [
746
799
  {
747
- onSubmit: handleSubmit,
748
- validationSchema: RELEASE_ACTION_FORM_SCHEMA,
749
- initialValues: INITIAL_VALUES,
750
- children: ({ values, setFieldValue }) => {
751
- return /* @__PURE__ */ jsxRuntime.jsxs(formik.Form, { children: [
752
- 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: [
753
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingBottom: 6, children: /* @__PURE__ */ jsxRuntime.jsx(
754
- designSystem.SingleSelect,
755
- {
756
- required: true,
757
- label: formatMessage({
758
- id: "content-releases.content-manager-edit-view.add-to-release.select-label",
759
- defaultMessage: "Select a release"
760
- }),
761
- placeholder: formatMessage({
762
- id: "content-releases.content-manager-edit-view.add-to-release.select-placeholder",
763
- defaultMessage: "Select"
764
- }),
765
- onChange: (value) => setFieldValue("releaseId", value),
766
- value: values.releaseId,
767
- children: releases?.map((release) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: release.id, children: release.name }, release.id))
768
- }
769
- ) }),
770
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.FieldLabel, { children: formatMessage({
771
- id: "content-releases.content-manager-edit-view.add-to-release.action-type-label",
772
- defaultMessage: "What do you want to do with this entry?"
773
- }) }),
774
- /* @__PURE__ */ jsxRuntime.jsx(
775
- ReleaseActionOptions,
776
- {
777
- selected: values.type,
778
- handleChange: (e) => setFieldValue("type", e.target.value),
779
- name: "type"
780
- }
781
- )
782
- ] }) }),
783
- /* @__PURE__ */ jsxRuntime.jsx(
784
- designSystem.ModalFooter,
785
- {
786
- startActions: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleClose, variant: "tertiary", name: "cancel", children: formatMessage({
787
- id: "content-releases.content-manager-edit-view.add-to-release.cancel-button",
788
- defaultMessage: "Cancel"
789
- }) }),
790
- endActions: (
791
- /**
792
- * TODO: Ideally we would use isValid from Formik to disable the button, however currently it always returns true
793
- * for yup.string().required(), even when the value is falsy (including empty string)
794
- */
795
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { type: "submit", disabled: !values.releaseId, loading: isLoading, children: formatMessage({
796
- id: "content-releases.content-manager-edit-view.add-to-release.continue-button",
797
- defaultMessage: "Continue"
798
- }) })
799
- )
800
- }
801
- )
802
- ] });
803
- }
800
+ action: "plugin::content-manager.explorer.update",
801
+ subject: contentTypeUid
804
802
  }
805
- )
806
- ] });
803
+ ]
804
+ });
805
+ if (!canUpdateContentType || !canUpdateEntryForLocale) {
806
+ return null;
807
+ }
808
+ return /* @__PURE__ */ jsxRuntime.jsx(
809
+ StyledMenuItem,
810
+ {
811
+ tag: reactRouterDom.NavLink,
812
+ isLink: true,
813
+ to: {
814
+ pathname: `/content-manager/collection-types/${contentTypeUid}/${documentId}`,
815
+ search: locale && `?plugins[i18n][locale]=${locale}`
816
+ },
817
+ children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
818
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Pencil, { width: "1.6rem", height: "1.6rem" }),
819
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: formatMessage({
820
+ id: "content-releases.content-manager-edit-view.edit-entry",
821
+ defaultMessage: "Edit entry"
822
+ }) })
823
+ ] })
824
+ }
825
+ );
807
826
  };
808
- const CMReleasesContainer = () => {
809
- const [isModalOpen, setIsModalOpen] = React__namespace.useState(false);
810
- const { formatMessage, formatDate, formatTime } = reactIntl.useIntl();
811
- const { id, slug, collectionType } = reactRouterDom.useParams();
812
- const isCreatingEntry = id === "create";
827
+ const EditReleaseItem = ({ releaseId }) => {
828
+ const { formatMessage } = reactIntl.useIntl();
829
+ return (
830
+ /* @ts-expect-error inference isn't working in DS */
831
+ /* @__PURE__ */ jsxRuntime.jsx(StyledMenuItem, { tag: reactRouterDom.NavLink, isLink: true, to: `/plugins/content-releases/${releaseId}`, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
832
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Pencil, { width: "1.6rem", height: "1.6rem" }),
833
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", variant: "omega", children: formatMessage({
834
+ id: "content-releases.content-manager-edit-view.edit-release",
835
+ defaultMessage: "Edit release"
836
+ }) })
837
+ ] }) })
838
+ );
839
+ };
840
+ const Root = ({ children }) => {
841
+ const { formatMessage } = reactIntl.useIntl();
842
+ const { allowedActions } = strapiAdmin.useRBAC(PERMISSIONS);
843
+ return (
844
+ // A user can access the dropdown if they have permissions to delete a release-action OR update a release
845
+ allowedActions.canDeleteAction || allowedActions.canUpdate ? /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Root, { children: [
846
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Menu.Trigger, { variant: "tertiary", endIcon: null, paddingLeft: 2, paddingRight: 2, children: /* @__PURE__ */ jsxRuntime.jsx(
847
+ designSystem.AccessibleIcon,
848
+ {
849
+ label: formatMessage({
850
+ id: "content-releases.content-manager-edit-view.release-action-menu",
851
+ defaultMessage: "Release action options"
852
+ }),
853
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.More, {})
854
+ }
855
+ ) }),
856
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Menu.Content, { top: 1, popoverPlacement: "bottom-end", children })
857
+ ] }) : null
858
+ );
859
+ };
860
+ const ReleaseActionMenu = {
861
+ Root,
862
+ EditReleaseItem,
863
+ DeleteReleaseActionItem,
864
+ ReleaseActionEntryLinkItem
865
+ };
866
+ const Panel = ({ model, documentId, collectionType }) => {
867
+ const [{ query }] = strapiAdmin.useQueryParams();
868
+ const locale = query.plugins?.i18n?.locale;
813
869
  const {
814
- allowedActions: { canCreateAction, canMain, canDeleteAction }
815
- } = strapiAdmin.useRBAC(PERMISSIONS);
816
- const { schema } = strapiAdmin.unstable_useDocument({
817
- collectionType,
818
- model: slug
819
- });
820
- const hasDraftAndPublish = schema?.options?.draftAndPublish;
821
- const contentTypeUid = slug;
822
- const canFetch = id != null && contentTypeUid != null;
823
- const fetchParams = canFetch ? {
824
- contentTypeUid,
825
- entryId: id,
870
+ edit: { options }
871
+ } = strapiAdmin$1.unstable_useDocumentLayout(model);
872
+ const { formatMessage, formatDate, formatTime } = reactIntl.useIntl();
873
+ const { allowedActions } = strapiAdmin.useRBAC(PERMISSIONS);
874
+ const { canRead, canDeleteAction } = allowedActions;
875
+ const response = useGetReleasesForEntryQuery({
876
+ contentType: model,
877
+ entryDocumentId: documentId,
878
+ locale,
826
879
  hasEntryAttached: true
827
- } : query.skipToken;
828
- const response = useGetReleasesForEntryQuery(fetchParams);
880
+ });
829
881
  const releases = response.data?.data;
830
- if (!canFetch) {
831
- return null;
832
- }
833
- if (isCreatingEntry || !hasDraftAndPublish) {
834
- return null;
835
- }
836
- const toggleModal = () => setIsModalOpen((prev) => !prev);
837
882
  const getReleaseColorVariant = (actionType, shade) => {
838
883
  if (actionType === "unpublish") {
839
884
  return `secondary${shade}`;
840
885
  }
841
886
  return `success${shade}`;
842
887
  };
843
- if (!canMain) {
888
+ if (!window.strapi.isEE || !options?.draftAndPublish || !canRead) {
844
889
  return null;
845
890
  }
846
- return /* @__PURE__ */ jsxRuntime.jsxs(
847
- designSystem.Box,
848
- {
849
- as: "aside",
850
- "aria-label": formatMessage({
851
- id: "content-releases.plugin.name",
852
- defaultMessage: "Releases"
853
- }),
854
- background: "neutral0",
855
- borderColor: "neutral150",
856
- hasRadius: true,
857
- padding: 4,
858
- shadow: "tableShadow",
859
- children: [
860
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 3, children: [
861
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", children: formatMessage({
862
- id: "content-releases.plugin.name",
863
- defaultMessage: "Releases"
864
- }) }),
865
- releases?.map((release) => {
866
- return /* @__PURE__ */ jsxRuntime.jsxs(
867
- designSystem.Flex,
868
- {
869
- direction: "column",
870
- alignItems: "start",
871
- borderWidth: "1px",
872
- borderStyle: "solid",
873
- borderColor: getReleaseColorVariant(release.action.type, "200"),
874
- overflow: "hidden",
875
- hasRadius: true,
876
- children: [
877
- /* @__PURE__ */ jsxRuntime.jsx(
878
- designSystem.Box,
879
- {
880
- paddingTop: 3,
881
- paddingBottom: 3,
882
- paddingLeft: 4,
883
- paddingRight: 4,
884
- background: getReleaseColorVariant(release.action.type, "100"),
885
- width: "100%",
886
- children: /* @__PURE__ */ jsxRuntime.jsx(
887
- designSystem.Typography,
888
- {
889
- fontSize: 1,
890
- variant: "pi",
891
- textColor: getReleaseColorVariant(release.action.type, "600"),
892
- children: formatMessage(
893
- {
894
- id: "content-releases.content-manager-edit-view.list-releases.title",
895
- defaultMessage: "{isPublish, select, true {Will be published in} other {Will be unpublished in}}"
896
- },
897
- { isPublish: release.action.type === "publish" }
898
- )
899
- }
900
- )
901
- }
902
- ),
903
- /* @__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: [
904
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontSize: 2, fontWeight: "bold", variant: "omega", textColor: "neutral700", children: release.name }),
905
- release.scheduledAt && release.timezone && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: formatMessage(
906
- {
907
- id: "content-releases.content-manager-edit-view.scheduled.date",
908
- defaultMessage: "{date} at {time} ({offset})"
909
- },
910
- {
911
- date: formatDate(new Date(release.scheduledAt), {
912
- day: "2-digit",
913
- month: "2-digit",
914
- year: "numeric",
915
- timeZone: release.timezone
916
- }),
917
- time: formatTime(new Date(release.scheduledAt), {
918
- hourCycle: "h23",
919
- timeZone: release.timezone
920
- }),
921
- offset: getTimezoneOffset(
922
- release.timezone,
923
- new Date(release.scheduledAt)
924
- )
925
- }
926
- ) }),
927
- canDeleteAction ? /* @__PURE__ */ jsxRuntime.jsxs(ReleaseActionMenu.Root, { hasTriggerBorder: true, children: [
928
- /* @__PURE__ */ jsxRuntime.jsx(ReleaseActionMenu.EditReleaseItem, { releaseId: release.id }),
929
- /* @__PURE__ */ jsxRuntime.jsx(
930
- ReleaseActionMenu.DeleteReleaseActionItem,
931
- {
932
- releaseId: release.id,
933
- actionId: release.action.id
934
- }
935
- )
936
- ] }) : null
937
- ] }) })
938
- ]
939
- },
940
- release.id
941
- );
942
- }),
943
- canCreateAction ? /* @__PURE__ */ jsxRuntime.jsx(
944
- designSystem.Button,
891
+ if (collectionType === "collection-types" && (!documentId || documentId === "create")) {
892
+ return null;
893
+ }
894
+ if (releases && releases.length === 0) {
895
+ return null;
896
+ }
897
+ return {
898
+ title: formatMessage({
899
+ id: "content-releases.plugin.name",
900
+ defaultMessage: "Releases"
901
+ }),
902
+ content: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 3, width: "100%", children: releases?.map((release) => /* @__PURE__ */ jsxRuntime.jsxs(
903
+ designSystem.Flex,
904
+ {
905
+ direction: "column",
906
+ alignItems: "start",
907
+ borderWidth: "1px",
908
+ borderStyle: "solid",
909
+ borderColor: getReleaseColorVariant(release.actions[0].type, "200"),
910
+ overflow: "hidden",
911
+ hasRadius: true,
912
+ children: [
913
+ /* @__PURE__ */ jsxRuntime.jsx(
914
+ designSystem.Box,
945
915
  {
946
- justifyContent: "center",
916
+ paddingTop: 3,
917
+ paddingBottom: 3,
947
918
  paddingLeft: 4,
948
919
  paddingRight: 4,
949
- color: "neutral700",
950
- variant: "tertiary",
951
- startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
952
- onClick: toggleModal,
953
- children: formatMessage({
954
- id: "content-releases.content-manager-edit-view.add-to-release",
955
- defaultMessage: "Add to release"
956
- })
920
+ background: getReleaseColorVariant(release.actions[0].type, "100"),
921
+ width: "100%",
922
+ children: /* @__PURE__ */ jsxRuntime.jsx(
923
+ designSystem.Typography,
924
+ {
925
+ fontSize: 1,
926
+ variant: "pi",
927
+ textColor: getReleaseColorVariant(release.actions[0].type, "600"),
928
+ children: formatMessage(
929
+ {
930
+ id: "content-releases.content-manager-edit-view.list-releases.title",
931
+ defaultMessage: "{isPublish, select, true {Will be published in} other {Will be unpublished in}}"
932
+ },
933
+ { isPublish: release.actions[0].type === "publish" }
934
+ )
935
+ }
936
+ )
957
937
  }
958
- ) : null
959
- ] }),
960
- isModalOpen && /* @__PURE__ */ jsxRuntime.jsx(
961
- AddActionToReleaseModal,
962
- {
963
- handleClose: toggleModal,
964
- contentTypeUid,
965
- entryId: id
966
- }
967
- )
968
- ]
969
- }
970
- );
938
+ ),
939
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { padding: 4, direction: "column", gap: 2, width: "100%", alignItems: "flex-start", children: [
940
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontSize: 2, fontWeight: "bold", variant: "omega", textColor: "neutral700", children: release.name }),
941
+ release.scheduledAt && release.timezone && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: formatMessage(
942
+ {
943
+ id: "content-releases.content-manager-edit-view.scheduled.date",
944
+ defaultMessage: "{date} at {time} ({offset})"
945
+ },
946
+ {
947
+ date: formatDate(new Date(release.scheduledAt), {
948
+ day: "2-digit",
949
+ month: "2-digit",
950
+ year: "numeric",
951
+ timeZone: release.timezone
952
+ }),
953
+ time: formatTime(new Date(release.scheduledAt), {
954
+ hourCycle: "h23",
955
+ timeZone: release.timezone
956
+ }),
957
+ offset: getTimezoneOffset(release.timezone, new Date(release.scheduledAt))
958
+ }
959
+ ) }),
960
+ canDeleteAction ? /* @__PURE__ */ jsxRuntime.jsxs(ReleaseActionMenu.Root, { hasTriggerBorder: true, children: [
961
+ /* @__PURE__ */ jsxRuntime.jsx(ReleaseActionMenu.EditReleaseItem, { releaseId: release.id }),
962
+ /* @__PURE__ */ jsxRuntime.jsx(
963
+ ReleaseActionMenu.DeleteReleaseActionItem,
964
+ {
965
+ releaseId: release.id,
966
+ actionId: release.actions[0].id
967
+ }
968
+ )
969
+ ] }) : null
970
+ ] })
971
+ ]
972
+ },
973
+ release.id
974
+ )) })
975
+ };
971
976
  };
977
+ const pluginId = "content-releases";
972
978
  const prefixPluginTranslations = (trad, pluginId2) => {
973
979
  if (!pluginId2) {
974
980
  throw new TypeError("pluginId can't be empty");
@@ -981,6 +987,7 @@ const prefixPluginTranslations = (trad, pluginId2) => {
981
987
  const admin = {
982
988
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
983
989
  register(app) {
990
+ app.createHook("ContentReleases/pages/ReleaseDetails/add-locale-in-releases");
984
991
  if (window.strapi.features.isEnabled("cms-content-releases")) {
985
992
  app.addMenuLink({
986
993
  to: `plugins/${pluginId}`,
@@ -989,37 +996,55 @@ const admin = {
989
996
  id: `${pluginId}.plugin.name`,
990
997
  defaultMessage: "Releases"
991
998
  },
992
- Component: () => Promise.resolve().then(() => require("./App-1LckaIGY.js")).then((mod) => ({ default: mod.App })),
993
- permissions: PERMISSIONS.main
994
- });
995
- app.addMiddlewares([() => releaseApi.middleware]);
996
- app.addReducers({
997
- [releaseApi.reducerPath]: releaseApi.reducer
999
+ Component: () => Promise.resolve().then(() => require("./App-B5UOQWbt.js")).then((mod) => ({ default: mod.App })),
1000
+ permissions: PERMISSIONS.main,
1001
+ position: 2
998
1002
  });
999
- app.injectContentManagerComponent("editView", "right-links", {
1000
- name: `${pluginId}-link`,
1001
- Component: CMReleasesContainer
1003
+ const contentManagerPluginApis = app.getPlugin("content-manager").apis;
1004
+ if ("addEditViewSidePanel" in contentManagerPluginApis && typeof contentManagerPluginApis.addEditViewSidePanel === "function") {
1005
+ contentManagerPluginApis.addEditViewSidePanel([Panel]);
1006
+ }
1007
+ if ("addDocumentAction" in contentManagerPluginApis && typeof contentManagerPluginApis.addDocumentAction === "function") {
1008
+ contentManagerPluginApis.addDocumentAction((actions) => {
1009
+ const indexOfDeleteAction = actions.findIndex((action) => action.type === "unpublish");
1010
+ actions.splice(indexOfDeleteAction, 0, ReleaseActionModalForm);
1011
+ return actions;
1012
+ });
1013
+ }
1014
+ app.addSettingsLink("global", {
1015
+ id: pluginId,
1016
+ to: "releases",
1017
+ intlLabel: {
1018
+ id: `${pluginId}.plugin.name`,
1019
+ defaultMessage: "Releases"
1020
+ },
1021
+ permissions: [],
1022
+ async Component() {
1023
+ const { SettingsPage } = await Promise.resolve().then(() => require("./SettingsPage-ped5WZ6Q.js"));
1024
+ return { default: SettingsPage };
1025
+ }
1002
1026
  });
1003
1027
  } else if (!window.strapi.features.isEnabled("cms-content-releases") && window.strapi?.flags?.promoteEE) {
1004
- app.addMenuLink({
1005
- to: `/plugins/purchase-content-releases`,
1006
- icon: icons.PaperPlane,
1028
+ app.addSettingsLink("global", {
1029
+ id: pluginId,
1030
+ to: "/plugins/purchase-content-releases",
1007
1031
  intlLabel: {
1008
1032
  id: `${pluginId}.plugin.name`,
1009
1033
  defaultMessage: "Releases"
1010
1034
  },
1035
+ permissions: [],
1011
1036
  async Component() {
1012
- const { PurchaseContentReleases } = await Promise.resolve().then(() => require("./PurchaseContentReleases-YhAPgpG9.js"));
1013
- return PurchaseContentReleases;
1037
+ const { PurchaseContentReleases } = await Promise.resolve().then(() => require("./PurchaseContentReleases-Be3acS2L.js"));
1038
+ return { default: PurchaseContentReleases };
1014
1039
  },
1015
- lockIcon: true
1040
+ licenseOnly: true
1016
1041
  });
1017
1042
  }
1018
1043
  },
1019
1044
  async registerTrads({ locales }) {
1020
1045
  const importedTrads = await Promise.all(
1021
1046
  locales.map((locale) => {
1022
- return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => Promise.resolve().then(() => require("./en-faJDuv3q.js")) }), `./translations/${locale}.json`).then(({ default: data }) => {
1047
+ return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => Promise.resolve().then(() => require("./en-aH5E5UNw.js")) }), `./translations/${locale}.json`).then(({ default: data }) => {
1023
1048
  return {
1024
1049
  data: prefixPluginTranslations(data, "content-releases"),
1025
1050
  locale
@@ -1040,7 +1065,6 @@ exports.ReleaseActionMenu = ReleaseActionMenu;
1040
1065
  exports.ReleaseActionOptions = ReleaseActionOptions;
1041
1066
  exports.admin = admin;
1042
1067
  exports.getTimezoneOffset = getTimezoneOffset;
1043
- exports.isAxiosError = isAxiosError;
1044
1068
  exports.pluginId = pluginId;
1045
1069
  exports.releaseApi = releaseApi;
1046
1070
  exports.useCreateReleaseMutation = useCreateReleaseMutation;
@@ -1051,4 +1075,4 @@ exports.useGetReleasesQuery = useGetReleasesQuery;
1051
1075
  exports.usePublishReleaseMutation = usePublishReleaseMutation;
1052
1076
  exports.useUpdateReleaseActionMutation = useUpdateReleaseActionMutation;
1053
1077
  exports.useUpdateReleaseMutation = useUpdateReleaseMutation;
1054
- //# sourceMappingURL=index-cYWov2wa.js.map
1078
+ //# sourceMappingURL=index-BgID5UQ7.js.map