@strapi/content-releases 0.0.0-experimental.950b677f6614f483cde77801d941607d6847a6e3 → 0.0.0-experimental.cae3a5a17d131a6f59673b62d01cfac869ea9cc2

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 (89) hide show
  1. package/dist/_chunks/{App-3f94ba77.mjs → App-_Jj3tWts.mjs} +350 -154
  2. package/dist/_chunks/App-_Jj3tWts.mjs.map +1 -0
  3. package/dist/_chunks/{App-ae9b2380.js → App-iqqoPnBO.js} +347 -151
  4. package/dist/_chunks/App-iqqoPnBO.js.map +1 -0
  5. package/dist/_chunks/{en-13576ce2.js → en-2DuPv5k0.js} +17 -4
  6. package/dist/_chunks/en-2DuPv5k0.js.map +1 -0
  7. package/dist/_chunks/{en-e98d8b57.mjs → en-SOqjCdyh.mjs} +17 -4
  8. package/dist/_chunks/en-SOqjCdyh.mjs.map +1 -0
  9. package/dist/_chunks/{index-40da7f6d.js → index-_lT-gI3M.js} +126 -37
  10. package/dist/_chunks/index-_lT-gI3M.js.map +1 -0
  11. package/dist/_chunks/{index-6ddf4a38.mjs → index-bsuc8ZwZ.mjs} +137 -48
  12. package/dist/_chunks/index-bsuc8ZwZ.mjs.map +1 -0
  13. package/dist/admin/index.js +2 -1
  14. package/dist/admin/index.js.map +1 -1
  15. package/dist/admin/index.mjs +3 -2
  16. package/dist/admin/index.mjs.map +1 -1
  17. package/dist/server/index.js +359 -102
  18. package/dist/server/index.js.map +1 -1
  19. package/dist/server/index.mjs +357 -103
  20. package/dist/server/index.mjs.map +1 -1
  21. package/package.json +13 -11
  22. package/dist/_chunks/App-3f94ba77.mjs.map +0 -1
  23. package/dist/_chunks/App-ae9b2380.js.map +0 -1
  24. package/dist/_chunks/en-13576ce2.js.map +0 -1
  25. package/dist/_chunks/en-e98d8b57.mjs.map +0 -1
  26. package/dist/_chunks/index-40da7f6d.js.map +0 -1
  27. package/dist/_chunks/index-6ddf4a38.mjs.map +0 -1
  28. package/dist/admin/src/components/CMReleasesContainer.d.ts +0 -1
  29. package/dist/admin/src/components/ReleaseActionMenu.d.ts +0 -7
  30. package/dist/admin/src/components/ReleaseActionOptions.d.ts +0 -8
  31. package/dist/admin/src/components/ReleaseModal.d.ts +0 -11
  32. package/dist/admin/src/constants.d.ts +0 -58
  33. package/dist/admin/src/index.d.ts +0 -3
  34. package/dist/admin/src/pages/App.d.ts +0 -1
  35. package/dist/admin/src/pages/ReleaseDetailsPage.d.ts +0 -10
  36. package/dist/admin/src/pages/ReleasesPage.d.ts +0 -11
  37. package/dist/admin/src/pages/tests/mockReleaseDetailsPageData.d.ts +0 -104
  38. package/dist/admin/src/pages/tests/mockReleasesPageData.d.ts +0 -38
  39. package/dist/admin/src/pluginId.d.ts +0 -1
  40. package/dist/admin/src/services/axios.d.ts +0 -29
  41. package/dist/admin/src/services/release.d.ts +0 -348
  42. package/dist/server/src/constants.d.ts +0 -9
  43. package/dist/server/src/constants.d.ts.map +0 -1
  44. package/dist/server/src/content-types/index.d.ts +0 -82
  45. package/dist/server/src/content-types/index.d.ts.map +0 -1
  46. package/dist/server/src/content-types/release/index.d.ts +0 -37
  47. package/dist/server/src/content-types/release/index.d.ts.map +0 -1
  48. package/dist/server/src/content-types/release/schema.d.ts +0 -36
  49. package/dist/server/src/content-types/release/schema.d.ts.map +0 -1
  50. package/dist/server/src/content-types/release-action/index.d.ts +0 -44
  51. package/dist/server/src/content-types/release-action/index.d.ts.map +0 -1
  52. package/dist/server/src/content-types/release-action/schema.d.ts +0 -43
  53. package/dist/server/src/content-types/release-action/schema.d.ts.map +0 -1
  54. package/dist/server/src/controllers/index.d.ts +0 -18
  55. package/dist/server/src/controllers/index.d.ts.map +0 -1
  56. package/dist/server/src/controllers/release-action.d.ts +0 -9
  57. package/dist/server/src/controllers/release-action.d.ts.map +0 -1
  58. package/dist/server/src/controllers/release.d.ts +0 -11
  59. package/dist/server/src/controllers/release.d.ts.map +0 -1
  60. package/dist/server/src/controllers/validation/release-action.d.ts +0 -3
  61. package/dist/server/src/controllers/validation/release-action.d.ts.map +0 -1
  62. package/dist/server/src/controllers/validation/release.d.ts +0 -2
  63. package/dist/server/src/controllers/validation/release.d.ts.map +0 -1
  64. package/dist/server/src/index.d.ts +0 -3749
  65. package/dist/server/src/index.d.ts.map +0 -1
  66. package/dist/server/src/register.d.ts +0 -5
  67. package/dist/server/src/register.d.ts.map +0 -1
  68. package/dist/server/src/routes/index.d.ts +0 -35
  69. package/dist/server/src/routes/index.d.ts.map +0 -1
  70. package/dist/server/src/routes/release-action.d.ts +0 -18
  71. package/dist/server/src/routes/release-action.d.ts.map +0 -1
  72. package/dist/server/src/routes/release.d.ts +0 -18
  73. package/dist/server/src/routes/release.d.ts.map +0 -1
  74. package/dist/server/src/services/index.d.ts +0 -3525
  75. package/dist/server/src/services/index.d.ts.map +0 -1
  76. package/dist/server/src/services/release.d.ts +0 -1779
  77. package/dist/server/src/services/release.d.ts.map +0 -1
  78. package/dist/server/src/services/validation.d.ts +0 -10
  79. package/dist/server/src/services/validation.d.ts.map +0 -1
  80. package/dist/server/src/utils/index.d.ts +0 -4
  81. package/dist/server/src/utils/index.d.ts.map +0 -1
  82. package/dist/shared/contracts/release-actions.d.ts +0 -95
  83. package/dist/shared/contracts/release-actions.d.ts.map +0 -1
  84. package/dist/shared/contracts/releases.d.ts +0 -153
  85. package/dist/shared/contracts/releases.d.ts.map +0 -1
  86. package/dist/shared/types.d.ts +0 -24
  87. package/dist/shared/types.d.ts.map +0 -1
  88. package/dist/shared/validation-schemas.d.ts +0 -2
  89. package/dist/shared/validation-schemas.d.ts.map +0 -1
@@ -1,12 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
+ const helperPlugin = require("@strapi/helper-plugin");
4
5
  const reactRouterDom = require("react-router-dom");
5
- const index = require("./index-40da7f6d.js");
6
+ const index = require("./index-_lT-gI3M.js");
6
7
  const React = require("react");
8
+ const strapiAdmin = require("@strapi/admin/strapi-admin");
7
9
  const designSystem = require("@strapi/design-system");
8
10
  const v2 = require("@strapi/design-system/v2");
9
- const helperPlugin = require("@strapi/helper-plugin");
10
11
  const icons = require("@strapi/icons");
11
12
  const reactIntl = require("react-intl");
12
13
  const styled = require("styled-components");
@@ -15,6 +16,7 @@ const yup = require("yup");
15
16
  require("@reduxjs/toolkit/query");
16
17
  require("axios");
17
18
  require("@reduxjs/toolkit/query/react");
19
+ require("react-redux");
18
20
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
19
21
  function _interopNamespace(e) {
20
22
  if (e && e.__esModule)
@@ -47,11 +49,16 @@ const ReleaseModal = ({
47
49
  isLoading = false
48
50
  }) => {
49
51
  const { formatMessage } = reactIntl.useIntl();
52
+ const { pathname } = reactRouterDom.useLocation();
53
+ const isCreatingRelease = pathname === `/plugins/${index.pluginId}`;
50
54
  return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.ModalLayout, { onClose: handleClose, labelledBy: "title", children: [
51
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.ModalHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "title", fontWeight: "bold", textColor: "neutral800", children: formatMessage({
52
- id: "content-releases.modal.add-release-title",
53
- defaultMessage: "New release"
54
- }) }) }),
55
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.ModalHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "title", fontWeight: "bold", textColor: "neutral800", children: formatMessage(
56
+ {
57
+ id: "content-releases.modal.title",
58
+ defaultMessage: "{isCreatingRelease, select, true {New release} other {Edit release}}"
59
+ },
60
+ { isCreatingRelease }
61
+ ) }) }),
55
62
  /* @__PURE__ */ jsxRuntime.jsx(
56
63
  formik.Formik,
57
64
  {
@@ -78,10 +85,22 @@ const ReleaseModal = ({
78
85
  designSystem.ModalFooter,
79
86
  {
80
87
  startActions: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleClose, variant: "tertiary", name: "cancel", children: formatMessage({ id: "cancel", defaultMessage: "Cancel" }) }),
81
- endActions: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { name: "submit", loading: isLoading, disabled: !values.name, type: "submit", children: formatMessage({
82
- id: "content-releases.modal.form.button.submit",
83
- defaultMessage: "Continue"
84
- }) })
88
+ endActions: /* @__PURE__ */ jsxRuntime.jsx(
89
+ designSystem.Button,
90
+ {
91
+ name: "submit",
92
+ loading: isLoading,
93
+ disabled: !values.name || values.name === initialValues.name,
94
+ type: "submit",
95
+ children: formatMessage(
96
+ {
97
+ id: "content-releases.modal.form.button.submit",
98
+ defaultMessage: "{isCreatingRelease, select, true {Continue} other {Save}}"
99
+ },
100
+ { isCreatingRelease }
101
+ )
102
+ }
103
+ )
85
104
  }
86
105
  )
87
106
  ] })
@@ -120,6 +139,9 @@ const TrashIcon = styled__default.default(icons.Trash)`
120
139
  fill: ${({ theme }) => theme.colors.danger600};
121
140
  }
122
141
  `;
142
+ const TypographyMaxWidth = styled__default.default(designSystem.Typography)`
143
+ max-width: 300px;
144
+ `;
123
145
  const PopoverButton = ({ onClick, disabled, children }) => {
124
146
  return /* @__PURE__ */ jsxRuntime.jsx(
125
147
  StyledFlex,
@@ -138,6 +160,49 @@ const PopoverButton = ({ onClick, disabled, children }) => {
138
160
  }
139
161
  );
140
162
  };
163
+ const EntryValidationText = ({ action, schema, components, entry }) => {
164
+ const { formatMessage } = reactIntl.useIntl();
165
+ const { validate } = strapiAdmin.unstable_useDocument();
166
+ const { errors } = validate(entry, {
167
+ contentType: schema,
168
+ components,
169
+ isCreatingEntry: false
170
+ });
171
+ if (Object.keys(errors).length > 0) {
172
+ const validationErrorsMessages = Object.entries(errors).map(
173
+ ([key, value]) => formatMessage(
174
+ { id: `${value.id}.withField`, defaultMessage: value.defaultMessage },
175
+ { field: key }
176
+ )
177
+ ).join(" ");
178
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
179
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Icon, { color: "danger600", as: icons.CrossCircle }),
180
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tooltip, { description: validationErrorsMessages, children: /* @__PURE__ */ jsxRuntime.jsx(TypographyMaxWidth, { textColor: "danger600", variant: "omega", fontWeight: "semiBold", ellipsis: true, children: validationErrorsMessages }) })
181
+ ] });
182
+ }
183
+ if (action == "publish") {
184
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
185
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Icon, { color: "success600", as: icons.CheckCircle }),
186
+ entry.publishedAt ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
187
+ id: "content-releases.pages.ReleaseDetails.entry-validation.already-published",
188
+ defaultMessage: "Already published"
189
+ }) }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
190
+ id: "content-releases.pages.ReleaseDetails.entry-validation.ready-to-publish",
191
+ defaultMessage: "Ready to publish"
192
+ }) })
193
+ ] });
194
+ }
195
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
196
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Icon, { color: "success600", as: icons.CheckCircle }),
197
+ !entry.publishedAt ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
198
+ id: "content-releases.pages.ReleaseDetails.entry-validation.already-unpublished",
199
+ defaultMessage: "Already unpublished"
200
+ }) }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
201
+ id: "content-releases.pages.ReleaseDetails.entry-validation.ready-to-unpublish",
202
+ defaultMessage: "Ready to unpublish"
203
+ }) })
204
+ ] });
205
+ };
141
206
  const ReleaseDetailsLayout = ({
142
207
  toggleEditReleaseModal,
143
208
  toggleWarningSubmit,
@@ -159,6 +224,7 @@ const ReleaseDetailsLayout = ({
159
224
  const {
160
225
  allowedActions: { canUpdate, canDelete }
161
226
  } = helperPlugin.useRBAC(index.PERMISSIONS);
227
+ const dispatch = index.useTypedDispatch();
162
228
  const release = data?.data;
163
229
  const handleTogglePopover = () => {
164
230
  setIsPopoverVisible((prev) => !prev);
@@ -193,6 +259,9 @@ const ReleaseDetailsLayout = ({
193
259
  toggleWarningSubmit();
194
260
  handleTogglePopover();
195
261
  };
262
+ const handleRefresh = () => {
263
+ dispatch(index.releaseApi.util.invalidateTags([{ type: "ReleaseAction", id: "LIST" }]));
264
+ };
196
265
  if (isLoadingDetails) {
197
266
  return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Main, { "aria-busy": isLoadingDetails, children: /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.LoadingIndicatorPage, {}) });
198
267
  }
@@ -214,7 +283,7 @@ const ReleaseDetailsLayout = ({
214
283
  );
215
284
  }
216
285
  const totalEntries = release.actions.meta.count || 0;
217
- const createdBy = `${release.createdBy.firstname} ${release.createdBy.lastname}`;
286
+ const createdBy = release.createdBy.lastname ? `${release.createdBy.firstname} ${release.createdBy.lastname}` : `${release.createdBy.firstname}`;
218
287
  return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Main, { "aria-busy": isLoadingDetails, children: [
219
288
  /* @__PURE__ */ jsxRuntime.jsx(
220
289
  designSystem.HeaderLayout,
@@ -298,6 +367,10 @@ const ReleaseDetailsLayout = ({
298
367
  ]
299
368
  }
300
369
  ),
370
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { size: "S", variant: "tertiary", onClick: handleRefresh, children: formatMessage({
371
+ id: "content-releases.header.actions.refresh",
372
+ defaultMessage: "Refresh"
373
+ }) }),
301
374
  /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.CheckPermissions, { permissions: index.PERMISSIONS.publish, children: /* @__PURE__ */ jsxRuntime.jsx(
302
375
  designSystem.Button,
303
376
  {
@@ -318,10 +391,29 @@ const ReleaseDetailsLayout = ({
318
391
  children
319
392
  ] });
320
393
  };
394
+ const GROUP_BY_OPTIONS = ["contentType", "locale", "action"];
395
+ const getGroupByOptionLabel = (value) => {
396
+ if (value === "locale") {
397
+ return {
398
+ id: "content-releases.pages.ReleaseDetails.groupBy.option.locales",
399
+ defaultMessage: "Locales"
400
+ };
401
+ }
402
+ if (value === "action") {
403
+ return {
404
+ id: "content-releases.pages.ReleaseDetails.groupBy.option.actions",
405
+ defaultMessage: "Actions"
406
+ };
407
+ }
408
+ return {
409
+ id: "content-releases.pages.ReleaseDetails.groupBy.option.content-type",
410
+ defaultMessage: "Content-Types"
411
+ };
412
+ };
321
413
  const ReleaseDetailsBody = () => {
322
414
  const { formatMessage } = reactIntl.useIntl();
323
415
  const { releaseId } = reactRouterDom.useParams();
324
- const [{ query }] = helperPlugin.useQueryParams();
416
+ const [{ query }, setQuery] = helperPlugin.useQueryParams();
325
417
  const toggleNotification = helperPlugin.useNotification();
326
418
  const { formatAPIError } = helperPlugin.useAPIErrorHandler();
327
419
  const {
@@ -331,6 +423,7 @@ const ReleaseDetailsBody = () => {
331
423
  error: releaseError
332
424
  } = index.useGetReleaseQuery({ id: releaseId });
333
425
  const release = releaseData?.data;
426
+ const selectedGroupBy = query?.groupBy || "contentType";
334
427
  const {
335
428
  isLoading,
336
429
  isFetching,
@@ -342,7 +435,7 @@ const ReleaseDetailsBody = () => {
342
435
  releaseId
343
436
  });
344
437
  const [updateReleaseAction] = index.useUpdateReleaseActionMutation();
345
- const handleChangeType = async (e, actionId) => {
438
+ const handleChangeType = async (e, actionId, actionPath) => {
346
439
  const response = await updateReleaseAction({
347
440
  params: {
348
441
  releaseId,
@@ -350,7 +443,11 @@ const ReleaseDetailsBody = () => {
350
443
  },
351
444
  body: {
352
445
  type: e.target.value
353
- }
446
+ },
447
+ query,
448
+ // We are passing the query params to make optimistic updates
449
+ actionPath
450
+ // We are passing the action path to found the position in the cache of the action for optimistic updates
354
451
  });
355
452
  if ("error" in response) {
356
453
  if (index.isAxiosError(response.error)) {
@@ -369,7 +466,11 @@ const ReleaseDetailsBody = () => {
369
466
  if (isLoading || isReleaseLoading) {
370
467
  return /* @__PURE__ */ jsxRuntime.jsx(designSystem.ContentLayout, { children: /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.LoadingIndicatorPage, {}) });
371
468
  }
372
- if (isError || isReleaseError || !release) {
469
+ const releaseActions = data?.data;
470
+ const releaseMeta = data?.meta;
471
+ const contentTypes = releaseMeta?.contentTypes || {};
472
+ const components = releaseMeta?.components || {};
473
+ if (isReleaseError || !release) {
373
474
  const errorsArray = [];
374
475
  if (releaseError) {
375
476
  errorsArray.push({
@@ -393,9 +494,10 @@ const ReleaseDetailsBody = () => {
393
494
  }
394
495
  );
395
496
  }
396
- const releaseActions = data?.data;
397
- const releaseMeta = data?.meta;
398
- if (!releaseActions || !releaseActions.length) {
497
+ if (isError || !releaseActions) {
498
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.ContentLayout, { children: /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.AnErrorOccurred, {}) });
499
+ }
500
+ if (Object.keys(releaseActions).length === 0) {
399
501
  return /* @__PURE__ */ jsxRuntime.jsx(designSystem.ContentLayout, { children: /* @__PURE__ */ jsxRuntime.jsx(
400
502
  helperPlugin.NoContent,
401
503
  {
@@ -421,92 +523,155 @@ const ReleaseDetailsBody = () => {
421
523
  }
422
524
  ) });
423
525
  }
424
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.ContentLayout, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 4, direction: "column", alignItems: "stretch", children: [
425
- /* @__PURE__ */ jsxRuntime.jsx(
426
- helperPlugin.Table.Root,
526
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.ContentLayout, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 8, direction: "column", alignItems: "stretch", children: [
527
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { children: /* @__PURE__ */ jsxRuntime.jsx(
528
+ designSystem.SingleSelect,
427
529
  {
428
- rows: releaseActions.map((action) => ({
429
- ...action,
430
- id: Number(action.entry.id)
431
- })),
432
- colCount: releaseActions.length,
433
- isLoading,
434
- isFetching,
435
- children: /* @__PURE__ */ jsxRuntime.jsxs(helperPlugin.Table.Content, { children: [
436
- /* @__PURE__ */ jsxRuntime.jsxs(helperPlugin.Table.Head, { children: [
437
- /* @__PURE__ */ jsxRuntime.jsx(
438
- helperPlugin.Table.HeaderCell,
439
- {
440
- fieldSchemaType: "string",
441
- label: formatMessage({
442
- id: "content-releases.page.ReleaseDetails.table.header.label.name",
443
- defaultMessage: "name"
444
- }),
445
- name: "name"
446
- }
447
- ),
448
- /* @__PURE__ */ jsxRuntime.jsx(
449
- helperPlugin.Table.HeaderCell,
450
- {
451
- fieldSchemaType: "string",
452
- label: formatMessage({
453
- id: "content-releases.page.ReleaseDetails.table.header.label.locale",
454
- defaultMessage: "locale"
455
- }),
456
- name: "locale"
457
- }
458
- ),
459
- /* @__PURE__ */ jsxRuntime.jsx(
460
- helperPlugin.Table.HeaderCell,
461
- {
462
- fieldSchemaType: "string",
463
- label: formatMessage({
464
- id: "content-releases.page.ReleaseDetails.table.header.label.content-type",
465
- defaultMessage: "content-type"
466
- }),
467
- name: "content-type"
468
- }
469
- ),
470
- /* @__PURE__ */ jsxRuntime.jsx(
471
- helperPlugin.Table.HeaderCell,
472
- {
473
- fieldSchemaType: "string",
474
- label: formatMessage({
475
- id: "content-releases.page.ReleaseDetails.table.header.label.action",
476
- defaultMessage: "action"
477
- }),
478
- name: "action"
479
- }
480
- ),
481
- /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.Table.HeaderHiddenActionsCell, {})
482
- ] }),
483
- /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.Table.LoadingBody, {}),
484
- /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.Table.Body, { children: releaseActions.map(({ id, type, entry }) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
485
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: `${entry.contentType.mainFieldValue || entry.id}` }) }),
486
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: `${entry?.locale?.name ? entry.locale.name : "-"}` }) }),
487
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: entry.contentType.displayName || "" }) }),
488
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: release.releasedAt ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage(
489
- {
490
- id: "content-releases.page.ReleaseDetails.table.action-published",
491
- defaultMessage: "This entry was <b>{isPublish, select, true {published} other {unpublished}}</b>."
492
- },
493
- {
494
- isPublish: type === "publish",
495
- b: (children) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children })
496
- }
497
- ) }) : /* @__PURE__ */ jsxRuntime.jsx(
498
- index.ReleaseActionOptions,
499
- {
500
- selected: type,
501
- handleChange: (e) => handleChangeType(e, id),
502
- name: `release-action-${id}-type`
503
- }
504
- ) }),
505
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "flex-end", children: /* @__PURE__ */ jsxRuntime.jsx(index.ReleaseActionMenu, { releaseId, actionId: id }) }) })
506
- ] }, id)) })
507
- ] })
530
+ "aria-label": formatMessage({
531
+ id: "content-releases.pages.ReleaseDetails.groupBy.label",
532
+ defaultMessage: "Group by"
533
+ }),
534
+ customizeContent: (value) => formatMessage(
535
+ {
536
+ id: `content-releases.pages.ReleaseDetails.groupBy.label`,
537
+ defaultMessage: `Group by {groupBy}`
538
+ },
539
+ {
540
+ groupBy: value
541
+ }
542
+ ),
543
+ value: formatMessage(getGroupByOptionLabel(selectedGroupBy)),
544
+ onChange: (value) => setQuery({ groupBy: value }),
545
+ children: GROUP_BY_OPTIONS.map((option) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: option, children: formatMessage(getGroupByOptionLabel(option)) }, option))
508
546
  }
509
- ),
547
+ ) }),
548
+ Object.keys(releaseActions).map((key) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 4, direction: "column", alignItems: "stretch", children: [
549
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { children: key }) }),
550
+ /* @__PURE__ */ jsxRuntime.jsx(
551
+ helperPlugin.Table.Root,
552
+ {
553
+ rows: releaseActions[key].map((item) => ({
554
+ ...item,
555
+ id: Number(item.entry.id)
556
+ })),
557
+ colCount: releaseActions[key].length,
558
+ isLoading,
559
+ isFetching,
560
+ children: /* @__PURE__ */ jsxRuntime.jsxs(helperPlugin.Table.Content, { children: [
561
+ /* @__PURE__ */ jsxRuntime.jsxs(helperPlugin.Table.Head, { children: [
562
+ /* @__PURE__ */ jsxRuntime.jsx(
563
+ helperPlugin.Table.HeaderCell,
564
+ {
565
+ fieldSchemaType: "string",
566
+ label: formatMessage({
567
+ id: "content-releases.page.ReleaseDetails.table.header.label.name",
568
+ defaultMessage: "name"
569
+ }),
570
+ name: "name"
571
+ }
572
+ ),
573
+ /* @__PURE__ */ jsxRuntime.jsx(
574
+ helperPlugin.Table.HeaderCell,
575
+ {
576
+ fieldSchemaType: "string",
577
+ label: formatMessage({
578
+ id: "content-releases.page.ReleaseDetails.table.header.label.locale",
579
+ defaultMessage: "locale"
580
+ }),
581
+ name: "locale"
582
+ }
583
+ ),
584
+ /* @__PURE__ */ jsxRuntime.jsx(
585
+ helperPlugin.Table.HeaderCell,
586
+ {
587
+ fieldSchemaType: "string",
588
+ label: formatMessage({
589
+ id: "content-releases.page.ReleaseDetails.table.header.label.content-type",
590
+ defaultMessage: "content-type"
591
+ }),
592
+ name: "content-type"
593
+ }
594
+ ),
595
+ /* @__PURE__ */ jsxRuntime.jsx(
596
+ helperPlugin.Table.HeaderCell,
597
+ {
598
+ fieldSchemaType: "string",
599
+ label: formatMessage({
600
+ id: "content-releases.page.ReleaseDetails.table.header.label.action",
601
+ defaultMessage: "action"
602
+ }),
603
+ name: "action"
604
+ }
605
+ ),
606
+ !release.releasedAt && /* @__PURE__ */ jsxRuntime.jsx(
607
+ helperPlugin.Table.HeaderCell,
608
+ {
609
+ fieldSchemaType: "string",
610
+ label: formatMessage({
611
+ id: "content-releases.page.ReleaseDetails.table.header.label.status",
612
+ defaultMessage: "status"
613
+ }),
614
+ name: "status"
615
+ }
616
+ )
617
+ ] }),
618
+ /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.Table.LoadingBody, {}),
619
+ /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.Table.Body, { children: releaseActions[key].map(
620
+ ({ id, contentType, locale, type, entry }, actionIndex) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
621
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { width: "25%", maxWidth: "200px", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { ellipsis: true, children: `${contentType.mainFieldValue || entry.id}` }) }),
622
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { width: "10%", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: `${locale?.name ? locale.name : "-"}` }) }),
623
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { width: "10%", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: contentType.displayName || "" }) }),
624
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { width: "20%", children: release.releasedAt ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage(
625
+ {
626
+ id: "content-releases.page.ReleaseDetails.table.action-published",
627
+ defaultMessage: "This entry was <b>{isPublish, select, true {published} other {unpublished}}</b>."
628
+ },
629
+ {
630
+ isPublish: type === "publish",
631
+ b: (children) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children })
632
+ }
633
+ ) }) : /* @__PURE__ */ jsxRuntime.jsx(
634
+ index.ReleaseActionOptions,
635
+ {
636
+ selected: type,
637
+ handleChange: (e) => handleChangeType(e, id, [key, actionIndex]),
638
+ name: `release-action-${id}-type`
639
+ }
640
+ ) }),
641
+ !release.releasedAt && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
642
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { width: "20%", minWidth: "200px", children: /* @__PURE__ */ jsxRuntime.jsx(
643
+ EntryValidationText,
644
+ {
645
+ action: type,
646
+ schema: contentTypes?.[contentType.uid],
647
+ components,
648
+ entry
649
+ }
650
+ ) }),
651
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "flex-end", children: /* @__PURE__ */ jsxRuntime.jsxs(index.ReleaseActionMenu.Root, { children: [
652
+ /* @__PURE__ */ jsxRuntime.jsx(
653
+ index.ReleaseActionMenu.ReleaseActionEntryLinkItem,
654
+ {
655
+ contentTypeUid: contentType.uid,
656
+ entryId: entry.id,
657
+ locale: locale?.code
658
+ }
659
+ ),
660
+ /* @__PURE__ */ jsxRuntime.jsx(
661
+ index.ReleaseActionMenu.DeleteReleaseActionItem,
662
+ {
663
+ releaseId: release.id,
664
+ actionId: id
665
+ }
666
+ )
667
+ ] }) }) })
668
+ ] })
669
+ ] }, id)
670
+ ) })
671
+ ] })
672
+ }
673
+ )
674
+ ] }, `releases-group-${key}`)),
510
675
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { paddingTop: 4, alignItems: "flex-end", justifyContent: "space-between", children: [
511
676
  /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.PageSizeURLQuery, { defaultValue: releaseMeta?.pagination?.pageSize.toString() }),
512
677
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -627,38 +792,6 @@ const ReleaseDetailsPage = () => {
627
792
  }
628
793
  );
629
794
  };
630
- const ProtectedReleaseDetailsPage = () => /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.CheckPermissions, { permissions: index.PERMISSIONS.main, children: /* @__PURE__ */ jsxRuntime.jsx(ReleaseDetailsPage, {}) });
631
- const ReleasesLayout = ({
632
- isLoading,
633
- totalReleases,
634
- onClickAddRelease,
635
- children
636
- }) => {
637
- const { formatMessage } = reactIntl.useIntl();
638
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Main, { "aria-busy": isLoading, children: [
639
- /* @__PURE__ */ jsxRuntime.jsx(
640
- designSystem.HeaderLayout,
641
- {
642
- title: formatMessage({
643
- id: "content-releases.pages.Releases.title",
644
- defaultMessage: "Releases"
645
- }),
646
- subtitle: !isLoading && formatMessage(
647
- {
648
- id: "content-releases.pages.Releases.header-subtitle",
649
- defaultMessage: "{number, plural, =0 {No releases} one {# release} other {# releases}}"
650
- },
651
- { number: totalReleases }
652
- ),
653
- primaryAction: /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.CheckPermissions, { permissions: index.PERMISSIONS.create, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}), onClick: onClickAddRelease, children: formatMessage({
654
- id: "content-releases.header.actions.add-release",
655
- defaultMessage: "New release"
656
- }) }) })
657
- }
658
- ),
659
- children
660
- ] });
661
- };
662
795
  const LinkCard = styled__default.default(v2.Link)`
663
796
  display: block;
664
797
  `;
@@ -710,10 +843,19 @@ const ReleasesGrid = ({ sectionTitle, releases = [], isError = false }) => {
710
843
  }
711
844
  ) }) }, id)) });
712
845
  };
846
+ const StyledAlert = styled__default.default(designSystem.Alert)`
847
+ button {
848
+ display: none;
849
+ }
850
+ p + div {
851
+ margin-left: auto;
852
+ }
853
+ `;
713
854
  const INITIAL_FORM_VALUES = {
714
855
  name: ""
715
856
  };
716
857
  const ReleasesPage = () => {
858
+ const tabRef = React__namespace.useRef(null);
717
859
  const location = reactRouterDom.useLocation();
718
860
  const [releaseModalShown, setReleaseModalShown] = React__namespace.useState(false);
719
861
  const toggleNotification = helperPlugin.useNotification();
@@ -723,7 +865,11 @@ const ReleasesPage = () => {
723
865
  const [{ query }, setQuery] = helperPlugin.useQueryParams();
724
866
  const response = index.useGetReleasesQuery(query);
725
867
  const [createRelease, { isLoading: isSubmittingForm }] = index.useCreateReleaseMutation();
868
+ const { getFeature } = strapiAdmin.useLicenseLimits();
869
+ const { maximumNumberOfPendingReleases = 3 } = getFeature("cms-content-releases");
726
870
  const { isLoading, isSuccess, isError } = response;
871
+ const activeTab = response?.currentData?.meta?.activeTab || "pending";
872
+ const activeTabIndex = ["pending", "done"].indexOf(activeTab);
727
873
  React__namespace.useEffect(() => {
728
874
  if (location?.state?.errors) {
729
875
  toggleNotification({
@@ -740,13 +886,19 @@ const ReleasesPage = () => {
740
886
  replace({ state: null });
741
887
  }
742
888
  }, [formatMessage, location?.state?.errors, replace, toggleNotification]);
889
+ React__namespace.useEffect(() => {
890
+ if (tabRef.current) {
891
+ tabRef.current._handlers.setSelectedTabIndex(activeTabIndex);
892
+ }
893
+ }, [activeTabIndex]);
743
894
  const toggleAddReleaseModal = () => {
744
895
  setReleaseModalShown((prev) => !prev);
745
896
  };
746
897
  if (isLoading) {
747
- return /* @__PURE__ */ jsxRuntime.jsx(ReleasesLayout, { onClickAddRelease: toggleAddReleaseModal, isLoading: true, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.ContentLayout, { children: /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.LoadingIndicatorPage, {}) }) });
898
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Main, { "aria-busy": isLoading, children: /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.LoadingIndicatorPage, {}) });
748
899
  }
749
900
  const totalReleases = isSuccess && response.currentData?.meta?.pagination?.total || 0;
901
+ const hasReachedMaximumPendingReleases = totalReleases >= maximumNumberOfPendingReleases;
750
902
  const handleTabChange = (index2) => {
751
903
  setQuery({
752
904
  ...query,
@@ -759,7 +911,6 @@ const ReleasesPage = () => {
759
911
  }
760
912
  });
761
913
  };
762
- const activeTab = response?.currentData?.meta?.activeTab || "pending";
763
914
  const handleAddRelease = async (values) => {
764
915
  const response2 = await createRelease({
765
916
  name: values.name
@@ -785,8 +936,60 @@ const ReleasesPage = () => {
785
936
  });
786
937
  }
787
938
  };
788
- return /* @__PURE__ */ jsxRuntime.jsxs(ReleasesLayout, { onClickAddRelease: toggleAddReleaseModal, totalReleases, children: [
939
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Main, { "aria-busy": isLoading, children: [
940
+ /* @__PURE__ */ jsxRuntime.jsx(
941
+ designSystem.HeaderLayout,
942
+ {
943
+ title: formatMessage({
944
+ id: "content-releases.pages.Releases.title",
945
+ defaultMessage: "Releases"
946
+ }),
947
+ subtitle: formatMessage(
948
+ {
949
+ id: "content-releases.pages.Releases.header-subtitle",
950
+ defaultMessage: "{number, plural, =0 {No releases} one {# release} other {# releases}}"
951
+ },
952
+ { number: totalReleases }
953
+ ),
954
+ primaryAction: /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.CheckPermissions, { permissions: index.PERMISSIONS.create, children: /* @__PURE__ */ jsxRuntime.jsx(
955
+ designSystem.Button,
956
+ {
957
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
958
+ onClick: toggleAddReleaseModal,
959
+ disabled: hasReachedMaximumPendingReleases,
960
+ children: formatMessage({
961
+ id: "content-releases.header.actions.add-release",
962
+ defaultMessage: "New release"
963
+ })
964
+ }
965
+ ) })
966
+ }
967
+ ),
789
968
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.ContentLayout, { children: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
969
+ activeTab === "pending" && hasReachedMaximumPendingReleases && /* @__PURE__ */ jsxRuntime.jsx(
970
+ StyledAlert,
971
+ {
972
+ marginBottom: 6,
973
+ action: /* @__PURE__ */ jsxRuntime.jsx(v2.Link, { href: "https://strapi.io/pricing-cloud", isExternal: true, children: formatMessage({
974
+ id: "content-releases.pages.Releases.max-limit-reached.action",
975
+ defaultMessage: "Explore plans"
976
+ }) }),
977
+ title: formatMessage(
978
+ {
979
+ id: "content-releases.pages.Releases.max-limit-reached.title",
980
+ defaultMessage: "You have reached the {number} pending {number, plural, one {release} other {releases}} limit."
981
+ },
982
+ { number: maximumNumberOfPendingReleases }
983
+ ),
984
+ onClose: () => {
985
+ },
986
+ closeLabel: "",
987
+ children: formatMessage({
988
+ id: "content-releases.pages.Releases.max-limit-reached.message",
989
+ defaultMessage: "Upgrade to manage an unlimited number of releases."
990
+ })
991
+ }
992
+ ),
790
993
  /* @__PURE__ */ jsxRuntime.jsxs(
791
994
  designSystem.TabGroup,
792
995
  {
@@ -795,8 +998,9 @@ const ReleasesPage = () => {
795
998
  defaultMessage: "Releases list"
796
999
  }),
797
1000
  variant: "simple",
798
- initialSelectedTabIndex: ["pending", "done"].indexOf(activeTab),
1001
+ initialSelectedTabIndex: activeTabIndex,
799
1002
  onTabChange: handleTabChange,
1003
+ ref: tabRef,
800
1004
  children: [
801
1005
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { paddingBottom: 8, children: [
802
1006
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tabs, { children: [
@@ -861,19 +1065,11 @@ const ReleasesPage = () => {
861
1065
  )
862
1066
  ] });
863
1067
  };
864
- const ProtectedReleasesPage = () => /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.CheckPermissions, { permissions: index.PERMISSIONS.main, children: /* @__PURE__ */ jsxRuntime.jsx(ReleasesPage, {}) });
865
1068
  const App = () => {
866
- return /* @__PURE__ */ jsxRuntime.jsxs(reactRouterDom.Switch, { children: [
867
- /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { exact: true, path: `/plugins/${index.pluginId}`, component: ProtectedReleasesPage }),
868
- /* @__PURE__ */ jsxRuntime.jsx(
869
- reactRouterDom.Route,
870
- {
871
- exact: true,
872
- path: `/plugins/${index.pluginId}/:releaseId`,
873
- component: ProtectedReleaseDetailsPage
874
- }
875
- )
876
- ] });
1069
+ return /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.CheckPagePermissions, { permissions: index.PERMISSIONS.main, children: /* @__PURE__ */ jsxRuntime.jsxs(reactRouterDom.Switch, { children: [
1070
+ /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { exact: true, path: `/plugins/${index.pluginId}`, component: ReleasesPage }),
1071
+ /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { exact: true, path: `/plugins/${index.pluginId}/:releaseId`, component: ReleaseDetailsPage })
1072
+ ] }) });
877
1073
  };
878
1074
  exports.App = App;
879
- //# sourceMappingURL=App-ae9b2380.js.map
1075
+ //# sourceMappingURL=App-iqqoPnBO.js.map