@strapi/content-releases 5.0.0-beta.4 → 5.0.0-beta.5

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.
Files changed (40) hide show
  1. package/dist/_chunks/{App-BIYLcg31.mjs → App-Cmn2Mkn7.mjs} +22 -12
  2. package/dist/_chunks/App-Cmn2Mkn7.mjs.map +1 -0
  3. package/dist/_chunks/{App-BEGE2QNe.js → App-FVorrIzF.js} +21 -11
  4. package/dist/_chunks/App-FVorrIzF.js.map +1 -0
  5. package/dist/_chunks/{en-C4IblV7-.mjs → en-B9Ur3VsE.mjs} +2 -1
  6. package/dist/_chunks/en-B9Ur3VsE.mjs.map +1 -0
  7. package/dist/_chunks/{en-B07S6EN4.js → en-DtFJ5ViE.js} +2 -1
  8. package/dist/_chunks/en-DtFJ5ViE.js.map +1 -0
  9. package/dist/_chunks/{index-CNPFfE_a.js → index-BfJLth9Z.js} +32 -13
  10. package/dist/_chunks/index-BfJLth9Z.js.map +1 -0
  11. package/dist/_chunks/{index-BoeHjl4L.mjs → index-DDohgTaQ.mjs} +32 -13
  12. package/dist/_chunks/index-DDohgTaQ.mjs.map +1 -0
  13. package/dist/admin/index.js +1 -1
  14. package/dist/admin/index.mjs +1 -1
  15. package/dist/admin/src/components/ReleaseListCell.d.ts +0 -0
  16. package/dist/admin/src/services/release.d.ts +61 -26
  17. package/dist/server/index.js +72 -10
  18. package/dist/server/index.js.map +1 -1
  19. package/dist/server/index.mjs +72 -10
  20. package/dist/server/index.mjs.map +1 -1
  21. package/dist/server/src/controllers/index.d.ts +1 -0
  22. package/dist/server/src/controllers/index.d.ts.map +1 -1
  23. package/dist/server/src/controllers/release.d.ts +1 -0
  24. package/dist/server/src/controllers/release.d.ts.map +1 -1
  25. package/dist/server/src/index.d.ts +2 -1
  26. package/dist/server/src/index.d.ts.map +1 -1
  27. package/dist/server/src/migrations/index.d.ts.map +1 -1
  28. package/dist/server/src/routes/release.d.ts.map +1 -1
  29. package/dist/server/src/services/index.d.ts +1 -1
  30. package/dist/server/src/services/release.d.ts +2 -2
  31. package/dist/server/src/services/release.d.ts.map +1 -1
  32. package/dist/shared/contracts/releases.d.ts +17 -1
  33. package/dist/shared/contracts/releases.d.ts.map +1 -1
  34. package/package.json +9 -9
  35. package/dist/_chunks/App-BEGE2QNe.js.map +0 -1
  36. package/dist/_chunks/App-BIYLcg31.mjs.map +0 -1
  37. package/dist/_chunks/en-B07S6EN4.js.map +0 -1
  38. package/dist/_chunks/en-C4IblV7-.mjs.map +0 -1
  39. package/dist/_chunks/index-BoeHjl4L.mjs.map +0 -1
  40. package/dist/_chunks/index-CNPFfE_a.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"App-FVorrIzF.js","sources":["../../admin/src/components/RelativeTime.tsx","../../shared/validation-schemas.ts","../../admin/src/components/ReleaseModal.tsx","../../admin/src/store/hooks.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 yup from 'yup';\n\nexport const RELEASE_SCHEMA = yup\n .object()\n .shape({\n name: yup.string().trim().required(),\n scheduledAt: yup.string().nullable(),\n isScheduled: yup.boolean().optional(),\n time: yup.string().when('isScheduled', {\n is: true,\n then: yup.string().trim().required(),\n otherwise: yup.string().nullable(),\n }),\n timezone: yup.string().when('isScheduled', {\n is: true,\n then: yup.string().required().nullable(),\n otherwise: yup.string().nullable(),\n }),\n date: yup.string().when('isScheduled', {\n is: true,\n then: yup.string().required().nullable(),\n otherwise: yup.string().nullable(),\n }),\n })\n .required()\n .noUnknown();\n","import * as React from 'react';\n\nimport {\n Button,\n ModalBody,\n ModalFooter,\n ModalLayout,\n ModalHeader,\n TextInput,\n Typography,\n Checkbox,\n Flex,\n Box,\n DatePicker,\n TimePicker,\n Combobox,\n ComboboxOption,\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 { RELEASE_SCHEMA } from '../../../shared/validation-schemas';\nimport { pluginId } from '../pluginId';\nimport { getTimezoneOffset } from '../utils/time';\n\nexport interface FormValues {\n name: string;\n date: string | null;\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}\n\nexport const ReleaseModal = ({\n handleClose,\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 <ModalLayout onClose={handleClose} labelledBy=\"title\">\n <ModalHeader>\n <Typography id=\"title\" fontWeight=\"bold\" textColor=\"neutral800\">\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 </Typography>\n </ModalHeader>\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 <Form>\n <ModalBody>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={6}>\n <TextInput\n label={formatMessage({\n id: 'content-releases.modal.form.input.label.release-name',\n defaultMessage: 'Name',\n })}\n name=\"name\"\n value={values.name}\n error={errors.name}\n onChange={handleChange}\n required\n />\n <Box width=\"max-content\">\n <Checkbox\n name=\"isScheduled\"\n value={values.isScheduled}\n onChange={(event) => {\n setFieldValue('isScheduled', event.target.checked);\n if (!event.target.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('timezone', initialValues.timezone ?? systemTimezone?.value);\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 <DatePicker\n label={formatMessage({\n id: 'content-releases.modal.form.input.label.date',\n defaultMessage: 'Date',\n })}\n name=\"date\"\n error={errors.date}\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 selectedDate={values.date || undefined}\n required\n minDate={utcToZonedTime(new Date(), values.timezone.split('&')[1])}\n />\n </Box>\n <Box width=\"100%\">\n <TimePicker\n label={formatMessage({\n id: 'content-releases.modal.form.input.label.time',\n defaultMessage: 'Time',\n })}\n name=\"time\"\n error={errors.time}\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 required\n />\n </Box>\n </Flex>\n <TimezoneComponent timezoneOptions={timezoneList} />\n </>\n )}\n </Flex>\n </ModalBody>\n <ModalFooter\n startActions={\n <Button onClick={handleClose} variant=\"tertiary\" name=\"cancel\">\n {formatMessage({ id: 'cancel', defaultMessage: 'Cancel' })}\n </Button>\n }\n endActions={\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 }\n />\n </Form>\n )}\n </Formik>\n </ModalLayout>\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 getTimezones = (selectedDate: Date) => {\n const timezoneList: ITimezoneOption[] = Intl.supportedValuesOf('timeZone').map((timezone) => {\n // Timezone will be in the format GMT${OFFSET} where offset could be nothing,\n // a four digit string e.g. +05:00 or -08:00\n const utcOffset = getTimezoneOffset(timezone, selectedDate);\n\n // Offset and timezone are concatenated with '&', so to split and save the required timezone in DB\n return { offset: utcOffset, value: `${utcOffset}&${timezone}` } satisfies ITimezoneOption;\n });\n\n const systemTimezone = timezoneList.find(\n (timezone) => timezone.value.split('&')[1] === Intl.DateTimeFormat().resolvedOptions().timeZone\n );\n\n return { timezoneList, systemTimezone };\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 <Combobox\n label={formatMessage({\n id: 'content-releases.modal.form.input.label.timezone',\n defaultMessage: 'Timezone',\n })}\n autocomplete={{ type: 'list', filter: 'contains' }}\n name=\"timezone\"\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 error={errors.timezone}\n required\n >\n {timezoneList.map((timezone) => (\n <ComboboxOption key={timezone.value} value={timezone.value}>\n {timezone.value.replace(/&/, ' ')}\n </ComboboxOption>\n ))}\n </Combobox>\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 * as React from 'react';\n\nimport {\n Page,\n Pagination,\n useTracking,\n useAPIErrorHandler,\n useNotification,\n useQueryParams,\n useRBAC,\n} from '@strapi/admin/strapi-admin';\nimport { useLicenseLimits } from '@strapi/admin/strapi-admin/ee';\nimport {\n Alert,\n Badge,\n Box,\n Button,\n ContentLayout,\n Divider,\n EmptyStateLayout,\n Flex,\n Grid,\n GridItem,\n HeaderLayout,\n Main,\n Tab,\n TabGroup,\n TabPanel,\n TabPanels,\n Tabs,\n Typography,\n} from '@strapi/design-system';\nimport { Link } from '@strapi/design-system/v2';\nimport { EmptyDocuments, Plus } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { useNavigate, useLocation } 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 { isAxiosError } from '../services/axios';\nimport {\n useGetReleasesQuery,\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=\"10rem\" />}\n />\n );\n }\n\n return (\n <Grid gap={4}>\n {releases.map(({ id, name, scheduledAt, status }) => (\n <GridItem col={3} s={6} xs={12} key={id}>\n <LinkCard href={`content-releases/${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 as=\"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 </GridItem>\n ))}\n </Grid>\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: null,\n time: '',\n isScheduled: true,\n scheduledAt: null,\n timezone: null,\n} satisfies FormValues;\n\nconst ReleasesPage = () => {\n const tabRef = React.useRef<any>(null);\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 [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, isSuccess, isError } = response;\n const activeTab = response?.currentData?.meta?.activeTab || 'pending';\n const activeTabIndex = ['pending', 'done'].indexOf(activeTab);\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 // TODO: Replace this solution with v2 of the Design System\n // Check if the active tab index changes and call the handler of the ref to update the tab group component\n React.useEffect(() => {\n if (tabRef.current) {\n tabRef.current._handlers.setSelectedTabIndex(activeTabIndex);\n }\n }, [activeTabIndex]);\n\n const toggleAddReleaseModal = () => {\n setReleaseModalShown((prev) => !prev);\n };\n\n if (isLoading) {\n return <Page.Loading />;\n }\n\n const totalPendingReleases = (isSuccess && response.currentData?.meta?.pendingReleasesCount) || 0;\n const hasReachedMaximumPendingReleases = totalPendingReleases >= maximumReleases;\n\n const handleTabChange = (index: number) => {\n setQuery({\n ...query,\n page: 1,\n pageSize: response?.currentData?.meta?.pagination?.pageSize || 16,\n filters: {\n releasedAt: {\n $notNull: index === 0 ? false : true,\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 (isAxiosError(response.error)) {\n // When the response returns an object with 'error', handle axios 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={isLoading}>\n <HeaderLayout\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 <ContentLayout>\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 <TabGroup\n label={formatMessage({\n id: 'content-releases.pages.Releases.tab-group.label',\n defaultMessage: 'Releases list',\n })}\n variant=\"simple\"\n initialSelectedTabIndex={activeTabIndex}\n onTabChange={handleTabChange}\n ref={tabRef}\n >\n <Box paddingBottom={8}>\n <Tabs>\n <Tab>\n {formatMessage(\n {\n id: 'content-releases.pages.Releases.tab.pending',\n defaultMessage: 'Pending ({count})',\n },\n {\n count: totalPendingReleases,\n }\n )}\n </Tab>\n <Tab>\n {formatMessage({\n id: 'content-releases.pages.Releases.tab.done',\n defaultMessage: 'Done',\n })}\n </Tab>\n </Tabs>\n <Divider />\n </Box>\n <TabPanels>\n {/* Pending releases */}\n <TabPanel>\n <ReleasesGrid\n sectionTitle=\"pending\"\n releases={response?.currentData?.data}\n isError={isError}\n />\n </TabPanel>\n {/* Done releases */}\n <TabPanel>\n <ReleasesGrid\n sectionTitle=\"done\"\n releases={response?.currentData?.data}\n isError={isError}\n />\n </TabPanel>\n </TabPanels>\n </TabGroup>\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 </ContentLayout>\n {releaseModalShown && (\n <ReleaseModal\n handleClose={toggleAddReleaseModal}\n handleSubmit={handleAddRelease}\n isLoading={isSubmittingForm}\n initialValues={INITIAL_FORM_VALUES}\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 useStrapiApp,\n} from '@strapi/admin/strapi-admin';\nimport {\n Button,\n ContentLayout,\n Flex,\n HeaderLayout,\n IconButton,\n Main,\n Tr,\n Td,\n Typography,\n Badge,\n SingleSelect,\n SingleSelectOption,\n Icon,\n Tooltip,\n EmptyStateLayout,\n} from '@strapi/design-system';\nimport { LinkButton, Menu } from '@strapi/design-system/v2';\nimport { CheckCircle, More, Pencil, Trash, CrossCircle, EmptyDocuments } from '@strapi/icons';\nimport { unstable_useDocument } from '@strapi/plugin-content-manager/strapi-admin';\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 { isAxiosError } from '../services/axios';\nimport {\n GetReleaseActionsQueryParams,\n useGetReleaseActionsQuery,\n useGetReleaseQuery,\n useUpdateReleaseMutation,\n useUpdateReleaseActionMutation,\n usePublishReleaseMutation,\n useDeleteReleaseMutation,\n releaseApi,\n} from '../services/release';\nimport { useTypedDispatch } from '../store/hooks';\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 { Schema } 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(Menu.Item)<{\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?: Schema.ContentType;\n components: { [key: Schema.Component['uid']]: Schema.Component };\n entry: ReleaseActionEntry;\n}\n\nconst EntryValidationText = ({ action, schema, entry }: EntryValidationTextProps) => {\n const { formatMessage } = useIntl();\n const { validate } = unstable_useDocument(\n {\n collectionType: schema?.kind ?? '',\n model: schema?.uid ?? '',\n },\n {\n skip: !schema,\n }\n );\n\n const errors = validate(entry) ?? {};\n\n if (Object.keys(errors).length > 0) {\n const validationErrorsMessages = Object.entries(errors)\n .map(([key, value]) =>\n formatMessage(\n { id: `${value.id}.withField`, defaultMessage: value.defaultMessage },\n { field: key }\n )\n )\n .join(' ');\n\n return (\n <Flex gap={2}>\n <Icon color=\"danger600\" as={CrossCircle} />\n <Tooltip description={validationErrorsMessages}>\n <TypographyMaxWidth textColor=\"danger600\" variant=\"omega\" fontWeight=\"semiBold\" ellipsis>\n {validationErrorsMessages}\n </TypographyMaxWidth>\n </Tooltip>\n </Flex>\n );\n }\n\n if (action == 'publish') {\n return (\n <Flex gap={2}>\n <Icon color=\"success600\" as={CheckCircle} />\n {entry.publishedAt ? (\n <Typography textColor=\"success600\" fontWeight=\"bold\">\n {formatMessage({\n id: 'content-releases.pages.ReleaseDetails.entry-validation.already-published',\n defaultMessage: 'Already published',\n })}\n </Typography>\n ) : (\n <Typography>\n {formatMessage({\n id: 'content-releases.pages.ReleaseDetails.entry-validation.ready-to-publish',\n defaultMessage: 'Ready to publish',\n })}\n </Typography>\n )}\n </Flex>\n );\n }\n\n return (\n <Flex gap={2}>\n <Icon color=\"success600\" as={CheckCircle} />\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 isError,\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 (isAxiosError(response.error)) {\n // When the response returns an object with 'error', handle axios 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 (isError || !release) {\n return (\n <Navigate\n to=\"..\"\n state={{\n errors: [\n {\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 <HeaderLayout\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 <Menu.Root>\n {/*\n TODO Fix in the DS\n - as={IconButton} has TS error: Property 'icon' does not exist on type 'IntrinsicAttributes & TriggerProps & RefAttributes<HTMLButtonElement>'\n - The Icon doesn't actually show unless you hack it with some padding...and it's still a little strange\n */}\n <Menu.Trigger\n as={IconButton}\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 // @ts-expect-error See above\n icon={<More />}\n variant=\"tertiary\"\n />\n {/*\n TODO: Using Menu instead of SimpleMenu mainly because there is no positioning provided from the DS,\n Refactor this once fixed in the DS\n */}\n <Menu.Content top={1} popoverPlacement=\"bottom-end\">\n <Flex\n alignItems=\"center\"\n justifyContent=\"center\"\n direction=\"column\"\n padding={1}\n width=\"100%\"\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 </Flex>\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 </Menu.Content>\n </Menu.Root>\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 isError: isReleaseError,\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 { hasI18nEnabled }: { displayedHeaders: any; hasI18nEnabled: boolean } = runHookWaterfall(\n 'ContentReleases/pages/ReleaseDetails/add-locale-in-releases',\n {\n displayedHeaders: {\n label: formatMessage({\n id: 'content-releases.page.ReleaseDetails.table.header.label.locale',\n defaultMessage: 'locale',\n }),\n name: 'locale',\n },\n hasI18nEnabled: false,\n }\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 (isAxiosError(response.error)) {\n // When the response returns an object with 'error', handle axios 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 (isReleaseError || !release) {\n const errorsArray = [];\n if (releaseError) {\n errorsArray.push({\n code: releaseError.code,\n });\n }\n if (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 <ContentLayout>\n <EmptyStateLayout\n action={\n <LinkButton\n as={ReactRouterLink}\n // @ts-expect-error - types are not inferred correctly through the as prop.\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=\"10rem\" />}\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 </ContentLayout>\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: formatMessage({\n id: 'content-releases.page.ReleaseDetails.table.header.label.name',\n defaultMessage: 'name',\n }),\n name: 'name',\n },\n {\n label: formatMessage({\n id: 'content-releases.page.ReleaseDetails.table.header.label.content-type',\n defaultMessage: 'content-type',\n }),\n name: 'content-type',\n },\n {\n label: formatMessage({\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: formatMessage({\n id: 'content-releases.page.ReleaseDetails.table.header.label.status',\n defaultMessage: 'status',\n }),\n name: 'status',\n },\n ]\n : []),\n ];\n const options = hasI18nEnabled ? GROUP_BY_OPTIONS : GROUP_BY_OPTIONS_NO_LOCALE;\n\n return (\n <ContentLayout>\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((header) => (\n <Table.HeaderCell key={header.name} {...header} />\n ))}\n </Table.Head>\n <Table.Loading />\n <Table.Body>\n {releaseActions[key].map(\n ({ id, contentType, locale, type, entry }, 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 />\n </Td>\n <Td>\n <Flex justifyContent=\"flex-end\">\n <ReleaseActionMenu.Root>\n <ReleaseActionMenu.ReleaseActionEntryLinkItem\n contentTypeUid={contentType.uid}\n entryId={entry.id}\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 </ContentLayout>\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 [updateRelease, { isLoading: isSubmittingForm }] = useUpdateReleaseMutation();\n const [deleteRelease] = useDeleteReleaseMutation();\n\n const toggleEditReleaseModal = () => {\n setReleaseModalShown((prev) => !prev);\n };\n\n const toggleWarningSubmit = () => setWarningSubmit((prevState) => !prevState);\n\n if (isLoadingDetails) {\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 = releaseData?.timezone ?? null;\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') : null;\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 (isAxiosError(response.error)) {\n // When the response returns an object with 'error', handle axios 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 (isAxiosError(response.error)) {\n // When the response returns an object with 'error', handle axios 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 {releaseModalShown && (\n <ReleaseModal\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 )}\n <ConfirmDialog\n isOpen={showWarningSubmit}\n onClose={toggleWarningSubmit}\n onConfirm={handleDeleteRelease}\n >\n {formatMessage({\n id: 'content-releases.dialog.confirmation-message',\n defaultMessage: 'Are you sure you want to delete this release?',\n })}\n </ConfirmDialog>\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","yup","useLocation","pluginId","zonedTimeToUtc","jsxs","ModalLayout","ModalHeader","Typography","Formik","Form","ModalBody","Flex","TextInput","Box","Checkbox","Fragment","DatePicker","formatISO","utcToZonedTime","TimePicker","ModalFooter","Button","getTimezoneOffset","useFormikContext","timezoneList","Combobox","ComboboxOption","useDispatch","styled","Link","BaseRelativeTime","Page","EmptyStateLayout","EmptyDocuments","Grid","GridItem","Badge","Alert","useNotification","useNavigate","useAPIErrorHandler","useQueryParams","useGetReleasesQuery","useCreateReleaseMutation","useLicenseLimits","useTracking","useRBAC","PERMISSIONS","index","response","isAxiosError","Main","HeaderLayout","Plus","ContentLayout","TabGroup","Tabs","Tab","Divider","TabPanels","TabPanel","Pagination","Menu","Pencil","Trash","unstable_useDocument","Icon","CrossCircle","Tooltip","CheckCircle","useParams","useGetReleaseQuery","usePublishReleaseMutation","totalEntries","releaseApi","Navigate","BackButton","IconButton","More","useStrapiApp","useGetReleaseActionsQuery","useUpdateReleaseActionMutation","LinkButton","ReactRouterLink","SingleSelect","SingleSelectOption","Table","Tr","Td","ReleaseActionOptions","ReleaseActionMenu","useUpdateReleaseMutation","useDeleteReleaseMutation","format","ConfirmDialog","Routes","Route"],"mappings":"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"}
@@ -24,6 +24,7 @@ const en = {
24
24
  "content-manager-list-view.add-to-release.notification.success.title": "Successfully added to release.",
25
25
  "content-manager-list-view.add-to-release.notification.success.message": "{entriesAlreadyInRelease} out of {totalEntries} entries were already in the release.",
26
26
  "content-manager.notification.entry-error": "Failed to get entry data",
27
+ "content-manager.list-view.releases-number": "{number} {number, plural, one {release} other {releases}}",
27
28
  "plugin.name": "Releases",
28
29
  "pages.Releases.title": "Releases",
29
30
  "pages.Releases.header-subtitle": "Create and manage content updates",
@@ -82,4 +83,4 @@ const en = {
82
83
  export {
83
84
  en as default
84
85
  };
85
- //# sourceMappingURL=en-C4IblV7-.mjs.map
86
+ //# sourceMappingURL=en-B9Ur3VsE.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"en-B9Ur3VsE.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -26,6 +26,7 @@ const en = {
26
26
  "content-manager-list-view.add-to-release.notification.success.title": "Successfully added to release.",
27
27
  "content-manager-list-view.add-to-release.notification.success.message": "{entriesAlreadyInRelease} out of {totalEntries} entries were already in the release.",
28
28
  "content-manager.notification.entry-error": "Failed to get entry data",
29
+ "content-manager.list-view.releases-number": "{number} {number, plural, one {release} other {releases}}",
29
30
  "plugin.name": "Releases",
30
31
  "pages.Releases.title": "Releases",
31
32
  "pages.Releases.header-subtitle": "Create and manage content updates",
@@ -82,4 +83,4 @@ const en = {
82
83
  "pages.ReleaseDetails.header-subtitle.scheduled": "Scheduled for {date} at {time} ({offset})"
83
84
  };
84
85
  exports.default = en;
85
- //# sourceMappingURL=en-B07S6EN4.js.map
86
+ //# sourceMappingURL=en-DtFJ5ViE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"en-DtFJ5ViE.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -159,7 +159,7 @@ const isAxiosError = (err) => {
159
159
  const releaseApi = react.createApi({
160
160
  reducerPath: pluginId,
161
161
  baseQuery: axiosBaseQuery,
162
- tagTypes: ["Release", "ReleaseAction"],
162
+ tagTypes: ["Release", "ReleaseAction", "EntriesInRelease"],
163
163
  endpoints: (build) => {
164
164
  return {
165
165
  getReleasesForEntry: build.query({
@@ -284,7 +284,8 @@ const releaseApi = react.createApi({
284
284
  },
285
285
  invalidatesTags: [
286
286
  { type: "Release", id: "LIST" },
287
- { type: "ReleaseAction", id: "LIST" }
287
+ { type: "ReleaseAction", id: "LIST" },
288
+ { type: "EntriesInRelease" }
288
289
  ]
289
290
  }),
290
291
  updateReleaseAction: build.mutation({
@@ -327,7 +328,8 @@ const releaseApi = react.createApi({
327
328
  invalidatesTags: (result, error, arg) => [
328
329
  { type: "Release", id: "LIST" },
329
330
  { type: "Release", id: arg.params.releaseId },
330
- { type: "ReleaseAction", id: "LIST" }
331
+ { type: "ReleaseAction", id: "LIST" },
332
+ { type: "EntriesInRelease" }
331
333
  ]
332
334
  }),
333
335
  publishRelease: build.mutation({
@@ -346,7 +348,22 @@ const releaseApi = react.createApi({
346
348
  method: "DELETE"
347
349
  };
348
350
  },
349
- invalidatesTags: () => [{ type: "Release", id: "LIST" }]
351
+ invalidatesTags: () => [{ type: "Release", id: "LIST" }, { type: "EntriesInRelease" }]
352
+ }),
353
+ getMappedEntriesInReleases: build.query({
354
+ query(params) {
355
+ return {
356
+ url: "/content-releases/mapEntriesToReleases",
357
+ method: "GET",
358
+ config: {
359
+ params
360
+ }
361
+ };
362
+ },
363
+ transformResponse(response) {
364
+ return response.data;
365
+ },
366
+ providesTags: [{ type: "EntriesInRelease" }]
350
367
  })
351
368
  };
352
369
  }
@@ -363,7 +380,8 @@ const {
363
380
  useUpdateReleaseActionMutation,
364
381
  usePublishReleaseMutation,
365
382
  useDeleteReleaseActionMutation,
366
- useDeleteReleaseMutation
383
+ useDeleteReleaseMutation,
384
+ useGetMappedEntriesInReleasesQuery
367
385
  } = releaseApi;
368
386
  const getTimezoneOffset = (timezone, date) => {
369
387
  try {
@@ -884,7 +902,7 @@ const CMReleasesContainer = () => {
884
902
  alignItems: "start",
885
903
  borderWidth: "1px",
886
904
  borderStyle: "solid",
887
- borderColor: getReleaseColorVariant(release.action.type, "200"),
905
+ borderColor: getReleaseColorVariant(release.actions[0].type, "200"),
888
906
  overflow: "hidden",
889
907
  hasRadius: true,
890
908
  children: [
@@ -895,20 +913,20 @@ const CMReleasesContainer = () => {
895
913
  paddingBottom: 3,
896
914
  paddingLeft: 4,
897
915
  paddingRight: 4,
898
- background: getReleaseColorVariant(release.action.type, "100"),
916
+ background: getReleaseColorVariant(release.actions[0].type, "100"),
899
917
  width: "100%",
900
918
  children: /* @__PURE__ */ jsxRuntime.jsx(
901
919
  designSystem.Typography,
902
920
  {
903
921
  fontSize: 1,
904
922
  variant: "pi",
905
- textColor: getReleaseColorVariant(release.action.type, "600"),
923
+ textColor: getReleaseColorVariant(release.actions[0].type, "600"),
906
924
  children: formatMessage(
907
925
  {
908
926
  id: "content-releases.content-manager-edit-view.list-releases.title",
909
927
  defaultMessage: "{isPublish, select, true {Will be published in} other {Will be unpublished in}}"
910
928
  },
911
- { isPublish: release.action.type === "publish" }
929
+ { isPublish: release.actions[0].type === "publish" }
912
930
  )
913
931
  }
914
932
  )
@@ -944,7 +962,7 @@ const CMReleasesContainer = () => {
944
962
  ReleaseActionMenu.DeleteReleaseActionItem,
945
963
  {
946
964
  releaseId: release.id,
947
- actionId: release.action.id
965
+ actionId: release.actions[0].id
948
966
  }
949
967
  )
950
968
  ] }) : null
@@ -1168,6 +1186,7 @@ const prefixPluginTranslations = (trad, pluginId2) => {
1168
1186
  const admin = {
1169
1187
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1170
1188
  register(app) {
1189
+ app.createHook("ContentReleases/pages/ReleaseDetails/add-locale-in-releases");
1171
1190
  if (window.strapi.features.isEnabled("cms-content-releases")) {
1172
1191
  app.addMenuLink({
1173
1192
  to: `plugins/${pluginId}`,
@@ -1176,7 +1195,7 @@ const admin = {
1176
1195
  id: `${pluginId}.plugin.name`,
1177
1196
  defaultMessage: "Releases"
1178
1197
  },
1179
- Component: () => Promise.resolve().then(() => require("./App-BEGE2QNe.js")).then((mod) => ({ default: mod.App })),
1198
+ Component: () => Promise.resolve().then(() => require("./App-FVorrIzF.js")).then((mod) => ({ default: mod.App })),
1180
1199
  permissions: PERMISSIONS.main
1181
1200
  });
1182
1201
  app.addMiddlewares([() => releaseApi.middleware]);
@@ -1212,7 +1231,7 @@ const admin = {
1212
1231
  async registerTrads({ locales }) {
1213
1232
  const importedTrads = await Promise.all(
1214
1233
  locales.map((locale) => {
1215
- return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => Promise.resolve().then(() => require("./en-B07S6EN4.js")) }), `./translations/${locale}.json`).then(({ default: data }) => {
1234
+ return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => Promise.resolve().then(() => require("./en-DtFJ5ViE.js")) }), `./translations/${locale}.json`).then(({ default: data }) => {
1216
1235
  return {
1217
1236
  data: prefixPluginTranslations(data, "content-releases"),
1218
1237
  locale
@@ -1244,4 +1263,4 @@ exports.useGetReleasesQuery = useGetReleasesQuery;
1244
1263
  exports.usePublishReleaseMutation = usePublishReleaseMutation;
1245
1264
  exports.useUpdateReleaseActionMutation = useUpdateReleaseActionMutation;
1246
1265
  exports.useUpdateReleaseMutation = useUpdateReleaseMutation;
1247
- //# sourceMappingURL=index-CNPFfE_a.js.map
1266
+ //# sourceMappingURL=index-BfJLth9Z.js.map