@strapi/content-releases 0.0.0-experimental.fc1ac2acd58c8a5a858679956b6d102ac5ee4011 → 0.0.0-experimental.fed75ee8e64c57dbed0b670b25ef026b69baab10
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/LICENSE +17 -1
- package/dist/_chunks/{App-0Er6xxcq.mjs → App-BA2xDdy0.mjs} +480 -464
- package/dist/_chunks/App-BA2xDdy0.mjs.map +1 -0
- package/dist/_chunks/{App-C768ulk4.js → App-D4Wira1X.js} +497 -483
- package/dist/_chunks/App-D4Wira1X.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/ReleasesSettingsPage-BAlbMWpw.mjs +178 -0
- package/dist/_chunks/ReleasesSettingsPage-BAlbMWpw.mjs.map +1 -0
- package/dist/_chunks/ReleasesSettingsPage-xhFyRXCM.js +178 -0
- package/dist/_chunks/ReleasesSettingsPage-xhFyRXCM.js.map +1 -0
- package/dist/_chunks/{en-gcJJ5htG.js → en-CmYoEnA7.js} +19 -4
- package/dist/_chunks/en-CmYoEnA7.js.map +1 -0
- package/dist/_chunks/{en-WuuhP6Bn.mjs → en-D0yVZFqf.mjs} +19 -4
- package/dist/_chunks/en-D0yVZFqf.mjs.map +1 -0
- package/dist/_chunks/index-CCFFG3Zs.mjs +1365 -0
- package/dist/_chunks/index-CCFFG3Zs.mjs.map +1 -0
- package/dist/_chunks/index-DxkQGp4N.js +1384 -0
- package/dist/_chunks/index-DxkQGp4N.js.map +1 -0
- package/dist/_chunks/schemas-BE1LxE9J.js +62 -0
- package/dist/_chunks/schemas-BE1LxE9J.js.map +1 -0
- package/dist/_chunks/schemas-DdA2ic2U.mjs +44 -0
- package/dist/_chunks/schemas-DdA2ic2U.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/ReleaseAction.d.ts +3 -0
- package/dist/admin/src/components/ReleaseActionMenu.d.ts +4 -4
- package/dist/admin/src/components/ReleaseActionModal.d.ts +24 -0
- package/dist/admin/src/components/ReleaseListCell.d.ts +28 -0
- package/dist/admin/src/components/ReleaseModal.d.ts +3 -2
- package/dist/admin/src/components/ReleasesPanel.d.ts +3 -0
- package/dist/admin/src/constants.d.ts +18 -0
- package/dist/admin/src/modules/hooks.d.ts +7 -0
- package/dist/admin/src/pages/ReleasesSettingsPage.d.ts +1 -0
- package/dist/admin/src/services/release.d.ts +66 -323
- 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 +9 -0
- package/dist/admin/src/validation/schemas.d.ts +6 -0
- package/dist/server/index.js +1053 -646
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +1054 -647
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/src/bootstrap.d.ts +2 -2
- package/dist/server/src/bootstrap.d.ts.map +1 -1
- package/dist/server/src/constants.d.ts +11 -2
- package/dist/server/src/constants.d.ts.map +1 -1
- package/dist/server/src/content-types/index.d.ts +3 -5
- package/dist/server/src/content-types/index.d.ts.map +1 -1
- package/dist/server/src/content-types/release-action/index.d.ts +3 -5
- package/dist/server/src/content-types/release-action/index.d.ts.map +1 -1
- package/dist/server/src/content-types/release-action/schema.d.ts +3 -5
- package/dist/server/src/content-types/release-action/schema.d.ts.map +1 -1
- package/dist/server/src/controllers/index.d.ts +8 -1
- package/dist/server/src/controllers/index.d.ts.map +1 -1
- package/dist/server/src/controllers/release-action.d.ts +1 -0
- package/dist/server/src/controllers/release-action.d.ts.map +1 -1
- package/dist/server/src/controllers/release.d.ts +8 -1
- package/dist/server/src/controllers/release.d.ts.map +1 -1
- package/dist/server/src/controllers/settings.d.ts +11 -0
- package/dist/server/src/controllers/settings.d.ts.map +1 -0
- package/dist/server/src/controllers/validation/release-action.d.ts +13 -2
- package/dist/server/src/controllers/validation/release-action.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/release.d.ts +2 -0
- package/dist/server/src/controllers/validation/release.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/settings.d.ts +3 -0
- package/dist/server/src/controllers/validation/settings.d.ts.map +1 -0
- package/dist/server/src/destroy.d.ts +2 -2
- package/dist/server/src/destroy.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +1518 -3241
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/middlewares/documents.d.ts +6 -0
- package/dist/server/src/middlewares/documents.d.ts.map +1 -0
- package/dist/server/src/migrations/database/5.0.0-document-id-in-actions.d.ts +9 -0
- package/dist/server/src/migrations/database/5.0.0-document-id-in-actions.d.ts.map +1 -0
- package/dist/server/src/migrations/index.d.ts +3 -0
- package/dist/server/src/migrations/index.d.ts.map +1 -1
- package/dist/server/src/register.d.ts +2 -2
- package/dist/server/src/register.d.ts.map +1 -1
- package/dist/server/src/routes/index.d.ts +16 -0
- package/dist/server/src/routes/index.d.ts.map +1 -1
- package/dist/server/src/routes/release-action.d.ts.map +1 -1
- package/dist/server/src/routes/release.d.ts.map +1 -1
- package/dist/server/src/routes/settings.d.ts +18 -0
- package/dist/server/src/routes/settings.d.ts.map +1 -0
- package/dist/server/src/services/index.d.ts +1482 -3226
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/release-action.d.ts +38 -0
- package/dist/server/src/services/release-action.d.ts.map +1 -0
- package/dist/server/src/services/release.d.ts +19 -1800
- package/dist/server/src/services/release.d.ts.map +1 -1
- package/dist/server/src/services/scheduling.d.ts +6 -6
- package/dist/server/src/services/scheduling.d.ts.map +1 -1
- package/dist/server/src/services/settings.d.ts +13 -0
- package/dist/server/src/services/settings.d.ts.map +1 -0
- package/dist/server/src/services/validation.d.ts +7 -3
- package/dist/server/src/services/validation.d.ts.map +1 -1
- package/dist/server/src/utils/index.d.ts +33 -16
- package/dist/server/src/utils/index.d.ts.map +1 -1
- package/dist/shared/contracts/release-actions.d.ts +37 -12
- package/dist/shared/contracts/release-actions.d.ts.map +1 -1
- package/dist/shared/contracts/releases.d.ts +24 -6
- package/dist/shared/contracts/releases.d.ts.map +1 -1
- package/dist/shared/contracts/settings.d.ts +39 -0
- package/dist/shared/contracts/settings.d.ts.map +1 -0
- package/dist/shared/types.d.ts +2 -2
- package/dist/shared/types.d.ts.map +1 -1
- package/package.json +28 -26
- package/dist/_chunks/App-0Er6xxcq.mjs.map +0 -1
- package/dist/_chunks/App-C768ulk4.js.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-WuuhP6Bn.mjs.map +0 -1
- package/dist/_chunks/en-gcJJ5htG.js.map +0 -1
- package/dist/_chunks/index-BLSMpbpZ.js +0 -1028
- package/dist/_chunks/index-BLSMpbpZ.js.map +0 -1
- package/dist/_chunks/index-fJx1up7m.mjs +0 -1007
- package/dist/_chunks/index-fJx1up7m.mjs.map +0 -1
- package/dist/admin/src/components/CMReleasesContainer.d.ts +0 -1
- package/dist/admin/src/services/axios.d.ts +0 -29
- package/dist/shared/validation-schemas.d.ts +0 -2
- package/dist/shared/validation-schemas.d.ts.map +0 -1
- package/strapi-server.js +0 -3
|
@@ -1,25 +1,23 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
import { useLocation, useNavigate, useParams, Navigate, Link as Link$
|
|
4
|
-
import { g as
|
|
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 getTimezones, p as pluginId, u as useGetReleasesQuery, a as useGetReleaseSettingsQuery, b as useCreateReleaseMutation, P as PERMISSIONS, c as useGetReleaseQuery, d as useUpdateReleaseMutation, e as useDeleteReleaseMutation, f as usePublishReleaseMutation, h as getTimezoneOffset, i as useGetReleaseActionsQuery, j as useUpdateReleaseActionMutation, R as ReleaseActionOptions, k as ReleaseActionMenu, r as releaseApi } from "./index-CCFFG3Zs.mjs";
|
|
5
5
|
import * as React from "react";
|
|
6
|
-
import {
|
|
7
|
-
import { Link,
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import format from "date-fns/format";
|
|
11
|
-
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, MenuItem, SimpleMenu, Dialog, LinkButton, SingleSelect, SingleSelectOption, Tr, Td, Tooltip } from "@strapi/design-system";
|
|
8
|
+
import { Plus, Pencil, Trash, More, CrossCircle, CheckCircle, ArrowsCounterClockwise } from "@strapi/icons";
|
|
9
|
+
import { EmptyDocuments } from "@strapi/icons/symbols";
|
|
10
|
+
import format$1 from "date-fns/format";
|
|
11
|
+
import { utcToZonedTime, zonedTimeToUtc } from "date-fns-tz";
|
|
12
12
|
import { useIntl } from "react-intl";
|
|
13
|
-
import styled from "styled-components";
|
|
14
|
-
import { intervalToDuration, isPast, formatISO,
|
|
13
|
+
import { styled } from "styled-components";
|
|
14
|
+
import { intervalToDuration, isPast, formatISO, format } from "date-fns";
|
|
15
15
|
import { Formik, Form, useFormikContext } from "formik";
|
|
16
|
-
import
|
|
17
|
-
import "
|
|
18
|
-
import "
|
|
19
|
-
import "@reduxjs/toolkit/query/react";
|
|
20
|
-
import "react-redux";
|
|
16
|
+
import { R as RELEASE_SCHEMA } from "./schemas-DdA2ic2U.mjs";
|
|
17
|
+
import { useDispatch } from "react-redux";
|
|
18
|
+
import { useLicenseLimits } from "@strapi/admin/strapi-admin/ee";
|
|
21
19
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
|
22
|
-
const RelativeTime = React.forwardRef(
|
|
20
|
+
const RelativeTime$1 = React.forwardRef(
|
|
23
21
|
({ timestamp, customIntervals = [], ...restProps }, forwardedRef) => {
|
|
24
22
|
const { formatRelativeTime, formatDate, formatTime } = useIntl();
|
|
25
23
|
const interval = intervalToDuration({
|
|
@@ -48,28 +46,9 @@ const RelativeTime = React.forwardRef(
|
|
|
48
46
|
);
|
|
49
47
|
}
|
|
50
48
|
);
|
|
51
|
-
const RELEASE_SCHEMA = yup.object().shape({
|
|
52
|
-
name: yup.string().trim().required(),
|
|
53
|
-
scheduledAt: yup.string().nullable(),
|
|
54
|
-
isScheduled: yup.boolean().optional(),
|
|
55
|
-
time: yup.string().when("isScheduled", {
|
|
56
|
-
is: true,
|
|
57
|
-
then: yup.string().trim().required(),
|
|
58
|
-
otherwise: yup.string().nullable()
|
|
59
|
-
}),
|
|
60
|
-
timezone: yup.string().when("isScheduled", {
|
|
61
|
-
is: true,
|
|
62
|
-
then: yup.string().required().nullable(),
|
|
63
|
-
otherwise: yup.string().nullable()
|
|
64
|
-
}),
|
|
65
|
-
date: yup.string().when("isScheduled", {
|
|
66
|
-
is: true,
|
|
67
|
-
then: yup.string().required().nullable(),
|
|
68
|
-
otherwise: yup.string().nullable()
|
|
69
|
-
})
|
|
70
|
-
}).required().noUnknown();
|
|
71
49
|
const ReleaseModal = ({
|
|
72
50
|
handleClose,
|
|
51
|
+
open,
|
|
73
52
|
handleSubmit,
|
|
74
53
|
initialValues,
|
|
75
54
|
isLoading = false
|
|
@@ -77,7 +56,6 @@ const ReleaseModal = ({
|
|
|
77
56
|
const { formatMessage } = useIntl();
|
|
78
57
|
const { pathname } = useLocation();
|
|
79
58
|
const isCreatingRelease = pathname === `/plugins/${pluginId}`;
|
|
80
|
-
const IsSchedulingEnabled = window.strapi.future.isEnabled("contentReleasesScheduling");
|
|
81
59
|
const { timezoneList, systemTimezone = { value: "UTC+00:00-Africa/Abidjan " } } = getTimezones(
|
|
82
60
|
initialValues.scheduledAt ? new Date(initialValues.scheduledAt) : /* @__PURE__ */ new Date()
|
|
83
61
|
);
|
|
@@ -85,18 +63,17 @@ const ReleaseModal = ({
|
|
|
85
63
|
const { date, time, timezone } = values;
|
|
86
64
|
if (!date || !time || !timezone)
|
|
87
65
|
return null;
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
return zonedTimeToUtc(formattedDate, timezoneWithoutOffset);
|
|
66
|
+
const timezoneWithoutOffset = timezone.split("&")[1];
|
|
67
|
+
return zonedTimeToUtc(`${date} ${time}`, timezoneWithoutOffset);
|
|
91
68
|
};
|
|
92
69
|
const getTimezoneWithOffset = () => {
|
|
93
70
|
const currentTimezone = timezoneList.find(
|
|
94
|
-
(timezone) => timezone.value.split("
|
|
71
|
+
(timezone) => timezone.value.split("&")[1] === initialValues.timezone
|
|
95
72
|
);
|
|
96
73
|
return currentTimezone?.value || systemTimezone.value;
|
|
97
74
|
};
|
|
98
|
-
return /* @__PURE__ */
|
|
99
|
-
/* @__PURE__ */ jsx(
|
|
75
|
+
return /* @__PURE__ */ jsx(Modal.Root, { open, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Modal.Content, { children: [
|
|
76
|
+
/* @__PURE__ */ jsx(Modal.Header, { children: /* @__PURE__ */ jsx(Modal.Title, { children: formatMessage(
|
|
100
77
|
{
|
|
101
78
|
id: "content-releases.modal.title",
|
|
102
79
|
defaultMessage: "{isCreatingRelease, select, true {New release} other {Edit release}}"
|
|
@@ -109,7 +86,7 @@ const ReleaseModal = ({
|
|
|
109
86
|
onSubmit: (values) => {
|
|
110
87
|
handleSubmit({
|
|
111
88
|
...values,
|
|
112
|
-
timezone: values.timezone ? values.timezone.split("
|
|
89
|
+
timezone: values.timezone ? values.timezone.split("&")[1] : null,
|
|
113
90
|
scheduledAt: values.isScheduled ? getScheduledTimestamp(values) : null
|
|
114
91
|
});
|
|
115
92
|
},
|
|
@@ -119,31 +96,33 @@ const ReleaseModal = ({
|
|
|
119
96
|
},
|
|
120
97
|
validationSchema: RELEASE_SCHEMA,
|
|
121
98
|
validateOnChange: false,
|
|
122
|
-
children: ({ values, errors, handleChange, setFieldValue }) =>
|
|
123
|
-
|
|
124
|
-
/* @__PURE__ */ jsx(
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
defaultMessage:
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
99
|
+
children: ({ values, errors, handleChange, setFieldValue }) => {
|
|
100
|
+
return /* @__PURE__ */ jsxs(Form, { children: [
|
|
101
|
+
/* @__PURE__ */ jsx(Modal.Body, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: [
|
|
102
|
+
/* @__PURE__ */ jsxs(
|
|
103
|
+
Field.Root,
|
|
104
|
+
{
|
|
105
|
+
name: "name",
|
|
106
|
+
error: errors.name && formatMessage({ id: errors.name, defaultMessage: errors.name }),
|
|
107
|
+
required: true,
|
|
108
|
+
children: [
|
|
109
|
+
/* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
|
|
110
|
+
id: "content-releases.modal.form.input.label.release-name",
|
|
111
|
+
defaultMessage: "Name"
|
|
112
|
+
}) }),
|
|
113
|
+
/* @__PURE__ */ jsx(TextInput, { value: values.name, onChange: handleChange }),
|
|
114
|
+
/* @__PURE__ */ jsx(Field.Error, {})
|
|
115
|
+
]
|
|
116
|
+
}
|
|
117
|
+
),
|
|
139
118
|
/* @__PURE__ */ jsx(Box, { width: "max-content", children: /* @__PURE__ */ jsx(
|
|
140
119
|
Checkbox,
|
|
141
120
|
{
|
|
142
121
|
name: "isScheduled",
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
setFieldValue("isScheduled",
|
|
146
|
-
if (!
|
|
122
|
+
checked: values.isScheduled,
|
|
123
|
+
onCheckedChange: (checked) => {
|
|
124
|
+
setFieldValue("isScheduled", checked);
|
|
125
|
+
if (!checked) {
|
|
147
126
|
setFieldValue("date", null);
|
|
148
127
|
setFieldValue("time", "");
|
|
149
128
|
setFieldValue("timezone", null);
|
|
@@ -171,85 +150,89 @@ const ReleaseModal = ({
|
|
|
171
150
|
) }),
|
|
172
151
|
values.isScheduled && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
173
152
|
/* @__PURE__ */ jsxs(Flex, { gap: 4, alignItems: "start", children: [
|
|
174
|
-
/* @__PURE__ */ jsx(Box, { width: "100%", children: /* @__PURE__ */
|
|
175
|
-
|
|
153
|
+
/* @__PURE__ */ jsx(Box, { width: "100%", children: /* @__PURE__ */ jsxs(
|
|
154
|
+
Field.Root,
|
|
176
155
|
{
|
|
177
|
-
label: formatMessage({
|
|
178
|
-
id: "content-releases.modal.form.input.label.date",
|
|
179
|
-
defaultMessage: "Date"
|
|
180
|
-
}),
|
|
181
156
|
name: "date",
|
|
182
|
-
error: errors.date,
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
157
|
+
error: errors.date && formatMessage({ id: errors.date, defaultMessage: errors.date }),
|
|
158
|
+
required: true,
|
|
159
|
+
children: [
|
|
160
|
+
/* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
|
|
161
|
+
id: "content-releases.modal.form.input.label.date",
|
|
162
|
+
defaultMessage: "Date"
|
|
163
|
+
}) }),
|
|
164
|
+
/* @__PURE__ */ jsx(
|
|
165
|
+
DatePicker,
|
|
166
|
+
{
|
|
167
|
+
onChange: (date) => {
|
|
168
|
+
const isoFormatDate = date ? formatISO(date, { representation: "date" }) : null;
|
|
169
|
+
setFieldValue("date", isoFormatDate);
|
|
170
|
+
},
|
|
171
|
+
clearLabel: formatMessage({
|
|
172
|
+
id: "content-releases.modal.form.input.clearLabel",
|
|
173
|
+
defaultMessage: "Clear"
|
|
174
|
+
}),
|
|
175
|
+
onClear: () => {
|
|
176
|
+
setFieldValue("date", null);
|
|
177
|
+
},
|
|
178
|
+
value: values.date ? new Date(values.date) : /* @__PURE__ */ new Date(),
|
|
179
|
+
minDate: utcToZonedTime(/* @__PURE__ */ new Date(), values.timezone.split("&")[1])
|
|
180
|
+
}
|
|
181
|
+
),
|
|
182
|
+
/* @__PURE__ */ jsx(Field.Error, {})
|
|
183
|
+
]
|
|
196
184
|
}
|
|
197
185
|
) }),
|
|
198
|
-
/* @__PURE__ */ jsx(Box, { width: "100%", children: /* @__PURE__ */
|
|
199
|
-
|
|
186
|
+
/* @__PURE__ */ jsx(Box, { width: "100%", children: /* @__PURE__ */ jsxs(
|
|
187
|
+
Field.Root,
|
|
200
188
|
{
|
|
201
|
-
label: formatMessage({
|
|
202
|
-
id: "content-releases.modal.form.input.label.time",
|
|
203
|
-
defaultMessage: "Time"
|
|
204
|
-
}),
|
|
205
189
|
name: "time",
|
|
206
|
-
error: errors.time,
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
190
|
+
error: errors.time && formatMessage({ id: errors.time, defaultMessage: errors.time }),
|
|
191
|
+
required: true,
|
|
192
|
+
children: [
|
|
193
|
+
/* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
|
|
194
|
+
id: "content-releases.modal.form.input.label.time",
|
|
195
|
+
defaultMessage: "Time"
|
|
196
|
+
}) }),
|
|
197
|
+
/* @__PURE__ */ jsx(
|
|
198
|
+
TimePicker,
|
|
199
|
+
{
|
|
200
|
+
onChange: (time) => {
|
|
201
|
+
setFieldValue("time", time);
|
|
202
|
+
},
|
|
203
|
+
clearLabel: formatMessage({
|
|
204
|
+
id: "content-releases.modal.form.input.clearLabel",
|
|
205
|
+
defaultMessage: "Clear"
|
|
206
|
+
}),
|
|
207
|
+
onClear: () => {
|
|
208
|
+
setFieldValue("time", "");
|
|
209
|
+
},
|
|
210
|
+
value: values.time || void 0
|
|
211
|
+
}
|
|
212
|
+
),
|
|
213
|
+
/* @__PURE__ */ jsx(Field.Error, {})
|
|
214
|
+
]
|
|
219
215
|
}
|
|
220
216
|
) })
|
|
221
217
|
] }),
|
|
222
218
|
/* @__PURE__ */ jsx(TimezoneComponent, { timezoneOptions: timezoneList })
|
|
223
219
|
] })
|
|
224
|
-
] })
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
{
|
|
229
|
-
startActions: /* @__PURE__ */ jsx(Button, { onClick: handleClose, variant: "tertiary", name: "cancel", children: formatMessage({ id: "cancel", defaultMessage: "Cancel" }) }),
|
|
230
|
-
endActions: /* @__PURE__ */ jsx(Button, { name: "submit", loading: isLoading, type: "submit", children: formatMessage(
|
|
220
|
+
] }) }),
|
|
221
|
+
/* @__PURE__ */ jsxs(Modal.Footer, { children: [
|
|
222
|
+
/* @__PURE__ */ jsx(Modal.Close, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", name: "cancel", children: formatMessage({ id: "cancel", defaultMessage: "Cancel" }) }) }),
|
|
223
|
+
/* @__PURE__ */ jsx(Button, { name: "submit", loading: isLoading, type: "submit", children: formatMessage(
|
|
231
224
|
{
|
|
232
225
|
id: "content-releases.modal.form.button.submit",
|
|
233
226
|
defaultMessage: "{isCreatingRelease, select, true {Continue} other {Save}}"
|
|
234
227
|
},
|
|
235
228
|
{ isCreatingRelease }
|
|
236
229
|
) })
|
|
237
|
-
}
|
|
238
|
-
)
|
|
239
|
-
|
|
230
|
+
] })
|
|
231
|
+
] });
|
|
232
|
+
}
|
|
240
233
|
}
|
|
241
234
|
)
|
|
242
|
-
] });
|
|
243
|
-
};
|
|
244
|
-
const getTimezones = (selectedDate) => {
|
|
245
|
-
const timezoneList = Intl.supportedValuesOf("timeZone").map((timezone) => {
|
|
246
|
-
const utcOffset = getTimezoneOffset(timezone, selectedDate);
|
|
247
|
-
return { offset: utcOffset, value: `${utcOffset}_${timezone}` };
|
|
248
|
-
});
|
|
249
|
-
const systemTimezone = timezoneList.find(
|
|
250
|
-
(timezone) => timezone.value.split("_")[1] === Intl.DateTimeFormat().resolvedOptions().timeZone
|
|
251
|
-
);
|
|
252
|
-
return { timezoneList, systemTimezone };
|
|
235
|
+
] }) });
|
|
253
236
|
};
|
|
254
237
|
const TimezoneComponent = ({ timezoneOptions }) => {
|
|
255
238
|
const { values, errors, setFieldValue } = useFormikContext();
|
|
@@ -259,42 +242,58 @@ const TimezoneComponent = ({ timezoneOptions }) => {
|
|
|
259
242
|
if (values.date) {
|
|
260
243
|
const { timezoneList: timezoneList2 } = getTimezones(new Date(values.date));
|
|
261
244
|
setTimezoneList(timezoneList2);
|
|
262
|
-
const updatedTimezone = values.timezone && timezoneList2.find((tz) => tz.value.split("
|
|
245
|
+
const updatedTimezone = values.timezone && timezoneList2.find((tz) => tz.value.split("&")[1] === values.timezone.split("&")[1]);
|
|
263
246
|
if (updatedTimezone) {
|
|
264
247
|
setFieldValue("timezone", updatedTimezone.value);
|
|
265
248
|
}
|
|
266
249
|
}
|
|
267
250
|
}, [setFieldValue, values.date, values.timezone]);
|
|
268
|
-
return /* @__PURE__ */
|
|
269
|
-
|
|
251
|
+
return /* @__PURE__ */ jsxs(
|
|
252
|
+
Field.Root,
|
|
270
253
|
{
|
|
271
|
-
label: formatMessage({
|
|
272
|
-
id: "content-releases.modal.form.input.label.timezone",
|
|
273
|
-
defaultMessage: "Timezone"
|
|
274
|
-
}),
|
|
275
254
|
name: "timezone",
|
|
276
|
-
|
|
277
|
-
textValue: values.timezone ? values.timezone.replace("_", " ") : void 0,
|
|
278
|
-
onChange: (timezone) => {
|
|
279
|
-
setFieldValue("timezone", timezone);
|
|
280
|
-
},
|
|
281
|
-
onTextValueChange: (timezone) => {
|
|
282
|
-
setFieldValue("timezone", timezone);
|
|
283
|
-
},
|
|
284
|
-
onClear: () => {
|
|
285
|
-
setFieldValue("timezone", "");
|
|
286
|
-
},
|
|
287
|
-
error: errors.timezone,
|
|
255
|
+
error: errors.timezone && formatMessage({ id: errors.timezone, defaultMessage: errors.timezone }),
|
|
288
256
|
required: true,
|
|
289
|
-
children:
|
|
257
|
+
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
|
+
]
|
|
290
282
|
}
|
|
291
283
|
);
|
|
292
284
|
};
|
|
285
|
+
const useTypedDispatch = useDispatch;
|
|
286
|
+
const isBaseQueryError = (error) => {
|
|
287
|
+
return typeof error !== "undefined" && error.name !== void 0;
|
|
288
|
+
};
|
|
293
289
|
const LinkCard = styled(Link)`
|
|
294
290
|
display: block;
|
|
295
291
|
`;
|
|
296
|
-
const
|
|
297
|
-
|
|
292
|
+
const RelativeTime = styled(RelativeTime$1)`
|
|
293
|
+
display: inline-block;
|
|
294
|
+
&::first-letter {
|
|
295
|
+
text-transform: uppercase;
|
|
296
|
+
}
|
|
298
297
|
`;
|
|
299
298
|
const getBadgeProps = (status) => {
|
|
300
299
|
let color;
|
|
@@ -323,7 +322,6 @@ const getBadgeProps = (status) => {
|
|
|
323
322
|
};
|
|
324
323
|
const ReleasesGrid = ({ sectionTitle, releases = [], isError = false }) => {
|
|
325
324
|
const { formatMessage } = useIntl();
|
|
326
|
-
const IsSchedulingEnabled = window.strapi.future.isEnabled("contentReleasesScheduling");
|
|
327
325
|
if (isError) {
|
|
328
326
|
return /* @__PURE__ */ jsx(Page.Error, {});
|
|
329
327
|
}
|
|
@@ -340,11 +338,11 @@ const ReleasesGrid = ({ sectionTitle, releases = [], isError = false }) => {
|
|
|
340
338
|
target: sectionTitle
|
|
341
339
|
}
|
|
342
340
|
),
|
|
343
|
-
icon: /* @__PURE__ */ jsx(EmptyDocuments, { width: "
|
|
341
|
+
icon: /* @__PURE__ */ jsx(EmptyDocuments, { width: "16rem" })
|
|
344
342
|
}
|
|
345
343
|
);
|
|
346
344
|
}
|
|
347
|
-
return /* @__PURE__ */ jsx(Grid, { gap: 4, children: releases.map(({ id, name,
|
|
345
|
+
return /* @__PURE__ */ jsx(Grid.Root, { gap: 4, children: releases.map(({ id, name, scheduledAt, status }) => /* @__PURE__ */ jsx(Grid.Item, { col: 3, s: 6, xs: 12, direction: "column", alignItems: "stretch", children: /* @__PURE__ */ jsx(LinkCard, { tag: NavLink, to: `${id}`, isExternal: false, children: /* @__PURE__ */ jsxs(
|
|
348
346
|
Flex,
|
|
349
347
|
{
|
|
350
348
|
direction: "column",
|
|
@@ -359,17 +357,11 @@ const ReleasesGrid = ({ sectionTitle, releases = [], isError = false }) => {
|
|
|
359
357
|
gap: 4,
|
|
360
358
|
children: [
|
|
361
359
|
/* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "start", gap: 1, children: [
|
|
362
|
-
/* @__PURE__ */ jsx(Typography, {
|
|
363
|
-
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children:
|
|
360
|
+
/* @__PURE__ */ jsx(Typography, { textColor: "neutral800", tag: "h3", variant: "delta", fontWeight: "bold", children: name }),
|
|
361
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: scheduledAt ? /* @__PURE__ */ jsx(RelativeTime, { timestamp: new Date(scheduledAt) }) : formatMessage({
|
|
364
362
|
id: "content-releases.pages.Releases.not-scheduled",
|
|
365
363
|
defaultMessage: "Not scheduled"
|
|
366
|
-
})
|
|
367
|
-
{
|
|
368
|
-
id: "content-releases.page.Releases.release-item.entries",
|
|
369
|
-
defaultMessage: "{number, plural, =0 {No entries} one {# entry} other {# entries}}"
|
|
370
|
-
},
|
|
371
|
-
{ number: actions.meta.count }
|
|
372
|
-
) })
|
|
364
|
+
}) })
|
|
373
365
|
] }),
|
|
374
366
|
/* @__PURE__ */ jsx(Badge, { ...getBadgeProps(status), children: status })
|
|
375
367
|
]
|
|
@@ -386,34 +378,35 @@ const StyledAlert = styled(Alert)`
|
|
|
386
378
|
`;
|
|
387
379
|
const INITIAL_FORM_VALUES = {
|
|
388
380
|
name: "",
|
|
389
|
-
date:
|
|
381
|
+
date: format(/* @__PURE__ */ new Date(), "yyyy-MM-dd"),
|
|
390
382
|
time: "",
|
|
391
|
-
|
|
392
|
-
isScheduled: window.strapi.future.isEnabled("contentReleasesScheduling"),
|
|
383
|
+
isScheduled: true,
|
|
393
384
|
scheduledAt: null,
|
|
394
385
|
timezone: null
|
|
395
386
|
};
|
|
396
387
|
const ReleasesPage = () => {
|
|
397
|
-
const tabRef = React.useRef(null);
|
|
398
388
|
const location = useLocation();
|
|
399
389
|
const [releaseModalShown, setReleaseModalShown] = React.useState(false);
|
|
400
|
-
const toggleNotification = useNotification();
|
|
390
|
+
const { toggleNotification } = useNotification();
|
|
401
391
|
const { formatMessage } = useIntl();
|
|
402
392
|
const navigate = useNavigate();
|
|
403
393
|
const { formatAPIError } = useAPIErrorHandler();
|
|
404
394
|
const [{ query }, setQuery] = useQueryParams();
|
|
405
395
|
const response = useGetReleasesQuery(query);
|
|
396
|
+
const { data, isLoading: isLoadingSettings } = useGetReleaseSettingsQuery();
|
|
406
397
|
const [createRelease, { isLoading: isSubmittingForm }] = useCreateReleaseMutation();
|
|
407
398
|
const { getFeature } = useLicenseLimits();
|
|
408
399
|
const { maximumReleases = 3 } = getFeature("cms-content-releases");
|
|
409
400
|
const { trackUsage } = useTracking();
|
|
410
|
-
const {
|
|
401
|
+
const {
|
|
402
|
+
allowedActions: { canCreate }
|
|
403
|
+
} = useRBAC(PERMISSIONS);
|
|
404
|
+
const { isLoading: isLoadingReleases, isSuccess, isError } = response;
|
|
411
405
|
const activeTab = response?.currentData?.meta?.activeTab || "pending";
|
|
412
|
-
const activeTabIndex = ["pending", "done"].indexOf(activeTab);
|
|
413
406
|
React.useEffect(() => {
|
|
414
407
|
if (location?.state?.errors) {
|
|
415
408
|
toggleNotification({
|
|
416
|
-
type: "
|
|
409
|
+
type: "danger",
|
|
417
410
|
title: formatMessage({
|
|
418
411
|
id: "content-releases.pages.Releases.notification.error.title",
|
|
419
412
|
defaultMessage: "Your request could not be processed."
|
|
@@ -426,27 +419,22 @@ const ReleasesPage = () => {
|
|
|
426
419
|
navigate("", { replace: true, state: null });
|
|
427
420
|
}
|
|
428
421
|
}, [formatMessage, location?.state?.errors, navigate, toggleNotification]);
|
|
429
|
-
React.useEffect(() => {
|
|
430
|
-
if (tabRef.current) {
|
|
431
|
-
tabRef.current._handlers.setSelectedTabIndex(activeTabIndex);
|
|
432
|
-
}
|
|
433
|
-
}, [activeTabIndex]);
|
|
434
422
|
const toggleAddReleaseModal = () => {
|
|
435
423
|
setReleaseModalShown((prev) => !prev);
|
|
436
424
|
};
|
|
437
|
-
if (
|
|
425
|
+
if (isLoadingReleases || isLoadingSettings) {
|
|
438
426
|
return /* @__PURE__ */ jsx(Page.Loading, {});
|
|
439
427
|
}
|
|
440
428
|
const totalPendingReleases = isSuccess && response.currentData?.meta?.pendingReleasesCount || 0;
|
|
441
429
|
const hasReachedMaximumPendingReleases = totalPendingReleases >= maximumReleases;
|
|
442
|
-
const handleTabChange = (
|
|
430
|
+
const handleTabChange = (tabValue) => {
|
|
443
431
|
setQuery({
|
|
444
432
|
...query,
|
|
445
433
|
page: 1,
|
|
446
434
|
pageSize: response?.currentData?.meta?.pagination?.pageSize || 16,
|
|
447
435
|
filters: {
|
|
448
436
|
releasedAt: {
|
|
449
|
-
$notNull:
|
|
437
|
+
$notNull: tabValue !== "pending"
|
|
450
438
|
}
|
|
451
439
|
}
|
|
452
440
|
});
|
|
@@ -467,21 +455,21 @@ const ReleasesPage = () => {
|
|
|
467
455
|
});
|
|
468
456
|
trackUsage("didCreateRelease");
|
|
469
457
|
navigate(response2.data.data.id.toString());
|
|
470
|
-
} else if (
|
|
458
|
+
} else if (isFetchError(response2.error)) {
|
|
471
459
|
toggleNotification({
|
|
472
|
-
type: "
|
|
460
|
+
type: "danger",
|
|
473
461
|
message: formatAPIError(response2.error)
|
|
474
462
|
});
|
|
475
463
|
} else {
|
|
476
464
|
toggleNotification({
|
|
477
|
-
type: "
|
|
465
|
+
type: "danger",
|
|
478
466
|
message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
|
|
479
467
|
});
|
|
480
468
|
}
|
|
481
469
|
};
|
|
482
|
-
return /* @__PURE__ */ jsxs(Main, { "aria-busy":
|
|
470
|
+
return /* @__PURE__ */ jsxs(Main, { "aria-busy": isLoadingReleases || isLoadingSettings, children: [
|
|
483
471
|
/* @__PURE__ */ jsx(
|
|
484
|
-
|
|
472
|
+
Layouts.Header,
|
|
485
473
|
{
|
|
486
474
|
title: formatMessage({
|
|
487
475
|
id: "content-releases.pages.Releases.title",
|
|
@@ -491,7 +479,7 @@ const ReleasesPage = () => {
|
|
|
491
479
|
id: "content-releases.pages.Releases.header-subtitle",
|
|
492
480
|
defaultMessage: "Create and manage content updates"
|
|
493
481
|
}),
|
|
494
|
-
primaryAction:
|
|
482
|
+
primaryAction: canCreate ? /* @__PURE__ */ jsx(
|
|
495
483
|
Button,
|
|
496
484
|
{
|
|
497
485
|
startIcon: /* @__PURE__ */ jsx(Plus, {}),
|
|
@@ -502,10 +490,10 @@ const ReleasesPage = () => {
|
|
|
502
490
|
defaultMessage: "New release"
|
|
503
491
|
})
|
|
504
492
|
}
|
|
505
|
-
)
|
|
493
|
+
) : null
|
|
506
494
|
}
|
|
507
495
|
),
|
|
508
|
-
/* @__PURE__ */ jsx(
|
|
496
|
+
/* @__PURE__ */ jsx(Layouts.Content, { children: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
509
497
|
hasReachedMaximumPendingReleases && /* @__PURE__ */ jsx(
|
|
510
498
|
StyledAlert,
|
|
511
499
|
{
|
|
@@ -530,21 +518,17 @@ const ReleasesPage = () => {
|
|
|
530
518
|
})
|
|
531
519
|
}
|
|
532
520
|
),
|
|
533
|
-
/* @__PURE__ */ jsxs(
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
children: [
|
|
545
|
-
/* @__PURE__ */ jsxs(Box, { paddingBottom: 8, children: [
|
|
546
|
-
/* @__PURE__ */ jsxs(Tabs, { children: [
|
|
547
|
-
/* @__PURE__ */ jsx(Tab, { children: formatMessage(
|
|
521
|
+
/* @__PURE__ */ jsxs(Tabs.Root, { variant: "simple", onValueChange: handleTabChange, value: activeTab, children: [
|
|
522
|
+
/* @__PURE__ */ jsxs(Box, { paddingBottom: 8, children: [
|
|
523
|
+
/* @__PURE__ */ jsxs(
|
|
524
|
+
Tabs.List,
|
|
525
|
+
{
|
|
526
|
+
"aria-label": formatMessage({
|
|
527
|
+
id: "content-releases.pages.Releases.tab-group.label",
|
|
528
|
+
defaultMessage: "Releases list"
|
|
529
|
+
}),
|
|
530
|
+
children: [
|
|
531
|
+
/* @__PURE__ */ jsx(Tabs.Trigger, { value: "pending", children: formatMessage(
|
|
548
532
|
{
|
|
549
533
|
id: "content-releases.pages.Releases.tab.pending",
|
|
550
534
|
defaultMessage: "Pending ({count})"
|
|
@@ -553,34 +537,32 @@ const ReleasesPage = () => {
|
|
|
553
537
|
count: totalPendingReleases
|
|
554
538
|
}
|
|
555
539
|
) }),
|
|
556
|
-
/* @__PURE__ */ jsx(
|
|
540
|
+
/* @__PURE__ */ jsx(Tabs.Trigger, { value: "done", children: formatMessage({
|
|
557
541
|
id: "content-releases.pages.Releases.tab.done",
|
|
558
542
|
defaultMessage: "Done"
|
|
559
543
|
}) })
|
|
560
|
-
]
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
}
|
|
583
|
-
),
|
|
544
|
+
]
|
|
545
|
+
}
|
|
546
|
+
),
|
|
547
|
+
/* @__PURE__ */ jsx(Divider, {})
|
|
548
|
+
] }),
|
|
549
|
+
/* @__PURE__ */ jsx(Tabs.Content, { value: "pending", children: /* @__PURE__ */ jsx(
|
|
550
|
+
ReleasesGrid,
|
|
551
|
+
{
|
|
552
|
+
sectionTitle: "pending",
|
|
553
|
+
releases: response?.currentData?.data,
|
|
554
|
+
isError
|
|
555
|
+
}
|
|
556
|
+
) }),
|
|
557
|
+
/* @__PURE__ */ jsx(Tabs.Content, { value: "done", children: /* @__PURE__ */ jsx(
|
|
558
|
+
ReleasesGrid,
|
|
559
|
+
{
|
|
560
|
+
sectionTitle: "done",
|
|
561
|
+
releases: response?.currentData?.data,
|
|
562
|
+
isError
|
|
563
|
+
}
|
|
564
|
+
) })
|
|
565
|
+
] }),
|
|
584
566
|
/* @__PURE__ */ jsxs(
|
|
585
567
|
Pagination.Root,
|
|
586
568
|
{
|
|
@@ -593,13 +575,17 @@ const ReleasesPage = () => {
|
|
|
593
575
|
}
|
|
594
576
|
)
|
|
595
577
|
] }) }),
|
|
596
|
-
|
|
578
|
+
/* @__PURE__ */ jsx(
|
|
597
579
|
ReleaseModal,
|
|
598
580
|
{
|
|
581
|
+
open: releaseModalShown,
|
|
599
582
|
handleClose: toggleAddReleaseModal,
|
|
600
583
|
handleSubmit: handleAddRelease,
|
|
601
584
|
isLoading: isSubmittingForm,
|
|
602
|
-
initialValues:
|
|
585
|
+
initialValues: {
|
|
586
|
+
...INITIAL_FORM_VALUES,
|
|
587
|
+
timezone: data?.data.defaultTimezone ? data.data.defaultTimezone.split("&")[1] : null
|
|
588
|
+
}
|
|
603
589
|
}
|
|
604
590
|
)
|
|
605
591
|
] });
|
|
@@ -610,7 +596,7 @@ const ReleaseInfoWrapper = styled(Flex)`
|
|
|
610
596
|
border-bottom-left-radius: ${({ theme }) => theme.borderRadius};
|
|
611
597
|
border-top: 1px solid ${({ theme }) => theme.colors.neutral150};
|
|
612
598
|
`;
|
|
613
|
-
const StyledMenuItem = styled(
|
|
599
|
+
const StyledMenuItem = styled(MenuItem)`
|
|
614
600
|
svg path {
|
|
615
601
|
fill: ${({ theme, disabled }) => disabled && theme.colors.neutral500};
|
|
616
602
|
}
|
|
@@ -619,19 +605,19 @@ const StyledMenuItem = styled(Menu.Item)`
|
|
|
619
605
|
}
|
|
620
606
|
|
|
621
607
|
&:hover {
|
|
622
|
-
background: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}100`]};
|
|
608
|
+
background: ${({ theme, $variant = "neutral" }) => theme.colors[`${$variant}100`]};
|
|
623
609
|
}
|
|
624
610
|
`;
|
|
625
611
|
const PencilIcon = styled(Pencil)`
|
|
626
|
-
width: ${({ theme }) => theme.spaces[
|
|
627
|
-
height: ${({ theme }) => theme.spaces[
|
|
612
|
+
width: ${({ theme }) => theme.spaces[4]};
|
|
613
|
+
height: ${({ theme }) => theme.spaces[4]};
|
|
628
614
|
path {
|
|
629
615
|
fill: ${({ theme }) => theme.colors.neutral600};
|
|
630
616
|
}
|
|
631
617
|
`;
|
|
632
618
|
const TrashIcon = styled(Trash)`
|
|
633
|
-
width: ${({ theme }) => theme.spaces[
|
|
634
|
-
height: ${({ theme }) => theme.spaces[
|
|
619
|
+
width: ${({ theme }) => theme.spaces[4]};
|
|
620
|
+
height: ${({ theme }) => theme.spaces[4]};
|
|
635
621
|
path {
|
|
636
622
|
fill: ${({ theme }) => theme.colors.danger600};
|
|
637
623
|
}
|
|
@@ -639,44 +625,93 @@ const TrashIcon = styled(Trash)`
|
|
|
639
625
|
const TypographyMaxWidth = styled(Typography)`
|
|
640
626
|
max-width: 300px;
|
|
641
627
|
`;
|
|
642
|
-
const EntryValidationText = ({ action, schema, entry }) => {
|
|
628
|
+
const EntryValidationText = ({ action, schema, entry, status }) => {
|
|
643
629
|
const { formatMessage } = useIntl();
|
|
644
|
-
const { validate } = unstable_useDocument(
|
|
630
|
+
const { validate, isLoading } = unstable_useDocument(
|
|
645
631
|
{
|
|
646
632
|
collectionType: schema?.kind ?? "",
|
|
647
633
|
model: schema?.uid ?? ""
|
|
648
634
|
},
|
|
649
635
|
{
|
|
650
|
-
skip
|
|
636
|
+
// useDocument makes a request to get more data about the entry, but we only want to have the validation function so we skip the request
|
|
637
|
+
skip: true
|
|
651
638
|
}
|
|
652
639
|
);
|
|
653
|
-
const
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
640
|
+
const errorsToString = (errors2, prefix = "") => {
|
|
641
|
+
if (Object.keys(errors2).length === 0) {
|
|
642
|
+
return "";
|
|
643
|
+
}
|
|
644
|
+
return Object.entries(errors2).map(([key, value]) => {
|
|
645
|
+
if (value === void 0 || value === null) {
|
|
646
|
+
return "";
|
|
647
|
+
}
|
|
648
|
+
if (typeof value === "string") {
|
|
649
|
+
return formatMessage(
|
|
650
|
+
{ id: value, defaultMessage: value },
|
|
651
|
+
{ field: prefix ? `${prefix}.${key}` : key }
|
|
652
|
+
);
|
|
653
|
+
}
|
|
654
|
+
if (typeof value === "object" && value !== null && "id" in value && "defaultMessage" in value) {
|
|
655
|
+
return formatMessage(
|
|
656
|
+
// @ts-expect-error – TODO: default message will be a string
|
|
657
|
+
{ id: `${value.id}.withField`, defaultMessage: value.defaultMessage },
|
|
658
|
+
{ field: prefix ? `${prefix}.${key}` : key }
|
|
659
|
+
);
|
|
660
|
+
}
|
|
661
|
+
return errorsToString(value, key);
|
|
662
|
+
}).join(" ");
|
|
663
|
+
};
|
|
664
|
+
if (isLoading) {
|
|
665
|
+
return null;
|
|
665
666
|
}
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
667
|
+
const errors = validate(entry) ?? {};
|
|
668
|
+
if (action === "publish") {
|
|
669
|
+
if (Object.keys(errors).length > 0) {
|
|
670
|
+
const validationErrorsMessages = errorsToString(errors);
|
|
671
|
+
return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
|
672
|
+
/* @__PURE__ */ jsx(CrossCircle, { fill: "danger600" }),
|
|
673
|
+
/* @__PURE__ */ jsx(Tooltip, { description: validationErrorsMessages, children: /* @__PURE__ */ jsx(
|
|
674
|
+
TypographyMaxWidth,
|
|
675
|
+
{
|
|
676
|
+
textColor: "danger600",
|
|
677
|
+
variant: "omega",
|
|
678
|
+
fontWeight: "semiBold",
|
|
679
|
+
ellipsis: true,
|
|
680
|
+
children: validationErrorsMessages
|
|
681
|
+
}
|
|
682
|
+
) })
|
|
683
|
+
] });
|
|
684
|
+
}
|
|
685
|
+
if (status === "draft") {
|
|
686
|
+
return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
|
687
|
+
/* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
|
|
688
|
+
/* @__PURE__ */ jsx(Typography, { children: formatMessage({
|
|
689
|
+
id: "content-releases.pages.ReleaseDetails.entry-validation.ready-to-publish",
|
|
690
|
+
defaultMessage: "Ready to publish"
|
|
691
|
+
}) })
|
|
692
|
+
] });
|
|
693
|
+
}
|
|
694
|
+
if (status === "modified") {
|
|
695
|
+
return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
|
696
|
+
/* @__PURE__ */ jsx(ArrowsCounterClockwise, { fill: "alternative600" }),
|
|
697
|
+
/* @__PURE__ */ jsx(Typography, { children: formatMessage({
|
|
698
|
+
id: "content-releases.pages.ReleaseDetails.entry-validation.modified",
|
|
699
|
+
defaultMessage: "Ready to publish changes"
|
|
700
|
+
}) })
|
|
701
|
+
] });
|
|
702
|
+
}
|
|
703
|
+
if (status === "published") {
|
|
704
|
+
return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
|
705
|
+
/* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
|
|
706
|
+
/* @__PURE__ */ jsx(Typography, { children: formatMessage({
|
|
707
|
+
id: "content-releases.pages.ReleaseDetails.entry-validation.already-published",
|
|
708
|
+
defaultMessage: "Already published"
|
|
709
|
+
}) })
|
|
710
|
+
] });
|
|
711
|
+
}
|
|
677
712
|
}
|
|
678
713
|
return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
|
679
|
-
/* @__PURE__ */ jsx(
|
|
714
|
+
/* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
|
|
680
715
|
!entry.publishedAt ? /* @__PURE__ */ jsx(Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
|
|
681
716
|
id: "content-releases.pages.ReleaseDetails.entry-validation.already-unpublished",
|
|
682
717
|
defaultMessage: "Already unpublished"
|
|
@@ -696,7 +731,6 @@ const ReleaseDetailsLayout = ({
|
|
|
696
731
|
const {
|
|
697
732
|
data,
|
|
698
733
|
isLoading: isLoadingDetails,
|
|
699
|
-
isError,
|
|
700
734
|
error
|
|
701
735
|
} = useGetReleaseQuery(
|
|
702
736
|
{ id: releaseId },
|
|
@@ -705,11 +739,10 @@ const ReleaseDetailsLayout = ({
|
|
|
705
739
|
}
|
|
706
740
|
);
|
|
707
741
|
const [publishRelease, { isLoading: isPublishing }] = usePublishReleaseMutation();
|
|
708
|
-
const toggleNotification = useNotification();
|
|
742
|
+
const { toggleNotification } = useNotification();
|
|
709
743
|
const { formatAPIError } = useAPIErrorHandler();
|
|
710
|
-
const {
|
|
711
|
-
|
|
712
|
-
} = useRBAC(PERMISSIONS);
|
|
744
|
+
const { allowedActions } = useRBAC(PERMISSIONS);
|
|
745
|
+
const { canUpdate, canDelete, canPublish } = allowedActions;
|
|
713
746
|
const dispatch = useTypedDispatch();
|
|
714
747
|
const { trackUsage } = useTracking();
|
|
715
748
|
const release = data?.data;
|
|
@@ -729,20 +762,25 @@ const ReleaseDetailsLayout = ({
|
|
|
729
762
|
totalPublishedEntries,
|
|
730
763
|
totalUnpublishedEntries
|
|
731
764
|
});
|
|
732
|
-
} else if (
|
|
765
|
+
} else if (isFetchError(response.error)) {
|
|
733
766
|
toggleNotification({
|
|
734
|
-
type: "
|
|
767
|
+
type: "danger",
|
|
735
768
|
message: formatAPIError(response.error)
|
|
736
769
|
});
|
|
737
770
|
} else {
|
|
738
771
|
toggleNotification({
|
|
739
|
-
type: "
|
|
772
|
+
type: "danger",
|
|
740
773
|
message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
|
|
741
774
|
});
|
|
742
775
|
}
|
|
743
776
|
};
|
|
744
777
|
const handleRefresh = () => {
|
|
745
|
-
dispatch(
|
|
778
|
+
dispatch(
|
|
779
|
+
releaseApi.util.invalidateTags([
|
|
780
|
+
{ type: "ReleaseAction", id: "LIST" },
|
|
781
|
+
{ type: "Release", id: releaseId }
|
|
782
|
+
])
|
|
783
|
+
);
|
|
746
784
|
};
|
|
747
785
|
const getCreatedByUser = () => {
|
|
748
786
|
if (!release?.createdBy) {
|
|
@@ -759,7 +797,7 @@ const ReleaseDetailsLayout = ({
|
|
|
759
797
|
if (isLoadingDetails) {
|
|
760
798
|
return /* @__PURE__ */ jsx(Page.Loading, {});
|
|
761
799
|
}
|
|
762
|
-
if (
|
|
800
|
+
if (isBaseQueryError(error) && "code" in error || !release) {
|
|
763
801
|
return /* @__PURE__ */ jsx(
|
|
764
802
|
Navigate,
|
|
765
803
|
{
|
|
@@ -767,6 +805,7 @@ const ReleaseDetailsLayout = ({
|
|
|
767
805
|
state: {
|
|
768
806
|
errors: [
|
|
769
807
|
{
|
|
808
|
+
// @ts-expect-error – TODO: fix this weird error flow
|
|
770
809
|
code: error?.code
|
|
771
810
|
}
|
|
772
811
|
]
|
|
@@ -776,7 +815,6 @@ const ReleaseDetailsLayout = ({
|
|
|
776
815
|
}
|
|
777
816
|
const totalEntries = release.actions.meta.count || 0;
|
|
778
817
|
const hasCreatedByUser = Boolean(getCreatedByUser());
|
|
779
|
-
const IsSchedulingEnabled = window.strapi.future.isEnabled("contentReleasesScheduling");
|
|
780
818
|
const isScheduled = release.scheduledAt && release.timezone;
|
|
781
819
|
const numberOfEntriesText = formatMessage(
|
|
782
820
|
{
|
|
@@ -807,101 +845,85 @@ const ReleaseDetailsLayout = ({
|
|
|
807
845
|
) : "";
|
|
808
846
|
return /* @__PURE__ */ jsxs(Main, { "aria-busy": isLoadingDetails, children: [
|
|
809
847
|
/* @__PURE__ */ jsx(
|
|
810
|
-
|
|
848
|
+
Layouts.Header,
|
|
811
849
|
{
|
|
812
850
|
title: release.name,
|
|
813
851
|
subtitle: /* @__PURE__ */ jsxs(Flex, { gap: 2, lineHeight: 6, children: [
|
|
814
|
-
/* @__PURE__ */ jsx(Typography, { textColor: "neutral600", variant: "epsilon", children: numberOfEntriesText + (
|
|
852
|
+
/* @__PURE__ */ jsx(Typography, { textColor: "neutral600", variant: "epsilon", children: numberOfEntriesText + (isScheduled ? ` - ${scheduledText}` : "") }),
|
|
815
853
|
/* @__PURE__ */ jsx(Badge, { ...getBadgeProps(release.status), children: release.status })
|
|
816
854
|
] }),
|
|
817
|
-
navigationAction: /* @__PURE__ */ jsx(
|
|
818
|
-
id: "global.back",
|
|
819
|
-
defaultMessage: "Back"
|
|
820
|
-
}) }),
|
|
855
|
+
navigationAction: /* @__PURE__ */ jsx(BackButton, {}),
|
|
821
856
|
primaryAction: !release.releasedAt && /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
|
822
|
-
/* @__PURE__ */ jsxs(
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
{
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
857
|
+
/* @__PURE__ */ jsxs(
|
|
858
|
+
SimpleMenuButton,
|
|
859
|
+
{
|
|
860
|
+
label: /* @__PURE__ */ jsx(More, {}),
|
|
861
|
+
variant: "tertiary",
|
|
862
|
+
endIcon: null,
|
|
863
|
+
paddingLeft: "7px",
|
|
864
|
+
paddingRight: "7px",
|
|
865
|
+
"aria-label": formatMessage({
|
|
866
|
+
id: "content-releases.header.actions.open-release-actions",
|
|
867
|
+
defaultMessage: "Release edit and delete menu"
|
|
868
|
+
}),
|
|
869
|
+
popoverPlacement: "bottom-end",
|
|
870
|
+
children: [
|
|
871
|
+
/* @__PURE__ */ jsx(StyledMenuItem, { disabled: !canUpdate, onSelect: toggleEditReleaseModal, children: /* @__PURE__ */ jsxs(Flex, { alignItems: "center", gap: 2, hasRadius: true, width: "100%", children: [
|
|
872
|
+
/* @__PURE__ */ jsx(PencilIcon, {}),
|
|
873
|
+
/* @__PURE__ */ jsx(Typography, { ellipsis: true, children: formatMessage({
|
|
874
|
+
id: "content-releases.header.actions.edit",
|
|
875
|
+
defaultMessage: "Edit"
|
|
876
|
+
}) })
|
|
877
|
+
] }) }),
|
|
878
|
+
/* @__PURE__ */ jsx(
|
|
879
|
+
StyledMenuItem,
|
|
880
|
+
{
|
|
881
|
+
disabled: !canDelete,
|
|
882
|
+
onSelect: toggleWarningSubmit,
|
|
883
|
+
$variant: "danger",
|
|
884
|
+
children: /* @__PURE__ */ jsxs(Flex, { alignItems: "center", gap: 2, hasRadius: true, width: "100%", children: [
|
|
885
|
+
/* @__PURE__ */ jsx(TrashIcon, {}),
|
|
886
|
+
/* @__PURE__ */ jsx(Typography, { ellipsis: true, textColor: "danger600", children: formatMessage({
|
|
887
|
+
id: "content-releases.header.actions.delete",
|
|
888
|
+
defaultMessage: "Delete"
|
|
852
889
|
}) })
|
|
853
|
-
] }) }),
|
|
854
|
-
/* @__PURE__ */ jsx(
|
|
855
|
-
StyledMenuItem,
|
|
856
|
-
{
|
|
857
|
-
disabled: !canDelete,
|
|
858
|
-
onSelect: toggleWarningSubmit,
|
|
859
|
-
variant: "danger",
|
|
860
|
-
children: /* @__PURE__ */ jsxs(Flex, { alignItems: "center", gap: 2, hasRadius: true, width: "100%", children: [
|
|
861
|
-
/* @__PURE__ */ jsx(TrashIcon, {}),
|
|
862
|
-
/* @__PURE__ */ jsx(Typography, { ellipsis: true, textColor: "danger600", children: formatMessage({
|
|
863
|
-
id: "content-releases.header.actions.delete",
|
|
864
|
-
defaultMessage: "Delete"
|
|
865
|
-
}) })
|
|
866
|
-
] })
|
|
867
|
-
}
|
|
868
|
-
)
|
|
869
|
-
]
|
|
870
|
-
}
|
|
871
|
-
),
|
|
872
|
-
/* @__PURE__ */ jsxs(
|
|
873
|
-
ReleaseInfoWrapper,
|
|
874
|
-
{
|
|
875
|
-
direction: "column",
|
|
876
|
-
justifyContent: "center",
|
|
877
|
-
alignItems: "flex-start",
|
|
878
|
-
gap: 1,
|
|
879
|
-
padding: 5,
|
|
880
|
-
children: [
|
|
881
|
-
/* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", children: formatMessage({
|
|
882
|
-
id: "content-releases.header.actions.created",
|
|
883
|
-
defaultMessage: "Created"
|
|
884
|
-
}) }),
|
|
885
|
-
/* @__PURE__ */ jsxs(Typography, { variant: "pi", color: "neutral300", children: [
|
|
886
|
-
/* @__PURE__ */ jsx(RelativeTime, { timestamp: new Date(release.createdAt) }),
|
|
887
|
-
formatMessage(
|
|
888
|
-
{
|
|
889
|
-
id: "content-releases.header.actions.created.description",
|
|
890
|
-
defaultMessage: "{hasCreatedByUser, select, true { by {createdBy}} other { by deleted user}}"
|
|
891
|
-
},
|
|
892
|
-
{ createdBy: getCreatedByUser(), hasCreatedByUser }
|
|
893
|
-
)
|
|
894
890
|
] })
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
891
|
+
}
|
|
892
|
+
),
|
|
893
|
+
/* @__PURE__ */ jsxs(
|
|
894
|
+
ReleaseInfoWrapper,
|
|
895
|
+
{
|
|
896
|
+
direction: "column",
|
|
897
|
+
justifyContent: "center",
|
|
898
|
+
alignItems: "flex-start",
|
|
899
|
+
gap: 1,
|
|
900
|
+
padding: 4,
|
|
901
|
+
children: [
|
|
902
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", children: formatMessage({
|
|
903
|
+
id: "content-releases.header.actions.created",
|
|
904
|
+
defaultMessage: "Created"
|
|
905
|
+
}) }),
|
|
906
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "pi", color: "neutral300", children: [
|
|
907
|
+
/* @__PURE__ */ jsx(RelativeTime$1, { timestamp: new Date(release.createdAt) }),
|
|
908
|
+
formatMessage(
|
|
909
|
+
{
|
|
910
|
+
id: "content-releases.header.actions.created.description",
|
|
911
|
+
defaultMessage: "{hasCreatedByUser, select, true { by {createdBy}} other { by deleted user}}"
|
|
912
|
+
},
|
|
913
|
+
{ createdBy: getCreatedByUser(), hasCreatedByUser }
|
|
914
|
+
)
|
|
915
|
+
] })
|
|
916
|
+
]
|
|
917
|
+
}
|
|
918
|
+
)
|
|
919
|
+
]
|
|
920
|
+
}
|
|
921
|
+
),
|
|
900
922
|
/* @__PURE__ */ jsx(Button, { size: "S", variant: "tertiary", onClick: handleRefresh, children: formatMessage({
|
|
901
923
|
id: "content-releases.header.actions.refresh",
|
|
902
924
|
defaultMessage: "Refresh"
|
|
903
925
|
}) }),
|
|
904
|
-
|
|
926
|
+
canPublish ? /* @__PURE__ */ jsx(
|
|
905
927
|
Button,
|
|
906
928
|
{
|
|
907
929
|
size: "S",
|
|
@@ -914,14 +936,20 @@ const ReleaseDetailsLayout = ({
|
|
|
914
936
|
defaultMessage: "Publish"
|
|
915
937
|
})
|
|
916
938
|
}
|
|
917
|
-
)
|
|
939
|
+
) : null
|
|
918
940
|
] })
|
|
919
941
|
}
|
|
920
942
|
),
|
|
921
943
|
children
|
|
922
944
|
] });
|
|
923
945
|
};
|
|
946
|
+
const SimpleMenuButton = styled(SimpleMenu)`
|
|
947
|
+
& > span {
|
|
948
|
+
display: flex;
|
|
949
|
+
}
|
|
950
|
+
`;
|
|
924
951
|
const GROUP_BY_OPTIONS = ["contentType", "locale", "action"];
|
|
952
|
+
const GROUP_BY_OPTIONS_NO_LOCALE = ["contentType", "action"];
|
|
925
953
|
const getGroupByOptionLabel = (value) => {
|
|
926
954
|
if (value === "locale") {
|
|
927
955
|
return {
|
|
@@ -943,17 +971,29 @@ const getGroupByOptionLabel = (value) => {
|
|
|
943
971
|
const ReleaseDetailsBody = ({ releaseId }) => {
|
|
944
972
|
const { formatMessage } = useIntl();
|
|
945
973
|
const [{ query }, setQuery] = useQueryParams();
|
|
946
|
-
const toggleNotification = useNotification();
|
|
974
|
+
const { toggleNotification } = useNotification();
|
|
947
975
|
const { formatAPIError } = useAPIErrorHandler();
|
|
948
976
|
const {
|
|
949
977
|
data: releaseData,
|
|
950
978
|
isLoading: isReleaseLoading,
|
|
951
|
-
isError: isReleaseError,
|
|
952
979
|
error: releaseError
|
|
953
980
|
} = useGetReleaseQuery({ id: releaseId });
|
|
954
981
|
const {
|
|
955
982
|
allowedActions: { canUpdate }
|
|
956
983
|
} = useRBAC(PERMISSIONS);
|
|
984
|
+
const runHookWaterfall = useStrapiApp("ReleaseDetailsPage", (state) => state.runHookWaterfall);
|
|
985
|
+
const { displayedHeaders, hasI18nEnabled } = runHookWaterfall("ContentReleases/pages/ReleaseDetails/add-locale-in-releases", {
|
|
986
|
+
displayedHeaders: [
|
|
987
|
+
{
|
|
988
|
+
label: {
|
|
989
|
+
id: "content-releases.page.ReleaseDetails.table.header.label.name",
|
|
990
|
+
defaultMessage: "name"
|
|
991
|
+
},
|
|
992
|
+
name: "name"
|
|
993
|
+
}
|
|
994
|
+
],
|
|
995
|
+
hasI18nEnabled: false
|
|
996
|
+
});
|
|
957
997
|
const release = releaseData?.data;
|
|
958
998
|
const selectedGroupBy = query?.groupBy || "contentType";
|
|
959
999
|
const {
|
|
@@ -982,14 +1022,14 @@ const ReleaseDetailsBody = ({ releaseId }) => {
|
|
|
982
1022
|
// We are passing the action path to found the position in the cache of the action for optimistic updates
|
|
983
1023
|
});
|
|
984
1024
|
if ("error" in response) {
|
|
985
|
-
if (
|
|
1025
|
+
if (isFetchError(response.error)) {
|
|
986
1026
|
toggleNotification({
|
|
987
|
-
type: "
|
|
1027
|
+
type: "danger",
|
|
988
1028
|
message: formatAPIError(response.error)
|
|
989
1029
|
});
|
|
990
1030
|
} else {
|
|
991
1031
|
toggleNotification({
|
|
992
|
-
type: "
|
|
1032
|
+
type: "danger",
|
|
993
1033
|
message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
|
|
994
1034
|
});
|
|
995
1035
|
}
|
|
@@ -1002,14 +1042,14 @@ const ReleaseDetailsBody = ({ releaseId }) => {
|
|
|
1002
1042
|
const releaseMeta = data?.meta;
|
|
1003
1043
|
const contentTypes = releaseMeta?.contentTypes || {};
|
|
1004
1044
|
const components = releaseMeta?.components || {};
|
|
1005
|
-
if (
|
|
1045
|
+
if (isBaseQueryError(releaseError) || !release) {
|
|
1006
1046
|
const errorsArray = [];
|
|
1007
|
-
if (releaseError) {
|
|
1047
|
+
if (releaseError && "code" in releaseError) {
|
|
1008
1048
|
errorsArray.push({
|
|
1009
1049
|
code: releaseError.code
|
|
1010
1050
|
});
|
|
1011
1051
|
}
|
|
1012
|
-
if (releaseActionsError) {
|
|
1052
|
+
if (releaseActionsError && "code" in releaseActionsError) {
|
|
1013
1053
|
errorsArray.push({
|
|
1014
1054
|
code: releaseActionsError.code
|
|
1015
1055
|
});
|
|
@@ -1028,13 +1068,13 @@ const ReleaseDetailsBody = ({ releaseId }) => {
|
|
|
1028
1068
|
return /* @__PURE__ */ jsx(Page.Error, {});
|
|
1029
1069
|
}
|
|
1030
1070
|
if (Object.keys(releaseActions).length === 0) {
|
|
1031
|
-
return /* @__PURE__ */ jsx(
|
|
1071
|
+
return /* @__PURE__ */ jsx(Layouts.Content, { children: /* @__PURE__ */ jsx(
|
|
1032
1072
|
EmptyStateLayout,
|
|
1033
1073
|
{
|
|
1034
1074
|
action: /* @__PURE__ */ jsx(
|
|
1035
1075
|
LinkButton,
|
|
1036
1076
|
{
|
|
1037
|
-
|
|
1077
|
+
tag: Link$1,
|
|
1038
1078
|
to: {
|
|
1039
1079
|
pathname: "/content-manager"
|
|
1040
1080
|
},
|
|
@@ -1046,7 +1086,7 @@ const ReleaseDetailsBody = ({ releaseId }) => {
|
|
|
1046
1086
|
})
|
|
1047
1087
|
}
|
|
1048
1088
|
),
|
|
1049
|
-
icon: /* @__PURE__ */ jsx(EmptyDocuments, { width: "
|
|
1089
|
+
icon: /* @__PURE__ */ jsx(EmptyDocuments, { width: "16rem" }),
|
|
1050
1090
|
content: formatMessage({
|
|
1051
1091
|
id: "content-releases.pages.Details.tab.emptyEntries",
|
|
1052
1092
|
defaultMessage: "This release is empty. Open the Content Manager, select an entry and add it to the release."
|
|
@@ -1054,14 +1094,43 @@ const ReleaseDetailsBody = ({ releaseId }) => {
|
|
|
1054
1094
|
}
|
|
1055
1095
|
) });
|
|
1056
1096
|
}
|
|
1057
|
-
|
|
1097
|
+
const groupByLabel = formatMessage({
|
|
1098
|
+
id: "content-releases.pages.ReleaseDetails.groupBy.aria-label",
|
|
1099
|
+
defaultMessage: "Group by"
|
|
1100
|
+
});
|
|
1101
|
+
const headers = [
|
|
1102
|
+
...displayedHeaders,
|
|
1103
|
+
{
|
|
1104
|
+
label: {
|
|
1105
|
+
id: "content-releases.page.ReleaseDetails.table.header.label.content-type",
|
|
1106
|
+
defaultMessage: "content-type"
|
|
1107
|
+
},
|
|
1108
|
+
name: "content-type"
|
|
1109
|
+
},
|
|
1110
|
+
{
|
|
1111
|
+
label: {
|
|
1112
|
+
id: "content-releases.page.ReleaseDetails.table.header.label.action",
|
|
1113
|
+
defaultMessage: "action"
|
|
1114
|
+
},
|
|
1115
|
+
name: "action"
|
|
1116
|
+
},
|
|
1117
|
+
...!release.releasedAt ? [
|
|
1118
|
+
{
|
|
1119
|
+
label: {
|
|
1120
|
+
id: "content-releases.page.ReleaseDetails.table.header.label.status",
|
|
1121
|
+
defaultMessage: "status"
|
|
1122
|
+
},
|
|
1123
|
+
name: "status"
|
|
1124
|
+
}
|
|
1125
|
+
] : []
|
|
1126
|
+
];
|
|
1127
|
+
const options = hasI18nEnabled ? GROUP_BY_OPTIONS : GROUP_BY_OPTIONS_NO_LOCALE;
|
|
1128
|
+
return /* @__PURE__ */ jsx(Layouts.Content, { children: /* @__PURE__ */ jsxs(Flex, { gap: 8, direction: "column", alignItems: "stretch", children: [
|
|
1058
1129
|
/* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(
|
|
1059
1130
|
SingleSelect,
|
|
1060
1131
|
{
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
defaultMessage: "Group by"
|
|
1064
|
-
}),
|
|
1132
|
+
placeholder: groupByLabel,
|
|
1133
|
+
"aria-label": groupByLabel,
|
|
1065
1134
|
customizeContent: (value) => formatMessage(
|
|
1066
1135
|
{
|
|
1067
1136
|
id: `content-releases.pages.ReleaseDetails.groupBy.label`,
|
|
@@ -1073,7 +1142,7 @@ const ReleaseDetailsBody = ({ releaseId }) => {
|
|
|
1073
1142
|
),
|
|
1074
1143
|
value: formatMessage(getGroupByOptionLabel(selectedGroupBy)),
|
|
1075
1144
|
onChange: (value) => setQuery({ groupBy: value }),
|
|
1076
|
-
children:
|
|
1145
|
+
children: options.map((option) => /* @__PURE__ */ jsx(SingleSelectOption, { value: option, children: formatMessage(getGroupByOptionLabel(option)) }, option))
|
|
1077
1146
|
}
|
|
1078
1147
|
) }),
|
|
1079
1148
|
Object.keys(releaseActions).map((key) => /* @__PURE__ */ jsxs(Flex, { gap: 4, direction: "column", alignItems: "stretch", children: [
|
|
@@ -1085,72 +1154,15 @@ const ReleaseDetailsBody = ({ releaseId }) => {
|
|
|
1085
1154
|
...item,
|
|
1086
1155
|
id: Number(item.entry.id)
|
|
1087
1156
|
})),
|
|
1088
|
-
|
|
1089
|
-
isLoading,
|
|
1090
|
-
isFetching,
|
|
1157
|
+
headers,
|
|
1158
|
+
isLoading: isLoading || isFetching,
|
|
1091
1159
|
children: /* @__PURE__ */ jsxs(Table.Content, { children: [
|
|
1092
|
-
/* @__PURE__ */
|
|
1093
|
-
|
|
1094
|
-
Table.HeaderCell,
|
|
1095
|
-
{
|
|
1096
|
-
attribute: { type: "string" },
|
|
1097
|
-
label: formatMessage({
|
|
1098
|
-
id: "content-releases.page.ReleaseDetails.table.header.label.name",
|
|
1099
|
-
defaultMessage: "name"
|
|
1100
|
-
}),
|
|
1101
|
-
name: "name"
|
|
1102
|
-
}
|
|
1103
|
-
),
|
|
1104
|
-
/* @__PURE__ */ jsx(
|
|
1105
|
-
Table.HeaderCell,
|
|
1106
|
-
{
|
|
1107
|
-
attribute: { type: "string" },
|
|
1108
|
-
label: formatMessage({
|
|
1109
|
-
id: "content-releases.page.ReleaseDetails.table.header.label.locale",
|
|
1110
|
-
defaultMessage: "locale"
|
|
1111
|
-
}),
|
|
1112
|
-
name: "locale"
|
|
1113
|
-
}
|
|
1114
|
-
),
|
|
1115
|
-
/* @__PURE__ */ jsx(
|
|
1116
|
-
Table.HeaderCell,
|
|
1117
|
-
{
|
|
1118
|
-
attribute: { type: "string" },
|
|
1119
|
-
label: formatMessage({
|
|
1120
|
-
id: "content-releases.page.ReleaseDetails.table.header.label.content-type",
|
|
1121
|
-
defaultMessage: "content-type"
|
|
1122
|
-
}),
|
|
1123
|
-
name: "content-type"
|
|
1124
|
-
}
|
|
1125
|
-
),
|
|
1126
|
-
/* @__PURE__ */ jsx(
|
|
1127
|
-
Table.HeaderCell,
|
|
1128
|
-
{
|
|
1129
|
-
attribute: { type: "string" },
|
|
1130
|
-
label: formatMessage({
|
|
1131
|
-
id: "content-releases.page.ReleaseDetails.table.header.label.action",
|
|
1132
|
-
defaultMessage: "action"
|
|
1133
|
-
}),
|
|
1134
|
-
name: "action"
|
|
1135
|
-
}
|
|
1136
|
-
),
|
|
1137
|
-
!release.releasedAt && /* @__PURE__ */ jsx(
|
|
1138
|
-
Table.HeaderCell,
|
|
1139
|
-
{
|
|
1140
|
-
attribute: { type: "string" },
|
|
1141
|
-
label: formatMessage({
|
|
1142
|
-
id: "content-releases.page.ReleaseDetails.table.header.label.status",
|
|
1143
|
-
defaultMessage: "status"
|
|
1144
|
-
}),
|
|
1145
|
-
name: "status"
|
|
1146
|
-
}
|
|
1147
|
-
)
|
|
1148
|
-
] }),
|
|
1149
|
-
/* @__PURE__ */ jsx(Table.LoadingBody, {}),
|
|
1160
|
+
/* @__PURE__ */ jsx(Table.Head, { children: headers.map(({ label, name }) => /* @__PURE__ */ jsx(Table.HeaderCell, { label: formatMessage(label), name }, name)) }),
|
|
1161
|
+
/* @__PURE__ */ jsx(Table.Loading, {}),
|
|
1150
1162
|
/* @__PURE__ */ jsx(Table.Body, { children: releaseActions[key].map(
|
|
1151
|
-
({ id, contentType, locale, type, entry }, actionIndex) => /* @__PURE__ */ jsxs(Tr, { children: [
|
|
1163
|
+
({ id, contentType, locale, type, entry, status }, actionIndex) => /* @__PURE__ */ jsxs(Tr, { children: [
|
|
1152
1164
|
/* @__PURE__ */ jsx(Td, { width: "25%", maxWidth: "200px", children: /* @__PURE__ */ jsx(Typography, { ellipsis: true, children: `${contentType.mainFieldValue || entry.id}` }) }),
|
|
1153
|
-
/* @__PURE__ */ jsx(Td, { width: "10%", children: /* @__PURE__ */ jsx(Typography, { children: `${locale?.name ? locale.name : "-"}` }) }),
|
|
1165
|
+
hasI18nEnabled && /* @__PURE__ */ jsx(Td, { width: "10%", children: /* @__PURE__ */ jsx(Typography, { children: `${locale?.name ? locale.name : "-"}` }) }),
|
|
1154
1166
|
/* @__PURE__ */ jsx(Td, { width: "10%", children: /* @__PURE__ */ jsx(Typography, { children: contentType.displayName || "" }) }),
|
|
1155
1167
|
/* @__PURE__ */ jsx(Td, { width: "20%", children: release.releasedAt ? /* @__PURE__ */ jsx(Typography, { children: formatMessage(
|
|
1156
1168
|
{
|
|
@@ -1177,7 +1189,8 @@ const ReleaseDetailsBody = ({ releaseId }) => {
|
|
|
1177
1189
|
action: type,
|
|
1178
1190
|
schema: contentTypes?.[contentType.uid],
|
|
1179
1191
|
components,
|
|
1180
|
-
entry
|
|
1192
|
+
entry,
|
|
1193
|
+
status
|
|
1181
1194
|
}
|
|
1182
1195
|
) }),
|
|
1183
1196
|
/* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Flex, { justifyContent: "flex-end", children: /* @__PURE__ */ jsxs(ReleaseActionMenu.Root, { children: [
|
|
@@ -1185,7 +1198,7 @@ const ReleaseDetailsBody = ({ releaseId }) => {
|
|
|
1185
1198
|
ReleaseActionMenu.ReleaseActionEntryLinkItem,
|
|
1186
1199
|
{
|
|
1187
1200
|
contentTypeUid: contentType.uid,
|
|
1188
|
-
|
|
1201
|
+
documentId: entry.documentId,
|
|
1189
1202
|
locale: locale?.code
|
|
1190
1203
|
}
|
|
1191
1204
|
),
|
|
@@ -1220,7 +1233,7 @@ const ReleaseDetailsBody = ({ releaseId }) => {
|
|
|
1220
1233
|
const ReleaseDetailsPage = () => {
|
|
1221
1234
|
const { formatMessage } = useIntl();
|
|
1222
1235
|
const { releaseId } = useParams();
|
|
1223
|
-
const toggleNotification = useNotification();
|
|
1236
|
+
const { toggleNotification } = useNotification();
|
|
1224
1237
|
const { formatAPIError } = useAPIErrorHandler();
|
|
1225
1238
|
const navigate = useNavigate();
|
|
1226
1239
|
const [releaseModalShown, setReleaseModalShown] = React.useState(false);
|
|
@@ -1235,13 +1248,24 @@ const ReleaseDetailsPage = () => {
|
|
|
1235
1248
|
skip: !releaseId
|
|
1236
1249
|
}
|
|
1237
1250
|
);
|
|
1251
|
+
const { data: dataTimezone, isLoading: isLoadingTimezone } = useGetReleaseSettingsQuery();
|
|
1238
1252
|
const [updateRelease, { isLoading: isSubmittingForm }] = useUpdateReleaseMutation();
|
|
1239
|
-
const [deleteRelease
|
|
1253
|
+
const [deleteRelease] = useDeleteReleaseMutation();
|
|
1240
1254
|
const toggleEditReleaseModal = () => {
|
|
1241
1255
|
setReleaseModalShown((prev) => !prev);
|
|
1242
1256
|
};
|
|
1257
|
+
const getTimezoneValue = () => {
|
|
1258
|
+
if (releaseData?.timezone) {
|
|
1259
|
+
return releaseData.timezone;
|
|
1260
|
+
} else {
|
|
1261
|
+
if (dataTimezone?.data.defaultTimezone) {
|
|
1262
|
+
return dataTimezone.data.defaultTimezone;
|
|
1263
|
+
}
|
|
1264
|
+
return null;
|
|
1265
|
+
}
|
|
1266
|
+
};
|
|
1243
1267
|
const toggleWarningSubmit = () => setWarningSubmit((prevState) => !prevState);
|
|
1244
|
-
if (isLoadingDetails) {
|
|
1268
|
+
if (isLoadingDetails || isLoadingTimezone) {
|
|
1245
1269
|
return /* @__PURE__ */ jsx(
|
|
1246
1270
|
ReleaseDetailsLayout,
|
|
1247
1271
|
{
|
|
@@ -1256,10 +1280,10 @@ const ReleaseDetailsPage = () => {
|
|
|
1256
1280
|
}
|
|
1257
1281
|
const releaseData = isSuccessDetails && data?.data || null;
|
|
1258
1282
|
const title = releaseData?.name || "";
|
|
1259
|
-
const timezone =
|
|
1283
|
+
const timezone = getTimezoneValue();
|
|
1260
1284
|
const scheduledAt = releaseData?.scheduledAt && timezone ? utcToZonedTime(releaseData.scheduledAt, timezone) : null;
|
|
1261
|
-
const date = scheduledAt ?
|
|
1262
|
-
const time = scheduledAt ? format(scheduledAt, "HH:mm") : "";
|
|
1285
|
+
const date = scheduledAt ? format$1(scheduledAt, "yyyy-MM-dd") : void 0;
|
|
1286
|
+
const time = scheduledAt ? format$1(scheduledAt, "HH:mm") : "";
|
|
1263
1287
|
const handleEditRelease = async (values) => {
|
|
1264
1288
|
const response = await updateRelease({
|
|
1265
1289
|
id: releaseId,
|
|
@@ -1275,18 +1299,18 @@ const ReleaseDetailsPage = () => {
|
|
|
1275
1299
|
defaultMessage: "Release updated."
|
|
1276
1300
|
})
|
|
1277
1301
|
});
|
|
1278
|
-
|
|
1302
|
+
toggleEditReleaseModal();
|
|
1303
|
+
} else if (isFetchError(response.error)) {
|
|
1279
1304
|
toggleNotification({
|
|
1280
|
-
type: "
|
|
1305
|
+
type: "danger",
|
|
1281
1306
|
message: formatAPIError(response.error)
|
|
1282
1307
|
});
|
|
1283
1308
|
} else {
|
|
1284
1309
|
toggleNotification({
|
|
1285
|
-
type: "
|
|
1310
|
+
type: "danger",
|
|
1286
1311
|
message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
|
|
1287
1312
|
});
|
|
1288
1313
|
}
|
|
1289
|
-
toggleEditReleaseModal();
|
|
1290
1314
|
};
|
|
1291
1315
|
const handleDeleteRelease = async () => {
|
|
1292
1316
|
const response = await deleteRelease({
|
|
@@ -1294,14 +1318,14 @@ const ReleaseDetailsPage = () => {
|
|
|
1294
1318
|
});
|
|
1295
1319
|
if ("data" in response) {
|
|
1296
1320
|
navigate("..");
|
|
1297
|
-
} else if (
|
|
1321
|
+
} else if (isFetchError(response.error)) {
|
|
1298
1322
|
toggleNotification({
|
|
1299
|
-
type: "
|
|
1323
|
+
type: "danger",
|
|
1300
1324
|
message: formatAPIError(response.error)
|
|
1301
1325
|
});
|
|
1302
1326
|
} else {
|
|
1303
1327
|
toggleNotification({
|
|
1304
|
-
type: "
|
|
1328
|
+
type: "danger",
|
|
1305
1329
|
message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
|
|
1306
1330
|
});
|
|
1307
1331
|
}
|
|
@@ -1313,9 +1337,10 @@ const ReleaseDetailsPage = () => {
|
|
|
1313
1337
|
toggleWarningSubmit,
|
|
1314
1338
|
children: [
|
|
1315
1339
|
/* @__PURE__ */ jsx(ReleaseDetailsBody, { releaseId }),
|
|
1316
|
-
|
|
1340
|
+
/* @__PURE__ */ jsx(
|
|
1317
1341
|
ReleaseModal,
|
|
1318
1342
|
{
|
|
1343
|
+
open: releaseModalShown,
|
|
1319
1344
|
handleClose: toggleEditReleaseModal,
|
|
1320
1345
|
handleSubmit: handleEditRelease,
|
|
1321
1346
|
isLoading: isLoadingDetails || isSubmittingForm,
|
|
@@ -1329,19 +1354,10 @@ const ReleaseDetailsPage = () => {
|
|
|
1329
1354
|
}
|
|
1330
1355
|
}
|
|
1331
1356
|
),
|
|
1332
|
-
/* @__PURE__ */ jsx(
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
id: "content-releases.dialog.confirmation-message",
|
|
1337
|
-
defaultMessage: "Are you sure you want to delete this release?"
|
|
1338
|
-
},
|
|
1339
|
-
isOpen: showWarningSubmit,
|
|
1340
|
-
isConfirmButtonLoading: isDeletingRelease,
|
|
1341
|
-
onToggleDialog: toggleWarningSubmit,
|
|
1342
|
-
onConfirm: handleDeleteRelease
|
|
1343
|
-
}
|
|
1344
|
-
)
|
|
1357
|
+
/* @__PURE__ */ jsx(Dialog.Root, { open: showWarningSubmit, onOpenChange: toggleWarningSubmit, children: /* @__PURE__ */ jsx(ConfirmDialog, { onConfirm: handleDeleteRelease, children: formatMessage({
|
|
1358
|
+
id: "content-releases.dialog.confirmation-message",
|
|
1359
|
+
defaultMessage: "Are you sure you want to delete this release?"
|
|
1360
|
+
}) }) })
|
|
1345
1361
|
]
|
|
1346
1362
|
}
|
|
1347
1363
|
);
|
|
@@ -1355,4 +1371,4 @@ const App = () => {
|
|
|
1355
1371
|
export {
|
|
1356
1372
|
App
|
|
1357
1373
|
};
|
|
1358
|
-
//# sourceMappingURL=App-
|
|
1374
|
+
//# sourceMappingURL=App-BA2xDdy0.mjs.map
|