@strapi/content-releases 5.0.0-rc.11 → 5.0.0-rc.12

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.
@@ -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--_NWfuDG.js");
6
+ const index = require("./index-BXCLDMjy.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");
@@ -660,19 +660,37 @@ const EntryValidationText = ({ action, schema, entry, status }) => {
660
660
  skip: true
661
661
  }
662
662
  );
663
+ const errorsToString = (errors2, prefix = "") => {
664
+ if (Object.keys(errors2).length === 0) {
665
+ return "";
666
+ }
667
+ return Object.entries(errors2).map(([key, value]) => {
668
+ if (value === void 0 || value === null) {
669
+ return "";
670
+ }
671
+ if (typeof value === "string") {
672
+ return formatMessage(
673
+ { id: value, defaultMessage: value },
674
+ { field: prefix ? `${prefix}.${key}` : key }
675
+ );
676
+ }
677
+ if (typeof value === "object" && value !== null && "id" in value && "defaultMessage" in value) {
678
+ return formatMessage(
679
+ // @ts-expect-error – TODO: default message will be a string
680
+ { id: `${value.id}.withField`, defaultMessage: value.defaultMessage },
681
+ { field: prefix ? `${prefix}.${key}` : key }
682
+ );
683
+ }
684
+ return errorsToString(value, key);
685
+ }).join(" ");
686
+ };
663
687
  if (isLoading) {
664
688
  return null;
665
689
  }
666
690
  const errors = validate(entry) ?? {};
667
691
  if (action === "publish") {
668
692
  if (Object.keys(errors).length > 0) {
669
- const validationErrorsMessages = Object.entries(errors).map(
670
- ([key, value]) => formatMessage(
671
- // @ts-expect-error – TODO: fix this will better checks
672
- { id: `${value.id}.withField`, defaultMessage: value.defaultMessage },
673
- { field: key }
674
- )
675
- ).join(" ");
693
+ const validationErrorsMessages = errorsToString(errors);
676
694
  return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
677
695
  /* @__PURE__ */ jsxRuntime.jsx(icons.CrossCircle, { fill: "danger600" }),
678
696
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tooltip, { description: validationErrorsMessages, children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -902,7 +920,7 @@ const ReleaseDetailsLayout = ({
902
920
  justifyContent: "center",
903
921
  alignItems: "flex-start",
904
922
  gap: 1,
905
- padding: 5,
923
+ padding: 4,
906
924
  children: [
907
925
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", children: formatMessage({
908
926
  id: "content-releases.header.actions.created",
@@ -1374,4 +1392,4 @@ const App = () => {
1374
1392
  ] }) });
1375
1393
  };
1376
1394
  exports.App = App;
1377
- //# sourceMappingURL=App-fAgiijnc.js.map
1395
+ //# sourceMappingURL=App-BJ6h-Xgj.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"App-BJ6h-Xgj.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 { MessageDescriptor, 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\n name=\"name\"\n error={\n errors.name &&\n formatMessage({ id: errors.name, defaultMessage: errors.name })\n }\n required\n >\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\n name=\"date\"\n error={\n errors.date &&\n formatMessage({ id: errors.date, defaultMessage: errors.date })\n }\n required\n >\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\n name=\"time\"\n error={\n errors.time &&\n formatMessage({ id: errors.time, defaultMessage: errors.time })\n }\n required\n >\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\n name=\"timezone\"\n error={\n errors.timezone && formatMessage({ id: errors.timezone, defaultMessage: errors.timezone })\n }\n required\n >\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 { format } from 'date-fns';\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} direction=\"column\" alignItems=\"stretch\">\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: format(new Date(), 'yyyy-MM-dd'),\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 FormErrors,\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 const errorsToString = (errors: FormErrors, prefix: string = ''): string => {\n if (Object.keys(errors).length === 0) {\n return '';\n }\n\n return Object.entries(errors)\n .map(([key, value]) => {\n if (value === undefined || value === null) {\n return '';\n }\n\n if (typeof value === 'string') {\n return formatMessage(\n { id: value, defaultMessage: value },\n { field: prefix ? `${prefix}.${key}` : key }\n );\n }\n\n if (\n typeof value === 'object' &&\n value !== null &&\n 'id' in value &&\n 'defaultMessage' in value\n ) {\n return formatMessage(\n // @ts-expect-error – TODO: default message will be a string\n { id: `${value.id}.withField`, defaultMessage: value.defaultMessage },\n { field: prefix ? `${prefix}.${key}` : key }\n );\n }\n\n return errorsToString(value as FormErrors, key);\n })\n .join(' ');\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 = errorsToString(errors);\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 <SimpleMenuButton\n label={<More />}\n variant=\"tertiary\"\n endIcon={null}\n paddingLeft=\"7px\"\n paddingRight=\"7px\"\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={4}\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 </SimpleMenuButton>\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\nconst SimpleMenuButton = styled(SimpleMenu)`\n & > span {\n display: flex;\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","format","useNotification","useNavigate","useAPIErrorHandler","useQueryParams","useGetReleasesQuery","useGetReleaseSettingsQuery","useCreateReleaseMutation","useLicenseLimits","useTracking","useRBAC","PERMISSIONS","response","isFetchError","Main","Layouts","Plus","Tabs","Divider","Pagination","MenuItem","Pencil","Trash","unstable_useDocument","errors","CrossCircle","Tooltip","CheckCircle","ArrowsCounterClockwise","useParams","useGetReleaseQuery","usePublishReleaseMutation","totalEntries","releaseApi","Navigate","getTimezoneOffset","BackButton","More","SimpleMenu","useStrapiApp","useGetReleaseActionsQuery","useUpdateReleaseActionMutation","LinkButton","ReactRouterLink","SingleSelect","SingleSelectOption","Table","Tr","Td","ReleaseActionOptions","ReleaseActionMenu","useUpdateReleaseMutation","useDeleteReleaseMutation","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 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-CYsQToWs.mjs";
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-DK8PBO2g.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, SimpleMenu, Dialog, LinkButton, SingleSelect, SingleSelectOption, Tr, Td, Tooltip } from "@strapi/design-system";
@@ -637,19 +637,37 @@ const EntryValidationText = ({ action, schema, entry, status }) => {
637
637
  skip: true
638
638
  }
639
639
  );
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
+ };
640
664
  if (isLoading) {
641
665
  return null;
642
666
  }
643
667
  const errors = validate(entry) ?? {};
644
668
  if (action === "publish") {
645
669
  if (Object.keys(errors).length > 0) {
646
- const validationErrorsMessages = Object.entries(errors).map(
647
- ([key, value]) => formatMessage(
648
- // @ts-expect-error – TODO: fix this will better checks
649
- { id: `${value.id}.withField`, defaultMessage: value.defaultMessage },
650
- { field: key }
651
- )
652
- ).join(" ");
670
+ const validationErrorsMessages = errorsToString(errors);
653
671
  return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
654
672
  /* @__PURE__ */ jsx(CrossCircle, { fill: "danger600" }),
655
673
  /* @__PURE__ */ jsx(Tooltip, { description: validationErrorsMessages, children: /* @__PURE__ */ jsx(
@@ -879,7 +897,7 @@ const ReleaseDetailsLayout = ({
879
897
  justifyContent: "center",
880
898
  alignItems: "flex-start",
881
899
  gap: 1,
882
- padding: 5,
900
+ padding: 4,
883
901
  children: [
884
902
  /* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", children: formatMessage({
885
903
  id: "content-releases.header.actions.created",
@@ -1353,4 +1371,4 @@ const App = () => {
1353
1371
  export {
1354
1372
  App
1355
1373
  };
1356
- //# sourceMappingURL=App-DMILern_.mjs.map
1374
+ //# sourceMappingURL=App-CxzD6PdQ.mjs.map