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