@strapi/content-releases 0.0.0-experimental.d4cb32ce579e12a4436d68036f2327132fba1309 → 0.0.0-experimental.d53e940834bf72ddc725f1d2fd36dac9abec30cb

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-xAkiD42p.mjs → App-B2R2exNT.mjs} +656 -625
  2. package/dist/_chunks/App-B2R2exNT.mjs.map +1 -0
  3. package/dist/_chunks/{App-OK4Xac-O.js → App-CEwOQkKT.js} +671 -641
  4. package/dist/_chunks/App-CEwOQkKT.js.map +1 -0
  5. package/dist/_chunks/{PurchaseContentReleases-YhAPgpG9.js → PurchaseContentReleases-Be3acS2L.js} +8 -7
  6. package/dist/_chunks/PurchaseContentReleases-Be3acS2L.js.map +1 -0
  7. package/dist/_chunks/{PurchaseContentReleases-Clm0iACO.mjs → PurchaseContentReleases-_MxP6-Dt.mjs} +9 -8
  8. package/dist/_chunks/PurchaseContentReleases-_MxP6-Dt.mjs.map +1 -0
  9. package/dist/_chunks/{en-veqvqeEr.mjs → en-B9Ur3VsE.mjs} +14 -5
  10. package/dist/_chunks/en-B9Ur3VsE.mjs.map +1 -0
  11. package/dist/_chunks/{en-r0otWaln.js → en-DtFJ5ViE.js} +14 -5
  12. package/dist/_chunks/en-DtFJ5ViE.js.map +1 -0
  13. package/dist/_chunks/{index-JvA2_26n.js → index-BrWv-zV4.js} +258 -244
  14. package/dist/_chunks/index-BrWv-zV4.js.map +1 -0
  15. package/dist/_chunks/{index-exoiSU3V.mjs → index-DbmynICx.mjs} +264 -248
  16. package/dist/_chunks/index-DbmynICx.mjs.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 +17 -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 +675 -232
  43. package/dist/server/index.js.map +1 -1
  44. package/dist/server/index.mjs +675 -232
  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-OK4Xac-O.js.map +0 -1
  104. package/dist/_chunks/App-xAkiD42p.mjs.map +0 -1
  105. package/dist/_chunks/PurchaseContentReleases-Clm0iACO.mjs.map +0 -1
  106. package/dist/_chunks/PurchaseContentReleases-YhAPgpG9.js.map +0 -1
  107. package/dist/_chunks/en-r0otWaln.js.map +0 -1
  108. package/dist/_chunks/en-veqvqeEr.mjs.map +0 -1
  109. package/dist/_chunks/index-JvA2_26n.js.map +0 -1
  110. package/dist/_chunks/index-exoiSU3V.mjs.map +0 -1
@@ -1,25 +1,23 @@
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
+ const strapiAdmin = require("@strapi/admin/strapi-admin");
5
5
  const reactRouterDom = require("react-router-dom");
6
- const index = require("./index-JvA2_26n.js");
6
+ const index = require("./index-BrWv-zV4.js");
7
7
  const React = require("react");
8
- const strapiAdmin = require("@strapi/admin/strapi-admin");
8
+ const strapiAdmin$1 = require("@strapi/content-manager/strapi-admin");
9
9
  const designSystem = require("@strapi/design-system");
10
- const v2 = require("@strapi/design-system/v2");
11
10
  const icons = require("@strapi/icons");
11
+ const symbols = require("@strapi/icons/symbols");
12
12
  const format = require("date-fns/format");
13
13
  const dateFnsTz = require("date-fns-tz");
14
14
  const reactIntl = require("react-intl");
15
- const styled = require("styled-components");
15
+ const styledComponents = require("styled-components");
16
16
  const dateFns = require("date-fns");
17
17
  const formik = require("formik");
18
18
  const yup = require("yup");
19
- require("@reduxjs/toolkit/query");
20
- require("axios");
21
- require("@reduxjs/toolkit/query/react");
22
- require("react-redux");
19
+ const reactRedux = require("react-redux");
20
+ const ee = require("@strapi/admin/strapi-admin/ee");
23
21
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
24
22
  function _interopNamespace(e) {
25
23
  if (e && e.__esModule)
@@ -41,8 +39,37 @@ function _interopNamespace(e) {
41
39
  }
42
40
  const React__namespace = /* @__PURE__ */ _interopNamespace(React);
43
41
  const format__default = /* @__PURE__ */ _interopDefault(format);
44
- const styled__default = /* @__PURE__ */ _interopDefault(styled);
45
42
  const yup__namespace = /* @__PURE__ */ _interopNamespace(yup);
43
+ const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
44
+ const RelativeTime$1 = React__namespace.forwardRef(
45
+ ({ timestamp, customIntervals = [], ...restProps }, forwardedRef) => {
46
+ const { formatRelativeTime, formatDate, formatTime } = reactIntl.useIntl();
47
+ const interval = dateFns.intervalToDuration({
48
+ start: timestamp,
49
+ end: Date.now()
50
+ // see https://github.com/date-fns/date-fns/issues/2891 – No idea why it's all partial it returns it every time.
51
+ });
52
+ const unit = intervals.find((intervalUnit) => {
53
+ return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);
54
+ });
55
+ const relativeTime = dateFns.isPast(timestamp) ? -interval[unit] : interval[unit];
56
+ const customInterval = customIntervals.find(
57
+ (custom) => interval[custom.unit] < custom.threshold
58
+ );
59
+ const displayText = customInterval ? customInterval.text : formatRelativeTime(relativeTime, unit, { numeric: "auto" });
60
+ return /* @__PURE__ */ jsxRuntime.jsx(
61
+ "time",
62
+ {
63
+ ref: forwardedRef,
64
+ dateTime: timestamp.toISOString(),
65
+ role: "time",
66
+ title: `${formatDate(timestamp)} ${formatTime(timestamp)}`,
67
+ ...restProps,
68
+ children: displayText
69
+ }
70
+ );
71
+ }
72
+ );
46
73
  const RELEASE_SCHEMA = yup__namespace.object().shape({
47
74
  name: yup__namespace.string().trim().required(),
48
75
  scheduledAt: yup__namespace.string().nullable(),
@@ -65,6 +92,7 @@ const RELEASE_SCHEMA = yup__namespace.object().shape({
65
92
  }).required().noUnknown();
66
93
  const ReleaseModal = ({
67
94
  handleClose,
95
+ open,
68
96
  handleSubmit,
69
97
  initialValues,
70
98
  isLoading = false
@@ -72,7 +100,6 @@ const ReleaseModal = ({
72
100
  const { formatMessage } = reactIntl.useIntl();
73
101
  const { pathname } = reactRouterDom.useLocation();
74
102
  const isCreatingRelease = pathname === `/plugins/${index.pluginId}`;
75
- const IsSchedulingEnabled = window.strapi.future.isEnabled("contentReleasesScheduling");
76
103
  const { timezoneList, systemTimezone = { value: "UTC+00:00-Africa/Abidjan " } } = getTimezones(
77
104
  initialValues.scheduledAt ? new Date(initialValues.scheduledAt) : /* @__PURE__ */ new Date()
78
105
  );
@@ -80,18 +107,17 @@ const ReleaseModal = ({
80
107
  const { date, time, timezone } = values;
81
108
  if (!date || !time || !timezone)
82
109
  return null;
83
- const formattedDate = dateFns.parse(time, "HH:mm", new Date(date));
84
- const timezoneWithoutOffset = timezone.split("_")[1];
85
- return dateFnsTz.zonedTimeToUtc(formattedDate, timezoneWithoutOffset);
110
+ const timezoneWithoutOffset = timezone.split("&")[1];
111
+ return dateFnsTz.zonedTimeToUtc(`${date} ${time}`, timezoneWithoutOffset);
86
112
  };
87
113
  const getTimezoneWithOffset = () => {
88
114
  const currentTimezone = timezoneList.find(
89
- (timezone) => timezone.value.split("_")[1] === initialValues.timezone
115
+ (timezone) => timezone.value.split("&")[1] === initialValues.timezone
90
116
  );
91
117
  return currentTimezone?.value || systemTimezone.value;
92
118
  };
93
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.ModalLayout, { onClose: handleClose, labelledBy: "title", children: [
94
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.ModalHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "title", fontWeight: "bold", textColor: "neutral800", children: formatMessage(
119
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Root, { open, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Content, { children: [
120
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Title, { children: formatMessage(
95
121
  {
96
122
  id: "content-releases.modal.title",
97
123
  defaultMessage: "{isCreatingRelease, select, true {New release} other {Edit release}}"
@@ -104,7 +130,7 @@ const ReleaseModal = ({
104
130
  onSubmit: (values) => {
105
131
  handleSubmit({
106
132
  ...values,
107
- timezone: values.timezone ? values.timezone.split("_")[1] : null,
133
+ timezone: values.timezone ? values.timezone.split("&")[1] : null,
108
134
  scheduledAt: values.isScheduled ? getScheduledTimestamp(values) : null
109
135
  });
110
136
  },
@@ -114,31 +140,25 @@ const ReleaseModal = ({
114
140
  },
115
141
  validationSchema: RELEASE_SCHEMA,
116
142
  validateOnChange: false,
117
- children: ({ values, errors, handleChange, setFieldValue }) => /* @__PURE__ */ jsxRuntime.jsxs(formik.Form, { children: [
118
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.ModalBody, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 6, children: [
119
- /* @__PURE__ */ jsxRuntime.jsx(
120
- designSystem.TextInput,
121
- {
122
- label: formatMessage({
143
+ children: ({ values, errors, handleChange, setFieldValue }) => {
144
+ return /* @__PURE__ */ jsxRuntime.jsxs(formik.Form, { children: [
145
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 6, children: [
146
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { name: "name", error: errors.name, required: true, children: [
147
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
123
148
  id: "content-releases.modal.form.input.label.release-name",
124
149
  defaultMessage: "Name"
125
- }),
126
- name: "name",
127
- value: values.name,
128
- error: errors.name,
129
- onChange: handleChange,
130
- required: true
131
- }
132
- ),
133
- IsSchedulingEnabled && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
150
+ }) }),
151
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.TextInput, { value: values.name, onChange: handleChange }),
152
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {})
153
+ ] }),
134
154
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "max-content", children: /* @__PURE__ */ jsxRuntime.jsx(
135
155
  designSystem.Checkbox,
136
156
  {
137
157
  name: "isScheduled",
138
- value: values.isScheduled,
139
- onChange: (event) => {
140
- setFieldValue("isScheduled", event.target.checked);
141
- if (!event.target.checked) {
158
+ checked: values.isScheduled,
159
+ onCheckedChange: (checked) => {
160
+ setFieldValue("isScheduled", checked);
161
+ if (!checked) {
142
162
  setFieldValue("date", null);
143
163
  setFieldValue("time", "");
144
164
  setFieldValue("timezone", null);
@@ -166,83 +186,81 @@ const ReleaseModal = ({
166
186
  ) }),
167
187
  values.isScheduled && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
168
188
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 4, alignItems: "start", children: [
169
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsx(
170
- designSystem.DatePicker,
171
- {
172
- label: formatMessage({
173
- id: "content-releases.modal.form.input.label.date",
174
- defaultMessage: "Date"
175
- }),
176
- name: "date",
177
- error: errors.date,
178
- onChange: (date) => {
179
- const isoFormatDate = date ? dateFns.formatISO(date, { representation: "date" }) : null;
180
- setFieldValue("date", isoFormatDate);
181
- },
182
- clearLabel: formatMessage({
183
- id: "content-releases.modal.form.input.clearLabel",
184
- defaultMessage: "Clear"
185
- }),
186
- onClear: () => {
187
- setFieldValue("date", null);
188
- },
189
- selectedDate: values.date || void 0,
190
- required: true
191
- }
192
- ) }),
193
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsx(
194
- designSystem.TimePicker,
195
- {
196
- label: formatMessage({
197
- id: "content-releases.modal.form.input.label.time",
198
- defaultMessage: "Time"
199
- }),
200
- name: "time",
201
- error: errors.time,
202
- onChange: (time) => {
203
- setFieldValue("time", time);
204
- },
205
- clearLabel: formatMessage({
206
- id: "content-releases.modal.form.input.clearLabel",
207
- defaultMessage: "Clear"
208
- }),
209
- onClear: () => {
210
- setFieldValue("time", "");
211
- },
212
- value: values.time || void 0,
213
- required: true
214
- }
215
- ) })
189
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { name: "date", error: errors.date, required: true, children: [
190
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
191
+ id: "content-releases.modal.form.input.label.date",
192
+ defaultMessage: "Date"
193
+ }) }),
194
+ /* @__PURE__ */ jsxRuntime.jsx(
195
+ designSystem.DatePicker,
196
+ {
197
+ onChange: (date) => {
198
+ const isoFormatDate = date ? dateFns.formatISO(date, { representation: "date" }) : null;
199
+ setFieldValue("date", isoFormatDate);
200
+ },
201
+ clearLabel: formatMessage({
202
+ id: "content-releases.modal.form.input.clearLabel",
203
+ defaultMessage: "Clear"
204
+ }),
205
+ onClear: () => {
206
+ setFieldValue("date", null);
207
+ },
208
+ value: values.date ? new Date(values.date) : /* @__PURE__ */ new Date(),
209
+ minDate: dateFnsTz.utcToZonedTime(/* @__PURE__ */ new Date(), values.timezone.split("&")[1])
210
+ }
211
+ ),
212
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {})
213
+ ] }) }),
214
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { name: "time", error: errors.time, required: true, children: [
215
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
216
+ id: "content-releases.modal.form.input.label.time",
217
+ defaultMessage: "Time"
218
+ }) }),
219
+ /* @__PURE__ */ jsxRuntime.jsx(
220
+ designSystem.TimePicker,
221
+ {
222
+ onChange: (time) => {
223
+ setFieldValue("time", time);
224
+ },
225
+ clearLabel: formatMessage({
226
+ id: "content-releases.modal.form.input.clearLabel",
227
+ defaultMessage: "Clear"
228
+ }),
229
+ onClear: () => {
230
+ setFieldValue("time", "");
231
+ },
232
+ value: values.time || void 0
233
+ }
234
+ ),
235
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {})
236
+ ] }) })
216
237
  ] }),
217
238
  /* @__PURE__ */ jsxRuntime.jsx(TimezoneComponent, { timezoneOptions: timezoneList })
218
239
  ] })
219
- ] })
220
- ] }) }),
221
- /* @__PURE__ */ jsxRuntime.jsx(
222
- designSystem.ModalFooter,
223
- {
224
- startActions: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleClose, variant: "tertiary", name: "cancel", children: formatMessage({ id: "cancel", defaultMessage: "Cancel" }) }),
225
- endActions: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { name: "submit", loading: isLoading, type: "submit", children: formatMessage(
240
+ ] }) }),
241
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
242
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Close, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", name: "cancel", children: formatMessage({ id: "cancel", defaultMessage: "Cancel" }) }) }),
243
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { name: "submit", loading: isLoading, type: "submit", children: formatMessage(
226
244
  {
227
245
  id: "content-releases.modal.form.button.submit",
228
246
  defaultMessage: "{isCreatingRelease, select, true {Continue} other {Save}}"
229
247
  },
230
248
  { isCreatingRelease }
231
249
  ) })
232
- }
233
- )
234
- ] })
250
+ ] })
251
+ ] });
252
+ }
235
253
  }
236
254
  )
237
- ] });
255
+ ] }) });
238
256
  };
239
257
  const getTimezones = (selectedDate) => {
240
258
  const timezoneList = Intl.supportedValuesOf("timeZone").map((timezone) => {
241
259
  const utcOffset = index.getTimezoneOffset(timezone, selectedDate);
242
- return { offset: utcOffset, value: `${utcOffset}_${timezone}` };
260
+ return { offset: utcOffset, value: `${utcOffset}&${timezone}` };
243
261
  });
244
262
  const systemTimezone = timezoneList.find(
245
- (timezone) => timezone.value.split("_")[1] === Intl.DateTimeFormat().resolvedOptions().timeZone
263
+ (timezone) => timezone.value.split("&")[1] === Intl.DateTimeFormat().resolvedOptions().timeZone
246
264
  );
247
265
  return { timezoneList, systemTimezone };
248
266
  };
@@ -254,88 +272,405 @@ const TimezoneComponent = ({ timezoneOptions }) => {
254
272
  if (values.date) {
255
273
  const { timezoneList: timezoneList2 } = getTimezones(new Date(values.date));
256
274
  setTimezoneList(timezoneList2);
257
- const updatedTimezone = values.timezone && timezoneList2.find((tz) => tz.value.split("_")[1] === values.timezone.split("_")[1]);
275
+ const updatedTimezone = values.timezone && timezoneList2.find((tz) => tz.value.split("&")[1] === values.timezone.split("&")[1]);
258
276
  if (updatedTimezone) {
259
277
  setFieldValue("timezone", updatedTimezone.value);
260
278
  }
261
279
  }
262
280
  }, [setFieldValue, values.date, values.timezone]);
263
- return /* @__PURE__ */ jsxRuntime.jsx(
264
- designSystem.Combobox,
281
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { name: "timezone", error: errors.timezone, required: true, children: [
282
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
283
+ id: "content-releases.modal.form.input.label.timezone",
284
+ defaultMessage: "Timezone"
285
+ }) }),
286
+ /* @__PURE__ */ jsxRuntime.jsx(
287
+ designSystem.Combobox,
288
+ {
289
+ autocomplete: { type: "list", filter: "contains" },
290
+ value: values.timezone || void 0,
291
+ textValue: values.timezone ? values.timezone.replace(/&/, " ") : void 0,
292
+ onChange: (timezone) => {
293
+ setFieldValue("timezone", timezone);
294
+ },
295
+ onTextValueChange: (timezone) => {
296
+ setFieldValue("timezone", timezone);
297
+ },
298
+ onClear: () => {
299
+ setFieldValue("timezone", "");
300
+ },
301
+ children: timezoneList.map((timezone) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.ComboboxOption, { value: timezone.value, children: timezone.value.replace(/&/, " ") }, timezone.value))
302
+ }
303
+ ),
304
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {})
305
+ ] });
306
+ };
307
+ const useTypedDispatch = reactRedux.useDispatch;
308
+ const isBaseQueryError = (error) => {
309
+ return typeof error !== "undefined" && error.name !== void 0;
310
+ };
311
+ const LinkCard = styledComponents.styled(designSystem.Link)`
312
+ display: block;
313
+ `;
314
+ const RelativeTime = styledComponents.styled(RelativeTime$1)`
315
+ display: inline-block;
316
+ &::first-letter {
317
+ text-transform: uppercase;
318
+ }
319
+ `;
320
+ const getBadgeProps = (status) => {
321
+ let color;
322
+ switch (status) {
323
+ case "ready":
324
+ color = "success";
325
+ break;
326
+ case "blocked":
327
+ color = "warning";
328
+ break;
329
+ case "failed":
330
+ color = "danger";
331
+ break;
332
+ case "done":
333
+ color = "primary";
334
+ break;
335
+ case "empty":
336
+ default:
337
+ color = "neutral";
338
+ }
339
+ return {
340
+ textColor: `${color}600`,
341
+ backgroundColor: `${color}100`,
342
+ borderColor: `${color}200`
343
+ };
344
+ };
345
+ const ReleasesGrid = ({ sectionTitle, releases = [], isError = false }) => {
346
+ const { formatMessage } = reactIntl.useIntl();
347
+ if (isError) {
348
+ return /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Page.Error, {});
349
+ }
350
+ if (releases?.length === 0) {
351
+ return /* @__PURE__ */ jsxRuntime.jsx(
352
+ designSystem.EmptyStateLayout,
353
+ {
354
+ content: formatMessage(
355
+ {
356
+ id: "content-releases.page.Releases.tab.emptyEntries",
357
+ defaultMessage: "No releases"
358
+ },
359
+ {
360
+ target: sectionTitle
361
+ }
362
+ ),
363
+ icon: /* @__PURE__ */ jsxRuntime.jsx(symbols.EmptyDocuments, { width: "16rem" })
364
+ }
365
+ );
366
+ }
367
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Root, { gap: 4, children: releases.map(({ id, name, scheduledAt, status }) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 3, s: 6, xs: 12, children: /* @__PURE__ */ jsxRuntime.jsx(LinkCard, { tag: reactRouterDom.NavLink, to: `${id}`, isExternal: false, children: /* @__PURE__ */ jsxRuntime.jsxs(
368
+ designSystem.Flex,
265
369
  {
266
- label: formatMessage({
267
- id: "content-releases.modal.form.input.label.timezone",
268
- defaultMessage: "Timezone"
269
- }),
270
- name: "timezone",
271
- value: values.timezone || void 0,
272
- textValue: values.timezone ? values.timezone.replace("_", " ") : void 0,
273
- onChange: (timezone) => {
274
- setFieldValue("timezone", timezone);
275
- },
276
- onClear: () => {
277
- setFieldValue("timezone", "");
278
- },
279
- error: errors.timezone,
280
- required: true,
281
- children: timezoneList.map((timezone) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.ComboboxOption, { value: timezone.value, children: timezone.value.replace("_", " ") }, timezone.value))
370
+ direction: "column",
371
+ justifyContent: "space-between",
372
+ padding: 4,
373
+ hasRadius: true,
374
+ background: "neutral0",
375
+ shadow: "tableShadow",
376
+ height: "100%",
377
+ width: "100%",
378
+ alignItems: "start",
379
+ gap: 4,
380
+ children: [
381
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "start", gap: 1, children: [
382
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", tag: "h3", variant: "delta", fontWeight: "bold", children: name }),
383
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: scheduledAt ? /* @__PURE__ */ jsxRuntime.jsx(RelativeTime, { timestamp: new Date(scheduledAt) }) : formatMessage({
384
+ id: "content-releases.pages.Releases.not-scheduled",
385
+ defaultMessage: "Not scheduled"
386
+ }) })
387
+ ] }),
388
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { ...getBadgeProps(status), children: status })
389
+ ]
282
390
  }
283
- );
391
+ ) }) }, id)) });
392
+ };
393
+ const StyledAlert = styledComponents.styled(designSystem.Alert)`
394
+ button {
395
+ display: none;
396
+ }
397
+ p + div {
398
+ margin-left: auto;
399
+ }
400
+ `;
401
+ const INITIAL_FORM_VALUES = {
402
+ name: "",
403
+ date: void 0,
404
+ time: "",
405
+ isScheduled: true,
406
+ scheduledAt: null,
407
+ timezone: null
408
+ };
409
+ const ReleasesPage = () => {
410
+ const location = reactRouterDom.useLocation();
411
+ const [releaseModalShown, setReleaseModalShown] = React__namespace.useState(false);
412
+ const { toggleNotification } = strapiAdmin.useNotification();
413
+ const { formatMessage } = reactIntl.useIntl();
414
+ const navigate = reactRouterDom.useNavigate();
415
+ const { formatAPIError } = strapiAdmin.useAPIErrorHandler();
416
+ const [{ query }, setQuery] = strapiAdmin.useQueryParams();
417
+ const response = index.useGetReleasesQuery(query);
418
+ const [createRelease, { isLoading: isSubmittingForm }] = index.useCreateReleaseMutation();
419
+ const { getFeature } = ee.useLicenseLimits();
420
+ const { maximumReleases = 3 } = getFeature("cms-content-releases");
421
+ const { trackUsage } = strapiAdmin.useTracking();
422
+ const {
423
+ allowedActions: { canCreate }
424
+ } = strapiAdmin.useRBAC(index.PERMISSIONS);
425
+ const { isLoading, isSuccess, isError } = response;
426
+ const activeTab = response?.currentData?.meta?.activeTab || "pending";
427
+ React__namespace.useEffect(() => {
428
+ if (location?.state?.errors) {
429
+ toggleNotification({
430
+ type: "danger",
431
+ title: formatMessage({
432
+ id: "content-releases.pages.Releases.notification.error.title",
433
+ defaultMessage: "Your request could not be processed."
434
+ }),
435
+ message: formatMessage({
436
+ id: "content-releases.pages.Releases.notification.error.message",
437
+ defaultMessage: "Please try again or open another release."
438
+ })
439
+ });
440
+ navigate("", { replace: true, state: null });
441
+ }
442
+ }, [formatMessage, location?.state?.errors, navigate, toggleNotification]);
443
+ const toggleAddReleaseModal = () => {
444
+ setReleaseModalShown((prev) => !prev);
445
+ };
446
+ if (isLoading) {
447
+ return /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Page.Loading, {});
448
+ }
449
+ const totalPendingReleases = isSuccess && response.currentData?.meta?.pendingReleasesCount || 0;
450
+ const hasReachedMaximumPendingReleases = totalPendingReleases >= maximumReleases;
451
+ const handleTabChange = (tabValue) => {
452
+ setQuery({
453
+ ...query,
454
+ page: 1,
455
+ pageSize: response?.currentData?.meta?.pagination?.pageSize || 16,
456
+ filters: {
457
+ releasedAt: {
458
+ $notNull: tabValue !== "pending"
459
+ }
460
+ }
461
+ });
462
+ };
463
+ const handleAddRelease = async ({ name, scheduledAt, timezone }) => {
464
+ const response2 = await createRelease({
465
+ name,
466
+ scheduledAt,
467
+ timezone
468
+ });
469
+ if ("data" in response2) {
470
+ toggleNotification({
471
+ type: "success",
472
+ message: formatMessage({
473
+ id: "content-releases.modal.release-created-notification-success",
474
+ defaultMessage: "Release created."
475
+ })
476
+ });
477
+ trackUsage("didCreateRelease");
478
+ navigate(response2.data.data.id.toString());
479
+ } else if (strapiAdmin.isFetchError(response2.error)) {
480
+ toggleNotification({
481
+ type: "danger",
482
+ message: formatAPIError(response2.error)
483
+ });
484
+ } else {
485
+ toggleNotification({
486
+ type: "danger",
487
+ message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
488
+ });
489
+ }
490
+ };
491
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Main, { "aria-busy": isLoading, children: [
492
+ /* @__PURE__ */ jsxRuntime.jsx(
493
+ strapiAdmin.Layouts.Header,
494
+ {
495
+ title: formatMessage({
496
+ id: "content-releases.pages.Releases.title",
497
+ defaultMessage: "Releases"
498
+ }),
499
+ subtitle: formatMessage({
500
+ id: "content-releases.pages.Releases.header-subtitle",
501
+ defaultMessage: "Create and manage content updates"
502
+ }),
503
+ primaryAction: canCreate ? /* @__PURE__ */ jsxRuntime.jsx(
504
+ designSystem.Button,
505
+ {
506
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
507
+ onClick: toggleAddReleaseModal,
508
+ disabled: hasReachedMaximumPendingReleases,
509
+ children: formatMessage({
510
+ id: "content-releases.header.actions.add-release",
511
+ defaultMessage: "New release"
512
+ })
513
+ }
514
+ ) : null
515
+ }
516
+ ),
517
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Layouts.Content, { children: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
518
+ hasReachedMaximumPendingReleases && /* @__PURE__ */ jsxRuntime.jsx(
519
+ StyledAlert,
520
+ {
521
+ marginBottom: 6,
522
+ action: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Link, { href: "https://strapi.io/pricing-cloud", isExternal: true, children: formatMessage({
523
+ id: "content-releases.pages.Releases.max-limit-reached.action",
524
+ defaultMessage: "Explore plans"
525
+ }) }),
526
+ title: formatMessage(
527
+ {
528
+ id: "content-releases.pages.Releases.max-limit-reached.title",
529
+ defaultMessage: "You have reached the {number} pending {number, plural, one {release} other {releases}} limit."
530
+ },
531
+ { number: maximumReleases }
532
+ ),
533
+ onClose: () => {
534
+ },
535
+ closeLabel: "",
536
+ children: formatMessage({
537
+ id: "content-releases.pages.Releases.max-limit-reached.message",
538
+ defaultMessage: "Upgrade to manage an unlimited number of releases."
539
+ })
540
+ }
541
+ ),
542
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tabs.Root, { variant: "simple", onValueChange: handleTabChange, value: activeTab, children: [
543
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { paddingBottom: 8, children: [
544
+ /* @__PURE__ */ jsxRuntime.jsxs(
545
+ designSystem.Tabs.List,
546
+ {
547
+ "aria-label": formatMessage({
548
+ id: "content-releases.pages.Releases.tab-group.label",
549
+ defaultMessage: "Releases list"
550
+ }),
551
+ children: [
552
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tabs.Trigger, { value: "pending", children: formatMessage(
553
+ {
554
+ id: "content-releases.pages.Releases.tab.pending",
555
+ defaultMessage: "Pending ({count})"
556
+ },
557
+ {
558
+ count: totalPendingReleases
559
+ }
560
+ ) }),
561
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tabs.Trigger, { value: "done", children: formatMessage({
562
+ id: "content-releases.pages.Releases.tab.done",
563
+ defaultMessage: "Done"
564
+ }) })
565
+ ]
566
+ }
567
+ ),
568
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Divider, {})
569
+ ] }),
570
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tabs.Content, { value: "pending", children: /* @__PURE__ */ jsxRuntime.jsx(
571
+ ReleasesGrid,
572
+ {
573
+ sectionTitle: "pending",
574
+ releases: response?.currentData?.data,
575
+ isError
576
+ }
577
+ ) }),
578
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tabs.Content, { value: "done", children: /* @__PURE__ */ jsxRuntime.jsx(
579
+ ReleasesGrid,
580
+ {
581
+ sectionTitle: "done",
582
+ releases: response?.currentData?.data,
583
+ isError
584
+ }
585
+ ) })
586
+ ] }),
587
+ /* @__PURE__ */ jsxRuntime.jsxs(
588
+ strapiAdmin.Pagination.Root,
589
+ {
590
+ ...response?.currentData?.meta?.pagination,
591
+ defaultPageSize: response?.currentData?.meta?.pagination?.pageSize,
592
+ children: [
593
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Pagination.PageSize, { options: ["8", "16", "32", "64"] }),
594
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Pagination.Links, {})
595
+ ]
596
+ }
597
+ )
598
+ ] }) }),
599
+ /* @__PURE__ */ jsxRuntime.jsx(
600
+ ReleaseModal,
601
+ {
602
+ open: releaseModalShown,
603
+ handleClose: toggleAddReleaseModal,
604
+ handleSubmit: handleAddRelease,
605
+ isLoading: isSubmittingForm,
606
+ initialValues: INITIAL_FORM_VALUES
607
+ }
608
+ )
609
+ ] });
284
610
  };
285
- const ReleaseInfoWrapper = styled__default.default(designSystem.Flex)`
611
+ const ReleaseInfoWrapper = styledComponents.styled(designSystem.Flex)`
286
612
  align-self: stretch;
287
613
  border-bottom-right-radius: ${({ theme }) => theme.borderRadius};
288
614
  border-bottom-left-radius: ${({ theme }) => theme.borderRadius};
289
615
  border-top: 1px solid ${({ theme }) => theme.colors.neutral150};
290
616
  `;
291
- const StyledMenuItem = styled__default.default(v2.Menu.Item)`
617
+ const StyledMenuItem = styledComponents.styled(designSystem.Menu.Item)`
292
618
  svg path {
293
619
  fill: ${({ theme, disabled }) => disabled && theme.colors.neutral500};
294
620
  }
295
621
  span {
296
622
  color: ${({ theme, disabled }) => disabled && theme.colors.neutral500};
297
623
  }
624
+
625
+ &:hover {
626
+ background: ${({ theme, $variant = "neutral" }) => theme.colors[`${$variant}100`]};
627
+ }
298
628
  `;
299
- const PencilIcon = styled__default.default(icons.Pencil)`
629
+ const PencilIcon = styledComponents.styled(icons.Pencil)`
300
630
  width: ${({ theme }) => theme.spaces[3]};
301
631
  height: ${({ theme }) => theme.spaces[3]};
302
632
  path {
303
633
  fill: ${({ theme }) => theme.colors.neutral600};
304
634
  }
305
635
  `;
306
- const TrashIcon = styled__default.default(icons.Trash)`
636
+ const TrashIcon = styledComponents.styled(icons.Trash)`
307
637
  width: ${({ theme }) => theme.spaces[3]};
308
638
  height: ${({ theme }) => theme.spaces[3]};
309
639
  path {
310
640
  fill: ${({ theme }) => theme.colors.danger600};
311
641
  }
312
642
  `;
313
- const TypographyMaxWidth = styled__default.default(designSystem.Typography)`
643
+ const TypographyMaxWidth = styledComponents.styled(designSystem.Typography)`
314
644
  max-width: 300px;
315
645
  `;
316
- const EntryValidationText = ({ action, schema, components, entry }) => {
646
+ const EntryValidationText = ({ action, schema, entry }) => {
317
647
  const { formatMessage } = reactIntl.useIntl();
318
- const { validate } = strapiAdmin.unstable_useDocument();
319
- const { errors } = validate(entry, {
320
- contentType: schema,
321
- components,
322
- isCreatingEntry: false
323
- });
324
- if (Object.keys(errors).length > 0) {
325
- const validationErrorsMessages = Object.entries(errors).map(
326
- ([key, value]) => formatMessage(
648
+ const { validate } = strapiAdmin$1.unstable_useDocument(
649
+ {
650
+ collectionType: schema?.kind ?? "",
651
+ model: schema?.uid ?? ""
652
+ },
653
+ {
654
+ skip: !schema
655
+ }
656
+ );
657
+ const errors = validate(entry) ?? {};
658
+ if (Object.keys(errors).length > 0) {
659
+ const validationErrorsMessages = Object.entries(errors).map(
660
+ ([key, value]) => formatMessage(
661
+ // @ts-expect-error – TODO: fix this will better checks
327
662
  { id: `${value.id}.withField`, defaultMessage: value.defaultMessage },
328
663
  { field: key }
329
664
  )
330
665
  ).join(" ");
331
666
  return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
332
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Icon, { color: "danger600", as: icons.CrossCircle }),
667
+ /* @__PURE__ */ jsxRuntime.jsx(icons.CrossCircle, { fill: "danger600" }),
333
668
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tooltip, { description: validationErrorsMessages, children: /* @__PURE__ */ jsxRuntime.jsx(TypographyMaxWidth, { textColor: "danger600", variant: "omega", fontWeight: "semiBold", ellipsis: true, children: validationErrorsMessages }) })
334
669
  ] });
335
670
  }
336
671
  if (action == "publish") {
337
672
  return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
338
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Icon, { color: "success600", as: icons.CheckCircle }),
673
+ /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { fill: "success600" }),
339
674
  entry.publishedAt ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
340
675
  id: "content-releases.pages.ReleaseDetails.entry-validation.already-published",
341
676
  defaultMessage: "Already published"
@@ -346,7 +681,7 @@ const EntryValidationText = ({ action, schema, components, entry }) => {
346
681
  ] });
347
682
  }
348
683
  return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
349
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Icon, { color: "success600", as: icons.CheckCircle }),
684
+ /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { fill: "success600" }),
350
685
  !entry.publishedAt ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
351
686
  id: "content-releases.pages.ReleaseDetails.entry-validation.already-unpublished",
352
687
  defaultMessage: "Already unpublished"
@@ -366,20 +701,23 @@ const ReleaseDetailsLayout = ({
366
701
  const {
367
702
  data,
368
703
  isLoading: isLoadingDetails,
369
- isError,
370
704
  error
371
- } = index.useGetReleaseQuery({ id: releaseId });
705
+ } = index.useGetReleaseQuery(
706
+ { id: releaseId },
707
+ {
708
+ skip: !releaseId
709
+ }
710
+ );
372
711
  const [publishRelease, { isLoading: isPublishing }] = index.usePublishReleaseMutation();
373
- const toggleNotification = helperPlugin.useNotification();
374
- const { formatAPIError } = helperPlugin.useAPIErrorHandler();
375
- const {
376
- allowedActions: { canUpdate, canDelete }
377
- } = helperPlugin.useRBAC(index.PERMISSIONS);
378
- const dispatch = index.useTypedDispatch();
379
- const { trackUsage } = helperPlugin.useTracking();
712
+ const { toggleNotification } = strapiAdmin.useNotification();
713
+ const { formatAPIError } = strapiAdmin.useAPIErrorHandler();
714
+ const { allowedActions } = strapiAdmin.useRBAC(index.PERMISSIONS);
715
+ const { canUpdate, canDelete, canPublish } = allowedActions;
716
+ const dispatch = useTypedDispatch();
717
+ const { trackUsage } = strapiAdmin.useTracking();
380
718
  const release = data?.data;
381
- const handlePublishRelease = async () => {
382
- const response = await publishRelease({ id: releaseId });
719
+ const handlePublishRelease = (id) => async () => {
720
+ const response = await publishRelease({ id });
383
721
  if ("data" in response) {
384
722
  toggleNotification({
385
723
  type: "success",
@@ -394,20 +732,25 @@ const ReleaseDetailsLayout = ({
394
732
  totalPublishedEntries,
395
733
  totalUnpublishedEntries
396
734
  });
397
- } else if (index.isAxiosError(response.error)) {
735
+ } else if (strapiAdmin.isFetchError(response.error)) {
398
736
  toggleNotification({
399
- type: "warning",
737
+ type: "danger",
400
738
  message: formatAPIError(response.error)
401
739
  });
402
740
  } else {
403
741
  toggleNotification({
404
- type: "warning",
742
+ type: "danger",
405
743
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
406
744
  });
407
745
  }
408
746
  };
409
747
  const handleRefresh = () => {
410
- dispatch(index.releaseApi.util.invalidateTags([{ type: "ReleaseAction", id: "LIST" }]));
748
+ dispatch(
749
+ index.releaseApi.util.invalidateTags([
750
+ { type: "ReleaseAction", id: "LIST" },
751
+ { type: "Release", id: releaseId }
752
+ ])
753
+ );
411
754
  };
412
755
  const getCreatedByUser = () => {
413
756
  if (!release?.createdBy) {
@@ -422,28 +765,26 @@ const ReleaseDetailsLayout = ({
422
765
  return release.createdBy.email;
423
766
  };
424
767
  if (isLoadingDetails) {
425
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Main, { "aria-busy": isLoadingDetails, children: /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.LoadingIndicatorPage, {}) });
768
+ return /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Page.Loading, {});
426
769
  }
427
- if (isError || !release) {
770
+ if (isBaseQueryError(error) && "code" in error || !release) {
428
771
  return /* @__PURE__ */ jsxRuntime.jsx(
429
- reactRouterDom.Redirect,
772
+ reactRouterDom.Navigate,
430
773
  {
431
- to: {
432
- pathname: "/plugins/content-releases",
433
- state: {
434
- errors: [
435
- {
436
- code: error?.code
437
- }
438
- ]
439
- }
774
+ to: "..",
775
+ state: {
776
+ errors: [
777
+ {
778
+ // @ts-expect-error – TODO: fix this weird error flow
779
+ code: error?.code
780
+ }
781
+ ]
440
782
  }
441
783
  }
442
784
  );
443
785
  }
444
786
  const totalEntries = release.actions.meta.count || 0;
445
787
  const hasCreatedByUser = Boolean(getCreatedByUser());
446
- const IsSchedulingEnabled = window.strapi.future.isEnabled("contentReleasesScheduling");
447
788
  const isScheduled = release.scheduledAt && release.timezone;
448
789
  const numberOfEntriesText = formatMessage(
449
790
  {
@@ -474,31 +815,30 @@ const ReleaseDetailsLayout = ({
474
815
  ) : "";
475
816
  return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Main, { "aria-busy": isLoadingDetails, children: [
476
817
  /* @__PURE__ */ jsxRuntime.jsx(
477
- designSystem.HeaderLayout,
818
+ strapiAdmin.Layouts.Header,
478
819
  {
479
820
  title: release.name,
480
- subtitle: numberOfEntriesText + (IsSchedulingEnabled && isScheduled ? ` - ${scheduledText}` : ""),
481
- navigationAction: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Link, { startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowLeft, {}), to: "/plugins/content-releases", children: formatMessage({
482
- id: "global.back",
483
- defaultMessage: "Back"
484
- }) }),
821
+ subtitle: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, lineHeight: 6, children: [
822
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", variant: "epsilon", children: numberOfEntriesText + (isScheduled ? ` - ${scheduledText}` : "") }),
823
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { ...getBadgeProps(release.status), children: release.status })
824
+ ] }),
825
+ navigationAction: /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.BackButton, {}),
485
826
  primaryAction: !release.releasedAt && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
486
- /* @__PURE__ */ jsxRuntime.jsxs(v2.Menu.Root, { children: [
827
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Root, { children: [
487
828
  /* @__PURE__ */ jsxRuntime.jsx(
488
- v2.Menu.Trigger,
829
+ designSystem.Menu.Trigger,
489
830
  {
490
- as: designSystem.IconButton,
491
831
  paddingLeft: 2,
492
832
  paddingRight: 2,
493
833
  "aria-label": formatMessage({
494
834
  id: "content-releases.header.actions.open-release-actions",
495
835
  defaultMessage: "Release edit and delete menu"
496
836
  }),
497
- icon: /* @__PURE__ */ jsxRuntime.jsx(icons.More, {}),
498
- variant: "tertiary"
837
+ variant: "tertiary",
838
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.More, {})
499
839
  }
500
840
  ),
501
- /* @__PURE__ */ jsxRuntime.jsxs(v2.Menu.Content, { top: 1, popoverPlacement: "bottom-end", children: [
841
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Content, { top: 1, popoverPlacement: "bottom-end", maxHeight: void 0, children: [
502
842
  /* @__PURE__ */ jsxRuntime.jsxs(
503
843
  designSystem.Flex,
504
844
  {
@@ -508,42 +848,28 @@ const ReleaseDetailsLayout = ({
508
848
  padding: 1,
509
849
  width: "100%",
510
850
  children: [
511
- /* @__PURE__ */ jsxRuntime.jsx(StyledMenuItem, { disabled: !canUpdate, onSelect: toggleEditReleaseModal, children: /* @__PURE__ */ jsxRuntime.jsxs(
512
- designSystem.Flex,
513
- {
514
- paddingTop: 2,
515
- paddingBottom: 2,
516
- alignItems: "center",
517
- gap: 2,
518
- hasRadius: true,
519
- width: "100%",
520
- children: [
521
- /* @__PURE__ */ jsxRuntime.jsx(PencilIcon, {}),
522
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { ellipsis: true, children: formatMessage({
523
- id: "content-releases.header.actions.edit",
524
- defaultMessage: "Edit"
525
- }) })
526
- ]
527
- }
528
- ) }),
529
- /* @__PURE__ */ jsxRuntime.jsx(StyledMenuItem, { disabled: !canDelete, onSelect: toggleWarningSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs(
530
- designSystem.Flex,
851
+ /* @__PURE__ */ jsxRuntime.jsx(StyledMenuItem, { disabled: !canUpdate, onSelect: toggleEditReleaseModal, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "center", gap: 2, hasRadius: true, width: "100%", children: [
852
+ /* @__PURE__ */ jsxRuntime.jsx(PencilIcon, {}),
853
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { ellipsis: true, children: formatMessage({
854
+ id: "content-releases.header.actions.edit",
855
+ defaultMessage: "Edit"
856
+ }) })
857
+ ] }) }),
858
+ /* @__PURE__ */ jsxRuntime.jsx(
859
+ StyledMenuItem,
531
860
  {
532
- paddingTop: 2,
533
- paddingBottom: 2,
534
- alignItems: "center",
535
- gap: 2,
536
- hasRadius: true,
537
- width: "100%",
538
- children: [
861
+ disabled: !canDelete,
862
+ onSelect: toggleWarningSubmit,
863
+ $variant: "danger",
864
+ children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "center", gap: 2, hasRadius: true, width: "100%", children: [
539
865
  /* @__PURE__ */ jsxRuntime.jsx(TrashIcon, {}),
540
866
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { ellipsis: true, textColor: "danger600", children: formatMessage({
541
867
  id: "content-releases.header.actions.delete",
542
868
  defaultMessage: "Delete"
543
869
  }) })
544
- ]
870
+ ] })
545
871
  }
546
- ) })
872
+ )
547
873
  ]
548
874
  }
549
875
  ),
@@ -561,7 +887,7 @@ const ReleaseDetailsLayout = ({
561
887
  defaultMessage: "Created"
562
888
  }) }),
563
889
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", color: "neutral300", children: [
564
- /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.RelativeTime, { timestamp: new Date(release.createdAt) }),
890
+ /* @__PURE__ */ jsxRuntime.jsx(RelativeTime$1, { timestamp: new Date(release.createdAt) }),
565
891
  formatMessage(
566
892
  {
567
893
  id: "content-releases.header.actions.created.description",
@@ -579,12 +905,12 @@ const ReleaseDetailsLayout = ({
579
905
  id: "content-releases.header.actions.refresh",
580
906
  defaultMessage: "Refresh"
581
907
  }) }),
582
- /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.CheckPermissions, { permissions: index.PERMISSIONS.publish, children: /* @__PURE__ */ jsxRuntime.jsx(
908
+ canPublish ? /* @__PURE__ */ jsxRuntime.jsx(
583
909
  designSystem.Button,
584
910
  {
585
911
  size: "S",
586
912
  variant: "default",
587
- onClick: handlePublishRelease,
913
+ onClick: handlePublishRelease(release.id.toString()),
588
914
  loading: isPublishing,
589
915
  disabled: release.actions.meta.count === 0,
590
916
  children: formatMessage({
@@ -592,7 +918,7 @@ const ReleaseDetailsLayout = ({
592
918
  defaultMessage: "Publish"
593
919
  })
594
920
  }
595
- ) })
921
+ ) : null
596
922
  ] })
597
923
  }
598
924
  ),
@@ -600,6 +926,7 @@ const ReleaseDetailsLayout = ({
600
926
  ] });
601
927
  };
602
928
  const GROUP_BY_OPTIONS = ["contentType", "locale", "action"];
929
+ const GROUP_BY_OPTIONS_NO_LOCALE = ["contentType", "action"];
603
930
  const getGroupByOptionLabel = (value) => {
604
931
  if (value === "locale") {
605
932
  return {
@@ -618,21 +945,33 @@ const getGroupByOptionLabel = (value) => {
618
945
  defaultMessage: "Content-Types"
619
946
  };
620
947
  };
621
- const ReleaseDetailsBody = () => {
948
+ const ReleaseDetailsBody = ({ releaseId }) => {
622
949
  const { formatMessage } = reactIntl.useIntl();
623
- const { releaseId } = reactRouterDom.useParams();
624
- const [{ query }, setQuery] = helperPlugin.useQueryParams();
625
- const toggleNotification = helperPlugin.useNotification();
626
- const { formatAPIError } = helperPlugin.useAPIErrorHandler();
950
+ const [{ query }, setQuery] = strapiAdmin.useQueryParams();
951
+ const { toggleNotification } = strapiAdmin.useNotification();
952
+ const { formatAPIError } = strapiAdmin.useAPIErrorHandler();
627
953
  const {
628
954
  data: releaseData,
629
955
  isLoading: isReleaseLoading,
630
- isError: isReleaseError,
631
956
  error: releaseError
632
957
  } = index.useGetReleaseQuery({ id: releaseId });
633
958
  const {
634
959
  allowedActions: { canUpdate }
635
- } = helperPlugin.useRBAC(index.PERMISSIONS);
960
+ } = strapiAdmin.useRBAC(index.PERMISSIONS);
961
+ const runHookWaterfall = strapiAdmin.useStrapiApp("ReleaseDetailsPage", (state) => state.runHookWaterfall);
962
+ const { hasI18nEnabled } = runHookWaterfall(
963
+ "ContentReleases/pages/ReleaseDetails/add-locale-in-releases",
964
+ {
965
+ displayedHeaders: {
966
+ label: formatMessage({
967
+ id: "content-releases.page.ReleaseDetails.table.header.label.locale",
968
+ defaultMessage: "locale"
969
+ }),
970
+ name: "locale"
971
+ },
972
+ hasI18nEnabled: false
973
+ }
974
+ );
636
975
  const release = releaseData?.data;
637
976
  const selectedGroupBy = query?.groupBy || "contentType";
638
977
  const {
@@ -661,65 +1000,59 @@ const ReleaseDetailsBody = () => {
661
1000
  // We are passing the action path to found the position in the cache of the action for optimistic updates
662
1001
  });
663
1002
  if ("error" in response) {
664
- if (index.isAxiosError(response.error)) {
1003
+ if (strapiAdmin.isFetchError(response.error)) {
665
1004
  toggleNotification({
666
- type: "warning",
1005
+ type: "danger",
667
1006
  message: formatAPIError(response.error)
668
1007
  });
669
1008
  } else {
670
1009
  toggleNotification({
671
- type: "warning",
1010
+ type: "danger",
672
1011
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
673
1012
  });
674
1013
  }
675
1014
  }
676
1015
  };
677
1016
  if (isLoading || isReleaseLoading) {
678
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.ContentLayout, { children: /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.LoadingIndicatorPage, {}) });
1017
+ return /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Page.Loading, {});
679
1018
  }
680
1019
  const releaseActions = data?.data;
681
1020
  const releaseMeta = data?.meta;
682
1021
  const contentTypes = releaseMeta?.contentTypes || {};
683
1022
  const components = releaseMeta?.components || {};
684
- if (isReleaseError || !release) {
1023
+ if (isBaseQueryError(releaseError) || !release) {
685
1024
  const errorsArray = [];
686
- if (releaseError) {
1025
+ if (releaseError && "code" in releaseError) {
687
1026
  errorsArray.push({
688
1027
  code: releaseError.code
689
1028
  });
690
1029
  }
691
- if (releaseActionsError) {
1030
+ if (releaseActionsError && "code" in releaseActionsError) {
692
1031
  errorsArray.push({
693
1032
  code: releaseActionsError.code
694
1033
  });
695
1034
  }
696
1035
  return /* @__PURE__ */ jsxRuntime.jsx(
697
- reactRouterDom.Redirect,
1036
+ reactRouterDom.Navigate,
698
1037
  {
699
- to: {
700
- pathname: "/plugins/content-releases",
701
- state: {
702
- errors: errorsArray
703
- }
1038
+ to: "..",
1039
+ state: {
1040
+ errors: errorsArray
704
1041
  }
705
1042
  }
706
1043
  );
707
1044
  }
708
1045
  if (isError || !releaseActions) {
709
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.ContentLayout, { children: /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.AnErrorOccurred, {}) });
1046
+ return /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Page.Error, {});
710
1047
  }
711
1048
  if (Object.keys(releaseActions).length === 0) {
712
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.ContentLayout, { children: /* @__PURE__ */ jsxRuntime.jsx(
713
- helperPlugin.NoContent,
1049
+ return /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Layouts.Content, { children: /* @__PURE__ */ jsxRuntime.jsx(
1050
+ designSystem.EmptyStateLayout,
714
1051
  {
715
- content: {
716
- id: "content-releases.pages.Details.tab.emptyEntries",
717
- defaultMessage: "This release is empty. Open the Content Manager, select an entry and add it to the release."
718
- },
719
1052
  action: /* @__PURE__ */ jsxRuntime.jsx(
720
- v2.LinkButton,
1053
+ designSystem.LinkButton,
721
1054
  {
722
- as: reactRouterDom.Link,
1055
+ tag: reactRouterDom.Link,
723
1056
  to: {
724
1057
  pathname: "/content-manager"
725
1058
  },
@@ -730,18 +1063,59 @@ const ReleaseDetailsBody = () => {
730
1063
  defaultMessage: "Open the Content Manager"
731
1064
  })
732
1065
  }
733
- )
1066
+ ),
1067
+ icon: /* @__PURE__ */ jsxRuntime.jsx(symbols.EmptyDocuments, { width: "16rem" }),
1068
+ content: formatMessage({
1069
+ id: "content-releases.pages.Details.tab.emptyEntries",
1070
+ defaultMessage: "This release is empty. Open the Content Manager, select an entry and add it to the release."
1071
+ })
734
1072
  }
735
1073
  ) });
736
1074
  }
737
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.ContentLayout, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 8, direction: "column", alignItems: "stretch", children: [
1075
+ const groupByLabel = formatMessage({
1076
+ id: "content-releases.pages.ReleaseDetails.groupBy.aria-label",
1077
+ defaultMessage: "Group by"
1078
+ });
1079
+ const headers = [
1080
+ // ...displayedHeaders,
1081
+ {
1082
+ label: formatMessage({
1083
+ id: "content-releases.page.ReleaseDetails.table.header.label.name",
1084
+ defaultMessage: "name"
1085
+ }),
1086
+ name: "name"
1087
+ },
1088
+ {
1089
+ label: formatMessage({
1090
+ id: "content-releases.page.ReleaseDetails.table.header.label.content-type",
1091
+ defaultMessage: "content-type"
1092
+ }),
1093
+ name: "content-type"
1094
+ },
1095
+ {
1096
+ label: formatMessage({
1097
+ id: "content-releases.page.ReleaseDetails.table.header.label.action",
1098
+ defaultMessage: "action"
1099
+ }),
1100
+ name: "action"
1101
+ },
1102
+ ...!release.releasedAt ? [
1103
+ {
1104
+ label: formatMessage({
1105
+ id: "content-releases.page.ReleaseDetails.table.header.label.status",
1106
+ defaultMessage: "status"
1107
+ }),
1108
+ name: "status"
1109
+ }
1110
+ ] : []
1111
+ ];
1112
+ const options = hasI18nEnabled ? GROUP_BY_OPTIONS : GROUP_BY_OPTIONS_NO_LOCALE;
1113
+ return /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Layouts.Content, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 8, direction: "column", alignItems: "stretch", children: [
738
1114
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { children: /* @__PURE__ */ jsxRuntime.jsx(
739
1115
  designSystem.SingleSelect,
740
1116
  {
741
- "aria-label": formatMessage({
742
- id: "content-releases.pages.ReleaseDetails.groupBy.aria-label",
743
- defaultMessage: "Group by"
744
- }),
1117
+ placeholder: groupByLabel,
1118
+ "aria-label": groupByLabel,
745
1119
  customizeContent: (value) => formatMessage(
746
1120
  {
747
1121
  id: `content-releases.pages.ReleaseDetails.groupBy.label`,
@@ -753,84 +1127,27 @@ const ReleaseDetailsBody = () => {
753
1127
  ),
754
1128
  value: formatMessage(getGroupByOptionLabel(selectedGroupBy)),
755
1129
  onChange: (value) => setQuery({ groupBy: value }),
756
- children: GROUP_BY_OPTIONS.map((option) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: option, children: formatMessage(getGroupByOptionLabel(option)) }, option))
1130
+ children: options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: option, children: formatMessage(getGroupByOptionLabel(option)) }, option))
757
1131
  }
758
1132
  ) }),
759
1133
  Object.keys(releaseActions).map((key) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 4, direction: "column", alignItems: "stretch", children: [
760
1134
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { role: "separator", "aria-label": key, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { children: key }) }),
761
1135
  /* @__PURE__ */ jsxRuntime.jsx(
762
- helperPlugin.Table.Root,
1136
+ strapiAdmin.Table.Root,
763
1137
  {
764
1138
  rows: releaseActions[key].map((item) => ({
765
1139
  ...item,
766
1140
  id: Number(item.entry.id)
767
1141
  })),
768
- colCount: releaseActions[key].length,
769
- isLoading,
770
- isFetching,
771
- children: /* @__PURE__ */ jsxRuntime.jsxs(helperPlugin.Table.Content, { children: [
772
- /* @__PURE__ */ jsxRuntime.jsxs(helperPlugin.Table.Head, { children: [
773
- /* @__PURE__ */ jsxRuntime.jsx(
774
- helperPlugin.Table.HeaderCell,
775
- {
776
- fieldSchemaType: "string",
777
- label: formatMessage({
778
- id: "content-releases.page.ReleaseDetails.table.header.label.name",
779
- defaultMessage: "name"
780
- }),
781
- name: "name"
782
- }
783
- ),
784
- /* @__PURE__ */ jsxRuntime.jsx(
785
- helperPlugin.Table.HeaderCell,
786
- {
787
- fieldSchemaType: "string",
788
- label: formatMessage({
789
- id: "content-releases.page.ReleaseDetails.table.header.label.locale",
790
- defaultMessage: "locale"
791
- }),
792
- name: "locale"
793
- }
794
- ),
795
- /* @__PURE__ */ jsxRuntime.jsx(
796
- helperPlugin.Table.HeaderCell,
797
- {
798
- fieldSchemaType: "string",
799
- label: formatMessage({
800
- id: "content-releases.page.ReleaseDetails.table.header.label.content-type",
801
- defaultMessage: "content-type"
802
- }),
803
- name: "content-type"
804
- }
805
- ),
806
- /* @__PURE__ */ jsxRuntime.jsx(
807
- helperPlugin.Table.HeaderCell,
808
- {
809
- fieldSchemaType: "string",
810
- label: formatMessage({
811
- id: "content-releases.page.ReleaseDetails.table.header.label.action",
812
- defaultMessage: "action"
813
- }),
814
- name: "action"
815
- }
816
- ),
817
- !release.releasedAt && /* @__PURE__ */ jsxRuntime.jsx(
818
- helperPlugin.Table.HeaderCell,
819
- {
820
- fieldSchemaType: "string",
821
- label: formatMessage({
822
- id: "content-releases.page.ReleaseDetails.table.header.label.status",
823
- defaultMessage: "status"
824
- }),
825
- name: "status"
826
- }
827
- )
828
- ] }),
829
- /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.Table.LoadingBody, {}),
830
- /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.Table.Body, { children: releaseActions[key].map(
1142
+ headers,
1143
+ isLoading: isLoading || isFetching,
1144
+ children: /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Content, { children: [
1145
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Head, { children: headers.map((header) => /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.HeaderCell, { ...header }, header.name)) }),
1146
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Loading, {}),
1147
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Body, { children: releaseActions[key].map(
831
1148
  ({ id, contentType, locale, type, entry }, actionIndex) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
832
1149
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { width: "25%", maxWidth: "200px", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { ellipsis: true, children: `${contentType.mainFieldValue || entry.id}` }) }),
833
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { width: "10%", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: `${locale?.name ? locale.name : "-"}` }) }),
1150
+ hasI18nEnabled && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { width: "10%", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: `${locale?.name ? locale.name : "-"}` }) }),
834
1151
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { width: "10%", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: contentType.displayName || "" }) }),
835
1152
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { width: "20%", children: release.releasedAt ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage(
836
1153
  {
@@ -884,34 +1201,39 @@ const ReleaseDetailsBody = () => {
884
1201
  }
885
1202
  )
886
1203
  ] }, `releases-group-${key}`)),
887
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { paddingTop: 4, alignItems: "flex-end", justifyContent: "space-between", children: [
888
- /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.PageSizeURLQuery, { defaultValue: releaseMeta?.pagination?.pageSize.toString() }),
889
- /* @__PURE__ */ jsxRuntime.jsx(
890
- helperPlugin.PaginationURLQuery,
891
- {
892
- pagination: {
893
- pageCount: releaseMeta?.pagination?.pageCount || 0
894
- }
895
- }
896
- )
897
- ] })
1204
+ /* @__PURE__ */ jsxRuntime.jsxs(
1205
+ strapiAdmin.Pagination.Root,
1206
+ {
1207
+ ...releaseMeta?.pagination,
1208
+ defaultPageSize: releaseMeta?.pagination?.pageSize,
1209
+ children: [
1210
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Pagination.PageSize, {}),
1211
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Pagination.Links, {})
1212
+ ]
1213
+ }
1214
+ )
898
1215
  ] }) });
899
1216
  };
900
1217
  const ReleaseDetailsPage = () => {
901
1218
  const { formatMessage } = reactIntl.useIntl();
902
1219
  const { releaseId } = reactRouterDom.useParams();
903
- const toggleNotification = helperPlugin.useNotification();
904
- const { formatAPIError } = helperPlugin.useAPIErrorHandler();
905
- const { push } = reactRouterDom.useHistory();
1220
+ const { toggleNotification } = strapiAdmin.useNotification();
1221
+ const { formatAPIError } = strapiAdmin.useAPIErrorHandler();
1222
+ const navigate = reactRouterDom.useNavigate();
906
1223
  const [releaseModalShown, setReleaseModalShown] = React__namespace.useState(false);
907
1224
  const [showWarningSubmit, setWarningSubmit] = React__namespace.useState(false);
908
1225
  const {
909
1226
  isLoading: isLoadingDetails,
910
1227
  data,
911
1228
  isSuccess: isSuccessDetails
912
- } = index.useGetReleaseQuery({ id: releaseId });
1229
+ } = index.useGetReleaseQuery(
1230
+ { id: releaseId },
1231
+ {
1232
+ skip: !releaseId
1233
+ }
1234
+ );
913
1235
  const [updateRelease, { isLoading: isSubmittingForm }] = index.useUpdateReleaseMutation();
914
- const [deleteRelease, { isLoading: isDeletingRelease }] = index.useDeleteReleaseMutation();
1236
+ const [deleteRelease] = index.useDeleteReleaseMutation();
915
1237
  const toggleEditReleaseModal = () => {
916
1238
  setReleaseModalShown((prev) => !prev);
917
1239
  };
@@ -922,15 +1244,18 @@ const ReleaseDetailsPage = () => {
922
1244
  {
923
1245
  toggleEditReleaseModal,
924
1246
  toggleWarningSubmit,
925
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.ContentLayout, { children: /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.LoadingIndicatorPage, {}) })
1247
+ children: /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Page.Loading, {})
926
1248
  }
927
1249
  );
928
1250
  }
1251
+ if (!releaseId) {
1252
+ return /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Navigate, { to: ".." });
1253
+ }
929
1254
  const releaseData = isSuccessDetails && data?.data || null;
930
1255
  const title = releaseData?.name || "";
931
1256
  const timezone = releaseData?.timezone ?? null;
932
1257
  const scheduledAt = releaseData?.scheduledAt && timezone ? dateFnsTz.utcToZonedTime(releaseData.scheduledAt, timezone) : null;
933
- const date = scheduledAt ? new Date(format__default.default(scheduledAt, "yyyy-MM-dd")) : null;
1258
+ const date = scheduledAt ? format__default.default(scheduledAt, "yyyy-MM-dd") : void 0;
934
1259
  const time = scheduledAt ? format__default.default(scheduledAt, "HH:mm") : "";
935
1260
  const handleEditRelease = async (values) => {
936
1261
  const response = await updateRelease({
@@ -947,33 +1272,33 @@ const ReleaseDetailsPage = () => {
947
1272
  defaultMessage: "Release updated."
948
1273
  })
949
1274
  });
950
- } else if (index.isAxiosError(response.error)) {
1275
+ toggleEditReleaseModal();
1276
+ } else if (strapiAdmin.isFetchError(response.error)) {
951
1277
  toggleNotification({
952
- type: "warning",
1278
+ type: "danger",
953
1279
  message: formatAPIError(response.error)
954
1280
  });
955
1281
  } else {
956
1282
  toggleNotification({
957
- type: "warning",
1283
+ type: "danger",
958
1284
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
959
1285
  });
960
1286
  }
961
- toggleEditReleaseModal();
962
1287
  };
963
1288
  const handleDeleteRelease = async () => {
964
1289
  const response = await deleteRelease({
965
1290
  id: releaseId
966
1291
  });
967
1292
  if ("data" in response) {
968
- push("/plugins/content-releases");
969
- } else if (index.isAxiosError(response.error)) {
1293
+ navigate("..");
1294
+ } else if (strapiAdmin.isFetchError(response.error)) {
970
1295
  toggleNotification({
971
- type: "warning",
1296
+ type: "danger",
972
1297
  message: formatAPIError(response.error)
973
1298
  });
974
1299
  } else {
975
1300
  toggleNotification({
976
- type: "warning",
1301
+ type: "danger",
977
1302
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
978
1303
  });
979
1304
  }
@@ -984,10 +1309,11 @@ const ReleaseDetailsPage = () => {
984
1309
  toggleEditReleaseModal,
985
1310
  toggleWarningSubmit,
986
1311
  children: [
987
- /* @__PURE__ */ jsxRuntime.jsx(ReleaseDetailsBody, {}),
988
- releaseModalShown && /* @__PURE__ */ jsxRuntime.jsx(
1312
+ /* @__PURE__ */ jsxRuntime.jsx(ReleaseDetailsBody, { releaseId }),
1313
+ /* @__PURE__ */ jsxRuntime.jsx(
989
1314
  ReleaseModal,
990
1315
  {
1316
+ open: releaseModalShown,
991
1317
  handleClose: toggleEditReleaseModal,
992
1318
  handleSubmit: handleEditRelease,
993
1319
  isLoading: isLoadingDetails || isSubmittingForm,
@@ -1001,315 +1327,19 @@ const ReleaseDetailsPage = () => {
1001
1327
  }
1002
1328
  }
1003
1329
  ),
1004
- /* @__PURE__ */ jsxRuntime.jsx(
1005
- helperPlugin.ConfirmDialog,
1006
- {
1007
- bodyText: {
1008
- id: "content-releases.dialog.confirmation-message",
1009
- defaultMessage: "Are you sure you want to delete this release?"
1010
- },
1011
- isOpen: showWarningSubmit,
1012
- isConfirmButtonLoading: isDeletingRelease,
1013
- onToggleDialog: toggleWarningSubmit,
1014
- onConfirm: handleDeleteRelease
1015
- }
1016
- )
1330
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: showWarningSubmit, onOpenChange: toggleWarningSubmit, children: /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.ConfirmDialog, { onConfirm: handleDeleteRelease, children: formatMessage({
1331
+ id: "content-releases.dialog.confirmation-message",
1332
+ defaultMessage: "Are you sure you want to delete this release?"
1333
+ }) }) })
1017
1334
  ]
1018
1335
  }
1019
1336
  );
1020
1337
  };
1021
- const LinkCard = styled__default.default(v2.Link)`
1022
- display: block;
1023
- `;
1024
- const ReleasesGrid = ({ sectionTitle, releases = [], isError = false }) => {
1025
- const { formatMessage } = reactIntl.useIntl();
1026
- const IsSchedulingEnabled = window.strapi.future.isEnabled("contentReleasesScheduling");
1027
- if (isError) {
1028
- return /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.AnErrorOccurred, {});
1029
- }
1030
- if (releases?.length === 0) {
1031
- return /* @__PURE__ */ jsxRuntime.jsx(
1032
- designSystem.EmptyStateLayout,
1033
- {
1034
- content: formatMessage(
1035
- {
1036
- id: "content-releases.page.Releases.tab.emptyEntries",
1037
- defaultMessage: "No releases"
1038
- },
1039
- {
1040
- target: sectionTitle
1041
- }
1042
- ),
1043
- icon: /* @__PURE__ */ jsxRuntime.jsx(icons.EmptyDocuments, { width: "10rem" })
1044
- }
1045
- );
1046
- }
1047
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid, { gap: 4, children: releases.map(({ id, name, actions, scheduledAt }) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.GridItem, { col: 3, s: 6, xs: 12, children: /* @__PURE__ */ jsxRuntime.jsx(LinkCard, { href: `content-releases/${id}`, isExternal: false, children: /* @__PURE__ */ jsxRuntime.jsxs(
1048
- designSystem.Flex,
1049
- {
1050
- direction: "column",
1051
- justifyContent: "space-between",
1052
- padding: 4,
1053
- hasRadius: true,
1054
- background: "neutral0",
1055
- shadow: "tableShadow",
1056
- height: "100%",
1057
- width: "100%",
1058
- alignItems: "start",
1059
- gap: 2,
1060
- children: [
1061
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { as: "h3", variant: "delta", fontWeight: "bold", children: name }),
1062
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: IsSchedulingEnabled ? scheduledAt ? /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.RelativeTime, { timestamp: new Date(scheduledAt) }) : formatMessage({
1063
- id: "content-releases.pages.Releases.not-scheduled",
1064
- defaultMessage: "Not scheduled"
1065
- }) : formatMessage(
1066
- {
1067
- id: "content-releases.page.Releases.release-item.entries",
1068
- defaultMessage: "{number, plural, =0 {No entries} one {# entry} other {# entries}}"
1069
- },
1070
- { number: actions.meta.count }
1071
- ) })
1072
- ]
1073
- }
1074
- ) }) }, id)) });
1075
- };
1076
- const StyledAlert = styled__default.default(designSystem.Alert)`
1077
- button {
1078
- display: none;
1079
- }
1080
- p + div {
1081
- margin-left: auto;
1082
- }
1083
- `;
1084
- const INITIAL_FORM_VALUES = {
1085
- name: "",
1086
- date: null,
1087
- time: "",
1088
- // Remove future flag check after Scheduling Beta release and replace with true as creating new release should include scheduling by default
1089
- isScheduled: window.strapi.future.isEnabled("contentReleasesScheduling"),
1090
- scheduledAt: null,
1091
- timezone: null
1092
- };
1093
- const ReleasesPage = () => {
1094
- const tabRef = React__namespace.useRef(null);
1095
- const location = reactRouterDom.useLocation();
1096
- const [releaseModalShown, setReleaseModalShown] = React__namespace.useState(false);
1097
- const toggleNotification = helperPlugin.useNotification();
1098
- const { formatMessage } = reactIntl.useIntl();
1099
- const { push, replace } = reactRouterDom.useHistory();
1100
- const { formatAPIError } = helperPlugin.useAPIErrorHandler();
1101
- const [{ query }, setQuery] = helperPlugin.useQueryParams();
1102
- const response = index.useGetReleasesQuery(query);
1103
- const [createRelease, { isLoading: isSubmittingForm }] = index.useCreateReleaseMutation();
1104
- const { getFeature } = strapiAdmin.useLicenseLimits();
1105
- const { maximumReleases = 3 } = getFeature("cms-content-releases");
1106
- const { trackUsage } = helperPlugin.useTracking();
1107
- const { isLoading, isSuccess, isError } = response;
1108
- const activeTab = response?.currentData?.meta?.activeTab || "pending";
1109
- const activeTabIndex = ["pending", "done"].indexOf(activeTab);
1110
- React__namespace.useEffect(() => {
1111
- if (location?.state?.errors) {
1112
- toggleNotification({
1113
- type: "warning",
1114
- title: formatMessage({
1115
- id: "content-releases.pages.Releases.notification.error.title",
1116
- defaultMessage: "Your request could not be processed."
1117
- }),
1118
- message: formatMessage({
1119
- id: "content-releases.pages.Releases.notification.error.message",
1120
- defaultMessage: "Please try again or open another release."
1121
- })
1122
- });
1123
- replace({ state: null });
1124
- }
1125
- }, [formatMessage, location?.state?.errors, replace, toggleNotification]);
1126
- React__namespace.useEffect(() => {
1127
- if (tabRef.current) {
1128
- tabRef.current._handlers.setSelectedTabIndex(activeTabIndex);
1129
- }
1130
- }, [activeTabIndex]);
1131
- const toggleAddReleaseModal = () => {
1132
- setReleaseModalShown((prev) => !prev);
1133
- };
1134
- if (isLoading) {
1135
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Main, { "aria-busy": isLoading, children: /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.LoadingIndicatorPage, {}) });
1136
- }
1137
- const totalReleases = isSuccess && response.currentData?.meta?.pagination?.total || 0;
1138
- const hasReachedMaximumPendingReleases = totalReleases >= maximumReleases;
1139
- const handleTabChange = (index2) => {
1140
- setQuery({
1141
- ...query,
1142
- page: 1,
1143
- pageSize: response?.currentData?.meta?.pagination?.pageSize || 16,
1144
- filters: {
1145
- releasedAt: {
1146
- $notNull: index2 === 0 ? false : true
1147
- }
1148
- }
1149
- });
1150
- };
1151
- const handleAddRelease = async ({ name, scheduledAt, timezone }) => {
1152
- const response2 = await createRelease({
1153
- name,
1154
- scheduledAt,
1155
- timezone
1156
- });
1157
- if ("data" in response2) {
1158
- toggleNotification({
1159
- type: "success",
1160
- message: formatMessage({
1161
- id: "content-releases.modal.release-created-notification-success",
1162
- defaultMessage: "Release created."
1163
- })
1164
- });
1165
- trackUsage("didCreateRelease");
1166
- push(`/plugins/content-releases/${response2.data.data.id}`);
1167
- } else if (index.isAxiosError(response2.error)) {
1168
- toggleNotification({
1169
- type: "warning",
1170
- message: formatAPIError(response2.error)
1171
- });
1172
- } else {
1173
- toggleNotification({
1174
- type: "warning",
1175
- message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
1176
- });
1177
- }
1178
- };
1179
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Main, { "aria-busy": isLoading, children: [
1180
- /* @__PURE__ */ jsxRuntime.jsx(
1181
- designSystem.HeaderLayout,
1182
- {
1183
- title: formatMessage({
1184
- id: "content-releases.pages.Releases.title",
1185
- defaultMessage: "Releases"
1186
- }),
1187
- subtitle: formatMessage(
1188
- {
1189
- id: "content-releases.pages.Releases.header-subtitle",
1190
- defaultMessage: "{number, plural, =0 {No releases} one {# release} other {# releases}}"
1191
- },
1192
- { number: totalReleases }
1193
- ),
1194
- primaryAction: /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.CheckPermissions, { permissions: index.PERMISSIONS.create, children: /* @__PURE__ */ jsxRuntime.jsx(
1195
- designSystem.Button,
1196
- {
1197
- startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
1198
- onClick: toggleAddReleaseModal,
1199
- disabled: hasReachedMaximumPendingReleases,
1200
- children: formatMessage({
1201
- id: "content-releases.header.actions.add-release",
1202
- defaultMessage: "New release"
1203
- })
1204
- }
1205
- ) })
1206
- }
1207
- ),
1208
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.ContentLayout, { children: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1209
- activeTab === "pending" && hasReachedMaximumPendingReleases && /* @__PURE__ */ jsxRuntime.jsx(
1210
- StyledAlert,
1211
- {
1212
- marginBottom: 6,
1213
- action: /* @__PURE__ */ jsxRuntime.jsx(v2.Link, { href: "https://strapi.io/pricing-cloud", isExternal: true, children: formatMessage({
1214
- id: "content-releases.pages.Releases.max-limit-reached.action",
1215
- defaultMessage: "Explore plans"
1216
- }) }),
1217
- title: formatMessage(
1218
- {
1219
- id: "content-releases.pages.Releases.max-limit-reached.title",
1220
- defaultMessage: "You have reached the {number} pending {number, plural, one {release} other {releases}} limit."
1221
- },
1222
- { number: maximumReleases }
1223
- ),
1224
- onClose: () => {
1225
- },
1226
- closeLabel: "",
1227
- children: formatMessage({
1228
- id: "content-releases.pages.Releases.max-limit-reached.message",
1229
- defaultMessage: "Upgrade to manage an unlimited number of releases."
1230
- })
1231
- }
1232
- ),
1233
- /* @__PURE__ */ jsxRuntime.jsxs(
1234
- designSystem.TabGroup,
1235
- {
1236
- label: formatMessage({
1237
- id: "content-releases.pages.Releases.tab-group.label",
1238
- defaultMessage: "Releases list"
1239
- }),
1240
- variant: "simple",
1241
- initialSelectedTabIndex: activeTabIndex,
1242
- onTabChange: handleTabChange,
1243
- ref: tabRef,
1244
- children: [
1245
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { paddingBottom: 8, children: [
1246
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tabs, { children: [
1247
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tab, { children: formatMessage({
1248
- id: "content-releases.pages.Releases.tab.pending",
1249
- defaultMessage: "Pending"
1250
- }) }),
1251
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tab, { children: formatMessage({
1252
- id: "content-releases.pages.Releases.tab.done",
1253
- defaultMessage: "Done"
1254
- }) })
1255
- ] }),
1256
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Divider, {})
1257
- ] }),
1258
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.TabPanels, { children: [
1259
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.TabPanel, { children: /* @__PURE__ */ jsxRuntime.jsx(
1260
- ReleasesGrid,
1261
- {
1262
- sectionTitle: "pending",
1263
- releases: response?.currentData?.data,
1264
- isError
1265
- }
1266
- ) }),
1267
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.TabPanel, { children: /* @__PURE__ */ jsxRuntime.jsx(
1268
- ReleasesGrid,
1269
- {
1270
- sectionTitle: "done",
1271
- releases: response?.currentData?.data,
1272
- isError
1273
- }
1274
- ) })
1275
- ] })
1276
- ]
1277
- }
1278
- ),
1279
- totalReleases > 0 && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { paddingTop: 4, alignItems: "flex-end", justifyContent: "space-between", children: [
1280
- /* @__PURE__ */ jsxRuntime.jsx(
1281
- helperPlugin.PageSizeURLQuery,
1282
- {
1283
- options: ["8", "16", "32", "64"],
1284
- defaultValue: response?.currentData?.meta?.pagination?.pageSize.toString()
1285
- }
1286
- ),
1287
- /* @__PURE__ */ jsxRuntime.jsx(
1288
- helperPlugin.PaginationURLQuery,
1289
- {
1290
- pagination: {
1291
- pageCount: response?.currentData?.meta?.pagination?.pageCount || 0
1292
- }
1293
- }
1294
- )
1295
- ] })
1296
- ] }) }),
1297
- releaseModalShown && /* @__PURE__ */ jsxRuntime.jsx(
1298
- ReleaseModal,
1299
- {
1300
- handleClose: toggleAddReleaseModal,
1301
- handleSubmit: handleAddRelease,
1302
- isLoading: isSubmittingForm,
1303
- initialValues: INITIAL_FORM_VALUES
1304
- }
1305
- )
1306
- ] });
1307
- };
1308
1338
  const App = () => {
1309
- return /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.CheckPagePermissions, { permissions: index.PERMISSIONS.main, children: /* @__PURE__ */ jsxRuntime.jsxs(reactRouterDom.Switch, { children: [
1310
- /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { exact: true, path: `/plugins/${index.pluginId}`, component: ReleasesPage }),
1311
- /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { exact: true, path: `/plugins/${index.pluginId}/:releaseId`, component: ReleaseDetailsPage })
1339
+ return /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Page.Protect, { permissions: index.PERMISSIONS.main, children: /* @__PURE__ */ jsxRuntime.jsxs(reactRouterDom.Routes, { children: [
1340
+ /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { index: true, element: /* @__PURE__ */ jsxRuntime.jsx(ReleasesPage, {}) }),
1341
+ /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { path: ":releaseId", element: /* @__PURE__ */ jsxRuntime.jsx(ReleaseDetailsPage, {}) })
1312
1342
  ] }) });
1313
1343
  };
1314
1344
  exports.App = App;
1315
- //# sourceMappingURL=App-OK4Xac-O.js.map
1345
+ //# sourceMappingURL=App-CEwOQkKT.js.map