@strapi/content-releases 0.0.0-next.3844395bef7efa05c25c6d4337306935905bc653 → 0.0.0-next.4af8963f6880c5fb9fae32ecd580f5cd33eaddda
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-L1jSxCiL.mjs → App-ise7GunC.mjs} +493 -235
- package/dist/_chunks/App-ise7GunC.mjs.map +1 -0
- package/dist/_chunks/{App-_20W9dYa.js → App-w2Zq-wj5.js} +489 -230
- package/dist/_chunks/App-w2Zq-wj5.js.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-gYDqKYFd.js → en-7P4i1cWH.js} +14 -3
- package/dist/_chunks/en-7P4i1cWH.js.map +1 -0
- package/dist/_chunks/{en-MyLPoISH.mjs → en-pb1wUzhy.mjs} +14 -3
- package/dist/_chunks/en-pb1wUzhy.mjs.map +1 -0
- package/dist/_chunks/{index-c4zRX_sg.mjs → index-D-Yjf60c.mjs} +89 -26
- package/dist/_chunks/index-D-Yjf60c.mjs.map +1 -0
- package/dist/_chunks/{index-KJa1Rb5F.js → index-Q8Pv7enO.js} +88 -25
- package/dist/_chunks/index-Q8Pv7enO.js.map +1 -0
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/server/index.js +597 -382
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +597 -382
- package/dist/server/index.mjs.map +1 -1
- package/package.json +12 -9
- package/dist/_chunks/App-L1jSxCiL.mjs.map +0 -1
- package/dist/_chunks/App-_20W9dYa.js.map +0 -1
- package/dist/_chunks/en-MyLPoISH.mjs.map +0 -1
- package/dist/_chunks/en-gYDqKYFd.js.map +0 -1
- package/dist/_chunks/index-KJa1Rb5F.js.map +0 -1
- package/dist/_chunks/index-c4zRX_sg.mjs.map +0 -1
|
@@ -3,14 +3,17 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
3
3
|
const jsxRuntime = require("react/jsx-runtime");
|
|
4
4
|
const helperPlugin = require("@strapi/helper-plugin");
|
|
5
5
|
const reactRouterDom = require("react-router-dom");
|
|
6
|
-
const index = require("./index-
|
|
6
|
+
const index = require("./index-Q8Pv7enO.js");
|
|
7
7
|
const React = require("react");
|
|
8
8
|
const strapiAdmin = require("@strapi/admin/strapi-admin");
|
|
9
9
|
const designSystem = require("@strapi/design-system");
|
|
10
10
|
const v2 = require("@strapi/design-system/v2");
|
|
11
11
|
const icons = require("@strapi/icons");
|
|
12
|
+
const format = require("date-fns/format");
|
|
13
|
+
const dateFnsTz = require("date-fns-tz");
|
|
12
14
|
const reactIntl = require("react-intl");
|
|
13
15
|
const styled = require("styled-components");
|
|
16
|
+
const dateFns = require("date-fns");
|
|
14
17
|
const formik = require("formik");
|
|
15
18
|
const yup = require("yup");
|
|
16
19
|
require("@reduxjs/toolkit/query");
|
|
@@ -37,10 +40,28 @@ function _interopNamespace(e) {
|
|
|
37
40
|
return Object.freeze(n);
|
|
38
41
|
}
|
|
39
42
|
const React__namespace = /* @__PURE__ */ _interopNamespace(React);
|
|
43
|
+
const format__default = /* @__PURE__ */ _interopDefault(format);
|
|
40
44
|
const styled__default = /* @__PURE__ */ _interopDefault(styled);
|
|
41
45
|
const yup__namespace = /* @__PURE__ */ _interopNamespace(yup);
|
|
42
46
|
const RELEASE_SCHEMA = yup__namespace.object().shape({
|
|
43
|
-
name: yup__namespace.string().trim().required()
|
|
47
|
+
name: yup__namespace.string().trim().required(),
|
|
48
|
+
scheduledAt: yup__namespace.string().nullable(),
|
|
49
|
+
isScheduled: yup__namespace.boolean().optional(),
|
|
50
|
+
time: yup__namespace.string().when("isScheduled", {
|
|
51
|
+
is: true,
|
|
52
|
+
then: yup__namespace.string().trim().required(),
|
|
53
|
+
otherwise: yup__namespace.string().nullable()
|
|
54
|
+
}),
|
|
55
|
+
timezone: yup__namespace.string().when("isScheduled", {
|
|
56
|
+
is: true,
|
|
57
|
+
then: yup__namespace.string().required().nullable(),
|
|
58
|
+
otherwise: yup__namespace.string().nullable()
|
|
59
|
+
}),
|
|
60
|
+
date: yup__namespace.string().when("isScheduled", {
|
|
61
|
+
is: true,
|
|
62
|
+
then: yup__namespace.string().required().nullable(),
|
|
63
|
+
otherwise: yup__namespace.string().nullable()
|
|
64
|
+
})
|
|
44
65
|
}).required().noUnknown();
|
|
45
66
|
const ReleaseModal = ({
|
|
46
67
|
handleClose,
|
|
@@ -51,6 +72,24 @@ const ReleaseModal = ({
|
|
|
51
72
|
const { formatMessage } = reactIntl.useIntl();
|
|
52
73
|
const { pathname } = reactRouterDom.useLocation();
|
|
53
74
|
const isCreatingRelease = pathname === `/plugins/${index.pluginId}`;
|
|
75
|
+
const IsSchedulingEnabled = window.strapi.future.isEnabled("contentReleasesScheduling");
|
|
76
|
+
const { timezoneList, systemTimezone = { value: "UTC+00:00-Africa/Abidjan " } } = getTimezones(
|
|
77
|
+
initialValues.scheduledAt ? new Date(initialValues.scheduledAt) : /* @__PURE__ */ new Date()
|
|
78
|
+
);
|
|
79
|
+
const getScheduledTimestamp = (values) => {
|
|
80
|
+
const { date, time, timezone } = values;
|
|
81
|
+
if (!date || !time || !timezone)
|
|
82
|
+
return null;
|
|
83
|
+
const formattedDate = dateFns.parse(time, "HH:mm", new Date(date));
|
|
84
|
+
const timezoneWithoutOffset = timezone.split("-")[1];
|
|
85
|
+
return dateFnsTz.zonedTimeToUtc(formattedDate, timezoneWithoutOffset);
|
|
86
|
+
};
|
|
87
|
+
const getTimezoneWithOffset = () => {
|
|
88
|
+
const currentTimezone = timezoneList.find(
|
|
89
|
+
(timezone) => timezone.value.split("-")[1] === initialValues.timezone
|
|
90
|
+
);
|
|
91
|
+
return currentTimezone?.value || systemTimezone.value;
|
|
92
|
+
};
|
|
54
93
|
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.ModalLayout, { onClose: handleClose, labelledBy: "title", children: [
|
|
55
94
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.ModalHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "title", fontWeight: "bold", textColor: "neutral800", children: formatMessage(
|
|
56
95
|
{
|
|
@@ -62,45 +101,134 @@ const ReleaseModal = ({
|
|
|
62
101
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
63
102
|
formik.Formik,
|
|
64
103
|
{
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
104
|
+
onSubmit: (values) => {
|
|
105
|
+
handleSubmit({
|
|
106
|
+
...values,
|
|
107
|
+
timezone: values.timezone ? values.timezone.split("-")[1] : null,
|
|
108
|
+
scheduledAt: values.isScheduled ? getScheduledTimestamp(values) : null
|
|
109
|
+
});
|
|
110
|
+
},
|
|
111
|
+
initialValues: {
|
|
112
|
+
...initialValues,
|
|
113
|
+
timezone: initialValues.timezone ? getTimezoneWithOffset() : systemTimezone.value
|
|
114
|
+
},
|
|
68
115
|
validationSchema: RELEASE_SCHEMA,
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
116
|
+
validateOnChange: false,
|
|
117
|
+
children: ({ values, errors, handleChange, setFieldValue }) => /* @__PURE__ */ jsxRuntime.jsxs(formik.Form, { children: [
|
|
118
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.ModalBody, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 6, children: [
|
|
119
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
120
|
+
designSystem.TextInput,
|
|
121
|
+
{
|
|
122
|
+
label: formatMessage({
|
|
123
|
+
id: "content-releases.modal.form.input.label.release-name",
|
|
124
|
+
defaultMessage: "Name"
|
|
125
|
+
}),
|
|
126
|
+
name: "name",
|
|
127
|
+
value: values.name,
|
|
128
|
+
error: errors.name,
|
|
129
|
+
onChange: handleChange,
|
|
130
|
+
required: true
|
|
131
|
+
}
|
|
132
|
+
),
|
|
133
|
+
IsSchedulingEnabled && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
134
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
135
|
+
designSystem.Checkbox,
|
|
136
|
+
{
|
|
137
|
+
name: "isScheduled",
|
|
138
|
+
value: values.isScheduled,
|
|
139
|
+
onChange: (event) => {
|
|
140
|
+
setFieldValue("isScheduled", event.target.checked);
|
|
141
|
+
if (!event.target.checked) {
|
|
142
|
+
setFieldValue("date", null);
|
|
143
|
+
setFieldValue("time", "");
|
|
144
|
+
setFieldValue("timezone", null);
|
|
145
|
+
} else {
|
|
146
|
+
setFieldValue("date", initialValues.date);
|
|
147
|
+
setFieldValue("time", initialValues.time);
|
|
148
|
+
setFieldValue(
|
|
149
|
+
"timezone",
|
|
150
|
+
initialValues.timezone ?? systemTimezone?.value
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
155
|
+
designSystem.Typography,
|
|
156
|
+
{
|
|
157
|
+
textColor: values.isScheduled ? "primary600" : "neutral800",
|
|
158
|
+
fontWeight: values.isScheduled ? "semiBold" : "regular",
|
|
159
|
+
children: formatMessage({
|
|
160
|
+
id: "modal.form.input.label.schedule-release",
|
|
161
|
+
defaultMessage: "Schedule release"
|
|
162
|
+
})
|
|
163
|
+
}
|
|
164
|
+
)
|
|
165
|
+
}
|
|
166
|
+
),
|
|
167
|
+
values.isScheduled && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
168
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 4, alignItems: "start", children: [
|
|
169
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
170
|
+
designSystem.DatePicker,
|
|
171
|
+
{
|
|
172
|
+
label: formatMessage({
|
|
173
|
+
id: "content-releases.modal.form.input.label.date",
|
|
174
|
+
defaultMessage: "Date"
|
|
175
|
+
}),
|
|
176
|
+
name: "date",
|
|
177
|
+
error: errors.date,
|
|
178
|
+
onChange: (date) => {
|
|
179
|
+
const isoFormatDate = date ? dateFns.formatISO(date, { representation: "date" }) : null;
|
|
180
|
+
setFieldValue("date", isoFormatDate);
|
|
181
|
+
},
|
|
182
|
+
clearLabel: formatMessage({
|
|
183
|
+
id: "content-releases.modal.form.input.clearLabel",
|
|
184
|
+
defaultMessage: "Clear"
|
|
185
|
+
}),
|
|
186
|
+
onClear: () => {
|
|
187
|
+
setFieldValue("date", null);
|
|
188
|
+
},
|
|
189
|
+
selectedDate: values.date || void 0,
|
|
190
|
+
required: true
|
|
191
|
+
}
|
|
192
|
+
) }),
|
|
193
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
194
|
+
designSystem.TimePicker,
|
|
195
|
+
{
|
|
196
|
+
label: formatMessage({
|
|
197
|
+
id: "content-releases.modal.form.input.label.time",
|
|
198
|
+
defaultMessage: "Time"
|
|
199
|
+
}),
|
|
200
|
+
name: "time",
|
|
201
|
+
error: errors.time,
|
|
202
|
+
onChange: (time) => {
|
|
203
|
+
setFieldValue("time", time);
|
|
204
|
+
},
|
|
205
|
+
clearLabel: formatMessage({
|
|
206
|
+
id: "content-releases.modal.form.input.clearLabel",
|
|
207
|
+
defaultMessage: "Clear"
|
|
208
|
+
}),
|
|
209
|
+
onClear: () => {
|
|
210
|
+
setFieldValue("time", "");
|
|
211
|
+
},
|
|
212
|
+
value: values.time || void 0,
|
|
213
|
+
required: true
|
|
214
|
+
}
|
|
215
|
+
) })
|
|
216
|
+
] }),
|
|
217
|
+
/* @__PURE__ */ jsxRuntime.jsx(TimezoneComponent, { timezoneOptions: timezoneList })
|
|
218
|
+
] })
|
|
219
|
+
] })
|
|
220
|
+
] }) }),
|
|
84
221
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
85
222
|
designSystem.ModalFooter,
|
|
86
223
|
{
|
|
87
224
|
startActions: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleClose, variant: "tertiary", name: "cancel", children: formatMessage({ id: "cancel", defaultMessage: "Cancel" }) }),
|
|
88
|
-
endActions: /* @__PURE__ */ jsxRuntime.jsx(
|
|
89
|
-
designSystem.Button,
|
|
225
|
+
endActions: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { name: "submit", loading: isLoading, type: "submit", children: formatMessage(
|
|
90
226
|
{
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
{
|
|
97
|
-
id: "content-releases.modal.form.button.submit",
|
|
98
|
-
defaultMessage: "{isCreatingRelease, select, true {Continue} other {Save}}"
|
|
99
|
-
},
|
|
100
|
-
{ isCreatingRelease }
|
|
101
|
-
)
|
|
102
|
-
}
|
|
103
|
-
)
|
|
227
|
+
id: "content-releases.modal.form.button.submit",
|
|
228
|
+
defaultMessage: "{isCreatingRelease, select, true {Continue} other {Save}}"
|
|
229
|
+
},
|
|
230
|
+
{ isCreatingRelease }
|
|
231
|
+
) })
|
|
104
232
|
}
|
|
105
233
|
)
|
|
106
234
|
] })
|
|
@@ -108,16 +236,67 @@ const ReleaseModal = ({
|
|
|
108
236
|
)
|
|
109
237
|
] });
|
|
110
238
|
};
|
|
239
|
+
const getTimezones = (selectedDate) => {
|
|
240
|
+
const timezoneList = Intl.supportedValuesOf("timeZone").map((timezone) => {
|
|
241
|
+
const offsetPart = new Intl.DateTimeFormat("en", {
|
|
242
|
+
timeZone: timezone,
|
|
243
|
+
timeZoneName: "longOffset"
|
|
244
|
+
}).formatToParts(selectedDate).find((part) => part.type === "timeZoneName");
|
|
245
|
+
const offset = offsetPart ? offsetPart.value : "";
|
|
246
|
+
let utcOffset = offset.replace("GMT", "UTC");
|
|
247
|
+
if (!utcOffset.includes("+") && !utcOffset.includes("-")) {
|
|
248
|
+
utcOffset = `${utcOffset}+00:00`;
|
|
249
|
+
}
|
|
250
|
+
return { offset: utcOffset, value: `${utcOffset}-${timezone}` };
|
|
251
|
+
});
|
|
252
|
+
const systemTimezone = timezoneList.find(
|
|
253
|
+
(timezone) => timezone.value.split("-")[1] === Intl.DateTimeFormat().resolvedOptions().timeZone
|
|
254
|
+
);
|
|
255
|
+
return { timezoneList, systemTimezone };
|
|
256
|
+
};
|
|
257
|
+
const TimezoneComponent = ({ timezoneOptions }) => {
|
|
258
|
+
const { values, errors, setFieldValue } = formik.useFormikContext();
|
|
259
|
+
const { formatMessage } = reactIntl.useIntl();
|
|
260
|
+
const [timezoneList, setTimezoneList] = React__namespace.useState(timezoneOptions);
|
|
261
|
+
React__namespace.useEffect(() => {
|
|
262
|
+
if (values.date) {
|
|
263
|
+
const { timezoneList: timezoneList2 } = getTimezones(new Date(values.date));
|
|
264
|
+
setTimezoneList(timezoneList2);
|
|
265
|
+
const updatedTimezone = values.timezone && timezoneList2.find((tz) => tz.value.split("-")[1] === values.timezone.split("-")[1]);
|
|
266
|
+
if (updatedTimezone) {
|
|
267
|
+
setFieldValue("timezone", updatedTimezone.value);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}, [setFieldValue, values.date, values.timezone]);
|
|
271
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
272
|
+
designSystem.Combobox,
|
|
273
|
+
{
|
|
274
|
+
label: formatMessage({
|
|
275
|
+
id: "content-releases.modal.form.input.label.timezone",
|
|
276
|
+
defaultMessage: "Timezone"
|
|
277
|
+
}),
|
|
278
|
+
name: "timezone",
|
|
279
|
+
value: values.timezone || void 0,
|
|
280
|
+
textValue: values.timezone ? values.timezone.replace("-", " ") : void 0,
|
|
281
|
+
onChange: (timezone) => {
|
|
282
|
+
setFieldValue("timezone", timezone);
|
|
283
|
+
},
|
|
284
|
+
onClear: () => {
|
|
285
|
+
setFieldValue("timezone", "");
|
|
286
|
+
},
|
|
287
|
+
error: errors.timezone,
|
|
288
|
+
required: true,
|
|
289
|
+
children: timezoneList.map((timezone) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.ComboboxOption, { value: timezone.value, children: timezone.value.replace("-", " ") }, timezone.value))
|
|
290
|
+
}
|
|
291
|
+
);
|
|
292
|
+
};
|
|
111
293
|
const ReleaseInfoWrapper = styled__default.default(designSystem.Flex)`
|
|
112
294
|
align-self: stretch;
|
|
113
295
|
border-bottom-right-radius: ${({ theme }) => theme.borderRadius};
|
|
114
296
|
border-bottom-left-radius: ${({ theme }) => theme.borderRadius};
|
|
115
297
|
border-top: 1px solid ${({ theme }) => theme.colors.neutral150};
|
|
116
298
|
`;
|
|
117
|
-
const
|
|
118
|
-
align-self: stretch;
|
|
119
|
-
cursor: ${({ disabled }) => disabled ? "not-allowed" : "pointer"};
|
|
120
|
-
|
|
299
|
+
const StyledMenuItem = styled__default.default(v2.Menu.Item)`
|
|
121
300
|
svg path {
|
|
122
301
|
fill: ${({ theme, disabled }) => disabled && theme.colors.neutral500};
|
|
123
302
|
}
|
|
@@ -126,15 +305,15 @@ const StyledFlex = styled__default.default(designSystem.Flex)`
|
|
|
126
305
|
}
|
|
127
306
|
`;
|
|
128
307
|
const PencilIcon = styled__default.default(icons.Pencil)`
|
|
129
|
-
width: ${({ theme }) => theme.spaces[
|
|
130
|
-
height: ${({ theme }) => theme.spaces[
|
|
308
|
+
width: ${({ theme }) => theme.spaces[3]};
|
|
309
|
+
height: ${({ theme }) => theme.spaces[3]};
|
|
131
310
|
path {
|
|
132
311
|
fill: ${({ theme }) => theme.colors.neutral600};
|
|
133
312
|
}
|
|
134
313
|
`;
|
|
135
314
|
const TrashIcon = styled__default.default(icons.Trash)`
|
|
136
|
-
width: ${({ theme }) => theme.spaces[
|
|
137
|
-
height: ${({ theme }) => theme.spaces[
|
|
315
|
+
width: ${({ theme }) => theme.spaces[3]};
|
|
316
|
+
height: ${({ theme }) => theme.spaces[3]};
|
|
138
317
|
path {
|
|
139
318
|
fill: ${({ theme }) => theme.colors.danger600};
|
|
140
319
|
}
|
|
@@ -142,24 +321,6 @@ const TrashIcon = styled__default.default(icons.Trash)`
|
|
|
142
321
|
const TypographyMaxWidth = styled__default.default(designSystem.Typography)`
|
|
143
322
|
max-width: 300px;
|
|
144
323
|
`;
|
|
145
|
-
const PopoverButton = ({ onClick, disabled, children }) => {
|
|
146
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
147
|
-
StyledFlex,
|
|
148
|
-
{
|
|
149
|
-
paddingTop: 2,
|
|
150
|
-
paddingBottom: 2,
|
|
151
|
-
paddingLeft: 4,
|
|
152
|
-
paddingRight: 4,
|
|
153
|
-
alignItems: "center",
|
|
154
|
-
gap: 2,
|
|
155
|
-
as: "button",
|
|
156
|
-
hasRadius: true,
|
|
157
|
-
onClick,
|
|
158
|
-
disabled,
|
|
159
|
-
children
|
|
160
|
-
}
|
|
161
|
-
);
|
|
162
|
-
};
|
|
163
324
|
const EntryValidationText = ({ action, schema, components, entry }) => {
|
|
164
325
|
const { formatMessage } = reactIntl.useIntl();
|
|
165
326
|
const { validate } = strapiAdmin.unstable_useDocument();
|
|
@@ -210,8 +371,6 @@ const ReleaseDetailsLayout = ({
|
|
|
210
371
|
}) => {
|
|
211
372
|
const { formatMessage } = reactIntl.useIntl();
|
|
212
373
|
const { releaseId } = reactRouterDom.useParams();
|
|
213
|
-
const [isPopoverVisible, setIsPopoverVisible] = React__namespace.useState(false);
|
|
214
|
-
const moreButtonRef = React__namespace.useRef(null);
|
|
215
374
|
const {
|
|
216
375
|
data,
|
|
217
376
|
isLoading: isLoadingDetails,
|
|
@@ -225,14 +384,8 @@ const ReleaseDetailsLayout = ({
|
|
|
225
384
|
allowedActions: { canUpdate, canDelete }
|
|
226
385
|
} = helperPlugin.useRBAC(index.PERMISSIONS);
|
|
227
386
|
const dispatch = index.useTypedDispatch();
|
|
387
|
+
const { trackUsage } = helperPlugin.useTracking();
|
|
228
388
|
const release = data?.data;
|
|
229
|
-
const handleTogglePopover = () => {
|
|
230
|
-
setIsPopoverVisible((prev) => !prev);
|
|
231
|
-
};
|
|
232
|
-
const openReleaseModal = () => {
|
|
233
|
-
toggleEditReleaseModal();
|
|
234
|
-
handleTogglePopover();
|
|
235
|
-
};
|
|
236
389
|
const handlePublishRelease = async () => {
|
|
237
390
|
const response = await publishRelease({ id: releaseId });
|
|
238
391
|
if ("data" in response) {
|
|
@@ -243,6 +396,12 @@ const ReleaseDetailsLayout = ({
|
|
|
243
396
|
defaultMessage: "Release was published successfully."
|
|
244
397
|
})
|
|
245
398
|
});
|
|
399
|
+
const { totalEntries: totalEntries2, totalPublishedEntries, totalUnpublishedEntries } = response.data.meta;
|
|
400
|
+
trackUsage("didPublishRelease", {
|
|
401
|
+
totalEntries: totalEntries2,
|
|
402
|
+
totalPublishedEntries,
|
|
403
|
+
totalUnpublishedEntries
|
|
404
|
+
});
|
|
246
405
|
} else if (index.isAxiosError(response.error)) {
|
|
247
406
|
toggleNotification({
|
|
248
407
|
type: "warning",
|
|
@@ -255,13 +414,21 @@ const ReleaseDetailsLayout = ({
|
|
|
255
414
|
});
|
|
256
415
|
}
|
|
257
416
|
};
|
|
258
|
-
const openWarningConfirmDialog = () => {
|
|
259
|
-
toggleWarningSubmit();
|
|
260
|
-
handleTogglePopover();
|
|
261
|
-
};
|
|
262
417
|
const handleRefresh = () => {
|
|
263
418
|
dispatch(index.releaseApi.util.invalidateTags([{ type: "ReleaseAction", id: "LIST" }]));
|
|
264
419
|
};
|
|
420
|
+
const getCreatedByUser = () => {
|
|
421
|
+
if (!release?.createdBy) {
|
|
422
|
+
return null;
|
|
423
|
+
}
|
|
424
|
+
if (release.createdBy.username) {
|
|
425
|
+
return release.createdBy.username;
|
|
426
|
+
}
|
|
427
|
+
if (release.createdBy.firstname) {
|
|
428
|
+
return `${release.createdBy.firstname} ${release.createdBy.lastname || ""}`.trim();
|
|
429
|
+
}
|
|
430
|
+
return release.createdBy.email;
|
|
431
|
+
};
|
|
265
432
|
if (isLoadingDetails) {
|
|
266
433
|
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Main, { "aria-busy": isLoadingDetails, children: /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.LoadingIndicatorPage, {}) });
|
|
267
434
|
}
|
|
@@ -283,7 +450,7 @@ const ReleaseDetailsLayout = ({
|
|
|
283
450
|
);
|
|
284
451
|
}
|
|
285
452
|
const totalEntries = release.actions.meta.count || 0;
|
|
286
|
-
const
|
|
453
|
+
const hasCreatedByUser = Boolean(getCreatedByUser());
|
|
287
454
|
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Main, { "aria-busy": isLoadingDetails, children: [
|
|
288
455
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
289
456
|
designSystem.HeaderLayout,
|
|
@@ -301,72 +468,98 @@ const ReleaseDetailsLayout = ({
|
|
|
301
468
|
defaultMessage: "Back"
|
|
302
469
|
}) }),
|
|
303
470
|
primaryAction: !release.releasedAt && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
|
304
|
-
/* @__PURE__ */ jsxRuntime.
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
{
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
471
|
+
/* @__PURE__ */ jsxRuntime.jsxs(v2.Menu.Root, { children: [
|
|
472
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
473
|
+
v2.Menu.Trigger,
|
|
474
|
+
{
|
|
475
|
+
as: designSystem.IconButton,
|
|
476
|
+
paddingLeft: 2,
|
|
477
|
+
paddingRight: 2,
|
|
478
|
+
"aria-label": formatMessage({
|
|
479
|
+
id: "content-releases.header.actions.open-release-actions",
|
|
480
|
+
defaultMessage: "Release edit and delete menu"
|
|
481
|
+
}),
|
|
482
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(icons.More, {}),
|
|
483
|
+
variant: "tertiary"
|
|
484
|
+
}
|
|
485
|
+
),
|
|
486
|
+
/* @__PURE__ */ jsxRuntime.jsxs(v2.Menu.Content, { top: 1, popoverPlacement: "bottom-end", children: [
|
|
487
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
488
|
+
designSystem.Flex,
|
|
489
|
+
{
|
|
490
|
+
alignItems: "center",
|
|
491
|
+
justifyContent: "center",
|
|
492
|
+
direction: "column",
|
|
493
|
+
padding: 1,
|
|
494
|
+
width: "100%",
|
|
495
|
+
children: [
|
|
496
|
+
/* @__PURE__ */ jsxRuntime.jsx(StyledMenuItem, { disabled: !canUpdate, onSelect: toggleEditReleaseModal, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
497
|
+
designSystem.Flex,
|
|
498
|
+
{
|
|
499
|
+
paddingTop: 2,
|
|
500
|
+
paddingBottom: 2,
|
|
501
|
+
alignItems: "center",
|
|
502
|
+
gap: 2,
|
|
503
|
+
hasRadius: true,
|
|
504
|
+
width: "100%",
|
|
505
|
+
children: [
|
|
506
|
+
/* @__PURE__ */ jsxRuntime.jsx(PencilIcon, {}),
|
|
507
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { ellipsis: true, children: formatMessage({
|
|
508
|
+
id: "content-releases.header.actions.edit",
|
|
509
|
+
defaultMessage: "Edit"
|
|
510
|
+
}) })
|
|
511
|
+
]
|
|
512
|
+
}
|
|
513
|
+
) }),
|
|
514
|
+
/* @__PURE__ */ jsxRuntime.jsx(StyledMenuItem, { disabled: !canDelete, onSelect: toggleWarningSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
515
|
+
designSystem.Flex,
|
|
516
|
+
{
|
|
517
|
+
paddingTop: 2,
|
|
518
|
+
paddingBottom: 2,
|
|
519
|
+
alignItems: "center",
|
|
520
|
+
gap: 2,
|
|
521
|
+
hasRadius: true,
|
|
522
|
+
width: "100%",
|
|
523
|
+
children: [
|
|
524
|
+
/* @__PURE__ */ jsxRuntime.jsx(TrashIcon, {}),
|
|
525
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { ellipsis: true, textColor: "danger600", children: formatMessage({
|
|
526
|
+
id: "content-releases.header.actions.delete",
|
|
527
|
+
defaultMessage: "Delete"
|
|
528
|
+
}) })
|
|
529
|
+
]
|
|
530
|
+
}
|
|
531
|
+
) })
|
|
532
|
+
]
|
|
533
|
+
}
|
|
534
|
+
),
|
|
535
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
536
|
+
ReleaseInfoWrapper,
|
|
537
|
+
{
|
|
538
|
+
direction: "column",
|
|
539
|
+
justifyContent: "center",
|
|
540
|
+
alignItems: "flex-start",
|
|
541
|
+
gap: 1,
|
|
542
|
+
padding: 5,
|
|
543
|
+
children: [
|
|
544
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", children: formatMessage({
|
|
545
|
+
id: "content-releases.header.actions.created",
|
|
546
|
+
defaultMessage: "Created"
|
|
547
|
+
}) }),
|
|
548
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", color: "neutral300", children: [
|
|
549
|
+
/* @__PURE__ */ jsxRuntime.jsx(helperPlugin.RelativeTime, { timestamp: new Date(release.createdAt) }),
|
|
550
|
+
formatMessage(
|
|
551
|
+
{
|
|
552
|
+
id: "content-releases.header.actions.created.description",
|
|
553
|
+
defaultMessage: "{hasCreatedByUser, select, true { by {createdBy}} other { by deleted user}}"
|
|
554
|
+
},
|
|
555
|
+
{ createdBy: getCreatedByUser(), hasCreatedByUser }
|
|
556
|
+
)
|
|
557
|
+
] })
|
|
558
|
+
]
|
|
559
|
+
}
|
|
560
|
+
)
|
|
561
|
+
] })
|
|
562
|
+
] }),
|
|
370
563
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { size: "S", variant: "tertiary", onClick: handleRefresh, children: formatMessage({
|
|
371
564
|
id: "content-releases.header.actions.refresh",
|
|
372
565
|
defaultMessage: "Refresh"
|
|
@@ -422,6 +615,9 @@ const ReleaseDetailsBody = () => {
|
|
|
422
615
|
isError: isReleaseError,
|
|
423
616
|
error: releaseError
|
|
424
617
|
} = index.useGetReleaseQuery({ id: releaseId });
|
|
618
|
+
const {
|
|
619
|
+
allowedActions: { canUpdate }
|
|
620
|
+
} = helperPlugin.useRBAC(index.PERMISSIONS);
|
|
425
621
|
const release = releaseData?.data;
|
|
426
622
|
const selectedGroupBy = query?.groupBy || "contentType";
|
|
427
623
|
const {
|
|
@@ -435,7 +631,7 @@ const ReleaseDetailsBody = () => {
|
|
|
435
631
|
releaseId
|
|
436
632
|
});
|
|
437
633
|
const [updateReleaseAction] = index.useUpdateReleaseActionMutation();
|
|
438
|
-
const handleChangeType = async (e, actionId) => {
|
|
634
|
+
const handleChangeType = async (e, actionId, actionPath) => {
|
|
439
635
|
const response = await updateReleaseAction({
|
|
440
636
|
params: {
|
|
441
637
|
releaseId,
|
|
@@ -443,7 +639,11 @@ const ReleaseDetailsBody = () => {
|
|
|
443
639
|
},
|
|
444
640
|
body: {
|
|
445
641
|
type: e.target.value
|
|
446
|
-
}
|
|
642
|
+
},
|
|
643
|
+
query,
|
|
644
|
+
// We are passing the query params to make optimistic updates
|
|
645
|
+
actionPath
|
|
646
|
+
// We are passing the action path to found the position in the cache of the action for optimistic updates
|
|
447
647
|
});
|
|
448
648
|
if ("error" in response) {
|
|
449
649
|
if (index.isAxiosError(response.error)) {
|
|
@@ -524,7 +724,7 @@ const ReleaseDetailsBody = () => {
|
|
|
524
724
|
designSystem.SingleSelect,
|
|
525
725
|
{
|
|
526
726
|
"aria-label": formatMessage({
|
|
527
|
-
id: "content-releases.pages.ReleaseDetails.groupBy.label",
|
|
727
|
+
id: "content-releases.pages.ReleaseDetails.groupBy.aria-label",
|
|
528
728
|
defaultMessage: "Group by"
|
|
529
729
|
}),
|
|
530
730
|
customizeContent: (value) => formatMessage(
|
|
@@ -542,7 +742,7 @@ const ReleaseDetailsBody = () => {
|
|
|
542
742
|
}
|
|
543
743
|
) }),
|
|
544
744
|
Object.keys(releaseActions).map((key) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 4, direction: "column", alignItems: "stretch", children: [
|
|
545
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { children: key }) }),
|
|
745
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { role: "separator", "aria-label": key, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { children: key }) }),
|
|
546
746
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
547
747
|
helperPlugin.Table.Root,
|
|
548
748
|
{
|
|
@@ -612,56 +812,59 @@ const ReleaseDetailsBody = () => {
|
|
|
612
812
|
)
|
|
613
813
|
] }),
|
|
614
814
|
/* @__PURE__ */ jsxRuntime.jsx(helperPlugin.Table.LoadingBody, {}),
|
|
615
|
-
/* @__PURE__ */ jsxRuntime.jsx(helperPlugin.Table.Body, { children: releaseActions[key].map(
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
{
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
isPublish: type === "publish",
|
|
626
|
-
b: (children) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children })
|
|
627
|
-
}
|
|
628
|
-
) }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
629
|
-
index.ReleaseActionOptions,
|
|
630
|
-
{
|
|
631
|
-
selected: type,
|
|
632
|
-
handleChange: (e) => handleChangeType(e, id),
|
|
633
|
-
name: `release-action-${id}-type`
|
|
634
|
-
}
|
|
635
|
-
) }),
|
|
636
|
-
!release.releasedAt && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
637
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { width: "20%", minWidth: "200px", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
638
|
-
EntryValidationText,
|
|
815
|
+
/* @__PURE__ */ jsxRuntime.jsx(helperPlugin.Table.Body, { children: releaseActions[key].map(
|
|
816
|
+
({ id, contentType, locale, type, entry }, actionIndex) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
|
|
817
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { width: "25%", maxWidth: "200px", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { ellipsis: true, children: `${contentType.mainFieldValue || entry.id}` }) }),
|
|
818
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { width: "10%", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: `${locale?.name ? locale.name : "-"}` }) }),
|
|
819
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { width: "10%", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: contentType.displayName || "" }) }),
|
|
820
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { width: "20%", children: release.releasedAt ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage(
|
|
821
|
+
{
|
|
822
|
+
id: "content-releases.page.ReleaseDetails.table.action-published",
|
|
823
|
+
defaultMessage: "This entry was <b>{isPublish, select, true {published} other {unpublished}}</b>."
|
|
824
|
+
},
|
|
639
825
|
{
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
826
|
+
isPublish: type === "publish",
|
|
827
|
+
b: (children) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children })
|
|
828
|
+
}
|
|
829
|
+
) }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
830
|
+
index.ReleaseActionOptions,
|
|
831
|
+
{
|
|
832
|
+
selected: type,
|
|
833
|
+
handleChange: (e) => handleChangeType(e, id, [key, actionIndex]),
|
|
834
|
+
name: `release-action-${id}-type`,
|
|
835
|
+
disabled: !canUpdate
|
|
644
836
|
}
|
|
645
837
|
) }),
|
|
646
|
-
|
|
647
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
648
|
-
|
|
649
|
-
{
|
|
650
|
-
contentTypeUid: contentType.uid,
|
|
651
|
-
entryId: entry.id,
|
|
652
|
-
locale: locale?.code
|
|
653
|
-
}
|
|
654
|
-
),
|
|
655
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
656
|
-
index.ReleaseActionMenu.DeleteReleaseActionItem,
|
|
838
|
+
!release.releasedAt && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
839
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { width: "20%", minWidth: "200px", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
840
|
+
EntryValidationText,
|
|
657
841
|
{
|
|
658
|
-
|
|
659
|
-
|
|
842
|
+
action: type,
|
|
843
|
+
schema: contentTypes?.[contentType.uid],
|
|
844
|
+
components,
|
|
845
|
+
entry
|
|
660
846
|
}
|
|
661
|
-
)
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
847
|
+
) }),
|
|
848
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "flex-end", children: /* @__PURE__ */ jsxRuntime.jsxs(index.ReleaseActionMenu.Root, { children: [
|
|
849
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
850
|
+
index.ReleaseActionMenu.ReleaseActionEntryLinkItem,
|
|
851
|
+
{
|
|
852
|
+
contentTypeUid: contentType.uid,
|
|
853
|
+
entryId: entry.id,
|
|
854
|
+
locale: locale?.code
|
|
855
|
+
}
|
|
856
|
+
),
|
|
857
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
858
|
+
index.ReleaseActionMenu.DeleteReleaseActionItem,
|
|
859
|
+
{
|
|
860
|
+
releaseId: release.id,
|
|
861
|
+
actionId: id
|
|
862
|
+
}
|
|
863
|
+
)
|
|
864
|
+
] }) }) })
|
|
865
|
+
] })
|
|
866
|
+
] }, id)
|
|
867
|
+
) })
|
|
665
868
|
] })
|
|
666
869
|
}
|
|
667
870
|
)
|
|
@@ -708,11 +911,18 @@ const ReleaseDetailsPage = () => {
|
|
|
708
911
|
}
|
|
709
912
|
);
|
|
710
913
|
}
|
|
711
|
-
const
|
|
914
|
+
const releaseData = isSuccessDetails && data?.data || null;
|
|
915
|
+
const title = releaseData?.name || "";
|
|
916
|
+
const timezone = releaseData?.timezone ?? null;
|
|
917
|
+
const scheduledAt = releaseData?.scheduledAt && timezone ? dateFnsTz.utcToZonedTime(releaseData.scheduledAt, timezone) : null;
|
|
918
|
+
const date = scheduledAt ? new Date(format__default.default(scheduledAt, "yyyy-MM-dd")) : null;
|
|
919
|
+
const time = scheduledAt ? format__default.default(scheduledAt, "HH:mm") : "";
|
|
712
920
|
const handleEditRelease = async (values) => {
|
|
713
921
|
const response = await updateRelease({
|
|
714
922
|
id: releaseId,
|
|
715
|
-
name: values.name
|
|
923
|
+
name: values.name,
|
|
924
|
+
scheduledAt: values.scheduledAt,
|
|
925
|
+
timezone: values.timezone
|
|
716
926
|
});
|
|
717
927
|
if ("data" in response) {
|
|
718
928
|
toggleNotification({
|
|
@@ -766,7 +976,14 @@ const ReleaseDetailsPage = () => {
|
|
|
766
976
|
handleClose: toggleEditReleaseModal,
|
|
767
977
|
handleSubmit: handleEditRelease,
|
|
768
978
|
isLoading: isLoadingDetails || isSubmittingForm,
|
|
769
|
-
initialValues: {
|
|
979
|
+
initialValues: {
|
|
980
|
+
name: title || "",
|
|
981
|
+
scheduledAt,
|
|
982
|
+
date,
|
|
983
|
+
time,
|
|
984
|
+
isScheduled: Boolean(scheduledAt),
|
|
985
|
+
timezone
|
|
986
|
+
}
|
|
770
987
|
}
|
|
771
988
|
),
|
|
772
989
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -786,37 +1003,6 @@ const ReleaseDetailsPage = () => {
|
|
|
786
1003
|
}
|
|
787
1004
|
);
|
|
788
1005
|
};
|
|
789
|
-
const ReleasesLayout = ({
|
|
790
|
-
isLoading,
|
|
791
|
-
totalReleases,
|
|
792
|
-
onClickAddRelease,
|
|
793
|
-
children
|
|
794
|
-
}) => {
|
|
795
|
-
const { formatMessage } = reactIntl.useIntl();
|
|
796
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Main, { "aria-busy": isLoading, children: [
|
|
797
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
798
|
-
designSystem.HeaderLayout,
|
|
799
|
-
{
|
|
800
|
-
title: formatMessage({
|
|
801
|
-
id: "content-releases.pages.Releases.title",
|
|
802
|
-
defaultMessage: "Releases"
|
|
803
|
-
}),
|
|
804
|
-
subtitle: !isLoading && formatMessage(
|
|
805
|
-
{
|
|
806
|
-
id: "content-releases.pages.Releases.header-subtitle",
|
|
807
|
-
defaultMessage: "{number, plural, =0 {No releases} one {# release} other {# releases}}"
|
|
808
|
-
},
|
|
809
|
-
{ number: totalReleases }
|
|
810
|
-
),
|
|
811
|
-
primaryAction: /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.CheckPermissions, { permissions: index.PERMISSIONS.create, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}), onClick: onClickAddRelease, children: formatMessage({
|
|
812
|
-
id: "content-releases.header.actions.add-release",
|
|
813
|
-
defaultMessage: "New release"
|
|
814
|
-
}) }) })
|
|
815
|
-
}
|
|
816
|
-
),
|
|
817
|
-
children
|
|
818
|
-
] });
|
|
819
|
-
};
|
|
820
1006
|
const LinkCard = styled__default.default(v2.Link)`
|
|
821
1007
|
display: block;
|
|
822
1008
|
`;
|
|
@@ -868,8 +1054,22 @@ const ReleasesGrid = ({ sectionTitle, releases = [], isError = false }) => {
|
|
|
868
1054
|
}
|
|
869
1055
|
) }) }, id)) });
|
|
870
1056
|
};
|
|
1057
|
+
const StyledAlert = styled__default.default(designSystem.Alert)`
|
|
1058
|
+
button {
|
|
1059
|
+
display: none;
|
|
1060
|
+
}
|
|
1061
|
+
p + div {
|
|
1062
|
+
margin-left: auto;
|
|
1063
|
+
}
|
|
1064
|
+
`;
|
|
871
1065
|
const INITIAL_FORM_VALUES = {
|
|
872
|
-
name: ""
|
|
1066
|
+
name: "",
|
|
1067
|
+
date: null,
|
|
1068
|
+
time: "",
|
|
1069
|
+
// Remove future flag check after Scheduling Beta release and replace with true as creating new release should include scheduling by default
|
|
1070
|
+
isScheduled: window.strapi.future.isEnabled("contentReleasesScheduling"),
|
|
1071
|
+
scheduledAt: null,
|
|
1072
|
+
timezone: null
|
|
873
1073
|
};
|
|
874
1074
|
const ReleasesPage = () => {
|
|
875
1075
|
const tabRef = React__namespace.useRef(null);
|
|
@@ -882,6 +1082,9 @@ const ReleasesPage = () => {
|
|
|
882
1082
|
const [{ query }, setQuery] = helperPlugin.useQueryParams();
|
|
883
1083
|
const response = index.useGetReleasesQuery(query);
|
|
884
1084
|
const [createRelease, { isLoading: isSubmittingForm }] = index.useCreateReleaseMutation();
|
|
1085
|
+
const { getFeature } = strapiAdmin.useLicenseLimits();
|
|
1086
|
+
const { maximumReleases = 3 } = getFeature("cms-content-releases");
|
|
1087
|
+
const { trackUsage } = helperPlugin.useTracking();
|
|
885
1088
|
const { isLoading, isSuccess, isError } = response;
|
|
886
1089
|
const activeTab = response?.currentData?.meta?.activeTab || "pending";
|
|
887
1090
|
const activeTabIndex = ["pending", "done"].indexOf(activeTab);
|
|
@@ -910,9 +1113,10 @@ const ReleasesPage = () => {
|
|
|
910
1113
|
setReleaseModalShown((prev) => !prev);
|
|
911
1114
|
};
|
|
912
1115
|
if (isLoading) {
|
|
913
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1116
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Main, { "aria-busy": isLoading, children: /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.LoadingIndicatorPage, {}) });
|
|
914
1117
|
}
|
|
915
1118
|
const totalReleases = isSuccess && response.currentData?.meta?.pagination?.total || 0;
|
|
1119
|
+
const hasReachedMaximumPendingReleases = totalReleases >= maximumReleases;
|
|
916
1120
|
const handleTabChange = (index2) => {
|
|
917
1121
|
setQuery({
|
|
918
1122
|
...query,
|
|
@@ -925,9 +1129,11 @@ const ReleasesPage = () => {
|
|
|
925
1129
|
}
|
|
926
1130
|
});
|
|
927
1131
|
};
|
|
928
|
-
const handleAddRelease = async (
|
|
1132
|
+
const handleAddRelease = async ({ name, scheduledAt, timezone }) => {
|
|
929
1133
|
const response2 = await createRelease({
|
|
930
|
-
name
|
|
1134
|
+
name,
|
|
1135
|
+
scheduledAt,
|
|
1136
|
+
timezone
|
|
931
1137
|
});
|
|
932
1138
|
if ("data" in response2) {
|
|
933
1139
|
toggleNotification({
|
|
@@ -937,6 +1143,7 @@ const ReleasesPage = () => {
|
|
|
937
1143
|
defaultMessage: "Release created."
|
|
938
1144
|
})
|
|
939
1145
|
});
|
|
1146
|
+
trackUsage("didCreateRelease");
|
|
940
1147
|
push(`/plugins/content-releases/${response2.data.data.id}`);
|
|
941
1148
|
} else if (index.isAxiosError(response2.error)) {
|
|
942
1149
|
toggleNotification({
|
|
@@ -950,8 +1157,60 @@ const ReleasesPage = () => {
|
|
|
950
1157
|
});
|
|
951
1158
|
}
|
|
952
1159
|
};
|
|
953
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1160
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Main, { "aria-busy": isLoading, children: [
|
|
1161
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1162
|
+
designSystem.HeaderLayout,
|
|
1163
|
+
{
|
|
1164
|
+
title: formatMessage({
|
|
1165
|
+
id: "content-releases.pages.Releases.title",
|
|
1166
|
+
defaultMessage: "Releases"
|
|
1167
|
+
}),
|
|
1168
|
+
subtitle: formatMessage(
|
|
1169
|
+
{
|
|
1170
|
+
id: "content-releases.pages.Releases.header-subtitle",
|
|
1171
|
+
defaultMessage: "{number, plural, =0 {No releases} one {# release} other {# releases}}"
|
|
1172
|
+
},
|
|
1173
|
+
{ number: totalReleases }
|
|
1174
|
+
),
|
|
1175
|
+
primaryAction: /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.CheckPermissions, { permissions: index.PERMISSIONS.create, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1176
|
+
designSystem.Button,
|
|
1177
|
+
{
|
|
1178
|
+
startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
|
|
1179
|
+
onClick: toggleAddReleaseModal,
|
|
1180
|
+
disabled: hasReachedMaximumPendingReleases,
|
|
1181
|
+
children: formatMessage({
|
|
1182
|
+
id: "content-releases.header.actions.add-release",
|
|
1183
|
+
defaultMessage: "New release"
|
|
1184
|
+
})
|
|
1185
|
+
}
|
|
1186
|
+
) })
|
|
1187
|
+
}
|
|
1188
|
+
),
|
|
954
1189
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.ContentLayout, { children: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1190
|
+
activeTab === "pending" && hasReachedMaximumPendingReleases && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1191
|
+
StyledAlert,
|
|
1192
|
+
{
|
|
1193
|
+
marginBottom: 6,
|
|
1194
|
+
action: /* @__PURE__ */ jsxRuntime.jsx(v2.Link, { href: "https://strapi.io/pricing-cloud", isExternal: true, children: formatMessage({
|
|
1195
|
+
id: "content-releases.pages.Releases.max-limit-reached.action",
|
|
1196
|
+
defaultMessage: "Explore plans"
|
|
1197
|
+
}) }),
|
|
1198
|
+
title: formatMessage(
|
|
1199
|
+
{
|
|
1200
|
+
id: "content-releases.pages.Releases.max-limit-reached.title",
|
|
1201
|
+
defaultMessage: "You have reached the {number} pending {number, plural, one {release} other {releases}} limit."
|
|
1202
|
+
},
|
|
1203
|
+
{ number: maximumReleases }
|
|
1204
|
+
),
|
|
1205
|
+
onClose: () => {
|
|
1206
|
+
},
|
|
1207
|
+
closeLabel: "",
|
|
1208
|
+
children: formatMessage({
|
|
1209
|
+
id: "content-releases.pages.Releases.max-limit-reached.message",
|
|
1210
|
+
defaultMessage: "Upgrade to manage an unlimited number of releases."
|
|
1211
|
+
})
|
|
1212
|
+
}
|
|
1213
|
+
),
|
|
955
1214
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
956
1215
|
designSystem.TabGroup,
|
|
957
1216
|
{
|
|
@@ -1034,4 +1293,4 @@ const App = () => {
|
|
|
1034
1293
|
] }) });
|
|
1035
1294
|
};
|
|
1036
1295
|
exports.App = App;
|
|
1037
|
-
//# sourceMappingURL=App-
|
|
1296
|
+
//# sourceMappingURL=App-w2Zq-wj5.js.map
|