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

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/LICENSE +17 -1
  2. package/dist/_chunks/{App-BsUSTHVD.mjs → App-CiZCkScI.mjs} +643 -428
  3. package/dist/_chunks/App-CiZCkScI.mjs.map +1 -0
  4. package/dist/_chunks/{App-CXRpb2hi.js → App-SGjO5UPV.js} +682 -470
  5. package/dist/_chunks/App-SGjO5UPV.js.map +1 -0
  6. package/dist/_chunks/{PurchaseContentReleases-Be3acS2L.js → PurchaseContentReleases--qQepXpP.js} +2 -2
  7. package/dist/_chunks/PurchaseContentReleases--qQepXpP.js.map +1 -0
  8. package/dist/_chunks/{PurchaseContentReleases-_MxP6-Dt.mjs → PurchaseContentReleases-D-n-w-st.mjs} +2 -2
  9. package/dist/_chunks/{PurchaseContentReleases-_MxP6-Dt.mjs.map → PurchaseContentReleases-D-n-w-st.mjs.map} +1 -1
  10. package/dist/_chunks/ReleasesSettingsPage-Cto_NLUd.js +178 -0
  11. package/dist/_chunks/ReleasesSettingsPage-Cto_NLUd.js.map +1 -0
  12. package/dist/_chunks/ReleasesSettingsPage-DQT8N3A-.mjs +178 -0
  13. package/dist/_chunks/ReleasesSettingsPage-DQT8N3A-.mjs.map +1 -0
  14. package/dist/_chunks/{en-DtFJ5ViE.js → en-BWPPsSH-.js} +18 -2
  15. package/dist/_chunks/en-BWPPsSH-.js.map +1 -0
  16. package/dist/_chunks/{en-B9Ur3VsE.mjs → en-D9Q4YW03.mjs} +18 -2
  17. package/dist/_chunks/en-D9Q4YW03.mjs.map +1 -0
  18. package/dist/_chunks/{index-DJLIZdZv.mjs → index-BjvFfTtA.mjs} +751 -605
  19. package/dist/_chunks/index-BjvFfTtA.mjs.map +1 -0
  20. package/dist/_chunks/{index-B6-lic1Q.js → index-CyU534vL.js} +739 -596
  21. package/dist/_chunks/index-CyU534vL.js.map +1 -0
  22. package/dist/_chunks/schemas-DBYv9gK8.js +61 -0
  23. package/dist/_chunks/schemas-DBYv9gK8.js.map +1 -0
  24. package/dist/_chunks/schemas-DdA2ic2U.mjs +44 -0
  25. package/dist/_chunks/schemas-DdA2ic2U.mjs.map +1 -0
  26. package/dist/admin/index.js +1 -1
  27. package/dist/admin/index.mjs +2 -2
  28. package/dist/admin/src/components/EntryValidationPopover.d.ts +13 -0
  29. package/dist/admin/src/components/ReleaseActionMenu.d.ts +3 -3
  30. package/dist/admin/src/components/{CMReleasesContainer.d.ts → ReleaseActionModal.d.ts} +3 -1
  31. package/dist/admin/src/components/ReleaseListCell.d.ts +28 -0
  32. package/dist/admin/src/components/ReleaseModal.d.ts +3 -2
  33. package/dist/admin/src/components/ReleasesPanel.d.ts +3 -0
  34. package/dist/admin/src/constants.d.ts +18 -0
  35. package/dist/admin/src/modules/hooks.d.ts +7 -0
  36. package/dist/admin/src/pages/ReleasesSettingsPage.d.ts +1 -0
  37. package/dist/admin/src/services/release.d.ts +53 -370
  38. package/dist/admin/src/utils/api.d.ts +6 -0
  39. package/dist/admin/src/utils/time.d.ts +9 -0
  40. package/dist/admin/src/validation/schemas.d.ts +6 -0
  41. package/dist/server/index.js +889 -614
  42. package/dist/server/index.js.map +1 -1
  43. package/dist/server/index.mjs +889 -613
  44. package/dist/server/index.mjs.map +1 -1
  45. package/dist/server/src/bootstrap.d.ts.map +1 -1
  46. package/dist/server/src/constants.d.ts +11 -2
  47. package/dist/server/src/constants.d.ts.map +1 -1
  48. package/dist/server/src/content-types/index.d.ts +3 -5
  49. package/dist/server/src/content-types/index.d.ts.map +1 -1
  50. package/dist/server/src/content-types/release-action/index.d.ts +3 -5
  51. package/dist/server/src/content-types/release-action/index.d.ts.map +1 -1
  52. package/dist/server/src/content-types/release-action/schema.d.ts +3 -5
  53. package/dist/server/src/content-types/release-action/schema.d.ts.map +1 -1
  54. package/dist/server/src/controllers/index.d.ts +6 -1
  55. package/dist/server/src/controllers/index.d.ts.map +1 -1
  56. package/dist/server/src/controllers/release-action.d.ts.map +1 -1
  57. package/dist/server/src/controllers/release.d.ts +7 -1
  58. package/dist/server/src/controllers/release.d.ts.map +1 -1
  59. package/dist/server/src/controllers/settings.d.ts +11 -0
  60. package/dist/server/src/controllers/settings.d.ts.map +1 -0
  61. package/dist/server/src/controllers/validation/release-action.d.ts +7 -1
  62. package/dist/server/src/controllers/validation/release-action.d.ts.map +1 -1
  63. package/dist/server/src/controllers/validation/release.d.ts +2 -0
  64. package/dist/server/src/controllers/validation/release.d.ts.map +1 -1
  65. package/dist/server/src/controllers/validation/settings.d.ts +3 -0
  66. package/dist/server/src/controllers/validation/settings.d.ts.map +1 -0
  67. package/dist/server/src/index.d.ts +64 -49
  68. package/dist/server/src/index.d.ts.map +1 -1
  69. package/dist/server/src/middlewares/documents.d.ts +6 -0
  70. package/dist/server/src/middlewares/documents.d.ts.map +1 -0
  71. package/dist/server/src/migrations/database/5.0.0-document-id-in-actions.d.ts +9 -0
  72. package/dist/server/src/migrations/database/5.0.0-document-id-in-actions.d.ts.map +1 -0
  73. package/dist/server/src/migrations/index.d.ts.map +1 -1
  74. package/dist/server/src/register.d.ts.map +1 -1
  75. package/dist/server/src/routes/index.d.ts +16 -0
  76. package/dist/server/src/routes/index.d.ts.map +1 -1
  77. package/dist/server/src/routes/release.d.ts.map +1 -1
  78. package/dist/server/src/routes/settings.d.ts +18 -0
  79. package/dist/server/src/routes/settings.d.ts.map +1 -0
  80. package/dist/server/src/services/index.d.ts +36 -38
  81. package/dist/server/src/services/index.d.ts.map +1 -1
  82. package/dist/server/src/services/release-action.d.ts +34 -0
  83. package/dist/server/src/services/release-action.d.ts.map +1 -0
  84. package/dist/server/src/services/release.d.ts +6 -41
  85. package/dist/server/src/services/release.d.ts.map +1 -1
  86. package/dist/server/src/services/settings.d.ts +13 -0
  87. package/dist/server/src/services/settings.d.ts.map +1 -0
  88. package/dist/server/src/services/validation.d.ts +1 -1
  89. package/dist/server/src/services/validation.d.ts.map +1 -1
  90. package/dist/server/src/utils/index.d.ts +29 -8
  91. package/dist/server/src/utils/index.d.ts.map +1 -1
  92. package/dist/shared/contracts/release-actions.d.ts +17 -11
  93. package/dist/shared/contracts/release-actions.d.ts.map +1 -1
  94. package/dist/shared/contracts/releases.d.ts +9 -7
  95. package/dist/shared/contracts/releases.d.ts.map +1 -1
  96. package/dist/shared/contracts/settings.d.ts +39 -0
  97. package/dist/shared/contracts/settings.d.ts.map +1 -0
  98. package/package.json +24 -23
  99. package/dist/_chunks/App-BsUSTHVD.mjs.map +0 -1
  100. package/dist/_chunks/App-CXRpb2hi.js.map +0 -1
  101. package/dist/_chunks/PurchaseContentReleases-Be3acS2L.js.map +0 -1
  102. package/dist/_chunks/en-B9Ur3VsE.mjs.map +0 -1
  103. package/dist/_chunks/en-DtFJ5ViE.js.map +0 -1
  104. package/dist/_chunks/index-B6-lic1Q.js.map +0 -1
  105. package/dist/_chunks/index-DJLIZdZv.mjs.map +0 -1
  106. package/dist/admin/src/services/axios.d.ts +0 -29
  107. package/dist/shared/validation-schemas.d.ts +0 -2
  108. package/dist/shared/validation-schemas.d.ts.map +0 -1
  109. package/strapi-server.js +0 -3
@@ -1,23 +1,18 @@
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");
7
- const strapiAdmin$1 = require("@strapi/content-manager/strapi-admin");
8
5
  const designSystem = require("@strapi/design-system");
9
- const symbols = require("@strapi/icons/symbols");
10
- const axios = require("axios");
11
6
  const formik = require("formik");
12
7
  const reactIntl = require("react-intl");
8
+ const strapiAdmin$1 = require("@strapi/content-manager/strapi-admin");
9
+ const symbols = require("@strapi/icons/symbols");
13
10
  const reactRouterDom = require("react-router-dom");
14
11
  const yup = require("yup");
15
- const react = require("@reduxjs/toolkit/query/react");
16
- const styled = require("styled-components");
17
- const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
12
+ const styledComponents = require("styled-components");
13
+ const React = require("react");
18
14
  function _interopNamespace(e) {
19
- if (e && e.__esModule)
20
- return e;
15
+ if (e && e.__esModule) return e;
21
16
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
22
17
  if (e) {
23
18
  for (const k in e) {
@@ -33,16 +28,22 @@ function _interopNamespace(e) {
33
28
  n.default = e;
34
29
  return Object.freeze(n);
35
30
  }
36
- const React__namespace = /* @__PURE__ */ _interopNamespace(React);
37
31
  const yup__namespace = /* @__PURE__ */ _interopNamespace(yup);
38
- const styled__default = /* @__PURE__ */ _interopDefault(styled);
39
- const __variableDynamicImportRuntimeHelper = (glob, path) => {
32
+ const React__namespace = /* @__PURE__ */ _interopNamespace(React);
33
+ const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
40
34
  const v = glob[path];
41
35
  if (v) {
42
36
  return typeof v === "function" ? v() : Promise.resolve(v);
43
37
  }
44
38
  return new Promise((_, reject) => {
45
- (typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(reject.bind(null, new Error("Unknown variable dynamic import: " + path)));
39
+ (typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
40
+ reject.bind(
41
+ null,
42
+ new Error(
43
+ "Unknown variable dynamic import: " + path + (path.split("/").length !== segs ? ". Note that variables only represent file names one level deep." : "")
44
+ )
45
+ )
46
+ );
46
47
  });
47
48
  };
48
49
  const PERMISSIONS = {
@@ -117,55 +118,70 @@ const PERMISSIONS = {
117
118
  }
118
119
  ]
119
120
  };
120
- const pluginId = "content-releases";
121
- const axiosBaseQuery = async ({
122
- url,
123
- method,
124
- data,
125
- config
126
- }) => {
127
- try {
128
- const { get, post, del, put } = strapiAdmin.getFetchClient();
129
- if (method === "POST") {
130
- const result2 = await post(url, data, config);
131
- return { data: result2.data };
132
- }
133
- if (method === "DELETE") {
134
- const result2 = await del(url, config);
135
- return { data: result2.data };
136
- }
137
- if (method === "PUT") {
138
- const result2 = await put(url, data, config);
139
- return { data: result2.data };
140
- }
141
- const result = await get(url, config);
142
- return { data: result.data };
143
- } catch (error) {
144
- const err = error;
145
- return {
146
- error: {
147
- status: err.response?.status,
148
- code: err.code,
149
- response: {
150
- data: err.response?.data
151
- }
152
- }
153
- };
121
+ const extendInvalidatesTags = (endpoint, extraTags) => {
122
+ if (!endpoint) {
123
+ return;
154
124
  }
125
+ const originalInvalidatesTags = endpoint.invalidatesTags;
126
+ const newInvalidatesTags = (result, err, args, meta) => {
127
+ const originalTags = typeof originalInvalidatesTags === "function" ? originalInvalidatesTags(result, err, args, meta) : originalInvalidatesTags;
128
+ return [...originalTags ?? [], ...extraTags];
129
+ };
130
+ Object.assign(endpoint, { invalidatesTags: newInvalidatesTags });
155
131
  };
156
- const isAxiosError = (err) => {
157
- return typeof err === "object" && err !== null && "response" in err && typeof err.response === "object" && err.response !== null && "data" in err.response;
158
- };
159
- const releaseApi = react.createApi({
160
- reducerPath: pluginId,
161
- baseQuery: axiosBaseQuery,
162
- tagTypes: ["Release", "ReleaseAction", "EntriesInRelease"],
132
+ const releaseApi = strapiAdmin.adminApi.enhanceEndpoints({
133
+ addTagTypes: ["Release", "ReleaseAction", "EntriesInRelease", "ReleaseSettings", "Document"],
134
+ endpoints: {
135
+ updateDocument(endpoint) {
136
+ extendInvalidatesTags(endpoint, [
137
+ { type: "Release", id: "LIST" },
138
+ { type: "ReleaseAction", id: "LIST" }
139
+ ]);
140
+ },
141
+ deleteDocument(endpoint) {
142
+ extendInvalidatesTags(endpoint, [
143
+ { type: "Release", id: "LIST" },
144
+ { type: "ReleaseAction", id: "LIST" }
145
+ ]);
146
+ },
147
+ deleteManyDocuments(endpoint) {
148
+ extendInvalidatesTags(endpoint, [
149
+ { type: "Release", id: "LIST" },
150
+ { type: "ReleaseAction", id: "LIST" }
151
+ ]);
152
+ },
153
+ discardDocument(endpoint) {
154
+ extendInvalidatesTags(endpoint, [
155
+ { type: "Release", id: "LIST" },
156
+ { type: "ReleaseAction", id: "LIST" }
157
+ ]);
158
+ },
159
+ createWorkflow(endpoint) {
160
+ extendInvalidatesTags(endpoint, [
161
+ { type: "Release", id: "LIST" },
162
+ { type: "ReleaseAction", id: "LIST" }
163
+ ]);
164
+ },
165
+ updateWorkflow(endpoint) {
166
+ extendInvalidatesTags(endpoint, [
167
+ { type: "Release", id: "LIST" },
168
+ { type: "ReleaseAction", id: "LIST" }
169
+ ]);
170
+ },
171
+ deleteWorkflow(endpoint) {
172
+ extendInvalidatesTags(endpoint, [
173
+ { type: "Release", id: "LIST" },
174
+ { type: "ReleaseAction", id: "LIST" }
175
+ ]);
176
+ }
177
+ }
178
+ }).injectEndpoints({
163
179
  endpoints: (build) => {
164
180
  return {
165
181
  getReleasesForEntry: build.query({
166
182
  query(params) {
167
183
  return {
168
- url: "/content-releases",
184
+ url: "/content-releases/getByDocumentAttached",
169
185
  method: "GET",
170
186
  config: {
171
187
  params
@@ -227,7 +243,10 @@ const releaseApi = react.createApi({
227
243
  method: "GET"
228
244
  };
229
245
  },
230
- providesTags: (result, error, arg) => [{ type: "Release", id: arg.id }]
246
+ providesTags: (result, error, arg) => [
247
+ { type: "Release", id: "LIST" },
248
+ { type: "Release", id: arg.id }
249
+ ]
231
250
  }),
232
251
  getReleaseActions: build.query({
233
252
  query({ releaseId, ...params }) {
@@ -296,20 +315,28 @@ const releaseApi = react.createApi({
296
315
  data: body
297
316
  };
298
317
  },
299
- invalidatesTags: () => [{ type: "ReleaseAction", id: "LIST" }],
300
- async onQueryStarted({ body, params, query: query2, actionPath }, { dispatch, queryFulfilled }) {
318
+ invalidatesTags: (res, error, arg) => [
319
+ { type: "ReleaseAction", id: "LIST" },
320
+ { type: "Release", id: "LIST" },
321
+ { type: "Release", id: arg.params.releaseId }
322
+ ],
323
+ async onQueryStarted({ body, params, query, actionPath }, { dispatch, queryFulfilled }) {
301
324
  const paramsWithoutActionId = {
302
325
  releaseId: params.releaseId,
303
- ...query2
326
+ ...query
304
327
  };
305
328
  const patchResult = dispatch(
306
- releaseApi.util.updateQueryData("getReleaseActions", paramsWithoutActionId, (draft) => {
307
- const [key, index] = actionPath;
308
- const action = draft.data[key][index];
309
- if (action) {
310
- action.type = body.type;
329
+ releaseApi.util.updateQueryData(
330
+ "getReleaseActions",
331
+ paramsWithoutActionId,
332
+ (draft) => {
333
+ const [key, index] = actionPath;
334
+ const action = draft.data[key][index];
335
+ if (action) {
336
+ action.type = body.type;
337
+ }
311
338
  }
312
- })
339
+ )
313
340
  );
314
341
  try {
315
342
  await queryFulfilled;
@@ -339,7 +366,10 @@ const releaseApi = react.createApi({
339
366
  method: "POST"
340
367
  };
341
368
  },
342
- invalidatesTags: (result, error, arg) => [{ type: "Release", id: arg.id }]
369
+ invalidatesTags: (result, error, arg) => [
370
+ { type: "Release", id: arg.id },
371
+ { type: "Document", id: `ALL_LIST` }
372
+ ]
343
373
  }),
344
374
  deleteRelease: build.mutation({
345
375
  query({ id }) {
@@ -364,6 +394,20 @@ const releaseApi = react.createApi({
364
394
  return response.data;
365
395
  },
366
396
  providesTags: [{ type: "EntriesInRelease" }]
397
+ }),
398
+ getReleaseSettings: build.query({
399
+ query: () => "/content-releases/settings",
400
+ providesTags: [{ type: "ReleaseSettings" }]
401
+ }),
402
+ updateReleaseSettings: build.mutation({
403
+ query(data) {
404
+ return {
405
+ url: "/content-releases/settings",
406
+ method: "PUT",
407
+ data
408
+ };
409
+ },
410
+ invalidatesTags: [{ type: "ReleaseSettings" }]
367
411
  })
368
412
  };
369
413
  }
@@ -381,199 +425,21 @@ const {
381
425
  usePublishReleaseMutation,
382
426
  useDeleteReleaseActionMutation,
383
427
  useDeleteReleaseMutation,
384
- useGetMappedEntriesInReleasesQuery
428
+ useGetMappedEntriesInReleasesQuery,
429
+ useGetReleaseSettingsQuery,
430
+ useUpdateReleaseSettingsMutation
385
431
  } = releaseApi;
386
- const getTimezoneOffset = (timezone, date) => {
387
- try {
388
- const offsetPart = new Intl.DateTimeFormat("en", {
389
- timeZone: timezone,
390
- timeZoneName: "longOffset"
391
- }).formatToParts(date).find((part) => part.type === "timeZoneName");
392
- const offset = offsetPart ? offsetPart.value : "";
393
- let utcOffset = offset.replace("GMT", "UTC");
394
- if (!utcOffset.includes("+") && !utcOffset.includes("-")) {
395
- utcOffset = `${utcOffset}+00:00`;
396
- }
397
- return utcOffset;
398
- } catch (error) {
399
- return "";
400
- }
401
- };
402
- const StyledMenuItem = styled__default.default(designSystem.Menu.Item)`
403
- &:hover {
404
- background: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}100`]};
405
-
406
- svg {
407
- fill: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}600`]};
408
- }
409
-
410
- a {
411
- color: ${({ theme }) => theme.colors.neutral800};
412
- }
413
- }
414
-
415
- svg {
416
- fill: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}600`]};
417
- }
418
-
419
- a {
420
- color: ${({ theme }) => theme.colors.neutral800};
421
- }
422
-
423
- span,
424
- a {
425
- width: 100%;
426
- }
427
- `;
428
- const StyledIconButton = styled__default.default(designSystem.IconButton)`
429
- /* Setting this style inline with borderColor will not apply the style */
430
- border: ${({ theme }) => `1px solid ${theme.colors.neutral200}`};
431
- `;
432
- const DeleteReleaseActionItem = ({ releaseId, actionId }) => {
433
- const { formatMessage } = reactIntl.useIntl();
434
- const { toggleNotification } = strapiAdmin.useNotification();
435
- const { formatAPIError } = strapiAdmin.useAPIErrorHandler();
436
- const [deleteReleaseAction] = useDeleteReleaseActionMutation();
437
- const {
438
- allowedActions: { canDeleteAction }
439
- } = strapiAdmin.useRBAC(PERMISSIONS);
440
- const handleDeleteAction = async () => {
441
- const response = await deleteReleaseAction({
442
- params: { releaseId, actionId }
443
- });
444
- if ("data" in response) {
445
- toggleNotification({
446
- type: "success",
447
- message: formatMessage({
448
- id: "content-releases.content-manager-edit-view.remove-from-release.notification.success",
449
- defaultMessage: "Entry removed from release"
450
- })
451
- });
452
- return;
453
- }
454
- if ("error" in response) {
455
- if (axios.isAxiosError(response.error)) {
456
- toggleNotification({
457
- type: "danger",
458
- message: formatAPIError(response.error)
459
- });
460
- } else {
461
- toggleNotification({
462
- type: "danger",
463
- message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
464
- });
465
- }
466
- }
467
- };
468
- if (!canDeleteAction) {
469
- return null;
470
- }
471
- return /* @__PURE__ */ jsxRuntime.jsx(StyledMenuItem, { variant: "danger", onSelect: handleDeleteAction, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
472
- /* @__PURE__ */ jsxRuntime.jsx(icons.Cross, { width: "1.6rem", height: "1.6rem" }),
473
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger600", variant: "omega", children: formatMessage({
474
- id: "content-releases.content-manager-edit-view.remove-from-release",
475
- defaultMessage: "Remove from release"
476
- }) })
477
- ] }) });
478
- };
479
- const ReleaseActionEntryLinkItem = ({
480
- contentTypeUid,
481
- entryId,
482
- locale
483
- }) => {
484
- const { formatMessage } = reactIntl.useIntl();
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(
509
- StyledMenuItem,
510
- {
511
- forwardedAs: reactRouterDom.Link,
512
- isLink: true,
513
- to: {
514
- pathname: `/content-manager/collection-types/${contentTypeUid}/${entryId}`,
515
- search: locale && `?plugins[i18n][locale]=${locale}`
516
- },
517
- children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
518
- /* @__PURE__ */ jsxRuntime.jsx(icons.Pencil, { width: "1.6rem", height: "1.6rem" }),
519
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: formatMessage({
520
- id: "content-releases.content-manager-edit-view.edit-entry",
521
- defaultMessage: "Edit entry"
522
- }) })
523
- ] })
524
- }
525
- );
526
- };
527
- const EditReleaseItem = ({ releaseId }) => {
528
- const { formatMessage } = reactIntl.useIntl();
529
- return /* @__PURE__ */ jsxRuntime.jsx(StyledMenuItem, { forwardedAs: reactRouterDom.Link, isLink: true, to: `/plugins/content-releases/${releaseId}`, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
530
- /* @__PURE__ */ jsxRuntime.jsx(icons.Pencil, { width: "1.6rem", height: "1.6rem" }),
531
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: formatMessage({
532
- id: "content-releases.content-manager-edit-view.edit-release",
533
- defaultMessage: "Edit release"
534
- }) })
535
- ] }) });
536
- };
537
- const Root = ({ children, hasTriggerBorder = false }) => {
538
- const { formatMessage } = reactIntl.useIntl();
539
- const { allowedActions } = strapiAdmin.useRBAC(PERMISSIONS);
540
- return (
541
- // A user can access the dropdown if they have permissions to delete a release-action OR update a release
542
- allowedActions.canDeleteAction || allowedActions.canUpdate ? /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Root, { children: [
543
- /* @__PURE__ */ jsxRuntime.jsx(
544
- designSystem.Menu.Trigger,
545
- {
546
- as: hasTriggerBorder ? StyledIconButton : designSystem.IconButton,
547
- paddingLeft: 2,
548
- paddingRight: 2,
549
- "aria-label": formatMessage({
550
- id: "content-releases.content-manager-edit-view.release-action-menu",
551
- defaultMessage: "Release action options"
552
- }),
553
- icon: /* @__PURE__ */ jsxRuntime.jsx(icons.More, {})
554
- }
555
- ),
556
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Menu.Content, { top: 1, popoverPlacement: "bottom-end", children })
557
- ] }) : null
558
- );
559
- };
560
- const ReleaseActionMenu = {
561
- Root,
562
- EditReleaseItem,
563
- DeleteReleaseActionItem,
564
- ReleaseActionEntryLinkItem
565
- };
566
432
  const getBorderLeftRadiusValue = (actionType) => {
567
433
  return actionType === "publish" ? 1 : 0;
568
434
  };
569
435
  const getBorderRightRadiusValue = (actionType) => {
570
436
  return actionType === "publish" ? 0 : 1;
571
437
  };
572
- const FieldWrapper = styled__default.default(designSystem.Field)`
573
- border-top-left-radius: ${({ actionType, theme }) => theme.spaces[getBorderLeftRadiusValue(actionType)]};
574
- border-bottom-left-radius: ${({ actionType, theme }) => theme.spaces[getBorderLeftRadiusValue(actionType)]};
575
- border-top-right-radius: ${({ actionType, theme }) => theme.spaces[getBorderRightRadiusValue(actionType)]};
576
- border-bottom-right-radius: ${({ actionType, theme }) => theme.spaces[getBorderRightRadiusValue(actionType)]};
438
+ const FieldWrapper = styledComponents.styled(designSystem.Field.Root)`
439
+ border-top-left-radius: ${({ $actionType, theme }) => theme.spaces[getBorderLeftRadiusValue($actionType)]};
440
+ border-bottom-left-radius: ${({ $actionType, theme }) => theme.spaces[getBorderLeftRadiusValue($actionType)]};
441
+ border-top-right-radius: ${({ $actionType, theme }) => theme.spaces[getBorderRightRadiusValue($actionType)]};
442
+ border-bottom-right-radius: ${({ $actionType, theme }) => theme.spaces[getBorderRightRadiusValue($actionType)]};
577
443
 
578
444
  > label {
579
445
  color: inherit;
@@ -584,14 +450,14 @@ const FieldWrapper = styled__default.default(designSystem.Field)`
584
450
  }
585
451
 
586
452
  &[data-checked='true'] {
587
- color: ${({ theme, actionType }) => actionType === "publish" ? theme.colors.primary700 : theme.colors.danger600};
588
- background-color: ${({ theme, actionType }) => actionType === "publish" ? theme.colors.primary100 : theme.colors.danger100};
589
- border-color: ${({ theme, actionType }) => actionType === "publish" ? theme.colors.primary700 : theme.colors.danger600};
453
+ color: ${({ theme, $actionType }) => $actionType === "publish" ? theme.colors.primary700 : theme.colors.danger600};
454
+ background-color: ${({ theme, $actionType }) => $actionType === "publish" ? theme.colors.primary100 : theme.colors.danger100};
455
+ border-color: ${({ theme, $actionType }) => $actionType === "publish" ? theme.colors.primary700 : theme.colors.danger600};
590
456
  }
591
457
 
592
458
  &[data-checked='false'] {
593
- border-left: ${({ actionType }) => actionType === "unpublish" && "none"};
594
- border-right: ${({ actionType }) => actionType === "publish" && "none"};
459
+ border-left: ${({ $actionType }) => $actionType === "unpublish" && "none"};
460
+ border-right: ${({ $actionType }) => $actionType === "publish" && "none"};
595
461
  }
596
462
 
597
463
  &[data-checked='false'][data-disabled='false']:hover {
@@ -620,7 +486,7 @@ const ActionOption = ({
620
486
  return /* @__PURE__ */ jsxRuntime.jsx(
621
487
  FieldWrapper,
622
488
  {
623
- actionType,
489
+ $actionType: actionType,
624
490
  background: "primary0",
625
491
  borderColor: "neutral200",
626
492
  color: selected === actionType ? "primary600" : "neutral600",
@@ -628,12 +494,11 @@ const ActionOption = ({
628
494
  cursor: "pointer",
629
495
  "data-checked": selected === actionType,
630
496
  "data-disabled": disabled && selected !== actionType,
631
- children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.FieldLabel, { htmlFor: `${name}-${actionType}`, children: [
497
+ children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Label, { children: [
632
498
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { children: /* @__PURE__ */ jsxRuntime.jsx(
633
- designSystem.FieldInput,
499
+ designSystem.Field.Input,
634
500
  {
635
501
  type: "radio",
636
- id: `${name}-${actionType}`,
637
502
  name,
638
503
  checked: selected === actionType,
639
504
  onChange: handleChange,
@@ -699,302 +564,192 @@ const NoReleases = () => {
699
564
  to: {
700
565
  pathname: "/plugins/content-releases"
701
566
  },
702
- as: reactRouterDom.Link,
567
+ tag: reactRouterDom.Link,
703
568
  variant: "secondary",
704
569
  children: formatMessage({
705
570
  id: "content-releases.content-manager-edit-view.add-to-release.redirect-button",
706
571
  defaultMessage: "Open the list of releases"
707
572
  })
708
573
  }
709
- )
574
+ ),
575
+ shadow: "none"
710
576
  }
711
577
  );
712
578
  };
713
579
  const AddActionToReleaseModal = ({
714
- handleClose,
715
- contentTypeUid,
716
- entryId
580
+ contentType,
581
+ documentId,
582
+ onInputChange,
583
+ values
717
584
  }) => {
718
- const releaseHeaderId = React__namespace.useId();
719
585
  const { formatMessage } = reactIntl.useIntl();
720
- const { toggleNotification } = strapiAdmin.useNotification();
721
- const { formatAPIError } = strapiAdmin.useAPIErrorHandler();
722
- const [{ query: query2 }] = strapiAdmin.useQueryParams();
723
- const locale = query2.plugins?.i18n?.locale;
586
+ const [{ query }] = strapiAdmin.useQueryParams();
587
+ const locale = query.plugins?.i18n?.locale;
724
588
  const response = useGetReleasesForEntryQuery({
725
- contentTypeUid,
726
- entryId,
727
- hasEntryAttached: false
589
+ contentType,
590
+ entryDocumentId: documentId,
591
+ hasEntryAttached: false,
592
+ locale
728
593
  });
729
594
  const releases = response.data?.data;
595
+ if (releases?.length === 0) {
596
+ return /* @__PURE__ */ jsxRuntime.jsx(NoReleases, {});
597
+ }
598
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
599
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingBottom: 6, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { required: true, children: [
600
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
601
+ id: "content-releases.content-manager-edit-view.add-to-release.select-label",
602
+ defaultMessage: "Select a release"
603
+ }) }),
604
+ /* @__PURE__ */ jsxRuntime.jsx(
605
+ designSystem.SingleSelect,
606
+ {
607
+ required: true,
608
+ placeholder: formatMessage({
609
+ id: "content-releases.content-manager-edit-view.add-to-release.select-placeholder",
610
+ defaultMessage: "Select"
611
+ }),
612
+ name: "releaseId",
613
+ onChange: (value) => onInputChange("releaseId", value),
614
+ value: values.releaseId,
615
+ children: releases?.map((release) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: release.id, children: release.name }, release.id))
616
+ }
617
+ )
618
+ ] }) }),
619
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
620
+ id: "content-releases.content-manager-edit-view.add-to-release.action-type-label",
621
+ defaultMessage: "What do you want to do with this entry?"
622
+ }) }),
623
+ /* @__PURE__ */ jsxRuntime.jsx(
624
+ ReleaseActionOptions,
625
+ {
626
+ selected: values.type,
627
+ handleChange: (e) => onInputChange("type", e.target.value),
628
+ name: "type"
629
+ }
630
+ )
631
+ ] });
632
+ };
633
+ const ReleaseActionModalForm = ({
634
+ documentId,
635
+ document,
636
+ model,
637
+ collectionType
638
+ }) => {
639
+ const { formatMessage } = reactIntl.useIntl();
640
+ const { allowedActions } = strapiAdmin.useRBAC(PERMISSIONS);
641
+ const { canCreateAction } = allowedActions;
730
642
  const [createReleaseAction, { isLoading }] = useCreateReleaseActionMutation();
731
- const handleSubmit = async (values) => {
732
- const releaseActionEntry = {
733
- contentType: contentTypeUid,
734
- id: entryId,
735
- locale
736
- };
737
- const response2 = await createReleaseAction({
738
- body: { type: values.type, entry: releaseActionEntry },
739
- params: { releaseId: values.releaseId }
740
- });
741
- if ("data" in response2) {
742
- toggleNotification({
743
- type: "success",
744
- message: formatMessage({
745
- id: "content-releases.content-manager-edit-view.add-to-release.notification.success",
746
- defaultMessage: "Entry added to release"
747
- })
748
- });
749
- handleClose();
750
- return;
751
- }
752
- if ("error" in response2) {
753
- if (axios.isAxiosError(response2.error)) {
643
+ const { toggleNotification } = strapiAdmin.useNotification();
644
+ const { formatAPIError } = strapiAdmin.useAPIErrorHandler();
645
+ const [{ query }] = strapiAdmin.useQueryParams();
646
+ const locale = query.plugins?.i18n?.locale;
647
+ const handleSubmit = async (e, onClose) => {
648
+ try {
649
+ await formik$1.handleSubmit(e);
650
+ onClose();
651
+ } catch (error) {
652
+ if (strapiAdmin.isFetchError(error)) {
754
653
  toggleNotification({
755
654
  type: "danger",
756
- message: formatAPIError(response2.error)
655
+ message: formatAPIError(error)
757
656
  });
758
657
  } else {
759
658
  toggleNotification({
760
659
  type: "danger",
761
- message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
660
+ message: formatMessage({
661
+ id: "notification.error",
662
+ defaultMessage: "An error occurred"
663
+ })
762
664
  });
763
665
  }
764
666
  }
765
667
  };
766
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.ModalLayout, { onClose: handleClose, labelledBy: releaseHeaderId, children: [
767
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.ModalHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: releaseHeaderId, fontWeight: "bold", textColor: "neutral800", children: formatMessage({
768
- id: "content-releases.content-manager-edit-view.add-to-release",
769
- defaultMessage: "Add to release"
770
- }) }) }),
771
- /* @__PURE__ */ jsxRuntime.jsx(
772
- formik.Formik,
773
- {
774
- onSubmit: handleSubmit,
775
- validationSchema: RELEASE_ACTION_FORM_SCHEMA,
776
- initialValues: INITIAL_VALUES,
777
- children: ({ values, setFieldValue }) => {
778
- return /* @__PURE__ */ jsxRuntime.jsxs(formik.Form, { children: [
779
- 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: [
780
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingBottom: 6, children: /* @__PURE__ */ jsxRuntime.jsx(
781
- designSystem.SingleSelect,
782
- {
783
- required: true,
784
- label: formatMessage({
785
- id: "content-releases.content-manager-edit-view.add-to-release.select-label",
786
- defaultMessage: "Select a release"
787
- }),
788
- placeholder: formatMessage({
789
- id: "content-releases.content-manager-edit-view.add-to-release.select-placeholder",
790
- defaultMessage: "Select"
791
- }),
792
- onChange: (value) => setFieldValue("releaseId", value),
793
- value: values.releaseId,
794
- children: releases?.map((release) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: release.id, children: release.name }, release.id))
795
- }
796
- ) }),
797
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.FieldLabel, { children: formatMessage({
798
- id: "content-releases.content-manager-edit-view.add-to-release.action-type-label",
799
- defaultMessage: "What do you want to do with this entry?"
800
- }) }),
801
- /* @__PURE__ */ jsxRuntime.jsx(
802
- ReleaseActionOptions,
803
- {
804
- selected: values.type,
805
- handleChange: (e) => setFieldValue("type", e.target.value),
806
- name: "type"
807
- }
808
- )
809
- ] }) }),
810
- /* @__PURE__ */ jsxRuntime.jsx(
811
- designSystem.ModalFooter,
812
- {
813
- startActions: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleClose, variant: "tertiary", name: "cancel", children: formatMessage({
814
- id: "content-releases.content-manager-edit-view.add-to-release.cancel-button",
815
- defaultMessage: "Cancel"
816
- }) }),
817
- endActions: (
818
- /**
819
- * TODO: Ideally we would use isValid from Formik to disable the button, however currently it always returns true
820
- * for yup.string().required(), even when the value is falsy (including empty string)
821
- */
822
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { type: "submit", disabled: !values.releaseId, loading: isLoading, children: formatMessage({
823
- id: "content-releases.content-manager-edit-view.add-to-release.continue-button",
824
- defaultMessage: "Continue"
825
- }) })
826
- )
827
- }
828
- )
829
- ] });
830
- }
668
+ const formik$1 = formik.useFormik({
669
+ initialValues: INITIAL_VALUES,
670
+ validationSchema: RELEASE_ACTION_FORM_SCHEMA,
671
+ onSubmit: async (values) => {
672
+ if (collectionType === "collection-types" && !documentId) {
673
+ throw new Error("Document id is required");
831
674
  }
832
- )
833
- ] });
834
- };
835
- const CMReleasesContainer = () => {
836
- const [isModalOpen, setIsModalOpen] = React__namespace.useState(false);
837
- const { formatMessage, formatDate, formatTime } = reactIntl.useIntl();
838
- const { id, slug, collectionType } = reactRouterDom.useParams();
839
- const isCreatingEntry = id === "create";
840
- const entryId = parseInt(id, 10);
841
- const { allowedActions } = strapiAdmin.useRBAC(PERMISSIONS);
842
- const { canCreateAction, canRead: canMain, canDeleteAction } = allowedActions;
843
- const { schema } = strapiAdmin$1.unstable_useDocument({
844
- collectionType,
845
- model: slug
675
+ const response = await createReleaseAction({
676
+ body: {
677
+ type: values.type,
678
+ contentType: model,
679
+ entryDocumentId: documentId,
680
+ locale
681
+ },
682
+ params: { releaseId: values.releaseId }
683
+ });
684
+ if ("data" in response) {
685
+ toggleNotification({
686
+ type: "success",
687
+ message: formatMessage({
688
+ id: "content-releases.content-manager-edit-view.add-to-release.notification.success",
689
+ defaultMessage: "Entry added to release"
690
+ })
691
+ });
692
+ return;
693
+ }
694
+ if ("error" in response) {
695
+ throw response.error;
696
+ }
697
+ }
846
698
  });
847
- const hasDraftAndPublish = schema?.options?.draftAndPublish;
848
- const contentTypeUid = slug;
849
- const canFetch = id != null && contentTypeUid != null;
850
- const fetchParams = canFetch ? {
851
- contentTypeUid,
852
- entryId,
853
- hasEntryAttached: true
854
- } : query.skipToken;
855
- const response = useGetReleasesForEntryQuery(fetchParams);
856
- const releases = response.data?.data;
857
- if (!canFetch) {
699
+ const {
700
+ edit: { options }
701
+ } = strapiAdmin$1.unstable_useDocumentLayout(model);
702
+ if (!window.strapi.isEE || !options?.draftAndPublish || !canCreateAction) {
858
703
  return null;
859
704
  }
860
- if (isCreatingEntry || !hasDraftAndPublish) {
705
+ if (collectionType === "collection-types" && (!documentId || documentId === "create")) {
861
706
  return null;
862
707
  }
863
- const toggleModal = () => setIsModalOpen((prev) => !prev);
864
- const getReleaseColorVariant = (actionType, shade) => {
865
- if (actionType === "unpublish") {
866
- return `secondary${shade}`;
867
- }
868
- return `success${shade}`;
869
- };
870
- if (!canMain) {
871
- return null;
872
- }
873
- return /* @__PURE__ */ jsxRuntime.jsxs(
874
- designSystem.Box,
875
- {
876
- as: "aside",
877
- "aria-label": formatMessage({
878
- id: "content-releases.plugin.name",
879
- defaultMessage: "Releases"
708
+ return {
709
+ label: formatMessage({
710
+ id: "content-releases.content-manager-edit-view.add-to-release",
711
+ defaultMessage: "Add to release"
712
+ }),
713
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.PaperPlane, {}),
714
+ // Entry is creating so we don't want to allow adding it to a release
715
+ disabled: !document,
716
+ position: ["panel", "table-row"],
717
+ dialog: {
718
+ type: "modal",
719
+ title: formatMessage({
720
+ id: "content-releases.content-manager-edit-view.add-to-release",
721
+ defaultMessage: "Add to release"
880
722
  }),
881
- background: "neutral0",
882
- borderColor: "neutral150",
883
- hasRadius: true,
884
- padding: 4,
885
- shadow: "tableShadow",
886
- children: [
887
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 3, children: [
888
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", children: formatMessage({
889
- id: "content-releases.plugin.name",
890
- defaultMessage: "Releases"
891
- }) }),
892
- releases?.map((release) => {
893
- return /* @__PURE__ */ jsxRuntime.jsxs(
894
- designSystem.Flex,
895
- {
896
- direction: "column",
897
- alignItems: "start",
898
- borderWidth: "1px",
899
- borderStyle: "solid",
900
- borderColor: getReleaseColorVariant(release.actions[0].type, "200"),
901
- overflow: "hidden",
902
- hasRadius: true,
903
- children: [
904
- /* @__PURE__ */ jsxRuntime.jsx(
905
- designSystem.Box,
906
- {
907
- paddingTop: 3,
908
- paddingBottom: 3,
909
- paddingLeft: 4,
910
- paddingRight: 4,
911
- background: getReleaseColorVariant(release.actions[0].type, "100"),
912
- width: "100%",
913
- children: /* @__PURE__ */ jsxRuntime.jsx(
914
- designSystem.Typography,
915
- {
916
- fontSize: 1,
917
- variant: "pi",
918
- textColor: getReleaseColorVariant(release.actions[0].type, "600"),
919
- children: formatMessage(
920
- {
921
- id: "content-releases.content-manager-edit-view.list-releases.title",
922
- defaultMessage: "{isPublish, select, true {Will be published in} other {Will be unpublished in}}"
923
- },
924
- { isPublish: release.actions[0].type === "publish" }
925
- )
926
- }
927
- )
928
- }
929
- ),
930
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { padding: 4, direction: "column", gap: 2, width: "100%", alignItems: "flex-start", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { padding: 4, direction: "column", gap: 2, width: "100%", alignItems: "flex-start", children: [
931
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontSize: 2, fontWeight: "bold", variant: "omega", textColor: "neutral700", children: release.name }),
932
- release.scheduledAt && release.timezone && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: formatMessage(
933
- {
934
- id: "content-releases.content-manager-edit-view.scheduled.date",
935
- defaultMessage: "{date} at {time} ({offset})"
936
- },
937
- {
938
- date: formatDate(new Date(release.scheduledAt), {
939
- day: "2-digit",
940
- month: "2-digit",
941
- year: "numeric",
942
- timeZone: release.timezone
943
- }),
944
- time: formatTime(new Date(release.scheduledAt), {
945
- hourCycle: "h23",
946
- timeZone: release.timezone
947
- }),
948
- offset: getTimezoneOffset(
949
- release.timezone,
950
- new Date(release.scheduledAt)
951
- )
952
- }
953
- ) }),
954
- canDeleteAction ? /* @__PURE__ */ jsxRuntime.jsxs(ReleaseActionMenu.Root, { hasTriggerBorder: true, children: [
955
- /* @__PURE__ */ jsxRuntime.jsx(ReleaseActionMenu.EditReleaseItem, { releaseId: release.id }),
956
- /* @__PURE__ */ jsxRuntime.jsx(
957
- ReleaseActionMenu.DeleteReleaseActionItem,
958
- {
959
- releaseId: release.id,
960
- actionId: release.actions[0].id
961
- }
962
- )
963
- ] }) : null
964
- ] }) })
965
- ]
966
- },
967
- release.id
968
- );
969
- }),
970
- canCreateAction ? /* @__PURE__ */ jsxRuntime.jsx(
971
- designSystem.Button,
972
- {
973
- justifyContent: "center",
974
- paddingLeft: 4,
975
- paddingRight: 4,
976
- color: "neutral700",
977
- variant: "tertiary",
978
- startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
979
- onClick: toggleModal,
980
- children: formatMessage({
981
- id: "content-releases.content-manager-edit-view.add-to-release",
982
- defaultMessage: "Add to release"
983
- })
984
- }
985
- ) : null
986
- ] }),
987
- isModalOpen && /* @__PURE__ */ jsxRuntime.jsx(
988
- AddActionToReleaseModal,
723
+ content: /* @__PURE__ */ jsxRuntime.jsx(
724
+ AddActionToReleaseModal,
725
+ {
726
+ contentType: model,
727
+ documentId,
728
+ onInputChange: formik$1.setFieldValue,
729
+ values: formik$1.values
730
+ }
731
+ ),
732
+ footer: ({ onClose }) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
733
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: onClose, variant: "tertiary", name: "cancel", children: formatMessage({
734
+ id: "content-releases.content-manager-edit-view.add-to-release.cancel-button",
735
+ defaultMessage: "Cancel"
736
+ }) }),
737
+ /* @__PURE__ */ jsxRuntime.jsx(
738
+ designSystem.Button,
989
739
  {
990
- handleClose: toggleModal,
991
- contentTypeUid,
992
- entryId
740
+ type: "submit",
741
+ onClick: (e) => handleSubmit(e, onClose),
742
+ disabled: !formik$1.values.releaseId,
743
+ loading: isLoading,
744
+ children: formatMessage({
745
+ id: "content-releases.content-manager-edit-view.add-to-release.continue-button",
746
+ defaultMessage: "Continue"
747
+ })
993
748
  }
994
749
  )
995
- ]
750
+ ] })
996
751
  }
997
- );
752
+ };
998
753
  };
999
754
  const getContentPermissions = (subject) => {
1000
755
  const permissions = {
@@ -1011,11 +766,11 @@ const getContentPermissions = (subject) => {
1011
766
  };
1012
767
  return permissions;
1013
768
  };
1014
- const ReleaseAction = ({ documentIds, model }) => {
769
+ const ReleaseAction = ({ documents, model }) => {
1015
770
  const { formatMessage } = reactIntl.useIntl();
1016
771
  const { toggleNotification } = strapiAdmin.useNotification();
1017
772
  const { formatAPIError } = strapiAdmin.useAPIErrorHandler();
1018
- const [{ query: query2 }] = strapiAdmin.useQueryParams();
773
+ const [{ query }] = strapiAdmin.useQueryParams();
1019
774
  const contentPermissions = getContentPermissions(model);
1020
775
  const {
1021
776
  allowedActions: { canPublish }
@@ -1026,16 +781,15 @@ const ReleaseAction = ({ documentIds, model }) => {
1026
781
  const response = useGetReleasesQuery();
1027
782
  const releases = response.data?.data;
1028
783
  const [createManyReleaseActions, { isLoading }] = useCreateManyReleaseActionsMutation();
784
+ const documentIds = documents.map((doc) => doc.documentId);
1029
785
  const handleSubmit = async (values) => {
1030
- const locale = query2.plugins?.i18n?.locale;
786
+ const locale = query.plugins?.i18n?.locale;
1031
787
  const releaseActionEntries = documentIds.map(
1032
- (id) => ({
788
+ (entryDocumentId) => ({
1033
789
  type: values.type,
1034
- entry: {
1035
- contentType: model,
1036
- id,
1037
- locale
1038
- }
790
+ contentType: model,
791
+ entryDocumentId,
792
+ locale
1039
793
  })
1040
794
  );
1041
795
  const response2 = await createManyReleaseActions({
@@ -1071,7 +825,7 @@ const ReleaseAction = ({ documentIds, model }) => {
1071
825
  return true;
1072
826
  }
1073
827
  if ("error" in response2) {
1074
- if (axios.isAxiosError(response2.error)) {
828
+ if (strapiAdmin.isFetchError(response2.error)) {
1075
829
  toggleNotification({
1076
830
  type: "warning",
1077
831
  message: formatAPIError(response2.error)
@@ -1084,8 +838,7 @@ const ReleaseAction = ({ documentIds, model }) => {
1084
838
  }
1085
839
  }
1086
840
  };
1087
- if (!canCreate || !canPublish)
1088
- return null;
841
+ if (!canCreate || !canPublish) return null;
1089
842
  return {
1090
843
  actionType: "release",
1091
844
  variant: "tertiary",
@@ -1112,25 +865,26 @@ const ReleaseAction = ({ documentIds, model }) => {
1112
865
  validationSchema: RELEASE_ACTION_FORM_SCHEMA,
1113
866
  initialValues: INITIAL_VALUES,
1114
867
  children: ({ values, setFieldValue }) => /* @__PURE__ */ jsxRuntime.jsxs(formik.Form, { children: [
1115
- releases?.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(NoReleases, {}) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.ModalBody, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
1116
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingBottom: 6, children: /* @__PURE__ */ jsxRuntime.jsx(
1117
- designSystem.SingleSelect,
1118
- {
1119
- required: true,
1120
- label: formatMessage({
1121
- id: "content-releases.content-manager-list-view.add-to-release.select-label",
1122
- defaultMessage: "Select a release"
1123
- }),
1124
- placeholder: formatMessage({
1125
- id: "content-releases.content-manager-list-view.add-to-release.select-placeholder",
1126
- defaultMessage: "Select"
1127
- }),
1128
- onChange: (value) => setFieldValue("releaseId", value),
1129
- value: values.releaseId,
1130
- children: releases?.map((release) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: release.id, children: release.name }, release.id))
1131
- }
1132
- ) }),
1133
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.FieldLabel, { children: formatMessage({
868
+ releases?.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(NoReleases, {}) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
869
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingBottom: 6, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { required: true, children: [
870
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
871
+ id: "content-releases.content-manager-list-view.add-to-release.select-label",
872
+ defaultMessage: "Select a release"
873
+ }) }),
874
+ /* @__PURE__ */ jsxRuntime.jsx(
875
+ designSystem.SingleSelect,
876
+ {
877
+ placeholder: formatMessage({
878
+ id: "content-releases.content-manager-list-view.add-to-release.select-placeholder",
879
+ defaultMessage: "Select"
880
+ }),
881
+ onChange: (value) => setFieldValue("releaseId", value),
882
+ value: values.releaseId,
883
+ children: releases?.map((release) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: release.id, children: release.name }, release.id))
884
+ }
885
+ )
886
+ ] }) }),
887
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
1134
888
  id: "content-releases.content-manager-list-view.add-to-release.action-type-label",
1135
889
  defaultMessage: "What do you want to do with these entries?"
1136
890
  }) }),
@@ -1143,25 +897,16 @@ const ReleaseAction = ({ documentIds, model }) => {
1143
897
  }
1144
898
  )
1145
899
  ] }) }),
1146
- /* @__PURE__ */ jsxRuntime.jsx(
1147
- designSystem.ModalFooter,
1148
- {
1149
- startActions: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: onClose, variant: "tertiary", name: "cancel", children: formatMessage({
1150
- id: "content-releases.content-manager-list-view.add-to-release.cancel-button",
1151
- defaultMessage: "Cancel"
1152
- }) }),
1153
- endActions: (
1154
- /**
1155
- * TODO: Ideally we would use isValid from Formik to disable the button, however currently it always returns true
1156
- * for yup.string().required(), even when the value is falsy (including empty string)
1157
- */
1158
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { type: "submit", disabled: !values.releaseId, loading: isLoading, children: formatMessage({
1159
- id: "content-releases.content-manager-list-view.add-to-release.continue-button",
1160
- defaultMessage: "Continue"
1161
- }) })
1162
- )
1163
- }
1164
- )
900
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
901
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: onClose, variant: "tertiary", name: "cancel", children: formatMessage({
902
+ id: "content-releases.content-manager-list-view.add-to-release.cancel-button",
903
+ defaultMessage: "Cancel"
904
+ }) }),
905
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { type: "submit", disabled: !values.releaseId, loading: isLoading, children: formatMessage({
906
+ id: "content-releases.content-manager-list-view.add-to-release.continue-button",
907
+ defaultMessage: "Continue"
908
+ }) })
909
+ ] })
1165
910
  ] })
1166
911
  }
1167
912
  );
@@ -1169,10 +914,386 @@ const ReleaseAction = ({ documentIds, model }) => {
1169
914
  }
1170
915
  };
1171
916
  };
1172
- const prefixPluginTranslations = (trad, pluginId2) => {
1173
- if (!pluginId2) {
1174
- throw new TypeError("pluginId can't be empty");
917
+ const useReleasesList = (contentTypeUid, documentId) => {
918
+ const listViewData = strapiAdmin.useTable("ListView", (state) => state.rows);
919
+ const documentIds = listViewData.map((entry) => entry.documentId);
920
+ const [{ query }] = strapiAdmin.useQueryParams();
921
+ const locale = query?.plugins?.i18n?.locale || void 0;
922
+ const response = useGetMappedEntriesInReleasesQuery(
923
+ { contentTypeUid, documentIds, locale },
924
+ { skip: !documentIds || !contentTypeUid || documentIds.length === 0 }
925
+ );
926
+ const mappedEntriesInReleases = response.data || {};
927
+ return mappedEntriesInReleases?.[documentId] || [];
928
+ };
929
+ const addColumnToTableHook = ({ displayedHeaders, layout }) => {
930
+ const { options } = layout;
931
+ if (!options?.draftAndPublish) {
932
+ return { displayedHeaders, layout };
933
+ }
934
+ return {
935
+ displayedHeaders: [
936
+ ...displayedHeaders,
937
+ {
938
+ searchable: false,
939
+ sortable: false,
940
+ name: "releases",
941
+ label: {
942
+ id: "content-releases.content-manager.list-view.releases.header",
943
+ defaultMessage: "To be released in"
944
+ },
945
+ cellFormatter: (props, _, { model }) => /* @__PURE__ */ jsxRuntime.jsx(ReleaseListCell, { ...props, model })
946
+ }
947
+ ],
948
+ layout
949
+ };
950
+ };
951
+ const ReleaseListCell = ({ documentId, model }) => {
952
+ const releases = useReleasesList(model, documentId);
953
+ const { formatMessage } = reactIntl.useIntl();
954
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Popover.Root, { children: [
955
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Popover.Trigger, { children: /* @__PURE__ */ jsxRuntime.jsx(
956
+ designSystem.Button,
957
+ {
958
+ variant: "ghost",
959
+ onClick: (e) => e.stopPropagation(),
960
+ endIcon: releases.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(icons.CaretDown, { width: "1.2rem", height: "1.2rem" }) : null,
961
+ children: /* @__PURE__ */ jsxRuntime.jsx(
962
+ designSystem.Typography,
963
+ {
964
+ style: { maxWidth: "252px", cursor: "pointer" },
965
+ textColor: "neutral800",
966
+ fontWeight: "regular",
967
+ children: releases.length > 0 ? formatMessage(
968
+ {
969
+ id: "content-releases.content-manager.list-view.releases-number",
970
+ defaultMessage: "{number} {number, plural, one {release} other {releases}}"
971
+ },
972
+ {
973
+ number: releases.length
974
+ }
975
+ ) : "-"
976
+ }
977
+ )
978
+ }
979
+ ) }),
980
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Popover.Content, { children: /* @__PURE__ */ jsxRuntime.jsx("ul", { children: releases.map(({ id, name }) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 3, tag: "li", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Link, { href: `/admin/plugins/content-releases/${id}`, isExternal: false, children: name }) }, id)) }) })
981
+ ] });
982
+ };
983
+ const getTimezoneOffset = (timezone, date) => {
984
+ try {
985
+ const offsetPart = new Intl.DateTimeFormat("en", {
986
+ timeZone: timezone,
987
+ timeZoneName: "longOffset"
988
+ }).formatToParts(date).find((part) => part.type === "timeZoneName");
989
+ const offset = offsetPart ? offsetPart.value : "";
990
+ let utcOffset = offset.replace("GMT", "UTC");
991
+ if (!utcOffset.includes("+") && !utcOffset.includes("-")) {
992
+ utcOffset = `${utcOffset}+00:00`;
993
+ }
994
+ return utcOffset;
995
+ } catch (error) {
996
+ return "";
997
+ }
998
+ };
999
+ const getTimezones = (selectedDate) => {
1000
+ const timezoneList = Intl.supportedValuesOf("timeZone").map((timezone) => {
1001
+ const utcOffset = getTimezoneOffset(timezone, selectedDate);
1002
+ return { offset: utcOffset, value: `${utcOffset}&${timezone}` };
1003
+ });
1004
+ const systemTimezone = timezoneList.find(
1005
+ (timezone) => timezone.value.split("&")[1] === Intl.DateTimeFormat().resolvedOptions().timeZone
1006
+ );
1007
+ return { timezoneList, systemTimezone };
1008
+ };
1009
+ const StyledMenuItem = styledComponents.styled(designSystem.Menu.Item)`
1010
+ &:hover {
1011
+ background: ${({ theme, $variant = "neutral" }) => theme.colors[`${$variant}100`]};
1012
+
1013
+ svg {
1014
+ fill: ${({ theme, $variant = "neutral" }) => theme.colors[`${$variant}600`]};
1015
+ }
1016
+
1017
+ a {
1018
+ color: ${({ theme }) => theme.colors.neutral800};
1019
+ }
1020
+ }
1021
+
1022
+ svg {
1023
+ color: ${({ theme, $variant = "neutral" }) => theme.colors[`${$variant}500`]};
1024
+ }
1025
+
1026
+ span {
1027
+ color: ${({ theme, $variant = "neutral" }) => theme.colors[`${$variant}800`]};
1028
+ }
1029
+
1030
+ span,
1031
+ a {
1032
+ width: 100%;
1033
+ }
1034
+ `;
1035
+ const DeleteReleaseActionItem = ({ releaseId, actionId }) => {
1036
+ const { formatMessage } = reactIntl.useIntl();
1037
+ const { toggleNotification } = strapiAdmin.useNotification();
1038
+ const { formatAPIError } = strapiAdmin.useAPIErrorHandler();
1039
+ const [deleteReleaseAction] = useDeleteReleaseActionMutation();
1040
+ const {
1041
+ allowedActions: { canDeleteAction }
1042
+ } = strapiAdmin.useRBAC(PERMISSIONS);
1043
+ const handleDeleteAction = async () => {
1044
+ const response = await deleteReleaseAction({
1045
+ params: { releaseId, actionId }
1046
+ });
1047
+ if ("data" in response) {
1048
+ toggleNotification({
1049
+ type: "success",
1050
+ message: formatMessage({
1051
+ id: "content-releases.content-manager-edit-view.remove-from-release.notification.success",
1052
+ defaultMessage: "Entry removed from release"
1053
+ })
1054
+ });
1055
+ return;
1056
+ }
1057
+ if ("error" in response) {
1058
+ if (strapiAdmin.isFetchError(response.error)) {
1059
+ toggleNotification({
1060
+ type: "danger",
1061
+ message: formatAPIError(response.error)
1062
+ });
1063
+ } else {
1064
+ toggleNotification({
1065
+ type: "danger",
1066
+ message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
1067
+ });
1068
+ }
1069
+ }
1070
+ };
1071
+ if (!canDeleteAction) {
1072
+ return null;
1073
+ }
1074
+ return /* @__PURE__ */ jsxRuntime.jsx(StyledMenuItem, { $variant: "danger", onSelect: handleDeleteAction, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
1075
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Cross, { width: "1.6rem", height: "1.6rem" }),
1076
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger600", variant: "omega", children: formatMessage({
1077
+ id: "content-releases.content-manager-edit-view.remove-from-release",
1078
+ defaultMessage: "Remove from release"
1079
+ }) })
1080
+ ] }) });
1081
+ };
1082
+ const ReleaseActionEntryLinkItem = ({
1083
+ contentTypeUid,
1084
+ documentId,
1085
+ locale
1086
+ }) => {
1087
+ const { formatMessage } = reactIntl.useIntl();
1088
+ const userPermissions = strapiAdmin.useAuth("ReleaseActionEntryLinkItem", (state) => state.permissions);
1089
+ const canUpdateEntryForLocale = React__namespace.useMemo(() => {
1090
+ const updatePermissions = userPermissions.find(
1091
+ (permission) => permission.subject === contentTypeUid && permission.action === "plugin::content-manager.explorer.update"
1092
+ );
1093
+ if (!updatePermissions) {
1094
+ return false;
1095
+ }
1096
+ return Boolean(!locale || updatePermissions.properties?.locales?.includes(locale));
1097
+ }, [contentTypeUid, locale, userPermissions]);
1098
+ const {
1099
+ allowedActions: { canUpdate: canUpdateContentType }
1100
+ } = strapiAdmin.useRBAC({
1101
+ updateContentType: [
1102
+ {
1103
+ action: "plugin::content-manager.explorer.update",
1104
+ subject: contentTypeUid
1105
+ }
1106
+ ]
1107
+ });
1108
+ if (!canUpdateContentType || !canUpdateEntryForLocale) {
1109
+ return null;
1110
+ }
1111
+ return /* @__PURE__ */ jsxRuntime.jsx(
1112
+ StyledMenuItem,
1113
+ {
1114
+ tag: reactRouterDom.NavLink,
1115
+ isLink: true,
1116
+ to: {
1117
+ pathname: `/content-manager/collection-types/${contentTypeUid}/${documentId}`,
1118
+ search: locale && `?plugins[i18n][locale]=${locale}`
1119
+ },
1120
+ children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
1121
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Pencil, { width: "1.6rem", height: "1.6rem" }),
1122
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: formatMessage({
1123
+ id: "content-releases.content-manager-edit-view.edit-entry",
1124
+ defaultMessage: "Edit entry"
1125
+ }) })
1126
+ ] })
1127
+ }
1128
+ );
1129
+ };
1130
+ const EditReleaseItem = ({ releaseId }) => {
1131
+ const { formatMessage } = reactIntl.useIntl();
1132
+ return (
1133
+ /* @ts-expect-error inference isn't working in DS */
1134
+ /* @__PURE__ */ jsxRuntime.jsx(StyledMenuItem, { tag: reactRouterDom.NavLink, isLink: true, to: `/plugins/content-releases/${releaseId}`, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
1135
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Pencil, { width: "1.6rem", height: "1.6rem" }),
1136
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", variant: "omega", children: formatMessage({
1137
+ id: "content-releases.content-manager-edit-view.edit-release",
1138
+ defaultMessage: "Edit release"
1139
+ }) })
1140
+ ] }) })
1141
+ );
1142
+ };
1143
+ const Root = ({ children }) => {
1144
+ const { formatMessage } = reactIntl.useIntl();
1145
+ const { allowedActions } = strapiAdmin.useRBAC(PERMISSIONS);
1146
+ return (
1147
+ // A user can access the dropdown if they have permissions to delete a release-action OR update a release
1148
+ allowedActions.canDeleteAction || allowedActions.canUpdate ? /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Root, { children: [
1149
+ /* @__PURE__ */ jsxRuntime.jsx(StyledMoreButton, { variant: "tertiary", endIcon: null, paddingLeft: "7px", paddingRight: "7px", children: /* @__PURE__ */ jsxRuntime.jsx(
1150
+ designSystem.AccessibleIcon,
1151
+ {
1152
+ label: formatMessage({
1153
+ id: "content-releases.content-manager-edit-view.release-action-menu",
1154
+ defaultMessage: "Release action options"
1155
+ }),
1156
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.More, {})
1157
+ }
1158
+ ) }),
1159
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Menu.Content, { top: 1, popoverPlacement: "bottom-end", children })
1160
+ ] }) : null
1161
+ );
1162
+ };
1163
+ const StyledMoreButton = styledComponents.styled(designSystem.Menu.Trigger)`
1164
+ & > span {
1165
+ display: flex;
1175
1166
  }
1167
+ `;
1168
+ const ReleaseActionMenu = {
1169
+ Root,
1170
+ EditReleaseItem,
1171
+ DeleteReleaseActionItem,
1172
+ ReleaseActionEntryLinkItem
1173
+ };
1174
+ const Panel = ({
1175
+ model,
1176
+ document,
1177
+ documentId,
1178
+ collectionType
1179
+ }) => {
1180
+ const [{ query }] = strapiAdmin.useQueryParams();
1181
+ const locale = query.plugins?.i18n?.locale;
1182
+ const {
1183
+ edit: { options }
1184
+ } = strapiAdmin$1.unstable_useDocumentLayout(model);
1185
+ const { formatMessage, formatDate, formatTime } = reactIntl.useIntl();
1186
+ const { allowedActions } = strapiAdmin.useRBAC(PERMISSIONS);
1187
+ const { canRead, canDeleteAction } = allowedActions;
1188
+ const response = useGetReleasesForEntryQuery(
1189
+ {
1190
+ contentType: model,
1191
+ entryDocumentId: documentId,
1192
+ locale,
1193
+ hasEntryAttached: true
1194
+ },
1195
+ {
1196
+ skip: !document
1197
+ }
1198
+ );
1199
+ const releases = response.data?.data;
1200
+ const getReleaseColorVariant = (actionType, shade) => {
1201
+ if (actionType === "unpublish") {
1202
+ return `secondary${shade}`;
1203
+ }
1204
+ return `success${shade}`;
1205
+ };
1206
+ if (!window.strapi.isEE || !options?.draftAndPublish || !canRead) {
1207
+ return null;
1208
+ }
1209
+ if (collectionType === "collection-types" && (!documentId || documentId === "create")) {
1210
+ return null;
1211
+ }
1212
+ if (!releases || releases.length === 0) {
1213
+ return null;
1214
+ }
1215
+ return {
1216
+ title: formatMessage({
1217
+ id: "content-releases.plugin.name",
1218
+ defaultMessage: "Releases"
1219
+ }),
1220
+ content: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 3, width: "100%", children: releases?.map((release) => /* @__PURE__ */ jsxRuntime.jsxs(
1221
+ designSystem.Flex,
1222
+ {
1223
+ direction: "column",
1224
+ alignItems: "start",
1225
+ borderWidth: "1px",
1226
+ borderStyle: "solid",
1227
+ borderColor: getReleaseColorVariant(release.actions[0].type, "200"),
1228
+ overflow: "hidden",
1229
+ hasRadius: true,
1230
+ children: [
1231
+ /* @__PURE__ */ jsxRuntime.jsx(
1232
+ designSystem.Box,
1233
+ {
1234
+ paddingTop: 3,
1235
+ paddingBottom: 3,
1236
+ paddingLeft: 4,
1237
+ paddingRight: 4,
1238
+ background: getReleaseColorVariant(release.actions[0].type, "100"),
1239
+ width: "100%",
1240
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1241
+ designSystem.Typography,
1242
+ {
1243
+ fontSize: 1,
1244
+ variant: "pi",
1245
+ textColor: getReleaseColorVariant(release.actions[0].type, "600"),
1246
+ children: formatMessage(
1247
+ {
1248
+ id: "content-releases.content-manager-edit-view.list-releases.title",
1249
+ defaultMessage: "{isPublish, select, true {Will be published in} other {Will be unpublished in}}"
1250
+ },
1251
+ { isPublish: release.actions[0].type === "publish" }
1252
+ )
1253
+ }
1254
+ )
1255
+ }
1256
+ ),
1257
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { padding: 4, direction: "column", gap: 2, width: "100%", alignItems: "flex-start", children: [
1258
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontSize: 2, fontWeight: "bold", variant: "omega", textColor: "neutral700", children: release.name }),
1259
+ release.scheduledAt && release.timezone && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: formatMessage(
1260
+ {
1261
+ id: "content-releases.content-manager-edit-view.scheduled.date",
1262
+ defaultMessage: "{date} at {time} ({offset})"
1263
+ },
1264
+ {
1265
+ date: formatDate(new Date(release.scheduledAt), {
1266
+ day: "2-digit",
1267
+ month: "2-digit",
1268
+ year: "numeric",
1269
+ timeZone: release.timezone
1270
+ }),
1271
+ time: formatTime(new Date(release.scheduledAt), {
1272
+ hourCycle: "h23",
1273
+ timeZone: release.timezone
1274
+ }),
1275
+ offset: getTimezoneOffset(release.timezone, new Date(release.scheduledAt))
1276
+ }
1277
+ ) }),
1278
+ canDeleteAction ? /* @__PURE__ */ jsxRuntime.jsxs(ReleaseActionMenu.Root, { hasTriggerBorder: true, children: [
1279
+ /* @__PURE__ */ jsxRuntime.jsx(ReleaseActionMenu.EditReleaseItem, { releaseId: release.id }),
1280
+ /* @__PURE__ */ jsxRuntime.jsx(
1281
+ ReleaseActionMenu.DeleteReleaseActionItem,
1282
+ {
1283
+ releaseId: release.id,
1284
+ actionId: release.actions[0].id
1285
+ }
1286
+ )
1287
+ ] }) : null
1288
+ ] })
1289
+ ]
1290
+ },
1291
+ release.id
1292
+ )) })
1293
+ };
1294
+ };
1295
+ const pluginId = "content-releases";
1296
+ const prefixPluginTranslations = (trad, pluginId2) => {
1176
1297
  return Object.keys(trad).reduce((acc, current) => {
1177
1298
  acc[`${pluginId2}.${current}`] = trad[current];
1178
1299
  return acc;
@@ -1190,43 +1311,63 @@ const admin = {
1190
1311
  id: `${pluginId}.plugin.name`,
1191
1312
  defaultMessage: "Releases"
1192
1313
  },
1193
- Component: () => Promise.resolve().then(() => require("./App-CXRpb2hi.js")).then((mod) => ({ default: mod.App })),
1194
- permissions: PERMISSIONS.main
1195
- });
1196
- app.addMiddlewares([() => releaseApi.middleware]);
1197
- app.addReducers({
1198
- [releaseApi.reducerPath]: releaseApi.reducer
1199
- });
1200
- app.getPlugin("content-manager").injectComponent("editView", "right-links", {
1201
- name: `${pluginId}-link`,
1202
- Component: CMReleasesContainer
1314
+ Component: () => Promise.resolve().then(() => require("./App-SGjO5UPV.js")).then((mod) => ({ default: mod.App })),
1315
+ permissions: PERMISSIONS.main,
1316
+ position: 2
1203
1317
  });
1204
- app.plugins["content-manager"].apis.addBulkAction((actions) => {
1205
- const deleteActionIndex = actions.findIndex((action) => action.name === "DeleteAction");
1206
- actions.splice(deleteActionIndex, 0, ReleaseAction);
1207
- return actions;
1318
+ const contentManagerPluginApis = app.getPlugin("content-manager").apis;
1319
+ if ("addEditViewSidePanel" in contentManagerPluginApis && typeof contentManagerPluginApis.addEditViewSidePanel === "function") {
1320
+ contentManagerPluginApis.addEditViewSidePanel([Panel]);
1321
+ }
1322
+ if ("addDocumentAction" in contentManagerPluginApis && typeof contentManagerPluginApis.addDocumentAction === "function") {
1323
+ contentManagerPluginApis.addDocumentAction((actions) => {
1324
+ const indexOfDeleteAction = actions.findIndex((action) => action.type === "unpublish");
1325
+ actions.splice(indexOfDeleteAction, 0, ReleaseActionModalForm);
1326
+ return actions;
1327
+ });
1328
+ }
1329
+ app.addSettingsLink("global", {
1330
+ id: pluginId,
1331
+ to: "releases",
1332
+ intlLabel: {
1333
+ id: `${pluginId}.plugin.name`,
1334
+ defaultMessage: "Releases"
1335
+ },
1336
+ permissions: [],
1337
+ async Component() {
1338
+ const { ProtectedReleasesSettingsPage } = await Promise.resolve().then(() => require("./ReleasesSettingsPage-Cto_NLUd.js"));
1339
+ return { default: ProtectedReleasesSettingsPage };
1340
+ }
1208
1341
  });
1342
+ if ("addBulkAction" in contentManagerPluginApis && typeof contentManagerPluginApis.addBulkAction === "function") {
1343
+ contentManagerPluginApis.addBulkAction((actions) => {
1344
+ const deleteActionIndex = actions.findIndex((action) => action.type === "delete");
1345
+ actions.splice(deleteActionIndex, 0, ReleaseAction);
1346
+ return actions;
1347
+ });
1348
+ }
1349
+ app.registerHook("Admin/CM/pages/ListView/inject-column-in-table", addColumnToTableHook);
1209
1350
  } else if (!window.strapi.features.isEnabled("cms-content-releases") && window.strapi?.flags?.promoteEE) {
1210
- app.addMenuLink({
1211
- to: `/plugins/purchase-content-releases`,
1212
- icon: icons.PaperPlane,
1351
+ app.addSettingsLink("global", {
1352
+ id: pluginId,
1353
+ to: "/plugins/purchase-content-releases",
1213
1354
  intlLabel: {
1214
1355
  id: `${pluginId}.plugin.name`,
1215
1356
  defaultMessage: "Releases"
1216
1357
  },
1217
1358
  permissions: [],
1218
1359
  async Component() {
1219
- const { PurchaseContentReleases } = await Promise.resolve().then(() => require("./PurchaseContentReleases-Be3acS2L.js"));
1360
+ const { PurchaseContentReleases } = await Promise.resolve().then(() => require("./PurchaseContentReleases--qQepXpP.js"));
1220
1361
  return { default: PurchaseContentReleases };
1221
1362
  },
1222
- lockIcon: true
1363
+ licenseOnly: true
1223
1364
  });
1224
1365
  }
1225
1366
  },
1226
1367
  async registerTrads({ locales }) {
1227
1368
  const importedTrads = await Promise.all(
1228
1369
  locales.map((locale) => {
1229
- return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => Promise.resolve().then(() => require("./en-DtFJ5ViE.js")) }), `./translations/${locale}.json`).then(({ default: data }) => {
1370
+ return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => Promise.resolve().then(() => require("./en-BWPPsSH-.js")) }), `./translations/${locale}.json`, 3).then(({ default: data }) => {
1230
1371
  return {
1231
1372
  data: prefixPluginTranslations(data, "content-releases"),
1232
1373
  locale
@@ -1247,15 +1388,17 @@ exports.ReleaseActionMenu = ReleaseActionMenu;
1247
1388
  exports.ReleaseActionOptions = ReleaseActionOptions;
1248
1389
  exports.admin = admin;
1249
1390
  exports.getTimezoneOffset = getTimezoneOffset;
1250
- exports.isAxiosError = isAxiosError;
1391
+ exports.getTimezones = getTimezones;
1251
1392
  exports.pluginId = pluginId;
1252
1393
  exports.releaseApi = releaseApi;
1253
1394
  exports.useCreateReleaseMutation = useCreateReleaseMutation;
1254
1395
  exports.useDeleteReleaseMutation = useDeleteReleaseMutation;
1255
1396
  exports.useGetReleaseActionsQuery = useGetReleaseActionsQuery;
1256
1397
  exports.useGetReleaseQuery = useGetReleaseQuery;
1398
+ exports.useGetReleaseSettingsQuery = useGetReleaseSettingsQuery;
1257
1399
  exports.useGetReleasesQuery = useGetReleasesQuery;
1258
1400
  exports.usePublishReleaseMutation = usePublishReleaseMutation;
1259
1401
  exports.useUpdateReleaseActionMutation = useUpdateReleaseActionMutation;
1260
1402
  exports.useUpdateReleaseMutation = useUpdateReleaseMutation;
1261
- //# sourceMappingURL=index-B6-lic1Q.js.map
1403
+ exports.useUpdateReleaseSettingsMutation = useUpdateReleaseSettingsMutation;
1404
+ //# sourceMappingURL=index-CyU534vL.js.map