@strapi/content-releases 4.16.2 → 4.18.0

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 (87) hide show
  1. package/dist/_chunks/{App-b83f4a97.mjs → App-g2P5kbSm.mjs} +341 -171
  2. package/dist/_chunks/App-g2P5kbSm.mjs.map +1 -0
  3. package/dist/_chunks/{App-b6df6b60.js → App-o5_WfqR-.js} +337 -167
  4. package/dist/_chunks/App-o5_WfqR-.js.map +1 -0
  5. package/dist/_chunks/{en-b5dfabe6.js → en-haKSQIo8.js} +19 -4
  6. package/dist/_chunks/en-haKSQIo8.js.map +1 -0
  7. package/dist/_chunks/{en-d837b82d.mjs → en-ngTk74JV.mjs} +19 -4
  8. package/dist/_chunks/en-ngTk74JV.mjs.map +1 -0
  9. package/dist/_chunks/{index-28e99164.js → index-EdBmRHRU.js} +96 -31
  10. package/dist/_chunks/index-EdBmRHRU.js.map +1 -0
  11. package/dist/_chunks/{index-c39292e3.mjs → index-XAQOX_IB.mjs} +101 -36
  12. package/dist/_chunks/index-XAQOX_IB.mjs.map +1 -0
  13. package/dist/admin/index.js +2 -2
  14. package/dist/admin/index.mjs +3 -3
  15. package/dist/server/index.js +60 -35
  16. package/dist/server/index.js.map +1 -1
  17. package/dist/server/index.mjs +58 -35
  18. package/dist/server/index.mjs.map +1 -1
  19. package/package.json +11 -10
  20. package/dist/_chunks/App-b6df6b60.js.map +0 -1
  21. package/dist/_chunks/App-b83f4a97.mjs.map +0 -1
  22. package/dist/_chunks/en-b5dfabe6.js.map +0 -1
  23. package/dist/_chunks/en-d837b82d.mjs.map +0 -1
  24. package/dist/_chunks/index-28e99164.js.map +0 -1
  25. package/dist/_chunks/index-c39292e3.mjs.map +0 -1
  26. package/dist/admin/src/components/CMReleasesContainer.d.ts +0 -1
  27. package/dist/admin/src/components/ReleaseActionMenu.d.ts +0 -7
  28. package/dist/admin/src/components/ReleaseActionOptions.d.ts +0 -8
  29. package/dist/admin/src/components/ReleaseModal.d.ts +0 -11
  30. package/dist/admin/src/constants.d.ts +0 -13
  31. package/dist/admin/src/index.d.ts +0 -3
  32. package/dist/admin/src/pages/App.d.ts +0 -1
  33. package/dist/admin/src/pages/ReleaseDetailsPage.d.ts +0 -10
  34. package/dist/admin/src/pages/ReleasesPage.d.ts +0 -11
  35. package/dist/admin/src/pages/tests/mockReleaseDetailsPageData.d.ts +0 -104
  36. package/dist/admin/src/pages/tests/mockReleasesPageData.d.ts +0 -38
  37. package/dist/admin/src/pluginId.d.ts +0 -1
  38. package/dist/admin/src/services/axios.d.ts +0 -29
  39. package/dist/admin/src/services/release.d.ts +0 -348
  40. package/dist/server/src/constants.d.ts +0 -9
  41. package/dist/server/src/constants.d.ts.map +0 -1
  42. package/dist/server/src/content-types/index.d.ts +0 -82
  43. package/dist/server/src/content-types/index.d.ts.map +0 -1
  44. package/dist/server/src/content-types/release/index.d.ts +0 -37
  45. package/dist/server/src/content-types/release/index.d.ts.map +0 -1
  46. package/dist/server/src/content-types/release/schema.d.ts +0 -36
  47. package/dist/server/src/content-types/release/schema.d.ts.map +0 -1
  48. package/dist/server/src/content-types/release-action/index.d.ts +0 -44
  49. package/dist/server/src/content-types/release-action/index.d.ts.map +0 -1
  50. package/dist/server/src/content-types/release-action/schema.d.ts +0 -43
  51. package/dist/server/src/content-types/release-action/schema.d.ts.map +0 -1
  52. package/dist/server/src/controllers/index.d.ts +0 -18
  53. package/dist/server/src/controllers/index.d.ts.map +0 -1
  54. package/dist/server/src/controllers/release-action.d.ts +0 -9
  55. package/dist/server/src/controllers/release-action.d.ts.map +0 -1
  56. package/dist/server/src/controllers/release.d.ts +0 -11
  57. package/dist/server/src/controllers/release.d.ts.map +0 -1
  58. package/dist/server/src/controllers/validation/release-action.d.ts +0 -3
  59. package/dist/server/src/controllers/validation/release-action.d.ts.map +0 -1
  60. package/dist/server/src/controllers/validation/release.d.ts +0 -2
  61. package/dist/server/src/controllers/validation/release.d.ts.map +0 -1
  62. package/dist/server/src/index.d.ts +0 -301
  63. package/dist/server/src/index.d.ts.map +0 -1
  64. package/dist/server/src/register.d.ts +0 -5
  65. package/dist/server/src/register.d.ts.map +0 -1
  66. package/dist/server/src/routes/index.d.ts +0 -35
  67. package/dist/server/src/routes/index.d.ts.map +0 -1
  68. package/dist/server/src/routes/release-action.d.ts +0 -18
  69. package/dist/server/src/routes/release-action.d.ts.map +0 -1
  70. package/dist/server/src/routes/release.d.ts +0 -18
  71. package/dist/server/src/routes/release.d.ts.map +0 -1
  72. package/dist/server/src/services/index.d.ts +0 -77
  73. package/dist/server/src/services/index.d.ts.map +0 -1
  74. package/dist/server/src/services/release.d.ts +0 -55
  75. package/dist/server/src/services/release.d.ts.map +0 -1
  76. package/dist/server/src/services/validation.d.ts +0 -10
  77. package/dist/server/src/services/validation.d.ts.map +0 -1
  78. package/dist/server/src/utils/index.d.ts +0 -4
  79. package/dist/server/src/utils/index.d.ts.map +0 -1
  80. package/dist/shared/contracts/release-actions.d.ts +0 -95
  81. package/dist/shared/contracts/release-actions.d.ts.map +0 -1
  82. package/dist/shared/contracts/releases.d.ts +0 -153
  83. package/dist/shared/contracts/releases.d.ts.map +0 -1
  84. package/dist/shared/types.d.ts +0 -24
  85. package/dist/shared/types.d.ts.map +0 -1
  86. package/dist/shared/validation-schemas.d.ts +0 -2
  87. package/dist/shared/validation-schemas.d.ts.map +0 -1
@@ -1,15 +1,15 @@
1
1
  import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
- import { useParams, useHistory, Switch, Route } from "react-router-dom";
3
- import { P as PERMISSIONS, u as useGetReleaseQuery, a as useUpdateReleaseMutation, b as useDeleteReleaseMutation, c as usePublishReleaseMutation, d as useGetReleaseActionsQuery, e as useUpdateReleaseActionMutation, R as ReleaseActionOptions, i as isAxiosError, f as useGetReleasesQuery, g as useCreateReleaseMutation, p as pluginId } from "./index-c39292e3.mjs";
2
+ import { useNotification, useAPIErrorHandler, LoadingIndicatorPage, ConfirmDialog, useRBAC, RelativeTime, CheckPermissions, useQueryParams, NoContent, Table, PageSizeURLQuery, PaginationURLQuery, AnErrorOccurred, CheckPagePermissions } from "@strapi/helper-plugin";
3
+ import { useLocation, useParams, useHistory, Redirect, Link as Link$1, Switch, Route } from "react-router-dom";
4
+ import { p as pluginId, u as useGetReleaseQuery, a as useUpdateReleaseMutation, b as useDeleteReleaseMutation, c as usePublishReleaseMutation, P as PERMISSIONS, d as useGetReleaseActionsQuery, e as useUpdateReleaseActionMutation, R as ReleaseActionOptions, f as ReleaseActionMenu, i as isAxiosError, g as useGetReleasesQuery, h as useCreateReleaseMutation } from "./index-XAQOX_IB.mjs";
4
5
  import * as React from "react";
5
- import { ModalLayout, ModalHeader, Typography, ModalBody, TextInput, ModalFooter, Button, Flex, ContentLayout, Main, Box, HeaderLayout, Link, IconButton, Popover, EmptyStateLayout, Tr, Td, TabGroup, Tabs, Tab, TabPanels, TabPanel, Grid, GridItem } from "@strapi/design-system";
6
- import { CheckPermissions, useNotification, useAPIErrorHandler, LoadingIndicatorPage, ConfirmDialog, AnErrorOccurred, RelativeTime, useQueryParams, Table, PageSizeURLQuery, PaginationURLQuery } from "@strapi/helper-plugin";
7
- import { Pencil, Trash, ArrowLeft, More, EmptyDocuments, Plus } from "@strapi/icons";
6
+ import { ModalLayout, ModalHeader, Typography, ModalBody, TextInput, ModalFooter, Button, Flex, ContentLayout, Main, HeaderLayout, Link, IconButton, Popover, SingleSelect, SingleSelectOption, Badge, Tr, Td, Icon, TabGroup, Box, Tabs, Tab, Divider, TabPanels, TabPanel, EmptyStateLayout, Grid, GridItem } from "@strapi/design-system";
7
+ import { LinkButton, Link as Link$2 } from "@strapi/design-system/v2";
8
+ import { Pencil, Trash, ArrowLeft, More, CheckCircle, Plus, EmptyDocuments } from "@strapi/icons";
8
9
  import { useIntl } from "react-intl";
9
10
  import styled from "styled-components";
10
11
  import { Formik, Form } from "formik";
11
12
  import * as yup from "yup";
12
- import { Link as Link$1 } from "@strapi/design-system/v2";
13
13
  import "@reduxjs/toolkit/query";
14
14
  import "axios";
15
15
  import "@reduxjs/toolkit/query/react";
@@ -23,11 +23,16 @@ const ReleaseModal = ({
23
23
  isLoading = false
24
24
  }) => {
25
25
  const { formatMessage } = useIntl();
26
+ const { pathname } = useLocation();
27
+ const isCreatingRelease = pathname === `/plugins/${pluginId}`;
26
28
  return /* @__PURE__ */ jsxs(ModalLayout, { onClose: handleClose, labelledBy: "title", children: [
27
- /* @__PURE__ */ jsx(ModalHeader, { children: /* @__PURE__ */ jsx(Typography, { id: "title", fontWeight: "bold", textColor: "neutral800", children: formatMessage({
28
- id: "content-releases.modal.add-release-title",
29
- defaultMessage: "New release"
30
- }) }) }),
29
+ /* @__PURE__ */ jsx(ModalHeader, { children: /* @__PURE__ */ jsx(Typography, { id: "title", fontWeight: "bold", textColor: "neutral800", children: formatMessage(
30
+ {
31
+ id: "content-releases.modal.title",
32
+ defaultMessage: "{isCreatingRelease, select, true {New release} other {Edit release}}"
33
+ },
34
+ { isCreatingRelease }
35
+ ) }) }),
31
36
  /* @__PURE__ */ jsx(
32
37
  Formik,
33
38
  {
@@ -54,10 +59,22 @@ const ReleaseModal = ({
54
59
  ModalFooter,
55
60
  {
56
61
  startActions: /* @__PURE__ */ jsx(Button, { onClick: handleClose, variant: "tertiary", name: "cancel", children: formatMessage({ id: "cancel", defaultMessage: "Cancel" }) }),
57
- endActions: /* @__PURE__ */ jsx(Button, { name: "submit", loading: isLoading, disabled: !values.name, type: "submit", children: formatMessage({
58
- id: "content-releases.modal.form.button.submit",
59
- defaultMessage: "Continue"
60
- }) })
62
+ endActions: /* @__PURE__ */ jsx(
63
+ Button,
64
+ {
65
+ name: "submit",
66
+ loading: isLoading,
67
+ disabled: !values.name || values.name === initialValues.name,
68
+ type: "submit",
69
+ children: formatMessage(
70
+ {
71
+ id: "content-releases.modal.form.button.submit",
72
+ defaultMessage: "{isCreatingRelease, select, true {Continue} other {Save}}"
73
+ },
74
+ { isCreatingRelease }
75
+ )
76
+ }
77
+ )
61
78
  }
62
79
  )
63
80
  ] })
@@ -73,6 +90,14 @@ const ReleaseInfoWrapper = styled(Flex)`
73
90
  `;
74
91
  const StyledFlex = styled(Flex)`
75
92
  align-self: stretch;
93
+ cursor: ${({ disabled }) => disabled ? "not-allowed" : "pointer"};
94
+
95
+ svg path {
96
+ fill: ${({ theme, disabled }) => disabled && theme.colors.neutral500};
97
+ }
98
+ span {
99
+ color: ${({ theme, disabled }) => disabled && theme.colors.neutral500};
100
+ }
76
101
  `;
77
102
  const PencilIcon = styled(Pencil)`
78
103
  width: ${({ theme }) => theme.spaces[4]};
@@ -88,7 +113,7 @@ const TrashIcon = styled(Trash)`
88
113
  fill: ${({ theme }) => theme.colors.danger600};
89
114
  }
90
115
  `;
91
- const PopoverButton = ({ onClick, children }) => {
116
+ const PopoverButton = ({ onClick, disabled, children }) => {
92
117
  return /* @__PURE__ */ jsx(
93
118
  StyledFlex,
94
119
  {
@@ -101,10 +126,36 @@ const PopoverButton = ({ onClick, children }) => {
101
126
  as: "button",
102
127
  hasRadius: true,
103
128
  onClick,
129
+ disabled,
104
130
  children
105
131
  }
106
132
  );
107
133
  };
134
+ const EntryValidationText = ({ status, action }) => {
135
+ const { formatMessage } = useIntl();
136
+ if (action == "publish") {
137
+ return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
138
+ /* @__PURE__ */ jsx(Icon, { color: "success600", as: CheckCircle }),
139
+ status === "published" ? /* @__PURE__ */ jsx(Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
140
+ id: "content-releases.pages.ReleaseDetails.entry-validation.already-published",
141
+ defaultMessage: "Already published"
142
+ }) }) : /* @__PURE__ */ jsx(Typography, { children: formatMessage({
143
+ id: "content-releases.pages.ReleaseDetails.entry-validation.ready-to-publish",
144
+ defaultMessage: "Ready to publish"
145
+ }) })
146
+ ] });
147
+ }
148
+ return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
149
+ /* @__PURE__ */ jsx(Icon, { color: "success600", as: CheckCircle }),
150
+ status === "draft" ? /* @__PURE__ */ jsx(Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
151
+ id: "content-releases.pages.ReleaseDetails.entry-validation.already-unpublished",
152
+ defaultMessage: "Already unpublished"
153
+ }) }) : /* @__PURE__ */ jsx(Typography, { children: formatMessage({
154
+ id: "content-releases.pages.ReleaseDetails.entry-validation.ready-to-unpublish",
155
+ defaultMessage: "Ready to unpublish"
156
+ }) })
157
+ ] });
158
+ };
108
159
  const ReleaseDetailsLayout = ({
109
160
  toggleEditReleaseModal,
110
161
  toggleWarningSubmit,
@@ -114,10 +165,18 @@ const ReleaseDetailsLayout = ({
114
165
  const { releaseId } = useParams();
115
166
  const [isPopoverVisible, setIsPopoverVisible] = React.useState(false);
116
167
  const moreButtonRef = React.useRef(null);
117
- const { data, isLoading: isLoadingDetails, isError } = useGetReleaseQuery({ id: releaseId });
168
+ const {
169
+ data,
170
+ isLoading: isLoadingDetails,
171
+ isError,
172
+ error
173
+ } = useGetReleaseQuery({ id: releaseId });
118
174
  const [publishRelease, { isLoading: isPublishing }] = usePublishReleaseMutation();
119
175
  const toggleNotification = useNotification();
120
176
  const { formatAPIError } = useAPIErrorHandler();
177
+ const {
178
+ allowedActions: { canUpdate, canDelete }
179
+ } = useRBAC(PERMISSIONS);
121
180
  const release = data?.data;
122
181
  const handleTogglePopover = () => {
123
182
  setIsPopoverVisible((prev) => !prev);
@@ -153,15 +212,29 @@ const ReleaseDetailsLayout = ({
153
212
  handleTogglePopover();
154
213
  };
155
214
  if (isLoadingDetails) {
156
- return /* @__PURE__ */ jsx(Main, { "aria-busy": isLoadingDetails, children: /* @__PURE__ */ jsx(Box, { paddingBottom: 8, children: /* @__PURE__ */ jsx(LoadingIndicatorPage, {}) }) });
215
+ return /* @__PURE__ */ jsx(Main, { "aria-busy": isLoadingDetails, children: /* @__PURE__ */ jsx(LoadingIndicatorPage, {}) });
157
216
  }
158
217
  if (isError || !release) {
159
- return /* @__PURE__ */ jsx(Main, { children: /* @__PURE__ */ jsx(Box, { paddingBottom: 8, children: /* @__PURE__ */ jsx(AnErrorOccurred, {}) }) });
218
+ return /* @__PURE__ */ jsx(
219
+ Redirect,
220
+ {
221
+ to: {
222
+ pathname: "/plugins/content-releases",
223
+ state: {
224
+ errors: [
225
+ {
226
+ code: error?.code
227
+ }
228
+ ]
229
+ }
230
+ }
231
+ }
232
+ );
160
233
  }
161
234
  const totalEntries = release.actions.meta.count || 0;
162
- const createdBy = `${release.createdBy.firstname} ${release.createdBy.lastname}`;
235
+ const createdBy = release.createdBy.lastname ? `${release.createdBy.firstname} ${release.createdBy.lastname}` : `${release.createdBy.firstname}`;
163
236
  return /* @__PURE__ */ jsxs(Main, { "aria-busy": isLoadingDetails, children: [
164
- /* @__PURE__ */ jsx(Box, { paddingBottom: 8, children: /* @__PURE__ */ jsx(
237
+ /* @__PURE__ */ jsx(
165
238
  HeaderLayout,
166
239
  {
167
240
  title: release.name,
@@ -198,31 +271,22 @@ const ReleaseDetailsLayout = ({
198
271
  spacing: 4,
199
272
  minWidth: "242px",
200
273
  children: [
201
- /* @__PURE__ */ jsxs(
202
- Flex,
203
- {
204
- alignItems: "center",
205
- justifyContent: "center",
206
- direction: "column",
207
- padding: 1,
208
- children: [
209
- /* @__PURE__ */ jsx(CheckPermissions, { permissions: PERMISSIONS.update, children: /* @__PURE__ */ jsxs(PopoverButton, { onClick: openReleaseModal, children: [
210
- /* @__PURE__ */ jsx(PencilIcon, {}),
211
- /* @__PURE__ */ jsx(Typography, { ellipsis: true, children: formatMessage({
212
- id: "content-releases.header.actions.edit",
213
- defaultMessage: "Edit"
214
- }) })
215
- ] }) }),
216
- /* @__PURE__ */ jsx(CheckPermissions, { permissions: PERMISSIONS.delete, children: /* @__PURE__ */ jsxs(PopoverButton, { onClick: openWarningConfirmDialog, children: [
217
- /* @__PURE__ */ jsx(TrashIcon, {}),
218
- /* @__PURE__ */ jsx(Typography, { ellipsis: true, textColor: "danger600", children: formatMessage({
219
- id: "content-releases.header.actions.delete",
220
- defaultMessage: "Delete"
221
- }) })
222
- ] }) })
223
- ]
224
- }
225
- ),
274
+ /* @__PURE__ */ jsxs(Flex, { alignItems: "center", justifyContent: "center", direction: "column", padding: 1, children: [
275
+ /* @__PURE__ */ jsxs(PopoverButton, { disabled: !canUpdate, onClick: openReleaseModal, children: [
276
+ /* @__PURE__ */ jsx(PencilIcon, {}),
277
+ /* @__PURE__ */ jsx(Typography, { ellipsis: true, children: formatMessage({
278
+ id: "content-releases.header.actions.edit",
279
+ defaultMessage: "Edit"
280
+ }) })
281
+ ] }),
282
+ /* @__PURE__ */ jsxs(PopoverButton, { disabled: !canDelete, onClick: openWarningConfirmDialog, children: [
283
+ /* @__PURE__ */ jsx(TrashIcon, {}),
284
+ /* @__PURE__ */ jsx(Typography, { ellipsis: true, textColor: "danger600", children: formatMessage({
285
+ id: "content-releases.header.actions.delete",
286
+ defaultMessage: "Delete"
287
+ }) })
288
+ ] })
289
+ ] }),
226
290
  /* @__PURE__ */ jsxs(
227
291
  ReleaseInfoWrapper,
228
292
  {
@@ -252,10 +316,6 @@ const ReleaseDetailsLayout = ({
252
316
  ]
253
317
  }
254
318
  ),
255
- /* @__PURE__ */ jsx(Button, { size: "S", variant: "tertiary", children: formatMessage({
256
- id: "content-releases.header.actions.refresh",
257
- defaultMessage: "Refresh"
258
- }) }),
259
319
  /* @__PURE__ */ jsx(CheckPermissions, { permissions: PERMISSIONS.publish, children: /* @__PURE__ */ jsx(
260
320
  Button,
261
321
  {
@@ -272,23 +332,50 @@ const ReleaseDetailsLayout = ({
272
332
  ) })
273
333
  ] })
274
334
  }
275
- ) }),
335
+ ),
276
336
  children
277
337
  ] });
278
338
  };
339
+ const GROUP_BY_OPTIONS = ["contentType", "locale", "action"];
340
+ const getGroupByOptionLabel = (value) => {
341
+ if (value === "locale") {
342
+ return {
343
+ id: "content-releases.pages.ReleaseDetails.groupBy.option.locales",
344
+ defaultMessage: "Locales"
345
+ };
346
+ }
347
+ if (value === "action") {
348
+ return {
349
+ id: "content-releases.pages.ReleaseDetails.groupBy.option.actions",
350
+ defaultMessage: "Actions"
351
+ };
352
+ }
353
+ return {
354
+ id: "content-releases.pages.ReleaseDetails.groupBy.option.content-type",
355
+ defaultMessage: "Content-Types"
356
+ };
357
+ };
279
358
  const ReleaseDetailsBody = () => {
280
359
  const { formatMessage } = useIntl();
281
360
  const { releaseId } = useParams();
282
- const [{ query }] = useQueryParams();
361
+ const [{ query }, setQuery] = useQueryParams();
283
362
  const toggleNotification = useNotification();
284
363
  const { formatAPIError } = useAPIErrorHandler();
285
364
  const {
286
365
  data: releaseData,
287
366
  isLoading: isReleaseLoading,
288
- isError: isReleaseError
367
+ isError: isReleaseError,
368
+ error: releaseError
289
369
  } = useGetReleaseQuery({ id: releaseId });
290
370
  const release = releaseData?.data;
291
- const { isLoading, isFetching, isError, data } = useGetReleaseActionsQuery({
371
+ const selectedGroupBy = query?.groupBy || "contentType";
372
+ const {
373
+ isLoading,
374
+ isFetching,
375
+ isError,
376
+ data,
377
+ error: releaseActionsError
378
+ } = useGetReleaseActionsQuery({
292
379
  ...query,
293
380
  releaseId
294
381
  });
@@ -320,107 +407,179 @@ const ReleaseDetailsBody = () => {
320
407
  if (isLoading || isReleaseLoading) {
321
408
  return /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsx(LoadingIndicatorPage, {}) });
322
409
  }
323
- if (isError || isReleaseError || !release) {
324
- return /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsx(AnErrorOccurred, {}) });
325
- }
326
410
  const releaseActions = data?.data;
327
411
  const releaseMeta = data?.meta;
328
- if (!releaseActions || !releaseActions.length) {
412
+ if (isError || isReleaseError || !release || !releaseActions) {
413
+ const errorsArray = [];
414
+ if (releaseError) {
415
+ errorsArray.push({
416
+ code: releaseError.code
417
+ });
418
+ }
419
+ if (releaseActionsError) {
420
+ errorsArray.push({
421
+ code: releaseActionsError.code
422
+ });
423
+ }
424
+ return /* @__PURE__ */ jsx(
425
+ Redirect,
426
+ {
427
+ to: {
428
+ pathname: "/plugins/content-releases",
429
+ state: {
430
+ errors: errorsArray
431
+ }
432
+ }
433
+ }
434
+ );
435
+ }
436
+ if (Object.keys(releaseActions).length === 0) {
329
437
  return /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsx(
330
- EmptyStateLayout,
438
+ NoContent,
331
439
  {
332
- content: formatMessage({
333
- id: "content-releases.pages.Details.empty-state.content",
334
- defaultMessage: "This release is empty."
335
- }),
336
- icon: /* @__PURE__ */ jsx(EmptyDocuments, { width: "10rem" })
440
+ content: {
441
+ id: "content-releases.pages.Details.tab.emptyEntries",
442
+ defaultMessage: "This release is empty. Open the Content Manager, select an entry and add it to the release."
443
+ },
444
+ action: /* @__PURE__ */ jsx(
445
+ LinkButton,
446
+ {
447
+ as: Link$1,
448
+ to: {
449
+ pathname: "/content-manager"
450
+ },
451
+ style: { textDecoration: "none" },
452
+ variant: "secondary",
453
+ children: formatMessage({
454
+ id: "content-releases.page.Details.button.openContentManager",
455
+ defaultMessage: "Open the Content Manager"
456
+ })
457
+ }
458
+ )
337
459
  }
338
460
  ) });
339
461
  }
340
- return /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsxs(Flex, { gap: 4, direction: "column", alignItems: "stretch", children: [
341
- /* @__PURE__ */ jsx(
342
- Table.Root,
462
+ return /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsxs(Flex, { gap: 8, direction: "column", alignItems: "stretch", children: [
463
+ /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(
464
+ SingleSelect,
343
465
  {
344
- rows: releaseActions.map((item) => ({
345
- ...item,
346
- id: Number(item.entry.id)
347
- })),
348
- colCount: releaseActions.length,
349
- isLoading,
350
- isFetching,
351
- children: /* @__PURE__ */ jsxs(Table.Content, { children: [
352
- /* @__PURE__ */ jsxs(Table.Head, { children: [
353
- /* @__PURE__ */ jsx(
354
- Table.HeaderCell,
355
- {
356
- fieldSchemaType: "string",
357
- label: formatMessage({
358
- id: "content-releases.page.ReleaseDetails.table.header.label.name",
359
- defaultMessage: "name"
360
- }),
361
- name: "name"
362
- }
363
- ),
364
- /* @__PURE__ */ jsx(
365
- Table.HeaderCell,
366
- {
367
- fieldSchemaType: "string",
368
- label: formatMessage({
369
- id: "content-releases.page.ReleaseDetails.table.header.label.locale",
370
- defaultMessage: "locale"
371
- }),
372
- name: "locale"
373
- }
374
- ),
375
- /* @__PURE__ */ jsx(
376
- Table.HeaderCell,
377
- {
378
- fieldSchemaType: "string",
379
- label: formatMessage({
380
- id: "content-releases.page.ReleaseDetails.table.header.label.content-type",
381
- defaultMessage: "content-type"
382
- }),
383
- name: "content-type"
384
- }
385
- ),
386
- /* @__PURE__ */ jsx(
387
- Table.HeaderCell,
388
- {
389
- fieldSchemaType: "string",
390
- label: formatMessage({
391
- id: "content-releases.page.ReleaseDetails.table.header.label.action",
392
- defaultMessage: "action"
393
- }),
394
- name: "action"
395
- }
396
- )
397
- ] }),
398
- /* @__PURE__ */ jsx(Table.LoadingBody, {}),
399
- /* @__PURE__ */ jsx(Table.Body, { children: releaseActions.map(({ id, type, entry }) => /* @__PURE__ */ jsxs(Tr, { children: [
400
- /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { children: `${entry.contentType.mainFieldValue || entry.id}` }) }),
401
- /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { children: `${entry?.locale?.name ? entry.locale.name : "-"}` }) }),
402
- /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { children: entry.contentType.displayName || "" }) }),
403
- /* @__PURE__ */ jsx(Td, { children: release.releasedAt ? /* @__PURE__ */ jsx(Typography, { children: formatMessage(
404
- {
405
- id: "content-releases.page.ReleaseDetails.table.action-published",
406
- defaultMessage: "This entry was <b>{isPublish, select, true {published} other {unpublished}}</b>."
407
- },
408
- {
409
- isPublish: type === "publish",
410
- b: (children) => /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children })
411
- }
412
- ) }) : /* @__PURE__ */ jsx(
413
- ReleaseActionOptions,
414
- {
415
- selected: type,
416
- handleChange: (e) => handleChangeType(e, id),
417
- name: `release-action-${id}-type`
418
- }
419
- ) })
420
- ] }, id)) })
421
- ] })
466
+ "aria-label": formatMessage({
467
+ id: "content-releases.pages.ReleaseDetails.groupBy.label",
468
+ defaultMessage: "Group by"
469
+ }),
470
+ customizeContent: (value) => formatMessage(
471
+ {
472
+ id: `content-releases.pages.ReleaseDetails.groupBy.label`,
473
+ defaultMessage: `Group by {groupBy}`
474
+ },
475
+ {
476
+ groupBy: value
477
+ }
478
+ ),
479
+ value: formatMessage(getGroupByOptionLabel(selectedGroupBy)),
480
+ onChange: (value) => setQuery({ groupBy: value }),
481
+ children: GROUP_BY_OPTIONS.map((option) => /* @__PURE__ */ jsx(SingleSelectOption, { value: option, children: formatMessage(getGroupByOptionLabel(option)) }, option))
422
482
  }
423
- ),
483
+ ) }),
484
+ Object.keys(releaseActions).map((key) => /* @__PURE__ */ jsxs(Flex, { gap: 4, direction: "column", alignItems: "stretch", children: [
485
+ /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(Badge, { children: key }) }),
486
+ /* @__PURE__ */ jsx(
487
+ Table.Root,
488
+ {
489
+ rows: releaseActions[key].map((item) => ({
490
+ ...item,
491
+ id: Number(item.entry.id)
492
+ })),
493
+ colCount: releaseActions[key].length,
494
+ isLoading,
495
+ isFetching,
496
+ children: /* @__PURE__ */ jsxs(Table.Content, { children: [
497
+ /* @__PURE__ */ jsxs(Table.Head, { children: [
498
+ /* @__PURE__ */ jsx(
499
+ Table.HeaderCell,
500
+ {
501
+ fieldSchemaType: "string",
502
+ label: formatMessage({
503
+ id: "content-releases.page.ReleaseDetails.table.header.label.name",
504
+ defaultMessage: "name"
505
+ }),
506
+ name: "name"
507
+ }
508
+ ),
509
+ /* @__PURE__ */ jsx(
510
+ Table.HeaderCell,
511
+ {
512
+ fieldSchemaType: "string",
513
+ label: formatMessage({
514
+ id: "content-releases.page.ReleaseDetails.table.header.label.locale",
515
+ defaultMessage: "locale"
516
+ }),
517
+ name: "locale"
518
+ }
519
+ ),
520
+ /* @__PURE__ */ jsx(
521
+ Table.HeaderCell,
522
+ {
523
+ fieldSchemaType: "string",
524
+ label: formatMessage({
525
+ id: "content-releases.page.ReleaseDetails.table.header.label.content-type",
526
+ defaultMessage: "content-type"
527
+ }),
528
+ name: "content-type"
529
+ }
530
+ ),
531
+ /* @__PURE__ */ jsx(
532
+ Table.HeaderCell,
533
+ {
534
+ fieldSchemaType: "string",
535
+ label: formatMessage({
536
+ id: "content-releases.page.ReleaseDetails.table.header.label.action",
537
+ defaultMessage: "action"
538
+ }),
539
+ name: "action"
540
+ }
541
+ ),
542
+ !release.releasedAt && /* @__PURE__ */ jsx(
543
+ Table.HeaderCell,
544
+ {
545
+ fieldSchemaType: "string",
546
+ label: formatMessage({
547
+ id: "content-releases.page.ReleaseDetails.table.header.label.status",
548
+ defaultMessage: "status"
549
+ }),
550
+ name: "status"
551
+ }
552
+ )
553
+ ] }),
554
+ /* @__PURE__ */ jsx(Table.LoadingBody, {}),
555
+ /* @__PURE__ */ jsx(Table.Body, { children: releaseActions[key].map(({ id, type, entry }) => /* @__PURE__ */ jsxs(Tr, { children: [
556
+ /* @__PURE__ */ jsx(Td, { width: "25%", children: /* @__PURE__ */ jsx(Typography, { ellipsis: true, children: `${entry.contentType.mainFieldValue || entry.id}` }) }),
557
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { children: `${entry?.locale?.name ? entry.locale.name : "-"}` }) }),
558
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { children: entry.contentType.displayName || "" }) }),
559
+ /* @__PURE__ */ jsx(Td, { children: release.releasedAt ? /* @__PURE__ */ jsx(Typography, { children: formatMessage(
560
+ {
561
+ id: "content-releases.page.ReleaseDetails.table.action-published",
562
+ defaultMessage: "This entry was <b>{isPublish, select, true {published} other {unpublished}}</b>."
563
+ },
564
+ {
565
+ isPublish: type === "publish",
566
+ b: (children) => /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children })
567
+ }
568
+ ) }) : /* @__PURE__ */ jsx(
569
+ ReleaseActionOptions,
570
+ {
571
+ selected: type,
572
+ handleChange: (e) => handleChangeType(e, id),
573
+ name: `release-action-${id}-type`
574
+ }
575
+ ) }),
576
+ !release.releasedAt && /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(EntryValidationText, { status: entry.status, action: type }) }),
577
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Flex, { justifyContent: "flex-end", children: /* @__PURE__ */ jsx(ReleaseActionMenu, { releaseId, actionId: id }) }) })
578
+ ] }, id)) })
579
+ ] })
580
+ }
581
+ )
582
+ ] }, `releases-group-${key}`)),
424
583
  /* @__PURE__ */ jsxs(Flex, { paddingTop: 4, alignItems: "flex-end", justifyContent: "space-between", children: [
425
584
  /* @__PURE__ */ jsx(PageSizeURLQuery, { defaultValue: releaseMeta?.pagination?.pageSize.toString() }),
426
585
  /* @__PURE__ */ jsx(
@@ -541,7 +700,6 @@ const ReleaseDetailsPage = () => {
541
700
  }
542
701
  );
543
702
  };
544
- const ProtectedReleaseDetailsPage = () => /* @__PURE__ */ jsx(CheckPermissions, { permissions: PERMISSIONS.main, children: /* @__PURE__ */ jsx(ReleaseDetailsPage, {}) });
545
703
  const ReleasesLayout = ({
546
704
  isLoading,
547
705
  totalReleases,
@@ -573,7 +731,7 @@ const ReleasesLayout = ({
573
731
  children
574
732
  ] });
575
733
  };
576
- const LinkCard = styled(Link$1)`
734
+ const LinkCard = styled(Link$2)`
577
735
  display: block;
578
736
  `;
579
737
  const ReleasesGrid = ({ sectionTitle, releases = [], isError = false }) => {
@@ -628,15 +786,32 @@ const INITIAL_FORM_VALUES = {
628
786
  name: ""
629
787
  };
630
788
  const ReleasesPage = () => {
789
+ const location = useLocation();
631
790
  const [releaseModalShown, setReleaseModalShown] = React.useState(false);
632
791
  const toggleNotification = useNotification();
633
792
  const { formatMessage } = useIntl();
634
- const { push } = useHistory();
793
+ const { push, replace } = useHistory();
635
794
  const { formatAPIError } = useAPIErrorHandler();
636
795
  const [{ query }, setQuery] = useQueryParams();
637
796
  const response = useGetReleasesQuery(query);
638
797
  const [createRelease, { isLoading: isSubmittingForm }] = useCreateReleaseMutation();
639
798
  const { isLoading, isSuccess, isError } = response;
799
+ React.useEffect(() => {
800
+ if (location?.state?.errors) {
801
+ toggleNotification({
802
+ type: "warning",
803
+ title: formatMessage({
804
+ id: "content-releases.pages.Releases.notification.error.title",
805
+ defaultMessage: "Your request could not be processed."
806
+ }),
807
+ message: formatMessage({
808
+ id: "content-releases.pages.Releases.notification.error.message",
809
+ defaultMessage: "Please try again or open another release."
810
+ })
811
+ });
812
+ replace({ state: null });
813
+ }
814
+ }, [formatMessage, location?.state?.errors, replace, toggleNotification]);
640
815
  const toggleAddReleaseModal = () => {
641
816
  setReleaseModalShown((prev) => !prev);
642
817
  };
@@ -695,16 +870,19 @@ const ReleasesPage = () => {
695
870
  initialSelectedTabIndex: ["pending", "done"].indexOf(activeTab),
696
871
  onTabChange: handleTabChange,
697
872
  children: [
698
- /* @__PURE__ */ jsx(Box, { paddingBottom: 8, children: /* @__PURE__ */ jsxs(Tabs, { children: [
699
- /* @__PURE__ */ jsx(Tab, { children: formatMessage({
700
- id: "content-releases.pages.Releases.tab.pending",
701
- defaultMessage: "Pending"
702
- }) }),
703
- /* @__PURE__ */ jsx(Tab, { children: formatMessage({
704
- id: "content-releases.pages.Releases.tab.done",
705
- defaultMessage: "Done"
706
- }) })
707
- ] }) }),
873
+ /* @__PURE__ */ jsxs(Box, { paddingBottom: 8, children: [
874
+ /* @__PURE__ */ jsxs(Tabs, { children: [
875
+ /* @__PURE__ */ jsx(Tab, { children: formatMessage({
876
+ id: "content-releases.pages.Releases.tab.pending",
877
+ defaultMessage: "Pending"
878
+ }) }),
879
+ /* @__PURE__ */ jsx(Tab, { children: formatMessage({
880
+ id: "content-releases.pages.Releases.tab.done",
881
+ defaultMessage: "Done"
882
+ }) })
883
+ ] }),
884
+ /* @__PURE__ */ jsx(Divider, {})
885
+ ] }),
708
886
  /* @__PURE__ */ jsxs(TabPanels, { children: [
709
887
  /* @__PURE__ */ jsx(TabPanel, { children: /* @__PURE__ */ jsx(
710
888
  ReleasesGrid,
@@ -755,21 +933,13 @@ const ReleasesPage = () => {
755
933
  )
756
934
  ] });
757
935
  };
758
- const ProtectedReleasesPage = () => /* @__PURE__ */ jsx(CheckPermissions, { permissions: PERMISSIONS.main, children: /* @__PURE__ */ jsx(ReleasesPage, {}) });
759
936
  const App = () => {
760
- return /* @__PURE__ */ jsxs(Switch, { children: [
761
- /* @__PURE__ */ jsx(Route, { exact: true, path: `/plugins/${pluginId}`, component: ProtectedReleasesPage }),
762
- /* @__PURE__ */ jsx(
763
- Route,
764
- {
765
- exact: true,
766
- path: `/plugins/${pluginId}/:releaseId`,
767
- component: ProtectedReleaseDetailsPage
768
- }
769
- )
770
- ] });
937
+ return /* @__PURE__ */ jsx(CheckPagePermissions, { permissions: PERMISSIONS.main, children: /* @__PURE__ */ jsxs(Switch, { children: [
938
+ /* @__PURE__ */ jsx(Route, { exact: true, path: `/plugins/${pluginId}`, component: ReleasesPage }),
939
+ /* @__PURE__ */ jsx(Route, { exact: true, path: `/plugins/${pluginId}/:releaseId`, component: ReleaseDetailsPage })
940
+ ] }) });
771
941
  };
772
942
  export {
773
943
  App
774
944
  };
775
- //# sourceMappingURL=App-b83f4a97.mjs.map
945
+ //# sourceMappingURL=App-g2P5kbSm.mjs.map