@strapi/content-releases 0.0.0-next.aa7c7ec6724534e157d8a23fe85ee8318dabbf37 → 0.0.0-next.b6d552f6e63dec5627cb8611ab2adcb8244359be
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-pspKUC-W.js → App-5G7GEzBM.js} +292 -69
- package/dist/_chunks/App-5G7GEzBM.js.map +1 -0
- package/dist/_chunks/{App-8FCxPK8-.mjs → App-WMxox0mk.mjs} +293 -71
- package/dist/_chunks/App-WMxox0mk.mjs.map +1 -0
- package/dist/_chunks/PurchaseContentReleases-Clm0iACO.mjs +51 -0
- package/dist/_chunks/PurchaseContentReleases-Clm0iACO.mjs.map +1 -0
- package/dist/_chunks/PurchaseContentReleases-YhAPgpG9.js +51 -0
- package/dist/_chunks/PurchaseContentReleases-YhAPgpG9.js.map +1 -0
- package/dist/_chunks/{en-m9eTk4UF.mjs → en-WuuhP6Bn.mjs} +15 -4
- package/dist/_chunks/en-WuuhP6Bn.mjs.map +1 -0
- package/dist/_chunks/{en-r9YocBH0.js → en-gcJJ5htG.js} +15 -4
- package/dist/_chunks/en-gcJJ5htG.js.map +1 -0
- package/dist/_chunks/{index-8aK7GzI5.mjs → index-BZ8RPGiV.mjs} +91 -14
- package/dist/_chunks/index-BZ8RPGiV.mjs.map +1 -0
- package/dist/_chunks/{index-nGaPcY9m.js → index-pQ3hnZJy.js} +87 -10
- package/dist/_chunks/index-pQ3hnZJy.js.map +1 -0
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +2 -2
- package/dist/server/index.js +769 -431
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +768 -431
- package/dist/server/index.mjs.map +1 -1
- package/package.json +13 -11
- package/dist/_chunks/App-8FCxPK8-.mjs.map +0 -1
- package/dist/_chunks/App-pspKUC-W.js.map +0 -1
- package/dist/_chunks/en-m9eTk4UF.mjs.map +0 -1
- package/dist/_chunks/en-r9YocBH0.js.map +0 -1
- package/dist/_chunks/index-8aK7GzI5.mjs.map +0 -1
- package/dist/_chunks/index-nGaPcY9m.js.map +0 -1
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useNotification, useAPIErrorHandler, LoadingIndicatorPage, ConfirmDialog, useRBAC, useTracking, RelativeTime, CheckPermissions, useQueryParams, AnErrorOccurred, NoContent, Table, PageSizeURLQuery, PaginationURLQuery, CheckPagePermissions } from "@strapi/helper-plugin";
|
|
3
3
|
import { useLocation, useParams, useHistory, Redirect, Link as Link$1, Switch, Route } from "react-router-dom";
|
|
4
|
-
import { p as pluginId, u as useGetReleaseQuery, a as useUpdateReleaseMutation, b as useDeleteReleaseMutation, c as usePublishReleaseMutation, P as PERMISSIONS, d as useTypedDispatch, e as useGetReleaseActionsQuery, f as useUpdateReleaseActionMutation, R as ReleaseActionOptions,
|
|
4
|
+
import { g as getTimezoneOffset, p as pluginId, u as useGetReleaseQuery, a as useUpdateReleaseMutation, b as useDeleteReleaseMutation, c as usePublishReleaseMutation, P as PERMISSIONS, d as useTypedDispatch, e as useGetReleaseActionsQuery, f as useUpdateReleaseActionMutation, R as ReleaseActionOptions, h as ReleaseActionMenu, i as isAxiosError, r as releaseApi, j as useGetReleasesQuery, k as useCreateReleaseMutation } from "./index-BZ8RPGiV.mjs";
|
|
5
5
|
import * as React from "react";
|
|
6
6
|
import { unstable_useDocument, useLicenseLimits } from "@strapi/admin/strapi-admin";
|
|
7
|
-
import { ModalLayout, ModalHeader, Typography, ModalBody, TextInput, ModalFooter, Button,
|
|
7
|
+
import { ModalLayout, ModalHeader, Typography, ModalBody, Flex, TextInput, Box, Checkbox, DatePicker, TimePicker, ModalFooter, Button, Combobox, ComboboxOption, ContentLayout, Main, HeaderLayout, Link, IconButton, SingleSelect, SingleSelectOption, Badge, Tr, Td, Icon, Tooltip, Alert, TabGroup, Tabs, Tab, Divider, TabPanels, TabPanel, EmptyStateLayout, Grid, GridItem } from "@strapi/design-system";
|
|
8
8
|
import { Menu, LinkButton, Link as Link$2 } from "@strapi/design-system/v2";
|
|
9
9
|
import { Pencil, Trash, ArrowLeft, More, CrossCircle, CheckCircle, Plus, EmptyDocuments } from "@strapi/icons";
|
|
10
|
+
import format from "date-fns/format";
|
|
11
|
+
import { zonedTimeToUtc, utcToZonedTime } from "date-fns-tz";
|
|
10
12
|
import { useIntl } from "react-intl";
|
|
11
13
|
import styled from "styled-components";
|
|
12
|
-
import {
|
|
14
|
+
import { formatISO, parse } from "date-fns";
|
|
15
|
+
import { Formik, Form, useFormikContext } from "formik";
|
|
13
16
|
import * as yup from "yup";
|
|
14
17
|
import "@reduxjs/toolkit/query";
|
|
15
18
|
import "axios";
|
|
@@ -17,8 +20,23 @@ import "@reduxjs/toolkit/query/react";
|
|
|
17
20
|
import "react-redux";
|
|
18
21
|
const RELEASE_SCHEMA = yup.object().shape({
|
|
19
22
|
name: yup.string().trim().required(),
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
scheduledAt: yup.string().nullable(),
|
|
24
|
+
isScheduled: yup.boolean().optional(),
|
|
25
|
+
time: yup.string().when("isScheduled", {
|
|
26
|
+
is: true,
|
|
27
|
+
then: yup.string().trim().required(),
|
|
28
|
+
otherwise: yup.string().nullable()
|
|
29
|
+
}),
|
|
30
|
+
timezone: yup.string().when("isScheduled", {
|
|
31
|
+
is: true,
|
|
32
|
+
then: yup.string().required().nullable(),
|
|
33
|
+
otherwise: yup.string().nullable()
|
|
34
|
+
}),
|
|
35
|
+
date: yup.string().when("isScheduled", {
|
|
36
|
+
is: true,
|
|
37
|
+
then: yup.string().required().nullable(),
|
|
38
|
+
otherwise: yup.string().nullable()
|
|
39
|
+
})
|
|
22
40
|
}).required().noUnknown();
|
|
23
41
|
const ReleaseModal = ({
|
|
24
42
|
handleClose,
|
|
@@ -29,6 +47,24 @@ const ReleaseModal = ({
|
|
|
29
47
|
const { formatMessage } = useIntl();
|
|
30
48
|
const { pathname } = useLocation();
|
|
31
49
|
const isCreatingRelease = pathname === `/plugins/${pluginId}`;
|
|
50
|
+
const IsSchedulingEnabled = window.strapi.future.isEnabled("contentReleasesScheduling");
|
|
51
|
+
const { timezoneList, systemTimezone = { value: "UTC+00:00-Africa/Abidjan " } } = getTimezones(
|
|
52
|
+
initialValues.scheduledAt ? new Date(initialValues.scheduledAt) : /* @__PURE__ */ new Date()
|
|
53
|
+
);
|
|
54
|
+
const getScheduledTimestamp = (values) => {
|
|
55
|
+
const { date, time, timezone } = values;
|
|
56
|
+
if (!date || !time || !timezone)
|
|
57
|
+
return null;
|
|
58
|
+
const formattedDate = parse(time, "HH:mm", new Date(date));
|
|
59
|
+
const timezoneWithoutOffset = timezone.split("_")[1];
|
|
60
|
+
return zonedTimeToUtc(formattedDate, timezoneWithoutOffset);
|
|
61
|
+
};
|
|
62
|
+
const getTimezoneWithOffset = () => {
|
|
63
|
+
const currentTimezone = timezoneList.find(
|
|
64
|
+
(timezone) => timezone.value.split("_")[1] === initialValues.timezone
|
|
65
|
+
);
|
|
66
|
+
return currentTimezone?.value || systemTimezone.value;
|
|
67
|
+
};
|
|
32
68
|
return /* @__PURE__ */ jsxs(ModalLayout, { onClose: handleClose, labelledBy: "title", children: [
|
|
33
69
|
/* @__PURE__ */ jsx(ModalHeader, { children: /* @__PURE__ */ jsx(Typography, { id: "title", fontWeight: "bold", textColor: "neutral800", children: formatMessage(
|
|
34
70
|
{
|
|
@@ -40,45 +76,134 @@ const ReleaseModal = ({
|
|
|
40
76
|
/* @__PURE__ */ jsx(
|
|
41
77
|
Formik,
|
|
42
78
|
{
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
79
|
+
onSubmit: (values) => {
|
|
80
|
+
handleSubmit({
|
|
81
|
+
...values,
|
|
82
|
+
timezone: values.timezone ? values.timezone.split("_")[1] : null,
|
|
83
|
+
scheduledAt: values.isScheduled ? getScheduledTimestamp(values) : null
|
|
84
|
+
});
|
|
85
|
+
},
|
|
86
|
+
initialValues: {
|
|
87
|
+
...initialValues,
|
|
88
|
+
timezone: initialValues.timezone ? getTimezoneWithOffset() : systemTimezone.value
|
|
89
|
+
},
|
|
46
90
|
validationSchema: RELEASE_SCHEMA,
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
91
|
+
validateOnChange: false,
|
|
92
|
+
children: ({ values, errors, handleChange, setFieldValue }) => /* @__PURE__ */ jsxs(Form, { children: [
|
|
93
|
+
/* @__PURE__ */ jsx(ModalBody, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: [
|
|
94
|
+
/* @__PURE__ */ jsx(
|
|
95
|
+
TextInput,
|
|
96
|
+
{
|
|
97
|
+
label: formatMessage({
|
|
98
|
+
id: "content-releases.modal.form.input.label.release-name",
|
|
99
|
+
defaultMessage: "Name"
|
|
100
|
+
}),
|
|
101
|
+
name: "name",
|
|
102
|
+
value: values.name,
|
|
103
|
+
error: errors.name,
|
|
104
|
+
onChange: handleChange,
|
|
105
|
+
required: true
|
|
106
|
+
}
|
|
107
|
+
),
|
|
108
|
+
IsSchedulingEnabled && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
109
|
+
/* @__PURE__ */ jsx(Box, { width: "max-content", children: /* @__PURE__ */ jsx(
|
|
110
|
+
Checkbox,
|
|
111
|
+
{
|
|
112
|
+
name: "isScheduled",
|
|
113
|
+
value: values.isScheduled,
|
|
114
|
+
onChange: (event) => {
|
|
115
|
+
setFieldValue("isScheduled", event.target.checked);
|
|
116
|
+
if (!event.target.checked) {
|
|
117
|
+
setFieldValue("date", null);
|
|
118
|
+
setFieldValue("time", "");
|
|
119
|
+
setFieldValue("timezone", null);
|
|
120
|
+
} else {
|
|
121
|
+
setFieldValue("date", initialValues.date);
|
|
122
|
+
setFieldValue("time", initialValues.time);
|
|
123
|
+
setFieldValue(
|
|
124
|
+
"timezone",
|
|
125
|
+
initialValues.timezone ?? systemTimezone?.value
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
children: /* @__PURE__ */ jsx(
|
|
130
|
+
Typography,
|
|
131
|
+
{
|
|
132
|
+
textColor: values.isScheduled ? "primary600" : "neutral800",
|
|
133
|
+
fontWeight: values.isScheduled ? "semiBold" : "regular",
|
|
134
|
+
children: formatMessage({
|
|
135
|
+
id: "modal.form.input.label.schedule-release",
|
|
136
|
+
defaultMessage: "Schedule release"
|
|
137
|
+
})
|
|
138
|
+
}
|
|
139
|
+
)
|
|
140
|
+
}
|
|
141
|
+
) }),
|
|
142
|
+
values.isScheduled && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
143
|
+
/* @__PURE__ */ jsxs(Flex, { gap: 4, alignItems: "start", children: [
|
|
144
|
+
/* @__PURE__ */ jsx(Box, { width: "100%", children: /* @__PURE__ */ jsx(
|
|
145
|
+
DatePicker,
|
|
146
|
+
{
|
|
147
|
+
label: formatMessage({
|
|
148
|
+
id: "content-releases.modal.form.input.label.date",
|
|
149
|
+
defaultMessage: "Date"
|
|
150
|
+
}),
|
|
151
|
+
name: "date",
|
|
152
|
+
error: errors.date,
|
|
153
|
+
onChange: (date) => {
|
|
154
|
+
const isoFormatDate = date ? formatISO(date, { representation: "date" }) : null;
|
|
155
|
+
setFieldValue("date", isoFormatDate);
|
|
156
|
+
},
|
|
157
|
+
clearLabel: formatMessage({
|
|
158
|
+
id: "content-releases.modal.form.input.clearLabel",
|
|
159
|
+
defaultMessage: "Clear"
|
|
160
|
+
}),
|
|
161
|
+
onClear: () => {
|
|
162
|
+
setFieldValue("date", null);
|
|
163
|
+
},
|
|
164
|
+
selectedDate: values.date || void 0,
|
|
165
|
+
required: true
|
|
166
|
+
}
|
|
167
|
+
) }),
|
|
168
|
+
/* @__PURE__ */ jsx(Box, { width: "100%", children: /* @__PURE__ */ jsx(
|
|
169
|
+
TimePicker,
|
|
170
|
+
{
|
|
171
|
+
label: formatMessage({
|
|
172
|
+
id: "content-releases.modal.form.input.label.time",
|
|
173
|
+
defaultMessage: "Time"
|
|
174
|
+
}),
|
|
175
|
+
name: "time",
|
|
176
|
+
error: errors.time,
|
|
177
|
+
onChange: (time) => {
|
|
178
|
+
setFieldValue("time", time);
|
|
179
|
+
},
|
|
180
|
+
clearLabel: formatMessage({
|
|
181
|
+
id: "content-releases.modal.form.input.clearLabel",
|
|
182
|
+
defaultMessage: "Clear"
|
|
183
|
+
}),
|
|
184
|
+
onClear: () => {
|
|
185
|
+
setFieldValue("time", "");
|
|
186
|
+
},
|
|
187
|
+
value: values.time || void 0,
|
|
188
|
+
required: true
|
|
189
|
+
}
|
|
190
|
+
) })
|
|
191
|
+
] }),
|
|
192
|
+
/* @__PURE__ */ jsx(TimezoneComponent, { timezoneOptions: timezoneList })
|
|
193
|
+
] })
|
|
194
|
+
] })
|
|
195
|
+
] }) }),
|
|
62
196
|
/* @__PURE__ */ jsx(
|
|
63
197
|
ModalFooter,
|
|
64
198
|
{
|
|
65
199
|
startActions: /* @__PURE__ */ jsx(Button, { onClick: handleClose, variant: "tertiary", name: "cancel", children: formatMessage({ id: "cancel", defaultMessage: "Cancel" }) }),
|
|
66
|
-
endActions: /* @__PURE__ */ jsx(
|
|
67
|
-
Button,
|
|
200
|
+
endActions: /* @__PURE__ */ jsx(Button, { name: "submit", loading: isLoading, type: "submit", children: formatMessage(
|
|
68
201
|
{
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
{
|
|
75
|
-
id: "content-releases.modal.form.button.submit",
|
|
76
|
-
defaultMessage: "{isCreatingRelease, select, true {Continue} other {Save}}"
|
|
77
|
-
},
|
|
78
|
-
{ isCreatingRelease }
|
|
79
|
-
)
|
|
80
|
-
}
|
|
81
|
-
)
|
|
202
|
+
id: "content-releases.modal.form.button.submit",
|
|
203
|
+
defaultMessage: "{isCreatingRelease, select, true {Continue} other {Save}}"
|
|
204
|
+
},
|
|
205
|
+
{ isCreatingRelease }
|
|
206
|
+
) })
|
|
82
207
|
}
|
|
83
208
|
)
|
|
84
209
|
] })
|
|
@@ -86,6 +211,52 @@ const ReleaseModal = ({
|
|
|
86
211
|
)
|
|
87
212
|
] });
|
|
88
213
|
};
|
|
214
|
+
const getTimezones = (selectedDate) => {
|
|
215
|
+
const timezoneList = Intl.supportedValuesOf("timeZone").map((timezone) => {
|
|
216
|
+
const utcOffset = getTimezoneOffset(timezone, selectedDate);
|
|
217
|
+
return { offset: utcOffset, value: `${utcOffset}_${timezone}` };
|
|
218
|
+
});
|
|
219
|
+
const systemTimezone = timezoneList.find(
|
|
220
|
+
(timezone) => timezone.value.split("_")[1] === Intl.DateTimeFormat().resolvedOptions().timeZone
|
|
221
|
+
);
|
|
222
|
+
return { timezoneList, systemTimezone };
|
|
223
|
+
};
|
|
224
|
+
const TimezoneComponent = ({ timezoneOptions }) => {
|
|
225
|
+
const { values, errors, setFieldValue } = useFormikContext();
|
|
226
|
+
const { formatMessage } = useIntl();
|
|
227
|
+
const [timezoneList, setTimezoneList] = React.useState(timezoneOptions);
|
|
228
|
+
React.useEffect(() => {
|
|
229
|
+
if (values.date) {
|
|
230
|
+
const { timezoneList: timezoneList2 } = getTimezones(new Date(values.date));
|
|
231
|
+
setTimezoneList(timezoneList2);
|
|
232
|
+
const updatedTimezone = values.timezone && timezoneList2.find((tz) => tz.value.split("_")[1] === values.timezone.split("_")[1]);
|
|
233
|
+
if (updatedTimezone) {
|
|
234
|
+
setFieldValue("timezone", updatedTimezone.value);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}, [setFieldValue, values.date, values.timezone]);
|
|
238
|
+
return /* @__PURE__ */ jsx(
|
|
239
|
+
Combobox,
|
|
240
|
+
{
|
|
241
|
+
label: formatMessage({
|
|
242
|
+
id: "content-releases.modal.form.input.label.timezone",
|
|
243
|
+
defaultMessage: "Timezone"
|
|
244
|
+
}),
|
|
245
|
+
name: "timezone",
|
|
246
|
+
value: values.timezone || void 0,
|
|
247
|
+
textValue: values.timezone ? values.timezone.replace("_", " ") : void 0,
|
|
248
|
+
onChange: (timezone) => {
|
|
249
|
+
setFieldValue("timezone", timezone);
|
|
250
|
+
},
|
|
251
|
+
onClear: () => {
|
|
252
|
+
setFieldValue("timezone", "");
|
|
253
|
+
},
|
|
254
|
+
error: errors.timezone,
|
|
255
|
+
required: true,
|
|
256
|
+
children: timezoneList.map((timezone) => /* @__PURE__ */ jsx(ComboboxOption, { value: timezone.value, children: timezone.value.replace("_", " ") }, timezone.value))
|
|
257
|
+
}
|
|
258
|
+
);
|
|
259
|
+
};
|
|
89
260
|
const ReleaseInfoWrapper = styled(Flex)`
|
|
90
261
|
align-self: stretch;
|
|
91
262
|
border-bottom-right-radius: ${({ theme }) => theme.borderRadius};
|
|
@@ -165,7 +336,7 @@ const ReleaseDetailsLayout = ({
|
|
|
165
336
|
toggleWarningSubmit,
|
|
166
337
|
children
|
|
167
338
|
}) => {
|
|
168
|
-
const { formatMessage } = useIntl();
|
|
339
|
+
const { formatMessage, formatDate, formatTime } = useIntl();
|
|
169
340
|
const { releaseId } = useParams();
|
|
170
341
|
const {
|
|
171
342
|
data,
|
|
@@ -247,18 +418,41 @@ const ReleaseDetailsLayout = ({
|
|
|
247
418
|
}
|
|
248
419
|
const totalEntries = release.actions.meta.count || 0;
|
|
249
420
|
const hasCreatedByUser = Boolean(getCreatedByUser());
|
|
421
|
+
const IsSchedulingEnabled = window.strapi.future.isEnabled("contentReleasesScheduling");
|
|
422
|
+
const isScheduled = release.scheduledAt && release.timezone;
|
|
423
|
+
const numberOfEntriesText = formatMessage(
|
|
424
|
+
{
|
|
425
|
+
id: "content-releases.pages.Details.header-subtitle",
|
|
426
|
+
defaultMessage: "{number, plural, =0 {No entries} one {# entry} other {# entries}}"
|
|
427
|
+
},
|
|
428
|
+
{ number: totalEntries }
|
|
429
|
+
);
|
|
430
|
+
const scheduledText = isScheduled ? formatMessage(
|
|
431
|
+
{
|
|
432
|
+
id: "content-releases.pages.ReleaseDetails.header-subtitle.scheduled",
|
|
433
|
+
defaultMessage: "Scheduled for {date} at {time} ({offset})"
|
|
434
|
+
},
|
|
435
|
+
{
|
|
436
|
+
date: formatDate(new Date(release.scheduledAt), {
|
|
437
|
+
weekday: "long",
|
|
438
|
+
day: "numeric",
|
|
439
|
+
month: "long",
|
|
440
|
+
year: "numeric",
|
|
441
|
+
timeZone: release.timezone
|
|
442
|
+
}),
|
|
443
|
+
time: formatTime(new Date(release.scheduledAt), {
|
|
444
|
+
timeZone: release.timezone,
|
|
445
|
+
hourCycle: "h23"
|
|
446
|
+
}),
|
|
447
|
+
offset: getTimezoneOffset(release.timezone, new Date(release.scheduledAt))
|
|
448
|
+
}
|
|
449
|
+
) : "";
|
|
250
450
|
return /* @__PURE__ */ jsxs(Main, { "aria-busy": isLoadingDetails, children: [
|
|
251
451
|
/* @__PURE__ */ jsx(
|
|
252
452
|
HeaderLayout,
|
|
253
453
|
{
|
|
254
454
|
title: release.name,
|
|
255
|
-
subtitle:
|
|
256
|
-
{
|
|
257
|
-
id: "content-releases.pages.Details.header-subtitle",
|
|
258
|
-
defaultMessage: "{number, plural, =0 {No entries} one {# entry} other {# entries}}"
|
|
259
|
-
},
|
|
260
|
-
{ number: totalEntries }
|
|
261
|
-
),
|
|
455
|
+
subtitle: numberOfEntriesText + (IsSchedulingEnabled && isScheduled ? ` - ${scheduledText}` : ""),
|
|
262
456
|
navigationAction: /* @__PURE__ */ jsx(Link, { startIcon: /* @__PURE__ */ jsx(ArrowLeft, {}), to: "/plugins/content-releases", children: formatMessage({
|
|
263
457
|
id: "global.back",
|
|
264
458
|
defaultMessage: "Back"
|
|
@@ -707,11 +901,18 @@ const ReleaseDetailsPage = () => {
|
|
|
707
901
|
}
|
|
708
902
|
);
|
|
709
903
|
}
|
|
710
|
-
const
|
|
904
|
+
const releaseData = isSuccessDetails && data?.data || null;
|
|
905
|
+
const title = releaseData?.name || "";
|
|
906
|
+
const timezone = releaseData?.timezone ?? null;
|
|
907
|
+
const scheduledAt = releaseData?.scheduledAt && timezone ? utcToZonedTime(releaseData.scheduledAt, timezone) : null;
|
|
908
|
+
const date = scheduledAt ? new Date(format(scheduledAt, "yyyy-MM-dd")) : null;
|
|
909
|
+
const time = scheduledAt ? format(scheduledAt, "HH:mm") : "";
|
|
711
910
|
const handleEditRelease = async (values) => {
|
|
712
911
|
const response = await updateRelease({
|
|
713
912
|
id: releaseId,
|
|
714
|
-
name: values.name
|
|
913
|
+
name: values.name,
|
|
914
|
+
scheduledAt: values.scheduledAt,
|
|
915
|
+
timezone: values.timezone
|
|
715
916
|
});
|
|
716
917
|
if ("data" in response) {
|
|
717
918
|
toggleNotification({
|
|
@@ -765,7 +966,14 @@ const ReleaseDetailsPage = () => {
|
|
|
765
966
|
handleClose: toggleEditReleaseModal,
|
|
766
967
|
handleSubmit: handleEditRelease,
|
|
767
968
|
isLoading: isLoadingDetails || isSubmittingForm,
|
|
768
|
-
initialValues: {
|
|
969
|
+
initialValues: {
|
|
970
|
+
name: title || "",
|
|
971
|
+
scheduledAt,
|
|
972
|
+
date,
|
|
973
|
+
time,
|
|
974
|
+
isScheduled: Boolean(scheduledAt),
|
|
975
|
+
timezone
|
|
976
|
+
}
|
|
769
977
|
}
|
|
770
978
|
),
|
|
771
979
|
/* @__PURE__ */ jsx(
|
|
@@ -790,6 +998,7 @@ const LinkCard = styled(Link$2)`
|
|
|
790
998
|
`;
|
|
791
999
|
const ReleasesGrid = ({ sectionTitle, releases = [], isError = false }) => {
|
|
792
1000
|
const { formatMessage } = useIntl();
|
|
1001
|
+
const IsSchedulingEnabled = window.strapi.future.isEnabled("contentReleasesScheduling");
|
|
793
1002
|
if (isError) {
|
|
794
1003
|
return /* @__PURE__ */ jsx(AnErrorOccurred, {});
|
|
795
1004
|
}
|
|
@@ -810,7 +1019,7 @@ const ReleasesGrid = ({ sectionTitle, releases = [], isError = false }) => {
|
|
|
810
1019
|
}
|
|
811
1020
|
);
|
|
812
1021
|
}
|
|
813
|
-
return /* @__PURE__ */ jsx(Grid, { gap: 4, children: releases.map(({ id, name, actions }) => /* @__PURE__ */ jsx(GridItem, { col: 3, s: 6, xs: 12, children: /* @__PURE__ */ jsx(LinkCard, { href: `content-releases/${id}`, isExternal: false, children: /* @__PURE__ */ jsxs(
|
|
1022
|
+
return /* @__PURE__ */ jsx(Grid, { gap: 4, children: releases.map(({ id, name, actions, scheduledAt }) => /* @__PURE__ */ jsx(GridItem, { col: 3, s: 6, xs: 12, children: /* @__PURE__ */ jsx(LinkCard, { href: `content-releases/${id}`, isExternal: false, children: /* @__PURE__ */ jsxs(
|
|
814
1023
|
Flex,
|
|
815
1024
|
{
|
|
816
1025
|
direction: "column",
|
|
@@ -825,7 +1034,10 @@ const ReleasesGrid = ({ sectionTitle, releases = [], isError = false }) => {
|
|
|
825
1034
|
gap: 2,
|
|
826
1035
|
children: [
|
|
827
1036
|
/* @__PURE__ */ jsx(Typography, { as: "h3", variant: "delta", fontWeight: "bold", children: name }),
|
|
828
|
-
/* @__PURE__ */ jsx(Typography, { variant: "pi", children: formatMessage(
|
|
1037
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: IsSchedulingEnabled ? scheduledAt ? /* @__PURE__ */ jsx(RelativeTime, { timestamp: new Date(scheduledAt) }) : formatMessage({
|
|
1038
|
+
id: "content-releases.pages.Releases.not-scheduled",
|
|
1039
|
+
defaultMessage: "Not scheduled"
|
|
1040
|
+
}) : formatMessage(
|
|
829
1041
|
{
|
|
830
1042
|
id: "content-releases.page.Releases.release-item.entries",
|
|
831
1043
|
defaultMessage: "{number, plural, =0 {No entries} one {# entry} other {# entries}}"
|
|
@@ -845,7 +1057,13 @@ const StyledAlert = styled(Alert)`
|
|
|
845
1057
|
}
|
|
846
1058
|
`;
|
|
847
1059
|
const INITIAL_FORM_VALUES = {
|
|
848
|
-
name: ""
|
|
1060
|
+
name: "",
|
|
1061
|
+
date: null,
|
|
1062
|
+
time: "",
|
|
1063
|
+
// Remove future flag check after Scheduling Beta release and replace with true as creating new release should include scheduling by default
|
|
1064
|
+
isScheduled: window.strapi.future.isEnabled("contentReleasesScheduling"),
|
|
1065
|
+
scheduledAt: null,
|
|
1066
|
+
timezone: null
|
|
849
1067
|
};
|
|
850
1068
|
const ReleasesPage = () => {
|
|
851
1069
|
const tabRef = React.useRef(null);
|
|
@@ -891,8 +1109,8 @@ const ReleasesPage = () => {
|
|
|
891
1109
|
if (isLoading) {
|
|
892
1110
|
return /* @__PURE__ */ jsx(Main, { "aria-busy": isLoading, children: /* @__PURE__ */ jsx(LoadingIndicatorPage, {}) });
|
|
893
1111
|
}
|
|
894
|
-
const
|
|
895
|
-
const hasReachedMaximumPendingReleases =
|
|
1112
|
+
const totalPendingReleases = isSuccess && response.currentData?.meta?.pendingReleasesCount || 0;
|
|
1113
|
+
const hasReachedMaximumPendingReleases = totalPendingReleases >= maximumReleases;
|
|
896
1114
|
const handleTabChange = (index) => {
|
|
897
1115
|
setQuery({
|
|
898
1116
|
...query,
|
|
@@ -905,9 +1123,11 @@ const ReleasesPage = () => {
|
|
|
905
1123
|
}
|
|
906
1124
|
});
|
|
907
1125
|
};
|
|
908
|
-
const handleAddRelease = async (
|
|
1126
|
+
const handleAddRelease = async ({ name, scheduledAt, timezone }) => {
|
|
909
1127
|
const response2 = await createRelease({
|
|
910
|
-
name
|
|
1128
|
+
name,
|
|
1129
|
+
scheduledAt,
|
|
1130
|
+
timezone
|
|
911
1131
|
});
|
|
912
1132
|
if ("data" in response2) {
|
|
913
1133
|
toggleNotification({
|
|
@@ -939,13 +1159,10 @@ const ReleasesPage = () => {
|
|
|
939
1159
|
id: "content-releases.pages.Releases.title",
|
|
940
1160
|
defaultMessage: "Releases"
|
|
941
1161
|
}),
|
|
942
|
-
subtitle: formatMessage(
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
},
|
|
947
|
-
{ number: totalReleases }
|
|
948
|
-
),
|
|
1162
|
+
subtitle: formatMessage({
|
|
1163
|
+
id: "content-releases.pages.Releases.header-subtitle",
|
|
1164
|
+
defaultMessage: "Create and manage content updates"
|
|
1165
|
+
}),
|
|
949
1166
|
primaryAction: /* @__PURE__ */ jsx(CheckPermissions, { permissions: PERMISSIONS.create, children: /* @__PURE__ */ jsx(
|
|
950
1167
|
Button,
|
|
951
1168
|
{
|
|
@@ -961,7 +1178,7 @@ const ReleasesPage = () => {
|
|
|
961
1178
|
}
|
|
962
1179
|
),
|
|
963
1180
|
/* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
964
|
-
|
|
1181
|
+
hasReachedMaximumPendingReleases && /* @__PURE__ */ jsx(
|
|
965
1182
|
StyledAlert,
|
|
966
1183
|
{
|
|
967
1184
|
marginBottom: 6,
|
|
@@ -999,10 +1216,15 @@ const ReleasesPage = () => {
|
|
|
999
1216
|
children: [
|
|
1000
1217
|
/* @__PURE__ */ jsxs(Box, { paddingBottom: 8, children: [
|
|
1001
1218
|
/* @__PURE__ */ jsxs(Tabs, { children: [
|
|
1002
|
-
/* @__PURE__ */ jsx(Tab, { children: formatMessage(
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1219
|
+
/* @__PURE__ */ jsx(Tab, { children: formatMessage(
|
|
1220
|
+
{
|
|
1221
|
+
id: "content-releases.pages.Releases.tab.pending",
|
|
1222
|
+
defaultMessage: "Pending ({count})"
|
|
1223
|
+
},
|
|
1224
|
+
{
|
|
1225
|
+
count: totalPendingReleases
|
|
1226
|
+
}
|
|
1227
|
+
) }),
|
|
1006
1228
|
/* @__PURE__ */ jsx(Tab, { children: formatMessage({
|
|
1007
1229
|
id: "content-releases.pages.Releases.tab.done",
|
|
1008
1230
|
defaultMessage: "Done"
|
|
@@ -1031,7 +1253,7 @@ const ReleasesPage = () => {
|
|
|
1031
1253
|
]
|
|
1032
1254
|
}
|
|
1033
1255
|
),
|
|
1034
|
-
|
|
1256
|
+
response.currentData?.meta?.pagination?.total ? /* @__PURE__ */ jsxs(Flex, { paddingTop: 4, alignItems: "flex-end", justifyContent: "space-between", children: [
|
|
1035
1257
|
/* @__PURE__ */ jsx(
|
|
1036
1258
|
PageSizeURLQuery,
|
|
1037
1259
|
{
|
|
@@ -1047,7 +1269,7 @@ const ReleasesPage = () => {
|
|
|
1047
1269
|
}
|
|
1048
1270
|
}
|
|
1049
1271
|
)
|
|
1050
|
-
] })
|
|
1272
|
+
] }) : null
|
|
1051
1273
|
] }) }),
|
|
1052
1274
|
releaseModalShown && /* @__PURE__ */ jsx(
|
|
1053
1275
|
ReleaseModal,
|
|
@@ -1069,4 +1291,4 @@ const App = () => {
|
|
|
1069
1291
|
export {
|
|
1070
1292
|
App
|
|
1071
1293
|
};
|
|
1072
|
-
//# sourceMappingURL=App-
|
|
1294
|
+
//# sourceMappingURL=App-WMxox0mk.mjs.map
|