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