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

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-Cmn2Mkn7.mjs → App-BA2xDdy0.mjs} +435 -404
  3. package/dist/_chunks/App-BA2xDdy0.mjs.map +1 -0
  4. package/dist/_chunks/{App-FVorrIzF.js → App-D4Wira1X.js} +440 -411
  5. package/dist/_chunks/App-D4Wira1X.js.map +1 -0
  6. package/dist/_chunks/{PurchaseContentReleases-sD6ADHk2.js → PurchaseContentReleases-Be3acS2L.js} +7 -6
  7. package/dist/_chunks/PurchaseContentReleases-Be3acS2L.js.map +1 -0
  8. package/dist/_chunks/{PurchaseContentReleases-C8djn9fP.mjs → PurchaseContentReleases-_MxP6-Dt.mjs} +8 -7
  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-DDohgTaQ.mjs → index-CCFFG3Zs.mjs} +724 -604
  19. package/dist/_chunks/index-CCFFG3Zs.mjs.map +1 -0
  20. package/dist/_chunks/{index-BfJLth9Z.js → index-DxkQGp4N.js} +712 -594
  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-Cmn2Mkn7.mjs.map +0 -1
  100. package/dist/_chunks/App-FVorrIzF.js.map +0 -1
  101. package/dist/_chunks/PurchaseContentReleases-C8djn9fP.mjs.map +0 -1
  102. package/dist/_chunks/PurchaseContentReleases-sD6ADHk2.js.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-BfJLth9Z.js.map +0 -1
  106. package/dist/_chunks/index-DDohgTaQ.mjs.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, EmptyDocuments, 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 { IconButton, Flex, Icon, Typography, Field, FieldLabel, VisuallyHidden, FieldInput, Box, Button, EmptyStateLayout, ModalLayout, ModalHeader, ModalBody, SingleSelect, SingleSelectOption, ModalFooter } from "@strapi/design-system";
7
- import { Menu, Link, LinkButton } from "@strapi/design-system/v2";
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,205 +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
- path {
385
- fill: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}600`]};
386
- }
387
- }
388
-
389
- a {
390
- color: ${({ theme }) => theme.colors.neutral800};
391
- }
392
- }
393
-
394
- svg {
395
- path {
396
- fill: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}600`]};
397
- }
398
- }
399
-
400
- a {
401
- color: ${({ theme }) => theme.colors.neutral800};
402
- }
403
-
404
- span,
405
- a {
406
- width: 100%;
407
- }
408
- `;
409
- const StyledIconButton = styled(IconButton)`
410
- /* Setting this style inline with borderColor will not apply the style */
411
- border: ${({ theme }) => `1px solid ${theme.colors.neutral200}`};
412
- `;
413
- const DeleteReleaseActionItem = ({ releaseId, actionId }) => {
414
- const { formatMessage } = useIntl();
415
- const { toggleNotification } = useNotification();
416
- const { formatAPIError } = useAPIErrorHandler();
417
- const [deleteReleaseAction] = useDeleteReleaseActionMutation();
418
- const {
419
- allowedActions: { canDeleteAction }
420
- } = useRBAC(PERMISSIONS);
421
- const handleDeleteAction = async () => {
422
- const response = await deleteReleaseAction({
423
- params: { releaseId, actionId }
424
- });
425
- if ("data" in response) {
426
- toggleNotification({
427
- type: "success",
428
- message: formatMessage({
429
- id: "content-releases.content-manager-edit-view.remove-from-release.notification.success",
430
- defaultMessage: "Entry removed from release"
431
- })
432
- });
433
- return;
434
- }
435
- if ("error" in response) {
436
- if (isAxiosError$1(response.error)) {
437
- toggleNotification({
438
- type: "danger",
439
- message: formatAPIError(response.error)
440
- });
441
- } else {
442
- toggleNotification({
443
- type: "danger",
444
- message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
445
- });
446
- }
447
- }
448
- };
449
- if (!canDeleteAction) {
450
- return null;
451
- }
452
- return /* @__PURE__ */ jsx(StyledMenuItem, { variant: "danger", onSelect: handleDeleteAction, children: /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
453
- /* @__PURE__ */ jsx(Icon, { as: Cross, width: 3, height: 3 }),
454
- /* @__PURE__ */ jsx(Typography, { textColor: "danger600", variant: "omega", children: formatMessage({
455
- id: "content-releases.content-manager-edit-view.remove-from-release",
456
- defaultMessage: "Remove from release"
457
- }) })
458
- ] }) });
459
- };
460
- const ReleaseActionEntryLinkItem = ({
461
- contentTypeUid,
462
- entryId,
463
- locale
464
- }) => {
465
- const { formatMessage } = useIntl();
466
- const userPermissions = useAuth("ReleaseActionEntryLinkItem", (state) => state.permissions);
467
- const canUpdateEntryForLocale = React.useMemo(() => {
468
- const updatePermissions = userPermissions.find(
469
- (permission) => permission.subject === contentTypeUid && permission.action === "plugin::content-manager.explorer.update"
470
- );
471
- if (!updatePermissions) {
472
- return false;
473
- }
474
- return Boolean(!locale || updatePermissions.properties?.locales?.includes(locale));
475
- }, [contentTypeUid, locale, userPermissions]);
476
- const {
477
- allowedActions: { canUpdate: canUpdateContentType }
478
- } = useRBAC({
479
- updateContentType: [
480
- {
481
- action: "plugin::content-manager.explorer.update",
482
- subject: contentTypeUid
483
- }
484
- ]
485
- });
486
- if (!canUpdateContentType || !canUpdateEntryForLocale) {
487
- return null;
488
- }
489
- return /* @__PURE__ */ jsx(StyledMenuItem, { children: /* @__PURE__ */ jsx(
490
- Link,
491
- {
492
- as: NavLink,
493
- to: {
494
- pathname: `/content-manager/collection-types/${contentTypeUid}/${entryId}`,
495
- search: locale && `?plugins[i18n][locale]=${locale}`
496
- },
497
- startIcon: /* @__PURE__ */ jsx(Icon, { as: Pencil, width: 3, height: 3 }),
498
- children: /* @__PURE__ */ jsx(Typography, { variant: "omega", children: formatMessage({
499
- id: "content-releases.content-manager-edit-view.edit-entry",
500
- defaultMessage: "Edit entry"
501
- }) })
502
- }
503
- ) });
504
- };
505
- const EditReleaseItem = ({ releaseId }) => {
506
- const { formatMessage } = useIntl();
507
- return /* @__PURE__ */ jsx(StyledMenuItem, { children: /* @__PURE__ */ jsx(
508
- Link,
509
- {
510
- href: `/admin/plugins/content-releases/${releaseId}`,
511
- startIcon: /* @__PURE__ */ jsx(Icon, { as: Pencil, width: 3, height: 3 }),
512
- isExternal: false,
513
- children: /* @__PURE__ */ jsx(Typography, { variant: "omega", children: formatMessage({
514
- id: "content-releases.content-manager-edit-view.edit-release",
515
- defaultMessage: "Edit release"
516
- }) })
517
- }
518
- ) });
519
- };
520
- const Root = ({ children, hasTriggerBorder = false }) => {
521
- const { formatMessage } = useIntl();
522
- const { allowedActions } = useRBAC(PERMISSIONS);
523
- return (
524
- // A user can access the dropdown if they have permissions to delete a release-action OR update a release
525
- allowedActions.canDeleteAction || allowedActions.canUpdate ? /* @__PURE__ */ jsxs(Menu.Root, { children: [
526
- /* @__PURE__ */ jsx(
527
- Menu.Trigger,
528
- {
529
- as: hasTriggerBorder ? StyledIconButton : IconButton,
530
- paddingLeft: 2,
531
- paddingRight: 2,
532
- "aria-label": formatMessage({
533
- id: "content-releases.content-manager-edit-view.release-action-menu",
534
- defaultMessage: "Release action options"
535
- }),
536
- icon: /* @__PURE__ */ jsx(More, {})
537
- }
538
- ),
539
- /* @__PURE__ */ jsx(Menu.Content, { top: 1, popoverPlacement: "bottom-end", children })
540
- ] }) : null
541
- );
542
- };
543
- const ReleaseActionMenu = {
544
- Root,
545
- EditReleaseItem,
546
- DeleteReleaseActionItem,
547
- ReleaseActionEntryLinkItem
548
- };
549
387
  const getBorderLeftRadiusValue = (actionType) => {
550
388
  return actionType === "publish" ? 1 : 0;
551
389
  };
552
390
  const getBorderRightRadiusValue = (actionType) => {
553
391
  return actionType === "publish" ? 0 : 1;
554
392
  };
555
- const FieldWrapper = styled(Field)`
556
- border-top-left-radius: ${({ actionType, theme }) => theme.spaces[getBorderLeftRadiusValue(actionType)]};
557
- border-bottom-left-radius: ${({ actionType, theme }) => theme.spaces[getBorderLeftRadiusValue(actionType)]};
558
- border-top-right-radius: ${({ actionType, theme }) => theme.spaces[getBorderRightRadiusValue(actionType)]};
559
- 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)]};
560
398
 
561
399
  > label {
562
400
  color: inherit;
@@ -567,14 +405,14 @@ const FieldWrapper = styled(Field)`
567
405
  }
568
406
 
569
407
  &[data-checked='true'] {
570
- color: ${({ theme, actionType }) => actionType === "publish" ? theme.colors.primary700 : theme.colors.danger600};
571
- background-color: ${({ theme, actionType }) => actionType === "publish" ? theme.colors.primary100 : theme.colors.danger100};
572
- 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};
573
411
  }
574
412
 
575
413
  &[data-checked='false'] {
576
- border-left: ${({ actionType }) => actionType === "unpublish" && "none"};
577
- border-right: ${({ actionType }) => actionType === "publish" && "none"};
414
+ border-left: ${({ $actionType }) => $actionType === "unpublish" && "none"};
415
+ border-right: ${({ $actionType }) => $actionType === "publish" && "none"};
578
416
  }
579
417
 
580
418
  &[data-checked='false'][data-disabled='false']:hover {
@@ -603,7 +441,7 @@ const ActionOption = ({
603
441
  return /* @__PURE__ */ jsx(
604
442
  FieldWrapper,
605
443
  {
606
- actionType,
444
+ $actionType: actionType,
607
445
  background: "primary0",
608
446
  borderColor: "neutral200",
609
447
  color: selected === actionType ? "primary600" : "neutral600",
@@ -611,12 +449,11 @@ const ActionOption = ({
611
449
  cursor: "pointer",
612
450
  "data-checked": selected === actionType,
613
451
  "data-disabled": disabled && selected !== actionType,
614
- children: /* @__PURE__ */ jsxs(FieldLabel, { htmlFor: `${name}-${actionType}`, children: [
452
+ children: /* @__PURE__ */ jsxs(Field.Label, { children: [
615
453
  /* @__PURE__ */ jsx(VisuallyHidden, { children: /* @__PURE__ */ jsx(
616
- FieldInput,
454
+ Field.Input,
617
455
  {
618
456
  type: "radio",
619
- id: `${name}-${actionType}`,
620
457
  name,
621
458
  checked: selected === actionType,
622
459
  onChange: handleChange,
@@ -671,7 +508,7 @@ const NoReleases = () => {
671
508
  return /* @__PURE__ */ jsx(
672
509
  EmptyStateLayout,
673
510
  {
674
- icon: /* @__PURE__ */ jsx(EmptyDocuments, { width: "10rem" }),
511
+ icon: /* @__PURE__ */ jsx(EmptyDocuments, { width: "16rem" }),
675
512
  content: formatMessage({
676
513
  id: "content-releases.content-manager-edit-view.add-to-release.no-releases-message",
677
514
  defaultMessage: "No available releases. Open the list of releases and create a new one from there."
@@ -682,301 +519,192 @@ const NoReleases = () => {
682
519
  to: {
683
520
  pathname: "/plugins/content-releases"
684
521
  },
685
- as: Link$1,
522
+ tag: Link,
686
523
  variant: "secondary",
687
524
  children: formatMessage({
688
525
  id: "content-releases.content-manager-edit-view.add-to-release.redirect-button",
689
526
  defaultMessage: "Open the list of releases"
690
527
  })
691
528
  }
692
- )
529
+ ),
530
+ shadow: "none"
693
531
  }
694
532
  );
695
533
  };
696
534
  const AddActionToReleaseModal = ({
697
- handleClose,
698
- contentTypeUid,
699
- entryId
535
+ contentType,
536
+ documentId,
537
+ onInputChange,
538
+ values
700
539
  }) => {
701
- const releaseHeaderId = React.useId();
702
540
  const { formatMessage } = useIntl();
703
- const { toggleNotification } = useNotification();
704
- const { formatAPIError } = useAPIErrorHandler();
705
541
  const [{ query }] = useQueryParams();
706
542
  const locale = query.plugins?.i18n?.locale;
707
543
  const response = useGetReleasesForEntryQuery({
708
- contentTypeUid,
709
- entryId,
710
- hasEntryAttached: false
544
+ contentType,
545
+ entryDocumentId: documentId,
546
+ hasEntryAttached: false,
547
+ locale
711
548
  });
712
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;
713
597
  const [createReleaseAction, { isLoading }] = useCreateReleaseActionMutation();
714
- const handleSubmit = async (values) => {
715
- const releaseActionEntry = {
716
- contentType: contentTypeUid,
717
- id: entryId,
718
- locale
719
- };
720
- const response2 = await createReleaseAction({
721
- body: { type: values.type, entry: releaseActionEntry },
722
- params: { releaseId: values.releaseId }
723
- });
724
- if ("data" in response2) {
725
- toggleNotification({
726
- type: "success",
727
- message: formatMessage({
728
- id: "content-releases.content-manager-edit-view.add-to-release.notification.success",
729
- defaultMessage: "Entry added to release"
730
- })
731
- });
732
- handleClose();
733
- return;
734
- }
735
- if ("error" in response2) {
736
- 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)) {
737
608
  toggleNotification({
738
609
  type: "danger",
739
- message: formatAPIError(response2.error)
610
+ message: formatAPIError(error)
740
611
  });
741
612
  } else {
742
613
  toggleNotification({
743
614
  type: "danger",
744
- message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
615
+ message: formatMessage({
616
+ id: "notification.error",
617
+ defaultMessage: "An error occurred"
618
+ })
745
619
  });
746
620
  }
747
621
  }
748
622
  };
749
- return /* @__PURE__ */ jsxs(ModalLayout, { onClose: handleClose, labelledBy: releaseHeaderId, children: [
750
- /* @__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({
751
665
  id: "content-releases.content-manager-edit-view.add-to-release",
752
666
  defaultMessage: "Add to release"
753
- }) }) }),
754
- /* @__PURE__ */ jsx(
755
- Formik,
756
- {
757
- onSubmit: handleSubmit,
758
- validationSchema: RELEASE_ACTION_FORM_SCHEMA,
759
- initialValues: INITIAL_VALUES,
760
- children: ({ values, setFieldValue }) => {
761
- return /* @__PURE__ */ jsxs(Form, { children: [
762
- releases?.length === 0 ? /* @__PURE__ */ jsx(NoReleases, {}) : /* @__PURE__ */ jsx(ModalBody, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
763
- /* @__PURE__ */ jsx(Box, { paddingBottom: 6, children: /* @__PURE__ */ jsx(
764
- SingleSelect,
765
- {
766
- required: true,
767
- label: formatMessage({
768
- id: "content-releases.content-manager-edit-view.add-to-release.select-label",
769
- defaultMessage: "Select a release"
770
- }),
771
- placeholder: formatMessage({
772
- id: "content-releases.content-manager-edit-view.add-to-release.select-placeholder",
773
- defaultMessage: "Select"
774
- }),
775
- onChange: (value) => setFieldValue("releaseId", value),
776
- value: values.releaseId,
777
- children: releases?.map((release) => /* @__PURE__ */ jsx(SingleSelectOption, { value: release.id, children: release.name }, release.id))
778
- }
779
- ) }),
780
- /* @__PURE__ */ jsx(FieldLabel, { children: formatMessage({
781
- id: "content-releases.content-manager-edit-view.add-to-release.action-type-label",
782
- defaultMessage: "What do you want to do with this entry?"
783
- }) }),
784
- /* @__PURE__ */ jsx(
785
- ReleaseActionOptions,
786
- {
787
- selected: values.type,
788
- handleChange: (e) => setFieldValue("type", e.target.value),
789
- name: "type"
790
- }
791
- )
792
- ] }) }),
793
- /* @__PURE__ */ jsx(
794
- ModalFooter,
795
- {
796
- startActions: /* @__PURE__ */ jsx(Button, { onClick: handleClose, variant: "tertiary", name: "cancel", children: formatMessage({
797
- id: "content-releases.content-manager-edit-view.add-to-release.cancel-button",
798
- defaultMessage: "Cancel"
799
- }) }),
800
- endActions: (
801
- /**
802
- * TODO: Ideally we would use isValid from Formik to disable the button, however currently it always returns true
803
- * for yup.string().required(), even when the value is falsy (including empty string)
804
- */
805
- /* @__PURE__ */ jsx(Button, { type: "submit", disabled: !values.releaseId, loading: isLoading, children: formatMessage({
806
- id: "content-releases.content-manager-edit-view.add-to-release.continue-button",
807
- defaultMessage: "Continue"
808
- }) })
809
- )
810
- }
811
- )
812
- ] });
813
- }
814
- }
815
- )
816
- ] });
817
- };
818
- const CMReleasesContainer = () => {
819
- const [isModalOpen, setIsModalOpen] = React.useState(false);
820
- const { formatMessage, formatDate, formatTime } = useIntl();
821
- const { id, slug, collectionType } = useParams();
822
- const isCreatingEntry = id === "create";
823
- const { allowedActions } = useRBAC(PERMISSIONS);
824
- const { canCreateAction, canRead: canMain, canDeleteAction } = allowedActions;
825
- const { schema } = unstable_useDocument({
826
- collectionType,
827
- model: slug
828
- });
829
- const hasDraftAndPublish = schema?.options?.draftAndPublish;
830
- const contentTypeUid = slug;
831
- const canFetch = id != null && contentTypeUid != null;
832
- const fetchParams = canFetch ? {
833
- contentTypeUid,
834
- entryId: id,
835
- hasEntryAttached: true
836
- } : skipToken;
837
- const response = useGetReleasesForEntryQuery(fetchParams);
838
- const releases = response.data?.data;
839
- if (!canFetch) {
840
- return null;
841
- }
842
- if (isCreatingEntry || !hasDraftAndPublish) {
843
- return null;
844
- }
845
- const toggleModal = () => setIsModalOpen((prev) => !prev);
846
- const getReleaseColorVariant = (actionType, shade) => {
847
- if (actionType === "unpublish") {
848
- return `secondary${shade}`;
849
- }
850
- return `success${shade}`;
851
- };
852
- if (!canMain) {
853
- return null;
854
- }
855
- return /* @__PURE__ */ jsxs(
856
- Box,
857
- {
858
- as: "aside",
859
- "aria-label": formatMessage({
860
- id: "content-releases.plugin.name",
861
- 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"
862
677
  }),
863
- background: "neutral0",
864
- borderColor: "neutral150",
865
- hasRadius: true,
866
- padding: 4,
867
- shadow: "tableShadow",
868
- children: [
869
- /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 3, children: [
870
- /* @__PURE__ */ jsx(Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", children: formatMessage({
871
- id: "content-releases.plugin.name",
872
- defaultMessage: "Releases"
873
- }) }),
874
- releases?.map((release) => {
875
- return /* @__PURE__ */ jsxs(
876
- Flex,
877
- {
878
- direction: "column",
879
- alignItems: "start",
880
- borderWidth: "1px",
881
- borderStyle: "solid",
882
- borderColor: getReleaseColorVariant(release.actions[0].type, "200"),
883
- overflow: "hidden",
884
- hasRadius: true,
885
- children: [
886
- /* @__PURE__ */ jsx(
887
- Box,
888
- {
889
- paddingTop: 3,
890
- paddingBottom: 3,
891
- paddingLeft: 4,
892
- paddingRight: 4,
893
- background: getReleaseColorVariant(release.actions[0].type, "100"),
894
- width: "100%",
895
- children: /* @__PURE__ */ jsx(
896
- Typography,
897
- {
898
- fontSize: 1,
899
- variant: "pi",
900
- textColor: getReleaseColorVariant(release.actions[0].type, "600"),
901
- children: formatMessage(
902
- {
903
- id: "content-releases.content-manager-edit-view.list-releases.title",
904
- defaultMessage: "{isPublish, select, true {Will be published in} other {Will be unpublished in}}"
905
- },
906
- { isPublish: release.actions[0].type === "publish" }
907
- )
908
- }
909
- )
910
- }
911
- ),
912
- /* @__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: [
913
- /* @__PURE__ */ jsx(Typography, { fontSize: 2, fontWeight: "bold", variant: "omega", textColor: "neutral700", children: release.name }),
914
- release.scheduledAt && release.timezone && /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: formatMessage(
915
- {
916
- id: "content-releases.content-manager-edit-view.scheduled.date",
917
- defaultMessage: "{date} at {time} ({offset})"
918
- },
919
- {
920
- date: formatDate(new Date(release.scheduledAt), {
921
- day: "2-digit",
922
- month: "2-digit",
923
- year: "numeric",
924
- timeZone: release.timezone
925
- }),
926
- time: formatTime(new Date(release.scheduledAt), {
927
- hourCycle: "h23",
928
- timeZone: release.timezone
929
- }),
930
- offset: getTimezoneOffset(
931
- release.timezone,
932
- new Date(release.scheduledAt)
933
- )
934
- }
935
- ) }),
936
- canDeleteAction ? /* @__PURE__ */ jsxs(ReleaseActionMenu.Root, { hasTriggerBorder: true, children: [
937
- /* @__PURE__ */ jsx(ReleaseActionMenu.EditReleaseItem, { releaseId: release.id }),
938
- /* @__PURE__ */ jsx(
939
- ReleaseActionMenu.DeleteReleaseActionItem,
940
- {
941
- releaseId: release.id,
942
- actionId: release.actions[0].id
943
- }
944
- )
945
- ] }) : null
946
- ] }) })
947
- ]
948
- },
949
- release.id
950
- );
951
- }),
952
- canCreateAction ? /* @__PURE__ */ jsx(
953
- Button,
954
- {
955
- justifyContent: "center",
956
- paddingLeft: 4,
957
- paddingRight: 4,
958
- color: "neutral700",
959
- variant: "tertiary",
960
- startIcon: /* @__PURE__ */ jsx(Plus, {}),
961
- onClick: toggleModal,
962
- children: formatMessage({
963
- id: "content-releases.content-manager-edit-view.add-to-release",
964
- defaultMessage: "Add to release"
965
- })
966
- }
967
- ) : null
968
- ] }),
969
- isModalOpen && /* @__PURE__ */ jsx(
970
- 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,
971
694
  {
972
- handleClose: toggleModal,
973
- contentTypeUid,
974
- 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
+ })
975
703
  }
976
704
  )
977
- ]
705
+ ] })
978
706
  }
979
- );
707
+ };
980
708
  };
981
709
  const getContentPermissions = (subject) => {
982
710
  const permissions = {
@@ -993,7 +721,7 @@ const getContentPermissions = (subject) => {
993
721
  };
994
722
  return permissions;
995
723
  };
996
- const ReleaseAction = ({ documentIds, model }) => {
724
+ const ReleaseAction = ({ documents, model }) => {
997
725
  const { formatMessage } = useIntl();
998
726
  const { toggleNotification } = useNotification();
999
727
  const { formatAPIError } = useAPIErrorHandler();
@@ -1008,16 +736,15 @@ const ReleaseAction = ({ documentIds, model }) => {
1008
736
  const response = useGetReleasesQuery();
1009
737
  const releases = response.data?.data;
1010
738
  const [createManyReleaseActions, { isLoading }] = useCreateManyReleaseActionsMutation();
739
+ const documentIds = documents.map((doc) => doc.documentId);
1011
740
  const handleSubmit = async (values) => {
1012
741
  const locale = query.plugins?.i18n?.locale;
1013
742
  const releaseActionEntries = documentIds.map(
1014
- (id) => ({
743
+ (entryDocumentId) => ({
1015
744
  type: values.type,
1016
- entry: {
1017
- contentType: model,
1018
- id,
1019
- locale
1020
- }
745
+ contentType: model,
746
+ entryDocumentId,
747
+ locale
1021
748
  })
1022
749
  );
1023
750
  const response2 = await createManyReleaseActions({
@@ -1053,7 +780,7 @@ const ReleaseAction = ({ documentIds, model }) => {
1053
780
  return true;
1054
781
  }
1055
782
  if ("error" in response2) {
1056
- if (isAxiosError$1(response2.error)) {
783
+ if (isFetchError(response2.error)) {
1057
784
  toggleNotification({
1058
785
  type: "warning",
1059
786
  message: formatAPIError(response2.error)
@@ -1094,25 +821,26 @@ const ReleaseAction = ({ documentIds, model }) => {
1094
821
  validationSchema: RELEASE_ACTION_FORM_SCHEMA,
1095
822
  initialValues: INITIAL_VALUES,
1096
823
  children: ({ values, setFieldValue }) => /* @__PURE__ */ jsxs(Form, { children: [
1097
- releases?.length === 0 ? /* @__PURE__ */ jsx(NoReleases, {}) : /* @__PURE__ */ jsx(ModalBody, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
1098
- /* @__PURE__ */ jsx(Box, { paddingBottom: 6, children: /* @__PURE__ */ jsx(
1099
- SingleSelect,
1100
- {
1101
- required: true,
1102
- label: formatMessage({
1103
- id: "content-releases.content-manager-list-view.add-to-release.select-label",
1104
- defaultMessage: "Select a release"
1105
- }),
1106
- placeholder: formatMessage({
1107
- id: "content-releases.content-manager-list-view.add-to-release.select-placeholder",
1108
- defaultMessage: "Select"
1109
- }),
1110
- onChange: (value) => setFieldValue("releaseId", value),
1111
- value: values.releaseId,
1112
- children: releases?.map((release) => /* @__PURE__ */ jsx(SingleSelectOption, { value: release.id, children: release.name }, release.id))
1113
- }
1114
- ) }),
1115
- /* @__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({
1116
844
  id: "content-releases.content-manager-list-view.add-to-release.action-type-label",
1117
845
  defaultMessage: "What do you want to do with these entries?"
1118
846
  }) }),
@@ -1125,25 +853,16 @@ const ReleaseAction = ({ documentIds, model }) => {
1125
853
  }
1126
854
  )
1127
855
  ] }) }),
1128
- /* @__PURE__ */ jsx(
1129
- ModalFooter,
1130
- {
1131
- startActions: /* @__PURE__ */ jsx(Button, { onClick: onClose, variant: "tertiary", name: "cancel", children: formatMessage({
1132
- id: "content-releases.content-manager-list-view.add-to-release.cancel-button",
1133
- defaultMessage: "Cancel"
1134
- }) }),
1135
- endActions: (
1136
- /**
1137
- * TODO: Ideally we would use isValid from Formik to disable the button, however currently it always returns true
1138
- * for yup.string().required(), even when the value is falsy (including empty string)
1139
- */
1140
- /* @__PURE__ */ jsx(Button, { type: "submit", disabled: !values.releaseId, loading: isLoading, children: formatMessage({
1141
- id: "content-releases.content-manager-list-view.add-to-release.continue-button",
1142
- defaultMessage: "Continue"
1143
- }) })
1144
- )
1145
- }
1146
- )
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
+ ] })
1147
866
  ] })
1148
867
  }
1149
868
  );
@@ -1151,6 +870,385 @@ const ReleaseAction = ({ documentIds, model }) => {
1151
870
  }
1152
871
  };
1153
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";
1154
1252
  const prefixPluginTranslations = (trad, pluginId2) => {
1155
1253
  if (!pluginId2) {
1156
1254
  throw new TypeError("pluginId can't be empty");
@@ -1172,43 +1270,63 @@ const admin = {
1172
1270
  id: `${pluginId}.plugin.name`,
1173
1271
  defaultMessage: "Releases"
1174
1272
  },
1175
- Component: () => import("./App-Cmn2Mkn7.mjs").then((mod) => ({ default: mod.App })),
1176
- permissions: PERMISSIONS.main
1177
- });
1178
- app.addMiddlewares([() => releaseApi.middleware]);
1179
- app.addReducers({
1180
- [releaseApi.reducerPath]: releaseApi.reducer
1181
- });
1182
- app.getPlugin("content-manager").injectComponent("editView", "right-links", {
1183
- name: `${pluginId}-link`,
1184
- Component: CMReleasesContainer
1273
+ Component: () => import("./App-BA2xDdy0.mjs").then((mod) => ({ default: mod.App })),
1274
+ permissions: PERMISSIONS.main,
1275
+ position: 2
1185
1276
  });
1186
- app.plugins["content-manager"].apis.addBulkAction((actions) => {
1187
- const deleteActionIndex = actions.findIndex((action) => action.name === "DeleteAction");
1188
- actions.splice(deleteActionIndex, 0, ReleaseAction);
1189
- 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
+ }
1190
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);
1191
1309
  } else if (!window.strapi.features.isEnabled("cms-content-releases") && window.strapi?.flags?.promoteEE) {
1192
- app.addMenuLink({
1193
- to: `/plugins/purchase-content-releases`,
1194
- icon: PaperPlane,
1310
+ app.addSettingsLink("global", {
1311
+ id: pluginId,
1312
+ to: "/plugins/purchase-content-releases",
1195
1313
  intlLabel: {
1196
1314
  id: `${pluginId}.plugin.name`,
1197
1315
  defaultMessage: "Releases"
1198
1316
  },
1199
1317
  permissions: [],
1200
1318
  async Component() {
1201
- const { PurchaseContentReleases } = await import("./PurchaseContentReleases-C8djn9fP.mjs");
1319
+ const { PurchaseContentReleases } = await import("./PurchaseContentReleases-_MxP6-Dt.mjs");
1202
1320
  return { default: PurchaseContentReleases };
1203
1321
  },
1204
- lockIcon: true
1322
+ licenseOnly: true
1205
1323
  });
1206
1324
  }
1207
1325
  },
1208
1326
  async registerTrads({ locales }) {
1209
1327
  const importedTrads = await Promise.all(
1210
1328
  locales.map((locale) => {
1211
- 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 }) => {
1212
1330
  return {
1213
1331
  data: prefixPluginTranslations(data, "content-releases"),
1214
1332
  locale
@@ -1227,19 +1345,21 @@ const admin = {
1227
1345
  export {
1228
1346
  PERMISSIONS as P,
1229
1347
  ReleaseActionOptions as R,
1230
- useCreateReleaseMutation as a,
1231
- useGetReleaseQuery as b,
1232
- useUpdateReleaseMutation as c,
1233
- useDeleteReleaseMutation as d,
1234
- usePublishReleaseMutation as e,
1235
- useGetReleaseActionsQuery as f,
1236
- getTimezoneOffset as g,
1237
- useUpdateReleaseActionMutation as h,
1238
- isAxiosError as i,
1239
- ReleaseActionMenu as j,
1240
- 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,
1241
1361
  pluginId as p,
1242
1362
  releaseApi as r,
1243
1363
  useGetReleasesQuery as u
1244
1364
  };
1245
- //# sourceMappingURL=index-DDohgTaQ.mjs.map
1365
+ //# sourceMappingURL=index-CCFFG3Zs.mjs.map