@strapi/content-releases 0.0.0-experimental.ec089c69ff953942fb39de032c12daafaf7176e6 → 0.0.0-experimental.f75e3c6d67cc47c64ab37479efdbb7b43be50b78

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/dist/_chunks/{App-HjWtUYmc.js → App-DUmziQ17.js} +401 -388
  2. package/dist/_chunks/App-DUmziQ17.js.map +1 -0
  3. package/dist/_chunks/{App-gu1aiP6i.mjs → App-D_6Y9N2F.mjs} +378 -364
  4. package/dist/_chunks/App-D_6Y9N2F.mjs.map +1 -0
  5. package/dist/_chunks/{PurchaseContentReleases-bpIYXOfu.js → PurchaseContentReleases-Be3acS2L.js} +7 -6
  6. package/dist/_chunks/PurchaseContentReleases-Be3acS2L.js.map +1 -0
  7. package/dist/_chunks/{PurchaseContentReleases-3tRbmbY3.mjs → PurchaseContentReleases-_MxP6-Dt.mjs} +8 -7
  8. package/dist/_chunks/PurchaseContentReleases-_MxP6-Dt.mjs.map +1 -0
  9. package/dist/_chunks/{en-ltT1TlKQ.mjs → en-B9Ur3VsE.mjs} +1 -1
  10. package/dist/_chunks/en-B9Ur3VsE.mjs.map +1 -0
  11. package/dist/_chunks/{en-HrREghh3.js → en-DtFJ5ViE.js} +1 -1
  12. package/dist/_chunks/en-DtFJ5ViE.js.map +1 -0
  13. package/dist/_chunks/{index-mvj9PSKd.mjs → index-BomF0-yY.mjs} +180 -476
  14. package/dist/_chunks/index-BomF0-yY.mjs.map +1 -0
  15. package/dist/_chunks/{index-ZNwxYN8H.js → index-C5Hc767q.js} +177 -475
  16. package/dist/_chunks/index-C5Hc767q.js.map +1 -0
  17. package/dist/admin/index.js +1 -15
  18. package/dist/admin/index.js.map +1 -1
  19. package/dist/admin/index.mjs +2 -16
  20. package/dist/admin/index.mjs.map +1 -1
  21. package/dist/admin/src/components/CMReleasesContainer.d.ts +22 -0
  22. package/dist/admin/src/components/RelativeTime.d.ts +28 -0
  23. package/dist/admin/src/components/ReleaseAction.d.ts +3 -0
  24. package/dist/admin/src/components/ReleaseActionMenu.d.ts +26 -0
  25. package/dist/admin/src/components/ReleaseActionOptions.d.ts +9 -0
  26. package/dist/admin/src/components/ReleaseListCell.d.ts +0 -0
  27. package/dist/admin/src/components/ReleaseModal.d.ts +16 -0
  28. package/dist/admin/src/constants.d.ts +58 -0
  29. package/dist/admin/src/index.d.ts +3 -0
  30. package/dist/admin/src/pages/App.d.ts +1 -0
  31. package/dist/admin/src/pages/PurchaseContentReleases.d.ts +2 -0
  32. package/dist/admin/src/pages/ReleaseDetailsPage.d.ts +2 -0
  33. package/dist/admin/src/pages/ReleasesPage.d.ts +8 -0
  34. package/dist/admin/src/pages/tests/mockReleaseDetailsPageData.d.ts +181 -0
  35. package/dist/admin/src/pages/tests/mockReleasesPageData.d.ts +39 -0
  36. package/dist/admin/src/pluginId.d.ts +1 -0
  37. package/dist/admin/src/services/release.d.ts +105 -0
  38. package/dist/admin/src/store/hooks.d.ts +7 -0
  39. package/dist/admin/src/utils/api.d.ts +6 -0
  40. package/dist/admin/src/utils/prefixPluginTranslations.d.ts +3 -0
  41. package/dist/admin/src/utils/time.d.ts +1 -0
  42. package/dist/server/index.js +83 -86
  43. package/dist/server/index.js.map +1 -1
  44. package/dist/server/index.mjs +84 -86
  45. package/dist/server/index.mjs.map +1 -1
  46. package/dist/server/src/bootstrap.d.ts +5 -0
  47. package/dist/server/src/bootstrap.d.ts.map +1 -0
  48. package/dist/server/src/constants.d.ts +12 -0
  49. package/dist/server/src/constants.d.ts.map +1 -0
  50. package/dist/server/src/content-types/index.d.ts +99 -0
  51. package/dist/server/src/content-types/index.d.ts.map +1 -0
  52. package/dist/server/src/content-types/release/index.d.ts +48 -0
  53. package/dist/server/src/content-types/release/index.d.ts.map +1 -0
  54. package/dist/server/src/content-types/release/schema.d.ts +47 -0
  55. package/dist/server/src/content-types/release/schema.d.ts.map +1 -0
  56. package/dist/server/src/content-types/release-action/index.d.ts +50 -0
  57. package/dist/server/src/content-types/release-action/index.d.ts.map +1 -0
  58. package/dist/server/src/content-types/release-action/schema.d.ts +49 -0
  59. package/dist/server/src/content-types/release-action/schema.d.ts.map +1 -0
  60. package/dist/server/src/controllers/index.d.ts +20 -0
  61. package/dist/server/src/controllers/index.d.ts.map +1 -0
  62. package/dist/server/src/controllers/release-action.d.ts +10 -0
  63. package/dist/server/src/controllers/release-action.d.ts.map +1 -0
  64. package/dist/server/src/controllers/release.d.ts +12 -0
  65. package/dist/server/src/controllers/release.d.ts.map +1 -0
  66. package/dist/server/src/controllers/validation/release-action.d.ts +8 -0
  67. package/dist/server/src/controllers/validation/release-action.d.ts.map +1 -0
  68. package/dist/server/src/controllers/validation/release.d.ts +2 -0
  69. package/dist/server/src/controllers/validation/release.d.ts.map +1 -0
  70. package/dist/server/src/destroy.d.ts +5 -0
  71. package/dist/server/src/destroy.d.ts.map +1 -0
  72. package/dist/server/src/index.d.ts +2096 -0
  73. package/dist/server/src/index.d.ts.map +1 -0
  74. package/dist/server/src/migrations/index.d.ts +13 -0
  75. package/dist/server/src/migrations/index.d.ts.map +1 -0
  76. package/dist/server/src/register.d.ts +5 -0
  77. package/dist/server/src/register.d.ts.map +1 -0
  78. package/dist/server/src/routes/index.d.ts +35 -0
  79. package/dist/server/src/routes/index.d.ts.map +1 -0
  80. package/dist/server/src/routes/release-action.d.ts +18 -0
  81. package/dist/server/src/routes/release-action.d.ts.map +1 -0
  82. package/dist/server/src/routes/release.d.ts +18 -0
  83. package/dist/server/src/routes/release.d.ts.map +1 -0
  84. package/dist/server/src/services/index.d.ts +1826 -0
  85. package/dist/server/src/services/index.d.ts.map +1 -0
  86. package/dist/server/src/services/release.d.ts +66 -0
  87. package/dist/server/src/services/release.d.ts.map +1 -0
  88. package/dist/server/src/services/scheduling.d.ts +18 -0
  89. package/dist/server/src/services/scheduling.d.ts.map +1 -0
  90. package/dist/server/src/services/validation.d.ts +18 -0
  91. package/dist/server/src/services/validation.d.ts.map +1 -0
  92. package/dist/server/src/utils/index.d.ts +14 -0
  93. package/dist/server/src/utils/index.d.ts.map +1 -0
  94. package/dist/shared/contracts/release-actions.d.ts +131 -0
  95. package/dist/shared/contracts/release-actions.d.ts.map +1 -0
  96. package/dist/shared/contracts/releases.d.ts +182 -0
  97. package/dist/shared/contracts/releases.d.ts.map +1 -0
  98. package/dist/shared/types.d.ts +24 -0
  99. package/dist/shared/types.d.ts.map +1 -0
  100. package/dist/shared/validation-schemas.d.ts +2 -0
  101. package/dist/shared/validation-schemas.d.ts.map +1 -0
  102. package/package.json +29 -36
  103. package/dist/_chunks/App-HjWtUYmc.js.map +0 -1
  104. package/dist/_chunks/App-gu1aiP6i.mjs.map +0 -1
  105. package/dist/_chunks/PurchaseContentReleases-3tRbmbY3.mjs.map +0 -1
  106. package/dist/_chunks/PurchaseContentReleases-bpIYXOfu.js.map +0 -1
  107. package/dist/_chunks/en-HrREghh3.js.map +0 -1
  108. package/dist/_chunks/en-ltT1TlKQ.mjs.map +0 -1
  109. package/dist/_chunks/index-ZNwxYN8H.js.map +0 -1
  110. package/dist/_chunks/index-mvj9PSKd.mjs.map +0 -1
@@ -1,23 +1,51 @@
1
- import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
- import { RelativeTime as RelativeTime$1, useNotification, useAPIErrorHandler, useQueryParams, useTracking, LoadingIndicatorPage, CheckPermissions, PageSizeURLQuery, PaginationURLQuery, AnErrorOccurred, ConfirmDialog, useRBAC, useStrapiApp, NoContent, Table, CheckPagePermissions } from "@strapi/helper-plugin";
3
- import { useLocation, useHistory, useParams, Redirect, Link as Link$2, Switch, Route } from "react-router-dom";
4
- import { g as getTimezoneOffset, p as pluginId, u as useGetReleasesQuery, a as useCreateReleaseMutation, P as PERMISSIONS, i as isAxiosError, b as useGetReleaseQuery, c as useUpdateReleaseMutation, d as useDeleteReleaseMutation, e as usePublishReleaseMutation, f as useTypedDispatch, h as useGetReleaseActionsQuery, j as useUpdateReleaseActionMutation, R as ReleaseActionOptions, k as ReleaseActionMenu, r as releaseApi } from "./index-mvj9PSKd.mjs";
1
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
+ import { useNotification, useAPIErrorHandler, useQueryParams, useTracking, useRBAC, Page, Layouts, Pagination, isFetchError, ConfirmDialog, BackButton, useStrapiApp, Table } from "@strapi/admin/strapi-admin";
3
+ import { useLocation, useNavigate, NavLink, useParams, Navigate, Link as Link$1, Routes, Route } from "react-router-dom";
4
+ import { g as getTimezoneOffset, p as pluginId, u as useGetReleasesQuery, a as useCreateReleaseMutation, P as PERMISSIONS, b as useGetReleaseQuery, c as useUpdateReleaseMutation, d as useDeleteReleaseMutation, e as usePublishReleaseMutation, f as useGetReleaseActionsQuery, h as useUpdateReleaseActionMutation, R as ReleaseActionOptions, i as ReleaseActionMenu, r as releaseApi } from "./index-BomF0-yY.mjs";
5
5
  import * as React from "react";
6
- import { useLicenseLimits, unstable_useDocument } from "@strapi/admin/strapi-admin";
7
- import { ModalLayout, ModalHeader, Typography, ModalBody, Flex, TextInput, Box, Checkbox, DatePicker, TimePicker, ModalFooter, Button, Combobox, ComboboxOption, Alert, Main, HeaderLayout, ContentLayout, TabGroup, Tabs, Tab, Divider, TabPanels, TabPanel, EmptyStateLayout, Grid, GridItem, Badge, Link as Link$1, IconButton, SingleSelect, SingleSelectOption, Tr, Td, Icon, Tooltip } from "@strapi/design-system";
8
- import { Link, Menu, LinkButton } from "@strapi/design-system/v2";
9
- import { Plus, EmptyDocuments, Pencil, Trash, ArrowLeft, More, CrossCircle, CheckCircle } from "@strapi/icons";
6
+ import { unstable_useDocument } from "@strapi/content-manager/strapi-admin";
7
+ import { ModalLayout, ModalHeader, Typography, ModalBody, Flex, Field, TextInput, Box, Checkbox, DatePicker, TimePicker, ModalFooter, Button, Combobox, ComboboxOption, Link, Alert, Main, TabGroup, Tabs, Tab, Divider, TabPanels, TabPanel, EmptyStateLayout, Grid, GridItem, Badge, Menu, LinkButton, SingleSelect, SingleSelectOption, Tr, Td, Tooltip } from "@strapi/design-system";
8
+ import { Plus, Pencil, Trash, More, CrossCircle, CheckCircle } from "@strapi/icons";
9
+ import { EmptyDocuments } from "@strapi/icons/symbols";
10
10
  import format from "date-fns/format";
11
11
  import { utcToZonedTime, zonedTimeToUtc } from "date-fns-tz";
12
12
  import { useIntl } from "react-intl";
13
- import styled from "styled-components";
14
- import { formatISO } from "date-fns";
13
+ import { styled } from "styled-components";
14
+ import { intervalToDuration, isPast, formatISO } from "date-fns";
15
15
  import { Formik, Form, useFormikContext } from "formik";
16
16
  import * as yup from "yup";
17
- import "@reduxjs/toolkit/query";
18
- import "axios";
19
- import "@reduxjs/toolkit/query/react";
20
- import "react-redux";
17
+ import { useDispatch } from "react-redux";
18
+ import { useLicenseLimits } from "@strapi/admin/strapi-admin/ee";
19
+ const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
20
+ const RelativeTime$1 = React.forwardRef(
21
+ ({ timestamp, customIntervals = [], ...restProps }, forwardedRef) => {
22
+ const { formatRelativeTime, formatDate, formatTime } = useIntl();
23
+ const interval = intervalToDuration({
24
+ start: timestamp,
25
+ end: Date.now()
26
+ // see https://github.com/date-fns/date-fns/issues/2891 – No idea why it's all partial it returns it every time.
27
+ });
28
+ const unit = intervals.find((intervalUnit) => {
29
+ return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);
30
+ });
31
+ const relativeTime = isPast(timestamp) ? -interval[unit] : interval[unit];
32
+ const customInterval = customIntervals.find(
33
+ (custom) => interval[custom.unit] < custom.threshold
34
+ );
35
+ const displayText = customInterval ? customInterval.text : formatRelativeTime(relativeTime, unit, { numeric: "auto" });
36
+ return /* @__PURE__ */ jsx(
37
+ "time",
38
+ {
39
+ ref: forwardedRef,
40
+ dateTime: timestamp.toISOString(),
41
+ role: "time",
42
+ title: `${formatDate(timestamp)} ${formatTime(timestamp)}`,
43
+ ...restProps,
44
+ children: displayText
45
+ }
46
+ );
47
+ }
48
+ );
21
49
  const RELEASE_SCHEMA = yup.object().shape({
22
50
  name: yup.string().trim().required(),
23
51
  scheduledAt: yup.string().nullable(),
@@ -87,120 +115,119 @@ const ReleaseModal = ({
87
115
  },
88
116
  validationSchema: RELEASE_SCHEMA,
89
117
  validateOnChange: false,
90
- children: ({ values, errors, handleChange, setFieldValue }) => /* @__PURE__ */ jsxs(Form, { children: [
91
- /* @__PURE__ */ jsx(ModalBody, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: [
92
- /* @__PURE__ */ jsx(
93
- TextInput,
94
- {
95
- label: formatMessage({
118
+ children: ({ values, errors, handleChange, setFieldValue }) => {
119
+ return /* @__PURE__ */ jsxs(Form, { children: [
120
+ /* @__PURE__ */ jsx(ModalBody, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: [
121
+ /* @__PURE__ */ jsxs(Field.Root, { name: "name", error: errors.name, required: true, children: [
122
+ /* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
96
123
  id: "content-releases.modal.form.input.label.release-name",
97
124
  defaultMessage: "Name"
98
- }),
99
- name: "name",
100
- value: values.name,
101
- error: errors.name,
102
- onChange: handleChange,
103
- required: true
104
- }
105
- ),
106
- /* @__PURE__ */ jsx(Box, { width: "max-content", children: /* @__PURE__ */ jsx(
107
- Checkbox,
108
- {
109
- name: "isScheduled",
110
- value: values.isScheduled,
111
- onChange: (event) => {
112
- setFieldValue("isScheduled", event.target.checked);
113
- if (!event.target.checked) {
114
- setFieldValue("date", null);
115
- setFieldValue("time", "");
116
- setFieldValue("timezone", null);
117
- } else {
118
- setFieldValue("date", initialValues.date);
119
- setFieldValue("time", initialValues.time);
120
- setFieldValue("timezone", initialValues.timezone ?? systemTimezone?.value);
121
- }
122
- },
123
- children: /* @__PURE__ */ jsx(
124
- Typography,
125
- {
126
- textColor: values.isScheduled ? "primary600" : "neutral800",
127
- fontWeight: values.isScheduled ? "semiBold" : "regular",
128
- children: formatMessage({
129
- id: "modal.form.input.label.schedule-release",
130
- defaultMessage: "Schedule release"
131
- })
132
- }
133
- )
134
- }
135
- ) }),
136
- values.isScheduled && /* @__PURE__ */ jsxs(Fragment, { children: [
137
- /* @__PURE__ */ jsxs(Flex, { gap: 4, alignItems: "start", children: [
138
- /* @__PURE__ */ jsx(Box, { width: "100%", children: /* @__PURE__ */ jsx(
139
- DatePicker,
140
- {
141
- label: formatMessage({
125
+ }) }),
126
+ /* @__PURE__ */ jsx(TextInput, { value: values.name, onChange: handleChange }),
127
+ /* @__PURE__ */ jsx(Field.Error, {})
128
+ ] }),
129
+ /* @__PURE__ */ jsx(Box, { width: "max-content", children: /* @__PURE__ */ jsx(
130
+ Checkbox,
131
+ {
132
+ name: "isScheduled",
133
+ value: values.isScheduled,
134
+ onChange: (event) => {
135
+ setFieldValue("isScheduled", event.target.checked);
136
+ if (!event.target.checked) {
137
+ setFieldValue("date", null);
138
+ setFieldValue("time", "");
139
+ setFieldValue("timezone", null);
140
+ } else {
141
+ setFieldValue("date", initialValues.date);
142
+ setFieldValue("time", initialValues.time);
143
+ setFieldValue(
144
+ "timezone",
145
+ initialValues.timezone ?? systemTimezone?.value
146
+ );
147
+ }
148
+ },
149
+ children: /* @__PURE__ */ jsx(
150
+ Typography,
151
+ {
152
+ textColor: values.isScheduled ? "primary600" : "neutral800",
153
+ fontWeight: values.isScheduled ? "semiBold" : "regular",
154
+ children: formatMessage({
155
+ id: "modal.form.input.label.schedule-release",
156
+ defaultMessage: "Schedule release"
157
+ })
158
+ }
159
+ )
160
+ }
161
+ ) }),
162
+ values.isScheduled && /* @__PURE__ */ jsxs(Fragment, { children: [
163
+ /* @__PURE__ */ jsxs(Flex, { gap: 4, alignItems: "start", children: [
164
+ /* @__PURE__ */ jsx(Box, { width: "100%", children: /* @__PURE__ */ jsxs(Field.Root, { name: "date", error: errors.date, required: true, children: [
165
+ /* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
142
166
  id: "content-releases.modal.form.input.label.date",
143
167
  defaultMessage: "Date"
144
- }),
145
- name: "date",
146
- error: errors.date,
147
- onChange: (date) => {
148
- const isoFormatDate = date ? formatISO(date, { representation: "date" }) : null;
149
- setFieldValue("date", isoFormatDate);
150
- },
151
- clearLabel: formatMessage({
152
- id: "content-releases.modal.form.input.clearLabel",
153
- defaultMessage: "Clear"
154
- }),
155
- onClear: () => {
156
- setFieldValue("date", null);
157
- },
158
- selectedDate: values.date || void 0,
159
- required: true,
160
- minDate: utcToZonedTime(/* @__PURE__ */ new Date(), values.timezone.split("&")[1])
161
- }
162
- ) }),
163
- /* @__PURE__ */ jsx(Box, { width: "100%", children: /* @__PURE__ */ jsx(
164
- TimePicker,
165
- {
166
- label: formatMessage({
168
+ }) }),
169
+ /* @__PURE__ */ jsx(
170
+ DatePicker,
171
+ {
172
+ onChange: (date) => {
173
+ const isoFormatDate = date ? formatISO(date, { representation: "date" }) : null;
174
+ setFieldValue("date", isoFormatDate);
175
+ },
176
+ clearLabel: formatMessage({
177
+ id: "content-releases.modal.form.input.clearLabel",
178
+ defaultMessage: "Clear"
179
+ }),
180
+ onClear: () => {
181
+ setFieldValue("date", null);
182
+ },
183
+ value: values.date ? new Date(values.date) : /* @__PURE__ */ new Date(),
184
+ minDate: utcToZonedTime(/* @__PURE__ */ new Date(), values.timezone.split("&")[1])
185
+ }
186
+ ),
187
+ /* @__PURE__ */ jsx(Field.Error, {})
188
+ ] }) }),
189
+ /* @__PURE__ */ jsx(Box, { width: "100%", children: /* @__PURE__ */ jsxs(Field.Root, { name: "time", error: errors.time, required: true, children: [
190
+ /* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
167
191
  id: "content-releases.modal.form.input.label.time",
168
192
  defaultMessage: "Time"
169
- }),
170
- name: "time",
171
- error: errors.time,
172
- onChange: (time) => {
173
- setFieldValue("time", time);
174
- },
175
- clearLabel: formatMessage({
176
- id: "content-releases.modal.form.input.clearLabel",
177
- defaultMessage: "Clear"
178
- }),
179
- onClear: () => {
180
- setFieldValue("time", "");
181
- },
182
- value: values.time || void 0,
183
- required: true
184
- }
193
+ }) }),
194
+ /* @__PURE__ */ jsx(
195
+ TimePicker,
196
+ {
197
+ onChange: (time) => {
198
+ setFieldValue("time", time);
199
+ },
200
+ clearLabel: formatMessage({
201
+ id: "content-releases.modal.form.input.clearLabel",
202
+ defaultMessage: "Clear"
203
+ }),
204
+ onClear: () => {
205
+ setFieldValue("time", "");
206
+ },
207
+ value: values.time || void 0
208
+ }
209
+ ),
210
+ /* @__PURE__ */ jsx(Field.Error, {})
211
+ ] }) })
212
+ ] }),
213
+ /* @__PURE__ */ jsx(TimezoneComponent, { timezoneOptions: timezoneList })
214
+ ] })
215
+ ] }) }),
216
+ /* @__PURE__ */ jsx(
217
+ ModalFooter,
218
+ {
219
+ startActions: /* @__PURE__ */ jsx(Button, { onClick: handleClose, variant: "tertiary", name: "cancel", children: formatMessage({ id: "cancel", defaultMessage: "Cancel" }) }),
220
+ endActions: /* @__PURE__ */ jsx(Button, { name: "submit", loading: isLoading, type: "submit", children: formatMessage(
221
+ {
222
+ id: "content-releases.modal.form.button.submit",
223
+ defaultMessage: "{isCreatingRelease, select, true {Continue} other {Save}}"
224
+ },
225
+ { isCreatingRelease }
185
226
  ) })
186
- ] }),
187
- /* @__PURE__ */ jsx(TimezoneComponent, { timezoneOptions: timezoneList })
188
- ] })
189
- ] }) }),
190
- /* @__PURE__ */ jsx(
191
- ModalFooter,
192
- {
193
- startActions: /* @__PURE__ */ jsx(Button, { onClick: handleClose, variant: "tertiary", name: "cancel", children: formatMessage({ id: "cancel", defaultMessage: "Cancel" }) }),
194
- endActions: /* @__PURE__ */ jsx(Button, { name: "submit", loading: isLoading, type: "submit", children: formatMessage(
195
- {
196
- id: "content-releases.modal.form.button.submit",
197
- defaultMessage: "{isCreatingRelease, select, true {Continue} other {Save}}"
198
- },
199
- { isCreatingRelease }
200
- ) })
201
- }
202
- )
203
- ] })
227
+ }
228
+ )
229
+ ] });
230
+ }
204
231
  }
205
232
  )
206
233
  ] });
@@ -229,31 +256,35 @@ const TimezoneComponent = ({ timezoneOptions }) => {
229
256
  }
230
257
  }
231
258
  }, [setFieldValue, values.date, values.timezone]);
232
- return /* @__PURE__ */ jsx(
233
- Combobox,
234
- {
235
- label: formatMessage({
236
- id: "content-releases.modal.form.input.label.timezone",
237
- defaultMessage: "Timezone"
238
- }),
239
- autocomplete: { type: "list", filter: "contains" },
240
- name: "timezone",
241
- value: values.timezone || void 0,
242
- textValue: values.timezone ? values.timezone.replace(/&/, " ") : void 0,
243
- onChange: (timezone) => {
244
- setFieldValue("timezone", timezone);
245
- },
246
- onTextValueChange: (timezone) => {
247
- setFieldValue("timezone", timezone);
248
- },
249
- onClear: () => {
250
- setFieldValue("timezone", "");
251
- },
252
- error: errors.timezone,
253
- required: true,
254
- children: timezoneList.map((timezone) => /* @__PURE__ */ jsx(ComboboxOption, { value: timezone.value, children: timezone.value.replace(/&/, " ") }, timezone.value))
255
- }
256
- );
259
+ return /* @__PURE__ */ jsxs(Field.Root, { name: "timezone", error: errors.timezone, required: true, children: [
260
+ /* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
261
+ id: "content-releases.modal.form.input.label.timezone",
262
+ defaultMessage: "Timezone"
263
+ }) }),
264
+ /* @__PURE__ */ jsx(
265
+ Combobox,
266
+ {
267
+ autocomplete: { type: "list", filter: "contains" },
268
+ value: values.timezone || void 0,
269
+ textValue: values.timezone ? values.timezone.replace(/&/, " ") : void 0,
270
+ onChange: (timezone) => {
271
+ setFieldValue("timezone", timezone);
272
+ },
273
+ onTextValueChange: (timezone) => {
274
+ setFieldValue("timezone", timezone);
275
+ },
276
+ onClear: () => {
277
+ setFieldValue("timezone", "");
278
+ },
279
+ children: timezoneList.map((timezone) => /* @__PURE__ */ jsx(ComboboxOption, { value: timezone.value, children: timezone.value.replace(/&/, " ") }, timezone.value))
280
+ }
281
+ ),
282
+ /* @__PURE__ */ jsx(Field.Error, {})
283
+ ] });
284
+ };
285
+ const useTypedDispatch = useDispatch;
286
+ const isBaseQueryError = (error) => {
287
+ return typeof error !== "undefined" && error.name !== void 0;
257
288
  };
258
289
  const LinkCard = styled(Link)`
259
290
  display: block;
@@ -292,7 +323,7 @@ const getBadgeProps = (status) => {
292
323
  const ReleasesGrid = ({ sectionTitle, releases = [], isError = false }) => {
293
324
  const { formatMessage } = useIntl();
294
325
  if (isError) {
295
- return /* @__PURE__ */ jsx(AnErrorOccurred, {});
326
+ return /* @__PURE__ */ jsx(Page.Error, {});
296
327
  }
297
328
  if (releases?.length === 0) {
298
329
  return /* @__PURE__ */ jsx(
@@ -307,11 +338,11 @@ const ReleasesGrid = ({ sectionTitle, releases = [], isError = false }) => {
307
338
  target: sectionTitle
308
339
  }
309
340
  ),
310
- icon: /* @__PURE__ */ jsx(EmptyDocuments, { width: "10rem" })
341
+ icon: /* @__PURE__ */ jsx(EmptyDocuments, { width: "16rem" })
311
342
  }
312
343
  );
313
344
  }
314
- return /* @__PURE__ */ jsx(Grid, { gap: 4, children: releases.map(({ id, name, scheduledAt, status }) => /* @__PURE__ */ jsx(GridItem, { col: 3, s: 6, xs: 12, children: /* @__PURE__ */ jsx(LinkCard, { href: `content-releases/${id}`, isExternal: false, children: /* @__PURE__ */ jsxs(
345
+ return /* @__PURE__ */ jsx(Grid, { gap: 4, children: releases.map(({ id, name, scheduledAt, status }) => /* @__PURE__ */ jsx(GridItem, { col: 3, s: 6, xs: 12, children: /* @__PURE__ */ jsx(LinkCard, { tag: NavLink, to: `${id}`, isExternal: false, children: /* @__PURE__ */ jsxs(
315
346
  Flex,
316
347
  {
317
348
  direction: "column",
@@ -326,7 +357,7 @@ const ReleasesGrid = ({ sectionTitle, releases = [], isError = false }) => {
326
357
  gap: 4,
327
358
  children: [
328
359
  /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "start", gap: 1, children: [
329
- /* @__PURE__ */ jsx(Typography, { as: "h3", variant: "delta", fontWeight: "bold", children: name }),
360
+ /* @__PURE__ */ jsx(Typography, { tag: "h3", variant: "delta", fontWeight: "bold", children: name }),
330
361
  /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: scheduledAt ? /* @__PURE__ */ jsx(RelativeTime, { timestamp: new Date(scheduledAt) }) : formatMessage({
331
362
  id: "content-releases.pages.Releases.not-scheduled",
332
363
  defaultMessage: "Not scheduled"
@@ -347,7 +378,7 @@ const StyledAlert = styled(Alert)`
347
378
  `;
348
379
  const INITIAL_FORM_VALUES = {
349
380
  name: "",
350
- date: null,
381
+ date: void 0,
351
382
  time: "",
352
383
  isScheduled: true,
353
384
  scheduledAt: null,
@@ -357,9 +388,9 @@ const ReleasesPage = () => {
357
388
  const tabRef = React.useRef(null);
358
389
  const location = useLocation();
359
390
  const [releaseModalShown, setReleaseModalShown] = React.useState(false);
360
- const toggleNotification = useNotification();
391
+ const { toggleNotification } = useNotification();
361
392
  const { formatMessage } = useIntl();
362
- const { push, replace } = useHistory();
393
+ const navigate = useNavigate();
363
394
  const { formatAPIError } = useAPIErrorHandler();
364
395
  const [{ query }, setQuery] = useQueryParams();
365
396
  const response = useGetReleasesQuery(query);
@@ -367,13 +398,16 @@ const ReleasesPage = () => {
367
398
  const { getFeature } = useLicenseLimits();
368
399
  const { maximumReleases = 3 } = getFeature("cms-content-releases");
369
400
  const { trackUsage } = useTracking();
401
+ const {
402
+ allowedActions: { canCreate }
403
+ } = useRBAC(PERMISSIONS);
370
404
  const { isLoading, isSuccess, isError } = response;
371
405
  const activeTab = response?.currentData?.meta?.activeTab || "pending";
372
406
  const activeTabIndex = ["pending", "done"].indexOf(activeTab);
373
407
  React.useEffect(() => {
374
408
  if (location?.state?.errors) {
375
409
  toggleNotification({
376
- type: "warning",
410
+ type: "danger",
377
411
  title: formatMessage({
378
412
  id: "content-releases.pages.Releases.notification.error.title",
379
413
  defaultMessage: "Your request could not be processed."
@@ -383,9 +417,9 @@ const ReleasesPage = () => {
383
417
  defaultMessage: "Please try again or open another release."
384
418
  })
385
419
  });
386
- replace({ state: null });
420
+ navigate("", { replace: true, state: null });
387
421
  }
388
- }, [formatMessage, location?.state?.errors, replace, toggleNotification]);
422
+ }, [formatMessage, location?.state?.errors, navigate, toggleNotification]);
389
423
  React.useEffect(() => {
390
424
  if (tabRef.current) {
391
425
  tabRef.current._handlers.setSelectedTabIndex(activeTabIndex);
@@ -395,7 +429,7 @@ const ReleasesPage = () => {
395
429
  setReleaseModalShown((prev) => !prev);
396
430
  };
397
431
  if (isLoading) {
398
- return /* @__PURE__ */ jsx(Main, { "aria-busy": isLoading, children: /* @__PURE__ */ jsx(LoadingIndicatorPage, {}) });
432
+ return /* @__PURE__ */ jsx(Page.Loading, {});
399
433
  }
400
434
  const totalPendingReleases = isSuccess && response.currentData?.meta?.pendingReleasesCount || 0;
401
435
  const hasReachedMaximumPendingReleases = totalPendingReleases >= maximumReleases;
@@ -426,22 +460,22 @@ const ReleasesPage = () => {
426
460
  })
427
461
  });
428
462
  trackUsage("didCreateRelease");
429
- push(`/plugins/content-releases/${response2.data.data.id}`);
430
- } else if (isAxiosError(response2.error)) {
463
+ navigate(response2.data.data.id.toString());
464
+ } else if (isFetchError(response2.error)) {
431
465
  toggleNotification({
432
- type: "warning",
466
+ type: "danger",
433
467
  message: formatAPIError(response2.error)
434
468
  });
435
469
  } else {
436
470
  toggleNotification({
437
- type: "warning",
471
+ type: "danger",
438
472
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
439
473
  });
440
474
  }
441
475
  };
442
476
  return /* @__PURE__ */ jsxs(Main, { "aria-busy": isLoading, children: [
443
477
  /* @__PURE__ */ jsx(
444
- HeaderLayout,
478
+ Layouts.Header,
445
479
  {
446
480
  title: formatMessage({
447
481
  id: "content-releases.pages.Releases.title",
@@ -451,7 +485,7 @@ const ReleasesPage = () => {
451
485
  id: "content-releases.pages.Releases.header-subtitle",
452
486
  defaultMessage: "Create and manage content updates"
453
487
  }),
454
- primaryAction: /* @__PURE__ */ jsx(CheckPermissions, { permissions: PERMISSIONS.create, children: /* @__PURE__ */ jsx(
488
+ primaryAction: canCreate ? /* @__PURE__ */ jsx(
455
489
  Button,
456
490
  {
457
491
  startIcon: /* @__PURE__ */ jsx(Plus, {}),
@@ -462,10 +496,10 @@ const ReleasesPage = () => {
462
496
  defaultMessage: "New release"
463
497
  })
464
498
  }
465
- ) })
499
+ ) : null
466
500
  }
467
501
  ),
468
- /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsxs(Fragment, { children: [
502
+ /* @__PURE__ */ jsx(Layouts.Content, { children: /* @__PURE__ */ jsxs(Fragment, { children: [
469
503
  hasReachedMaximumPendingReleases && /* @__PURE__ */ jsx(
470
504
  StyledAlert,
471
505
  {
@@ -541,23 +575,17 @@ const ReleasesPage = () => {
541
575
  ]
542
576
  }
543
577
  ),
544
- response.currentData?.meta?.pagination?.total ? /* @__PURE__ */ jsxs(Flex, { paddingTop: 4, alignItems: "flex-end", justifyContent: "space-between", children: [
545
- /* @__PURE__ */ jsx(
546
- PageSizeURLQuery,
547
- {
548
- options: ["8", "16", "32", "64"],
549
- defaultValue: response?.currentData?.meta?.pagination?.pageSize.toString()
550
- }
551
- ),
552
- /* @__PURE__ */ jsx(
553
- PaginationURLQuery,
554
- {
555
- pagination: {
556
- pageCount: response?.currentData?.meta?.pagination?.pageCount || 0
557
- }
558
- }
559
- )
560
- ] }) : null
578
+ /* @__PURE__ */ jsxs(
579
+ Pagination.Root,
580
+ {
581
+ ...response?.currentData?.meta?.pagination,
582
+ defaultPageSize: response?.currentData?.meta?.pagination?.pageSize,
583
+ children: [
584
+ /* @__PURE__ */ jsx(Pagination.PageSize, { options: ["8", "16", "32", "64"] }),
585
+ /* @__PURE__ */ jsx(Pagination.Links, {})
586
+ ]
587
+ }
588
+ )
561
589
  ] }) }),
562
590
  releaseModalShown && /* @__PURE__ */ jsx(
563
591
  ReleaseModal,
@@ -585,7 +613,7 @@ const StyledMenuItem = styled(Menu.Item)`
585
613
  }
586
614
 
587
615
  &:hover {
588
- background: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}100`]};
616
+ background: ${({ theme, $variant = "neutral" }) => theme.colors[`${$variant}100`]};
589
617
  }
590
618
  `;
591
619
  const PencilIcon = styled(Pencil)`
@@ -605,29 +633,34 @@ const TrashIcon = styled(Trash)`
605
633
  const TypographyMaxWidth = styled(Typography)`
606
634
  max-width: 300px;
607
635
  `;
608
- const EntryValidationText = ({ action, schema, components, entry }) => {
636
+ const EntryValidationText = ({ action, schema, entry }) => {
609
637
  const { formatMessage } = useIntl();
610
- const { validate } = unstable_useDocument();
611
- const { errors } = validate(entry, {
612
- contentType: schema,
613
- components,
614
- isCreatingEntry: false
615
- });
638
+ const { validate } = unstable_useDocument(
639
+ {
640
+ collectionType: schema?.kind ?? "",
641
+ model: schema?.uid ?? ""
642
+ },
643
+ {
644
+ skip: !schema
645
+ }
646
+ );
647
+ const errors = validate(entry) ?? {};
616
648
  if (Object.keys(errors).length > 0) {
617
649
  const validationErrorsMessages = Object.entries(errors).map(
618
650
  ([key, value]) => formatMessage(
651
+ // @ts-expect-error – TODO: fix this will better checks
619
652
  { id: `${value.id}.withField`, defaultMessage: value.defaultMessage },
620
653
  { field: key }
621
654
  )
622
655
  ).join(" ");
623
656
  return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
624
- /* @__PURE__ */ jsx(Icon, { color: "danger600", as: CrossCircle }),
657
+ /* @__PURE__ */ jsx(CrossCircle, { fill: "danger600" }),
625
658
  /* @__PURE__ */ jsx(Tooltip, { description: validationErrorsMessages, children: /* @__PURE__ */ jsx(TypographyMaxWidth, { textColor: "danger600", variant: "omega", fontWeight: "semiBold", ellipsis: true, children: validationErrorsMessages }) })
626
659
  ] });
627
660
  }
628
661
  if (action == "publish") {
629
662
  return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
630
- /* @__PURE__ */ jsx(Icon, { color: "success600", as: CheckCircle }),
663
+ /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
631
664
  entry.publishedAt ? /* @__PURE__ */ jsx(Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
632
665
  id: "content-releases.pages.ReleaseDetails.entry-validation.already-published",
633
666
  defaultMessage: "Already published"
@@ -638,7 +671,7 @@ const EntryValidationText = ({ action, schema, components, entry }) => {
638
671
  ] });
639
672
  }
640
673
  return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
641
- /* @__PURE__ */ jsx(Icon, { color: "success600", as: CheckCircle }),
674
+ /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
642
675
  !entry.publishedAt ? /* @__PURE__ */ jsx(Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
643
676
  id: "content-releases.pages.ReleaseDetails.entry-validation.already-unpublished",
644
677
  defaultMessage: "Already unpublished"
@@ -658,20 +691,23 @@ const ReleaseDetailsLayout = ({
658
691
  const {
659
692
  data,
660
693
  isLoading: isLoadingDetails,
661
- isError,
662
694
  error
663
- } = useGetReleaseQuery({ id: releaseId });
695
+ } = useGetReleaseQuery(
696
+ { id: releaseId },
697
+ {
698
+ skip: !releaseId
699
+ }
700
+ );
664
701
  const [publishRelease, { isLoading: isPublishing }] = usePublishReleaseMutation();
665
- const toggleNotification = useNotification();
702
+ const { toggleNotification } = useNotification();
666
703
  const { formatAPIError } = useAPIErrorHandler();
667
- const {
668
- allowedActions: { canUpdate, canDelete }
669
- } = useRBAC(PERMISSIONS);
704
+ const { allowedActions } = useRBAC(PERMISSIONS);
705
+ const { canUpdate, canDelete, canPublish } = allowedActions;
670
706
  const dispatch = useTypedDispatch();
671
707
  const { trackUsage } = useTracking();
672
708
  const release = data?.data;
673
- const handlePublishRelease = async () => {
674
- const response = await publishRelease({ id: releaseId });
709
+ const handlePublishRelease = (id) => async () => {
710
+ const response = await publishRelease({ id });
675
711
  if ("data" in response) {
676
712
  toggleNotification({
677
713
  type: "success",
@@ -686,14 +722,14 @@ const ReleaseDetailsLayout = ({
686
722
  totalPublishedEntries,
687
723
  totalUnpublishedEntries
688
724
  });
689
- } else if (isAxiosError(response.error)) {
725
+ } else if (isFetchError(response.error)) {
690
726
  toggleNotification({
691
- type: "warning",
727
+ type: "danger",
692
728
  message: formatAPIError(response.error)
693
729
  });
694
730
  } else {
695
731
  toggleNotification({
696
- type: "warning",
732
+ type: "danger",
697
733
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
698
734
  });
699
735
  }
@@ -719,21 +755,20 @@ const ReleaseDetailsLayout = ({
719
755
  return release.createdBy.email;
720
756
  };
721
757
  if (isLoadingDetails) {
722
- return /* @__PURE__ */ jsx(Main, { "aria-busy": isLoadingDetails, children: /* @__PURE__ */ jsx(LoadingIndicatorPage, {}) });
758
+ return /* @__PURE__ */ jsx(Page.Loading, {});
723
759
  }
724
- if (isError || !release) {
760
+ if (isBaseQueryError(error) && "code" in error || !release) {
725
761
  return /* @__PURE__ */ jsx(
726
- Redirect,
762
+ Navigate,
727
763
  {
728
- to: {
729
- pathname: "/plugins/content-releases",
730
- state: {
731
- errors: [
732
- {
733
- code: error?.code
734
- }
735
- ]
736
- }
764
+ to: "..",
765
+ state: {
766
+ errors: [
767
+ {
768
+ // @ts-expect-error – TODO: fix this weird error flow
769
+ code: error?.code
770
+ }
771
+ ]
737
772
  }
738
773
  }
739
774
  );
@@ -770,34 +805,30 @@ const ReleaseDetailsLayout = ({
770
805
  ) : "";
771
806
  return /* @__PURE__ */ jsxs(Main, { "aria-busy": isLoadingDetails, children: [
772
807
  /* @__PURE__ */ jsx(
773
- HeaderLayout,
808
+ Layouts.Header,
774
809
  {
775
810
  title: release.name,
776
811
  subtitle: /* @__PURE__ */ jsxs(Flex, { gap: 2, lineHeight: 6, children: [
777
812
  /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", variant: "epsilon", children: numberOfEntriesText + (isScheduled ? ` - ${scheduledText}` : "") }),
778
813
  /* @__PURE__ */ jsx(Badge, { ...getBadgeProps(release.status), children: release.status })
779
814
  ] }),
780
- navigationAction: /* @__PURE__ */ jsx(Link$1, { startIcon: /* @__PURE__ */ jsx(ArrowLeft, {}), to: "/plugins/content-releases", children: formatMessage({
781
- id: "global.back",
782
- defaultMessage: "Back"
783
- }) }),
815
+ navigationAction: /* @__PURE__ */ jsx(BackButton, {}),
784
816
  primaryAction: !release.releasedAt && /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
785
817
  /* @__PURE__ */ jsxs(Menu.Root, { children: [
786
818
  /* @__PURE__ */ jsx(
787
819
  Menu.Trigger,
788
820
  {
789
- as: IconButton,
790
821
  paddingLeft: 2,
791
822
  paddingRight: 2,
792
823
  "aria-label": formatMessage({
793
824
  id: "content-releases.header.actions.open-release-actions",
794
825
  defaultMessage: "Release edit and delete menu"
795
826
  }),
796
- icon: /* @__PURE__ */ jsx(More, {}),
797
- variant: "tertiary"
827
+ variant: "tertiary",
828
+ children: /* @__PURE__ */ jsx(More, {})
798
829
  }
799
830
  ),
800
- /* @__PURE__ */ jsxs(Menu.Content, { top: 1, popoverPlacement: "bottom-end", children: [
831
+ /* @__PURE__ */ jsxs(Menu.Content, { top: 1, popoverPlacement: "bottom-end", maxHeight: void 0, children: [
801
832
  /* @__PURE__ */ jsxs(
802
833
  Flex,
803
834
  {
@@ -819,7 +850,7 @@ const ReleaseDetailsLayout = ({
819
850
  {
820
851
  disabled: !canDelete,
821
852
  onSelect: toggleWarningSubmit,
822
- variant: "danger",
853
+ $variant: "danger",
823
854
  children: /* @__PURE__ */ jsxs(Flex, { alignItems: "center", gap: 2, hasRadius: true, width: "100%", children: [
824
855
  /* @__PURE__ */ jsx(TrashIcon, {}),
825
856
  /* @__PURE__ */ jsx(Typography, { ellipsis: true, textColor: "danger600", children: formatMessage({
@@ -864,12 +895,12 @@ const ReleaseDetailsLayout = ({
864
895
  id: "content-releases.header.actions.refresh",
865
896
  defaultMessage: "Refresh"
866
897
  }) }),
867
- /* @__PURE__ */ jsx(CheckPermissions, { permissions: PERMISSIONS.publish, children: /* @__PURE__ */ jsx(
898
+ canPublish ? /* @__PURE__ */ jsx(
868
899
  Button,
869
900
  {
870
901
  size: "S",
871
902
  variant: "default",
872
- onClick: handlePublishRelease,
903
+ onClick: handlePublishRelease(release.id.toString()),
873
904
  loading: isPublishing,
874
905
  disabled: release.actions.meta.count === 0,
875
906
  children: formatMessage({
@@ -877,7 +908,7 @@ const ReleaseDetailsLayout = ({
877
908
  defaultMessage: "Publish"
878
909
  })
879
910
  }
880
- ) })
911
+ ) : null
881
912
  ] })
882
913
  }
883
914
  ),
@@ -904,44 +935,30 @@ const getGroupByOptionLabel = (value) => {
904
935
  defaultMessage: "Content-Types"
905
936
  };
906
937
  };
907
- const DEFAULT_RELEASE_DETAILS_HEADER = [
908
- {
909
- key: "__name__",
910
- fieldSchema: { type: "string" },
911
- metadatas: {
912
- label: {
913
- id: "content-releases.page.ReleaseDetails.table.header.label.name",
914
- defaultMessage: "name"
915
- },
916
- searchable: false,
917
- sortable: false
918
- },
919
- name: "name"
920
- }
921
- ];
922
- const ReleaseDetailsBody = () => {
938
+ const ReleaseDetailsBody = ({ releaseId }) => {
923
939
  const { formatMessage } = useIntl();
924
- const { releaseId } = useParams();
925
940
  const [{ query }, setQuery] = useQueryParams();
926
- const toggleNotification = useNotification();
941
+ const { toggleNotification } = useNotification();
927
942
  const { formatAPIError } = useAPIErrorHandler();
928
943
  const {
929
944
  data: releaseData,
930
945
  isLoading: isReleaseLoading,
931
- isError: isReleaseError,
932
946
  error: releaseError
933
947
  } = useGetReleaseQuery({ id: releaseId });
934
948
  const {
935
949
  allowedActions: { canUpdate }
936
950
  } = useRBAC(PERMISSIONS);
937
- const { runHookWaterfall } = useStrapiApp();
938
- const {
939
- displayedHeaders,
940
- hasI18nEnabled
941
- } = runHookWaterfall(
951
+ const runHookWaterfall = useStrapiApp("ReleaseDetailsPage", (state) => state.runHookWaterfall);
952
+ const { hasI18nEnabled } = runHookWaterfall(
942
953
  "ContentReleases/pages/ReleaseDetails/add-locale-in-releases",
943
954
  {
944
- displayedHeaders: DEFAULT_RELEASE_DETAILS_HEADER,
955
+ displayedHeaders: {
956
+ label: formatMessage({
957
+ id: "content-releases.page.ReleaseDetails.table.header.label.locale",
958
+ defaultMessage: "locale"
959
+ }),
960
+ name: "locale"
961
+ },
945
962
  hasI18nEnabled: false
946
963
  }
947
964
  );
@@ -973,65 +990,59 @@ const ReleaseDetailsBody = () => {
973
990
  // We are passing the action path to found the position in the cache of the action for optimistic updates
974
991
  });
975
992
  if ("error" in response) {
976
- if (isAxiosError(response.error)) {
993
+ if (isFetchError(response.error)) {
977
994
  toggleNotification({
978
- type: "warning",
995
+ type: "danger",
979
996
  message: formatAPIError(response.error)
980
997
  });
981
998
  } else {
982
999
  toggleNotification({
983
- type: "warning",
1000
+ type: "danger",
984
1001
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
985
1002
  });
986
1003
  }
987
1004
  }
988
1005
  };
989
1006
  if (isLoading || isReleaseLoading) {
990
- return /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsx(LoadingIndicatorPage, {}) });
1007
+ return /* @__PURE__ */ jsx(Page.Loading, {});
991
1008
  }
992
1009
  const releaseActions = data?.data;
993
1010
  const releaseMeta = data?.meta;
994
1011
  const contentTypes = releaseMeta?.contentTypes || {};
995
1012
  const components = releaseMeta?.components || {};
996
- if (isReleaseError || !release) {
1013
+ if (isBaseQueryError(releaseError) || !release) {
997
1014
  const errorsArray = [];
998
- if (releaseError) {
1015
+ if (releaseError && "code" in releaseError) {
999
1016
  errorsArray.push({
1000
1017
  code: releaseError.code
1001
1018
  });
1002
1019
  }
1003
- if (releaseActionsError) {
1020
+ if (releaseActionsError && "code" in releaseActionsError) {
1004
1021
  errorsArray.push({
1005
1022
  code: releaseActionsError.code
1006
1023
  });
1007
1024
  }
1008
1025
  return /* @__PURE__ */ jsx(
1009
- Redirect,
1026
+ Navigate,
1010
1027
  {
1011
- to: {
1012
- pathname: "/plugins/content-releases",
1013
- state: {
1014
- errors: errorsArray
1015
- }
1028
+ to: "..",
1029
+ state: {
1030
+ errors: errorsArray
1016
1031
  }
1017
1032
  }
1018
1033
  );
1019
1034
  }
1020
1035
  if (isError || !releaseActions) {
1021
- return /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsx(AnErrorOccurred, {}) });
1036
+ return /* @__PURE__ */ jsx(Page.Error, {});
1022
1037
  }
1023
1038
  if (Object.keys(releaseActions).length === 0) {
1024
- return /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsx(
1025
- NoContent,
1039
+ return /* @__PURE__ */ jsx(Layouts.Content, { children: /* @__PURE__ */ jsx(
1040
+ EmptyStateLayout,
1026
1041
  {
1027
- content: {
1028
- id: "content-releases.pages.Details.tab.emptyEntries",
1029
- defaultMessage: "This release is empty. Open the Content Manager, select an entry and add it to the release."
1030
- },
1031
1042
  action: /* @__PURE__ */ jsx(
1032
1043
  LinkButton,
1033
1044
  {
1034
- as: Link$2,
1045
+ tag: Link$1,
1035
1046
  to: {
1036
1047
  pathname: "/content-manager"
1037
1048
  },
@@ -1042,19 +1053,59 @@ const ReleaseDetailsBody = () => {
1042
1053
  defaultMessage: "Open the Content Manager"
1043
1054
  })
1044
1055
  }
1045
- )
1056
+ ),
1057
+ icon: /* @__PURE__ */ jsx(EmptyDocuments, { width: "16rem" }),
1058
+ content: formatMessage({
1059
+ id: "content-releases.pages.Details.tab.emptyEntries",
1060
+ defaultMessage: "This release is empty. Open the Content Manager, select an entry and add it to the release."
1061
+ })
1046
1062
  }
1047
1063
  ) });
1048
1064
  }
1065
+ const groupByLabel = formatMessage({
1066
+ id: "content-releases.pages.ReleaseDetails.groupBy.aria-label",
1067
+ defaultMessage: "Group by"
1068
+ });
1069
+ const headers = [
1070
+ // ...displayedHeaders,
1071
+ {
1072
+ label: formatMessage({
1073
+ id: "content-releases.page.ReleaseDetails.table.header.label.name",
1074
+ defaultMessage: "name"
1075
+ }),
1076
+ name: "name"
1077
+ },
1078
+ {
1079
+ label: formatMessage({
1080
+ id: "content-releases.page.ReleaseDetails.table.header.label.content-type",
1081
+ defaultMessage: "content-type"
1082
+ }),
1083
+ name: "content-type"
1084
+ },
1085
+ {
1086
+ label: formatMessage({
1087
+ id: "content-releases.page.ReleaseDetails.table.header.label.action",
1088
+ defaultMessage: "action"
1089
+ }),
1090
+ name: "action"
1091
+ },
1092
+ ...!release.releasedAt ? [
1093
+ {
1094
+ label: formatMessage({
1095
+ id: "content-releases.page.ReleaseDetails.table.header.label.status",
1096
+ defaultMessage: "status"
1097
+ }),
1098
+ name: "status"
1099
+ }
1100
+ ] : []
1101
+ ];
1049
1102
  const options = hasI18nEnabled ? GROUP_BY_OPTIONS : GROUP_BY_OPTIONS_NO_LOCALE;
1050
- return /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsxs(Flex, { gap: 8, direction: "column", alignItems: "stretch", children: [
1103
+ return /* @__PURE__ */ jsx(Layouts.Content, { children: /* @__PURE__ */ jsxs(Flex, { gap: 8, direction: "column", alignItems: "stretch", children: [
1051
1104
  /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(
1052
1105
  SingleSelect,
1053
1106
  {
1054
- "aria-label": formatMessage({
1055
- id: "content-releases.pages.ReleaseDetails.groupBy.aria-label",
1056
- defaultMessage: "Group by"
1057
- }),
1107
+ placeholder: groupByLabel,
1108
+ "aria-label": groupByLabel,
1058
1109
  customizeContent: (value) => formatMessage(
1059
1110
  {
1060
1111
  id: `content-releases.pages.ReleaseDetails.groupBy.label`,
@@ -1078,55 +1129,11 @@ const ReleaseDetailsBody = () => {
1078
1129
  ...item,
1079
1130
  id: Number(item.entry.id)
1080
1131
  })),
1081
- colCount: releaseActions[key].length,
1082
- isLoading,
1083
- isFetching,
1132
+ headers,
1133
+ isLoading: isLoading || isFetching,
1084
1134
  children: /* @__PURE__ */ jsxs(Table.Content, { children: [
1085
- /* @__PURE__ */ jsxs(Table.Head, { children: [
1086
- displayedHeaders.map(({ key: key2, fieldSchema, metadatas, name }) => /* @__PURE__ */ jsx(
1087
- Table.HeaderCell,
1088
- {
1089
- fieldSchemaType: fieldSchema.type,
1090
- label: formatMessage(metadatas.label),
1091
- name
1092
- },
1093
- key2
1094
- )),
1095
- /* @__PURE__ */ jsx(
1096
- Table.HeaderCell,
1097
- {
1098
- fieldSchemaType: "string",
1099
- label: formatMessage({
1100
- id: "content-releases.page.ReleaseDetails.table.header.label.content-type",
1101
- defaultMessage: "content-type"
1102
- }),
1103
- name: "content-type"
1104
- }
1105
- ),
1106
- /* @__PURE__ */ jsx(
1107
- Table.HeaderCell,
1108
- {
1109
- fieldSchemaType: "string",
1110
- label: formatMessage({
1111
- id: "content-releases.page.ReleaseDetails.table.header.label.action",
1112
- defaultMessage: "action"
1113
- }),
1114
- name: "action"
1115
- }
1116
- ),
1117
- !release.releasedAt && /* @__PURE__ */ jsx(
1118
- Table.HeaderCell,
1119
- {
1120
- fieldSchemaType: "string",
1121
- label: formatMessage({
1122
- id: "content-releases.page.ReleaseDetails.table.header.label.status",
1123
- defaultMessage: "status"
1124
- }),
1125
- name: "status"
1126
- }
1127
- )
1128
- ] }),
1129
- /* @__PURE__ */ jsx(Table.LoadingBody, {}),
1135
+ /* @__PURE__ */ jsx(Table.Head, { children: headers.map((header) => /* @__PURE__ */ jsx(Table.HeaderCell, { ...header }, header.name)) }),
1136
+ /* @__PURE__ */ jsx(Table.Loading, {}),
1130
1137
  /* @__PURE__ */ jsx(Table.Body, { children: releaseActions[key].map(
1131
1138
  ({ id, contentType, locale, type, entry }, actionIndex) => /* @__PURE__ */ jsxs(Tr, { children: [
1132
1139
  /* @__PURE__ */ jsx(Td, { width: "25%", maxWidth: "200px", children: /* @__PURE__ */ jsx(Typography, { ellipsis: true, children: `${contentType.mainFieldValue || entry.id}` }) }),
@@ -1184,34 +1191,39 @@ const ReleaseDetailsBody = () => {
1184
1191
  }
1185
1192
  )
1186
1193
  ] }, `releases-group-${key}`)),
1187
- /* @__PURE__ */ jsxs(Flex, { paddingTop: 4, alignItems: "flex-end", justifyContent: "space-between", children: [
1188
- /* @__PURE__ */ jsx(PageSizeURLQuery, { defaultValue: releaseMeta?.pagination?.pageSize.toString() }),
1189
- /* @__PURE__ */ jsx(
1190
- PaginationURLQuery,
1191
- {
1192
- pagination: {
1193
- pageCount: releaseMeta?.pagination?.pageCount || 0
1194
- }
1195
- }
1196
- )
1197
- ] })
1194
+ /* @__PURE__ */ jsxs(
1195
+ Pagination.Root,
1196
+ {
1197
+ ...releaseMeta?.pagination,
1198
+ defaultPageSize: releaseMeta?.pagination?.pageSize,
1199
+ children: [
1200
+ /* @__PURE__ */ jsx(Pagination.PageSize, {}),
1201
+ /* @__PURE__ */ jsx(Pagination.Links, {})
1202
+ ]
1203
+ }
1204
+ )
1198
1205
  ] }) });
1199
1206
  };
1200
1207
  const ReleaseDetailsPage = () => {
1201
1208
  const { formatMessage } = useIntl();
1202
1209
  const { releaseId } = useParams();
1203
- const toggleNotification = useNotification();
1210
+ const { toggleNotification } = useNotification();
1204
1211
  const { formatAPIError } = useAPIErrorHandler();
1205
- const { replace } = useHistory();
1212
+ const navigate = useNavigate();
1206
1213
  const [releaseModalShown, setReleaseModalShown] = React.useState(false);
1207
1214
  const [showWarningSubmit, setWarningSubmit] = React.useState(false);
1208
1215
  const {
1209
1216
  isLoading: isLoadingDetails,
1210
1217
  data,
1211
1218
  isSuccess: isSuccessDetails
1212
- } = useGetReleaseQuery({ id: releaseId });
1219
+ } = useGetReleaseQuery(
1220
+ { id: releaseId },
1221
+ {
1222
+ skip: !releaseId
1223
+ }
1224
+ );
1213
1225
  const [updateRelease, { isLoading: isSubmittingForm }] = useUpdateReleaseMutation();
1214
- const [deleteRelease, { isLoading: isDeletingRelease }] = useDeleteReleaseMutation();
1226
+ const [deleteRelease] = useDeleteReleaseMutation();
1215
1227
  const toggleEditReleaseModal = () => {
1216
1228
  setReleaseModalShown((prev) => !prev);
1217
1229
  };
@@ -1222,15 +1234,18 @@ const ReleaseDetailsPage = () => {
1222
1234
  {
1223
1235
  toggleEditReleaseModal,
1224
1236
  toggleWarningSubmit,
1225
- children: /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsx(LoadingIndicatorPage, {}) })
1237
+ children: /* @__PURE__ */ jsx(Page.Loading, {})
1226
1238
  }
1227
1239
  );
1228
1240
  }
1241
+ if (!releaseId) {
1242
+ return /* @__PURE__ */ jsx(Navigate, { to: ".." });
1243
+ }
1229
1244
  const releaseData = isSuccessDetails && data?.data || null;
1230
1245
  const title = releaseData?.name || "";
1231
1246
  const timezone = releaseData?.timezone ?? null;
1232
1247
  const scheduledAt = releaseData?.scheduledAt && timezone ? utcToZonedTime(releaseData.scheduledAt, timezone) : null;
1233
- const date = scheduledAt ? format(scheduledAt, "yyyy-MM-dd") : null;
1248
+ const date = scheduledAt ? format(scheduledAt, "yyyy-MM-dd") : void 0;
1234
1249
  const time = scheduledAt ? format(scheduledAt, "HH:mm") : "";
1235
1250
  const handleEditRelease = async (values) => {
1236
1251
  const response = await updateRelease({
@@ -1248,14 +1263,14 @@ const ReleaseDetailsPage = () => {
1248
1263
  })
1249
1264
  });
1250
1265
  toggleEditReleaseModal();
1251
- } else if (isAxiosError(response.error)) {
1266
+ } else if (isFetchError(response.error)) {
1252
1267
  toggleNotification({
1253
- type: "warning",
1268
+ type: "danger",
1254
1269
  message: formatAPIError(response.error)
1255
1270
  });
1256
1271
  } else {
1257
1272
  toggleNotification({
1258
- type: "warning",
1273
+ type: "danger",
1259
1274
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
1260
1275
  });
1261
1276
  }
@@ -1265,15 +1280,15 @@ const ReleaseDetailsPage = () => {
1265
1280
  id: releaseId
1266
1281
  });
1267
1282
  if ("data" in response) {
1268
- replace("/plugins/content-releases");
1269
- } else if (isAxiosError(response.error)) {
1283
+ navigate("..");
1284
+ } else if (isFetchError(response.error)) {
1270
1285
  toggleNotification({
1271
- type: "warning",
1286
+ type: "danger",
1272
1287
  message: formatAPIError(response.error)
1273
1288
  });
1274
1289
  } else {
1275
1290
  toggleNotification({
1276
- type: "warning",
1291
+ type: "danger",
1277
1292
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
1278
1293
  });
1279
1294
  }
@@ -1284,7 +1299,7 @@ const ReleaseDetailsPage = () => {
1284
1299
  toggleEditReleaseModal,
1285
1300
  toggleWarningSubmit,
1286
1301
  children: [
1287
- /* @__PURE__ */ jsx(ReleaseDetailsBody, {}),
1302
+ /* @__PURE__ */ jsx(ReleaseDetailsBody, { releaseId }),
1288
1303
  releaseModalShown && /* @__PURE__ */ jsx(
1289
1304
  ReleaseModal,
1290
1305
  {
@@ -1304,14 +1319,13 @@ const ReleaseDetailsPage = () => {
1304
1319
  /* @__PURE__ */ jsx(
1305
1320
  ConfirmDialog,
1306
1321
  {
1307
- bodyText: {
1322
+ isOpen: showWarningSubmit,
1323
+ onClose: toggleWarningSubmit,
1324
+ onConfirm: handleDeleteRelease,
1325
+ children: formatMessage({
1308
1326
  id: "content-releases.dialog.confirmation-message",
1309
1327
  defaultMessage: "Are you sure you want to delete this release?"
1310
- },
1311
- isOpen: showWarningSubmit,
1312
- isConfirmButtonLoading: isDeletingRelease,
1313
- onToggleDialog: toggleWarningSubmit,
1314
- onConfirm: handleDeleteRelease
1328
+ })
1315
1329
  }
1316
1330
  )
1317
1331
  ]
@@ -1319,12 +1333,12 @@ const ReleaseDetailsPage = () => {
1319
1333
  );
1320
1334
  };
1321
1335
  const App = () => {
1322
- return /* @__PURE__ */ jsx(CheckPagePermissions, { permissions: PERMISSIONS.main, children: /* @__PURE__ */ jsxs(Switch, { children: [
1323
- /* @__PURE__ */ jsx(Route, { exact: true, path: `/plugins/${pluginId}`, component: ReleasesPage }),
1324
- /* @__PURE__ */ jsx(Route, { exact: true, path: `/plugins/${pluginId}/:releaseId`, component: ReleaseDetailsPage })
1336
+ return /* @__PURE__ */ jsx(Page.Protect, { permissions: PERMISSIONS.main, children: /* @__PURE__ */ jsxs(Routes, { children: [
1337
+ /* @__PURE__ */ jsx(Route, { index: true, element: /* @__PURE__ */ jsx(ReleasesPage, {}) }),
1338
+ /* @__PURE__ */ jsx(Route, { path: ":releaseId", element: /* @__PURE__ */ jsx(ReleaseDetailsPage, {}) })
1325
1339
  ] }) });
1326
1340
  };
1327
1341
  export {
1328
1342
  App
1329
1343
  };
1330
- //# sourceMappingURL=App-gu1aiP6i.mjs.map
1344
+ //# sourceMappingURL=App-D_6Y9N2F.mjs.map