@strapi/content-releases 0.0.0-experimental.d5b46d578a5c055b8dcc66939e1b5d540976fafb → 0.0.0-experimental.d954d57341a6623992a0d211daaec8e245c3517d

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-OP70yd5M.js → App-CqbuK4M6.js} +440 -433
  2. package/dist/_chunks/App-CqbuK4M6.js.map +1 -0
  3. package/dist/_chunks/{App-x6Tjj3HN.mjs → App-Do-Rnv0A.mjs} +418 -410
  4. package/dist/_chunks/App-Do-Rnv0A.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-bpHsnU0n.mjs → en-B9Ur3VsE.mjs} +2 -1
  10. package/dist/_chunks/en-B9Ur3VsE.mjs.map +1 -0
  11. package/dist/_chunks/{en-3SGjiVyR.js → en-DtFJ5ViE.js} +2 -1
  12. package/dist/_chunks/en-DtFJ5ViE.js.map +1 -0
  13. package/dist/_chunks/{index-1ejXLtzt.mjs → index-D_pgdqQL.mjs} +227 -420
  14. package/dist/_chunks/index-D_pgdqQL.mjs.map +1 -0
  15. package/dist/_chunks/{index-ydocdaZ0.js → index-Tedsw4GC.js} +227 -422
  16. package/dist/_chunks/index-Tedsw4GC.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 +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 +152 -93
  43. package/dist/server/index.js.map +1 -1
  44. package/dist/server/index.mjs +153 -93
  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-OP70yd5M.js.map +0 -1
  104. package/dist/_chunks/App-x6Tjj3HN.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-3SGjiVyR.js.map +0 -1
  108. package/dist/_chunks/en-bpHsnU0n.mjs.map +0 -1
  109. package/dist/_chunks/index-1ejXLtzt.mjs.map +0 -1
  110. package/dist/_chunks/index-ydocdaZ0.js.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, 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-1ejXLtzt.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-D_pgdqQL.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 { Modal, Flex, Field, TextInput, Box, Checkbox, Typography, DatePicker, TimePicker, Button, Combobox, ComboboxOption, Link, Alert, Main, Tabs, Divider, EmptyStateLayout, Grid, Badge, Menu, Dialog, 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(),
@@ -40,6 +68,7 @@ const RELEASE_SCHEMA = yup.object().shape({
40
68
  }).required().noUnknown();
41
69
  const ReleaseModal = ({
42
70
  handleClose,
71
+ open,
43
72
  handleSubmit,
44
73
  initialValues,
45
74
  isLoading = false
@@ -63,8 +92,8 @@ const ReleaseModal = ({
63
92
  );
64
93
  return currentTimezone?.value || systemTimezone.value;
65
94
  };
66
- return /* @__PURE__ */ jsxs(ModalLayout, { onClose: handleClose, labelledBy: "title", children: [
67
- /* @__PURE__ */ jsx(ModalHeader, { children: /* @__PURE__ */ jsx(Typography, { id: "title", fontWeight: "bold", textColor: "neutral800", children: formatMessage(
95
+ return /* @__PURE__ */ jsx(Modal.Root, { open, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Modal.Content, { children: [
96
+ /* @__PURE__ */ jsx(Modal.Header, { children: /* @__PURE__ */ jsx(Modal.Title, { children: formatMessage(
68
97
  {
69
98
  id: "content-releases.modal.title",
70
99
  defaultMessage: "{isCreatingRelease, select, true {New release} other {Edit release}}"
@@ -87,123 +116,119 @@ const ReleaseModal = ({
87
116
  },
88
117
  validationSchema: RELEASE_SCHEMA,
89
118
  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({
119
+ children: ({ values, errors, handleChange, setFieldValue }) => {
120
+ return /* @__PURE__ */ jsxs(Form, { children: [
121
+ /* @__PURE__ */ jsx(Modal.Body, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: [
122
+ /* @__PURE__ */ jsxs(Field.Root, { name: "name", error: errors.name, required: true, children: [
123
+ /* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
96
124
  id: "content-releases.modal.form.input.label.release-name",
97
125
  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({
126
+ }) }),
127
+ /* @__PURE__ */ jsx(TextInput, { value: values.name, onChange: handleChange }),
128
+ /* @__PURE__ */ jsx(Field.Error, {})
129
+ ] }),
130
+ /* @__PURE__ */ jsx(Box, { width: "max-content", children: /* @__PURE__ */ jsx(
131
+ Checkbox,
132
+ {
133
+ name: "isScheduled",
134
+ checked: values.isScheduled,
135
+ onCheckedChange: (checked) => {
136
+ setFieldValue("isScheduled", checked);
137
+ if (!checked) {
138
+ setFieldValue("date", null);
139
+ setFieldValue("time", "");
140
+ setFieldValue("timezone", null);
141
+ } else {
142
+ setFieldValue("date", initialValues.date);
143
+ setFieldValue("time", initialValues.time);
144
+ setFieldValue(
145
+ "timezone",
146
+ initialValues.timezone ?? systemTimezone?.value
147
+ );
148
+ }
149
+ },
150
+ children: /* @__PURE__ */ jsx(
151
+ Typography,
152
+ {
153
+ textColor: values.isScheduled ? "primary600" : "neutral800",
154
+ fontWeight: values.isScheduled ? "semiBold" : "regular",
155
+ children: formatMessage({
156
+ id: "modal.form.input.label.schedule-release",
157
+ defaultMessage: "Schedule release"
158
+ })
159
+ }
160
+ )
161
+ }
162
+ ) }),
163
+ values.isScheduled && /* @__PURE__ */ jsxs(Fragment, { children: [
164
+ /* @__PURE__ */ jsxs(Flex, { gap: 4, alignItems: "start", children: [
165
+ /* @__PURE__ */ jsx(Box, { width: "100%", children: /* @__PURE__ */ jsxs(Field.Root, { name: "date", error: errors.date, required: true, children: [
166
+ /* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
142
167
  id: "content-releases.modal.form.input.label.date",
143
168
  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({
169
+ }) }),
170
+ /* @__PURE__ */ jsx(
171
+ DatePicker,
172
+ {
173
+ onChange: (date) => {
174
+ const isoFormatDate = date ? formatISO(date, { representation: "date" }) : null;
175
+ setFieldValue("date", isoFormatDate);
176
+ },
177
+ clearLabel: formatMessage({
178
+ id: "content-releases.modal.form.input.clearLabel",
179
+ defaultMessage: "Clear"
180
+ }),
181
+ onClear: () => {
182
+ setFieldValue("date", null);
183
+ },
184
+ value: values.date ? new Date(values.date) : /* @__PURE__ */ new Date(),
185
+ minDate: utcToZonedTime(/* @__PURE__ */ new Date(), values.timezone.split("&")[1])
186
+ }
187
+ ),
188
+ /* @__PURE__ */ jsx(Field.Error, {})
189
+ ] }) }),
190
+ /* @__PURE__ */ jsx(Box, { width: "100%", children: /* @__PURE__ */ jsxs(Field.Root, { name: "time", error: errors.time, required: true, children: [
191
+ /* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
167
192
  id: "content-releases.modal.form.input.label.time",
168
193
  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
- }
185
- ) })
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(
194
+ }) }),
195
+ /* @__PURE__ */ jsx(
196
+ TimePicker,
197
+ {
198
+ onChange: (time) => {
199
+ setFieldValue("time", time);
200
+ },
201
+ clearLabel: formatMessage({
202
+ id: "content-releases.modal.form.input.clearLabel",
203
+ defaultMessage: "Clear"
204
+ }),
205
+ onClear: () => {
206
+ setFieldValue("time", "");
207
+ },
208
+ value: values.time || void 0
209
+ }
210
+ ),
211
+ /* @__PURE__ */ jsx(Field.Error, {})
212
+ ] }) })
213
+ ] }),
214
+ /* @__PURE__ */ jsx(TimezoneComponent, { timezoneOptions: timezoneList })
215
+ ] })
216
+ ] }) }),
217
+ /* @__PURE__ */ jsxs(Modal.Footer, { children: [
218
+ /* @__PURE__ */ jsx(Modal.Close, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", name: "cancel", children: formatMessage({ id: "cancel", defaultMessage: "Cancel" }) }) }),
219
+ /* @__PURE__ */ jsx(Button, { name: "submit", loading: isLoading, type: "submit", children: formatMessage(
195
220
  {
196
221
  id: "content-releases.modal.form.button.submit",
197
222
  defaultMessage: "{isCreatingRelease, select, true {Continue} other {Save}}"
198
223
  },
199
224
  { isCreatingRelease }
200
225
  ) })
201
- }
202
- )
203
- ] })
226
+ ] })
227
+ ] });
228
+ }
204
229
  }
205
230
  )
206
- ] });
231
+ ] }) });
207
232
  };
208
233
  const getTimezones = (selectedDate) => {
209
234
  const timezoneList = Intl.supportedValuesOf("timeZone").map((timezone) => {
@@ -229,31 +254,35 @@ const TimezoneComponent = ({ timezoneOptions }) => {
229
254
  }
230
255
  }
231
256
  }, [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
- );
257
+ return /* @__PURE__ */ jsxs(Field.Root, { name: "timezone", error: errors.timezone, required: true, children: [
258
+ /* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
259
+ id: "content-releases.modal.form.input.label.timezone",
260
+ defaultMessage: "Timezone"
261
+ }) }),
262
+ /* @__PURE__ */ jsx(
263
+ Combobox,
264
+ {
265
+ autocomplete: { type: "list", filter: "contains" },
266
+ value: values.timezone || void 0,
267
+ textValue: values.timezone ? values.timezone.replace(/&/, " ") : void 0,
268
+ onChange: (timezone) => {
269
+ setFieldValue("timezone", timezone);
270
+ },
271
+ onTextValueChange: (timezone) => {
272
+ setFieldValue("timezone", timezone);
273
+ },
274
+ onClear: () => {
275
+ setFieldValue("timezone", "");
276
+ },
277
+ children: timezoneList.map((timezone) => /* @__PURE__ */ jsx(ComboboxOption, { value: timezone.value, children: timezone.value.replace(/&/, " ") }, timezone.value))
278
+ }
279
+ ),
280
+ /* @__PURE__ */ jsx(Field.Error, {})
281
+ ] });
282
+ };
283
+ const useTypedDispatch = useDispatch;
284
+ const isBaseQueryError = (error) => {
285
+ return typeof error !== "undefined" && error.name !== void 0;
257
286
  };
258
287
  const LinkCard = styled(Link)`
259
288
  display: block;
@@ -292,7 +321,7 @@ const getBadgeProps = (status) => {
292
321
  const ReleasesGrid = ({ sectionTitle, releases = [], isError = false }) => {
293
322
  const { formatMessage } = useIntl();
294
323
  if (isError) {
295
- return /* @__PURE__ */ jsx(AnErrorOccurred, {});
324
+ return /* @__PURE__ */ jsx(Page.Error, {});
296
325
  }
297
326
  if (releases?.length === 0) {
298
327
  return /* @__PURE__ */ jsx(
@@ -307,11 +336,11 @@ const ReleasesGrid = ({ sectionTitle, releases = [], isError = false }) => {
307
336
  target: sectionTitle
308
337
  }
309
338
  ),
310
- icon: /* @__PURE__ */ jsx(EmptyDocuments, { width: "10rem" })
339
+ icon: /* @__PURE__ */ jsx(EmptyDocuments, { width: "16rem" })
311
340
  }
312
341
  );
313
342
  }
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(
343
+ return /* @__PURE__ */ jsx(Grid.Root, { gap: 4, children: releases.map(({ id, name, scheduledAt, status }) => /* @__PURE__ */ jsx(Grid.Item, { col: 3, s: 6, xs: 12, children: /* @__PURE__ */ jsx(LinkCard, { tag: NavLink, to: `${id}`, isExternal: false, children: /* @__PURE__ */ jsxs(
315
344
  Flex,
316
345
  {
317
346
  direction: "column",
@@ -326,7 +355,7 @@ const ReleasesGrid = ({ sectionTitle, releases = [], isError = false }) => {
326
355
  gap: 4,
327
356
  children: [
328
357
  /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "start", gap: 1, children: [
329
- /* @__PURE__ */ jsx(Typography, { as: "h3", variant: "delta", fontWeight: "bold", children: name }),
358
+ /* @__PURE__ */ jsx(Typography, { textColor: "neutral800", tag: "h3", variant: "delta", fontWeight: "bold", children: name }),
330
359
  /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: scheduledAt ? /* @__PURE__ */ jsx(RelativeTime, { timestamp: new Date(scheduledAt) }) : formatMessage({
331
360
  id: "content-releases.pages.Releases.not-scheduled",
332
361
  defaultMessage: "Not scheduled"
@@ -347,19 +376,18 @@ const StyledAlert = styled(Alert)`
347
376
  `;
348
377
  const INITIAL_FORM_VALUES = {
349
378
  name: "",
350
- date: null,
379
+ date: void 0,
351
380
  time: "",
352
381
  isScheduled: true,
353
382
  scheduledAt: null,
354
383
  timezone: null
355
384
  };
356
385
  const ReleasesPage = () => {
357
- const tabRef = React.useRef(null);
358
386
  const location = useLocation();
359
387
  const [releaseModalShown, setReleaseModalShown] = React.useState(false);
360
- const toggleNotification = useNotification();
388
+ const { toggleNotification } = useNotification();
361
389
  const { formatMessage } = useIntl();
362
- const { push, replace } = useHistory();
390
+ const navigate = useNavigate();
363
391
  const { formatAPIError } = useAPIErrorHandler();
364
392
  const [{ query }, setQuery] = useQueryParams();
365
393
  const response = useGetReleasesQuery(query);
@@ -367,13 +395,15 @@ const ReleasesPage = () => {
367
395
  const { getFeature } = useLicenseLimits();
368
396
  const { maximumReleases = 3 } = getFeature("cms-content-releases");
369
397
  const { trackUsage } = useTracking();
398
+ const {
399
+ allowedActions: { canCreate }
400
+ } = useRBAC(PERMISSIONS);
370
401
  const { isLoading, isSuccess, isError } = response;
371
402
  const activeTab = response?.currentData?.meta?.activeTab || "pending";
372
- const activeTabIndex = ["pending", "done"].indexOf(activeTab);
373
403
  React.useEffect(() => {
374
404
  if (location?.state?.errors) {
375
405
  toggleNotification({
376
- type: "warning",
406
+ type: "danger",
377
407
  title: formatMessage({
378
408
  id: "content-releases.pages.Releases.notification.error.title",
379
409
  defaultMessage: "Your request could not be processed."
@@ -383,30 +413,25 @@ const ReleasesPage = () => {
383
413
  defaultMessage: "Please try again or open another release."
384
414
  })
385
415
  });
386
- replace({ state: null });
387
- }
388
- }, [formatMessage, location?.state?.errors, replace, toggleNotification]);
389
- React.useEffect(() => {
390
- if (tabRef.current) {
391
- tabRef.current._handlers.setSelectedTabIndex(activeTabIndex);
416
+ navigate("", { replace: true, state: null });
392
417
  }
393
- }, [activeTabIndex]);
418
+ }, [formatMessage, location?.state?.errors, navigate, toggleNotification]);
394
419
  const toggleAddReleaseModal = () => {
395
420
  setReleaseModalShown((prev) => !prev);
396
421
  };
397
422
  if (isLoading) {
398
- return /* @__PURE__ */ jsx(Main, { "aria-busy": isLoading, children: /* @__PURE__ */ jsx(LoadingIndicatorPage, {}) });
423
+ return /* @__PURE__ */ jsx(Page.Loading, {});
399
424
  }
400
425
  const totalPendingReleases = isSuccess && response.currentData?.meta?.pendingReleasesCount || 0;
401
426
  const hasReachedMaximumPendingReleases = totalPendingReleases >= maximumReleases;
402
- const handleTabChange = (index) => {
427
+ const handleTabChange = (tabValue) => {
403
428
  setQuery({
404
429
  ...query,
405
430
  page: 1,
406
431
  pageSize: response?.currentData?.meta?.pagination?.pageSize || 16,
407
432
  filters: {
408
433
  releasedAt: {
409
- $notNull: index === 0 ? false : true
434
+ $notNull: tabValue === "pending"
410
435
  }
411
436
  }
412
437
  });
@@ -426,22 +451,22 @@ const ReleasesPage = () => {
426
451
  })
427
452
  });
428
453
  trackUsage("didCreateRelease");
429
- push(`/plugins/content-releases/${response2.data.data.id}`);
430
- } else if (isAxiosError(response2.error)) {
454
+ navigate(response2.data.data.id.toString());
455
+ } else if (isFetchError(response2.error)) {
431
456
  toggleNotification({
432
- type: "warning",
457
+ type: "danger",
433
458
  message: formatAPIError(response2.error)
434
459
  });
435
460
  } else {
436
461
  toggleNotification({
437
- type: "warning",
462
+ type: "danger",
438
463
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
439
464
  });
440
465
  }
441
466
  };
442
467
  return /* @__PURE__ */ jsxs(Main, { "aria-busy": isLoading, children: [
443
468
  /* @__PURE__ */ jsx(
444
- HeaderLayout,
469
+ Layouts.Header,
445
470
  {
446
471
  title: formatMessage({
447
472
  id: "content-releases.pages.Releases.title",
@@ -451,7 +476,7 @@ const ReleasesPage = () => {
451
476
  id: "content-releases.pages.Releases.header-subtitle",
452
477
  defaultMessage: "Create and manage content updates"
453
478
  }),
454
- primaryAction: /* @__PURE__ */ jsx(CheckPermissions, { permissions: PERMISSIONS.create, children: /* @__PURE__ */ jsx(
479
+ primaryAction: canCreate ? /* @__PURE__ */ jsx(
455
480
  Button,
456
481
  {
457
482
  startIcon: /* @__PURE__ */ jsx(Plus, {}),
@@ -462,10 +487,10 @@ const ReleasesPage = () => {
462
487
  defaultMessage: "New release"
463
488
  })
464
489
  }
465
- ) })
490
+ ) : null
466
491
  }
467
492
  ),
468
- /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsxs(Fragment, { children: [
493
+ /* @__PURE__ */ jsx(Layouts.Content, { children: /* @__PURE__ */ jsxs(Fragment, { children: [
469
494
  hasReachedMaximumPendingReleases && /* @__PURE__ */ jsx(
470
495
  StyledAlert,
471
496
  {
@@ -490,21 +515,17 @@ const ReleasesPage = () => {
490
515
  })
491
516
  }
492
517
  ),
493
- /* @__PURE__ */ jsxs(
494
- TabGroup,
495
- {
496
- label: formatMessage({
497
- id: "content-releases.pages.Releases.tab-group.label",
498
- defaultMessage: "Releases list"
499
- }),
500
- variant: "simple",
501
- initialSelectedTabIndex: activeTabIndex,
502
- onTabChange: handleTabChange,
503
- ref: tabRef,
504
- children: [
505
- /* @__PURE__ */ jsxs(Box, { paddingBottom: 8, children: [
506
- /* @__PURE__ */ jsxs(Tabs, { children: [
507
- /* @__PURE__ */ jsx(Tab, { children: formatMessage(
518
+ /* @__PURE__ */ jsxs(Tabs.Root, { variant: "simple", onValueChange: handleTabChange, value: activeTab, children: [
519
+ /* @__PURE__ */ jsxs(Box, { paddingBottom: 8, children: [
520
+ /* @__PURE__ */ jsxs(
521
+ Tabs.List,
522
+ {
523
+ "aria-label": formatMessage({
524
+ id: "content-releases.pages.Releases.tab-group.label",
525
+ defaultMessage: "Releases list"
526
+ }),
527
+ children: [
528
+ /* @__PURE__ */ jsx(Tabs.Trigger, { value: "pending", children: formatMessage(
508
529
  {
509
530
  id: "content-releases.pages.Releases.tab.pending",
510
531
  defaultMessage: "Pending ({count})"
@@ -513,55 +534,48 @@ const ReleasesPage = () => {
513
534
  count: totalPendingReleases
514
535
  }
515
536
  ) }),
516
- /* @__PURE__ */ jsx(Tab, { children: formatMessage({
537
+ /* @__PURE__ */ jsx(Tabs.Trigger, { value: "done", children: formatMessage({
517
538
  id: "content-releases.pages.Releases.tab.done",
518
539
  defaultMessage: "Done"
519
540
  }) })
520
- ] }),
521
- /* @__PURE__ */ jsx(Divider, {})
522
- ] }),
523
- /* @__PURE__ */ jsxs(TabPanels, { children: [
524
- /* @__PURE__ */ jsx(TabPanel, { children: /* @__PURE__ */ jsx(
525
- ReleasesGrid,
526
- {
527
- sectionTitle: "pending",
528
- releases: response?.currentData?.data,
529
- isError
530
- }
531
- ) }),
532
- /* @__PURE__ */ jsx(TabPanel, { children: /* @__PURE__ */ jsx(
533
- ReleasesGrid,
534
- {
535
- sectionTitle: "done",
536
- releases: response?.currentData?.data,
537
- isError
538
- }
539
- ) })
540
- ] })
541
- ]
542
- }
543
- ),
544
- response.currentData?.meta?.pagination?.total ? /* @__PURE__ */ jsxs(Flex, { paddingTop: 4, alignItems: "flex-end", justifyContent: "space-between", children: [
545
- /* @__PURE__ */ jsx(
546
- PageSizeURLQuery,
541
+ ]
542
+ }
543
+ ),
544
+ /* @__PURE__ */ jsx(Divider, {})
545
+ ] }),
546
+ /* @__PURE__ */ jsx(Tabs.Content, { value: "pending", children: /* @__PURE__ */ jsx(
547
+ ReleasesGrid,
547
548
  {
548
- options: ["8", "16", "32", "64"],
549
- defaultValue: response?.currentData?.meta?.pagination?.pageSize.toString()
549
+ sectionTitle: "pending",
550
+ releases: response?.currentData?.data,
551
+ isError
550
552
  }
551
- ),
552
- /* @__PURE__ */ jsx(
553
- PaginationURLQuery,
553
+ ) }),
554
+ /* @__PURE__ */ jsx(Tabs.Content, { value: "done", children: /* @__PURE__ */ jsx(
555
+ ReleasesGrid,
554
556
  {
555
- pagination: {
556
- pageCount: response?.currentData?.meta?.pagination?.pageCount || 0
557
- }
557
+ sectionTitle: "done",
558
+ releases: response?.currentData?.data,
559
+ isError
558
560
  }
559
- )
560
- ] }) : null
561
+ ) })
562
+ ] }),
563
+ /* @__PURE__ */ jsxs(
564
+ Pagination.Root,
565
+ {
566
+ ...response?.currentData?.meta?.pagination,
567
+ defaultPageSize: response?.currentData?.meta?.pagination?.pageSize,
568
+ children: [
569
+ /* @__PURE__ */ jsx(Pagination.PageSize, { options: ["8", "16", "32", "64"] }),
570
+ /* @__PURE__ */ jsx(Pagination.Links, {})
571
+ ]
572
+ }
573
+ )
561
574
  ] }) }),
562
- releaseModalShown && /* @__PURE__ */ jsx(
575
+ /* @__PURE__ */ jsx(
563
576
  ReleaseModal,
564
577
  {
578
+ open: releaseModalShown,
565
579
  handleClose: toggleAddReleaseModal,
566
580
  handleSubmit: handleAddRelease,
567
581
  isLoading: isSubmittingForm,
@@ -585,7 +599,7 @@ const StyledMenuItem = styled(Menu.Item)`
585
599
  }
586
600
 
587
601
  &:hover {
588
- background: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}100`]};
602
+ background: ${({ theme, $variant = "neutral" }) => theme.colors[`${$variant}100`]};
589
603
  }
590
604
  `;
591
605
  const PencilIcon = styled(Pencil)`
@@ -605,29 +619,34 @@ const TrashIcon = styled(Trash)`
605
619
  const TypographyMaxWidth = styled(Typography)`
606
620
  max-width: 300px;
607
621
  `;
608
- const EntryValidationText = ({ action, schema, components, entry }) => {
622
+ const EntryValidationText = ({ action, schema, entry }) => {
609
623
  const { formatMessage } = useIntl();
610
- const { validate } = unstable_useDocument();
611
- const { errors } = validate(entry, {
612
- contentType: schema,
613
- components,
614
- isCreatingEntry: false
615
- });
624
+ const { validate } = unstable_useDocument(
625
+ {
626
+ collectionType: schema?.kind ?? "",
627
+ model: schema?.uid ?? ""
628
+ },
629
+ {
630
+ skip: !schema
631
+ }
632
+ );
633
+ const errors = validate(entry) ?? {};
616
634
  if (Object.keys(errors).length > 0) {
617
635
  const validationErrorsMessages = Object.entries(errors).map(
618
636
  ([key, value]) => formatMessage(
637
+ // @ts-expect-error – TODO: fix this will better checks
619
638
  { id: `${value.id}.withField`, defaultMessage: value.defaultMessage },
620
639
  { field: key }
621
640
  )
622
641
  ).join(" ");
623
642
  return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
624
- /* @__PURE__ */ jsx(Icon, { color: "danger600", as: CrossCircle }),
643
+ /* @__PURE__ */ jsx(CrossCircle, { fill: "danger600" }),
625
644
  /* @__PURE__ */ jsx(Tooltip, { description: validationErrorsMessages, children: /* @__PURE__ */ jsx(TypographyMaxWidth, { textColor: "danger600", variant: "omega", fontWeight: "semiBold", ellipsis: true, children: validationErrorsMessages }) })
626
645
  ] });
627
646
  }
628
647
  if (action == "publish") {
629
648
  return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
630
- /* @__PURE__ */ jsx(Icon, { color: "success600", as: CheckCircle }),
649
+ /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
631
650
  entry.publishedAt ? /* @__PURE__ */ jsx(Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
632
651
  id: "content-releases.pages.ReleaseDetails.entry-validation.already-published",
633
652
  defaultMessage: "Already published"
@@ -638,7 +657,7 @@ const EntryValidationText = ({ action, schema, components, entry }) => {
638
657
  ] });
639
658
  }
640
659
  return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
641
- /* @__PURE__ */ jsx(Icon, { color: "success600", as: CheckCircle }),
660
+ /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
642
661
  !entry.publishedAt ? /* @__PURE__ */ jsx(Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
643
662
  id: "content-releases.pages.ReleaseDetails.entry-validation.already-unpublished",
644
663
  defaultMessage: "Already unpublished"
@@ -658,20 +677,23 @@ const ReleaseDetailsLayout = ({
658
677
  const {
659
678
  data,
660
679
  isLoading: isLoadingDetails,
661
- isError,
662
680
  error
663
- } = useGetReleaseQuery({ id: releaseId });
681
+ } = useGetReleaseQuery(
682
+ { id: releaseId },
683
+ {
684
+ skip: !releaseId
685
+ }
686
+ );
664
687
  const [publishRelease, { isLoading: isPublishing }] = usePublishReleaseMutation();
665
- const toggleNotification = useNotification();
688
+ const { toggleNotification } = useNotification();
666
689
  const { formatAPIError } = useAPIErrorHandler();
667
- const {
668
- allowedActions: { canUpdate, canDelete }
669
- } = useRBAC(PERMISSIONS);
690
+ const { allowedActions } = useRBAC(PERMISSIONS);
691
+ const { canUpdate, canDelete, canPublish } = allowedActions;
670
692
  const dispatch = useTypedDispatch();
671
693
  const { trackUsage } = useTracking();
672
694
  const release = data?.data;
673
- const handlePublishRelease = async () => {
674
- const response = await publishRelease({ id: releaseId });
695
+ const handlePublishRelease = (id) => async () => {
696
+ const response = await publishRelease({ id });
675
697
  if ("data" in response) {
676
698
  toggleNotification({
677
699
  type: "success",
@@ -686,14 +708,14 @@ const ReleaseDetailsLayout = ({
686
708
  totalPublishedEntries,
687
709
  totalUnpublishedEntries
688
710
  });
689
- } else if (isAxiosError(response.error)) {
711
+ } else if (isFetchError(response.error)) {
690
712
  toggleNotification({
691
- type: "warning",
713
+ type: "danger",
692
714
  message: formatAPIError(response.error)
693
715
  });
694
716
  } else {
695
717
  toggleNotification({
696
- type: "warning",
718
+ type: "danger",
697
719
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
698
720
  });
699
721
  }
@@ -719,21 +741,20 @@ const ReleaseDetailsLayout = ({
719
741
  return release.createdBy.email;
720
742
  };
721
743
  if (isLoadingDetails) {
722
- return /* @__PURE__ */ jsx(Main, { "aria-busy": isLoadingDetails, children: /* @__PURE__ */ jsx(LoadingIndicatorPage, {}) });
744
+ return /* @__PURE__ */ jsx(Page.Loading, {});
723
745
  }
724
- if (isError || !release) {
746
+ if (isBaseQueryError(error) && "code" in error || !release) {
725
747
  return /* @__PURE__ */ jsx(
726
- Redirect,
748
+ Navigate,
727
749
  {
728
- to: {
729
- pathname: "/plugins/content-releases",
730
- state: {
731
- errors: [
732
- {
733
- code: error?.code
734
- }
735
- ]
736
- }
750
+ to: "..",
751
+ state: {
752
+ errors: [
753
+ {
754
+ // @ts-expect-error – TODO: fix this weird error flow
755
+ code: error?.code
756
+ }
757
+ ]
737
758
  }
738
759
  }
739
760
  );
@@ -770,34 +791,30 @@ const ReleaseDetailsLayout = ({
770
791
  ) : "";
771
792
  return /* @__PURE__ */ jsxs(Main, { "aria-busy": isLoadingDetails, children: [
772
793
  /* @__PURE__ */ jsx(
773
- HeaderLayout,
794
+ Layouts.Header,
774
795
  {
775
796
  title: release.name,
776
797
  subtitle: /* @__PURE__ */ jsxs(Flex, { gap: 2, lineHeight: 6, children: [
777
798
  /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", variant: "epsilon", children: numberOfEntriesText + (isScheduled ? ` - ${scheduledText}` : "") }),
778
799
  /* @__PURE__ */ jsx(Badge, { ...getBadgeProps(release.status), children: release.status })
779
800
  ] }),
780
- navigationAction: /* @__PURE__ */ jsx(Link$1, { startIcon: /* @__PURE__ */ jsx(ArrowLeft, {}), to: "/plugins/content-releases", children: formatMessage({
781
- id: "global.back",
782
- defaultMessage: "Back"
783
- }) }),
801
+ navigationAction: /* @__PURE__ */ jsx(BackButton, {}),
784
802
  primaryAction: !release.releasedAt && /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
785
803
  /* @__PURE__ */ jsxs(Menu.Root, { children: [
786
804
  /* @__PURE__ */ jsx(
787
805
  Menu.Trigger,
788
806
  {
789
- as: IconButton,
790
807
  paddingLeft: 2,
791
808
  paddingRight: 2,
792
809
  "aria-label": formatMessage({
793
810
  id: "content-releases.header.actions.open-release-actions",
794
811
  defaultMessage: "Release edit and delete menu"
795
812
  }),
796
- icon: /* @__PURE__ */ jsx(More, {}),
797
- variant: "tertiary"
813
+ variant: "tertiary",
814
+ children: /* @__PURE__ */ jsx(More, {})
798
815
  }
799
816
  ),
800
- /* @__PURE__ */ jsxs(Menu.Content, { top: 1, popoverPlacement: "bottom-end", children: [
817
+ /* @__PURE__ */ jsxs(Menu.Content, { top: 1, popoverPlacement: "bottom-end", maxHeight: void 0, children: [
801
818
  /* @__PURE__ */ jsxs(
802
819
  Flex,
803
820
  {
@@ -819,7 +836,7 @@ const ReleaseDetailsLayout = ({
819
836
  {
820
837
  disabled: !canDelete,
821
838
  onSelect: toggleWarningSubmit,
822
- variant: "danger",
839
+ $variant: "danger",
823
840
  children: /* @__PURE__ */ jsxs(Flex, { alignItems: "center", gap: 2, hasRadius: true, width: "100%", children: [
824
841
  /* @__PURE__ */ jsx(TrashIcon, {}),
825
842
  /* @__PURE__ */ jsx(Typography, { ellipsis: true, textColor: "danger600", children: formatMessage({
@@ -864,12 +881,12 @@ const ReleaseDetailsLayout = ({
864
881
  id: "content-releases.header.actions.refresh",
865
882
  defaultMessage: "Refresh"
866
883
  }) }),
867
- /* @__PURE__ */ jsx(CheckPermissions, { permissions: PERMISSIONS.publish, children: /* @__PURE__ */ jsx(
884
+ canPublish ? /* @__PURE__ */ jsx(
868
885
  Button,
869
886
  {
870
887
  size: "S",
871
888
  variant: "default",
872
- onClick: handlePublishRelease,
889
+ onClick: handlePublishRelease(release.id.toString()),
873
890
  loading: isPublishing,
874
891
  disabled: release.actions.meta.count === 0,
875
892
  children: formatMessage({
@@ -877,7 +894,7 @@ const ReleaseDetailsLayout = ({
877
894
  defaultMessage: "Publish"
878
895
  })
879
896
  }
880
- ) })
897
+ ) : null
881
898
  ] })
882
899
  }
883
900
  ),
@@ -885,6 +902,7 @@ const ReleaseDetailsLayout = ({
885
902
  ] });
886
903
  };
887
904
  const GROUP_BY_OPTIONS = ["contentType", "locale", "action"];
905
+ const GROUP_BY_OPTIONS_NO_LOCALE = ["contentType", "action"];
888
906
  const getGroupByOptionLabel = (value) => {
889
907
  if (value === "locale") {
890
908
  return {
@@ -903,21 +921,33 @@ const getGroupByOptionLabel = (value) => {
903
921
  defaultMessage: "Content-Types"
904
922
  };
905
923
  };
906
- const ReleaseDetailsBody = () => {
924
+ const ReleaseDetailsBody = ({ releaseId }) => {
907
925
  const { formatMessage } = useIntl();
908
- const { releaseId } = useParams();
909
926
  const [{ query }, setQuery] = useQueryParams();
910
- const toggleNotification = useNotification();
927
+ const { toggleNotification } = useNotification();
911
928
  const { formatAPIError } = useAPIErrorHandler();
912
929
  const {
913
930
  data: releaseData,
914
931
  isLoading: isReleaseLoading,
915
- isError: isReleaseError,
916
932
  error: releaseError
917
933
  } = useGetReleaseQuery({ id: releaseId });
918
934
  const {
919
935
  allowedActions: { canUpdate }
920
936
  } = useRBAC(PERMISSIONS);
937
+ const runHookWaterfall = useStrapiApp("ReleaseDetailsPage", (state) => state.runHookWaterfall);
938
+ const { hasI18nEnabled } = runHookWaterfall(
939
+ "ContentReleases/pages/ReleaseDetails/add-locale-in-releases",
940
+ {
941
+ displayedHeaders: {
942
+ label: formatMessage({
943
+ id: "content-releases.page.ReleaseDetails.table.header.label.locale",
944
+ defaultMessage: "locale"
945
+ }),
946
+ name: "locale"
947
+ },
948
+ hasI18nEnabled: false
949
+ }
950
+ );
921
951
  const release = releaseData?.data;
922
952
  const selectedGroupBy = query?.groupBy || "contentType";
923
953
  const {
@@ -946,65 +976,59 @@ const ReleaseDetailsBody = () => {
946
976
  // We are passing the action path to found the position in the cache of the action for optimistic updates
947
977
  });
948
978
  if ("error" in response) {
949
- if (isAxiosError(response.error)) {
979
+ if (isFetchError(response.error)) {
950
980
  toggleNotification({
951
- type: "warning",
981
+ type: "danger",
952
982
  message: formatAPIError(response.error)
953
983
  });
954
984
  } else {
955
985
  toggleNotification({
956
- type: "warning",
986
+ type: "danger",
957
987
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
958
988
  });
959
989
  }
960
990
  }
961
991
  };
962
992
  if (isLoading || isReleaseLoading) {
963
- return /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsx(LoadingIndicatorPage, {}) });
993
+ return /* @__PURE__ */ jsx(Page.Loading, {});
964
994
  }
965
995
  const releaseActions = data?.data;
966
996
  const releaseMeta = data?.meta;
967
997
  const contentTypes = releaseMeta?.contentTypes || {};
968
998
  const components = releaseMeta?.components || {};
969
- if (isReleaseError || !release) {
999
+ if (isBaseQueryError(releaseError) || !release) {
970
1000
  const errorsArray = [];
971
- if (releaseError) {
1001
+ if (releaseError && "code" in releaseError) {
972
1002
  errorsArray.push({
973
1003
  code: releaseError.code
974
1004
  });
975
1005
  }
976
- if (releaseActionsError) {
1006
+ if (releaseActionsError && "code" in releaseActionsError) {
977
1007
  errorsArray.push({
978
1008
  code: releaseActionsError.code
979
1009
  });
980
1010
  }
981
1011
  return /* @__PURE__ */ jsx(
982
- Redirect,
1012
+ Navigate,
983
1013
  {
984
- to: {
985
- pathname: "/plugins/content-releases",
986
- state: {
987
- errors: errorsArray
988
- }
1014
+ to: "..",
1015
+ state: {
1016
+ errors: errorsArray
989
1017
  }
990
1018
  }
991
1019
  );
992
1020
  }
993
1021
  if (isError || !releaseActions) {
994
- return /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsx(AnErrorOccurred, {}) });
1022
+ return /* @__PURE__ */ jsx(Page.Error, {});
995
1023
  }
996
1024
  if (Object.keys(releaseActions).length === 0) {
997
- return /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsx(
998
- NoContent,
1025
+ return /* @__PURE__ */ jsx(Layouts.Content, { children: /* @__PURE__ */ jsx(
1026
+ EmptyStateLayout,
999
1027
  {
1000
- content: {
1001
- id: "content-releases.pages.Details.tab.emptyEntries",
1002
- defaultMessage: "This release is empty. Open the Content Manager, select an entry and add it to the release."
1003
- },
1004
1028
  action: /* @__PURE__ */ jsx(
1005
1029
  LinkButton,
1006
1030
  {
1007
- as: Link$2,
1031
+ tag: Link$1,
1008
1032
  to: {
1009
1033
  pathname: "/content-manager"
1010
1034
  },
@@ -1015,18 +1039,59 @@ const ReleaseDetailsBody = () => {
1015
1039
  defaultMessage: "Open the Content Manager"
1016
1040
  })
1017
1041
  }
1018
- )
1042
+ ),
1043
+ icon: /* @__PURE__ */ jsx(EmptyDocuments, { width: "16rem" }),
1044
+ content: formatMessage({
1045
+ id: "content-releases.pages.Details.tab.emptyEntries",
1046
+ defaultMessage: "This release is empty. Open the Content Manager, select an entry and add it to the release."
1047
+ })
1019
1048
  }
1020
1049
  ) });
1021
1050
  }
1022
- return /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsxs(Flex, { gap: 8, direction: "column", alignItems: "stretch", children: [
1051
+ const groupByLabel = formatMessage({
1052
+ id: "content-releases.pages.ReleaseDetails.groupBy.aria-label",
1053
+ defaultMessage: "Group by"
1054
+ });
1055
+ const headers = [
1056
+ // ...displayedHeaders,
1057
+ {
1058
+ label: formatMessage({
1059
+ id: "content-releases.page.ReleaseDetails.table.header.label.name",
1060
+ defaultMessage: "name"
1061
+ }),
1062
+ name: "name"
1063
+ },
1064
+ {
1065
+ label: formatMessage({
1066
+ id: "content-releases.page.ReleaseDetails.table.header.label.content-type",
1067
+ defaultMessage: "content-type"
1068
+ }),
1069
+ name: "content-type"
1070
+ },
1071
+ {
1072
+ label: formatMessage({
1073
+ id: "content-releases.page.ReleaseDetails.table.header.label.action",
1074
+ defaultMessage: "action"
1075
+ }),
1076
+ name: "action"
1077
+ },
1078
+ ...!release.releasedAt ? [
1079
+ {
1080
+ label: formatMessage({
1081
+ id: "content-releases.page.ReleaseDetails.table.header.label.status",
1082
+ defaultMessage: "status"
1083
+ }),
1084
+ name: "status"
1085
+ }
1086
+ ] : []
1087
+ ];
1088
+ const options = hasI18nEnabled ? GROUP_BY_OPTIONS : GROUP_BY_OPTIONS_NO_LOCALE;
1089
+ return /* @__PURE__ */ jsx(Layouts.Content, { children: /* @__PURE__ */ jsxs(Flex, { gap: 8, direction: "column", alignItems: "stretch", children: [
1023
1090
  /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(
1024
1091
  SingleSelect,
1025
1092
  {
1026
- "aria-label": formatMessage({
1027
- id: "content-releases.pages.ReleaseDetails.groupBy.aria-label",
1028
- defaultMessage: "Group by"
1029
- }),
1093
+ placeholder: groupByLabel,
1094
+ "aria-label": groupByLabel,
1030
1095
  customizeContent: (value) => formatMessage(
1031
1096
  {
1032
1097
  id: `content-releases.pages.ReleaseDetails.groupBy.label`,
@@ -1038,7 +1103,7 @@ const ReleaseDetailsBody = () => {
1038
1103
  ),
1039
1104
  value: formatMessage(getGroupByOptionLabel(selectedGroupBy)),
1040
1105
  onChange: (value) => setQuery({ groupBy: value }),
1041
- children: GROUP_BY_OPTIONS.map((option) => /* @__PURE__ */ jsx(SingleSelectOption, { value: option, children: formatMessage(getGroupByOptionLabel(option)) }, option))
1106
+ children: options.map((option) => /* @__PURE__ */ jsx(SingleSelectOption, { value: option, children: formatMessage(getGroupByOptionLabel(option)) }, option))
1042
1107
  }
1043
1108
  ) }),
1044
1109
  Object.keys(releaseActions).map((key) => /* @__PURE__ */ jsxs(Flex, { gap: 4, direction: "column", alignItems: "stretch", children: [
@@ -1050,72 +1115,15 @@ const ReleaseDetailsBody = () => {
1050
1115
  ...item,
1051
1116
  id: Number(item.entry.id)
1052
1117
  })),
1053
- colCount: releaseActions[key].length,
1054
- isLoading,
1055
- isFetching,
1118
+ headers,
1119
+ isLoading: isLoading || isFetching,
1056
1120
  children: /* @__PURE__ */ jsxs(Table.Content, { children: [
1057
- /* @__PURE__ */ jsxs(Table.Head, { children: [
1058
- /* @__PURE__ */ jsx(
1059
- Table.HeaderCell,
1060
- {
1061
- fieldSchemaType: "string",
1062
- label: formatMessage({
1063
- id: "content-releases.page.ReleaseDetails.table.header.label.name",
1064
- defaultMessage: "name"
1065
- }),
1066
- name: "name"
1067
- }
1068
- ),
1069
- /* @__PURE__ */ jsx(
1070
- Table.HeaderCell,
1071
- {
1072
- fieldSchemaType: "string",
1073
- label: formatMessage({
1074
- id: "content-releases.page.ReleaseDetails.table.header.label.locale",
1075
- defaultMessage: "locale"
1076
- }),
1077
- name: "locale"
1078
- }
1079
- ),
1080
- /* @__PURE__ */ jsx(
1081
- Table.HeaderCell,
1082
- {
1083
- fieldSchemaType: "string",
1084
- label: formatMessage({
1085
- id: "content-releases.page.ReleaseDetails.table.header.label.content-type",
1086
- defaultMessage: "content-type"
1087
- }),
1088
- name: "content-type"
1089
- }
1090
- ),
1091
- /* @__PURE__ */ jsx(
1092
- Table.HeaderCell,
1093
- {
1094
- fieldSchemaType: "string",
1095
- label: formatMessage({
1096
- id: "content-releases.page.ReleaseDetails.table.header.label.action",
1097
- defaultMessage: "action"
1098
- }),
1099
- name: "action"
1100
- }
1101
- ),
1102
- !release.releasedAt && /* @__PURE__ */ jsx(
1103
- Table.HeaderCell,
1104
- {
1105
- fieldSchemaType: "string",
1106
- label: formatMessage({
1107
- id: "content-releases.page.ReleaseDetails.table.header.label.status",
1108
- defaultMessage: "status"
1109
- }),
1110
- name: "status"
1111
- }
1112
- )
1113
- ] }),
1114
- /* @__PURE__ */ jsx(Table.LoadingBody, {}),
1121
+ /* @__PURE__ */ jsx(Table.Head, { children: headers.map((header) => /* @__PURE__ */ jsx(Table.HeaderCell, { ...header }, header.name)) }),
1122
+ /* @__PURE__ */ jsx(Table.Loading, {}),
1115
1123
  /* @__PURE__ */ jsx(Table.Body, { children: releaseActions[key].map(
1116
1124
  ({ id, contentType, locale, type, entry }, actionIndex) => /* @__PURE__ */ jsxs(Tr, { children: [
1117
1125
  /* @__PURE__ */ jsx(Td, { width: "25%", maxWidth: "200px", children: /* @__PURE__ */ jsx(Typography, { ellipsis: true, children: `${contentType.mainFieldValue || entry.id}` }) }),
1118
- /* @__PURE__ */ jsx(Td, { width: "10%", children: /* @__PURE__ */ jsx(Typography, { children: `${locale?.name ? locale.name : "-"}` }) }),
1126
+ hasI18nEnabled && /* @__PURE__ */ jsx(Td, { width: "10%", children: /* @__PURE__ */ jsx(Typography, { children: `${locale?.name ? locale.name : "-"}` }) }),
1119
1127
  /* @__PURE__ */ jsx(Td, { width: "10%", children: /* @__PURE__ */ jsx(Typography, { children: contentType.displayName || "" }) }),
1120
1128
  /* @__PURE__ */ jsx(Td, { width: "20%", children: release.releasedAt ? /* @__PURE__ */ jsx(Typography, { children: formatMessage(
1121
1129
  {
@@ -1169,34 +1177,39 @@ const ReleaseDetailsBody = () => {
1169
1177
  }
1170
1178
  )
1171
1179
  ] }, `releases-group-${key}`)),
1172
- /* @__PURE__ */ jsxs(Flex, { paddingTop: 4, alignItems: "flex-end", justifyContent: "space-between", children: [
1173
- /* @__PURE__ */ jsx(PageSizeURLQuery, { defaultValue: releaseMeta?.pagination?.pageSize.toString() }),
1174
- /* @__PURE__ */ jsx(
1175
- PaginationURLQuery,
1176
- {
1177
- pagination: {
1178
- pageCount: releaseMeta?.pagination?.pageCount || 0
1179
- }
1180
- }
1181
- )
1182
- ] })
1180
+ /* @__PURE__ */ jsxs(
1181
+ Pagination.Root,
1182
+ {
1183
+ ...releaseMeta?.pagination,
1184
+ defaultPageSize: releaseMeta?.pagination?.pageSize,
1185
+ children: [
1186
+ /* @__PURE__ */ jsx(Pagination.PageSize, {}),
1187
+ /* @__PURE__ */ jsx(Pagination.Links, {})
1188
+ ]
1189
+ }
1190
+ )
1183
1191
  ] }) });
1184
1192
  };
1185
1193
  const ReleaseDetailsPage = () => {
1186
1194
  const { formatMessage } = useIntl();
1187
1195
  const { releaseId } = useParams();
1188
- const toggleNotification = useNotification();
1196
+ const { toggleNotification } = useNotification();
1189
1197
  const { formatAPIError } = useAPIErrorHandler();
1190
- const { replace } = useHistory();
1198
+ const navigate = useNavigate();
1191
1199
  const [releaseModalShown, setReleaseModalShown] = React.useState(false);
1192
1200
  const [showWarningSubmit, setWarningSubmit] = React.useState(false);
1193
1201
  const {
1194
1202
  isLoading: isLoadingDetails,
1195
1203
  data,
1196
1204
  isSuccess: isSuccessDetails
1197
- } = useGetReleaseQuery({ id: releaseId });
1205
+ } = useGetReleaseQuery(
1206
+ { id: releaseId },
1207
+ {
1208
+ skip: !releaseId
1209
+ }
1210
+ );
1198
1211
  const [updateRelease, { isLoading: isSubmittingForm }] = useUpdateReleaseMutation();
1199
- const [deleteRelease, { isLoading: isDeletingRelease }] = useDeleteReleaseMutation();
1212
+ const [deleteRelease] = useDeleteReleaseMutation();
1200
1213
  const toggleEditReleaseModal = () => {
1201
1214
  setReleaseModalShown((prev) => !prev);
1202
1215
  };
@@ -1207,15 +1220,18 @@ const ReleaseDetailsPage = () => {
1207
1220
  {
1208
1221
  toggleEditReleaseModal,
1209
1222
  toggleWarningSubmit,
1210
- children: /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsx(LoadingIndicatorPage, {}) })
1223
+ children: /* @__PURE__ */ jsx(Page.Loading, {})
1211
1224
  }
1212
1225
  );
1213
1226
  }
1227
+ if (!releaseId) {
1228
+ return /* @__PURE__ */ jsx(Navigate, { to: ".." });
1229
+ }
1214
1230
  const releaseData = isSuccessDetails && data?.data || null;
1215
1231
  const title = releaseData?.name || "";
1216
1232
  const timezone = releaseData?.timezone ?? null;
1217
1233
  const scheduledAt = releaseData?.scheduledAt && timezone ? utcToZonedTime(releaseData.scheduledAt, timezone) : null;
1218
- const date = scheduledAt ? format(scheduledAt, "yyyy-MM-dd") : null;
1234
+ const date = scheduledAt ? format(scheduledAt, "yyyy-MM-dd") : void 0;
1219
1235
  const time = scheduledAt ? format(scheduledAt, "HH:mm") : "";
1220
1236
  const handleEditRelease = async (values) => {
1221
1237
  const response = await updateRelease({
@@ -1233,14 +1249,14 @@ const ReleaseDetailsPage = () => {
1233
1249
  })
1234
1250
  });
1235
1251
  toggleEditReleaseModal();
1236
- } else if (isAxiosError(response.error)) {
1252
+ } else if (isFetchError(response.error)) {
1237
1253
  toggleNotification({
1238
- type: "warning",
1254
+ type: "danger",
1239
1255
  message: formatAPIError(response.error)
1240
1256
  });
1241
1257
  } else {
1242
1258
  toggleNotification({
1243
- type: "warning",
1259
+ type: "danger",
1244
1260
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
1245
1261
  });
1246
1262
  }
@@ -1250,15 +1266,15 @@ const ReleaseDetailsPage = () => {
1250
1266
  id: releaseId
1251
1267
  });
1252
1268
  if ("data" in response) {
1253
- replace("/plugins/content-releases");
1254
- } else if (isAxiosError(response.error)) {
1269
+ navigate("..");
1270
+ } else if (isFetchError(response.error)) {
1255
1271
  toggleNotification({
1256
- type: "warning",
1272
+ type: "danger",
1257
1273
  message: formatAPIError(response.error)
1258
1274
  });
1259
1275
  } else {
1260
1276
  toggleNotification({
1261
- type: "warning",
1277
+ type: "danger",
1262
1278
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
1263
1279
  });
1264
1280
  }
@@ -1269,10 +1285,11 @@ const ReleaseDetailsPage = () => {
1269
1285
  toggleEditReleaseModal,
1270
1286
  toggleWarningSubmit,
1271
1287
  children: [
1272
- /* @__PURE__ */ jsx(ReleaseDetailsBody, {}),
1273
- releaseModalShown && /* @__PURE__ */ jsx(
1288
+ /* @__PURE__ */ jsx(ReleaseDetailsBody, { releaseId }),
1289
+ /* @__PURE__ */ jsx(
1274
1290
  ReleaseModal,
1275
1291
  {
1292
+ open: releaseModalShown,
1276
1293
  handleClose: toggleEditReleaseModal,
1277
1294
  handleSubmit: handleEditRelease,
1278
1295
  isLoading: isLoadingDetails || isSubmittingForm,
@@ -1286,30 +1303,21 @@ const ReleaseDetailsPage = () => {
1286
1303
  }
1287
1304
  }
1288
1305
  ),
1289
- /* @__PURE__ */ jsx(
1290
- ConfirmDialog,
1291
- {
1292
- bodyText: {
1293
- id: "content-releases.dialog.confirmation-message",
1294
- defaultMessage: "Are you sure you want to delete this release?"
1295
- },
1296
- isOpen: showWarningSubmit,
1297
- isConfirmButtonLoading: isDeletingRelease,
1298
- onToggleDialog: toggleWarningSubmit,
1299
- onConfirm: handleDeleteRelease
1300
- }
1301
- )
1306
+ /* @__PURE__ */ jsx(Dialog.Root, { open: showWarningSubmit, onOpenChange: toggleWarningSubmit, children: /* @__PURE__ */ jsx(ConfirmDialog, { onConfirm: handleDeleteRelease, children: formatMessage({
1307
+ id: "content-releases.dialog.confirmation-message",
1308
+ defaultMessage: "Are you sure you want to delete this release?"
1309
+ }) }) })
1302
1310
  ]
1303
1311
  }
1304
1312
  );
1305
1313
  };
1306
1314
  const App = () => {
1307
- return /* @__PURE__ */ jsx(CheckPagePermissions, { permissions: PERMISSIONS.main, children: /* @__PURE__ */ jsxs(Switch, { children: [
1308
- /* @__PURE__ */ jsx(Route, { exact: true, path: `/plugins/${pluginId}`, component: ReleasesPage }),
1309
- /* @__PURE__ */ jsx(Route, { exact: true, path: `/plugins/${pluginId}/:releaseId`, component: ReleaseDetailsPage })
1315
+ return /* @__PURE__ */ jsx(Page.Protect, { permissions: PERMISSIONS.main, children: /* @__PURE__ */ jsxs(Routes, { children: [
1316
+ /* @__PURE__ */ jsx(Route, { index: true, element: /* @__PURE__ */ jsx(ReleasesPage, {}) }),
1317
+ /* @__PURE__ */ jsx(Route, { path: ":releaseId", element: /* @__PURE__ */ jsx(ReleaseDetailsPage, {}) })
1310
1318
  ] }) });
1311
1319
  };
1312
1320
  export {
1313
1321
  App
1314
1322
  };
1315
- //# sourceMappingURL=App-x6Tjj3HN.mjs.map
1323
+ //# sourceMappingURL=App-Do-Rnv0A.mjs.map