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

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