@strapi/content-releases 5.0.0-rc.1 → 5.0.0-rc.2
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-CatMj4_9.js → App-CKoteEu-.js} +25 -10
- package/dist/_chunks/App-CKoteEu-.js.map +1 -0
- package/dist/_chunks/{App-CdTs45Xr.mjs → App-CwBi9wFK.mjs} +24 -9
- package/dist/_chunks/App-CwBi9wFK.mjs.map +1 -0
- package/dist/_chunks/{ReleasesSettingsPage-C2L6_E3J.mjs → ReleasesSettingsPage-Be1qEgcA.mjs} +3 -3
- package/dist/_chunks/ReleasesSettingsPage-Be1qEgcA.mjs.map +1 -0
- package/dist/_chunks/{ReleasesSettingsPage-hHmY2fiE.js → ReleasesSettingsPage-U9Ud3HzH.js} +4 -4
- package/dist/_chunks/ReleasesSettingsPage-U9Ud3HzH.js.map +1 -0
- package/dist/_chunks/{index-DYXEZrUA.js → index-JLkDg3pp.js} +4 -4
- package/dist/_chunks/index-JLkDg3pp.js.map +1 -0
- package/dist/_chunks/{index-CJpYVXMt.mjs → index-VB3t7pBK.mjs} +16 -16
- package/dist/_chunks/index-VB3t7pBK.mjs.map +1 -0
- package/dist/_chunks/{validation-schemas-bib1fBc7.js → schemas-3o-6hwUE.js} +18 -5
- package/dist/_chunks/schemas-3o-6hwUE.js.map +1 -0
- package/dist/_chunks/{validation-schemas-C7P2rhPu.mjs → schemas-CBVqXur2.mjs} +18 -5
- package/dist/_chunks/schemas-CBVqXur2.mjs.map +1 -0
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/{shared/validation-schemas.d.ts → admin/src/validation/schemas.d.ts} +0 -1
- package/dist/server/index.js +10 -21
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +10 -21
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/src/controllers/validation/release.d.ts +1 -0
- package/dist/server/src/controllers/validation/release.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/settings.d.ts +1 -0
- package/dist/server/src/controllers/validation/settings.d.ts.map +1 -1
- package/package.json +8 -8
- package/dist/_chunks/App-CatMj4_9.js.map +0 -1
- package/dist/_chunks/App-CdTs45Xr.mjs.map +0 -1
- package/dist/_chunks/ReleasesSettingsPage-C2L6_E3J.mjs.map +0 -1
- package/dist/_chunks/ReleasesSettingsPage-hHmY2fiE.js.map +0 -1
- package/dist/_chunks/index-CJpYVXMt.mjs.map +0 -1
- package/dist/_chunks/index-DYXEZrUA.js.map +0 -1
- package/dist/_chunks/validation-schemas-C7P2rhPu.mjs.map +0 -1
- package/dist/_chunks/validation-schemas-bib1fBc7.js.map +0 -1
- package/dist/shared/validation-schemas.d.ts.map +0 -1
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
3
3
|
const jsxRuntime = require("react/jsx-runtime");
|
|
4
4
|
const strapiAdmin = require("@strapi/admin/strapi-admin");
|
|
5
5
|
const reactRouterDom = require("react-router-dom");
|
|
6
|
-
const index = require("./index-
|
|
6
|
+
const index = require("./index-JLkDg3pp.js");
|
|
7
7
|
const React = require("react");
|
|
8
8
|
const strapiAdmin$1 = require("@strapi/content-manager/strapi-admin");
|
|
9
9
|
const designSystem = require("@strapi/design-system");
|
|
@@ -15,7 +15,7 @@ const reactIntl = require("react-intl");
|
|
|
15
15
|
const styledComponents = require("styled-components");
|
|
16
16
|
const dateFns = require("date-fns");
|
|
17
17
|
const formik = require("formik");
|
|
18
|
-
const
|
|
18
|
+
const schemas = require("./schemas-3o-6hwUE.js");
|
|
19
19
|
const reactRedux = require("react-redux");
|
|
20
20
|
const ee = require("@strapi/admin/strapi-admin/ee");
|
|
21
21
|
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
|
@@ -117,7 +117,7 @@ const ReleaseModal = ({
|
|
|
117
117
|
...initialValues,
|
|
118
118
|
timezone: initialValues.timezone ? getTimezoneWithOffset() : systemTimezone.value
|
|
119
119
|
},
|
|
120
|
-
validationSchema:
|
|
120
|
+
validationSchema: schemas.RELEASE_SCHEMA,
|
|
121
121
|
validateOnChange: false,
|
|
122
122
|
children: ({ values, errors, handleChange, setFieldValue }) => {
|
|
123
123
|
return /* @__PURE__ */ jsxRuntime.jsxs(formik.Form, { children: [
|
|
@@ -384,6 +384,7 @@ const ReleasesPage = () => {
|
|
|
384
384
|
const { formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
|
385
385
|
const [{ query }, setQuery] = strapiAdmin.useQueryParams();
|
|
386
386
|
const response = index.useGetReleasesQuery(query);
|
|
387
|
+
const { data, isLoading: isLoadingSettings } = index.useGetReleaseSettingsQuery();
|
|
387
388
|
const [createRelease, { isLoading: isSubmittingForm }] = index.useCreateReleaseMutation();
|
|
388
389
|
const { getFeature } = ee.useLicenseLimits();
|
|
389
390
|
const { maximumReleases = 3 } = getFeature("cms-content-releases");
|
|
@@ -391,7 +392,7 @@ const ReleasesPage = () => {
|
|
|
391
392
|
const {
|
|
392
393
|
allowedActions: { canCreate }
|
|
393
394
|
} = strapiAdmin.useRBAC(index.PERMISSIONS);
|
|
394
|
-
const { isLoading, isSuccess, isError } = response;
|
|
395
|
+
const { isLoading: isLoadingReleases, isSuccess, isError } = response;
|
|
395
396
|
const activeTab = response?.currentData?.meta?.activeTab || "pending";
|
|
396
397
|
React__namespace.useEffect(() => {
|
|
397
398
|
if (location?.state?.errors) {
|
|
@@ -412,7 +413,7 @@ const ReleasesPage = () => {
|
|
|
412
413
|
const toggleAddReleaseModal = () => {
|
|
413
414
|
setReleaseModalShown((prev) => !prev);
|
|
414
415
|
};
|
|
415
|
-
if (
|
|
416
|
+
if (isLoadingReleases || isLoadingSettings) {
|
|
416
417
|
return /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Page.Loading, {});
|
|
417
418
|
}
|
|
418
419
|
const totalPendingReleases = isSuccess && response.currentData?.meta?.pendingReleasesCount || 0;
|
|
@@ -457,7 +458,7 @@ const ReleasesPage = () => {
|
|
|
457
458
|
});
|
|
458
459
|
}
|
|
459
460
|
};
|
|
460
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Main, { "aria-busy":
|
|
461
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Main, { "aria-busy": isLoadingReleases || isLoadingSettings, children: [
|
|
461
462
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
462
463
|
strapiAdmin.Layouts.Header,
|
|
463
464
|
{
|
|
@@ -572,7 +573,10 @@ const ReleasesPage = () => {
|
|
|
572
573
|
handleClose: toggleAddReleaseModal,
|
|
573
574
|
handleSubmit: handleAddRelease,
|
|
574
575
|
isLoading: isSubmittingForm,
|
|
575
|
-
initialValues:
|
|
576
|
+
initialValues: {
|
|
577
|
+
...INITIAL_FORM_VALUES,
|
|
578
|
+
timezone: data?.data.defaultTimezone ? data.data.defaultTimezone.split("&")[1] : null
|
|
579
|
+
}
|
|
576
580
|
}
|
|
577
581
|
)
|
|
578
582
|
] });
|
|
@@ -1212,13 +1216,24 @@ const ReleaseDetailsPage = () => {
|
|
|
1212
1216
|
skip: !releaseId
|
|
1213
1217
|
}
|
|
1214
1218
|
);
|
|
1219
|
+
const { data: dataTimezone, isLoading: isLoadingTimezone } = index.useGetReleaseSettingsQuery();
|
|
1215
1220
|
const [updateRelease, { isLoading: isSubmittingForm }] = index.useUpdateReleaseMutation();
|
|
1216
1221
|
const [deleteRelease] = index.useDeleteReleaseMutation();
|
|
1217
1222
|
const toggleEditReleaseModal = () => {
|
|
1218
1223
|
setReleaseModalShown((prev) => !prev);
|
|
1219
1224
|
};
|
|
1225
|
+
const getTimezoneValue = () => {
|
|
1226
|
+
if (releaseData?.timezone) {
|
|
1227
|
+
return releaseData.timezone;
|
|
1228
|
+
} else {
|
|
1229
|
+
if (dataTimezone?.data.defaultTimezone) {
|
|
1230
|
+
return dataTimezone.data.defaultTimezone;
|
|
1231
|
+
}
|
|
1232
|
+
return null;
|
|
1233
|
+
}
|
|
1234
|
+
};
|
|
1220
1235
|
const toggleWarningSubmit = () => setWarningSubmit((prevState) => !prevState);
|
|
1221
|
-
if (isLoadingDetails) {
|
|
1236
|
+
if (isLoadingDetails || isLoadingTimezone) {
|
|
1222
1237
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1223
1238
|
ReleaseDetailsLayout,
|
|
1224
1239
|
{
|
|
@@ -1233,7 +1248,7 @@ const ReleaseDetailsPage = () => {
|
|
|
1233
1248
|
}
|
|
1234
1249
|
const releaseData = isSuccessDetails && data?.data || null;
|
|
1235
1250
|
const title = releaseData?.name || "";
|
|
1236
|
-
const timezone =
|
|
1251
|
+
const timezone = getTimezoneValue();
|
|
1237
1252
|
const scheduledAt = releaseData?.scheduledAt && timezone ? dateFnsTz.utcToZonedTime(releaseData.scheduledAt, timezone) : null;
|
|
1238
1253
|
const date = scheduledAt ? format__default.default(scheduledAt, "yyyy-MM-dd") : void 0;
|
|
1239
1254
|
const time = scheduledAt ? format__default.default(scheduledAt, "HH:mm") : "";
|
|
@@ -1322,4 +1337,4 @@ const App = () => {
|
|
|
1322
1337
|
] }) });
|
|
1323
1338
|
};
|
|
1324
1339
|
exports.App = App;
|
|
1325
|
-
//# sourceMappingURL=App-
|
|
1340
|
+
//# sourceMappingURL=App-CKoteEu-.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"App-CKoteEu-.js","sources":["../../admin/src/components/RelativeTime.tsx","../../admin/src/components/ReleaseModal.tsx","../../admin/src/store/hooks.ts","../../admin/src/utils/api.ts","../../admin/src/pages/ReleasesPage.tsx","../../admin/src/pages/ReleaseDetailsPage.tsx","../../admin/src/pages/App.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Duration, intervalToDuration, isPast } from 'date-fns';\nimport { useIntl } from 'react-intl';\n\nconst intervals: Array<keyof Duration> = ['years', 'months', 'days', 'hours', 'minutes', 'seconds'];\n\ninterface CustomInterval {\n unit: keyof Duration;\n text: string;\n threshold: number;\n}\n\ninterface RelativeTimeProps extends React.ComponentPropsWithoutRef<'time'> {\n timestamp: Date;\n customIntervals?: CustomInterval[];\n}\n\n/**\n * Displays the relative time between a given timestamp and the current time.\n * You can display a custom message for given time intervals by passing an array of custom intervals.\n *\n * @example\n * ```jsx\n * <caption>Display \"last hour\" if the timestamp is less than an hour ago</caption>\n * <RelativeTime\n * timestamp={new Date('2021-01-01')}\n * customIntervals={[\n * { unit: 'hours', threshold: 1, text: 'last hour' },\n * ]}\n * ```\n */\nconst RelativeTime = React.forwardRef<HTMLTimeElement, RelativeTimeProps>(\n ({ timestamp, customIntervals = [], ...restProps }, forwardedRef) => {\n const { formatRelativeTime, formatDate, formatTime } = useIntl();\n\n /**\n * TODO: make this auto-update, like a clock.\n */\n const interval = intervalToDuration({\n start: timestamp,\n end: Date.now(),\n // see https://github.com/date-fns/date-fns/issues/2891 – No idea why it's all partial it returns it every time.\n }) as Required<Duration>;\n\n const unit = intervals.find((intervalUnit) => {\n return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);\n })!;\n\n const relativeTime = isPast(timestamp) ? -interval[unit] : interval[unit];\n\n // Display custom text if interval is less than the threshold\n const customInterval = customIntervals.find(\n (custom) => interval[custom.unit] < custom.threshold\n );\n\n const displayText = customInterval\n ? customInterval.text\n : formatRelativeTime(relativeTime, unit, { numeric: 'auto' });\n\n return (\n <time\n ref={forwardedRef}\n dateTime={timestamp.toISOString()}\n role=\"time\"\n title={`${formatDate(timestamp)} ${formatTime(timestamp)}`}\n {...restProps}\n >\n {displayText}\n </time>\n );\n }\n);\n\nexport { RelativeTime };\nexport type { CustomInterval, RelativeTimeProps };\n","import * as React from 'react';\n\nimport {\n Button,\n Modal,\n TextInput,\n Typography,\n Checkbox,\n Flex,\n Box,\n DatePicker,\n TimePicker,\n Combobox,\n ComboboxOption,\n Field,\n} from '@strapi/design-system';\nimport { formatISO } from 'date-fns';\nimport { utcToZonedTime, zonedTimeToUtc } from 'date-fns-tz';\nimport { Formik, Form, useFormikContext } from 'formik';\nimport { useIntl } from 'react-intl';\nimport { useLocation } from 'react-router-dom';\n\nimport { pluginId } from '../pluginId';\nimport { getTimezones } from '../utils/time';\nimport { RELEASE_SCHEMA } from '../validation/schemas';\n\nexport interface FormValues {\n name: string;\n date?: string;\n time: string;\n timezone: string | null;\n isScheduled?: boolean;\n scheduledAt: Date | null;\n}\n\ninterface ReleaseModalProps {\n handleClose: () => void;\n handleSubmit: (values: FormValues) => void;\n isLoading?: boolean;\n initialValues: FormValues;\n open?: boolean;\n}\n\nexport const ReleaseModal = ({\n handleClose,\n open,\n handleSubmit,\n initialValues,\n isLoading = false,\n}: ReleaseModalProps) => {\n const { formatMessage } = useIntl();\n const { pathname } = useLocation();\n const isCreatingRelease = pathname === `/plugins/${pluginId}`;\n // Set default first timezone from the list if no system timezone detected\n const { timezoneList, systemTimezone = { value: 'UTC+00:00-Africa/Abidjan ' } } = getTimezones(\n initialValues.scheduledAt ? new Date(initialValues.scheduledAt) : new Date()\n );\n\n /**\n * Generate scheduled time using selected date, time and timezone\n */\n const getScheduledTimestamp = (values: FormValues) => {\n const { date, time, timezone } = values;\n if (!date || !time || !timezone) return null;\n const timezoneWithoutOffset = timezone.split('&')[1];\n return zonedTimeToUtc(`${date} ${time}`, timezoneWithoutOffset);\n };\n\n /**\n * Get timezone with offset to show the selected value in the dropdown\n */\n const getTimezoneWithOffset = () => {\n const currentTimezone = timezoneList.find(\n (timezone) => timezone.value.split('&')[1] === initialValues.timezone\n );\n return currentTimezone?.value || systemTimezone.value;\n };\n\n return (\n <Modal.Root open={open} onOpenChange={handleClose}>\n <Modal.Content>\n <Modal.Header>\n <Modal.Title>\n {formatMessage(\n {\n id: 'content-releases.modal.title',\n defaultMessage:\n '{isCreatingRelease, select, true {New release} other {Edit release}}',\n },\n { isCreatingRelease: isCreatingRelease }\n )}\n </Modal.Title>\n </Modal.Header>\n <Formik\n onSubmit={(values) => {\n handleSubmit({\n ...values,\n timezone: values.timezone ? values.timezone.split('&')[1] : null,\n scheduledAt: values.isScheduled ? getScheduledTimestamp(values) : null,\n });\n }}\n initialValues={{\n ...initialValues,\n timezone: initialValues.timezone ? getTimezoneWithOffset() : systemTimezone.value,\n }}\n validationSchema={RELEASE_SCHEMA}\n validateOnChange={false}\n >\n {({ values, errors, handleChange, setFieldValue }) => {\n return (\n <Form>\n <Modal.Body>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={6}>\n <Field.Root name=\"name\" error={errors.name} required>\n <Field.Label>\n {formatMessage({\n id: 'content-releases.modal.form.input.label.release-name',\n defaultMessage: 'Name',\n })}\n </Field.Label>\n <TextInput value={values.name} onChange={handleChange} />\n <Field.Error />\n </Field.Root>\n <Box width=\"max-content\">\n <Checkbox\n name=\"isScheduled\"\n checked={values.isScheduled}\n onCheckedChange={(checked) => {\n setFieldValue('isScheduled', checked);\n if (!checked) {\n // Clear scheduling info from a release on unchecking schedule release, which reset scheduling info in DB\n setFieldValue('date', null);\n setFieldValue('time', '');\n setFieldValue('timezone', null);\n } else {\n // On ticking back schedule release date, time and timezone should be restored to the initial state\n setFieldValue('date', initialValues.date);\n setFieldValue('time', initialValues.time);\n setFieldValue(\n 'timezone',\n initialValues.timezone ?? systemTimezone?.value\n );\n }\n }}\n >\n <Typography\n textColor={values.isScheduled ? 'primary600' : 'neutral800'}\n fontWeight={values.isScheduled ? 'semiBold' : 'regular'}\n >\n {formatMessage({\n id: 'modal.form.input.label.schedule-release',\n defaultMessage: 'Schedule release',\n })}\n </Typography>\n </Checkbox>\n </Box>\n {values.isScheduled && (\n <>\n <Flex gap={4} alignItems=\"start\">\n <Box width=\"100%\">\n <Field.Root name=\"date\" error={errors.date} required>\n <Field.Label>\n {formatMessage({\n id: 'content-releases.modal.form.input.label.date',\n defaultMessage: 'Date',\n })}\n </Field.Label>\n <DatePicker\n onChange={(date) => {\n const isoFormatDate = date\n ? formatISO(date, { representation: 'date' })\n : null;\n setFieldValue('date', isoFormatDate);\n }}\n clearLabel={formatMessage({\n id: 'content-releases.modal.form.input.clearLabel',\n defaultMessage: 'Clear',\n })}\n onClear={() => {\n setFieldValue('date', null);\n }}\n value={values.date ? new Date(values.date) : new Date()}\n minDate={utcToZonedTime(new Date(), values.timezone.split('&')[1])}\n />\n <Field.Error />\n </Field.Root>\n </Box>\n <Box width=\"100%\">\n <Field.Root name=\"time\" error={errors.time} required>\n <Field.Label>\n {formatMessage({\n id: 'content-releases.modal.form.input.label.time',\n defaultMessage: 'Time',\n })}\n </Field.Label>\n <TimePicker\n onChange={(time) => {\n setFieldValue('time', time);\n }}\n clearLabel={formatMessage({\n id: 'content-releases.modal.form.input.clearLabel',\n defaultMessage: 'Clear',\n })}\n onClear={() => {\n setFieldValue('time', '');\n }}\n value={values.time || undefined}\n />\n <Field.Error />\n </Field.Root>\n </Box>\n </Flex>\n <TimezoneComponent timezoneOptions={timezoneList} />\n </>\n )}\n </Flex>\n </Modal.Body>\n <Modal.Footer>\n <Modal.Close>\n <Button variant=\"tertiary\" name=\"cancel\">\n {formatMessage({ id: 'cancel', defaultMessage: 'Cancel' })}\n </Button>\n </Modal.Close>\n <Button name=\"submit\" loading={isLoading} type=\"submit\">\n {formatMessage(\n {\n id: 'content-releases.modal.form.button.submit',\n defaultMessage: '{isCreatingRelease, select, true {Continue} other {Save}}',\n },\n { isCreatingRelease: isCreatingRelease }\n )}\n </Button>\n </Modal.Footer>\n </Form>\n );\n }}\n </Formik>\n </Modal.Content>\n </Modal.Root>\n );\n};\n\n/**\n * Generates the list of timezones and user's current timezone(system timezone)\n */\ninterface ITimezoneOption {\n offset: string;\n value: string;\n}\n\nconst TimezoneComponent = ({ timezoneOptions }: { timezoneOptions: ITimezoneOption[] }) => {\n const { values, errors, setFieldValue } = useFormikContext<FormValues>();\n const { formatMessage } = useIntl();\n const [timezoneList, setTimezoneList] = React.useState<ITimezoneOption[]>(timezoneOptions);\n\n React.useEffect(() => {\n if (values.date) {\n // Update the timezone offset which varies with DST based on the date selected\n const { timezoneList } = getTimezones(new Date(values.date));\n setTimezoneList(timezoneList);\n\n const updatedTimezone =\n values.timezone &&\n timezoneList.find((tz) => tz.value.split('&')[1] === values.timezone!.split('&')[1]);\n if (updatedTimezone) {\n setFieldValue('timezone', updatedTimezone!.value);\n }\n }\n }, [setFieldValue, values.date, values.timezone]);\n\n return (\n <Field.Root name=\"timezone\" error={errors.timezone} required>\n <Field.Label>\n {formatMessage({\n id: 'content-releases.modal.form.input.label.timezone',\n defaultMessage: 'Timezone',\n })}\n </Field.Label>\n <Combobox\n autocomplete={{ type: 'list', filter: 'contains' }}\n value={values.timezone || undefined}\n textValue={values.timezone ? values.timezone.replace(/&/, ' ') : undefined} // textValue is required to show the updated DST timezone\n onChange={(timezone) => {\n setFieldValue('timezone', timezone);\n }}\n onTextValueChange={(timezone) => {\n setFieldValue('timezone', timezone);\n }}\n onClear={() => {\n setFieldValue('timezone', '');\n }}\n >\n {timezoneList.map((timezone) => (\n <ComboboxOption key={timezone.value} value={timezone.value}>\n {timezone.value.replace(/&/, ' ')}\n </ComboboxOption>\n ))}\n </Combobox>\n <Field.Error />\n </Field.Root>\n );\n};\n","import { Dispatch } from '@reduxjs/toolkit';\nimport { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';\n\nimport type { Store } from '@strapi/admin/strapi-admin';\n\ntype RootState = ReturnType<Store['getState']>;\n\nconst useTypedDispatch: () => Dispatch = useDispatch;\nconst useTypedSelector: TypedUseSelectorHook<RootState> = useSelector;\n\nexport { useTypedSelector, useTypedDispatch };\n","import { SerializedError } from '@reduxjs/toolkit';\nimport { ApiError } from '@strapi/admin/strapi-admin';\n\ntype BaseQueryError = ApiError | SerializedError;\n\nconst isBaseQueryError = (error?: BaseQueryError): error is BaseQueryError => {\n return typeof error !== 'undefined' && error.name !== undefined;\n};\n\nexport { isBaseQueryError };\nexport type { BaseQueryError };\n","import * as React from 'react';\n\nimport {\n Page,\n Pagination,\n useTracking,\n useAPIErrorHandler,\n useNotification,\n useQueryParams,\n useRBAC,\n isFetchError,\n Layouts,\n} from '@strapi/admin/strapi-admin';\nimport { useLicenseLimits } from '@strapi/admin/strapi-admin/ee';\nimport {\n Alert,\n Badge,\n Box,\n Button,\n Divider,\n EmptyStateLayout,\n Flex,\n Grid,\n Main,\n Tabs,\n Typography,\n Link,\n} from '@strapi/design-system';\nimport { Plus } from '@strapi/icons';\nimport { EmptyDocuments } from '@strapi/icons/symbols';\nimport { useIntl } from 'react-intl';\nimport { useNavigate, useLocation, NavLink } from 'react-router-dom';\nimport { styled } from 'styled-components';\n\nimport { GetReleases, type Release } from '../../../shared/contracts/releases';\nimport { RelativeTime as BaseRelativeTime } from '../components/RelativeTime';\nimport { ReleaseModal, FormValues } from '../components/ReleaseModal';\nimport { PERMISSIONS } from '../constants';\nimport {\n useGetReleasesQuery,\n useGetReleaseSettingsQuery,\n GetReleasesQueryParams,\n useCreateReleaseMutation,\n} from '../services/release';\n\n/* -------------------------------------------------------------------------------------------------\n * ReleasesGrid\n * -----------------------------------------------------------------------------------------------*/\ninterface ReleasesGridProps {\n sectionTitle: 'pending' | 'done';\n releases?: GetReleases.Response['data'];\n isError?: boolean;\n}\n\nconst LinkCard = styled(Link)`\n display: block;\n`;\n\nconst RelativeTime = styled(BaseRelativeTime)`\n display: inline-block;\n &::first-letter {\n text-transform: uppercase;\n }\n`;\n\nconst getBadgeProps = (status: Release['status']) => {\n let color;\n switch (status) {\n case 'ready':\n color = 'success';\n break;\n case 'blocked':\n color = 'warning';\n break;\n case 'failed':\n color = 'danger';\n break;\n case 'done':\n color = 'primary';\n break;\n case 'empty':\n default:\n color = 'neutral';\n }\n\n return {\n textColor: `${color}600`,\n backgroundColor: `${color}100`,\n borderColor: `${color}200`,\n };\n};\n\nconst ReleasesGrid = ({ sectionTitle, releases = [], isError = false }: ReleasesGridProps) => {\n const { formatMessage } = useIntl();\n\n if (isError) {\n return <Page.Error />;\n }\n\n if (releases?.length === 0) {\n return (\n <EmptyStateLayout\n content={formatMessage(\n {\n id: 'content-releases.page.Releases.tab.emptyEntries',\n defaultMessage: 'No releases',\n },\n {\n target: sectionTitle,\n }\n )}\n icon={<EmptyDocuments width=\"16rem\" />}\n />\n );\n }\n\n return (\n <Grid.Root gap={4}>\n {releases.map(({ id, name, scheduledAt, status }) => (\n <Grid.Item col={3} s={6} xs={12} key={id}>\n <LinkCard tag={NavLink} to={`${id}`} isExternal={false}>\n <Flex\n direction=\"column\"\n justifyContent=\"space-between\"\n padding={4}\n hasRadius\n background=\"neutral0\"\n shadow=\"tableShadow\"\n height=\"100%\"\n width=\"100%\"\n alignItems=\"start\"\n gap={4}\n >\n <Flex direction=\"column\" alignItems=\"start\" gap={1}>\n <Typography textColor=\"neutral800\" tag=\"h3\" variant=\"delta\" fontWeight=\"bold\">\n {name}\n </Typography>\n <Typography variant=\"pi\" textColor=\"neutral600\">\n {scheduledAt ? (\n <RelativeTime timestamp={new Date(scheduledAt)} />\n ) : (\n formatMessage({\n id: 'content-releases.pages.Releases.not-scheduled',\n defaultMessage: 'Not scheduled',\n })\n )}\n </Typography>\n </Flex>\n <Badge {...getBadgeProps(status)}>{status}</Badge>\n </Flex>\n </LinkCard>\n </Grid.Item>\n ))}\n </Grid.Root>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ReleasesPage\n * -----------------------------------------------------------------------------------------------*/\n\nconst StyledAlert = styled(Alert)`\n button {\n display: none;\n }\n p + div {\n margin-left: auto;\n }\n`;\n\nconst INITIAL_FORM_VALUES = {\n name: '',\n date: undefined,\n time: '',\n isScheduled: true,\n scheduledAt: null,\n timezone: null,\n} satisfies FormValues;\n\nconst ReleasesPage = () => {\n const location = useLocation();\n const [releaseModalShown, setReleaseModalShown] = React.useState(false);\n const { toggleNotification } = useNotification();\n const { formatMessage } = useIntl();\n const navigate = useNavigate();\n const { formatAPIError } = useAPIErrorHandler();\n const [{ query }, setQuery] = useQueryParams<GetReleasesQueryParams>();\n const response = useGetReleasesQuery(query);\n const { data, isLoading: isLoadingSettings } = useGetReleaseSettingsQuery();\n const [createRelease, { isLoading: isSubmittingForm }] = useCreateReleaseMutation();\n const { getFeature } = useLicenseLimits();\n const { maximumReleases = 3 } = getFeature('cms-content-releases') as {\n maximumReleases: number;\n };\n const { trackUsage } = useTracking();\n const {\n allowedActions: { canCreate },\n } = useRBAC(PERMISSIONS);\n\n const { isLoading: isLoadingReleases, isSuccess, isError } = response;\n const activeTab = response?.currentData?.meta?.activeTab || 'pending';\n\n // Check if we have some errors and show a notification to the user to explain the error\n React.useEffect(() => {\n if (location?.state?.errors) {\n toggleNotification({\n type: 'danger',\n title: formatMessage({\n id: 'content-releases.pages.Releases.notification.error.title',\n defaultMessage: 'Your request could not be processed.',\n }),\n message: formatMessage({\n id: 'content-releases.pages.Releases.notification.error.message',\n defaultMessage: 'Please try again or open another release.',\n }),\n });\n navigate('', { replace: true, state: null });\n }\n }, [formatMessage, location?.state?.errors, navigate, toggleNotification]);\n\n const toggleAddReleaseModal = () => {\n setReleaseModalShown((prev) => !prev);\n };\n\n if (isLoadingReleases || isLoadingSettings) {\n return <Page.Loading />;\n }\n\n const totalPendingReleases = (isSuccess && response.currentData?.meta?.pendingReleasesCount) || 0;\n const hasReachedMaximumPendingReleases = totalPendingReleases >= maximumReleases;\n\n const handleTabChange = (tabValue: string) => {\n setQuery({\n ...query,\n page: 1,\n pageSize: response?.currentData?.meta?.pagination?.pageSize || 16,\n filters: {\n releasedAt: {\n $notNull: tabValue !== 'pending',\n },\n },\n });\n };\n\n const handleAddRelease = async ({ name, scheduledAt, timezone }: FormValues) => {\n const response = await createRelease({\n name,\n scheduledAt,\n timezone,\n });\n if ('data' in response) {\n // When the response returns an object with 'data', handle success\n toggleNotification({\n type: 'success',\n message: formatMessage({\n id: 'content-releases.modal.release-created-notification-success',\n defaultMessage: 'Release created.',\n }),\n });\n\n trackUsage('didCreateRelease');\n navigate(response.data.data.id.toString());\n } else if (isFetchError(response.error)) {\n // When the response returns an object with 'error', handle fetch error\n toggleNotification({\n type: 'danger',\n message: formatAPIError(response.error),\n });\n } else {\n // Otherwise, the response returns an object with 'error', handle a generic error\n toggleNotification({\n type: 'danger',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error occurred' }),\n });\n }\n };\n\n return (\n <Main aria-busy={isLoadingReleases || isLoadingSettings}>\n <Layouts.Header\n title={formatMessage({\n id: 'content-releases.pages.Releases.title',\n defaultMessage: 'Releases',\n })}\n subtitle={formatMessage({\n id: 'content-releases.pages.Releases.header-subtitle',\n defaultMessage: 'Create and manage content updates',\n })}\n primaryAction={\n canCreate ? (\n <Button\n startIcon={<Plus />}\n onClick={toggleAddReleaseModal}\n disabled={hasReachedMaximumPendingReleases}\n >\n {formatMessage({\n id: 'content-releases.header.actions.add-release',\n defaultMessage: 'New release',\n })}\n </Button>\n ) : null\n }\n />\n <Layouts.Content>\n <>\n {hasReachedMaximumPendingReleases && (\n <StyledAlert\n marginBottom={6}\n action={\n <Link href=\"https://strapi.io/pricing-cloud\" isExternal>\n {formatMessage({\n id: 'content-releases.pages.Releases.max-limit-reached.action',\n defaultMessage: 'Explore plans',\n })}\n </Link>\n }\n title={formatMessage(\n {\n id: 'content-releases.pages.Releases.max-limit-reached.title',\n defaultMessage:\n 'You have reached the {number} pending {number, plural, one {release} other {releases}} limit.',\n },\n { number: maximumReleases }\n )}\n onClose={() => {}}\n closeLabel=\"\"\n >\n {formatMessage({\n id: 'content-releases.pages.Releases.max-limit-reached.message',\n defaultMessage: 'Upgrade to manage an unlimited number of releases.',\n })}\n </StyledAlert>\n )}\n <Tabs.Root variant=\"simple\" onValueChange={handleTabChange} value={activeTab}>\n <Box paddingBottom={8}>\n <Tabs.List\n aria-label={formatMessage({\n id: 'content-releases.pages.Releases.tab-group.label',\n defaultMessage: 'Releases list',\n })}\n >\n <Tabs.Trigger value=\"pending\">\n {formatMessage(\n {\n id: 'content-releases.pages.Releases.tab.pending',\n defaultMessage: 'Pending ({count})',\n },\n {\n count: totalPendingReleases,\n }\n )}\n </Tabs.Trigger>\n <Tabs.Trigger value=\"done\">\n {formatMessage({\n id: 'content-releases.pages.Releases.tab.done',\n defaultMessage: 'Done',\n })}\n </Tabs.Trigger>\n </Tabs.List>\n <Divider />\n </Box>\n {/* Pending releases */}\n <Tabs.Content value=\"pending\">\n <ReleasesGrid\n sectionTitle=\"pending\"\n releases={response?.currentData?.data}\n isError={isError}\n />\n </Tabs.Content>\n {/* Done releases */}\n <Tabs.Content value=\"done\">\n <ReleasesGrid\n sectionTitle=\"done\"\n releases={response?.currentData?.data}\n isError={isError}\n />\n </Tabs.Content>\n </Tabs.Root>\n <Pagination.Root\n {...response?.currentData?.meta?.pagination}\n defaultPageSize={response?.currentData?.meta?.pagination?.pageSize}\n >\n <Pagination.PageSize options={['8', '16', '32', '64']} />\n <Pagination.Links />\n </Pagination.Root>\n </>\n </Layouts.Content>\n <ReleaseModal\n open={releaseModalShown}\n handleClose={toggleAddReleaseModal}\n handleSubmit={handleAddRelease}\n isLoading={isSubmittingForm}\n initialValues={{\n ...INITIAL_FORM_VALUES,\n timezone: data?.data.defaultTimezone ? data.data.defaultTimezone.split('&')[1] : null,\n }}\n />\n </Main>\n );\n};\n\nexport { ReleasesPage, getBadgeProps };\n","import * as React from 'react';\n\nimport {\n Page,\n Pagination,\n Table,\n BackButton,\n ConfirmDialog,\n useTracking,\n useAPIErrorHandler,\n useNotification,\n useQueryParams,\n useRBAC,\n isFetchError,\n useStrapiApp,\n Layouts,\n} from '@strapi/admin/strapi-admin';\nimport { unstable_useDocument } from '@strapi/content-manager/strapi-admin';\nimport {\n Button,\n Flex,\n Main,\n Tr,\n Td,\n Typography,\n Badge,\n SingleSelect,\n SingleSelectOption,\n Tooltip,\n EmptyStateLayout,\n LinkButton,\n Dialog,\n SimpleMenu,\n MenuItem,\n} from '@strapi/design-system';\nimport {\n CheckCircle,\n More,\n Pencil,\n Trash,\n CrossCircle,\n ArrowsCounterClockwise,\n} from '@strapi/icons';\nimport { EmptyDocuments } from '@strapi/icons/symbols';\nimport format from 'date-fns/format';\nimport { utcToZonedTime } from 'date-fns-tz';\nimport { useIntl } from 'react-intl';\nimport { useParams, useNavigate, Link as ReactRouterLink, Navigate } from 'react-router-dom';\nimport { styled } from 'styled-components';\n\nimport { RelativeTime } from '../components/RelativeTime';\nimport { ReleaseActionMenu } from '../components/ReleaseActionMenu';\nimport { ReleaseActionOptions } from '../components/ReleaseActionOptions';\nimport { ReleaseModal, FormValues } from '../components/ReleaseModal';\nimport { PERMISSIONS } from '../constants';\nimport {\n GetReleaseActionsQueryParams,\n useGetReleaseActionsQuery,\n useGetReleaseQuery,\n useGetReleaseSettingsQuery,\n useUpdateReleaseMutation,\n useUpdateReleaseActionMutation,\n usePublishReleaseMutation,\n useDeleteReleaseMutation,\n releaseApi,\n} from '../services/release';\nimport { useTypedDispatch } from '../store/hooks';\nimport { isBaseQueryError } from '../utils/api';\nimport { getTimezoneOffset } from '../utils/time';\n\nimport { getBadgeProps } from './ReleasesPage';\n\nimport type {\n ReleaseAction,\n ReleaseActionGroupBy,\n ReleaseActionEntry,\n} from '../../../shared/contracts/release-actions';\nimport type { Struct, Internal } from '@strapi/types';\n\n/* -------------------------------------------------------------------------------------------------\n * ReleaseDetailsLayout\n * -----------------------------------------------------------------------------------------------*/\nconst ReleaseInfoWrapper = styled(Flex)`\n align-self: stretch;\n border-bottom-right-radius: ${({ theme }) => theme.borderRadius};\n border-bottom-left-radius: ${({ theme }) => theme.borderRadius};\n border-top: 1px solid ${({ theme }) => theme.colors.neutral150};\n`;\n\nconst StyledMenuItem = styled(MenuItem)<{\n disabled?: boolean;\n $variant?: 'neutral' | 'danger';\n}>`\n svg path {\n fill: ${({ theme, disabled }) => disabled && theme.colors.neutral500};\n }\n span {\n color: ${({ theme, disabled }) => disabled && theme.colors.neutral500};\n }\n\n &:hover {\n background: ${({ theme, $variant = 'neutral' }) => theme.colors[`${$variant}100`]};\n }\n`;\n\nconst PencilIcon = styled(Pencil)`\n width: ${({ theme }) => theme.spaces[3]};\n height: ${({ theme }) => theme.spaces[3]};\n path {\n fill: ${({ theme }) => theme.colors.neutral600};\n }\n`;\n\nconst TrashIcon = styled(Trash)`\n width: ${({ theme }) => theme.spaces[3]};\n height: ${({ theme }) => theme.spaces[3]};\n path {\n fill: ${({ theme }) => theme.colors.danger600};\n }\n`;\n\nconst TypographyMaxWidth = styled(Typography)`\n max-width: 300px;\n`;\n\ninterface EntryValidationTextProps {\n action: ReleaseAction['type'];\n schema?: Struct.ContentTypeSchema;\n components: { [key: Internal.UID.Component]: Struct.ComponentSchema };\n entry: ReleaseActionEntry;\n status: ReleaseAction['status'];\n}\n\nconst EntryValidationText = ({ action, schema, entry, status }: EntryValidationTextProps) => {\n const { formatMessage } = useIntl();\n\n const { validate, isLoading } = unstable_useDocument(\n {\n collectionType: schema?.kind ?? '',\n model: schema?.uid ?? '',\n },\n {\n // 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\n skip: true,\n }\n );\n\n if (isLoading) {\n return null;\n }\n\n const errors = validate(entry) ?? {};\n\n if (action === 'publish') {\n if (Object.keys(errors).length > 0) {\n const validationErrorsMessages = Object.entries(errors)\n .map(([key, value]) =>\n formatMessage(\n // @ts-expect-error – TODO: fix this will better checks\n { id: `${value.id}.withField`, defaultMessage: value.defaultMessage },\n { field: key }\n )\n )\n .join(' ');\n\n return (\n <Flex gap={2}>\n <CrossCircle fill=\"danger600\" />\n <Tooltip description={validationErrorsMessages}>\n <TypographyMaxWidth\n textColor=\"danger600\"\n variant=\"omega\"\n fontWeight=\"semiBold\"\n ellipsis\n >\n {validationErrorsMessages}\n </TypographyMaxWidth>\n </Tooltip>\n </Flex>\n );\n }\n\n if (status === 'draft') {\n return (\n <Flex gap={2}>\n <CheckCircle fill=\"success600\" />\n <Typography>\n {formatMessage({\n id: 'content-releases.pages.ReleaseDetails.entry-validation.ready-to-publish',\n defaultMessage: 'Ready to publish',\n })}\n </Typography>\n </Flex>\n );\n }\n\n if (status === 'modified') {\n return (\n <Flex gap={2}>\n <ArrowsCounterClockwise fill=\"alternative600\" />\n <Typography>\n {formatMessage({\n id: 'content-releases.pages.ReleaseDetails.entry-validation.modified',\n defaultMessage: 'Ready to publish changes',\n })}\n </Typography>\n </Flex>\n );\n }\n\n if (status === 'published') {\n return (\n <Flex gap={2}>\n <CheckCircle fill=\"success600\" />\n <Typography>\n {formatMessage({\n id: 'content-releases.pages.ReleaseDetails.entry-validation.already-published',\n defaultMessage: 'Already published',\n })}\n </Typography>\n </Flex>\n );\n }\n }\n\n return (\n <Flex gap={2}>\n <CheckCircle fill=\"success600\" />\n {!entry.publishedAt ? (\n <Typography textColor=\"success600\" fontWeight=\"bold\">\n {formatMessage({\n id: 'content-releases.pages.ReleaseDetails.entry-validation.already-unpublished',\n defaultMessage: 'Already unpublished',\n })}\n </Typography>\n ) : (\n <Typography>\n {formatMessage({\n id: 'content-releases.pages.ReleaseDetails.entry-validation.ready-to-unpublish',\n defaultMessage: 'Ready to unpublish',\n })}\n </Typography>\n )}\n </Flex>\n );\n};\ninterface ReleaseDetailsLayoutProps {\n toggleEditReleaseModal: () => void;\n toggleWarningSubmit: () => void;\n children: React.ReactNode;\n}\n\nconst ReleaseDetailsLayout = ({\n toggleEditReleaseModal,\n toggleWarningSubmit,\n children,\n}: ReleaseDetailsLayoutProps) => {\n const { formatMessage, formatDate, formatTime } = useIntl();\n const { releaseId } = useParams<{ releaseId: string }>();\n const {\n data,\n isLoading: isLoadingDetails,\n error,\n } = useGetReleaseQuery(\n { id: releaseId! },\n {\n skip: !releaseId,\n }\n );\n const [publishRelease, { isLoading: isPublishing }] = usePublishReleaseMutation();\n const { toggleNotification } = useNotification();\n const { formatAPIError } = useAPIErrorHandler();\n const { allowedActions } = useRBAC(PERMISSIONS);\n const { canUpdate, canDelete, canPublish } = allowedActions;\n const dispatch = useTypedDispatch();\n const { trackUsage } = useTracking();\n\n const release = data?.data;\n\n const handlePublishRelease = (id: string) => async () => {\n const response = await publishRelease({ id });\n\n if ('data' in response) {\n // When the response returns an object with 'data', handle success\n toggleNotification({\n type: 'success',\n message: formatMessage({\n id: 'content-releases.pages.ReleaseDetails.publish-notification-success',\n defaultMessage: 'Release was published successfully.',\n }),\n });\n\n const { totalEntries, totalPublishedEntries, totalUnpublishedEntries } = response.data.meta;\n\n trackUsage('didPublishRelease', {\n totalEntries,\n totalPublishedEntries,\n totalUnpublishedEntries,\n });\n } else if (isFetchError(response.error)) {\n // When the response returns an object with 'error', handle fetch error\n toggleNotification({\n type: 'danger',\n message: formatAPIError(response.error),\n });\n } else {\n // Otherwise, the response returns an object with 'error', handle a generic error\n toggleNotification({\n type: 'danger',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error occurred' }),\n });\n }\n };\n\n const handleRefresh = () => {\n dispatch(\n releaseApi.util.invalidateTags([\n { type: 'ReleaseAction', id: 'LIST' },\n { type: 'Release', id: releaseId },\n ])\n );\n };\n\n const getCreatedByUser = () => {\n if (!release?.createdBy) {\n return null;\n }\n\n // Favor the username\n if (release.createdBy.username) {\n return release.createdBy.username;\n }\n\n // Firstname may not exist if created with SSO\n if (release.createdBy.firstname) {\n return `${release.createdBy.firstname} ${release.createdBy.lastname || ''}`.trim();\n }\n\n // All users must have at least an email\n return release.createdBy.email;\n };\n\n if (isLoadingDetails) {\n return <Page.Loading />;\n }\n\n if ((isBaseQueryError(error) && 'code' in error) || !release) {\n return (\n <Navigate\n to=\"..\"\n state={{\n errors: [\n {\n // @ts-expect-error – TODO: fix this weird error flow\n code: error?.code,\n },\n ],\n }}\n />\n );\n }\n\n const totalEntries = release.actions.meta.count || 0;\n const hasCreatedByUser = Boolean(getCreatedByUser());\n\n const isScheduled = release.scheduledAt && release.timezone;\n const numberOfEntriesText = formatMessage(\n {\n id: 'content-releases.pages.Details.header-subtitle',\n defaultMessage: '{number, plural, =0 {No entries} one {# entry} other {# entries}}',\n },\n { number: totalEntries }\n );\n const scheduledText = isScheduled\n ? formatMessage(\n {\n id: 'content-releases.pages.ReleaseDetails.header-subtitle.scheduled',\n defaultMessage: 'Scheduled for {date} at {time} ({offset})',\n },\n {\n date: formatDate(new Date(release.scheduledAt!), {\n weekday: 'long',\n day: 'numeric',\n month: 'long',\n year: 'numeric',\n timeZone: release.timezone!,\n }),\n time: formatTime(new Date(release.scheduledAt!), {\n timeZone: release.timezone!,\n hourCycle: 'h23',\n }),\n offset: getTimezoneOffset(release.timezone!, new Date(release.scheduledAt!)),\n }\n )\n : '';\n\n return (\n <Main aria-busy={isLoadingDetails}>\n <Layouts.Header\n title={release.name}\n subtitle={\n <Flex gap={2} lineHeight={6}>\n <Typography textColor=\"neutral600\" variant=\"epsilon\">\n {numberOfEntriesText + (isScheduled ? ` - ${scheduledText}` : '')}\n </Typography>\n <Badge {...getBadgeProps(release.status)}>{release.status}</Badge>\n </Flex>\n }\n navigationAction={<BackButton />}\n primaryAction={\n !release.releasedAt && (\n <Flex gap={2}>\n <SimpleMenu\n label={<More />}\n variant=\"tertiary\"\n endIcon={null}\n paddingLeft={2}\n paddingRight={2}\n aria-label={formatMessage({\n id: 'content-releases.header.actions.open-release-actions',\n defaultMessage: 'Release edit and delete menu',\n })}\n popoverPlacement=\"bottom-end\"\n >\n <StyledMenuItem disabled={!canUpdate} onSelect={toggleEditReleaseModal}>\n <Flex alignItems=\"center\" gap={2} hasRadius width=\"100%\">\n <PencilIcon />\n <Typography ellipsis>\n {formatMessage({\n id: 'content-releases.header.actions.edit',\n defaultMessage: 'Edit',\n })}\n </Typography>\n </Flex>\n </StyledMenuItem>\n <StyledMenuItem\n disabled={!canDelete}\n onSelect={toggleWarningSubmit}\n $variant=\"danger\"\n >\n <Flex alignItems=\"center\" gap={2} hasRadius width=\"100%\">\n <TrashIcon />\n <Typography ellipsis textColor=\"danger600\">\n {formatMessage({\n id: 'content-releases.header.actions.delete',\n defaultMessage: 'Delete',\n })}\n </Typography>\n </Flex>\n </StyledMenuItem>\n <ReleaseInfoWrapper\n direction=\"column\"\n justifyContent=\"center\"\n alignItems=\"flex-start\"\n gap={1}\n padding={5}\n >\n <Typography variant=\"pi\" fontWeight=\"bold\">\n {formatMessage({\n id: 'content-releases.header.actions.created',\n defaultMessage: 'Created',\n })}\n </Typography>\n <Typography variant=\"pi\" color=\"neutral300\">\n <RelativeTime timestamp={new Date(release.createdAt)} />\n {formatMessage(\n {\n id: 'content-releases.header.actions.created.description',\n defaultMessage:\n '{hasCreatedByUser, select, true { by {createdBy}} other { by deleted user}}',\n },\n { createdBy: getCreatedByUser(), hasCreatedByUser }\n )}\n </Typography>\n </ReleaseInfoWrapper>\n </SimpleMenu>\n <Button size=\"S\" variant=\"tertiary\" onClick={handleRefresh}>\n {formatMessage({\n id: 'content-releases.header.actions.refresh',\n defaultMessage: 'Refresh',\n })}\n </Button>\n {canPublish ? (\n <Button\n size=\"S\"\n variant=\"default\"\n onClick={handlePublishRelease(release.id.toString())}\n loading={isPublishing}\n disabled={release.actions.meta.count === 0}\n >\n {formatMessage({\n id: 'content-releases.header.actions.publish',\n defaultMessage: 'Publish',\n })}\n </Button>\n ) : null}\n </Flex>\n )\n }\n />\n {children}\n </Main>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ReleaseDetailsBody\n * -----------------------------------------------------------------------------------------------*/\nconst GROUP_BY_OPTIONS = ['contentType', 'locale', 'action'] as const;\nconst GROUP_BY_OPTIONS_NO_LOCALE = ['contentType', 'action'] as const;\nconst getGroupByOptionLabel = (value: (typeof GROUP_BY_OPTIONS)[number]) => {\n if (value === 'locale') {\n return {\n id: 'content-releases.pages.ReleaseDetails.groupBy.option.locales',\n defaultMessage: 'Locales',\n };\n }\n\n if (value === 'action') {\n return {\n id: 'content-releases.pages.ReleaseDetails.groupBy.option.actions',\n defaultMessage: 'Actions',\n };\n }\n\n return {\n id: 'content-releases.pages.ReleaseDetails.groupBy.option.content-type',\n defaultMessage: 'Content-Types',\n };\n};\n\ninterface ReleaseDetailsBodyProps {\n releaseId: string;\n}\n\nconst ReleaseDetailsBody = ({ releaseId }: ReleaseDetailsBodyProps) => {\n const { formatMessage } = useIntl();\n const [{ query }, setQuery] = useQueryParams<GetReleaseActionsQueryParams>();\n const { toggleNotification } = useNotification();\n const { formatAPIError } = useAPIErrorHandler();\n const {\n data: releaseData,\n isLoading: isReleaseLoading,\n error: releaseError,\n } = useGetReleaseQuery({ id: releaseId });\n const {\n allowedActions: { canUpdate },\n } = useRBAC(PERMISSIONS);\n const runHookWaterfall = useStrapiApp('ReleaseDetailsPage', (state) => state.runHookWaterfall);\n\n // TODO: Migrated displayedHeader to v5\n const { displayedHeaders, hasI18nEnabled }: { displayedHeaders: any; hasI18nEnabled: boolean } =\n runHookWaterfall('ContentReleases/pages/ReleaseDetails/add-locale-in-releases', {\n displayedHeaders: [\n {\n label: {\n id: 'content-releases.page.ReleaseDetails.table.header.label.name',\n defaultMessage: 'name',\n },\n name: 'name',\n },\n ],\n hasI18nEnabled: false,\n });\n\n const release = releaseData?.data;\n const selectedGroupBy = query?.groupBy || 'contentType';\n\n const {\n isLoading,\n isFetching,\n isError,\n data,\n error: releaseActionsError,\n } = useGetReleaseActionsQuery({\n ...query,\n releaseId,\n });\n\n const [updateReleaseAction] = useUpdateReleaseActionMutation();\n\n const handleChangeType = async (\n e: React.ChangeEvent<HTMLInputElement>,\n actionId: ReleaseAction['id'],\n actionPath: [string, number]\n ) => {\n const response = await updateReleaseAction({\n params: {\n releaseId,\n actionId,\n },\n body: {\n type: e.target.value as ReleaseAction['type'],\n },\n query, // We are passing the query params to make optimistic updates\n actionPath, // We are passing the action path to found the position in the cache of the action for optimistic updates\n });\n\n if ('error' in response) {\n if (isFetchError(response.error)) {\n // When the response returns an object with 'error', handle fetch error\n toggleNotification({\n type: 'danger',\n message: formatAPIError(response.error),\n });\n } else {\n // Otherwise, the response returns an object with 'error', handle a generic error\n toggleNotification({\n type: 'danger',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error occurred' }),\n });\n }\n }\n };\n\n if (isLoading || isReleaseLoading) {\n return <Page.Loading />;\n }\n\n const releaseActions = data?.data;\n const releaseMeta = data?.meta;\n const contentTypes = releaseMeta?.contentTypes || {};\n const components = releaseMeta?.components || {};\n\n if (isBaseQueryError(releaseError) || !release) {\n const errorsArray = [];\n if (releaseError && 'code' in releaseError) {\n errorsArray.push({\n code: releaseError.code,\n });\n }\n if (releaseActionsError && 'code' in releaseActionsError) {\n errorsArray.push({\n code: releaseActionsError.code,\n });\n }\n return (\n <Navigate\n to=\"..\"\n state={{\n errors: errorsArray,\n }}\n />\n );\n }\n\n if (isError || !releaseActions) {\n return <Page.Error />;\n }\n\n if (Object.keys(releaseActions).length === 0) {\n return (\n <Layouts.Content>\n <EmptyStateLayout\n action={\n <LinkButton\n tag={ReactRouterLink}\n to={{\n pathname: '/content-manager',\n }}\n style={{ textDecoration: 'none' }}\n variant=\"secondary\"\n >\n {formatMessage({\n id: 'content-releases.page.Details.button.openContentManager',\n defaultMessage: 'Open the Content Manager',\n })}\n </LinkButton>\n }\n icon={<EmptyDocuments width=\"16rem\" />}\n content={formatMessage({\n id: 'content-releases.pages.Details.tab.emptyEntries',\n defaultMessage:\n 'This release is empty. Open the Content Manager, select an entry and add it to the release.',\n })}\n />\n </Layouts.Content>\n );\n }\n\n const groupByLabel = formatMessage({\n id: 'content-releases.pages.ReleaseDetails.groupBy.aria-label',\n defaultMessage: 'Group by',\n });\n const headers = [\n ...displayedHeaders,\n {\n label: {\n id: 'content-releases.page.ReleaseDetails.table.header.label.content-type',\n defaultMessage: 'content-type',\n },\n name: 'content-type',\n },\n {\n label: {\n id: 'content-releases.page.ReleaseDetails.table.header.label.action',\n defaultMessage: 'action',\n },\n name: 'action',\n },\n ...(!release.releasedAt\n ? [\n {\n label: {\n id: 'content-releases.page.ReleaseDetails.table.header.label.status',\n defaultMessage: 'status',\n },\n name: 'status',\n },\n ]\n : []),\n ];\n\n const options = hasI18nEnabled ? GROUP_BY_OPTIONS : GROUP_BY_OPTIONS_NO_LOCALE;\n\n return (\n <Layouts.Content>\n <Flex gap={8} direction=\"column\" alignItems=\"stretch\">\n <Flex>\n <SingleSelect\n placeholder={groupByLabel}\n aria-label={groupByLabel}\n customizeContent={(value) =>\n formatMessage(\n {\n id: `content-releases.pages.ReleaseDetails.groupBy.label`,\n defaultMessage: `Group by {groupBy}`,\n },\n {\n groupBy: value,\n }\n )\n }\n value={formatMessage(getGroupByOptionLabel(selectedGroupBy))}\n onChange={(value) => setQuery({ groupBy: value as ReleaseActionGroupBy })}\n >\n {options.map((option) => (\n <SingleSelectOption key={option} value={option}>\n {formatMessage(getGroupByOptionLabel(option))}\n </SingleSelectOption>\n ))}\n </SingleSelect>\n </Flex>\n {Object.keys(releaseActions).map((key) => (\n <Flex key={`releases-group-${key}`} gap={4} direction=\"column\" alignItems=\"stretch\">\n <Flex role=\"separator\" aria-label={key}>\n <Badge>{key}</Badge>\n </Flex>\n <Table.Root\n rows={releaseActions[key].map((item) => ({\n ...item,\n id: Number(item.entry.id),\n }))}\n headers={headers}\n isLoading={isLoading || isFetching}\n >\n <Table.Content>\n <Table.Head>\n {headers.map(({ label, name }) => (\n <Table.HeaderCell key={name} label={formatMessage(label)} name={name} />\n ))}\n </Table.Head>\n <Table.Loading />\n <Table.Body>\n {releaseActions[key].map(\n ({ id, contentType, locale, type, entry, status }, actionIndex) => (\n <Tr key={id}>\n <Td width=\"25%\" maxWidth=\"200px\">\n <Typography ellipsis>{`${\n contentType.mainFieldValue || entry.id\n }`}</Typography>\n </Td>\n {hasI18nEnabled && (\n <Td width=\"10%\">\n <Typography>{`${locale?.name ? locale.name : '-'}`}</Typography>\n </Td>\n )}\n\n <Td width=\"10%\">\n <Typography>{contentType.displayName || ''}</Typography>\n </Td>\n <Td width=\"20%\">\n {release.releasedAt ? (\n <Typography>\n {formatMessage(\n {\n id: 'content-releases.page.ReleaseDetails.table.action-published',\n defaultMessage:\n 'This entry was <b>{isPublish, select, true {published} other {unpublished}}</b>.',\n },\n {\n isPublish: type === 'publish',\n b: (children: React.ReactNode) => (\n <Typography fontWeight=\"bold\">{children}</Typography>\n ),\n }\n )}\n </Typography>\n ) : (\n <ReleaseActionOptions\n selected={type}\n handleChange={(e) => handleChangeType(e, id, [key, actionIndex])}\n name={`release-action-${id}-type`}\n disabled={!canUpdate}\n />\n )}\n </Td>\n {!release.releasedAt && (\n <>\n <Td width=\"20%\" minWidth=\"200px\">\n <EntryValidationText\n action={type}\n schema={contentTypes?.[contentType.uid]}\n components={components}\n entry={entry}\n status={status}\n />\n </Td>\n <Td>\n <Flex justifyContent=\"flex-end\">\n <ReleaseActionMenu.Root>\n <ReleaseActionMenu.ReleaseActionEntryLinkItem\n contentTypeUid={contentType.uid}\n documentId={entry.documentId}\n locale={locale?.code}\n />\n <ReleaseActionMenu.DeleteReleaseActionItem\n releaseId={release.id}\n actionId={id}\n />\n </ReleaseActionMenu.Root>\n </Flex>\n </Td>\n </>\n )}\n </Tr>\n )\n )}\n </Table.Body>\n </Table.Content>\n </Table.Root>\n </Flex>\n ))}\n <Pagination.Root\n {...releaseMeta?.pagination}\n defaultPageSize={releaseMeta?.pagination?.pageSize}\n >\n <Pagination.PageSize />\n <Pagination.Links />\n </Pagination.Root>\n </Flex>\n </Layouts.Content>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ReleaseDetailsPage\n * -----------------------------------------------------------------------------------------------*/\nconst ReleaseDetailsPage = () => {\n const { formatMessage } = useIntl();\n const { releaseId } = useParams<{ releaseId: string }>();\n const { toggleNotification } = useNotification();\n const { formatAPIError } = useAPIErrorHandler();\n const navigate = useNavigate();\n const [releaseModalShown, setReleaseModalShown] = React.useState(false);\n const [showWarningSubmit, setWarningSubmit] = React.useState(false);\n\n const {\n isLoading: isLoadingDetails,\n data,\n isSuccess: isSuccessDetails,\n } = useGetReleaseQuery(\n { id: releaseId! },\n {\n skip: !releaseId,\n }\n );\n const { data: dataTimezone, isLoading: isLoadingTimezone } = useGetReleaseSettingsQuery();\n const [updateRelease, { isLoading: isSubmittingForm }] = useUpdateReleaseMutation();\n const [deleteRelease] = useDeleteReleaseMutation();\n\n const toggleEditReleaseModal = () => {\n setReleaseModalShown((prev) => !prev);\n };\n\n const getTimezoneValue = () => {\n if (releaseData?.timezone) {\n return releaseData.timezone;\n } else {\n if (dataTimezone?.data.defaultTimezone) {\n return dataTimezone.data.defaultTimezone;\n }\n return null;\n }\n };\n\n const toggleWarningSubmit = () => setWarningSubmit((prevState) => !prevState);\n\n if (isLoadingDetails || isLoadingTimezone) {\n return (\n <ReleaseDetailsLayout\n toggleEditReleaseModal={toggleEditReleaseModal}\n toggleWarningSubmit={toggleWarningSubmit}\n >\n <Page.Loading />\n </ReleaseDetailsLayout>\n );\n }\n\n if (!releaseId) {\n return <Navigate to=\"..\" />;\n }\n\n const releaseData = (isSuccessDetails && data?.data) || null;\n\n const title = releaseData?.name || '';\n const timezone = getTimezoneValue();\n const scheduledAt =\n releaseData?.scheduledAt && timezone ? utcToZonedTime(releaseData.scheduledAt, timezone) : null;\n // Just get the date and time to display without considering updated timezone time\n const date = scheduledAt ? format(scheduledAt, 'yyyy-MM-dd') : undefined;\n const time = scheduledAt ? format(scheduledAt, 'HH:mm') : '';\n\n const handleEditRelease = async (values: FormValues) => {\n const response = await updateRelease({\n id: releaseId,\n name: values.name,\n scheduledAt: values.scheduledAt,\n timezone: values.timezone,\n });\n\n if ('data' in response) {\n // When the response returns an object with 'data', handle success\n toggleNotification({\n type: 'success',\n message: formatMessage({\n id: 'content-releases.modal.release-updated-notification-success',\n defaultMessage: 'Release updated.',\n }),\n });\n toggleEditReleaseModal();\n } else if (isFetchError(response.error)) {\n // When the response returns an object with 'error', handle fetch error\n toggleNotification({\n type: 'danger',\n message: formatAPIError(response.error),\n });\n } else {\n // Otherwise, the response returns an object with 'error', handle a generic error\n toggleNotification({\n type: 'danger',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error occurred' }),\n });\n }\n };\n\n const handleDeleteRelease = async () => {\n const response = await deleteRelease({\n id: releaseId,\n });\n\n if ('data' in response) {\n navigate('..');\n } else if (isFetchError(response.error)) {\n // When the response returns an object with 'error', handle fetch error\n toggleNotification({\n type: 'danger',\n message: formatAPIError(response.error),\n });\n } else {\n // Otherwise, the response returns an object with 'error', handle a generic error\n toggleNotification({\n type: 'danger',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error occurred' }),\n });\n }\n };\n\n return (\n <ReleaseDetailsLayout\n toggleEditReleaseModal={toggleEditReleaseModal}\n toggleWarningSubmit={toggleWarningSubmit}\n >\n <ReleaseDetailsBody releaseId={releaseId} />\n <ReleaseModal\n open={releaseModalShown}\n handleClose={toggleEditReleaseModal}\n handleSubmit={handleEditRelease}\n isLoading={isLoadingDetails || isSubmittingForm}\n initialValues={{\n name: title || '',\n scheduledAt,\n date,\n time,\n isScheduled: Boolean(scheduledAt),\n timezone,\n }}\n />\n <Dialog.Root open={showWarningSubmit} onOpenChange={toggleWarningSubmit}>\n <ConfirmDialog onConfirm={handleDeleteRelease}>\n {formatMessage({\n id: 'content-releases.dialog.confirmation-message',\n defaultMessage: 'Are you sure you want to delete this release?',\n })}\n </ConfirmDialog>\n </Dialog.Root>\n </ReleaseDetailsLayout>\n );\n};\n\nexport { ReleaseDetailsPage };\n","import { Page } from '@strapi/admin/strapi-admin';\nimport { Route, Routes } from 'react-router-dom';\n\nimport { PERMISSIONS } from '../constants';\n\nimport { ReleaseDetailsPage } from './ReleaseDetailsPage';\nimport { ReleasesPage } from './ReleasesPage';\n\nexport const App = () => {\n return (\n <Page.Protect permissions={PERMISSIONS.main}>\n <Routes>\n <Route index element={<ReleasesPage />} />\n <Route path={':releaseId'} element={<ReleaseDetailsPage />} />\n </Routes>\n </Page.Protect>\n );\n};\n"],"names":["RelativeTime","React","useIntl","intervalToDuration","isPast","jsx","useLocation","pluginId","getTimezones","zonedTimeToUtc","Modal","jsxs","Formik","RELEASE_SCHEMA","Form","Flex","Field","TextInput","Box","Checkbox","Typography","Fragment","DatePicker","formatISO","utcToZonedTime","TimePicker","Button","useFormikContext","timezoneList","Combobox","ComboboxOption","useDispatch","styled","Link","BaseRelativeTime","Page","EmptyStateLayout","EmptyDocuments","Grid","NavLink","Badge","Alert","useNotification","useNavigate","useAPIErrorHandler","useQueryParams","useGetReleasesQuery","useGetReleaseSettingsQuery","useCreateReleaseMutation","useLicenseLimits","useTracking","useRBAC","PERMISSIONS","response","isFetchError","Main","Layouts","Plus","Tabs","Divider","Pagination","MenuItem","Pencil","Trash","unstable_useDocument","CrossCircle","Tooltip","CheckCircle","ArrowsCounterClockwise","useParams","useGetReleaseQuery","usePublishReleaseMutation","totalEntries","releaseApi","Navigate","getTimezoneOffset","BackButton","SimpleMenu","More","useStrapiApp","useGetReleaseActionsQuery","useUpdateReleaseActionMutation","LinkButton","ReactRouterLink","SingleSelect","SingleSelectOption","Table","Tr","Td","ReleaseActionOptions","ReleaseActionMenu","useUpdateReleaseMutation","useDeleteReleaseMutation","format","Dialog","ConfirmDialog","Routes","Route"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useNotification, useAPIErrorHandler, useQueryParams, useTracking, useRBAC, Page, Layouts, Pagination, isFetchError, ConfirmDialog, BackButton, useStrapiApp, Table } from "@strapi/admin/strapi-admin";
|
|
3
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 useCreateReleaseMutation, P as PERMISSIONS,
|
|
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-VB3t7pBK.mjs";
|
|
5
5
|
import * as React from "react";
|
|
6
6
|
import { unstable_useDocument } from "@strapi/content-manager/strapi-admin";
|
|
7
7
|
import { Modal, Flex, Field, TextInput, Box, Checkbox, Typography, DatePicker, TimePicker, Button, Combobox, ComboboxOption, Link, Alert, Main, Tabs, Divider, EmptyStateLayout, Grid, Badge, MenuItem, Dialog, SimpleMenu, LinkButton, SingleSelect, SingleSelectOption, Tr, Td, Tooltip } from "@strapi/design-system";
|
|
@@ -13,7 +13,7 @@ import { useIntl } from "react-intl";
|
|
|
13
13
|
import { styled } from "styled-components";
|
|
14
14
|
import { intervalToDuration, isPast, formatISO } from "date-fns";
|
|
15
15
|
import { Formik, Form, useFormikContext } from "formik";
|
|
16
|
-
import { R as RELEASE_SCHEMA } from "./
|
|
16
|
+
import { R as RELEASE_SCHEMA } from "./schemas-CBVqXur2.mjs";
|
|
17
17
|
import { useDispatch } from "react-redux";
|
|
18
18
|
import { useLicenseLimits } from "@strapi/admin/strapi-admin/ee";
|
|
19
19
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
|
@@ -361,6 +361,7 @@ const ReleasesPage = () => {
|
|
|
361
361
|
const { formatAPIError } = useAPIErrorHandler();
|
|
362
362
|
const [{ query }, setQuery] = useQueryParams();
|
|
363
363
|
const response = useGetReleasesQuery(query);
|
|
364
|
+
const { data, isLoading: isLoadingSettings } = useGetReleaseSettingsQuery();
|
|
364
365
|
const [createRelease, { isLoading: isSubmittingForm }] = useCreateReleaseMutation();
|
|
365
366
|
const { getFeature } = useLicenseLimits();
|
|
366
367
|
const { maximumReleases = 3 } = getFeature("cms-content-releases");
|
|
@@ -368,7 +369,7 @@ const ReleasesPage = () => {
|
|
|
368
369
|
const {
|
|
369
370
|
allowedActions: { canCreate }
|
|
370
371
|
} = useRBAC(PERMISSIONS);
|
|
371
|
-
const { isLoading, isSuccess, isError } = response;
|
|
372
|
+
const { isLoading: isLoadingReleases, isSuccess, isError } = response;
|
|
372
373
|
const activeTab = response?.currentData?.meta?.activeTab || "pending";
|
|
373
374
|
React.useEffect(() => {
|
|
374
375
|
if (location?.state?.errors) {
|
|
@@ -389,7 +390,7 @@ const ReleasesPage = () => {
|
|
|
389
390
|
const toggleAddReleaseModal = () => {
|
|
390
391
|
setReleaseModalShown((prev) => !prev);
|
|
391
392
|
};
|
|
392
|
-
if (
|
|
393
|
+
if (isLoadingReleases || isLoadingSettings) {
|
|
393
394
|
return /* @__PURE__ */ jsx(Page.Loading, {});
|
|
394
395
|
}
|
|
395
396
|
const totalPendingReleases = isSuccess && response.currentData?.meta?.pendingReleasesCount || 0;
|
|
@@ -434,7 +435,7 @@ const ReleasesPage = () => {
|
|
|
434
435
|
});
|
|
435
436
|
}
|
|
436
437
|
};
|
|
437
|
-
return /* @__PURE__ */ jsxs(Main, { "aria-busy":
|
|
438
|
+
return /* @__PURE__ */ jsxs(Main, { "aria-busy": isLoadingReleases || isLoadingSettings, children: [
|
|
438
439
|
/* @__PURE__ */ jsx(
|
|
439
440
|
Layouts.Header,
|
|
440
441
|
{
|
|
@@ -549,7 +550,10 @@ const ReleasesPage = () => {
|
|
|
549
550
|
handleClose: toggleAddReleaseModal,
|
|
550
551
|
handleSubmit: handleAddRelease,
|
|
551
552
|
isLoading: isSubmittingForm,
|
|
552
|
-
initialValues:
|
|
553
|
+
initialValues: {
|
|
554
|
+
...INITIAL_FORM_VALUES,
|
|
555
|
+
timezone: data?.data.defaultTimezone ? data.data.defaultTimezone.split("&")[1] : null
|
|
556
|
+
}
|
|
553
557
|
}
|
|
554
558
|
)
|
|
555
559
|
] });
|
|
@@ -1189,13 +1193,24 @@ const ReleaseDetailsPage = () => {
|
|
|
1189
1193
|
skip: !releaseId
|
|
1190
1194
|
}
|
|
1191
1195
|
);
|
|
1196
|
+
const { data: dataTimezone, isLoading: isLoadingTimezone } = useGetReleaseSettingsQuery();
|
|
1192
1197
|
const [updateRelease, { isLoading: isSubmittingForm }] = useUpdateReleaseMutation();
|
|
1193
1198
|
const [deleteRelease] = useDeleteReleaseMutation();
|
|
1194
1199
|
const toggleEditReleaseModal = () => {
|
|
1195
1200
|
setReleaseModalShown((prev) => !prev);
|
|
1196
1201
|
};
|
|
1202
|
+
const getTimezoneValue = () => {
|
|
1203
|
+
if (releaseData?.timezone) {
|
|
1204
|
+
return releaseData.timezone;
|
|
1205
|
+
} else {
|
|
1206
|
+
if (dataTimezone?.data.defaultTimezone) {
|
|
1207
|
+
return dataTimezone.data.defaultTimezone;
|
|
1208
|
+
}
|
|
1209
|
+
return null;
|
|
1210
|
+
}
|
|
1211
|
+
};
|
|
1197
1212
|
const toggleWarningSubmit = () => setWarningSubmit((prevState) => !prevState);
|
|
1198
|
-
if (isLoadingDetails) {
|
|
1213
|
+
if (isLoadingDetails || isLoadingTimezone) {
|
|
1199
1214
|
return /* @__PURE__ */ jsx(
|
|
1200
1215
|
ReleaseDetailsLayout,
|
|
1201
1216
|
{
|
|
@@ -1210,7 +1225,7 @@ const ReleaseDetailsPage = () => {
|
|
|
1210
1225
|
}
|
|
1211
1226
|
const releaseData = isSuccessDetails && data?.data || null;
|
|
1212
1227
|
const title = releaseData?.name || "";
|
|
1213
|
-
const timezone =
|
|
1228
|
+
const timezone = getTimezoneValue();
|
|
1214
1229
|
const scheduledAt = releaseData?.scheduledAt && timezone ? utcToZonedTime(releaseData.scheduledAt, timezone) : null;
|
|
1215
1230
|
const date = scheduledAt ? format(scheduledAt, "yyyy-MM-dd") : void 0;
|
|
1216
1231
|
const time = scheduledAt ? format(scheduledAt, "HH:mm") : "";
|
|
@@ -1301,4 +1316,4 @@ const App = () => {
|
|
|
1301
1316
|
export {
|
|
1302
1317
|
App
|
|
1303
1318
|
};
|
|
1304
|
-
//# sourceMappingURL=App-
|
|
1319
|
+
//# sourceMappingURL=App-CwBi9wFK.mjs.map
|