@strapi/content-releases 0.0.0-experimental.d23c1d5b0e45dd06ef09977f526c85468be05403 → 0.0.0-experimental.d325780feab1caf1b9e4423588eb1cc73b74c376

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 (111) hide show
  1. package/LICENSE +17 -1
  2. package/dist/_chunks/{App-Cmn2Mkn7.mjs → App-CiZCkScI.mjs} +651 -436
  3. package/dist/_chunks/App-CiZCkScI.mjs.map +1 -0
  4. package/dist/_chunks/{App-FVorrIzF.js → App-SGjO5UPV.js} +687 -475
  5. package/dist/_chunks/App-SGjO5UPV.js.map +1 -0
  6. package/dist/_chunks/{PurchaseContentReleases-sD6ADHk2.js → PurchaseContentReleases--qQepXpP.js} +8 -7
  7. package/dist/_chunks/PurchaseContentReleases--qQepXpP.js.map +1 -0
  8. package/dist/_chunks/{PurchaseContentReleases-C8djn9fP.mjs → PurchaseContentReleases-D-n-w-st.mjs} +9 -8
  9. package/dist/_chunks/PurchaseContentReleases-D-n-w-st.mjs.map +1 -0
  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-DDohgTaQ.mjs → index-BjvFfTtA.mjs} +752 -611
  19. package/dist/_chunks/index-BjvFfTtA.mjs.map +1 -0
  20. package/dist/_chunks/{index-BfJLth9Z.js → index-CyU534vL.js} +745 -607
  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/ReleaseAction.d.ts +1 -1
  30. package/dist/admin/src/components/ReleaseActionMenu.d.ts +3 -3
  31. package/dist/admin/src/components/{CMReleasesContainer.d.ts → ReleaseActionModal.d.ts} +3 -1
  32. package/dist/admin/src/components/ReleaseListCell.d.ts +28 -0
  33. package/dist/admin/src/components/ReleaseModal.d.ts +3 -2
  34. package/dist/admin/src/components/ReleasesPanel.d.ts +3 -0
  35. package/dist/admin/src/constants.d.ts +18 -0
  36. package/dist/admin/src/modules/hooks.d.ts +7 -0
  37. package/dist/admin/src/pages/ReleasesSettingsPage.d.ts +1 -0
  38. package/dist/admin/src/services/release.d.ts +53 -370
  39. package/dist/admin/src/utils/api.d.ts +6 -0
  40. package/dist/admin/src/utils/time.d.ts +9 -0
  41. package/dist/admin/src/validation/schemas.d.ts +6 -0
  42. package/dist/server/index.js +889 -614
  43. package/dist/server/index.js.map +1 -1
  44. package/dist/server/index.mjs +889 -613
  45. package/dist/server/index.mjs.map +1 -1
  46. package/dist/server/src/bootstrap.d.ts.map +1 -1
  47. package/dist/server/src/constants.d.ts +11 -2
  48. package/dist/server/src/constants.d.ts.map +1 -1
  49. package/dist/server/src/content-types/index.d.ts +3 -5
  50. package/dist/server/src/content-types/index.d.ts.map +1 -1
  51. package/dist/server/src/content-types/release-action/index.d.ts +3 -5
  52. package/dist/server/src/content-types/release-action/index.d.ts.map +1 -1
  53. package/dist/server/src/content-types/release-action/schema.d.ts +3 -5
  54. package/dist/server/src/content-types/release-action/schema.d.ts.map +1 -1
  55. package/dist/server/src/controllers/index.d.ts +6 -1
  56. package/dist/server/src/controllers/index.d.ts.map +1 -1
  57. package/dist/server/src/controllers/release-action.d.ts.map +1 -1
  58. package/dist/server/src/controllers/release.d.ts +7 -1
  59. package/dist/server/src/controllers/release.d.ts.map +1 -1
  60. package/dist/server/src/controllers/settings.d.ts +11 -0
  61. package/dist/server/src/controllers/settings.d.ts.map +1 -0
  62. package/dist/server/src/controllers/validation/release-action.d.ts +7 -1
  63. package/dist/server/src/controllers/validation/release-action.d.ts.map +1 -1
  64. package/dist/server/src/controllers/validation/release.d.ts +2 -0
  65. package/dist/server/src/controllers/validation/release.d.ts.map +1 -1
  66. package/dist/server/src/controllers/validation/settings.d.ts +3 -0
  67. package/dist/server/src/controllers/validation/settings.d.ts.map +1 -0
  68. package/dist/server/src/index.d.ts +64 -49
  69. package/dist/server/src/index.d.ts.map +1 -1
  70. package/dist/server/src/middlewares/documents.d.ts +6 -0
  71. package/dist/server/src/middlewares/documents.d.ts.map +1 -0
  72. package/dist/server/src/migrations/database/5.0.0-document-id-in-actions.d.ts +9 -0
  73. package/dist/server/src/migrations/database/5.0.0-document-id-in-actions.d.ts.map +1 -0
  74. package/dist/server/src/migrations/index.d.ts.map +1 -1
  75. package/dist/server/src/register.d.ts.map +1 -1
  76. package/dist/server/src/routes/index.d.ts +16 -0
  77. package/dist/server/src/routes/index.d.ts.map +1 -1
  78. package/dist/server/src/routes/release.d.ts.map +1 -1
  79. package/dist/server/src/routes/settings.d.ts +18 -0
  80. package/dist/server/src/routes/settings.d.ts.map +1 -0
  81. package/dist/server/src/services/index.d.ts +36 -38
  82. package/dist/server/src/services/index.d.ts.map +1 -1
  83. package/dist/server/src/services/release-action.d.ts +34 -0
  84. package/dist/server/src/services/release-action.d.ts.map +1 -0
  85. package/dist/server/src/services/release.d.ts +6 -41
  86. package/dist/server/src/services/release.d.ts.map +1 -1
  87. package/dist/server/src/services/settings.d.ts +13 -0
  88. package/dist/server/src/services/settings.d.ts.map +1 -0
  89. package/dist/server/src/services/validation.d.ts +1 -1
  90. package/dist/server/src/services/validation.d.ts.map +1 -1
  91. package/dist/server/src/utils/index.d.ts +29 -8
  92. package/dist/server/src/utils/index.d.ts.map +1 -1
  93. package/dist/shared/contracts/release-actions.d.ts +17 -11
  94. package/dist/shared/contracts/release-actions.d.ts.map +1 -1
  95. package/dist/shared/contracts/releases.d.ts +9 -7
  96. package/dist/shared/contracts/releases.d.ts.map +1 -1
  97. package/dist/shared/contracts/settings.d.ts +39 -0
  98. package/dist/shared/contracts/settings.d.ts.map +1 -0
  99. package/package.json +24 -24
  100. package/dist/_chunks/App-Cmn2Mkn7.mjs.map +0 -1
  101. package/dist/_chunks/App-FVorrIzF.js.map +0 -1
  102. package/dist/_chunks/PurchaseContentReleases-C8djn9fP.mjs.map +0 -1
  103. package/dist/_chunks/PurchaseContentReleases-sD6ADHk2.js.map +0 -1
  104. package/dist/_chunks/en-B9Ur3VsE.mjs.map +0 -1
  105. package/dist/_chunks/en-DtFJ5ViE.js.map +0 -1
  106. package/dist/_chunks/index-BfJLth9Z.js.map +0 -1
  107. package/dist/_chunks/index-DDohgTaQ.mjs.map +0 -1
  108. package/dist/admin/src/services/axios.d.ts +0 -29
  109. package/dist/shared/validation-schemas.d.ts +0 -2
  110. package/dist/shared/validation-schemas.d.ts.map +0 -1
  111. 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
5
  const designSystem = require("@strapi/design-system");
8
- const v2 = require("@strapi/design-system/v2");
9
- const strapiAdmin$1 = require("@strapi/plugin-content-manager/strapi-admin");
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,205 +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(v2.Menu.Item)`
403
- &:hover {
404
- background: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}100`]};
405
-
406
- svg {
407
- path {
408
- fill: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}600`]};
409
- }
410
- }
411
-
412
- a {
413
- color: ${({ theme }) => theme.colors.neutral800};
414
- }
415
- }
416
-
417
- svg {
418
- path {
419
- fill: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}600`]};
420
- }
421
- }
422
-
423
- a {
424
- color: ${({ theme }) => theme.colors.neutral800};
425
- }
426
-
427
- span,
428
- a {
429
- width: 100%;
430
- }
431
- `;
432
- const StyledIconButton = styled__default.default(designSystem.IconButton)`
433
- /* Setting this style inline with borderColor will not apply the style */
434
- border: ${({ theme }) => `1px solid ${theme.colors.neutral200}`};
435
- `;
436
- const DeleteReleaseActionItem = ({ releaseId, actionId }) => {
437
- const { formatMessage } = reactIntl.useIntl();
438
- const { toggleNotification } = strapiAdmin.useNotification();
439
- const { formatAPIError } = strapiAdmin.useAPIErrorHandler();
440
- const [deleteReleaseAction] = useDeleteReleaseActionMutation();
441
- const {
442
- allowedActions: { canDeleteAction }
443
- } = strapiAdmin.useRBAC(PERMISSIONS);
444
- const handleDeleteAction = async () => {
445
- const response = await deleteReleaseAction({
446
- params: { releaseId, actionId }
447
- });
448
- if ("data" in response) {
449
- toggleNotification({
450
- type: "success",
451
- message: formatMessage({
452
- id: "content-releases.content-manager-edit-view.remove-from-release.notification.success",
453
- defaultMessage: "Entry removed from release"
454
- })
455
- });
456
- return;
457
- }
458
- if ("error" in response) {
459
- if (axios.isAxiosError(response.error)) {
460
- toggleNotification({
461
- type: "danger",
462
- message: formatAPIError(response.error)
463
- });
464
- } else {
465
- toggleNotification({
466
- type: "danger",
467
- message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
468
- });
469
- }
470
- }
471
- };
472
- if (!canDeleteAction) {
473
- return null;
474
- }
475
- return /* @__PURE__ */ jsxRuntime.jsx(StyledMenuItem, { variant: "danger", onSelect: handleDeleteAction, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
476
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Icon, { as: icons.Cross, width: 3, height: 3 }),
477
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger600", variant: "omega", children: formatMessage({
478
- id: "content-releases.content-manager-edit-view.remove-from-release",
479
- defaultMessage: "Remove from release"
480
- }) })
481
- ] }) });
482
- };
483
- const ReleaseActionEntryLinkItem = ({
484
- contentTypeUid,
485
- entryId,
486
- locale
487
- }) => {
488
- const { formatMessage } = reactIntl.useIntl();
489
- const userPermissions = strapiAdmin.useAuth("ReleaseActionEntryLinkItem", (state) => state.permissions);
490
- const canUpdateEntryForLocale = React__namespace.useMemo(() => {
491
- const updatePermissions = userPermissions.find(
492
- (permission) => permission.subject === contentTypeUid && permission.action === "plugin::content-manager.explorer.update"
493
- );
494
- if (!updatePermissions) {
495
- return false;
496
- }
497
- return Boolean(!locale || updatePermissions.properties?.locales?.includes(locale));
498
- }, [contentTypeUid, locale, userPermissions]);
499
- const {
500
- allowedActions: { canUpdate: canUpdateContentType }
501
- } = strapiAdmin.useRBAC({
502
- updateContentType: [
503
- {
504
- action: "plugin::content-manager.explorer.update",
505
- subject: contentTypeUid
506
- }
507
- ]
508
- });
509
- if (!canUpdateContentType || !canUpdateEntryForLocale) {
510
- return null;
511
- }
512
- return /* @__PURE__ */ jsxRuntime.jsx(StyledMenuItem, { children: /* @__PURE__ */ jsxRuntime.jsx(
513
- v2.Link,
514
- {
515
- as: reactRouterDom.NavLink,
516
- to: {
517
- pathname: `/content-manager/collection-types/${contentTypeUid}/${entryId}`,
518
- search: locale && `?plugins[i18n][locale]=${locale}`
519
- },
520
- startIcon: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Icon, { as: icons.Pencil, width: 3, height: 3 }),
521
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: formatMessage({
522
- id: "content-releases.content-manager-edit-view.edit-entry",
523
- defaultMessage: "Edit entry"
524
- }) })
525
- }
526
- ) });
527
- };
528
- const EditReleaseItem = ({ releaseId }) => {
529
- const { formatMessage } = reactIntl.useIntl();
530
- return /* @__PURE__ */ jsxRuntime.jsx(StyledMenuItem, { children: /* @__PURE__ */ jsxRuntime.jsx(
531
- v2.Link,
532
- {
533
- href: `/admin/plugins/content-releases/${releaseId}`,
534
- startIcon: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Icon, { as: icons.Pencil, width: 3, height: 3 }),
535
- isExternal: false,
536
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: formatMessage({
537
- id: "content-releases.content-manager-edit-view.edit-release",
538
- defaultMessage: "Edit release"
539
- }) })
540
- }
541
- ) });
542
- };
543
- const Root = ({ children, hasTriggerBorder = false }) => {
544
- const { formatMessage } = reactIntl.useIntl();
545
- const { allowedActions } = strapiAdmin.useRBAC(PERMISSIONS);
546
- return (
547
- // A user can access the dropdown if they have permissions to delete a release-action OR update a release
548
- allowedActions.canDeleteAction || allowedActions.canUpdate ? /* @__PURE__ */ jsxRuntime.jsxs(v2.Menu.Root, { children: [
549
- /* @__PURE__ */ jsxRuntime.jsx(
550
- v2.Menu.Trigger,
551
- {
552
- as: hasTriggerBorder ? StyledIconButton : designSystem.IconButton,
553
- paddingLeft: 2,
554
- paddingRight: 2,
555
- "aria-label": formatMessage({
556
- id: "content-releases.content-manager-edit-view.release-action-menu",
557
- defaultMessage: "Release action options"
558
- }),
559
- icon: /* @__PURE__ */ jsxRuntime.jsx(icons.More, {})
560
- }
561
- ),
562
- /* @__PURE__ */ jsxRuntime.jsx(v2.Menu.Content, { top: 1, popoverPlacement: "bottom-end", children })
563
- ] }) : null
564
- );
565
- };
566
- const ReleaseActionMenu = {
567
- Root,
568
- EditReleaseItem,
569
- DeleteReleaseActionItem,
570
- ReleaseActionEntryLinkItem
571
- };
572
432
  const getBorderLeftRadiusValue = (actionType) => {
573
433
  return actionType === "publish" ? 1 : 0;
574
434
  };
575
435
  const getBorderRightRadiusValue = (actionType) => {
576
436
  return actionType === "publish" ? 0 : 1;
577
437
  };
578
- const FieldWrapper = styled__default.default(designSystem.Field)`
579
- border-top-left-radius: ${({ actionType, theme }) => theme.spaces[getBorderLeftRadiusValue(actionType)]};
580
- border-bottom-left-radius: ${({ actionType, theme }) => theme.spaces[getBorderLeftRadiusValue(actionType)]};
581
- border-top-right-radius: ${({ actionType, theme }) => theme.spaces[getBorderRightRadiusValue(actionType)]};
582
- 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)]};
583
443
 
584
444
  > label {
585
445
  color: inherit;
@@ -590,14 +450,14 @@ const FieldWrapper = styled__default.default(designSystem.Field)`
590
450
  }
591
451
 
592
452
  &[data-checked='true'] {
593
- color: ${({ theme, actionType }) => actionType === "publish" ? theme.colors.primary700 : theme.colors.danger600};
594
- background-color: ${({ theme, actionType }) => actionType === "publish" ? theme.colors.primary100 : theme.colors.danger100};
595
- 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};
596
456
  }
597
457
 
598
458
  &[data-checked='false'] {
599
- border-left: ${({ actionType }) => actionType === "unpublish" && "none"};
600
- border-right: ${({ actionType }) => actionType === "publish" && "none"};
459
+ border-left: ${({ $actionType }) => $actionType === "unpublish" && "none"};
460
+ border-right: ${({ $actionType }) => $actionType === "publish" && "none"};
601
461
  }
602
462
 
603
463
  &[data-checked='false'][data-disabled='false']:hover {
@@ -626,7 +486,7 @@ const ActionOption = ({
626
486
  return /* @__PURE__ */ jsxRuntime.jsx(
627
487
  FieldWrapper,
628
488
  {
629
- actionType,
489
+ $actionType: actionType,
630
490
  background: "primary0",
631
491
  borderColor: "neutral200",
632
492
  color: selected === actionType ? "primary600" : "neutral600",
@@ -634,12 +494,11 @@ const ActionOption = ({
634
494
  cursor: "pointer",
635
495
  "data-checked": selected === actionType,
636
496
  "data-disabled": disabled && selected !== actionType,
637
- children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.FieldLabel, { htmlFor: `${name}-${actionType}`, children: [
497
+ children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Label, { children: [
638
498
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { children: /* @__PURE__ */ jsxRuntime.jsx(
639
- designSystem.FieldInput,
499
+ designSystem.Field.Input,
640
500
  {
641
501
  type: "radio",
642
- id: `${name}-${actionType}`,
643
502
  name,
644
503
  checked: selected === actionType,
645
504
  onChange: handleChange,
@@ -694,312 +553,203 @@ const NoReleases = () => {
694
553
  return /* @__PURE__ */ jsxRuntime.jsx(
695
554
  designSystem.EmptyStateLayout,
696
555
  {
697
- icon: /* @__PURE__ */ jsxRuntime.jsx(icons.EmptyDocuments, { width: "10rem" }),
556
+ icon: /* @__PURE__ */ jsxRuntime.jsx(symbols.EmptyDocuments, { width: "16rem" }),
698
557
  content: formatMessage({
699
558
  id: "content-releases.content-manager-edit-view.add-to-release.no-releases-message",
700
559
  defaultMessage: "No available releases. Open the list of releases and create a new one from there."
701
560
  }),
702
561
  action: /* @__PURE__ */ jsxRuntime.jsx(
703
- v2.LinkButton,
562
+ designSystem.LinkButton,
704
563
  {
705
564
  to: {
706
565
  pathname: "/plugins/content-releases"
707
566
  },
708
- as: reactRouterDom.Link,
567
+ tag: reactRouterDom.Link,
709
568
  variant: "secondary",
710
569
  children: formatMessage({
711
570
  id: "content-releases.content-manager-edit-view.add-to-release.redirect-button",
712
571
  defaultMessage: "Open the list of releases"
713
572
  })
714
573
  }
715
- )
574
+ ),
575
+ shadow: "none"
716
576
  }
717
577
  );
718
578
  };
719
579
  const AddActionToReleaseModal = ({
720
- handleClose,
721
- contentTypeUid,
722
- entryId
580
+ contentType,
581
+ documentId,
582
+ onInputChange,
583
+ values
723
584
  }) => {
724
- const releaseHeaderId = React__namespace.useId();
725
585
  const { formatMessage } = reactIntl.useIntl();
726
- const { toggleNotification } = strapiAdmin.useNotification();
727
- const { formatAPIError } = strapiAdmin.useAPIErrorHandler();
728
- const [{ query: query2 }] = strapiAdmin.useQueryParams();
729
- const locale = query2.plugins?.i18n?.locale;
586
+ const [{ query }] = strapiAdmin.useQueryParams();
587
+ const locale = query.plugins?.i18n?.locale;
730
588
  const response = useGetReleasesForEntryQuery({
731
- contentTypeUid,
732
- entryId,
733
- hasEntryAttached: false
589
+ contentType,
590
+ entryDocumentId: documentId,
591
+ hasEntryAttached: false,
592
+ locale
734
593
  });
735
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;
736
642
  const [createReleaseAction, { isLoading }] = useCreateReleaseActionMutation();
737
- const handleSubmit = async (values) => {
738
- const releaseActionEntry = {
739
- contentType: contentTypeUid,
740
- id: entryId,
741
- locale
742
- };
743
- const response2 = await createReleaseAction({
744
- body: { type: values.type, entry: releaseActionEntry },
745
- params: { releaseId: values.releaseId }
746
- });
747
- if ("data" in response2) {
748
- toggleNotification({
749
- type: "success",
750
- message: formatMessage({
751
- id: "content-releases.content-manager-edit-view.add-to-release.notification.success",
752
- defaultMessage: "Entry added to release"
753
- })
754
- });
755
- handleClose();
756
- return;
757
- }
758
- if ("error" in response2) {
759
- 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)) {
760
653
  toggleNotification({
761
654
  type: "danger",
762
- message: formatAPIError(response2.error)
655
+ message: formatAPIError(error)
763
656
  });
764
657
  } else {
765
658
  toggleNotification({
766
659
  type: "danger",
767
- message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
660
+ message: formatMessage({
661
+ id: "notification.error",
662
+ defaultMessage: "An error occurred"
663
+ })
768
664
  });
769
665
  }
770
666
  }
771
667
  };
772
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.ModalLayout, { onClose: handleClose, labelledBy: releaseHeaderId, children: [
773
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.ModalHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: releaseHeaderId, fontWeight: "bold", textColor: "neutral800", children: formatMessage({
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");
674
+ }
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
+ }
698
+ });
699
+ const {
700
+ edit: { options }
701
+ } = strapiAdmin$1.unstable_useDocumentLayout(model);
702
+ if (!window.strapi.isEE || !options?.draftAndPublish || !canCreateAction) {
703
+ return null;
704
+ }
705
+ if (collectionType === "collection-types" && (!documentId || documentId === "create")) {
706
+ return null;
707
+ }
708
+ return {
709
+ label: formatMessage({
774
710
  id: "content-releases.content-manager-edit-view.add-to-release",
775
711
  defaultMessage: "Add to release"
776
- }) }) }),
777
- /* @__PURE__ */ jsxRuntime.jsx(
778
- formik.Formik,
779
- {
780
- onSubmit: handleSubmit,
781
- validationSchema: RELEASE_ACTION_FORM_SCHEMA,
782
- initialValues: INITIAL_VALUES,
783
- children: ({ values, setFieldValue }) => {
784
- return /* @__PURE__ */ jsxRuntime.jsxs(formik.Form, { children: [
785
- 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: [
786
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingBottom: 6, children: /* @__PURE__ */ jsxRuntime.jsx(
787
- designSystem.SingleSelect,
788
- {
789
- required: true,
790
- label: formatMessage({
791
- id: "content-releases.content-manager-edit-view.add-to-release.select-label",
792
- defaultMessage: "Select a release"
793
- }),
794
- placeholder: formatMessage({
795
- id: "content-releases.content-manager-edit-view.add-to-release.select-placeholder",
796
- defaultMessage: "Select"
797
- }),
798
- onChange: (value) => setFieldValue("releaseId", value),
799
- value: values.releaseId,
800
- children: releases?.map((release) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: release.id, children: release.name }, release.id))
801
- }
802
- ) }),
803
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.FieldLabel, { children: formatMessage({
804
- id: "content-releases.content-manager-edit-view.add-to-release.action-type-label",
805
- defaultMessage: "What do you want to do with this entry?"
806
- }) }),
807
- /* @__PURE__ */ jsxRuntime.jsx(
808
- ReleaseActionOptions,
809
- {
810
- selected: values.type,
811
- handleChange: (e) => setFieldValue("type", e.target.value),
812
- name: "type"
813
- }
814
- )
815
- ] }) }),
816
- /* @__PURE__ */ jsxRuntime.jsx(
817
- designSystem.ModalFooter,
818
- {
819
- startActions: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleClose, variant: "tertiary", name: "cancel", children: formatMessage({
820
- id: "content-releases.content-manager-edit-view.add-to-release.cancel-button",
821
- defaultMessage: "Cancel"
822
- }) }),
823
- endActions: (
824
- /**
825
- * TODO: Ideally we would use isValid from Formik to disable the button, however currently it always returns true
826
- * for yup.string().required(), even when the value is falsy (including empty string)
827
- */
828
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { type: "submit", disabled: !values.releaseId, loading: isLoading, children: formatMessage({
829
- id: "content-releases.content-manager-edit-view.add-to-release.continue-button",
830
- defaultMessage: "Continue"
831
- }) })
832
- )
833
- }
834
- )
835
- ] });
836
- }
837
- }
838
- )
839
- ] });
840
- };
841
- const CMReleasesContainer = () => {
842
- const [isModalOpen, setIsModalOpen] = React__namespace.useState(false);
843
- const { formatMessage, formatDate, formatTime } = reactIntl.useIntl();
844
- const { id, slug, collectionType } = reactRouterDom.useParams();
845
- const isCreatingEntry = id === "create";
846
- const { allowedActions } = strapiAdmin.useRBAC(PERMISSIONS);
847
- const { canCreateAction, canRead: canMain, canDeleteAction } = allowedActions;
848
- const { schema } = strapiAdmin$1.unstable_useDocument({
849
- collectionType,
850
- model: slug
851
- });
852
- const hasDraftAndPublish = schema?.options?.draftAndPublish;
853
- const contentTypeUid = slug;
854
- const canFetch = id != null && contentTypeUid != null;
855
- const fetchParams = canFetch ? {
856
- contentTypeUid,
857
- entryId: id,
858
- hasEntryAttached: true
859
- } : query.skipToken;
860
- const response = useGetReleasesForEntryQuery(fetchParams);
861
- const releases = response.data?.data;
862
- if (!canFetch) {
863
- return null;
864
- }
865
- if (isCreatingEntry || !hasDraftAndPublish) {
866
- return null;
867
- }
868
- const toggleModal = () => setIsModalOpen((prev) => !prev);
869
- const getReleaseColorVariant = (actionType, shade) => {
870
- if (actionType === "unpublish") {
871
- return `secondary${shade}`;
872
- }
873
- return `success${shade}`;
874
- };
875
- if (!canMain) {
876
- return null;
877
- }
878
- return /* @__PURE__ */ jsxRuntime.jsxs(
879
- designSystem.Box,
880
- {
881
- as: "aside",
882
- "aria-label": formatMessage({
883
- id: "content-releases.plugin.name",
884
- defaultMessage: "Releases"
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"
885
722
  }),
886
- background: "neutral0",
887
- borderColor: "neutral150",
888
- hasRadius: true,
889
- padding: 4,
890
- shadow: "tableShadow",
891
- children: [
892
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 3, children: [
893
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", children: formatMessage({
894
- id: "content-releases.plugin.name",
895
- defaultMessage: "Releases"
896
- }) }),
897
- releases?.map((release) => {
898
- return /* @__PURE__ */ jsxRuntime.jsxs(
899
- designSystem.Flex,
900
- {
901
- direction: "column",
902
- alignItems: "start",
903
- borderWidth: "1px",
904
- borderStyle: "solid",
905
- borderColor: getReleaseColorVariant(release.actions[0].type, "200"),
906
- overflow: "hidden",
907
- hasRadius: true,
908
- children: [
909
- /* @__PURE__ */ jsxRuntime.jsx(
910
- designSystem.Box,
911
- {
912
- paddingTop: 3,
913
- paddingBottom: 3,
914
- paddingLeft: 4,
915
- paddingRight: 4,
916
- background: getReleaseColorVariant(release.actions[0].type, "100"),
917
- width: "100%",
918
- children: /* @__PURE__ */ jsxRuntime.jsx(
919
- designSystem.Typography,
920
- {
921
- fontSize: 1,
922
- variant: "pi",
923
- textColor: getReleaseColorVariant(release.actions[0].type, "600"),
924
- children: formatMessage(
925
- {
926
- id: "content-releases.content-manager-edit-view.list-releases.title",
927
- defaultMessage: "{isPublish, select, true {Will be published in} other {Will be unpublished in}}"
928
- },
929
- { isPublish: release.actions[0].type === "publish" }
930
- )
931
- }
932
- )
933
- }
934
- ),
935
- /* @__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: [
936
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontSize: 2, fontWeight: "bold", variant: "omega", textColor: "neutral700", children: release.name }),
937
- release.scheduledAt && release.timezone && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: formatMessage(
938
- {
939
- id: "content-releases.content-manager-edit-view.scheduled.date",
940
- defaultMessage: "{date} at {time} ({offset})"
941
- },
942
- {
943
- date: formatDate(new Date(release.scheduledAt), {
944
- day: "2-digit",
945
- month: "2-digit",
946
- year: "numeric",
947
- timeZone: release.timezone
948
- }),
949
- time: formatTime(new Date(release.scheduledAt), {
950
- hourCycle: "h23",
951
- timeZone: release.timezone
952
- }),
953
- offset: getTimezoneOffset(
954
- release.timezone,
955
- new Date(release.scheduledAt)
956
- )
957
- }
958
- ) }),
959
- canDeleteAction ? /* @__PURE__ */ jsxRuntime.jsxs(ReleaseActionMenu.Root, { hasTriggerBorder: true, children: [
960
- /* @__PURE__ */ jsxRuntime.jsx(ReleaseActionMenu.EditReleaseItem, { releaseId: release.id }),
961
- /* @__PURE__ */ jsxRuntime.jsx(
962
- ReleaseActionMenu.DeleteReleaseActionItem,
963
- {
964
- releaseId: release.id,
965
- actionId: release.actions[0].id
966
- }
967
- )
968
- ] }) : null
969
- ] }) })
970
- ]
971
- },
972
- release.id
973
- );
974
- }),
975
- canCreateAction ? /* @__PURE__ */ jsxRuntime.jsx(
976
- designSystem.Button,
977
- {
978
- justifyContent: "center",
979
- paddingLeft: 4,
980
- paddingRight: 4,
981
- color: "neutral700",
982
- variant: "tertiary",
983
- startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
984
- onClick: toggleModal,
985
- children: formatMessage({
986
- id: "content-releases.content-manager-edit-view.add-to-release",
987
- defaultMessage: "Add to release"
988
- })
989
- }
990
- ) : null
991
- ] }),
992
- isModalOpen && /* @__PURE__ */ jsxRuntime.jsx(
993
- 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,
994
739
  {
995
- handleClose: toggleModal,
996
- contentTypeUid,
997
- entryId: id
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
+ })
998
748
  }
999
749
  )
1000
- ]
750
+ ] })
1001
751
  }
1002
- );
752
+ };
1003
753
  };
1004
754
  const getContentPermissions = (subject) => {
1005
755
  const permissions = {
@@ -1016,11 +766,11 @@ const getContentPermissions = (subject) => {
1016
766
  };
1017
767
  return permissions;
1018
768
  };
1019
- const ReleaseAction = ({ documentIds, model }) => {
769
+ const ReleaseAction = ({ documents, model }) => {
1020
770
  const { formatMessage } = reactIntl.useIntl();
1021
771
  const { toggleNotification } = strapiAdmin.useNotification();
1022
772
  const { formatAPIError } = strapiAdmin.useAPIErrorHandler();
1023
- const [{ query: query2 }] = strapiAdmin.useQueryParams();
773
+ const [{ query }] = strapiAdmin.useQueryParams();
1024
774
  const contentPermissions = getContentPermissions(model);
1025
775
  const {
1026
776
  allowedActions: { canPublish }
@@ -1031,16 +781,15 @@ const ReleaseAction = ({ documentIds, model }) => {
1031
781
  const response = useGetReleasesQuery();
1032
782
  const releases = response.data?.data;
1033
783
  const [createManyReleaseActions, { isLoading }] = useCreateManyReleaseActionsMutation();
784
+ const documentIds = documents.map((doc) => doc.documentId);
1034
785
  const handleSubmit = async (values) => {
1035
- const locale = query2.plugins?.i18n?.locale;
786
+ const locale = query.plugins?.i18n?.locale;
1036
787
  const releaseActionEntries = documentIds.map(
1037
- (id) => ({
788
+ (entryDocumentId) => ({
1038
789
  type: values.type,
1039
- entry: {
1040
- contentType: model,
1041
- id,
1042
- locale
1043
- }
790
+ contentType: model,
791
+ entryDocumentId,
792
+ locale
1044
793
  })
1045
794
  );
1046
795
  const response2 = await createManyReleaseActions({
@@ -1076,7 +825,7 @@ const ReleaseAction = ({ documentIds, model }) => {
1076
825
  return true;
1077
826
  }
1078
827
  if ("error" in response2) {
1079
- if (axios.isAxiosError(response2.error)) {
828
+ if (strapiAdmin.isFetchError(response2.error)) {
1080
829
  toggleNotification({
1081
830
  type: "warning",
1082
831
  message: formatAPIError(response2.error)
@@ -1089,8 +838,7 @@ const ReleaseAction = ({ documentIds, model }) => {
1089
838
  }
1090
839
  }
1091
840
  };
1092
- if (!canCreate || !canPublish)
1093
- return null;
841
+ if (!canCreate || !canPublish) return null;
1094
842
  return {
1095
843
  actionType: "release",
1096
844
  variant: "tertiary",
@@ -1117,25 +865,26 @@ const ReleaseAction = ({ documentIds, model }) => {
1117
865
  validationSchema: RELEASE_ACTION_FORM_SCHEMA,
1118
866
  initialValues: INITIAL_VALUES,
1119
867
  children: ({ values, setFieldValue }) => /* @__PURE__ */ jsxRuntime.jsxs(formik.Form, { children: [
1120
- 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: [
1121
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingBottom: 6, children: /* @__PURE__ */ jsxRuntime.jsx(
1122
- designSystem.SingleSelect,
1123
- {
1124
- required: true,
1125
- label: formatMessage({
1126
- id: "content-releases.content-manager-list-view.add-to-release.select-label",
1127
- defaultMessage: "Select a release"
1128
- }),
1129
- placeholder: formatMessage({
1130
- id: "content-releases.content-manager-list-view.add-to-release.select-placeholder",
1131
- defaultMessage: "Select"
1132
- }),
1133
- onChange: (value) => setFieldValue("releaseId", value),
1134
- value: values.releaseId,
1135
- children: releases?.map((release) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: release.id, children: release.name }, release.id))
1136
- }
1137
- ) }),
1138
- /* @__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({
1139
888
  id: "content-releases.content-manager-list-view.add-to-release.action-type-label",
1140
889
  defaultMessage: "What do you want to do with these entries?"
1141
890
  }) }),
@@ -1148,25 +897,16 @@ const ReleaseAction = ({ documentIds, model }) => {
1148
897
  }
1149
898
  )
1150
899
  ] }) }),
1151
- /* @__PURE__ */ jsxRuntime.jsx(
1152
- designSystem.ModalFooter,
1153
- {
1154
- startActions: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: onClose, variant: "tertiary", name: "cancel", children: formatMessage({
1155
- id: "content-releases.content-manager-list-view.add-to-release.cancel-button",
1156
- defaultMessage: "Cancel"
1157
- }) }),
1158
- endActions: (
1159
- /**
1160
- * TODO: Ideally we would use isValid from Formik to disable the button, however currently it always returns true
1161
- * for yup.string().required(), even when the value is falsy (including empty string)
1162
- */
1163
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { type: "submit", disabled: !values.releaseId, loading: isLoading, children: formatMessage({
1164
- id: "content-releases.content-manager-list-view.add-to-release.continue-button",
1165
- defaultMessage: "Continue"
1166
- }) })
1167
- )
1168
- }
1169
- )
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
+ ] })
1170
910
  ] })
1171
911
  }
1172
912
  );
@@ -1174,10 +914,386 @@ const ReleaseAction = ({ documentIds, model }) => {
1174
914
  }
1175
915
  };
1176
916
  };
1177
- const prefixPluginTranslations = (trad, pluginId2) => {
1178
- if (!pluginId2) {
1179
- 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;
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;
1180
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) => {
1181
1297
  return Object.keys(trad).reduce((acc, current) => {
1182
1298
  acc[`${pluginId2}.${current}`] = trad[current];
1183
1299
  return acc;
@@ -1195,43 +1311,63 @@ const admin = {
1195
1311
  id: `${pluginId}.plugin.name`,
1196
1312
  defaultMessage: "Releases"
1197
1313
  },
1198
- Component: () => Promise.resolve().then(() => require("./App-FVorrIzF.js")).then((mod) => ({ default: mod.App })),
1199
- permissions: PERMISSIONS.main
1200
- });
1201
- app.addMiddlewares([() => releaseApi.middleware]);
1202
- app.addReducers({
1203
- [releaseApi.reducerPath]: releaseApi.reducer
1314
+ Component: () => Promise.resolve().then(() => require("./App-SGjO5UPV.js")).then((mod) => ({ default: mod.App })),
1315
+ permissions: PERMISSIONS.main,
1316
+ position: 2
1204
1317
  });
1205
- app.getPlugin("content-manager").injectComponent("editView", "right-links", {
1206
- name: `${pluginId}-link`,
1207
- Component: CMReleasesContainer
1208
- });
1209
- app.plugins["content-manager"].apis.addBulkAction((actions) => {
1210
- const deleteActionIndex = actions.findIndex((action) => action.name === "DeleteAction");
1211
- actions.splice(deleteActionIndex, 0, ReleaseAction);
1212
- 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
+ }
1213
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);
1214
1350
  } else if (!window.strapi.features.isEnabled("cms-content-releases") && window.strapi?.flags?.promoteEE) {
1215
- app.addMenuLink({
1216
- to: `/plugins/purchase-content-releases`,
1217
- icon: icons.PaperPlane,
1351
+ app.addSettingsLink("global", {
1352
+ id: pluginId,
1353
+ to: "/plugins/purchase-content-releases",
1218
1354
  intlLabel: {
1219
1355
  id: `${pluginId}.plugin.name`,
1220
1356
  defaultMessage: "Releases"
1221
1357
  },
1222
1358
  permissions: [],
1223
1359
  async Component() {
1224
- const { PurchaseContentReleases } = await Promise.resolve().then(() => require("./PurchaseContentReleases-sD6ADHk2.js"));
1360
+ const { PurchaseContentReleases } = await Promise.resolve().then(() => require("./PurchaseContentReleases--qQepXpP.js"));
1225
1361
  return { default: PurchaseContentReleases };
1226
1362
  },
1227
- lockIcon: true
1363
+ licenseOnly: true
1228
1364
  });
1229
1365
  }
1230
1366
  },
1231
1367
  async registerTrads({ locales }) {
1232
1368
  const importedTrads = await Promise.all(
1233
1369
  locales.map((locale) => {
1234
- 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 }) => {
1235
1371
  return {
1236
1372
  data: prefixPluginTranslations(data, "content-releases"),
1237
1373
  locale
@@ -1252,15 +1388,17 @@ exports.ReleaseActionMenu = ReleaseActionMenu;
1252
1388
  exports.ReleaseActionOptions = ReleaseActionOptions;
1253
1389
  exports.admin = admin;
1254
1390
  exports.getTimezoneOffset = getTimezoneOffset;
1255
- exports.isAxiosError = isAxiosError;
1391
+ exports.getTimezones = getTimezones;
1256
1392
  exports.pluginId = pluginId;
1257
1393
  exports.releaseApi = releaseApi;
1258
1394
  exports.useCreateReleaseMutation = useCreateReleaseMutation;
1259
1395
  exports.useDeleteReleaseMutation = useDeleteReleaseMutation;
1260
1396
  exports.useGetReleaseActionsQuery = useGetReleaseActionsQuery;
1261
1397
  exports.useGetReleaseQuery = useGetReleaseQuery;
1398
+ exports.useGetReleaseSettingsQuery = useGetReleaseSettingsQuery;
1262
1399
  exports.useGetReleasesQuery = useGetReleasesQuery;
1263
1400
  exports.usePublishReleaseMutation = usePublishReleaseMutation;
1264
1401
  exports.useUpdateReleaseActionMutation = useUpdateReleaseActionMutation;
1265
1402
  exports.useUpdateReleaseMutation = useUpdateReleaseMutation;
1266
- //# sourceMappingURL=index-BfJLth9Z.js.map
1403
+ exports.useUpdateReleaseSettingsMutation = useUpdateReleaseSettingsMutation;
1404
+ //# sourceMappingURL=index-CyU534vL.js.map