@strapi/content-releases 5.0.0-beta.7 → 5.0.0-beta.9
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.
- package/dist/_chunks/{App-BdcItFff.js → App-DUmziQ17.js} +126 -119
- package/dist/_chunks/App-DUmziQ17.js.map +1 -0
- package/dist/_chunks/{App-CJdkbHnd.mjs → App-D_6Y9N2F.mjs} +128 -121
- package/dist/_chunks/App-D_6Y9N2F.mjs.map +1 -0
- package/dist/_chunks/{index-BvhZTh4j.mjs → index-BomF0-yY.mjs} +28 -249
- package/dist/_chunks/index-BomF0-yY.mjs.map +1 -0
- package/dist/_chunks/{index-B6Y2hJ10.js → index-C5Hc767q.js} +26 -247
- package/dist/_chunks/index-C5Hc767q.js.map +1 -0
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/admin/src/components/ReleaseActionMenu.d.ts +1 -1
- package/dist/admin/src/components/ReleaseModal.d.ts +1 -1
- package/dist/admin/src/services/release.d.ts +36 -495
- package/dist/admin/src/utils/api.d.ts +6 -0
- package/package.json +13 -14
- package/dist/_chunks/App-BdcItFff.js.map +0 -1
- package/dist/_chunks/App-CJdkbHnd.mjs.map +0 -1
- package/dist/_chunks/index-B6Y2hJ10.js.map +0 -1
- package/dist/_chunks/index-BvhZTh4j.mjs.map +0 -1
- package/dist/admin/src/services/baseQuery.d.ts +0 -26
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
3
3
|
const jsxRuntime = require("react/jsx-runtime");
|
|
4
4
|
const strapiAdmin = require("@strapi/admin/strapi-admin");
|
|
5
5
|
const reactRouterDom = require("react-router-dom");
|
|
6
|
-
const index = require("./index-
|
|
6
|
+
const index = require("./index-C5Hc767q.js");
|
|
7
7
|
const React = require("react");
|
|
8
8
|
const strapiAdmin$1 = require("@strapi/content-manager/strapi-admin");
|
|
9
9
|
const designSystem = require("@strapi/design-system");
|
|
@@ -139,114 +139,119 @@ const ReleaseModal = ({
|
|
|
139
139
|
},
|
|
140
140
|
validationSchema: RELEASE_SCHEMA,
|
|
141
141
|
validateOnChange: false,
|
|
142
|
-
children: ({ values, errors, handleChange, setFieldValue }) =>
|
|
143
|
-
|
|
144
|
-
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.
|
|
145
|
-
/* @__PURE__ */ jsxRuntime.
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
designSystem.
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
{
|
|
172
|
-
textColor: values.isScheduled ? "primary600" : "neutral800",
|
|
173
|
-
fontWeight: values.isScheduled ? "semiBold" : "regular",
|
|
174
|
-
children: formatMessage({
|
|
175
|
-
id: "modal.form.input.label.schedule-release",
|
|
176
|
-
defaultMessage: "Schedule release"
|
|
177
|
-
})
|
|
178
|
-
}
|
|
179
|
-
)
|
|
180
|
-
}
|
|
181
|
-
) }),
|
|
182
|
-
values.isScheduled && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
183
|
-
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 4, alignItems: "start", children: [
|
|
184
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { name: "date", error: errors.date, required: true, children: [
|
|
185
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
|
|
186
|
-
id: "content-releases.modal.form.input.label.date",
|
|
187
|
-
defaultMessage: "Date"
|
|
188
|
-
}) }),
|
|
189
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
190
|
-
designSystem.DatePicker,
|
|
191
|
-
{
|
|
192
|
-
onChange: (date) => {
|
|
193
|
-
const isoFormatDate = date ? dateFns.formatISO(date, { representation: "date" }) : null;
|
|
194
|
-
setFieldValue("date", isoFormatDate);
|
|
195
|
-
},
|
|
196
|
-
clearLabel: formatMessage({
|
|
197
|
-
id: "content-releases.modal.form.input.clearLabel",
|
|
198
|
-
defaultMessage: "Clear"
|
|
199
|
-
}),
|
|
200
|
-
onClear: () => {
|
|
201
|
-
setFieldValue("date", null);
|
|
202
|
-
},
|
|
203
|
-
selectedDate: values.date || void 0,
|
|
204
|
-
minDate: dateFnsTz.utcToZonedTime(/* @__PURE__ */ new Date(), values.timezone.split("&")[1])
|
|
142
|
+
children: ({ values, errors, handleChange, setFieldValue }) => {
|
|
143
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(formik.Form, { children: [
|
|
144
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.ModalBody, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 6, children: [
|
|
145
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { name: "name", error: errors.name, required: true, children: [
|
|
146
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
|
|
147
|
+
id: "content-releases.modal.form.input.label.release-name",
|
|
148
|
+
defaultMessage: "Name"
|
|
149
|
+
}) }),
|
|
150
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.TextInput, { value: values.name, onChange: handleChange }),
|
|
151
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {})
|
|
152
|
+
] }),
|
|
153
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "max-content", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
154
|
+
designSystem.Checkbox,
|
|
155
|
+
{
|
|
156
|
+
name: "isScheduled",
|
|
157
|
+
value: values.isScheduled,
|
|
158
|
+
onChange: (event) => {
|
|
159
|
+
setFieldValue("isScheduled", event.target.checked);
|
|
160
|
+
if (!event.target.checked) {
|
|
161
|
+
setFieldValue("date", null);
|
|
162
|
+
setFieldValue("time", "");
|
|
163
|
+
setFieldValue("timezone", null);
|
|
164
|
+
} else {
|
|
165
|
+
setFieldValue("date", initialValues.date);
|
|
166
|
+
setFieldValue("time", initialValues.time);
|
|
167
|
+
setFieldValue(
|
|
168
|
+
"timezone",
|
|
169
|
+
initialValues.timezone ?? systemTimezone?.value
|
|
170
|
+
);
|
|
205
171
|
}
|
|
206
|
-
|
|
207
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
208
|
-
|
|
209
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { name: "time", error: errors.time, required: true, children: [
|
|
210
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
|
|
211
|
-
id: "content-releases.modal.form.input.label.time",
|
|
212
|
-
defaultMessage: "Time"
|
|
213
|
-
}) }),
|
|
214
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
215
|
-
designSystem.TimePicker,
|
|
172
|
+
},
|
|
173
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
174
|
+
designSystem.Typography,
|
|
216
175
|
{
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
}),
|
|
224
|
-
onClear: () => {
|
|
225
|
-
setFieldValue("time", "");
|
|
226
|
-
},
|
|
227
|
-
value: values.time || void 0
|
|
176
|
+
textColor: values.isScheduled ? "primary600" : "neutral800",
|
|
177
|
+
fontWeight: values.isScheduled ? "semiBold" : "regular",
|
|
178
|
+
children: formatMessage({
|
|
179
|
+
id: "modal.form.input.label.schedule-release",
|
|
180
|
+
defaultMessage: "Schedule release"
|
|
181
|
+
})
|
|
228
182
|
}
|
|
229
|
-
)
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
183
|
+
)
|
|
184
|
+
}
|
|
185
|
+
) }),
|
|
186
|
+
values.isScheduled && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
187
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 4, alignItems: "start", children: [
|
|
188
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { name: "date", error: errors.date, required: true, children: [
|
|
189
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
|
|
190
|
+
id: "content-releases.modal.form.input.label.date",
|
|
191
|
+
defaultMessage: "Date"
|
|
192
|
+
}) }),
|
|
193
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
194
|
+
designSystem.DatePicker,
|
|
195
|
+
{
|
|
196
|
+
onChange: (date) => {
|
|
197
|
+
const isoFormatDate = date ? dateFns.formatISO(date, { representation: "date" }) : null;
|
|
198
|
+
setFieldValue("date", isoFormatDate);
|
|
199
|
+
},
|
|
200
|
+
clearLabel: formatMessage({
|
|
201
|
+
id: "content-releases.modal.form.input.clearLabel",
|
|
202
|
+
defaultMessage: "Clear"
|
|
203
|
+
}),
|
|
204
|
+
onClear: () => {
|
|
205
|
+
setFieldValue("date", null);
|
|
206
|
+
},
|
|
207
|
+
value: values.date ? new Date(values.date) : /* @__PURE__ */ new Date(),
|
|
208
|
+
minDate: dateFnsTz.utcToZonedTime(/* @__PURE__ */ new Date(), values.timezone.split("&")[1])
|
|
209
|
+
}
|
|
210
|
+
),
|
|
211
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {})
|
|
212
|
+
] }) }),
|
|
213
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { name: "time", error: errors.time, required: true, children: [
|
|
214
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
|
|
215
|
+
id: "content-releases.modal.form.input.label.time",
|
|
216
|
+
defaultMessage: "Time"
|
|
217
|
+
}) }),
|
|
218
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
219
|
+
designSystem.TimePicker,
|
|
220
|
+
{
|
|
221
|
+
onChange: (time) => {
|
|
222
|
+
setFieldValue("time", time);
|
|
223
|
+
},
|
|
224
|
+
clearLabel: formatMessage({
|
|
225
|
+
id: "content-releases.modal.form.input.clearLabel",
|
|
226
|
+
defaultMessage: "Clear"
|
|
227
|
+
}),
|
|
228
|
+
onClear: () => {
|
|
229
|
+
setFieldValue("time", "");
|
|
230
|
+
},
|
|
231
|
+
value: values.time || void 0
|
|
232
|
+
}
|
|
233
|
+
),
|
|
234
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {})
|
|
235
|
+
] }) })
|
|
236
|
+
] }),
|
|
237
|
+
/* @__PURE__ */ jsxRuntime.jsx(TimezoneComponent, { timezoneOptions: timezoneList })
|
|
238
|
+
] })
|
|
239
|
+
] }) }),
|
|
240
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
241
|
+
designSystem.ModalFooter,
|
|
242
|
+
{
|
|
243
|
+
startActions: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleClose, variant: "tertiary", name: "cancel", children: formatMessage({ id: "cancel", defaultMessage: "Cancel" }) }),
|
|
244
|
+
endActions: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { name: "submit", loading: isLoading, type: "submit", children: formatMessage(
|
|
245
|
+
{
|
|
246
|
+
id: "content-releases.modal.form.button.submit",
|
|
247
|
+
defaultMessage: "{isCreatingRelease, select, true {Continue} other {Save}}"
|
|
248
|
+
},
|
|
249
|
+
{ isCreatingRelease }
|
|
250
|
+
) })
|
|
251
|
+
}
|
|
252
|
+
)
|
|
253
|
+
] });
|
|
254
|
+
}
|
|
250
255
|
}
|
|
251
256
|
)
|
|
252
257
|
] });
|
|
@@ -302,6 +307,9 @@ const TimezoneComponent = ({ timezoneOptions }) => {
|
|
|
302
307
|
] });
|
|
303
308
|
};
|
|
304
309
|
const useTypedDispatch = reactRedux.useDispatch;
|
|
310
|
+
const isBaseQueryError = (error) => {
|
|
311
|
+
return typeof error !== "undefined" && error.name !== void 0;
|
|
312
|
+
};
|
|
305
313
|
const LinkCard = styledComponents.styled(designSystem.Link)`
|
|
306
314
|
display: block;
|
|
307
315
|
`;
|
|
@@ -358,7 +366,7 @@ const ReleasesGrid = ({ sectionTitle, releases = [], isError = false }) => {
|
|
|
358
366
|
}
|
|
359
367
|
);
|
|
360
368
|
}
|
|
361
|
-
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid, { gap: 4, children: releases.map(({ id, name, scheduledAt, status }) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.GridItem, { col: 3, s: 6, xs: 12, children: /* @__PURE__ */ jsxRuntime.jsx(LinkCard, {
|
|
369
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid, { gap: 4, children: releases.map(({ id, name, scheduledAt, status }) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.GridItem, { col: 3, s: 6, xs: 12, children: /* @__PURE__ */ jsxRuntime.jsx(LinkCard, { tag: reactRouterDom.NavLink, to: `${id}`, isExternal: false, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
362
370
|
designSystem.Flex,
|
|
363
371
|
{
|
|
364
372
|
direction: "column",
|
|
@@ -394,7 +402,7 @@ const StyledAlert = styledComponents.styled(designSystem.Alert)`
|
|
|
394
402
|
`;
|
|
395
403
|
const INITIAL_FORM_VALUES = {
|
|
396
404
|
name: "",
|
|
397
|
-
date:
|
|
405
|
+
date: void 0,
|
|
398
406
|
time: "",
|
|
399
407
|
isScheduled: true,
|
|
400
408
|
scheduledAt: null,
|
|
@@ -664,6 +672,7 @@ const EntryValidationText = ({ action, schema, entry }) => {
|
|
|
664
672
|
if (Object.keys(errors).length > 0) {
|
|
665
673
|
const validationErrorsMessages = Object.entries(errors).map(
|
|
666
674
|
([key, value]) => formatMessage(
|
|
675
|
+
// @ts-expect-error – TODO: fix this will better checks
|
|
667
676
|
{ id: `${value.id}.withField`, defaultMessage: value.defaultMessage },
|
|
668
677
|
{ field: key }
|
|
669
678
|
)
|
|
@@ -706,7 +715,6 @@ const ReleaseDetailsLayout = ({
|
|
|
706
715
|
const {
|
|
707
716
|
data,
|
|
708
717
|
isLoading: isLoadingDetails,
|
|
709
|
-
isError,
|
|
710
718
|
error
|
|
711
719
|
} = index.useGetReleaseQuery(
|
|
712
720
|
{ id: releaseId },
|
|
@@ -773,7 +781,7 @@ const ReleaseDetailsLayout = ({
|
|
|
773
781
|
if (isLoadingDetails) {
|
|
774
782
|
return /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Page.Loading, {});
|
|
775
783
|
}
|
|
776
|
-
if (
|
|
784
|
+
if (isBaseQueryError(error) && "code" in error || !release) {
|
|
777
785
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
778
786
|
reactRouterDom.Navigate,
|
|
779
787
|
{
|
|
@@ -781,6 +789,7 @@ const ReleaseDetailsLayout = ({
|
|
|
781
789
|
state: {
|
|
782
790
|
errors: [
|
|
783
791
|
{
|
|
792
|
+
// @ts-expect-error – TODO: fix this weird error flow
|
|
784
793
|
code: error?.code
|
|
785
794
|
}
|
|
786
795
|
]
|
|
@@ -833,15 +842,14 @@ const ReleaseDetailsLayout = ({
|
|
|
833
842
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
834
843
|
designSystem.Menu.Trigger,
|
|
835
844
|
{
|
|
836
|
-
tag: designSystem.IconButton,
|
|
837
845
|
paddingLeft: 2,
|
|
838
846
|
paddingRight: 2,
|
|
839
847
|
"aria-label": formatMessage({
|
|
840
848
|
id: "content-releases.header.actions.open-release-actions",
|
|
841
849
|
defaultMessage: "Release edit and delete menu"
|
|
842
850
|
}),
|
|
843
|
-
|
|
844
|
-
|
|
851
|
+
variant: "tertiary",
|
|
852
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(icons.More, {})
|
|
845
853
|
}
|
|
846
854
|
),
|
|
847
855
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Content, { top: 1, popoverPlacement: "bottom-end", maxHeight: void 0, children: [
|
|
@@ -959,7 +967,6 @@ const ReleaseDetailsBody = ({ releaseId }) => {
|
|
|
959
967
|
const {
|
|
960
968
|
data: releaseData,
|
|
961
969
|
isLoading: isReleaseLoading,
|
|
962
|
-
isError: isReleaseError,
|
|
963
970
|
error: releaseError
|
|
964
971
|
} = index.useGetReleaseQuery({ id: releaseId });
|
|
965
972
|
const {
|
|
@@ -1027,14 +1034,14 @@ const ReleaseDetailsBody = ({ releaseId }) => {
|
|
|
1027
1034
|
const releaseMeta = data?.meta;
|
|
1028
1035
|
const contentTypes = releaseMeta?.contentTypes || {};
|
|
1029
1036
|
const components = releaseMeta?.components || {};
|
|
1030
|
-
if (
|
|
1037
|
+
if (isBaseQueryError(releaseError) || !release) {
|
|
1031
1038
|
const errorsArray = [];
|
|
1032
|
-
if (releaseError) {
|
|
1039
|
+
if (releaseError && "code" in releaseError) {
|
|
1033
1040
|
errorsArray.push({
|
|
1034
1041
|
code: releaseError.code
|
|
1035
1042
|
});
|
|
1036
1043
|
}
|
|
1037
|
-
if (releaseActionsError) {
|
|
1044
|
+
if (releaseActionsError && "code" in releaseActionsError) {
|
|
1038
1045
|
errorsArray.push({
|
|
1039
1046
|
code: releaseActionsError.code
|
|
1040
1047
|
});
|
|
@@ -1262,7 +1269,7 @@ const ReleaseDetailsPage = () => {
|
|
|
1262
1269
|
const title = releaseData?.name || "";
|
|
1263
1270
|
const timezone = releaseData?.timezone ?? null;
|
|
1264
1271
|
const scheduledAt = releaseData?.scheduledAt && timezone ? dateFnsTz.utcToZonedTime(releaseData.scheduledAt, timezone) : null;
|
|
1265
|
-
const date = scheduledAt ? format__default.default(scheduledAt, "yyyy-MM-dd") :
|
|
1272
|
+
const date = scheduledAt ? format__default.default(scheduledAt, "yyyy-MM-dd") : void 0;
|
|
1266
1273
|
const time = scheduledAt ? format__default.default(scheduledAt, "HH:mm") : "";
|
|
1267
1274
|
const handleEditRelease = async (values) => {
|
|
1268
1275
|
const response = await updateRelease({
|
|
@@ -1356,4 +1363,4 @@ const App = () => {
|
|
|
1356
1363
|
] }) });
|
|
1357
1364
|
};
|
|
1358
1365
|
exports.App = App;
|
|
1359
|
-
//# sourceMappingURL=App-
|
|
1366
|
+
//# sourceMappingURL=App-DUmziQ17.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"App-DUmziQ17.js","sources":["../../admin/src/components/RelativeTime.tsx","../../shared/validation-schemas.ts","../../admin/src/components/ReleaseModal.tsx","../../admin/src/store/hooks.ts","../../admin/src/utils/api.ts","../../admin/src/pages/ReleasesPage.tsx","../../admin/src/pages/ReleaseDetailsPage.tsx","../../admin/src/pages/App.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Duration, intervalToDuration, isPast } from 'date-fns';\nimport { useIntl } from 'react-intl';\n\nconst intervals: Array<keyof Duration> = ['years', 'months', 'days', 'hours', 'minutes', 'seconds'];\n\ninterface CustomInterval {\n unit: keyof Duration;\n text: string;\n threshold: number;\n}\n\ninterface RelativeTimeProps extends React.ComponentPropsWithoutRef<'time'> {\n timestamp: Date;\n customIntervals?: CustomInterval[];\n}\n\n/**\n * Displays the relative time between a given timestamp and the current time.\n * You can display a custom message for given time intervals by passing an array of custom intervals.\n *\n * @example\n * ```jsx\n * <caption>Display \"last hour\" if the timestamp is less than an hour ago</caption>\n * <RelativeTime\n * timestamp={new Date('2021-01-01')}\n * customIntervals={[\n * { unit: 'hours', threshold: 1, text: 'last hour' },\n * ]}\n * ```\n */\nconst RelativeTime = React.forwardRef<HTMLTimeElement, RelativeTimeProps>(\n ({ timestamp, customIntervals = [], ...restProps }, forwardedRef) => {\n const { formatRelativeTime, formatDate, formatTime } = useIntl();\n\n /**\n * TODO: make this auto-update, like a clock.\n */\n const interval = intervalToDuration({\n start: timestamp,\n end: Date.now(),\n // see https://github.com/date-fns/date-fns/issues/2891 – No idea why it's all partial it returns it every time.\n }) as Required<Duration>;\n\n const unit = intervals.find((intervalUnit) => {\n return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);\n })!;\n\n const relativeTime = isPast(timestamp) ? -interval[unit] : interval[unit];\n\n // Display custom text if interval is less than the threshold\n const customInterval = customIntervals.find(\n (custom) => interval[custom.unit] < custom.threshold\n );\n\n const displayText = customInterval\n ? customInterval.text\n : formatRelativeTime(relativeTime, unit, { numeric: 'auto' });\n\n return (\n <time\n ref={forwardedRef}\n dateTime={timestamp.toISOString()}\n role=\"time\"\n title={`${formatDate(timestamp)} ${formatTime(timestamp)}`}\n {...restProps}\n >\n {displayText}\n </time>\n );\n }\n);\n\nexport { RelativeTime };\nexport type { CustomInterval, RelativeTimeProps };\n","import * as yup from 'yup';\n\nexport const RELEASE_SCHEMA = yup\n .object()\n .shape({\n name: yup.string().trim().required(),\n scheduledAt: yup.string().nullable(),\n isScheduled: yup.boolean().optional(),\n time: yup.string().when('isScheduled', {\n is: true,\n then: yup.string().trim().required(),\n otherwise: yup.string().nullable(),\n }),\n timezone: yup.string().when('isScheduled', {\n is: true,\n then: yup.string().required().nullable(),\n otherwise: yup.string().nullable(),\n }),\n date: yup.string().when('isScheduled', {\n is: true,\n then: yup.string().required().nullable(),\n otherwise: yup.string().nullable(),\n }),\n })\n .required()\n .noUnknown();\n","import * as React from 'react';\n\nimport {\n Button,\n ModalBody,\n ModalFooter,\n ModalLayout,\n ModalHeader,\n TextInput,\n Typography,\n Checkbox,\n Flex,\n Box,\n DatePicker,\n TimePicker,\n Combobox,\n ComboboxOption,\n Field,\n} from '@strapi/design-system';\nimport { formatISO } from 'date-fns';\nimport { utcToZonedTime, zonedTimeToUtc } from 'date-fns-tz';\nimport { Formik, Form, useFormikContext } from 'formik';\nimport { useIntl } from 'react-intl';\nimport { useLocation } from 'react-router-dom';\n\nimport { RELEASE_SCHEMA } from '../../../shared/validation-schemas';\nimport { pluginId } from '../pluginId';\nimport { getTimezoneOffset } from '../utils/time';\n\nexport interface FormValues {\n name: string;\n date?: string;\n time: string;\n timezone: string | null;\n isScheduled?: boolean;\n scheduledAt: Date | null;\n}\n\ninterface ReleaseModalProps {\n handleClose: () => void;\n handleSubmit: (values: FormValues) => void;\n isLoading?: boolean;\n initialValues: FormValues;\n}\n\nexport const ReleaseModal = ({\n handleClose,\n handleSubmit,\n initialValues,\n isLoading = false,\n}: ReleaseModalProps) => {\n const { formatMessage } = useIntl();\n const { pathname } = useLocation();\n const isCreatingRelease = pathname === `/plugins/${pluginId}`;\n // Set default first timezone from the list if no system timezone detected\n const { timezoneList, systemTimezone = { value: 'UTC+00:00-Africa/Abidjan ' } } = getTimezones(\n initialValues.scheduledAt ? new Date(initialValues.scheduledAt) : new Date()\n );\n\n /**\n * Generate scheduled time using selected date, time and timezone\n */\n const getScheduledTimestamp = (values: FormValues) => {\n const { date, time, timezone } = values;\n if (!date || !time || !timezone) return null;\n const timezoneWithoutOffset = timezone.split('&')[1];\n return zonedTimeToUtc(`${date} ${time}`, timezoneWithoutOffset);\n };\n\n /**\n * Get timezone with offset to show the selected value in the dropdown\n */\n const getTimezoneWithOffset = () => {\n const currentTimezone = timezoneList.find(\n (timezone) => timezone.value.split('&')[1] === initialValues.timezone\n );\n return currentTimezone?.value || systemTimezone.value;\n };\n\n return (\n <ModalLayout onClose={handleClose} labelledBy=\"title\">\n <ModalHeader>\n <Typography id=\"title\" fontWeight=\"bold\" textColor=\"neutral800\">\n {formatMessage(\n {\n id: 'content-releases.modal.title',\n defaultMessage:\n '{isCreatingRelease, select, true {New release} other {Edit release}}',\n },\n { isCreatingRelease: isCreatingRelease }\n )}\n </Typography>\n </ModalHeader>\n <Formik\n onSubmit={(values) => {\n handleSubmit({\n ...values,\n timezone: values.timezone ? values.timezone.split('&')[1] : null,\n scheduledAt: values.isScheduled ? getScheduledTimestamp(values) : null,\n });\n }}\n initialValues={{\n ...initialValues,\n timezone: initialValues.timezone ? getTimezoneWithOffset() : systemTimezone.value,\n }}\n validationSchema={RELEASE_SCHEMA}\n validateOnChange={false}\n >\n {({ values, errors, handleChange, setFieldValue }) => {\n return (\n <Form>\n <ModalBody>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={6}>\n <Field.Root name=\"name\" error={errors.name} required>\n <Field.Label>\n {formatMessage({\n id: 'content-releases.modal.form.input.label.release-name',\n defaultMessage: 'Name',\n })}\n </Field.Label>\n <TextInput value={values.name} onChange={handleChange} />\n <Field.Error />\n </Field.Root>\n <Box width=\"max-content\">\n <Checkbox\n name=\"isScheduled\"\n value={values.isScheduled}\n onChange={(event) => {\n setFieldValue('isScheduled', event.target.checked);\n if (!event.target.checked) {\n // Clear scheduling info from a release on unchecking schedule release, which reset scheduling info in DB\n setFieldValue('date', null);\n setFieldValue('time', '');\n setFieldValue('timezone', null);\n } else {\n // On ticking back schedule release date, time and timezone should be restored to the initial state\n setFieldValue('date', initialValues.date);\n setFieldValue('time', initialValues.time);\n setFieldValue(\n 'timezone',\n initialValues.timezone ?? systemTimezone?.value\n );\n }\n }}\n >\n <Typography\n textColor={values.isScheduled ? 'primary600' : 'neutral800'}\n fontWeight={values.isScheduled ? 'semiBold' : 'regular'}\n >\n {formatMessage({\n id: 'modal.form.input.label.schedule-release',\n defaultMessage: 'Schedule release',\n })}\n </Typography>\n </Checkbox>\n </Box>\n {values.isScheduled && (\n <>\n <Flex gap={4} alignItems=\"start\">\n <Box width=\"100%\">\n <Field.Root name=\"date\" error={errors.date} required>\n <Field.Label>\n {formatMessage({\n id: 'content-releases.modal.form.input.label.date',\n defaultMessage: 'Date',\n })}\n </Field.Label>\n <DatePicker\n onChange={(date) => {\n const isoFormatDate = date\n ? formatISO(date, { representation: 'date' })\n : null;\n setFieldValue('date', isoFormatDate);\n }}\n clearLabel={formatMessage({\n id: 'content-releases.modal.form.input.clearLabel',\n defaultMessage: 'Clear',\n })}\n onClear={() => {\n setFieldValue('date', null);\n }}\n value={values.date ? new Date(values.date) : new Date()}\n minDate={utcToZonedTime(new Date(), values.timezone.split('&')[1])}\n />\n <Field.Error />\n </Field.Root>\n </Box>\n <Box width=\"100%\">\n <Field.Root name=\"time\" error={errors.time} required>\n <Field.Label>\n {formatMessage({\n id: 'content-releases.modal.form.input.label.time',\n defaultMessage: 'Time',\n })}\n </Field.Label>\n <TimePicker\n onChange={(time) => {\n setFieldValue('time', time);\n }}\n clearLabel={formatMessage({\n id: 'content-releases.modal.form.input.clearLabel',\n defaultMessage: 'Clear',\n })}\n onClear={() => {\n setFieldValue('time', '');\n }}\n value={values.time || undefined}\n />\n <Field.Error />\n </Field.Root>\n </Box>\n </Flex>\n <TimezoneComponent timezoneOptions={timezoneList} />\n </>\n )}\n </Flex>\n </ModalBody>\n <ModalFooter\n startActions={\n <Button onClick={handleClose} variant=\"tertiary\" name=\"cancel\">\n {formatMessage({ id: 'cancel', defaultMessage: 'Cancel' })}\n </Button>\n }\n endActions={\n <Button name=\"submit\" loading={isLoading} type=\"submit\">\n {formatMessage(\n {\n id: 'content-releases.modal.form.button.submit',\n defaultMessage: '{isCreatingRelease, select, true {Continue} other {Save}}',\n },\n { isCreatingRelease: isCreatingRelease }\n )}\n </Button>\n }\n />\n </Form>\n );\n }}\n </Formik>\n </ModalLayout>\n );\n};\n\n/**\n * Generates the list of timezones and user's current timezone(system timezone)\n */\ninterface ITimezoneOption {\n offset: string;\n value: string;\n}\n\nconst getTimezones = (selectedDate: Date) => {\n const timezoneList: ITimezoneOption[] = Intl.supportedValuesOf('timeZone').map((timezone) => {\n // Timezone will be in the format GMT${OFFSET} where offset could be nothing,\n // a four digit string e.g. +05:00 or -08:00\n const utcOffset = getTimezoneOffset(timezone, selectedDate);\n\n // Offset and timezone are concatenated with '&', so to split and save the required timezone in DB\n return { offset: utcOffset, value: `${utcOffset}&${timezone}` } satisfies ITimezoneOption;\n });\n\n const systemTimezone = timezoneList.find(\n (timezone) => timezone.value.split('&')[1] === Intl.DateTimeFormat().resolvedOptions().timeZone\n );\n\n return { timezoneList, systemTimezone };\n};\n\nconst TimezoneComponent = ({ timezoneOptions }: { timezoneOptions: ITimezoneOption[] }) => {\n const { values, errors, setFieldValue } = useFormikContext<FormValues>();\n const { formatMessage } = useIntl();\n const [timezoneList, setTimezoneList] = React.useState<ITimezoneOption[]>(timezoneOptions);\n\n React.useEffect(() => {\n if (values.date) {\n // Update the timezone offset which varies with DST based on the date selected\n const { timezoneList } = getTimezones(new Date(values.date));\n setTimezoneList(timezoneList);\n\n const updatedTimezone =\n values.timezone &&\n timezoneList.find((tz) => tz.value.split('&')[1] === values.timezone!.split('&')[1]);\n if (updatedTimezone) {\n setFieldValue('timezone', updatedTimezone!.value);\n }\n }\n }, [setFieldValue, values.date, values.timezone]);\n\n return (\n <Field.Root name=\"timezone\" error={errors.timezone} required>\n <Field.Label>\n {formatMessage({\n id: 'content-releases.modal.form.input.label.timezone',\n defaultMessage: 'Timezone',\n })}\n </Field.Label>\n <Combobox\n autocomplete={{ type: 'list', filter: 'contains' }}\n value={values.timezone || undefined}\n textValue={values.timezone ? values.timezone.replace(/&/, ' ') : undefined} // textValue is required to show the updated DST timezone\n onChange={(timezone) => {\n setFieldValue('timezone', timezone);\n }}\n onTextValueChange={(timezone) => {\n setFieldValue('timezone', timezone);\n }}\n onClear={() => {\n setFieldValue('timezone', '');\n }}\n >\n {timezoneList.map((timezone) => (\n <ComboboxOption key={timezone.value} value={timezone.value}>\n {timezone.value.replace(/&/, ' ')}\n </ComboboxOption>\n ))}\n </Combobox>\n <Field.Error />\n </Field.Root>\n );\n};\n","import { Dispatch } from '@reduxjs/toolkit';\nimport { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';\n\nimport type { Store } from '@strapi/admin/strapi-admin';\n\ntype RootState = ReturnType<Store['getState']>;\n\nconst useTypedDispatch: () => Dispatch = useDispatch;\nconst useTypedSelector: TypedUseSelectorHook<RootState> = useSelector;\n\nexport { useTypedSelector, useTypedDispatch };\n","import { SerializedError } from '@reduxjs/toolkit';\nimport { ApiError } from '@strapi/admin/strapi-admin';\n\ntype BaseQueryError = ApiError | SerializedError;\n\nconst isBaseQueryError = (error?: BaseQueryError): error is BaseQueryError => {\n return typeof error !== 'undefined' && error.name !== undefined;\n};\n\nexport { isBaseQueryError };\nexport type { BaseQueryError };\n","import * as React from 'react';\n\nimport {\n Page,\n Pagination,\n useTracking,\n useAPIErrorHandler,\n useNotification,\n useQueryParams,\n useRBAC,\n isFetchError,\n Layouts,\n} from '@strapi/admin/strapi-admin';\nimport { useLicenseLimits } from '@strapi/admin/strapi-admin/ee';\nimport {\n Alert,\n Badge,\n Box,\n Button,\n Divider,\n EmptyStateLayout,\n Flex,\n Grid,\n GridItem,\n Main,\n Tab,\n TabGroup,\n TabPanel,\n TabPanels,\n Tabs,\n Typography,\n Link,\n} from '@strapi/design-system';\nimport { Plus } from '@strapi/icons';\nimport { EmptyDocuments } from '@strapi/icons/symbols';\nimport { useIntl } from 'react-intl';\nimport { useNavigate, useLocation, NavLink } from 'react-router-dom';\nimport { styled } from 'styled-components';\n\nimport { GetReleases, type Release } from '../../../shared/contracts/releases';\nimport { RelativeTime as BaseRelativeTime } from '../components/RelativeTime';\nimport { ReleaseModal, FormValues } from '../components/ReleaseModal';\nimport { PERMISSIONS } from '../constants';\nimport {\n useGetReleasesQuery,\n GetReleasesQueryParams,\n useCreateReleaseMutation,\n} from '../services/release';\n\n/* -------------------------------------------------------------------------------------------------\n * ReleasesGrid\n * -----------------------------------------------------------------------------------------------*/\ninterface ReleasesGridProps {\n sectionTitle: 'pending' | 'done';\n releases?: GetReleases.Response['data'];\n isError?: boolean;\n}\n\nconst LinkCard = styled(Link)`\n display: block;\n`;\n\nconst RelativeTime = styled(BaseRelativeTime)`\n display: inline-block;\n &::first-letter {\n text-transform: uppercase;\n }\n`;\n\nconst getBadgeProps = (status: Release['status']) => {\n let color;\n switch (status) {\n case 'ready':\n color = 'success';\n break;\n case 'blocked':\n color = 'warning';\n break;\n case 'failed':\n color = 'danger';\n break;\n case 'done':\n color = 'primary';\n break;\n case 'empty':\n default:\n color = 'neutral';\n }\n\n return {\n textColor: `${color}600`,\n backgroundColor: `${color}100`,\n borderColor: `${color}200`,\n };\n};\n\nconst ReleasesGrid = ({ sectionTitle, releases = [], isError = false }: ReleasesGridProps) => {\n const { formatMessage } = useIntl();\n\n if (isError) {\n return <Page.Error />;\n }\n\n if (releases?.length === 0) {\n return (\n <EmptyStateLayout\n content={formatMessage(\n {\n id: 'content-releases.page.Releases.tab.emptyEntries',\n defaultMessage: 'No releases',\n },\n {\n target: sectionTitle,\n }\n )}\n icon={<EmptyDocuments width=\"16rem\" />}\n />\n );\n }\n\n return (\n <Grid gap={4}>\n {releases.map(({ id, name, scheduledAt, status }) => (\n <GridItem col={3} s={6} xs={12} key={id}>\n <LinkCard tag={NavLink} to={`${id}`} isExternal={false}>\n <Flex\n direction=\"column\"\n justifyContent=\"space-between\"\n padding={4}\n hasRadius\n background=\"neutral0\"\n shadow=\"tableShadow\"\n height=\"100%\"\n width=\"100%\"\n alignItems=\"start\"\n gap={4}\n >\n <Flex direction=\"column\" alignItems=\"start\" gap={1}>\n <Typography tag=\"h3\" variant=\"delta\" fontWeight=\"bold\">\n {name}\n </Typography>\n <Typography variant=\"pi\" textColor=\"neutral600\">\n {scheduledAt ? (\n <RelativeTime timestamp={new Date(scheduledAt)} />\n ) : (\n formatMessage({\n id: 'content-releases.pages.Releases.not-scheduled',\n defaultMessage: 'Not scheduled',\n })\n )}\n </Typography>\n </Flex>\n <Badge {...getBadgeProps(status)}>{status}</Badge>\n </Flex>\n </LinkCard>\n </GridItem>\n ))}\n </Grid>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ReleasesPage\n * -----------------------------------------------------------------------------------------------*/\n\nconst StyledAlert = styled(Alert)`\n button {\n display: none;\n }\n p + div {\n margin-left: auto;\n }\n`;\n\nconst INITIAL_FORM_VALUES = {\n name: '',\n date: undefined,\n time: '',\n isScheduled: true,\n scheduledAt: null,\n timezone: null,\n} satisfies FormValues;\n\nconst ReleasesPage = () => {\n const tabRef = React.useRef<any>(null);\n const location = useLocation();\n const [releaseModalShown, setReleaseModalShown] = React.useState(false);\n const { toggleNotification } = useNotification();\n const { formatMessage } = useIntl();\n const navigate = useNavigate();\n const { formatAPIError } = useAPIErrorHandler();\n const [{ query }, setQuery] = useQueryParams<GetReleasesQueryParams>();\n const response = useGetReleasesQuery(query);\n const [createRelease, { isLoading: isSubmittingForm }] = useCreateReleaseMutation();\n const { getFeature } = useLicenseLimits();\n const { maximumReleases = 3 } = getFeature('cms-content-releases') as {\n maximumReleases: number;\n };\n const { trackUsage } = useTracking();\n const {\n allowedActions: { canCreate },\n } = useRBAC(PERMISSIONS);\n\n const { isLoading, isSuccess, isError } = response;\n const activeTab = response?.currentData?.meta?.activeTab || 'pending';\n const activeTabIndex = ['pending', 'done'].indexOf(activeTab);\n\n // Check if we have some errors and show a notification to the user to explain the error\n React.useEffect(() => {\n if (location?.state?.errors) {\n toggleNotification({\n type: 'danger',\n title: formatMessage({\n id: 'content-releases.pages.Releases.notification.error.title',\n defaultMessage: 'Your request could not be processed.',\n }),\n message: formatMessage({\n id: 'content-releases.pages.Releases.notification.error.message',\n defaultMessage: 'Please try again or open another release.',\n }),\n });\n navigate('', { replace: true, state: null });\n }\n }, [formatMessage, location?.state?.errors, navigate, toggleNotification]);\n\n // TODO: Replace this solution with v2 of the Design System\n // Check if the active tab index changes and call the handler of the ref to update the tab group component\n React.useEffect(() => {\n if (tabRef.current) {\n tabRef.current._handlers.setSelectedTabIndex(activeTabIndex);\n }\n }, [activeTabIndex]);\n\n const toggleAddReleaseModal = () => {\n setReleaseModalShown((prev) => !prev);\n };\n\n if (isLoading) {\n return <Page.Loading />;\n }\n\n const totalPendingReleases = (isSuccess && response.currentData?.meta?.pendingReleasesCount) || 0;\n const hasReachedMaximumPendingReleases = totalPendingReleases >= maximumReleases;\n\n const handleTabChange = (index: number) => {\n setQuery({\n ...query,\n page: 1,\n pageSize: response?.currentData?.meta?.pagination?.pageSize || 16,\n filters: {\n releasedAt: {\n $notNull: index === 0 ? false : true,\n },\n },\n });\n };\n\n const handleAddRelease = async ({ name, scheduledAt, timezone }: FormValues) => {\n const response = await createRelease({\n name,\n scheduledAt,\n timezone,\n });\n if ('data' in response) {\n // When the response returns an object with 'data', handle success\n toggleNotification({\n type: 'success',\n message: formatMessage({\n id: 'content-releases.modal.release-created-notification-success',\n defaultMessage: 'Release created.',\n }),\n });\n\n trackUsage('didCreateRelease');\n navigate(response.data.data.id.toString());\n } else if (isFetchError(response.error)) {\n // When the response returns an object with 'error', handle fetch error\n toggleNotification({\n type: 'danger',\n message: formatAPIError(response.error),\n });\n } else {\n // Otherwise, the response returns an object with 'error', handle a generic error\n toggleNotification({\n type: 'danger',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error occurred' }),\n });\n }\n };\n\n return (\n <Main aria-busy={isLoading}>\n <Layouts.Header\n title={formatMessage({\n id: 'content-releases.pages.Releases.title',\n defaultMessage: 'Releases',\n })}\n subtitle={formatMessage({\n id: 'content-releases.pages.Releases.header-subtitle',\n defaultMessage: 'Create and manage content updates',\n })}\n primaryAction={\n canCreate ? (\n <Button\n startIcon={<Plus />}\n onClick={toggleAddReleaseModal}\n disabled={hasReachedMaximumPendingReleases}\n >\n {formatMessage({\n id: 'content-releases.header.actions.add-release',\n defaultMessage: 'New release',\n })}\n </Button>\n ) : null\n }\n />\n <Layouts.Content>\n <>\n {hasReachedMaximumPendingReleases && (\n <StyledAlert\n marginBottom={6}\n action={\n <Link href=\"https://strapi.io/pricing-cloud\" isExternal>\n {formatMessage({\n id: 'content-releases.pages.Releases.max-limit-reached.action',\n defaultMessage: 'Explore plans',\n })}\n </Link>\n }\n title={formatMessage(\n {\n id: 'content-releases.pages.Releases.max-limit-reached.title',\n defaultMessage:\n 'You have reached the {number} pending {number, plural, one {release} other {releases}} limit.',\n },\n { number: maximumReleases }\n )}\n onClose={() => {}}\n closeLabel=\"\"\n >\n {formatMessage({\n id: 'content-releases.pages.Releases.max-limit-reached.message',\n defaultMessage: 'Upgrade to manage an unlimited number of releases.',\n })}\n </StyledAlert>\n )}\n <TabGroup\n label={formatMessage({\n id: 'content-releases.pages.Releases.tab-group.label',\n defaultMessage: 'Releases list',\n })}\n variant=\"simple\"\n initialSelectedTabIndex={activeTabIndex}\n onTabChange={handleTabChange}\n ref={tabRef}\n >\n <Box paddingBottom={8}>\n <Tabs>\n <Tab>\n {formatMessage(\n {\n id: 'content-releases.pages.Releases.tab.pending',\n defaultMessage: 'Pending ({count})',\n },\n {\n count: totalPendingReleases,\n }\n )}\n </Tab>\n <Tab>\n {formatMessage({\n id: 'content-releases.pages.Releases.tab.done',\n defaultMessage: 'Done',\n })}\n </Tab>\n </Tabs>\n <Divider />\n </Box>\n <TabPanels>\n {/* Pending releases */}\n <TabPanel>\n <ReleasesGrid\n sectionTitle=\"pending\"\n releases={response?.currentData?.data}\n isError={isError}\n />\n </TabPanel>\n {/* Done releases */}\n <TabPanel>\n <ReleasesGrid\n sectionTitle=\"done\"\n releases={response?.currentData?.data}\n isError={isError}\n />\n </TabPanel>\n </TabPanels>\n </TabGroup>\n <Pagination.Root\n {...response?.currentData?.meta?.pagination}\n defaultPageSize={response?.currentData?.meta?.pagination?.pageSize}\n >\n <Pagination.PageSize options={['8', '16', '32', '64']} />\n <Pagination.Links />\n </Pagination.Root>\n </>\n </Layouts.Content>\n {releaseModalShown && (\n <ReleaseModal\n handleClose={toggleAddReleaseModal}\n handleSubmit={handleAddRelease}\n isLoading={isSubmittingForm}\n initialValues={INITIAL_FORM_VALUES}\n />\n )}\n </Main>\n );\n};\n\nexport { ReleasesPage, getBadgeProps };\n","import * as React from 'react';\n\nimport {\n Page,\n Pagination,\n Table,\n BackButton,\n ConfirmDialog,\n useTracking,\n useAPIErrorHandler,\n useNotification,\n useQueryParams,\n useRBAC,\n isFetchError,\n useStrapiApp,\n Layouts,\n} from '@strapi/admin/strapi-admin';\nimport { unstable_useDocument } from '@strapi/content-manager/strapi-admin';\nimport {\n Button,\n Flex,\n Main,\n Tr,\n Td,\n Typography,\n Badge,\n SingleSelect,\n SingleSelectOption,\n Tooltip,\n EmptyStateLayout,\n LinkButton,\n Menu,\n} from '@strapi/design-system';\nimport { CheckCircle, More, Pencil, Trash, CrossCircle } from '@strapi/icons';\nimport { EmptyDocuments } from '@strapi/icons/symbols';\nimport format from 'date-fns/format';\nimport { utcToZonedTime } from 'date-fns-tz';\nimport { useIntl } from 'react-intl';\nimport { useParams, useNavigate, Link as ReactRouterLink, Navigate } from 'react-router-dom';\nimport { styled } from 'styled-components';\n\nimport { RelativeTime } from '../components/RelativeTime';\nimport { ReleaseActionMenu } from '../components/ReleaseActionMenu';\nimport { ReleaseActionOptions } from '../components/ReleaseActionOptions';\nimport { ReleaseModal, FormValues } from '../components/ReleaseModal';\nimport { PERMISSIONS } from '../constants';\nimport {\n GetReleaseActionsQueryParams,\n useGetReleaseActionsQuery,\n useGetReleaseQuery,\n useUpdateReleaseMutation,\n useUpdateReleaseActionMutation,\n usePublishReleaseMutation,\n useDeleteReleaseMutation,\n releaseApi,\n} from '../services/release';\nimport { useTypedDispatch } from '../store/hooks';\nimport { isBaseQueryError } from '../utils/api';\nimport { getTimezoneOffset } from '../utils/time';\n\nimport { getBadgeProps } from './ReleasesPage';\n\nimport type {\n ReleaseAction,\n ReleaseActionGroupBy,\n ReleaseActionEntry,\n} from '../../../shared/contracts/release-actions';\nimport type { Struct, Internal } from '@strapi/types';\n\n/* -------------------------------------------------------------------------------------------------\n * ReleaseDetailsLayout\n * -----------------------------------------------------------------------------------------------*/\nconst ReleaseInfoWrapper = styled(Flex)`\n align-self: stretch;\n border-bottom-right-radius: ${({ theme }) => theme.borderRadius};\n border-bottom-left-radius: ${({ theme }) => theme.borderRadius};\n border-top: 1px solid ${({ theme }) => theme.colors.neutral150};\n`;\n\nconst StyledMenuItem = styled(Menu.Item)<{\n disabled?: boolean;\n $variant?: 'neutral' | 'danger';\n}>`\n svg path {\n fill: ${({ theme, disabled }) => disabled && theme.colors.neutral500};\n }\n span {\n color: ${({ theme, disabled }) => disabled && theme.colors.neutral500};\n }\n\n &:hover {\n background: ${({ theme, $variant = 'neutral' }) => theme.colors[`${$variant}100`]};\n }\n`;\n\nconst PencilIcon = styled(Pencil)`\n width: ${({ theme }) => theme.spaces[3]};\n height: ${({ theme }) => theme.spaces[3]};\n path {\n fill: ${({ theme }) => theme.colors.neutral600};\n }\n`;\n\nconst TrashIcon = styled(Trash)`\n width: ${({ theme }) => theme.spaces[3]};\n height: ${({ theme }) => theme.spaces[3]};\n path {\n fill: ${({ theme }) => theme.colors.danger600};\n }\n`;\n\nconst TypographyMaxWidth = styled(Typography)`\n max-width: 300px;\n`;\n\ninterface EntryValidationTextProps {\n action: ReleaseAction['type'];\n schema?: Struct.ContentTypeSchema;\n components: { [key: Internal.UID.Component]: Struct.ComponentSchema };\n entry: ReleaseActionEntry;\n}\n\nconst EntryValidationText = ({ action, schema, entry }: EntryValidationTextProps) => {\n const { formatMessage } = useIntl();\n const { validate } = unstable_useDocument(\n {\n collectionType: schema?.kind ?? '',\n model: schema?.uid ?? '',\n },\n {\n skip: !schema,\n }\n );\n\n const errors = validate(entry) ?? {};\n\n if (Object.keys(errors).length > 0) {\n const validationErrorsMessages = Object.entries(errors)\n .map(([key, value]) =>\n formatMessage(\n // @ts-expect-error – TODO: fix this will better checks\n { id: `${value.id}.withField`, defaultMessage: value.defaultMessage },\n { field: key }\n )\n )\n .join(' ');\n\n return (\n <Flex gap={2}>\n <CrossCircle fill=\"danger600\" />\n <Tooltip description={validationErrorsMessages}>\n <TypographyMaxWidth textColor=\"danger600\" variant=\"omega\" fontWeight=\"semiBold\" ellipsis>\n {validationErrorsMessages}\n </TypographyMaxWidth>\n </Tooltip>\n </Flex>\n );\n }\n\n if (action == 'publish') {\n return (\n <Flex gap={2}>\n <CheckCircle fill=\"success600\" />\n {entry.publishedAt ? (\n <Typography textColor=\"success600\" fontWeight=\"bold\">\n {formatMessage({\n id: 'content-releases.pages.ReleaseDetails.entry-validation.already-published',\n defaultMessage: 'Already published',\n })}\n </Typography>\n ) : (\n <Typography>\n {formatMessage({\n id: 'content-releases.pages.ReleaseDetails.entry-validation.ready-to-publish',\n defaultMessage: 'Ready to publish',\n })}\n </Typography>\n )}\n </Flex>\n );\n }\n\n return (\n <Flex gap={2}>\n <CheckCircle fill=\"success600\" />\n {!entry.publishedAt ? (\n <Typography textColor=\"success600\" fontWeight=\"bold\">\n {formatMessage({\n id: 'content-releases.pages.ReleaseDetails.entry-validation.already-unpublished',\n defaultMessage: 'Already unpublished',\n })}\n </Typography>\n ) : (\n <Typography>\n {formatMessage({\n id: 'content-releases.pages.ReleaseDetails.entry-validation.ready-to-unpublish',\n defaultMessage: 'Ready to unpublish',\n })}\n </Typography>\n )}\n </Flex>\n );\n};\ninterface ReleaseDetailsLayoutProps {\n toggleEditReleaseModal: () => void;\n toggleWarningSubmit: () => void;\n children: React.ReactNode;\n}\n\nconst ReleaseDetailsLayout = ({\n toggleEditReleaseModal,\n toggleWarningSubmit,\n children,\n}: ReleaseDetailsLayoutProps) => {\n const { formatMessage, formatDate, formatTime } = useIntl();\n const { releaseId } = useParams<{ releaseId: string }>();\n const {\n data,\n isLoading: isLoadingDetails,\n error,\n } = useGetReleaseQuery(\n { id: releaseId! },\n {\n skip: !releaseId,\n }\n );\n const [publishRelease, { isLoading: isPublishing }] = usePublishReleaseMutation();\n const { toggleNotification } = useNotification();\n const { formatAPIError } = useAPIErrorHandler();\n const { allowedActions } = useRBAC(PERMISSIONS);\n const { canUpdate, canDelete, canPublish } = allowedActions;\n const dispatch = useTypedDispatch();\n const { trackUsage } = useTracking();\n\n const release = data?.data;\n\n const handlePublishRelease = (id: string) => async () => {\n const response = await publishRelease({ id });\n\n if ('data' in response) {\n // When the response returns an object with 'data', handle success\n toggleNotification({\n type: 'success',\n message: formatMessage({\n id: 'content-releases.pages.ReleaseDetails.publish-notification-success',\n defaultMessage: 'Release was published successfully.',\n }),\n });\n\n const { totalEntries, totalPublishedEntries, totalUnpublishedEntries } = response.data.meta;\n\n trackUsage('didPublishRelease', {\n totalEntries,\n totalPublishedEntries,\n totalUnpublishedEntries,\n });\n } else if (isFetchError(response.error)) {\n // When the response returns an object with 'error', handle fetch error\n toggleNotification({\n type: 'danger',\n message: formatAPIError(response.error),\n });\n } else {\n // Otherwise, the response returns an object with 'error', handle a generic error\n toggleNotification({\n type: 'danger',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error occurred' }),\n });\n }\n };\n\n const handleRefresh = () => {\n dispatch(\n releaseApi.util.invalidateTags([\n { type: 'ReleaseAction', id: 'LIST' },\n { type: 'Release', id: releaseId },\n ])\n );\n };\n\n const getCreatedByUser = () => {\n if (!release?.createdBy) {\n return null;\n }\n\n // Favor the username\n if (release.createdBy.username) {\n return release.createdBy.username;\n }\n\n // Firstname may not exist if created with SSO\n if (release.createdBy.firstname) {\n return `${release.createdBy.firstname} ${release.createdBy.lastname || ''}`.trim();\n }\n\n // All users must have at least an email\n return release.createdBy.email;\n };\n\n if (isLoadingDetails) {\n return <Page.Loading />;\n }\n\n if ((isBaseQueryError(error) && 'code' in error) || !release) {\n return (\n <Navigate\n to=\"..\"\n state={{\n errors: [\n {\n // @ts-expect-error – TODO: fix this weird error flow\n code: error?.code,\n },\n ],\n }}\n />\n );\n }\n\n const totalEntries = release.actions.meta.count || 0;\n const hasCreatedByUser = Boolean(getCreatedByUser());\n\n const isScheduled = release.scheduledAt && release.timezone;\n const numberOfEntriesText = formatMessage(\n {\n id: 'content-releases.pages.Details.header-subtitle',\n defaultMessage: '{number, plural, =0 {No entries} one {# entry} other {# entries}}',\n },\n { number: totalEntries }\n );\n const scheduledText = isScheduled\n ? formatMessage(\n {\n id: 'content-releases.pages.ReleaseDetails.header-subtitle.scheduled',\n defaultMessage: 'Scheduled for {date} at {time} ({offset})',\n },\n {\n date: formatDate(new Date(release.scheduledAt!), {\n weekday: 'long',\n day: 'numeric',\n month: 'long',\n year: 'numeric',\n timeZone: release.timezone!,\n }),\n time: formatTime(new Date(release.scheduledAt!), {\n timeZone: release.timezone!,\n hourCycle: 'h23',\n }),\n offset: getTimezoneOffset(release.timezone!, new Date(release.scheduledAt!)),\n }\n )\n : '';\n\n return (\n <Main aria-busy={isLoadingDetails}>\n <Layouts.Header\n title={release.name}\n subtitle={\n <Flex gap={2} lineHeight={6}>\n <Typography textColor=\"neutral600\" variant=\"epsilon\">\n {numberOfEntriesText + (isScheduled ? ` - ${scheduledText}` : '')}\n </Typography>\n <Badge {...getBadgeProps(release.status)}>{release.status}</Badge>\n </Flex>\n }\n navigationAction={<BackButton />}\n primaryAction={\n !release.releasedAt && (\n <Flex gap={2}>\n <Menu.Root>\n {/*\n TODO Fix in the DS\n - tag={IconButton} has TS error: Property 'icon' does not exist on type 'IntrinsicAttributes & TriggerProps & RefAttributes<HTMLButtonElement>'\n - The Icon doesn't actually show unless you hack it with some padding...and it's still a little strange\n */}\n <Menu.Trigger\n paddingLeft={2}\n paddingRight={2}\n aria-label={formatMessage({\n id: 'content-releases.header.actions.open-release-actions',\n defaultMessage: 'Release edit and delete menu',\n })}\n variant=\"tertiary\"\n >\n <More />\n </Menu.Trigger>\n {/*\n TODO: Using Menu instead of SimpleMenu mainly because there is no positioning provided from the DS,\n Refactor this once fixed in the DS\n */}\n <Menu.Content top={1} popoverPlacement=\"bottom-end\" maxHeight={undefined}>\n <Flex\n alignItems=\"center\"\n justifyContent=\"center\"\n direction=\"column\"\n padding={1}\n width=\"100%\"\n >\n <StyledMenuItem disabled={!canUpdate} onSelect={toggleEditReleaseModal}>\n <Flex alignItems=\"center\" gap={2} hasRadius width=\"100%\">\n <PencilIcon />\n <Typography ellipsis>\n {formatMessage({\n id: 'content-releases.header.actions.edit',\n defaultMessage: 'Edit',\n })}\n </Typography>\n </Flex>\n </StyledMenuItem>\n <StyledMenuItem\n disabled={!canDelete}\n onSelect={toggleWarningSubmit}\n $variant=\"danger\"\n >\n <Flex alignItems=\"center\" gap={2} hasRadius width=\"100%\">\n <TrashIcon />\n <Typography ellipsis textColor=\"danger600\">\n {formatMessage({\n id: 'content-releases.header.actions.delete',\n defaultMessage: 'Delete',\n })}\n </Typography>\n </Flex>\n </StyledMenuItem>\n </Flex>\n <ReleaseInfoWrapper\n direction=\"column\"\n justifyContent=\"center\"\n alignItems=\"flex-start\"\n gap={1}\n padding={5}\n >\n <Typography variant=\"pi\" fontWeight=\"bold\">\n {formatMessage({\n id: 'content-releases.header.actions.created',\n defaultMessage: 'Created',\n })}\n </Typography>\n <Typography variant=\"pi\" color=\"neutral300\">\n <RelativeTime timestamp={new Date(release.createdAt)} />\n {formatMessage(\n {\n id: 'content-releases.header.actions.created.description',\n defaultMessage:\n '{hasCreatedByUser, select, true { by {createdBy}} other { by deleted user}}',\n },\n { createdBy: getCreatedByUser(), hasCreatedByUser }\n )}\n </Typography>\n </ReleaseInfoWrapper>\n </Menu.Content>\n </Menu.Root>\n <Button size=\"S\" variant=\"tertiary\" onClick={handleRefresh}>\n {formatMessage({\n id: 'content-releases.header.actions.refresh',\n defaultMessage: 'Refresh',\n })}\n </Button>\n {canPublish ? (\n <Button\n size=\"S\"\n variant=\"default\"\n onClick={handlePublishRelease(release.id.toString())}\n loading={isPublishing}\n disabled={release.actions.meta.count === 0}\n >\n {formatMessage({\n id: 'content-releases.header.actions.publish',\n defaultMessage: 'Publish',\n })}\n </Button>\n ) : null}\n </Flex>\n )\n }\n />\n {children}\n </Main>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ReleaseDetailsBody\n * -----------------------------------------------------------------------------------------------*/\nconst GROUP_BY_OPTIONS = ['contentType', 'locale', 'action'] as const;\nconst GROUP_BY_OPTIONS_NO_LOCALE = ['contentType', 'action'] as const;\nconst getGroupByOptionLabel = (value: (typeof GROUP_BY_OPTIONS)[number]) => {\n if (value === 'locale') {\n return {\n id: 'content-releases.pages.ReleaseDetails.groupBy.option.locales',\n defaultMessage: 'Locales',\n };\n }\n\n if (value === 'action') {\n return {\n id: 'content-releases.pages.ReleaseDetails.groupBy.option.actions',\n defaultMessage: 'Actions',\n };\n }\n\n return {\n id: 'content-releases.pages.ReleaseDetails.groupBy.option.content-type',\n defaultMessage: 'Content-Types',\n };\n};\n\ninterface ReleaseDetailsBodyProps {\n releaseId: string;\n}\n\nconst ReleaseDetailsBody = ({ releaseId }: ReleaseDetailsBodyProps) => {\n const { formatMessage } = useIntl();\n const [{ query }, setQuery] = useQueryParams<GetReleaseActionsQueryParams>();\n const { toggleNotification } = useNotification();\n const { formatAPIError } = useAPIErrorHandler();\n const {\n data: releaseData,\n isLoading: isReleaseLoading,\n error: releaseError,\n } = useGetReleaseQuery({ id: releaseId });\n const {\n allowedActions: { canUpdate },\n } = useRBAC(PERMISSIONS);\n const runHookWaterfall = useStrapiApp('ReleaseDetailsPage', (state) => state.runHookWaterfall);\n\n // TODO: Migrated displayedHeader to v5\n const { hasI18nEnabled }: { displayedHeaders: any; hasI18nEnabled: boolean } = runHookWaterfall(\n 'ContentReleases/pages/ReleaseDetails/add-locale-in-releases',\n {\n displayedHeaders: {\n label: formatMessage({\n id: 'content-releases.page.ReleaseDetails.table.header.label.locale',\n defaultMessage: 'locale',\n }),\n name: 'locale',\n },\n hasI18nEnabled: false,\n }\n );\n\n const release = releaseData?.data;\n const selectedGroupBy = query?.groupBy || 'contentType';\n\n const {\n isLoading,\n isFetching,\n isError,\n data,\n error: releaseActionsError,\n } = useGetReleaseActionsQuery({\n ...query,\n releaseId,\n });\n\n const [updateReleaseAction] = useUpdateReleaseActionMutation();\n\n const handleChangeType = async (\n e: React.ChangeEvent<HTMLInputElement>,\n actionId: ReleaseAction['id'],\n actionPath: [string, number]\n ) => {\n const response = await updateReleaseAction({\n params: {\n releaseId,\n actionId,\n },\n body: {\n type: e.target.value as ReleaseAction['type'],\n },\n query, // We are passing the query params to make optimistic updates\n actionPath, // We are passing the action path to found the position in the cache of the action for optimistic updates\n });\n\n if ('error' in response) {\n if (isFetchError(response.error)) {\n // When the response returns an object with 'error', handle fetch error\n toggleNotification({\n type: 'danger',\n message: formatAPIError(response.error),\n });\n } else {\n // Otherwise, the response returns an object with 'error', handle a generic error\n toggleNotification({\n type: 'danger',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error occurred' }),\n });\n }\n }\n };\n\n if (isLoading || isReleaseLoading) {\n return <Page.Loading />;\n }\n\n const releaseActions = data?.data;\n const releaseMeta = data?.meta;\n const contentTypes = releaseMeta?.contentTypes || {};\n const components = releaseMeta?.components || {};\n\n if (isBaseQueryError(releaseError) || !release) {\n const errorsArray = [];\n if (releaseError && 'code' in releaseError) {\n errorsArray.push({\n code: releaseError.code,\n });\n }\n if (releaseActionsError && 'code' in releaseActionsError) {\n errorsArray.push({\n code: releaseActionsError.code,\n });\n }\n return (\n <Navigate\n to=\"..\"\n state={{\n errors: errorsArray,\n }}\n />\n );\n }\n\n if (isError || !releaseActions) {\n return <Page.Error />;\n }\n\n if (Object.keys(releaseActions).length === 0) {\n return (\n <Layouts.Content>\n <EmptyStateLayout\n action={\n <LinkButton\n tag={ReactRouterLink}\n to={{\n pathname: '/content-manager',\n }}\n style={{ textDecoration: 'none' }}\n variant=\"secondary\"\n >\n {formatMessage({\n id: 'content-releases.page.Details.button.openContentManager',\n defaultMessage: 'Open the Content Manager',\n })}\n </LinkButton>\n }\n icon={<EmptyDocuments width=\"16rem\" />}\n content={formatMessage({\n id: 'content-releases.pages.Details.tab.emptyEntries',\n defaultMessage:\n 'This release is empty. Open the Content Manager, select an entry and add it to the release.',\n })}\n />\n </Layouts.Content>\n );\n }\n\n const groupByLabel = formatMessage({\n id: 'content-releases.pages.ReleaseDetails.groupBy.aria-label',\n defaultMessage: 'Group by',\n });\n const headers = [\n // ...displayedHeaders,\n {\n label: formatMessage({\n id: 'content-releases.page.ReleaseDetails.table.header.label.name',\n defaultMessage: 'name',\n }),\n name: 'name',\n },\n {\n label: formatMessage({\n id: 'content-releases.page.ReleaseDetails.table.header.label.content-type',\n defaultMessage: 'content-type',\n }),\n name: 'content-type',\n },\n {\n label: formatMessage({\n id: 'content-releases.page.ReleaseDetails.table.header.label.action',\n defaultMessage: 'action',\n }),\n name: 'action',\n },\n ...(!release.releasedAt\n ? [\n {\n label: formatMessage({\n id: 'content-releases.page.ReleaseDetails.table.header.label.status',\n defaultMessage: 'status',\n }),\n name: 'status',\n },\n ]\n : []),\n ];\n\n const options = hasI18nEnabled ? GROUP_BY_OPTIONS : GROUP_BY_OPTIONS_NO_LOCALE;\n\n return (\n <Layouts.Content>\n <Flex gap={8} direction=\"column\" alignItems=\"stretch\">\n <Flex>\n <SingleSelect\n placeholder={groupByLabel}\n aria-label={groupByLabel}\n customizeContent={(value) =>\n formatMessage(\n {\n id: `content-releases.pages.ReleaseDetails.groupBy.label`,\n defaultMessage: `Group by {groupBy}`,\n },\n {\n groupBy: value,\n }\n )\n }\n value={formatMessage(getGroupByOptionLabel(selectedGroupBy))}\n onChange={(value) => setQuery({ groupBy: value as ReleaseActionGroupBy })}\n >\n {options.map((option) => (\n <SingleSelectOption key={option} value={option}>\n {formatMessage(getGroupByOptionLabel(option))}\n </SingleSelectOption>\n ))}\n </SingleSelect>\n </Flex>\n {Object.keys(releaseActions).map((key) => (\n <Flex key={`releases-group-${key}`} gap={4} direction=\"column\" alignItems=\"stretch\">\n <Flex role=\"separator\" aria-label={key}>\n <Badge>{key}</Badge>\n </Flex>\n <Table.Root\n rows={releaseActions[key].map((item) => ({\n ...item,\n id: Number(item.entry.id),\n }))}\n headers={headers}\n isLoading={isLoading || isFetching}\n >\n <Table.Content>\n <Table.Head>\n {headers.map((header) => (\n <Table.HeaderCell key={header.name} {...header} />\n ))}\n </Table.Head>\n <Table.Loading />\n <Table.Body>\n {releaseActions[key].map(\n ({ id, contentType, locale, type, entry }, actionIndex) => (\n <Tr key={id}>\n <Td width=\"25%\" maxWidth=\"200px\">\n <Typography ellipsis>{`${\n contentType.mainFieldValue || entry.id\n }`}</Typography>\n </Td>\n {hasI18nEnabled && (\n <Td width=\"10%\">\n <Typography>{`${locale?.name ? locale.name : '-'}`}</Typography>\n </Td>\n )}\n\n <Td width=\"10%\">\n <Typography>{contentType.displayName || ''}</Typography>\n </Td>\n <Td width=\"20%\">\n {release.releasedAt ? (\n <Typography>\n {formatMessage(\n {\n id: 'content-releases.page.ReleaseDetails.table.action-published',\n defaultMessage:\n 'This entry was <b>{isPublish, select, true {published} other {unpublished}}</b>.',\n },\n {\n isPublish: type === 'publish',\n b: (children: React.ReactNode) => (\n <Typography fontWeight=\"bold\">{children}</Typography>\n ),\n }\n )}\n </Typography>\n ) : (\n <ReleaseActionOptions\n selected={type}\n handleChange={(e) => handleChangeType(e, id, [key, actionIndex])}\n name={`release-action-${id}-type`}\n disabled={!canUpdate}\n />\n )}\n </Td>\n {!release.releasedAt && (\n <>\n <Td width=\"20%\" minWidth=\"200px\">\n <EntryValidationText\n action={type}\n schema={contentTypes?.[contentType.uid]}\n components={components}\n entry={entry}\n />\n </Td>\n <Td>\n <Flex justifyContent=\"flex-end\">\n <ReleaseActionMenu.Root>\n <ReleaseActionMenu.ReleaseActionEntryLinkItem\n contentTypeUid={contentType.uid}\n entryId={entry.id}\n locale={locale?.code}\n />\n <ReleaseActionMenu.DeleteReleaseActionItem\n releaseId={release.id}\n actionId={id}\n />\n </ReleaseActionMenu.Root>\n </Flex>\n </Td>\n </>\n )}\n </Tr>\n )\n )}\n </Table.Body>\n </Table.Content>\n </Table.Root>\n </Flex>\n ))}\n <Pagination.Root\n {...releaseMeta?.pagination}\n defaultPageSize={releaseMeta?.pagination?.pageSize}\n >\n <Pagination.PageSize />\n <Pagination.Links />\n </Pagination.Root>\n </Flex>\n </Layouts.Content>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ReleaseDetailsPage\n * -----------------------------------------------------------------------------------------------*/\nconst ReleaseDetailsPage = () => {\n const { formatMessage } = useIntl();\n const { releaseId } = useParams<{ releaseId: string }>();\n const { toggleNotification } = useNotification();\n const { formatAPIError } = useAPIErrorHandler();\n const navigate = useNavigate();\n const [releaseModalShown, setReleaseModalShown] = React.useState(false);\n const [showWarningSubmit, setWarningSubmit] = React.useState(false);\n\n const {\n isLoading: isLoadingDetails,\n data,\n isSuccess: isSuccessDetails,\n } = useGetReleaseQuery(\n { id: releaseId! },\n {\n skip: !releaseId,\n }\n );\n const [updateRelease, { isLoading: isSubmittingForm }] = useUpdateReleaseMutation();\n const [deleteRelease] = useDeleteReleaseMutation();\n\n const toggleEditReleaseModal = () => {\n setReleaseModalShown((prev) => !prev);\n };\n\n const toggleWarningSubmit = () => setWarningSubmit((prevState) => !prevState);\n\n if (isLoadingDetails) {\n return (\n <ReleaseDetailsLayout\n toggleEditReleaseModal={toggleEditReleaseModal}\n toggleWarningSubmit={toggleWarningSubmit}\n >\n <Page.Loading />\n </ReleaseDetailsLayout>\n );\n }\n\n if (!releaseId) {\n return <Navigate to=\"..\" />;\n }\n\n const releaseData = (isSuccessDetails && data?.data) || null;\n\n const title = releaseData?.name || '';\n const timezone = releaseData?.timezone ?? null;\n const scheduledAt =\n releaseData?.scheduledAt && timezone ? utcToZonedTime(releaseData.scheduledAt, timezone) : null;\n // Just get the date and time to display without considering updated timezone time\n const date = scheduledAt ? format(scheduledAt, 'yyyy-MM-dd') : undefined;\n const time = scheduledAt ? format(scheduledAt, 'HH:mm') : '';\n\n const handleEditRelease = async (values: FormValues) => {\n const response = await updateRelease({\n id: releaseId,\n name: values.name,\n scheduledAt: values.scheduledAt,\n timezone: values.timezone,\n });\n\n if ('data' in response) {\n // When the response returns an object with 'data', handle success\n toggleNotification({\n type: 'success',\n message: formatMessage({\n id: 'content-releases.modal.release-updated-notification-success',\n defaultMessage: 'Release updated.',\n }),\n });\n toggleEditReleaseModal();\n } else if (isFetchError(response.error)) {\n // When the response returns an object with 'error', handle fetch error\n toggleNotification({\n type: 'danger',\n message: formatAPIError(response.error),\n });\n } else {\n // Otherwise, the response returns an object with 'error', handle a generic error\n toggleNotification({\n type: 'danger',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error occurred' }),\n });\n }\n };\n\n const handleDeleteRelease = async () => {\n const response = await deleteRelease({\n id: releaseId,\n });\n\n if ('data' in response) {\n navigate('..');\n } else if (isFetchError(response.error)) {\n // When the response returns an object with 'error', handle fetch error\n toggleNotification({\n type: 'danger',\n message: formatAPIError(response.error),\n });\n } else {\n // Otherwise, the response returns an object with 'error', handle a generic error\n toggleNotification({\n type: 'danger',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error occurred' }),\n });\n }\n };\n\n return (\n <ReleaseDetailsLayout\n toggleEditReleaseModal={toggleEditReleaseModal}\n toggleWarningSubmit={toggleWarningSubmit}\n >\n <ReleaseDetailsBody releaseId={releaseId} />\n {releaseModalShown && (\n <ReleaseModal\n handleClose={toggleEditReleaseModal}\n handleSubmit={handleEditRelease}\n isLoading={isLoadingDetails || isSubmittingForm}\n initialValues={{\n name: title || '',\n scheduledAt,\n date,\n time,\n isScheduled: Boolean(scheduledAt),\n timezone,\n }}\n />\n )}\n <ConfirmDialog\n isOpen={showWarningSubmit}\n onClose={toggleWarningSubmit}\n onConfirm={handleDeleteRelease}\n >\n {formatMessage({\n id: 'content-releases.dialog.confirmation-message',\n defaultMessage: 'Are you sure you want to delete this release?',\n })}\n </ConfirmDialog>\n </ReleaseDetailsLayout>\n );\n};\n\nexport { ReleaseDetailsPage };\n","import { Page } from '@strapi/admin/strapi-admin';\nimport { Route, Routes } from 'react-router-dom';\n\nimport { PERMISSIONS } from '../constants';\n\nimport { ReleaseDetailsPage } from './ReleaseDetailsPage';\nimport { ReleasesPage } from './ReleasesPage';\n\nexport const App = () => {\n return (\n <Page.Protect permissions={PERMISSIONS.main}>\n <Routes>\n <Route index element={<ReleasesPage />} />\n <Route path={':releaseId'} element={<ReleaseDetailsPage />} />\n </Routes>\n </Page.Protect>\n );\n};\n"],"names":["RelativeTime","React","useIntl","intervalToDuration","isPast","jsx","yup","useLocation","pluginId","zonedTimeToUtc","jsxs","ModalLayout","ModalHeader","Typography","Formik","Form","ModalBody","Flex","Field","TextInput","Box","Checkbox","Fragment","DatePicker","formatISO","utcToZonedTime","TimePicker","ModalFooter","Button","getTimezoneOffset","useFormikContext","timezoneList","Combobox","ComboboxOption","useDispatch","styled","Link","BaseRelativeTime","Page","EmptyStateLayout","EmptyDocuments","Grid","GridItem","NavLink","Badge","Alert","useNotification","useNavigate","useAPIErrorHandler","useQueryParams","useGetReleasesQuery","useCreateReleaseMutation","useLicenseLimits","useTracking","useRBAC","PERMISSIONS","index","response","isFetchError","Main","Layouts","Plus","TabGroup","Tabs","Tab","Divider","TabPanels","TabPanel","Pagination","Menu","Pencil","Trash","unstable_useDocument","CrossCircle","Tooltip","CheckCircle","useParams","useGetReleaseQuery","usePublishReleaseMutation","totalEntries","releaseApi","Navigate","BackButton","More","useStrapiApp","useGetReleaseActionsQuery","useUpdateReleaseActionMutation","LinkButton","ReactRouterLink","SingleSelect","SingleSelectOption","Table","Tr","Td","ReleaseActionOptions","ReleaseActionMenu","useUpdateReleaseMutation","useDeleteReleaseMutation","format","ConfirmDialog","Routes","Route"],"mappings":"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"}
|