@strapi/content-releases 0.0.0-experimental.f7b9b47085e387e97f990d8695971b51d7f7149a → 0.0.0-experimental.fb8e9fec2e10d6b55e3aee59c4eb76bb7a11432a

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-KJa1Rb5F.js","sources":["../../admin/src/constants.ts","../../admin/src/pluginId.ts","../../admin/src/services/axios.ts","../../admin/src/services/release.ts","../../admin/src/store/hooks.ts","../../admin/src/components/ReleaseActionMenu.tsx","../../admin/src/components/ReleaseActionOptions.tsx","../../admin/src/components/CMReleasesContainer.tsx","../../admin/src/index.ts"],"sourcesContent":["import { Permission as StrapiPermission } from '@strapi/helper-plugin';\n\nexport const PERMISSIONS = {\n main: [\n {\n action: 'plugin::content-releases.read',\n subject: null,\n id: '',\n actionParameters: {},\n properties: {},\n conditions: [],\n },\n ],\n create: [\n {\n action: 'plugin::content-releases.create',\n subject: null,\n id: '',\n actionParameters: {},\n properties: {},\n conditions: [],\n },\n ],\n update: [\n {\n action: 'plugin::content-releases.update',\n subject: null,\n id: '',\n actionParameters: {},\n properties: {},\n conditions: [],\n },\n ],\n delete: [\n {\n action: 'plugin::content-releases.delete',\n subject: null,\n id: '',\n actionParameters: {},\n properties: {},\n conditions: [],\n },\n ],\n createAction: [\n {\n action: 'plugin::content-releases.create-action',\n subject: null,\n id: '',\n actionParameters: {},\n properties: {},\n conditions: [],\n },\n ],\n deleteAction: [\n {\n action: 'plugin::content-releases.delete-action',\n subject: null,\n id: '',\n actionParameters: {},\n properties: {},\n conditions: [],\n },\n ],\n publish: [\n {\n action: 'plugin::content-releases.publish',\n subject: null,\n id: '',\n actionParameters: {},\n properties: {},\n conditions: [],\n },\n ],\n} satisfies Record<string, StrapiPermission[]>;\n","export const pluginId = 'content-releases';\n","import { getFetchClient } from '@strapi/helper-plugin';\n\nimport type { AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios';\n\n/* -------------------------------------------------------------------------------------------------\n * Axios data\n * -----------------------------------------------------------------------------------------------*/\nexport interface QueryArguments<TSend> {\n url: string;\n method: 'PUT' | 'GET' | 'POST' | 'DELETE';\n data?: TSend;\n config?: AxiosRequestConfig<TSend>;\n}\n\nconst axiosBaseQuery = async <TData = any, TSend = any>({\n url,\n method,\n data,\n config,\n}: QueryArguments<TSend>) => {\n try {\n const { get, post, del, put } = getFetchClient();\n\n if (method === 'POST') {\n const result = await post<TData, AxiosResponse<TData>, TSend>(url, data, config);\n return { data: result.data };\n }\n\n if (method === 'DELETE') {\n const result = await del<TData, AxiosResponse<TData>, TSend>(url, config);\n return { data: result.data };\n }\n\n if (method === 'PUT') {\n const result = await put<TData, AxiosResponse<TData>, TSend>(url, data, config);\n return { data: result.data };\n }\n\n /**\n * Default is GET.\n */\n const result = await get<TData, AxiosResponse<TData>, TSend>(url, config);\n return { data: result.data };\n } catch (error) {\n const err = error as AxiosError;\n /**\n * Handle error of type AxiosError\n *\n * This format mimics what we want from an AxiosError which is what the\n * rest of the app works with, except this format is \"serializable\" since\n * it goes into the redux store.\n *\n * NOTE – passing the whole response will highlight this \"serializability\" issue.\n */\n return {\n error: {\n status: err.response?.status,\n code: err.code,\n response: {\n data: err.response?.data,\n },\n },\n };\n }\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Axios error\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * This asserts the errors from redux-toolkit-query are\n * axios errors so we can pass them to our utility functions\n * to correctly render error messages.\n */\nconst isAxiosError = (err: unknown): err is AxiosError<{ error: any }> => {\n return (\n typeof err === 'object' &&\n err !== null &&\n 'response' in err &&\n typeof err.response === 'object' &&\n err.response !== null &&\n 'data' in err.response\n );\n};\n\nexport { isAxiosError, axiosBaseQuery };\n","import { createApi } from '@reduxjs/toolkit/query/react';\n\nimport {\n CreateReleaseAction,\n DeleteReleaseAction,\n} from '../../../shared/contracts/release-actions';\nimport { pluginId } from '../pluginId';\n\nimport { axiosBaseQuery } from './axios';\n\nimport type {\n GetReleaseActions,\n UpdateReleaseAction,\n ReleaseActionGroupBy,\n} from '../../../shared/contracts/release-actions';\nimport type {\n CreateRelease,\n DeleteRelease,\n GetContentTypeEntryReleases,\n GetReleases,\n UpdateRelease,\n GetRelease,\n PublishRelease,\n} from '../../../shared/contracts/releases';\n\nexport interface GetReleasesQueryParams {\n page?: number;\n pageSize?: number;\n filters?: {\n releasedAt?: {\n // TODO: this should be a boolean, find a way to avoid strings\n $notNull?: boolean | 'true' | 'false';\n };\n };\n}\n\nexport interface GetReleaseActionsQueryParams {\n page?: number;\n pageSize?: number;\n groupBy?: ReleaseActionGroupBy;\n}\n\ntype GetReleasesTabResponse = GetReleases.Response & {\n meta: {\n activeTab: 'pending' | 'done';\n };\n};\n\nconst releaseApi = createApi({\n reducerPath: pluginId,\n baseQuery: axiosBaseQuery,\n tagTypes: ['Release', 'ReleaseAction'],\n endpoints: (build) => {\n return {\n getReleasesForEntry: build.query<\n GetContentTypeEntryReleases.Response,\n Partial<GetContentTypeEntryReleases.Request['query']>\n >({\n query(params) {\n return {\n url: '/content-releases',\n method: 'GET',\n config: {\n params,\n },\n };\n },\n providesTags: (result) =>\n result\n ? [\n ...result.data.map(({ id }) => ({ type: 'Release' as const, id })),\n { type: 'Release', id: 'LIST' },\n ]\n : [],\n }),\n getReleases: build.query<GetReleasesTabResponse, GetReleasesQueryParams | void>({\n query(\n { page, pageSize, filters } = {\n page: 1,\n pageSize: 16,\n filters: {\n releasedAt: {\n $notNull: false,\n },\n },\n }\n ) {\n return {\n url: '/content-releases',\n method: 'GET',\n config: {\n params: {\n page: page || 1,\n pageSize: pageSize || 16,\n filters: filters || {\n releasedAt: {\n $notNull: false,\n },\n },\n },\n },\n };\n },\n transformResponse(response: GetReleasesTabResponse, meta, arg) {\n const releasedAtValue = arg?.filters?.releasedAt?.$notNull;\n const isActiveDoneTab = releasedAtValue === 'true';\n const newResponse: GetReleasesTabResponse = {\n ...response,\n meta: {\n ...response.meta,\n activeTab: isActiveDoneTab ? 'done' : 'pending',\n },\n };\n\n return newResponse;\n },\n providesTags: (result) =>\n result\n ? [\n ...result.data.map(({ id }) => ({ type: 'Release' as const, id })),\n { type: 'Release', id: 'LIST' },\n ]\n : [{ type: 'Release', id: 'LIST' }],\n }),\n getRelease: build.query<GetRelease.Response, GetRelease.Request['params']>({\n query({ id }) {\n return {\n url: `/content-releases/${id}`,\n method: 'GET',\n };\n },\n providesTags: (result, error, arg) => [{ type: 'Release' as const, id: arg.id }],\n }),\n getReleaseActions: build.query<\n GetReleaseActions.Response,\n GetReleaseActions.Request['params'] & GetReleaseActions.Request['query']\n >({\n query({ releaseId, ...params }) {\n return {\n url: `/content-releases/${releaseId}/actions`,\n method: 'GET',\n config: {\n params,\n },\n };\n },\n providesTags: [{ type: 'ReleaseAction', id: 'LIST' }],\n }),\n createRelease: build.mutation<CreateRelease.Response, CreateRelease.Request['body']>({\n query(data) {\n return {\n url: '/content-releases',\n method: 'POST',\n data,\n };\n },\n invalidatesTags: [{ type: 'Release', id: 'LIST' }],\n }),\n updateRelease: build.mutation<\n void,\n UpdateRelease.Request['params'] & UpdateRelease.Request['body']\n >({\n query({ id, ...data }) {\n return {\n url: `/content-releases/${id}`,\n method: 'PUT',\n data,\n };\n },\n invalidatesTags: (result, error, arg) => [{ type: 'Release', id: arg.id }],\n }),\n createReleaseAction: build.mutation<\n CreateReleaseAction.Response,\n CreateReleaseAction.Request\n >({\n query({ body, params }) {\n return {\n url: `/content-releases/${params.releaseId}/actions`,\n method: 'POST',\n data: body,\n };\n },\n invalidatesTags: [\n { type: 'Release', id: 'LIST' },\n { type: 'ReleaseAction', id: 'LIST' },\n ],\n }),\n updateReleaseAction: build.mutation<\n UpdateReleaseAction.Response,\n UpdateReleaseAction.Request\n >({\n query({ body, params }) {\n return {\n url: `/content-releases/${params.releaseId}/actions/${params.actionId}`,\n method: 'PUT',\n data: body,\n };\n },\n invalidatesTags: () => [{ type: 'ReleaseAction', id: 'LIST' }],\n }),\n deleteReleaseAction: build.mutation<\n DeleteReleaseAction.Response,\n DeleteReleaseAction.Request\n >({\n query({ params }) {\n return {\n url: `/content-releases/${params.releaseId}/actions/${params.actionId}`,\n method: 'DELETE',\n };\n },\n invalidatesTags: [\n { type: 'Release', id: 'LIST' },\n { type: 'ReleaseAction', id: 'LIST' },\n ],\n }),\n publishRelease: build.mutation<PublishRelease.Response, PublishRelease.Request['params']>({\n query({ id }) {\n return {\n url: `/content-releases/${id}/publish`,\n method: 'POST',\n };\n },\n invalidatesTags: (result, error, arg) => [{ type: 'Release', id: arg.id }],\n }),\n deleteRelease: build.mutation<DeleteRelease.Response, DeleteRelease.Request['params']>({\n query({ id }) {\n return {\n url: `/content-releases/${id}`,\n method: 'DELETE',\n };\n },\n invalidatesTags: (result, error, arg) => [{ type: 'Release', id: arg.id }],\n }),\n };\n },\n});\n\nconst {\n useGetReleasesQuery,\n useGetReleasesForEntryQuery,\n useGetReleaseQuery,\n useGetReleaseActionsQuery,\n useCreateReleaseMutation,\n useCreateReleaseActionMutation,\n useUpdateReleaseMutation,\n useUpdateReleaseActionMutation,\n usePublishReleaseMutation,\n useDeleteReleaseActionMutation,\n useDeleteReleaseMutation,\n} = releaseApi;\n\nexport {\n useGetReleasesQuery,\n useGetReleasesForEntryQuery,\n useGetReleaseQuery,\n useGetReleaseActionsQuery,\n useCreateReleaseMutation,\n useCreateReleaseActionMutation,\n useUpdateReleaseMutation,\n useUpdateReleaseActionMutation,\n usePublishReleaseMutation,\n useDeleteReleaseActionMutation,\n useDeleteReleaseMutation,\n releaseApi,\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 { Flex, IconButton, Typography, Icon } from '@strapi/design-system';\nimport { Menu, Link } from '@strapi/design-system/v2';\nimport { CheckPermissions, useAPIErrorHandler, useNotification } from '@strapi/helper-plugin';\nimport { Cross, More, Pencil } from '@strapi/icons';\nimport { isAxiosError } from 'axios';\nimport { useIntl } from 'react-intl';\nimport { NavLink } from 'react-router-dom';\nimport styled from 'styled-components';\n\nimport { DeleteReleaseAction, ReleaseAction } from '../../../shared/contracts/release-actions';\nimport { PERMISSIONS } from '../constants';\nimport { useDeleteReleaseActionMutation } from '../services/release';\nimport { useTypedSelector } from '../store/hooks';\n\nimport type { Permission } from '@strapi/helper-plugin';\n\nconst StyledMenuItem = styled(Menu.Item)<{ variant?: 'neutral' | 'danger' }>`\n &:hover {\n background: ${({ theme, variant = 'neutral' }) => theme.colors[`${variant}100`]};\n\n svg {\n path {\n fill: ${({ theme, variant = 'neutral' }) => theme.colors[`${variant}600`]};\n }\n }\n\n a {\n color: ${({ theme }) => theme.colors.neutral800};\n }\n }\n\n svg {\n path {\n fill: ${({ theme, variant = 'neutral' }) => theme.colors[`${variant}600`]};\n }\n }\n\n a {\n color: ${({ theme }) => theme.colors.neutral800};\n }\n\n span,\n a {\n width: 100%;\n }\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * DeleteReleaseActionItemProps\n * -----------------------------------------------------------------------------------------------*/\nconst StyledIconButton = styled(IconButton)`\n /* Setting this style inline with borderColor will not apply the style */\n border: ${({ theme }) => `1px solid ${theme.colors.neutral200}`};\n`;\ninterface DeleteReleaseActionItemProps {\n releaseId: DeleteReleaseAction.Request['params']['releaseId'];\n actionId: DeleteReleaseAction.Request['params']['actionId'];\n}\n\nconst DeleteReleaseActionItem = ({ releaseId, actionId }: DeleteReleaseActionItemProps) => {\n const { formatMessage } = useIntl();\n const toggleNotification = useNotification();\n const { formatAPIError } = useAPIErrorHandler();\n const [deleteReleaseAction] = useDeleteReleaseActionMutation();\n\n const handleDeleteAction = async () => {\n const response = await deleteReleaseAction({\n params: { releaseId, actionId },\n });\n\n if ('data' in response) {\n // Handle success\n toggleNotification({\n type: 'success',\n message: formatMessage({\n id: 'content-releases.content-manager-edit-view.remove-from-release.notification.success',\n defaultMessage: 'Entry removed from release',\n }),\n });\n\n return;\n }\n\n if ('error' in response) {\n if (isAxiosError(response.error)) {\n // Handle axios error\n toggleNotification({\n type: 'warning',\n message: formatAPIError(response.error),\n });\n } else {\n // Handle generic error\n toggleNotification({\n type: 'warning',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error occurred' }),\n });\n }\n }\n };\n\n return (\n <CheckPermissions permissions={PERMISSIONS.deleteAction}>\n <StyledMenuItem variant=\"danger\" onSelect={handleDeleteAction}>\n <Flex gap={2}>\n <Icon as={Cross} padding={1} />\n <Typography textColor=\"danger600\" variant=\"omega\">\n {formatMessage({\n id: 'content-releases.content-manager-edit-view.remove-from-release',\n defaultMessage: 'Remove from release',\n })}\n </Typography>\n </Flex>\n </StyledMenuItem>\n </CheckPermissions>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ReleaseActionEntryLinkItem\n * -----------------------------------------------------------------------------------------------*/\ninterface ReleaseActionEntryLinkItemProps {\n contentTypeUid: ReleaseAction['contentType'];\n entryId: ReleaseAction['entry']['id'];\n locale: ReleaseAction['locale'];\n}\n\nconst ReleaseActionEntryLinkItem = ({\n contentTypeUid,\n entryId,\n locale,\n}: ReleaseActionEntryLinkItemProps) => {\n const { formatMessage } = useIntl();\n // Confirm user has permissions to access the entry for the given locale\n const collectionTypePermissions = useTypedSelector(\n (state) => state.rbacProvider.collectionTypesRelatedPermissions\n );\n const updatePermissions = contentTypeUid\n ? collectionTypePermissions[contentTypeUid]?.['plugin::content-manager.explorer.update']\n : [];\n const canUpdateEntryForLocale = Boolean(\n !locale ||\n updatePermissions?.find((permission: Permission) =>\n permission.properties?.locales?.includes(locale)\n )\n );\n\n return (\n <CheckPermissions\n permissions={[\n {\n action: 'plugin::content-manager.explorer.update',\n subject: contentTypeUid,\n },\n ]}\n >\n {canUpdateEntryForLocale && (\n <StyledMenuItem>\n <Link\n as={NavLink}\n // @ts-expect-error TODO: This component from DS is not using types from NavLink\n to={{\n pathname: `/content-manager/collection-types/${contentTypeUid}/${entryId}`,\n search: locale && `?plugins[i18n][locale]=${locale}`,\n }}\n startIcon={<Icon as={Pencil} padding={1} />}\n >\n <Typography variant=\"omega\">\n {formatMessage({\n id: 'content-releases.content-manager-edit-view.edit-entry',\n defaultMessage: 'Edit entry',\n })}\n </Typography>\n </Link>\n </StyledMenuItem>\n )}\n </CheckPermissions>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Root\n * -----------------------------------------------------------------------------------------------*/\n\ninterface RootProps {\n children: React.ReactNode;\n hasTriggerBorder?: boolean;\n}\n\nconst Root = ({ children, hasTriggerBorder = false }: RootProps) => {\n const { formatMessage } = useIntl();\n\n return (\n // A user can access the dropdown if they have permissions to delete a release-action OR update a release\n <CheckPermissions permissions={[...PERMISSIONS.deleteAction, ...PERMISSIONS.update]}>\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={hasTriggerBorder ? StyledIconButton : IconButton}\n paddingLeft={2}\n paddingRight={2}\n aria-label={formatMessage({\n id: 'content-releases.content-manager-edit-view.release-action-menu',\n defaultMessage: 'Release action options',\n })}\n // @ts-expect-error See above\n icon={<More />}\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 {children}\n </Menu.Content>\n </Menu.Root>\n </CheckPermissions>\n );\n};\n\nexport const ReleaseActionMenu = {\n Root,\n DeleteReleaseActionItem,\n ReleaseActionEntryLinkItem,\n};\n","import * as React from 'react';\n\nimport {\n FieldInput,\n FieldLabel,\n VisuallyHidden,\n Field,\n Flex,\n type FieldProps,\n} from '@strapi/design-system';\nimport styled from 'styled-components';\n\ninterface FieldWrapperProps extends FieldProps {\n actionType: 'publish' | 'unpublish';\n}\n\nconst getBorderLeftRadiusValue = (actionType: FieldWrapperProps['actionType']) => {\n return actionType === 'publish' ? 1 : 0;\n};\n\nconst getBorderRightRadiusValue = (actionType: FieldWrapperProps['actionType']) => {\n return actionType === 'publish' ? 0 : 1;\n};\n\nconst FieldWrapper = styled(Field)<FieldWrapperProps>`\n border-top-left-radius: ${({ actionType, theme }) =>\n theme.spaces[getBorderLeftRadiusValue(actionType)]};\n border-bottom-left-radius: ${({ actionType, theme }) =>\n theme.spaces[getBorderLeftRadiusValue(actionType)]};\n border-top-right-radius: ${({ actionType, theme }) =>\n theme.spaces[getBorderRightRadiusValue(actionType)]};\n border-bottom-right-radius: ${({ actionType, theme }) =>\n theme.spaces[getBorderRightRadiusValue(actionType)]};\n\n > label {\n color: inherit;\n padding: ${({ theme }) => `${theme.spaces[2]} ${theme.spaces[3]}`};\n text-align: center;\n vertical-align: middle;\n text-transform: capitalize;\n }\n\n &:active,\n &[data-checked='true'] {\n color: ${({ theme }) => theme.colors.primary700};\n background-color: ${({ theme }) => theme.colors.primary100};\n border-color: ${({ theme }) => theme.colors.primary700};\n }\n\n &[data-checked='false'] {\n border-left: ${({ actionType }) => actionType === 'unpublish' && 'none'};\n border-right: ${({ actionType }) => actionType === 'publish' && 'none'};\n }\n`;\n\ninterface ActionOptionProps {\n selected: 'publish' | 'unpublish';\n handleChange: (e: React.ChangeEvent<HTMLInputElement>) => void;\n name: string;\n}\n\ninterface OptionProps extends ActionOptionProps {\n actionType: 'publish' | 'unpublish';\n}\n\nconst ActionOption = ({ selected, actionType, handleChange, name }: OptionProps) => {\n return (\n <FieldWrapper\n actionType={actionType}\n background=\"primary0\"\n borderColor=\"neutral200\"\n color={selected === actionType ? 'primary600' : 'neutral600'}\n position=\"relative\"\n cursor=\"pointer\"\n data-checked={selected === actionType}\n >\n <FieldLabel htmlFor={`${name}-${actionType}`}>\n <VisuallyHidden>\n <FieldInput\n type=\"radio\"\n id={`${name}-${actionType}`}\n name={name}\n checked={selected === actionType}\n onChange={handleChange}\n value={actionType}\n />\n </VisuallyHidden>\n {actionType}\n </FieldLabel>\n </FieldWrapper>\n );\n};\n\nexport const ReleaseActionOptions = ({ selected, handleChange, name }: ActionOptionProps) => {\n return (\n <Flex>\n <ActionOption\n actionType=\"publish\"\n selected={selected}\n handleChange={handleChange}\n name={name}\n />\n <ActionOption\n actionType=\"unpublish\"\n selected={selected}\n handleChange={handleChange}\n name={name}\n />\n </Flex>\n );\n};\n","import * as React from 'react';\n\nimport { skipToken } from '@reduxjs/toolkit/query';\nimport {\n Box,\n Button,\n FieldLabel,\n Flex,\n ModalBody,\n ModalHeader,\n ModalLayout,\n SingleSelect,\n SingleSelectOption,\n Typography,\n ModalFooter,\n} from '@strapi/design-system';\nimport { LinkButton } from '@strapi/design-system/v2';\nimport {\n CheckPermissions,\n NoContent,\n useAPIErrorHandler,\n useCMEditViewDataManager,\n useNotification,\n} from '@strapi/helper-plugin';\nimport { Plus } from '@strapi/icons';\nimport { isAxiosError } from 'axios';\nimport { Formik, Form } from 'formik';\nimport { useIntl } from 'react-intl';\nimport { useParams, Link as ReactRouterLink } from 'react-router-dom';\nimport * as yup from 'yup';\n\nimport { CreateReleaseAction } from '../../../shared/contracts/release-actions';\nimport { GetContentTypeEntryReleases } from '../../../shared/contracts/releases';\nimport { PERMISSIONS } from '../constants';\nimport { useCreateReleaseActionMutation, useGetReleasesForEntryQuery } from '../services/release';\n\nimport { ReleaseActionMenu } from './ReleaseActionMenu';\nimport { ReleaseActionOptions } from './ReleaseActionOptions';\n\n/* -------------------------------------------------------------------------------------------------\n * AddActionToReleaseModal\n * -----------------------------------------------------------------------------------------------*/\n\nconst RELEASE_ACTION_FORM_SCHEMA = yup.object().shape({\n type: yup.string().oneOf(['publish', 'unpublish']).required(),\n releaseId: yup.string().required(),\n});\n\ninterface FormValues {\n type: CreateReleaseAction.Request['body']['type'];\n releaseId: CreateReleaseAction.Request['params']['releaseId'];\n}\n\nconst INITIAL_VALUES = {\n type: 'publish',\n releaseId: '',\n} satisfies FormValues;\n\ninterface AddActionToReleaseModalProps {\n handleClose: () => void;\n contentTypeUid: GetContentTypeEntryReleases.Request['query']['contentTypeUid'];\n entryId: GetContentTypeEntryReleases.Request['query']['entryId'];\n}\n\nconst NoReleases = () => {\n const { formatMessage } = useIntl();\n return (\n <NoContent\n content={{\n id: 'content-releases.content-manager-edit-view.add-to-release.no-releases-message',\n defaultMessage:\n 'No available releases. Open the list of releases and create a new one from there.',\n }}\n action={\n <LinkButton\n // @ts-expect-error - types are not inferred correctly through the as prop.\n to={{\n pathname: '/plugins/content-releases',\n }}\n as={ReactRouterLink}\n variant=\"secondary\"\n >\n {formatMessage({\n id: 'content-releases.content-manager-edit-view.add-to-release.redirect-button',\n defaultMessage: 'Open the list of releases',\n })}\n </LinkButton>\n }\n />\n );\n};\n\nconst AddActionToReleaseModal = ({\n handleClose,\n contentTypeUid,\n entryId,\n}: AddActionToReleaseModalProps) => {\n const { formatMessage } = useIntl();\n const toggleNotification = useNotification();\n const { formatAPIError } = useAPIErrorHandler();\n const { modifiedData } = useCMEditViewDataManager();\n\n // Get all 'pending' releases that do not have the entry attached\n const response = useGetReleasesForEntryQuery({\n contentTypeUid,\n entryId,\n hasEntryAttached: false,\n });\n\n const releases = response.data?.data;\n const [createReleaseAction, { isLoading }] = useCreateReleaseActionMutation();\n\n const handleSubmit = async (values: FormValues) => {\n const locale = modifiedData.locale as string | undefined;\n const releaseActionEntry = {\n contentType: contentTypeUid,\n id: entryId,\n locale,\n };\n const response = await createReleaseAction({\n body: { type: values.type, entry: releaseActionEntry },\n params: { releaseId: values.releaseId },\n });\n\n if ('data' in response) {\n // Handle success\n toggleNotification({\n type: 'success',\n message: formatMessage({\n id: 'content-releases.content-manager-edit-view.add-to-release.notification.success',\n defaultMessage: 'Entry added to release',\n }),\n });\n\n handleClose();\n return;\n }\n\n if ('error' in response) {\n if (isAxiosError(response.error)) {\n // Handle axios error\n toggleNotification({\n type: 'warning',\n message: formatAPIError(response.error),\n });\n } else {\n // Handle generic error\n toggleNotification({\n type: 'warning',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error occurred' }),\n });\n }\n }\n };\n\n return (\n <ModalLayout onClose={handleClose} labelledBy=\"title\">\n <ModalHeader>\n <Typography id=\"title\" fontWeight=\"bold\" textColor=\"neutral800\">\n {formatMessage({\n id: 'content-releases.content-manager-edit-view.add-to-release',\n defaultMessage: 'Add to release',\n })}\n </Typography>\n </ModalHeader>\n <Formik\n onSubmit={handleSubmit}\n validationSchema={RELEASE_ACTION_FORM_SCHEMA}\n initialValues={INITIAL_VALUES}\n >\n {({ values, setFieldValue }) => {\n return (\n <Form>\n {releases?.length === 0 ? (\n <NoReleases />\n ) : (\n <ModalBody>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={2}>\n <Box paddingBottom={6}>\n <SingleSelect\n required\n label={formatMessage({\n id: 'content-releases.content-manager-edit-view.add-to-release.select-label',\n defaultMessage: 'Select a release',\n })}\n placeholder={formatMessage({\n id: 'content-releases.content-manager-edit-view.add-to-release.select-placeholder',\n defaultMessage: 'Select',\n })}\n onChange={(value) => setFieldValue('releaseId', value)}\n value={values.releaseId}\n >\n {releases?.map((release) => (\n <SingleSelectOption key={release.id} value={release.id}>\n {release.name}\n </SingleSelectOption>\n ))}\n </SingleSelect>\n </Box>\n <FieldLabel>\n {formatMessage({\n id: 'content-releases.content-manager-edit-view.add-to-release.action-type-label',\n defaultMessage: 'What do you want to do with this entry?',\n })}\n </FieldLabel>\n <ReleaseActionOptions\n selected={values.type}\n handleChange={(e) => setFieldValue('type', e.target.value)}\n name=\"type\"\n />\n </Flex>\n </ModalBody>\n )}\n <ModalFooter\n startActions={\n <Button onClick={handleClose} variant=\"tertiary\" name=\"cancel\">\n {formatMessage({\n id: 'content-releases.content-manager-edit-view.add-to-release.cancel-button',\n defaultMessage: 'Cancel',\n })}\n </Button>\n }\n endActions={\n /**\n * TODO: Ideally we would use isValid from Formik to disable the button, however currently it always returns true\n * for yup.string().required(), even when the value is falsy (including empty string)\n */\n <Button type=\"submit\" disabled={!values.releaseId} loading={isLoading}>\n {formatMessage({\n id: 'content-releases.content-manager-edit-view.add-to-release.continue-button',\n defaultMessage: 'Continue',\n })}\n </Button>\n }\n />\n </Form>\n );\n }}\n </Formik>\n </ModalLayout>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * CMReleasesContainer\n * -----------------------------------------------------------------------------------------------*/\n\nexport const CMReleasesContainer = () => {\n const [isModalOpen, setIsModalOpen] = React.useState(false);\n const { formatMessage } = useIntl();\n const {\n isCreatingEntry,\n allLayoutData: { contentType },\n } = useCMEditViewDataManager();\n const params = useParams<{ id: string }>();\n\n const canFetch = params?.id != null && contentType?.uid != null;\n const fetchParams = canFetch\n ? {\n contentTypeUid: contentType.uid,\n entryId: params.id,\n hasEntryAttached: true,\n }\n : skipToken;\n // Get all 'pending' releases that have the entry attached\n const response = useGetReleasesForEntryQuery(fetchParams);\n const releases = response.data?.data;\n\n /**\n * If we don't have a contentType.uid or params.id then the data was never fetched\n * TODO: Should we handle this with an error message in the UI or just not show the container?\n */\n if (!canFetch) {\n return null;\n }\n\n /**\n * - Impossible to add entry to release before it exists\n * - Content types without draft and publish cannot add entries to release\n * TODO v5: All contentTypes will have draft and publish enabled\n */\n if (isCreatingEntry || !contentType?.options?.draftAndPublish) {\n return null;\n }\n\n const toggleModal = () => setIsModalOpen((prev) => !prev);\n\n const getReleaseColorVariant = (\n actionType: 'publish' | 'unpublish',\n shade: '100' | '200' | '600'\n ) => {\n if (actionType === 'unpublish') {\n return `secondary${shade}`;\n }\n\n return `success${shade}`;\n };\n\n return (\n <CheckPermissions permissions={PERMISSIONS.main}>\n <Box\n as=\"aside\"\n aria-label={formatMessage({\n id: 'content-releases.plugin.name',\n defaultMessage: 'Releases',\n })}\n background=\"neutral0\"\n borderColor=\"neutral150\"\n hasRadius\n padding={4}\n shadow=\"tableShadow\"\n >\n <Flex direction=\"column\" alignItems=\"stretch\" gap={3}>\n <Typography variant=\"sigma\" textColor=\"neutral600\" textTransform=\"uppercase\">\n {formatMessage({\n id: 'content-releases.plugin.name',\n defaultMessage: 'Releases',\n })}\n </Typography>\n {releases?.map((release) => {\n return (\n <Flex\n key={release.id}\n direction=\"column\"\n alignItems=\"start\"\n borderWidth=\"1px\"\n borderStyle=\"solid\"\n borderColor={getReleaseColorVariant(release.action.type, '200')}\n overflow=\"hidden\"\n hasRadius\n >\n <Box\n paddingTop={3}\n paddingBottom={3}\n paddingLeft={4}\n paddingRight={4}\n background={getReleaseColorVariant(release.action.type, '100')}\n width=\"100%\"\n >\n <Typography\n fontSize={1}\n variant=\"pi\"\n textColor={getReleaseColorVariant(release.action.type, '600')}\n >\n {formatMessage(\n {\n id: 'content-releases.content-manager-edit-view.list-releases.title',\n defaultMessage:\n '{isPublish, select, true {Will be published in} other {Will be unpublished in}}',\n },\n { isPublish: release.action.type === 'publish' }\n )}\n </Typography>\n </Box>\n <Flex padding={4} direction=\"column\" gap={3} width=\"100%\" alignItems=\"flex-start\">\n <Typography fontSize={2} fontWeight=\"bold\" variant=\"omega\" textColor=\"neutral700\">\n {release.name}\n </Typography>\n <CheckPermissions permissions={PERMISSIONS.deleteAction}>\n <ReleaseActionMenu.Root hasTriggerBorder>\n <ReleaseActionMenu.DeleteReleaseActionItem\n releaseId={release.id}\n actionId={release.action.id}\n />\n </ReleaseActionMenu.Root>\n </CheckPermissions>\n </Flex>\n </Flex>\n );\n })}\n <CheckPermissions permissions={PERMISSIONS.createAction}>\n <Button\n justifyContent=\"center\"\n paddingLeft={4}\n paddingRight={4}\n color=\"neutral700\"\n variant=\"tertiary\"\n startIcon={<Plus />}\n onClick={toggleModal}\n >\n {formatMessage({\n id: 'content-releases.content-manager-edit-view.add-to-release',\n defaultMessage: 'Add to release',\n })}\n </Button>\n </CheckPermissions>\n </Flex>\n {isModalOpen && (\n <AddActionToReleaseModal\n handleClose={toggleModal}\n contentTypeUid={contentType.uid}\n entryId={params.id}\n />\n )}\n </Box>\n </CheckPermissions>\n );\n};\n","import { prefixPluginTranslations } from '@strapi/helper-plugin';\nimport { PaperPlane } from '@strapi/icons';\n\nimport { CMReleasesContainer } from './components/CMReleasesContainer';\nimport { PERMISSIONS } from './constants';\nimport { pluginId } from './pluginId';\nimport { releaseApi } from './services/release';\n\nimport type { Plugin } from '@strapi/types';\n\n// eslint-disable-next-line import/no-default-export\nconst admin: Plugin.Config.AdminInput = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n register(app: any) {\n if (window.strapi.features.isEnabled('cms-content-releases')) {\n app.addMenuLink({\n to: `/plugins/${pluginId}`,\n icon: PaperPlane,\n intlLabel: {\n id: `${pluginId}.plugin.name`,\n defaultMessage: 'Releases',\n },\n async Component() {\n const { App } = await import('./pages/App');\n return App;\n },\n permissions: PERMISSIONS.main,\n });\n\n /**\n * For some reason every middleware you pass has to a function\n * that returns the actual middleware. It's annoying but no one knows why....\n */\n app.addMiddlewares([() => releaseApi.middleware]);\n\n app.addReducers({\n [releaseApi.reducerPath]: releaseApi.reducer,\n });\n\n // Insert the Releases container in the 'right-links' zone of the Content Manager's edit view\n app.injectContentManagerComponent('editView', 'right-links', {\n name: `${pluginId}-link`,\n Component: CMReleasesContainer,\n });\n }\n },\n async registerTrads({ locales }: { locales: string[] }) {\n const importedTrads = await Promise.all(\n locales.map((locale) => {\n return import(`./translations/${locale}.json`)\n .then(({ default: data }) => {\n return {\n data: prefixPluginTranslations(data, 'content-releases'),\n locale,\n };\n })\n .catch(() => {\n return {\n data: {},\n locale,\n };\n });\n })\n );\n\n return Promise.resolve(importedTrads);\n },\n};\n\n// eslint-disable-next-line import/no-default-export\nexport default admin;\n"],"names":["getFetchClient","result","createApi","useDispatch","useSelector","styled","Menu","IconButton","useIntl","useNotification","useAPIErrorHandler","isAxiosError","jsx","CheckPermissions","jsxs","Flex","Icon","Cross","Typography","Link","NavLink","Pencil","More","Field","FieldLabel","VisuallyHidden","FieldInput","yup","NoContent","LinkButton","ReactRouterLink","useCMEditViewDataManager","response","ModalLayout","ModalHeader","Formik","Form","ModalBody","Box","SingleSelect","SingleSelectOption","ModalFooter","Button","React","useParams","skipToken","Plus","PaperPlane","prefixPluginTranslations"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEO,MAAM,cAAc;AAAA,EACzB,MAAM;AAAA,IACJ;AAAA,MACE,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,IAAI;AAAA,MACJ,kBAAkB,CAAC;AAAA,MACnB,YAAY,CAAC;AAAA,MACb,YAAY,CAAC;AAAA,IACf;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN;AAAA,MACE,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,IAAI;AAAA,MACJ,kBAAkB,CAAC;AAAA,MACnB,YAAY,CAAC;AAAA,MACb,YAAY,CAAC;AAAA,IACf;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN;AAAA,MACE,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,IAAI;AAAA,MACJ,kBAAkB,CAAC;AAAA,MACnB,YAAY,CAAC;AAAA,MACb,YAAY,CAAC;AAAA,IACf;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN;AAAA,MACE,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,IAAI;AAAA,MACJ,kBAAkB,CAAC;AAAA,MACnB,YAAY,CAAC;AAAA,MACb,YAAY,CAAC;AAAA,IACf;AAAA,EACF;AAAA,EACA,cAAc;AAAA,IACZ;AAAA,MACE,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,IAAI;AAAA,MACJ,kBAAkB,CAAC;AAAA,MACnB,YAAY,CAAC;AAAA,MACb,YAAY,CAAC;AAAA,IACf;AAAA,EACF;AAAA,EACA,cAAc;AAAA,IACZ;AAAA,MACE,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,IAAI;AAAA,MACJ,kBAAkB,CAAC;AAAA,MACnB,YAAY,CAAC;AAAA,MACb,YAAY,CAAC;AAAA,IACf;AAAA,EACF;AAAA,EACA,SAAS;AAAA,IACP;AAAA,MACE,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,IAAI;AAAA,MACJ,kBAAkB,CAAC;AAAA,MACnB,YAAY,CAAC;AAAA,MACb,YAAY,CAAC;AAAA,IACf;AAAA,EACF;AACF;ACzEO,MAAM,WAAW;ACcxB,MAAM,iBAAiB,OAAiC;AAAA,EACtD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAA6B;AACvB,MAAA;AACF,UAAM,EAAE,KAAK,MAAM,KAAK,IAAA,IAAQA,aAAAA;AAEhC,QAAI,WAAW,QAAQ;AACrB,YAAMC,UAAS,MAAM,KAAyC,KAAK,MAAM,MAAM;AACxE,aAAA,EAAE,MAAMA,QAAO;IACxB;AAEA,QAAI,WAAW,UAAU;AACvB,YAAMA,UAAS,MAAM,IAAwC,KAAK,MAAM;AACjE,aAAA,EAAE,MAAMA,QAAO;IACxB;AAEA,QAAI,WAAW,OAAO;AACpB,YAAMA,UAAS,MAAM,IAAwC,KAAK,MAAM,MAAM;AACvE,aAAA,EAAE,MAAMA,QAAO;IACxB;AAKA,UAAM,SAAS,MAAM,IAAwC,KAAK,MAAM;AACjE,WAAA,EAAE,MAAM,OAAO;WACf,OAAO;AACd,UAAM,MAAM;AAUL,WAAA;AAAA,MACL,OAAO;AAAA,QACL,QAAQ,IAAI,UAAU;AAAA,QACtB,MAAM,IAAI;AAAA,QACV,UAAU;AAAA,UACR,MAAM,IAAI,UAAU;AAAA,QACtB;AAAA,MACF;AAAA,IAAA;AAAA,EAEJ;AACF;AAWM,MAAA,eAAe,CAAC,QAAoD;AACxE,SACE,OAAO,QAAQ,YACf,QAAQ,QACR,cAAc,OACd,OAAO,IAAI,aAAa,YACxB,IAAI,aAAa,QACjB,UAAU,IAAI;AAElB;ACpCA,MAAM,aAAaC,MAAAA,UAAU;AAAA,EAC3B,aAAa;AAAA,EACb,WAAW;AAAA,EACX,UAAU,CAAC,WAAW,eAAe;AAAA,EACrC,WAAW,CAAC,UAAU;AACb,WAAA;AAAA,MACL,qBAAqB,MAAM,MAGzB;AAAA,QACA,MAAM,QAAQ;AACL,iBAAA;AAAA,YACL,KAAK;AAAA,YACL,QAAQ;AAAA,YACR,QAAQ;AAAA,cACN;AAAA,YACF;AAAA,UAAA;AAAA,QAEJ;AAAA,QACA,cAAc,CAAC,WACb,SACI;AAAA,UACE,GAAG,OAAO,KAAK,IAAI,CAAC,EAAE,UAAU,EAAE,MAAM,WAAoB,GAAA,EAAK;AAAA,UACjE,EAAE,MAAM,WAAW,IAAI,OAAO;AAAA,QAAA,IAEhC,CAAC;AAAA,MAAA,CACR;AAAA,MACD,aAAa,MAAM,MAA6D;AAAA,QAC9E,MACE,EAAE,MAAM,UAAU,YAAY;AAAA,UAC5B,MAAM;AAAA,UACN,UAAU;AAAA,UACV,SAAS;AAAA,YACP,YAAY;AAAA,cACV,UAAU;AAAA,YACZ;AAAA,UACF;AAAA,QAAA,GAEF;AACO,iBAAA;AAAA,YACL,KAAK;AAAA,YACL,QAAQ;AAAA,YACR,QAAQ;AAAA,cACN,QAAQ;AAAA,gBACN,MAAM,QAAQ;AAAA,gBACd,UAAU,YAAY;AAAA,gBACtB,SAAS,WAAW;AAAA,kBAClB,YAAY;AAAA,oBACV,UAAU;AAAA,kBACZ;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UAAA;AAAA,QAEJ;AAAA,QACA,kBAAkB,UAAkC,MAAM,KAAK;AACvD,gBAAA,kBAAkB,KAAK,SAAS,YAAY;AAClD,gBAAM,kBAAkB,oBAAoB;AAC5C,gBAAM,cAAsC;AAAA,YAC1C,GAAG;AAAA,YACH,MAAM;AAAA,cACJ,GAAG,SAAS;AAAA,cACZ,WAAW,kBAAkB,SAAS;AAAA,YACxC;AAAA,UAAA;AAGK,iBAAA;AAAA,QACT;AAAA,QACA,cAAc,CAAC,WACb,SACI;AAAA,UACE,GAAG,OAAO,KAAK,IAAI,CAAC,EAAE,UAAU,EAAE,MAAM,WAAoB,GAAA,EAAK;AAAA,UACjE,EAAE,MAAM,WAAW,IAAI,OAAO;AAAA,YAEhC,CAAC,EAAE,MAAM,WAAW,IAAI,QAAQ;AAAA,MAAA,CACvC;AAAA,MACD,YAAY,MAAM,MAAyD;AAAA,QACzE,MAAM,EAAE,MAAM;AACL,iBAAA;AAAA,YACL,KAAK,qBAAqB,EAAE;AAAA,YAC5B,QAAQ;AAAA,UAAA;AAAA,QAEZ;AAAA,QACA,cAAc,CAAC,QAAQ,OAAO,QAAQ,CAAC,EAAE,MAAM,WAAoB,IAAI,IAAI,GAAA,CAAI;AAAA,MAAA,CAChF;AAAA,MACD,mBAAmB,MAAM,MAGvB;AAAA,QACA,MAAM,EAAE,WAAW,GAAG,UAAU;AACvB,iBAAA;AAAA,YACL,KAAK,qBAAqB,SAAS;AAAA,YACnC,QAAQ;AAAA,YACR,QAAQ;AAAA,cACN;AAAA,YACF;AAAA,UAAA;AAAA,QAEJ;AAAA,QACA,cAAc,CAAC,EAAE,MAAM,iBAAiB,IAAI,QAAQ;AAAA,MAAA,CACrD;AAAA,MACD,eAAe,MAAM,SAAgE;AAAA,QACnF,MAAM,MAAM;AACH,iBAAA;AAAA,YACL,KAAK;AAAA,YACL,QAAQ;AAAA,YACR;AAAA,UAAA;AAAA,QAEJ;AAAA,QACA,iBAAiB,CAAC,EAAE,MAAM,WAAW,IAAI,QAAQ;AAAA,MAAA,CAClD;AAAA,MACD,eAAe,MAAM,SAGnB;AAAA,QACA,MAAM,EAAE,IAAI,GAAG,QAAQ;AACd,iBAAA;AAAA,YACL,KAAK,qBAAqB,EAAE;AAAA,YAC5B,QAAQ;AAAA,YACR;AAAA,UAAA;AAAA,QAEJ;AAAA,QACA,iBAAiB,CAAC,QAAQ,OAAO,QAAQ,CAAC,EAAE,MAAM,WAAW,IAAI,IAAI,GAAA,CAAI;AAAA,MAAA,CAC1E;AAAA,MACD,qBAAqB,MAAM,SAGzB;AAAA,QACA,MAAM,EAAE,MAAM,UAAU;AACf,iBAAA;AAAA,YACL,KAAK,qBAAqB,OAAO,SAAS;AAAA,YAC1C,QAAQ;AAAA,YACR,MAAM;AAAA,UAAA;AAAA,QAEV;AAAA,QACA,iBAAiB;AAAA,UACf,EAAE,MAAM,WAAW,IAAI,OAAO;AAAA,UAC9B,EAAE,MAAM,iBAAiB,IAAI,OAAO;AAAA,QACtC;AAAA,MAAA,CACD;AAAA,MACD,qBAAqB,MAAM,SAGzB;AAAA,QACA,MAAM,EAAE,MAAM,UAAU;AACf,iBAAA;AAAA,YACL,KAAK,qBAAqB,OAAO,SAAS,YAAY,OAAO,QAAQ;AAAA,YACrE,QAAQ;AAAA,YACR,MAAM;AAAA,UAAA;AAAA,QAEV;AAAA,QACA,iBAAiB,MAAM,CAAC,EAAE,MAAM,iBAAiB,IAAI,QAAQ;AAAA,MAAA,CAC9D;AAAA,MACD,qBAAqB,MAAM,SAGzB;AAAA,QACA,MAAM,EAAE,UAAU;AACT,iBAAA;AAAA,YACL,KAAK,qBAAqB,OAAO,SAAS,YAAY,OAAO,QAAQ;AAAA,YACrE,QAAQ;AAAA,UAAA;AAAA,QAEZ;AAAA,QACA,iBAAiB;AAAA,UACf,EAAE,MAAM,WAAW,IAAI,OAAO;AAAA,UAC9B,EAAE,MAAM,iBAAiB,IAAI,OAAO;AAAA,QACtC;AAAA,MAAA,CACD;AAAA,MACD,gBAAgB,MAAM,SAAoE;AAAA,QACxF,MAAM,EAAE,MAAM;AACL,iBAAA;AAAA,YACL,KAAK,qBAAqB,EAAE;AAAA,YAC5B,QAAQ;AAAA,UAAA;AAAA,QAEZ;AAAA,QACA,iBAAiB,CAAC,QAAQ,OAAO,QAAQ,CAAC,EAAE,MAAM,WAAW,IAAI,IAAI,GAAA,CAAI;AAAA,MAAA,CAC1E;AAAA,MACD,eAAe,MAAM,SAAkE;AAAA,QACrF,MAAM,EAAE,MAAM;AACL,iBAAA;AAAA,YACL,KAAK,qBAAqB,EAAE;AAAA,YAC5B,QAAQ;AAAA,UAAA;AAAA,QAEZ;AAAA,QACA,iBAAiB,CAAC,QAAQ,OAAO,QAAQ,CAAC,EAAE,MAAM,WAAW,IAAI,IAAI,GAAA,CAAI;AAAA,MAAA,CAC1E;AAAA,IAAA;AAAA,EAEL;AACF,CAAC;AAEK,MAAA;AAAA,EACJ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,IAAI;AClPJ,MAAM,mBAAmCC,WAAA;AACzC,MAAM,mBAAoDC,WAAA;ACU1D,MAAM,iBAAiBC,gBAAO,QAAAC,QAAK,IAAI;AAAA;AAAA,kBAErB,CAAC,EAAE,OAAO,UAAU,UAAgB,MAAA,MAAM,OAAO,GAAG,OAAO,KAAK,CAAC;AAAA;AAAA;AAAA;AAAA,gBAInE,CAAC,EAAE,OAAO,UAAU,UAAgB,MAAA,MAAM,OAAO,GAAG,OAAO,KAAK,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,eAKlE,CAAC,EAAE,MAAA,MAAY,MAAM,OAAO,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAMvC,CAAC,EAAE,OAAO,UAAU,UAAgB,MAAA,MAAM,OAAO,GAAG,OAAO,KAAK,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,aAKlE,CAAC,EAAE,MAAA,MAAY,MAAM,OAAO,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYnD,MAAM,mBAAmBD,gBAAAA,QAAOE,aAAAA,UAAU;AAAA;AAAA,YAE9B,CAAC,EAAE,MAAM,MAAM,aAAa,MAAM,OAAO,UAAU,EAAE;AAAA;AAOjE,MAAM,0BAA0B,CAAC,EAAE,WAAW,eAA6C;AACnF,QAAA,EAAE,kBAAkBC,UAAAA;AAC1B,QAAM,qBAAqBC,aAAAA;AACrB,QAAA,EAAE,mBAAmBC,aAAAA;AACrB,QAAA,CAAC,mBAAmB,IAAI;AAE9B,QAAM,qBAAqB,YAAY;AAC/B,UAAA,WAAW,MAAM,oBAAoB;AAAA,MACzC,QAAQ,EAAE,WAAW,SAAS;AAAA,IAAA,CAC/B;AAED,QAAI,UAAU,UAAU;AAEH,yBAAA;AAAA,QACjB,MAAM;AAAA,QACN,SAAS,cAAc;AAAA,UACrB,IAAI;AAAA,UACJ,gBAAgB;AAAA,QAAA,CACjB;AAAA,MAAA,CACF;AAED;AAAA,IACF;AAEA,QAAI,WAAW,UAAU;AACnB,UAAAC,MAAA,aAAa,SAAS,KAAK,GAAG;AAEb,2BAAA;AAAA,UACjB,MAAM;AAAA,UACN,SAAS,eAAe,SAAS,KAAK;AAAA,QAAA,CACvC;AAAA,MAAA,OACI;AAEc,2BAAA;AAAA,UACjB,MAAM;AAAA,UACN,SAAS,cAAc,EAAE,IAAI,sBAAsB,gBAAgB,qBAAqB;AAAA,QAAA,CACzF;AAAA,MACH;AAAA,IACF;AAAA,EAAA;AAGF,SACGC,2BAAA,IAAAC,aAAA,kBAAA,EAAiB,aAAa,YAAY,cACzC,UAACD,2BAAA,IAAA,gBAAA,EAAe,SAAQ,UAAS,UAAU,oBACzC,UAACE,2BAAAA,KAAAC,aAAAA,MAAA,EAAK,KAAK,GACT,UAAA;AAAA,IAAAH,2BAAA,IAACI,aAAK,MAAA,EAAA,IAAIC,MAAAA,OAAO,SAAS,GAAG;AAAA,mCAC5BC,aAAAA,YAAW,EAAA,WAAU,aAAY,SAAQ,SACvC,UAAc,cAAA;AAAA,MACb,IAAI;AAAA,MACJ,gBAAgB;AAAA,IACjB,CAAA,GACH;AAAA,EAAA,GACF,GACF,EACF,CAAA;AAEJ;AAWA,MAAM,6BAA6B,CAAC;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AACF,MAAuC;AAC/B,QAAA,EAAE,kBAAkBV,UAAAA;AAE1B,QAAM,4BAA4B;AAAA,IAChC,CAAC,UAAU,MAAM,aAAa;AAAA,EAAA;AAEhC,QAAM,oBAAoB,iBACtB,0BAA0B,cAAc,IAAI,yCAAyC,IACrF;AACJ,QAAM,0BAA0B;AAAA,IAC9B,CAAC,UACC,mBAAmB;AAAA,MAAK,CAAC,eACvB,WAAW,YAAY,SAAS,SAAS,MAAM;AAAA,IACjD;AAAA,EAAA;AAIF,SAAAI,2BAAA;AAAA,IAACC,aAAA;AAAA,IAAA;AAAA,MACC,aAAa;AAAA,QACX;AAAA,UACE,QAAQ;AAAA,UACR,SAAS;AAAA,QACX;AAAA,MACF;AAAA,MAEC,UAAA,0DACE,gBACC,EAAA,UAAAD,2BAAA;AAAA,QAACO,GAAA;AAAA,QAAA;AAAA,UACC,IAAIC,eAAA;AAAA,UAEJ,IAAI;AAAA,YACF,UAAU,qCAAqC,cAAc,IAAI,OAAO;AAAA,YACxE,QAAQ,UAAU,0BAA0B,MAAM;AAAA,UACpD;AAAA,UACA,WAAYR,2BAAA,IAAAI,mBAAA,EAAK,IAAIK,cAAQ,SAAS,GAAG;AAAA,UAEzC,UAACT,2BAAA,IAAAM,yBAAA,EAAW,SAAQ,SACjB,UAAc,cAAA;AAAA,YACb,IAAI;AAAA,YACJ,gBAAgB;AAAA,UACjB,CAAA,GACH;AAAA,QAAA;AAAA,MAAA,GAEJ;AAAA,IAAA;AAAA,EAAA;AAIR;AAWA,MAAM,OAAO,CAAC,EAAE,UAAU,mBAAmB,YAAuB;AAC5D,QAAA,EAAE,kBAAkBV,UAAAA;AAE1B;AAAA;AAAA,IAEGI,2BAAA,IAAAC,aAAA,kBAAA,EAAiB,aAAa,CAAC,GAAG,YAAY,cAAc,GAAG,YAAY,MAAM,GAChF,UAACC,2BAAAA,KAAAR,GAAAA,KAAK,MAAL,EAMC,UAAA;AAAA,MAAAM,2BAAA;AAAA,QAACN,GAAAA,KAAK;AAAA,QAAL;AAAA,UACC,IAAI,mBAAmB,mBAAmBC,aAAA;AAAA,UAC1C,aAAa;AAAA,UACb,cAAc;AAAA,UACd,cAAY,cAAc;AAAA,YACxB,IAAI;AAAA,YACJ,gBAAgB;AAAA,UAAA,CACjB;AAAA,UAED,qCAAOe,MAAK,MAAA,EAAA;AAAA,QAAA;AAAA,MACd;AAAA,MAKAV,+BAACN,GAAAA,KAAK,SAAL,EAAa,KAAK,GAAG,kBAAiB,cACpC,UACH;AAAA,IAAA,EAAA,CACF,EACF,CAAA;AAAA;AAEJ;AAEO,MAAM,oBAAoB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AACF;ACrNA,MAAM,2BAA2B,CAAC,eAAgD;AACzE,SAAA,eAAe,YAAY,IAAI;AACxC;AAEA,MAAM,4BAA4B,CAAC,eAAgD;AAC1E,SAAA,eAAe,YAAY,IAAI;AACxC;AAEA,MAAM,eAAeD,gBAAAA,QAAOkB,aAAAA,KAAK;AAAA,4BACL,CAAC,EAAE,YAAY,MAAM,MAC7C,MAAM,OAAO,yBAAyB,UAAU,CAAC,CAAC;AAAA,+BACvB,CAAC,EAAE,YAAY,MAAM,MAChD,MAAM,OAAO,yBAAyB,UAAU,CAAC,CAAC;AAAA,6BACzB,CAAC,EAAE,YAAY,MAAM,MAC9C,MAAM,OAAO,0BAA0B,UAAU,CAAC,CAAC;AAAA,gCACvB,CAAC,EAAE,YAAY,MAAM,MACjD,MAAM,OAAO,0BAA0B,UAAU,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA,eAIxC,CAAC,EAAE,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,CAAC,IAAI,MAAM,OAAO,CAAC,CAAC,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,aAQxD,CAAC,EAAE,MAAA,MAAY,MAAM,OAAO,UAAU;AAAA,wBAC3B,CAAC,EAAE,MAAA,MAAY,MAAM,OAAO,UAAU;AAAA,oBAC1C,CAAC,EAAE,MAAA,MAAY,MAAM,OAAO,UAAU;AAAA;AAAA;AAAA;AAAA,mBAIvC,CAAC,EAAE,WAAA,MAAiB,eAAe,eAAe,MAAM;AAAA,oBACvD,CAAC,EAAE,WAAA,MAAiB,eAAe,aAAa,MAAM;AAAA;AAAA;AAc1E,MAAM,eAAe,CAAC,EAAE,UAAU,YAAY,cAAc,WAAwB;AAEhF,SAAAX,2BAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC;AAAA,MACA,YAAW;AAAA,MACX,aAAY;AAAA,MACZ,OAAO,aAAa,aAAa,eAAe;AAAA,MAChD,UAAS;AAAA,MACT,QAAO;AAAA,MACP,gBAAc,aAAa;AAAA,MAE3B,0CAACY,yBAAW,EAAA,SAAS,GAAG,IAAI,IAAI,UAAU,IACxC,UAAA;AAAA,QAAAZ,+BAACa,aAAAA,gBACC,EAAA,UAAAb,2BAAA;AAAA,UAACc,aAAA;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,IAAI,GAAG,IAAI,IAAI,UAAU;AAAA,YACzB;AAAA,YACA,SAAS,aAAa;AAAA,YACtB,UAAU;AAAA,YACV,OAAO;AAAA,UAAA;AAAA,QAAA,GAEX;AAAA,QACC;AAAA,MAAA,GACH;AAAA,IAAA;AAAA,EAAA;AAGN;AAEO,MAAM,uBAAuB,CAAC,EAAE,UAAU,cAAc,WAA8B;AAC3F,yCACGX,mBACC,EAAA,UAAA;AAAA,IAAAH,2BAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,YAAW;AAAA,QACX;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,IACF;AAAA,IACAA,2BAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,YAAW;AAAA,QACX;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,IACF;AAAA,EACF,EAAA,CAAA;AAEJ;ACnEA,MAAM,6BAA6Be,eAAI,OAAO,EAAE,MAAM;AAAA,EACpD,MAAMA,eAAI,SAAS,MAAM,CAAC,WAAW,WAAW,CAAC,EAAE,SAAS;AAAA,EAC5D,WAAWA,eAAI,OAAO,EAAE,SAAS;AACnC,CAAC;AAOD,MAAM,iBAAiB;AAAA,EACrB,MAAM;AAAA,EACN,WAAW;AACb;AAQA,MAAM,aAAa,MAAM;AACjB,QAAA,EAAE,kBAAkBnB,UAAAA;AAExB,SAAAI,2BAAA;AAAA,IAACgB,aAAA;AAAA,IAAA;AAAA,MACC,SAAS;AAAA,QACP,IAAI;AAAA,QACJ,gBACE;AAAA,MACJ;AAAA,MACA,QACEhB,2BAAA;AAAA,QAACiB,GAAA;AAAA,QAAA;AAAA,UAEC,IAAI;AAAA,YACF,UAAU;AAAA,UACZ;AAAA,UACA,IAAIC,eAAA;AAAA,UACJ,SAAQ;AAAA,UAEP,UAAc,cAAA;AAAA,YACb,IAAI;AAAA,YACJ,gBAAgB;AAAA,UAAA,CACjB;AAAA,QAAA;AAAA,MACH;AAAA,IAAA;AAAA,EAAA;AAIR;AAEA,MAAM,0BAA0B,CAAC;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AACF,MAAoC;AAC5B,QAAA,EAAE,kBAAkBtB,UAAAA;AAC1B,QAAM,qBAAqBC,aAAAA;AACrB,QAAA,EAAE,mBAAmBC,aAAAA;AACrB,QAAA,EAAE,iBAAiBqB,aAAAA;AAGzB,QAAM,WAAW,4BAA4B;AAAA,IAC3C;AAAA,IACA;AAAA,IACA,kBAAkB;AAAA,EAAA,CACnB;AAEK,QAAA,WAAW,SAAS,MAAM;AAChC,QAAM,CAAC,qBAAqB,EAAE,UAAU,CAAC,IAAI,+BAA+B;AAEtE,QAAA,eAAe,OAAO,WAAuB;AACjD,UAAM,SAAS,aAAa;AAC5B,UAAM,qBAAqB;AAAA,MACzB,aAAa;AAAA,MACb,IAAI;AAAA,MACJ;AAAA,IAAA;AAEIC,UAAAA,YAAW,MAAM,oBAAoB;AAAA,MACzC,MAAM,EAAE,MAAM,OAAO,MAAM,OAAO,mBAAmB;AAAA,MACrD,QAAQ,EAAE,WAAW,OAAO,UAAU;AAAA,IAAA,CACvC;AAED,QAAI,UAAUA,WAAU;AAEH,yBAAA;AAAA,QACjB,MAAM;AAAA,QACN,SAAS,cAAc;AAAA,UACrB,IAAI;AAAA,UACJ,gBAAgB;AAAA,QAAA,CACjB;AAAA,MAAA,CACF;AAEW;AACZ;AAAA,IACF;AAEA,QAAI,WAAWA,WAAU;AACnB,UAAArB,MAAA,aAAaqB,UAAS,KAAK,GAAG;AAEb,2BAAA;AAAA,UACjB,MAAM;AAAA,UACN,SAAS,eAAeA,UAAS,KAAK;AAAA,QAAA,CACvC;AAAA,MAAA,OACI;AAEc,2BAAA;AAAA,UACjB,MAAM;AAAA,UACN,SAAS,cAAc,EAAE,IAAI,sBAAsB,gBAAgB,qBAAqB;AAAA,QAAA,CACzF;AAAA,MACH;AAAA,IACF;AAAA,EAAA;AAGF,SACGlB,2BAAAA,KAAAmB,aAAAA,aAAA,EAAY,SAAS,aAAa,YAAW,SAC5C,UAAA;AAAA,IAACrB,2BAAAA,IAAAsB,aAAAA,aAAA,EACC,yCAAChB,aAAW,YAAA,EAAA,IAAG,SAAQ,YAAW,QAAO,WAAU,cAChD,UAAc,cAAA;AAAA,MACb,IAAI;AAAA,MACJ,gBAAgB;AAAA,IAAA,CACjB,GACH,EACF,CAAA;AAAA,IACAN,2BAAA;AAAA,MAACuB,OAAA;AAAA,MAAA;AAAA,QACC,UAAU;AAAA,QACV,kBAAkB;AAAA,QAClB,eAAe;AAAA,QAEd,UAAC,CAAA,EAAE,QAAQ,oBAAoB;AAC9B,iDACGC,aACE,EAAA,UAAA;AAAA,YAAA,UAAU,WAAW,IACnBxB,2BAAA,IAAA,YAAA,EAAW,IAEXA,+BAAAyB,aAAAA,WAAA,EACC,UAACvB,2BAAAA,KAAAC,aAAA,MAAA,EAAK,WAAU,UAAS,YAAW,WAAU,KAAK,GACjD,UAAA;AAAA,cAACH,2BAAAA,IAAA0B,aAAAA,KAAA,EAAI,eAAe,GAClB,UAAA1B,2BAAA;AAAA,gBAAC2B,aAAA;AAAA,gBAAA;AAAA,kBACC,UAAQ;AAAA,kBACR,OAAO,cAAc;AAAA,oBACnB,IAAI;AAAA,oBACJ,gBAAgB;AAAA,kBAAA,CACjB;AAAA,kBACD,aAAa,cAAc;AAAA,oBACzB,IAAI;AAAA,oBACJ,gBAAgB;AAAA,kBAAA,CACjB;AAAA,kBACD,UAAU,CAAC,UAAU,cAAc,aAAa,KAAK;AAAA,kBACrD,OAAO,OAAO;AAAA,kBAEb,UAAU,UAAA,IAAI,CAAC,YACb3B,2BAAAA,IAAA4B,aAAAA,oBAAA,EAAoC,OAAO,QAAQ,IACjD,UAAA,QAAQ,KADc,GAAA,QAAQ,EAEjC,CACD;AAAA,gBAAA;AAAA,cAAA,GAEL;AAAA,cACA5B,2BAAAA,IAACY,2BACE,UAAc,cAAA;AAAA,gBACb,IAAI;AAAA,gBACJ,gBAAgB;AAAA,cACjB,CAAA,GACH;AAAA,cACAZ,2BAAA;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,UAAU,OAAO;AAAA,kBACjB,cAAc,CAAC,MAAM,cAAc,QAAQ,EAAE,OAAO,KAAK;AAAA,kBACzD,MAAK;AAAA,gBAAA;AAAA,cACP;AAAA,YAAA,EAAA,CACF,EACF,CAAA;AAAA,YAEFA,2BAAA;AAAA,cAAC6B,aAAA;AAAA,cAAA;AAAA,gBACC,6CACGC,qBAAO,EAAA,SAAS,aAAa,SAAQ,YAAW,MAAK,UACnD,UAAc,cAAA;AAAA,kBACb,IAAI;AAAA,kBACJ,gBAAgB;AAAA,gBACjB,CAAA,GACH;AAAA,gBAEF;AAAA;AAAA;AAAA;AAAA;AAAA,kBAKE9B,2BAAAA,IAAC8B,aAAO,QAAA,EAAA,MAAK,UAAS,UAAU,CAAC,OAAO,WAAW,SAAS,WACzD,UAAc,cAAA;AAAA,oBACb,IAAI;AAAA,oBACJ,gBAAgB;AAAA,kBACjB,CAAA,GACH;AAAA;AAAA,cAAA;AAAA,YAEJ;AAAA,UACF,EAAA,CAAA;AAAA,QAEJ;AAAA,MAAA;AAAA,IACF;AAAA,EACF,EAAA,CAAA;AAEJ;AAMO,MAAM,sBAAsB,MAAM;AACvC,QAAM,CAAC,aAAa,cAAc,IAAIC,iBAAM,SAAS,KAAK;AACpD,QAAA,EAAE,kBAAkBnC,UAAAA;AACpB,QAAA;AAAA,IACJ;AAAA,IACA,eAAe,EAAE,YAAY;AAAA,MAC3BuB,aAAyB,yBAAA;AAC7B,QAAM,SAASa,eAAAA;AAEf,QAAM,WAAW,QAAQ,MAAM,QAAQ,aAAa,OAAO;AAC3D,QAAM,cAAc,WAChB;AAAA,IACE,gBAAgB,YAAY;AAAA,IAC5B,SAAS,OAAO;AAAA,IAChB,kBAAkB;AAAA,EAEpB,IAAAC;AAEE,QAAA,WAAW,4BAA4B,WAAW;AAClD,QAAA,WAAW,SAAS,MAAM;AAMhC,MAAI,CAAC,UAAU;AACN,WAAA;AAAA,EACT;AAOA,MAAI,mBAAmB,CAAC,aAAa,SAAS,iBAAiB;AACtD,WAAA;AAAA,EACT;AAEA,QAAM,cAAc,MAAM,eAAe,CAAC,SAAS,CAAC,IAAI;AAElD,QAAA,yBAAyB,CAC7B,YACA,UACG;AACH,QAAI,eAAe,aAAa;AAC9B,aAAO,YAAY,KAAK;AAAA,IAC1B;AAEA,WAAO,UAAU,KAAK;AAAA,EAAA;AAGxB,SACGjC,2BAAAA,IAAAC,aAAAA,kBAAA,EAAiB,aAAa,YAAY,MACzC,UAAAC,2BAAA;AAAA,IAACwB,aAAA;AAAA,IAAA;AAAA,MACC,IAAG;AAAA,MACH,cAAY,cAAc;AAAA,QACxB,IAAI;AAAA,QACJ,gBAAgB;AAAA,MAAA,CACjB;AAAA,MACD,YAAW;AAAA,MACX,aAAY;AAAA,MACZ,WAAS;AAAA,MACT,SAAS;AAAA,MACT,QAAO;AAAA,MAEP,UAAA;AAAA,QAAAxB,gCAACC,aAAAA,QAAK,WAAU,UAAS,YAAW,WAAU,KAAK,GACjD,UAAA;AAAA,UAAAH,2BAAAA,IAACM,2BAAW,SAAQ,SAAQ,WAAU,cAAa,eAAc,aAC9D,UAAc,cAAA;AAAA,YACb,IAAI;AAAA,YACJ,gBAAgB;AAAA,UACjB,CAAA,GACH;AAAA,UACC,UAAU,IAAI,CAAC,YAAY;AAExB,mBAAAJ,2BAAA;AAAA,cAACC,aAAA;AAAA,cAAA;AAAA,gBAEC,WAAU;AAAA,gBACV,YAAW;AAAA,gBACX,aAAY;AAAA,gBACZ,aAAY;AAAA,gBACZ,aAAa,uBAAuB,QAAQ,OAAO,MAAM,KAAK;AAAA,gBAC9D,UAAS;AAAA,gBACT,WAAS;AAAA,gBAET,UAAA;AAAA,kBAAAH,2BAAA;AAAA,oBAAC0B,aAAA;AAAA,oBAAA;AAAA,sBACC,YAAY;AAAA,sBACZ,eAAe;AAAA,sBACf,aAAa;AAAA,sBACb,cAAc;AAAA,sBACd,YAAY,uBAAuB,QAAQ,OAAO,MAAM,KAAK;AAAA,sBAC7D,OAAM;AAAA,sBAEN,UAAA1B,2BAAA;AAAA,wBAACM,aAAA;AAAA,wBAAA;AAAA,0BACC,UAAU;AAAA,0BACV,SAAQ;AAAA,0BACR,WAAW,uBAAuB,QAAQ,OAAO,MAAM,KAAK;AAAA,0BAE3D,UAAA;AAAA,4BACC;AAAA,8BACE,IAAI;AAAA,8BACJ,gBACE;AAAA,4BACJ;AAAA,4BACA,EAAE,WAAW,QAAQ,OAAO,SAAS,UAAU;AAAA,0BACjD;AAAA,wBAAA;AAAA,sBACF;AAAA,oBAAA;AAAA,kBACF;AAAA,kBACAJ,2BAAAA,KAACC,aAAAA,MAAK,EAAA,SAAS,GAAG,WAAU,UAAS,KAAK,GAAG,OAAM,QAAO,YAAW,cACnE,UAAA;AAAA,oBAACH,2BAAAA,IAAAM,aAAAA,YAAA,EAAW,UAAU,GAAG,YAAW,QAAO,SAAQ,SAAQ,WAAU,cAClE,UAAA,QAAQ,KACX,CAAA;AAAA,oBACAN,2BAAAA,IAACC,aAAAA,kBAAiB,EAAA,aAAa,YAAY,cACzC,yCAAC,kBAAkB,MAAlB,EAAuB,kBAAgB,MACtC,UAAAD,2BAAA;AAAA,sBAAC,kBAAkB;AAAA,sBAAlB;AAAA,wBACC,WAAW,QAAQ;AAAA,wBACnB,UAAU,QAAQ,OAAO;AAAA,sBAAA;AAAA,uBAE7B,EACF,CAAA;AAAA,kBAAA,GACF;AAAA,gBAAA;AAAA,cAAA;AAAA,cA5CK,QAAQ;AAAA,YAAA;AAAA,UA6Cf,CAEH;AAAA,UACAA,2BAAA,IAAAC,aAAA,kBAAA,EAAiB,aAAa,YAAY,cACzC,UAAAD,2BAAA;AAAA,YAAC8B,aAAA;AAAA,YAAA;AAAA,cACC,gBAAe;AAAA,cACf,aAAa;AAAA,cACb,cAAc;AAAA,cACd,OAAM;AAAA,cACN,SAAQ;AAAA,cACR,0CAAYI,MAAK,MAAA,EAAA;AAAA,cACjB,SAAS;AAAA,cAER,UAAc,cAAA;AAAA,gBACb,IAAI;AAAA,gBACJ,gBAAgB;AAAA,cAAA,CACjB;AAAA,YAAA;AAAA,UAAA,GAEL;AAAA,QAAA,GACF;AAAA,QACC,eACClC,2BAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,aAAa;AAAA,YACb,gBAAgB,YAAY;AAAA,YAC5B,SAAS,OAAO;AAAA,UAAA;AAAA,QAClB;AAAA,MAAA;AAAA,IAAA;AAAA,EAGN,EAAA,CAAA;AAEJ;AClYA,MAAM,QAAkC;AAAA;AAAA,EAEtC,SAAS,KAAU;AACjB,QAAI,OAAO,OAAO,SAAS,UAAU,sBAAsB,GAAG;AAC5D,UAAI,YAAY;AAAA,QACd,IAAI,YAAY,QAAQ;AAAA,QACxB,MAAMmC,MAAA;AAAA,QACN,WAAW;AAAA,UACT,IAAI,GAAG,QAAQ;AAAA,UACf,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,YAAY;AAChB,gBAAM,EAAE,IAAA,IAAQ,MAAM,QAAA,QAAA,EAAA,KAAA,MAAA,QAAO,mBAAa,CAAA;AACnC,iBAAA;AAAA,QACT;AAAA,QACA,aAAa,YAAY;AAAA,MAAA,CAC1B;AAMD,UAAI,eAAe,CAAC,MAAM,WAAW,UAAU,CAAC;AAEhD,UAAI,YAAY;AAAA,QACd,CAAC,WAAW,WAAW,GAAG,WAAW;AAAA,MAAA,CACtC;AAGG,UAAA,8BAA8B,YAAY,eAAe;AAAA,QAC3D,MAAM,GAAG,QAAQ;AAAA,QACjB,WAAW;AAAA,MAAA,CACZ;AAAA,IACH;AAAA,EACF;AAAA,EACA,MAAM,cAAc,EAAE,WAAkC;AAChD,UAAA,gBAAgB,MAAM,QAAQ;AAAA,MAClC,QAAQ,IAAI,CAAC,WAAW;AACf,eAAA,qCAA+B,uBAAA,OAAA,EAAA,0BAAA,MAAA,QAAA,QAAA,EAAA,KAAA,MAAA,QAAA,kBAAA,CAAA,EAAA,CAAA,GAAA,kBAAA,MAAA,OAAA,EACnC,KAAK,CAAC,EAAE,SAAS,WAAW;AACpB,iBAAA;AAAA,YACL,MAAMC,aAAAA,yBAAyB,MAAM,kBAAkB;AAAA,YACvD;AAAA,UAAA;AAAA,QACF,CACD,EACA,MAAM,MAAM;AACJ,iBAAA;AAAA,YACL,MAAM,CAAC;AAAA,YACP;AAAA,UAAA;AAAA,QACF,CACD;AAAA,MAAA,CACJ;AAAA,IAAA;AAGI,WAAA,QAAQ,QAAQ,aAAa;AAAA,EACtC;AACF;;;;;;;;;;;;;;;;;"}
@@ -1,17 +1,18 @@
1
1
  import { getFetchClient, useNotification, useAPIErrorHandler, CheckPermissions, useCMEditViewDataManager, NoContent, prefixPluginTranslations } from "@strapi/helper-plugin";
2
- import { Cross, More, Plus, PaperPlane } from "@strapi/icons";
2
+ import { Cross, Pencil, More, Plus, PaperPlane } from "@strapi/icons";
3
3
  import { jsx, jsxs } from "react/jsx-runtime";
4
4
  import * as React from "react";
5
5
  import { skipToken } from "@reduxjs/toolkit/query";
6
- import { IconButton, Flex, Typography, Field, FieldLabel, VisuallyHidden, FieldInput, Box, Button, ModalLayout, ModalHeader, ModalBody, SingleSelect, SingleSelectOption, ModalFooter } from "@strapi/design-system";
7
- import { Menu, LinkButton } from "@strapi/design-system/v2";
6
+ import { IconButton, Flex, Icon, Typography, Field, FieldLabel, VisuallyHidden, FieldInput, Box, Button, ModalLayout, ModalHeader, ModalBody, SingleSelect, SingleSelectOption, ModalFooter } from "@strapi/design-system";
7
+ import { Menu, Link, LinkButton } from "@strapi/design-system/v2";
8
8
  import { isAxiosError as isAxiosError$1 } from "axios";
9
9
  import { Formik, Form } from "formik";
10
10
  import { useIntl } from "react-intl";
11
- import { useParams, Link } from "react-router-dom";
11
+ import { NavLink, useParams, Link as Link$1 } from "react-router-dom";
12
12
  import * as yup from "yup";
13
13
  import { createApi } from "@reduxjs/toolkit/query/react";
14
14
  import styled from "styled-components";
15
+ import { useDispatch, useSelector } from "react-redux";
15
16
  const __variableDynamicImportRuntimeHelper = (glob, path) => {
16
17
  const v = glob[path];
17
18
  if (v) {
@@ -206,22 +207,16 @@ const releaseApi = createApi({
206
207
  providesTags: (result, error, arg) => [{ type: "Release", id: arg.id }]
207
208
  }),
208
209
  getReleaseActions: build.query({
209
- query({ releaseId, page, pageSize }) {
210
+ query({ releaseId, ...params }) {
210
211
  return {
211
212
  url: `/content-releases/${releaseId}/actions`,
212
213
  method: "GET",
213
214
  config: {
214
- params: {
215
- page,
216
- pageSize
217
- }
215
+ params
218
216
  }
219
217
  };
220
218
  },
221
- providesTags: (result, error, arg) => result ? [
222
- ...result.data.map(({ id }) => ({ type: "ReleaseAction", id })),
223
- { type: "ReleaseAction", id: "LIST" }
224
- ] : [{ type: "ReleaseAction", id: "LIST" }]
219
+ providesTags: [{ type: "ReleaseAction", id: "LIST" }]
225
220
  }),
226
221
  createRelease: build.mutation({
227
222
  query(data) {
@@ -264,9 +259,7 @@ const releaseApi = createApi({
264
259
  data: body
265
260
  };
266
261
  },
267
- invalidatesTags: (result, error, arg) => [
268
- { type: "ReleaseAction", id: arg.params.actionId }
269
- ]
262
+ invalidatesTags: () => [{ type: "ReleaseAction", id: "LIST" }]
270
263
  }),
271
264
  deleteReleaseAction: build.mutation({
272
265
  query({ params }) {
@@ -314,29 +307,43 @@ const {
314
307
  useDeleteReleaseActionMutation,
315
308
  useDeleteReleaseMutation
316
309
  } = releaseApi;
310
+ const useTypedDispatch = useDispatch;
311
+ const useTypedSelector = useSelector;
317
312
  const StyledMenuItem = styled(Menu.Item)`
318
313
  &:hover {
319
- background: transparent;
314
+ background: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}100`]};
315
+
316
+ svg {
317
+ path {
318
+ fill: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}600`]};
319
+ }
320
+ }
321
+
322
+ a {
323
+ color: ${({ theme }) => theme.colors.neutral800};
324
+ }
320
325
  }
321
326
 
322
327
  svg {
323
328
  path {
324
- fill: ${({ theme }) => theme.colors.danger600};
329
+ fill: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}600`]};
325
330
  }
326
331
  }
327
332
 
328
- &:hover {
329
- svg {
330
- path {
331
- fill: ${({ theme }) => theme.colors.danger600};
332
- }
333
- }
333
+ a {
334
+ color: ${({ theme }) => theme.colors.neutral800};
335
+ }
336
+
337
+ span,
338
+ a {
339
+ width: 100%;
334
340
  }
335
341
  `;
336
- const StyledCross = styled(Cross)`
337
- padding: ${({ theme }) => theme.spaces[1]};
342
+ const StyledIconButton = styled(IconButton)`
343
+ /* Setting this style inline with borderColor will not apply the style */
344
+ border: ${({ theme }) => `1px solid ${theme.colors.neutral200}`};
338
345
  `;
339
- const ReleaseActionMenu = ({ releaseId, actionId }) => {
346
+ const DeleteReleaseActionItem = ({ releaseId, actionId }) => {
340
347
  const { formatMessage } = useIntl();
341
348
  const toggleNotification = useNotification();
342
349
  const { formatAPIError } = useAPIErrorHandler();
@@ -369,13 +376,65 @@ const ReleaseActionMenu = ({ releaseId, actionId }) => {
369
376
  }
370
377
  }
371
378
  };
379
+ return /* @__PURE__ */ jsx(CheckPermissions, { permissions: PERMISSIONS.deleteAction, children: /* @__PURE__ */ jsx(StyledMenuItem, { variant: "danger", onSelect: handleDeleteAction, children: /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
380
+ /* @__PURE__ */ jsx(Icon, { as: Cross, padding: 1 }),
381
+ /* @__PURE__ */ jsx(Typography, { textColor: "danger600", variant: "omega", children: formatMessage({
382
+ id: "content-releases.content-manager-edit-view.remove-from-release",
383
+ defaultMessage: "Remove from release"
384
+ }) })
385
+ ] }) }) });
386
+ };
387
+ const ReleaseActionEntryLinkItem = ({
388
+ contentTypeUid,
389
+ entryId,
390
+ locale
391
+ }) => {
392
+ const { formatMessage } = useIntl();
393
+ const collectionTypePermissions = useTypedSelector(
394
+ (state) => state.rbacProvider.collectionTypesRelatedPermissions
395
+ );
396
+ const updatePermissions = contentTypeUid ? collectionTypePermissions[contentTypeUid]?.["plugin::content-manager.explorer.update"] : [];
397
+ const canUpdateEntryForLocale = Boolean(
398
+ !locale || updatePermissions?.find(
399
+ (permission) => permission.properties?.locales?.includes(locale)
400
+ )
401
+ );
402
+ return /* @__PURE__ */ jsx(
403
+ CheckPermissions,
404
+ {
405
+ permissions: [
406
+ {
407
+ action: "plugin::content-manager.explorer.update",
408
+ subject: contentTypeUid
409
+ }
410
+ ],
411
+ children: canUpdateEntryForLocale && /* @__PURE__ */ jsx(StyledMenuItem, { children: /* @__PURE__ */ jsx(
412
+ Link,
413
+ {
414
+ as: NavLink,
415
+ to: {
416
+ pathname: `/content-manager/collection-types/${contentTypeUid}/${entryId}`,
417
+ search: locale && `?plugins[i18n][locale]=${locale}`
418
+ },
419
+ startIcon: /* @__PURE__ */ jsx(Icon, { as: Pencil, padding: 1 }),
420
+ children: /* @__PURE__ */ jsx(Typography, { variant: "omega", children: formatMessage({
421
+ id: "content-releases.content-manager-edit-view.edit-entry",
422
+ defaultMessage: "Edit entry"
423
+ }) })
424
+ }
425
+ ) })
426
+ }
427
+ );
428
+ };
429
+ const Root = ({ children, hasTriggerBorder = false }) => {
430
+ const { formatMessage } = useIntl();
372
431
  return (
373
432
  // A user can access the dropdown if they have permissions to delete a release-action OR update a release
374
433
  /* @__PURE__ */ jsx(CheckPermissions, { permissions: [...PERMISSIONS.deleteAction, ...PERMISSIONS.update], children: /* @__PURE__ */ jsxs(Menu.Root, { children: [
375
434
  /* @__PURE__ */ jsx(
376
435
  Menu.Trigger,
377
436
  {
378
- as: IconButton,
437
+ as: hasTriggerBorder ? StyledIconButton : IconButton,
379
438
  paddingLeft: 2,
380
439
  paddingRight: 2,
381
440
  "aria-label": formatMessage({
@@ -385,16 +444,15 @@ const ReleaseActionMenu = ({ releaseId, actionId }) => {
385
444
  icon: /* @__PURE__ */ jsx(More, {})
386
445
  }
387
446
  ),
388
- /* @__PURE__ */ jsx(Menu.Content, { top: 1, children: /* @__PURE__ */ jsx(CheckPermissions, { permissions: PERMISSIONS.deleteAction, children: /* @__PURE__ */ jsx(StyledMenuItem, { color: "danger600", onSelect: handleDeleteAction, children: /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
389
- /* @__PURE__ */ jsx(StyledCross, {}),
390
- /* @__PURE__ */ jsx(Typography, { variant: "omega", children: formatMessage({
391
- id: "content-releases.content-manager-edit-view.remove-from-release",
392
- defaultMessage: "Remove from release"
393
- }) })
394
- ] }) }) }) })
447
+ /* @__PURE__ */ jsx(Menu.Content, { top: 1, popoverPlacement: "bottom-end", children })
395
448
  ] }) })
396
449
  );
397
450
  };
451
+ const ReleaseActionMenu = {
452
+ Root,
453
+ DeleteReleaseActionItem,
454
+ ReleaseActionEntryLinkItem
455
+ };
398
456
  const getBorderLeftRadiusValue = (actionType) => {
399
457
  return actionType === "publish" ? 1 : 0;
400
458
  };
@@ -500,7 +558,7 @@ const NoReleases = () => {
500
558
  to: {
501
559
  pathname: "/plugins/content-releases"
502
560
  },
503
- as: Link,
561
+ as: Link$1,
504
562
  variant: "secondary",
505
563
  children: formatMessage({
506
564
  id: "content-releases.content-manager-edit-view.add-to-release.redirect-button",
@@ -519,6 +577,7 @@ const AddActionToReleaseModal = ({
519
577
  const { formatMessage } = useIntl();
520
578
  const toggleNotification = useNotification();
521
579
  const { formatAPIError } = useAPIErrorHandler();
580
+ const { modifiedData } = useCMEditViewDataManager();
522
581
  const response = useGetReleasesForEntryQuery({
523
582
  contentTypeUid,
524
583
  entryId,
@@ -527,9 +586,11 @@ const AddActionToReleaseModal = ({
527
586
  const releases = response.data?.data;
528
587
  const [createReleaseAction, { isLoading }] = useCreateReleaseActionMutation();
529
588
  const handleSubmit = async (values) => {
589
+ const locale = modifiedData.locale;
530
590
  const releaseActionEntry = {
531
591
  contentType: contentTypeUid,
532
- id: entryId
592
+ id: entryId,
593
+ locale
533
594
  };
534
595
  const response2 = await createReleaseAction({
535
596
  body: { type: values.type, entry: releaseActionEntry },
@@ -717,7 +778,13 @@ const CMReleasesContainer = () => {
717
778
  ),
718
779
  /* @__PURE__ */ jsxs(Flex, { padding: 4, direction: "column", gap: 3, width: "100%", alignItems: "flex-start", children: [
719
780
  /* @__PURE__ */ jsx(Typography, { fontSize: 2, fontWeight: "bold", variant: "omega", textColor: "neutral700", children: release.name }),
720
- /* @__PURE__ */ jsx(ReleaseActionMenu, { releaseId: release.id, actionId: release.action.id })
781
+ /* @__PURE__ */ jsx(CheckPermissions, { permissions: PERMISSIONS.deleteAction, children: /* @__PURE__ */ jsx(ReleaseActionMenu.Root, { hasTriggerBorder: true, children: /* @__PURE__ */ jsx(
782
+ ReleaseActionMenu.DeleteReleaseActionItem,
783
+ {
784
+ releaseId: release.id,
785
+ actionId: release.action.id
786
+ }
787
+ ) }) })
721
788
  ] })
722
789
  ]
723
790
  },
@@ -756,7 +823,7 @@ const CMReleasesContainer = () => {
756
823
  const admin = {
757
824
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
758
825
  register(app) {
759
- if (window.strapi.features.isEnabled("cms-content-releases") && window.strapi.future.isEnabled("contentReleases")) {
826
+ if (window.strapi.features.isEnabled("cms-content-releases")) {
760
827
  app.addMenuLink({
761
828
  to: `/plugins/${pluginId}`,
762
829
  icon: PaperPlane,
@@ -765,7 +832,7 @@ const admin = {
765
832
  defaultMessage: "Releases"
766
833
  },
767
834
  async Component() {
768
- const { App } = await import("./App-a4843fda.mjs");
835
+ const { App } = await import("./App-L1jSxCiL.mjs");
769
836
  return App;
770
837
  },
771
838
  permissions: PERMISSIONS.main
@@ -783,7 +850,7 @@ const admin = {
783
850
  async registerTrads({ locales }) {
784
851
  const importedTrads = await Promise.all(
785
852
  locales.map((locale) => {
786
- return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => import("./en-e98d8b57.mjs") }), `./translations/${locale}.json`).then(({ default: data }) => {
853
+ return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => import("./en-MyLPoISH.mjs") }), `./translations/${locale}.json`).then(({ default: data }) => {
787
854
  return {
788
855
  data: prefixPluginTranslations(data, "content-releases"),
789
856
  locale
@@ -805,13 +872,16 @@ export {
805
872
  useUpdateReleaseMutation as a,
806
873
  useDeleteReleaseMutation as b,
807
874
  usePublishReleaseMutation as c,
808
- useGetReleaseActionsQuery as d,
809
- useUpdateReleaseActionMutation as e,
810
- useGetReleasesQuery as f,
811
- useCreateReleaseMutation as g,
812
- admin as h,
875
+ useTypedDispatch as d,
876
+ useGetReleaseActionsQuery as e,
877
+ useUpdateReleaseActionMutation as f,
878
+ ReleaseActionMenu as g,
879
+ useGetReleasesQuery as h,
813
880
  isAxiosError as i,
881
+ useCreateReleaseMutation as j,
882
+ admin as k,
814
883
  pluginId as p,
884
+ releaseApi as r,
815
885
  useGetReleaseQuery as u
816
886
  };
817
- //# sourceMappingURL=index-937f8179.mjs.map
887
+ //# sourceMappingURL=index-c4zRX_sg.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-c4zRX_sg.mjs","sources":["../../admin/src/constants.ts","../../admin/src/pluginId.ts","../../admin/src/services/axios.ts","../../admin/src/services/release.ts","../../admin/src/store/hooks.ts","../../admin/src/components/ReleaseActionMenu.tsx","../../admin/src/components/ReleaseActionOptions.tsx","../../admin/src/components/CMReleasesContainer.tsx","../../admin/src/index.ts"],"sourcesContent":["import { Permission as StrapiPermission } from '@strapi/helper-plugin';\n\nexport const PERMISSIONS = {\n main: [\n {\n action: 'plugin::content-releases.read',\n subject: null,\n id: '',\n actionParameters: {},\n properties: {},\n conditions: [],\n },\n ],\n create: [\n {\n action: 'plugin::content-releases.create',\n subject: null,\n id: '',\n actionParameters: {},\n properties: {},\n conditions: [],\n },\n ],\n update: [\n {\n action: 'plugin::content-releases.update',\n subject: null,\n id: '',\n actionParameters: {},\n properties: {},\n conditions: [],\n },\n ],\n delete: [\n {\n action: 'plugin::content-releases.delete',\n subject: null,\n id: '',\n actionParameters: {},\n properties: {},\n conditions: [],\n },\n ],\n createAction: [\n {\n action: 'plugin::content-releases.create-action',\n subject: null,\n id: '',\n actionParameters: {},\n properties: {},\n conditions: [],\n },\n ],\n deleteAction: [\n {\n action: 'plugin::content-releases.delete-action',\n subject: null,\n id: '',\n actionParameters: {},\n properties: {},\n conditions: [],\n },\n ],\n publish: [\n {\n action: 'plugin::content-releases.publish',\n subject: null,\n id: '',\n actionParameters: {},\n properties: {},\n conditions: [],\n },\n ],\n} satisfies Record<string, StrapiPermission[]>;\n","export const pluginId = 'content-releases';\n","import { getFetchClient } from '@strapi/helper-plugin';\n\nimport type { AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios';\n\n/* -------------------------------------------------------------------------------------------------\n * Axios data\n * -----------------------------------------------------------------------------------------------*/\nexport interface QueryArguments<TSend> {\n url: string;\n method: 'PUT' | 'GET' | 'POST' | 'DELETE';\n data?: TSend;\n config?: AxiosRequestConfig<TSend>;\n}\n\nconst axiosBaseQuery = async <TData = any, TSend = any>({\n url,\n method,\n data,\n config,\n}: QueryArguments<TSend>) => {\n try {\n const { get, post, del, put } = getFetchClient();\n\n if (method === 'POST') {\n const result = await post<TData, AxiosResponse<TData>, TSend>(url, data, config);\n return { data: result.data };\n }\n\n if (method === 'DELETE') {\n const result = await del<TData, AxiosResponse<TData>, TSend>(url, config);\n return { data: result.data };\n }\n\n if (method === 'PUT') {\n const result = await put<TData, AxiosResponse<TData>, TSend>(url, data, config);\n return { data: result.data };\n }\n\n /**\n * Default is GET.\n */\n const result = await get<TData, AxiosResponse<TData>, TSend>(url, config);\n return { data: result.data };\n } catch (error) {\n const err = error as AxiosError;\n /**\n * Handle error of type AxiosError\n *\n * This format mimics what we want from an AxiosError which is what the\n * rest of the app works with, except this format is \"serializable\" since\n * it goes into the redux store.\n *\n * NOTE – passing the whole response will highlight this \"serializability\" issue.\n */\n return {\n error: {\n status: err.response?.status,\n code: err.code,\n response: {\n data: err.response?.data,\n },\n },\n };\n }\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Axios error\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * This asserts the errors from redux-toolkit-query are\n * axios errors so we can pass them to our utility functions\n * to correctly render error messages.\n */\nconst isAxiosError = (err: unknown): err is AxiosError<{ error: any }> => {\n return (\n typeof err === 'object' &&\n err !== null &&\n 'response' in err &&\n typeof err.response === 'object' &&\n err.response !== null &&\n 'data' in err.response\n );\n};\n\nexport { isAxiosError, axiosBaseQuery };\n","import { createApi } from '@reduxjs/toolkit/query/react';\n\nimport {\n CreateReleaseAction,\n DeleteReleaseAction,\n} from '../../../shared/contracts/release-actions';\nimport { pluginId } from '../pluginId';\n\nimport { axiosBaseQuery } from './axios';\n\nimport type {\n GetReleaseActions,\n UpdateReleaseAction,\n ReleaseActionGroupBy,\n} from '../../../shared/contracts/release-actions';\nimport type {\n CreateRelease,\n DeleteRelease,\n GetContentTypeEntryReleases,\n GetReleases,\n UpdateRelease,\n GetRelease,\n PublishRelease,\n} from '../../../shared/contracts/releases';\n\nexport interface GetReleasesQueryParams {\n page?: number;\n pageSize?: number;\n filters?: {\n releasedAt?: {\n // TODO: this should be a boolean, find a way to avoid strings\n $notNull?: boolean | 'true' | 'false';\n };\n };\n}\n\nexport interface GetReleaseActionsQueryParams {\n page?: number;\n pageSize?: number;\n groupBy?: ReleaseActionGroupBy;\n}\n\ntype GetReleasesTabResponse = GetReleases.Response & {\n meta: {\n activeTab: 'pending' | 'done';\n };\n};\n\nconst releaseApi = createApi({\n reducerPath: pluginId,\n baseQuery: axiosBaseQuery,\n tagTypes: ['Release', 'ReleaseAction'],\n endpoints: (build) => {\n return {\n getReleasesForEntry: build.query<\n GetContentTypeEntryReleases.Response,\n Partial<GetContentTypeEntryReleases.Request['query']>\n >({\n query(params) {\n return {\n url: '/content-releases',\n method: 'GET',\n config: {\n params,\n },\n };\n },\n providesTags: (result) =>\n result\n ? [\n ...result.data.map(({ id }) => ({ type: 'Release' as const, id })),\n { type: 'Release', id: 'LIST' },\n ]\n : [],\n }),\n getReleases: build.query<GetReleasesTabResponse, GetReleasesQueryParams | void>({\n query(\n { page, pageSize, filters } = {\n page: 1,\n pageSize: 16,\n filters: {\n releasedAt: {\n $notNull: false,\n },\n },\n }\n ) {\n return {\n url: '/content-releases',\n method: 'GET',\n config: {\n params: {\n page: page || 1,\n pageSize: pageSize || 16,\n filters: filters || {\n releasedAt: {\n $notNull: false,\n },\n },\n },\n },\n };\n },\n transformResponse(response: GetReleasesTabResponse, meta, arg) {\n const releasedAtValue = arg?.filters?.releasedAt?.$notNull;\n const isActiveDoneTab = releasedAtValue === 'true';\n const newResponse: GetReleasesTabResponse = {\n ...response,\n meta: {\n ...response.meta,\n activeTab: isActiveDoneTab ? 'done' : 'pending',\n },\n };\n\n return newResponse;\n },\n providesTags: (result) =>\n result\n ? [\n ...result.data.map(({ id }) => ({ type: 'Release' as const, id })),\n { type: 'Release', id: 'LIST' },\n ]\n : [{ type: 'Release', id: 'LIST' }],\n }),\n getRelease: build.query<GetRelease.Response, GetRelease.Request['params']>({\n query({ id }) {\n return {\n url: `/content-releases/${id}`,\n method: 'GET',\n };\n },\n providesTags: (result, error, arg) => [{ type: 'Release' as const, id: arg.id }],\n }),\n getReleaseActions: build.query<\n GetReleaseActions.Response,\n GetReleaseActions.Request['params'] & GetReleaseActions.Request['query']\n >({\n query({ releaseId, ...params }) {\n return {\n url: `/content-releases/${releaseId}/actions`,\n method: 'GET',\n config: {\n params,\n },\n };\n },\n providesTags: [{ type: 'ReleaseAction', id: 'LIST' }],\n }),\n createRelease: build.mutation<CreateRelease.Response, CreateRelease.Request['body']>({\n query(data) {\n return {\n url: '/content-releases',\n method: 'POST',\n data,\n };\n },\n invalidatesTags: [{ type: 'Release', id: 'LIST' }],\n }),\n updateRelease: build.mutation<\n void,\n UpdateRelease.Request['params'] & UpdateRelease.Request['body']\n >({\n query({ id, ...data }) {\n return {\n url: `/content-releases/${id}`,\n method: 'PUT',\n data,\n };\n },\n invalidatesTags: (result, error, arg) => [{ type: 'Release', id: arg.id }],\n }),\n createReleaseAction: build.mutation<\n CreateReleaseAction.Response,\n CreateReleaseAction.Request\n >({\n query({ body, params }) {\n return {\n url: `/content-releases/${params.releaseId}/actions`,\n method: 'POST',\n data: body,\n };\n },\n invalidatesTags: [\n { type: 'Release', id: 'LIST' },\n { type: 'ReleaseAction', id: 'LIST' },\n ],\n }),\n updateReleaseAction: build.mutation<\n UpdateReleaseAction.Response,\n UpdateReleaseAction.Request\n >({\n query({ body, params }) {\n return {\n url: `/content-releases/${params.releaseId}/actions/${params.actionId}`,\n method: 'PUT',\n data: body,\n };\n },\n invalidatesTags: () => [{ type: 'ReleaseAction', id: 'LIST' }],\n }),\n deleteReleaseAction: build.mutation<\n DeleteReleaseAction.Response,\n DeleteReleaseAction.Request\n >({\n query({ params }) {\n return {\n url: `/content-releases/${params.releaseId}/actions/${params.actionId}`,\n method: 'DELETE',\n };\n },\n invalidatesTags: [\n { type: 'Release', id: 'LIST' },\n { type: 'ReleaseAction', id: 'LIST' },\n ],\n }),\n publishRelease: build.mutation<PublishRelease.Response, PublishRelease.Request['params']>({\n query({ id }) {\n return {\n url: `/content-releases/${id}/publish`,\n method: 'POST',\n };\n },\n invalidatesTags: (result, error, arg) => [{ type: 'Release', id: arg.id }],\n }),\n deleteRelease: build.mutation<DeleteRelease.Response, DeleteRelease.Request['params']>({\n query({ id }) {\n return {\n url: `/content-releases/${id}`,\n method: 'DELETE',\n };\n },\n invalidatesTags: (result, error, arg) => [{ type: 'Release', id: arg.id }],\n }),\n };\n },\n});\n\nconst {\n useGetReleasesQuery,\n useGetReleasesForEntryQuery,\n useGetReleaseQuery,\n useGetReleaseActionsQuery,\n useCreateReleaseMutation,\n useCreateReleaseActionMutation,\n useUpdateReleaseMutation,\n useUpdateReleaseActionMutation,\n usePublishReleaseMutation,\n useDeleteReleaseActionMutation,\n useDeleteReleaseMutation,\n} = releaseApi;\n\nexport {\n useGetReleasesQuery,\n useGetReleasesForEntryQuery,\n useGetReleaseQuery,\n useGetReleaseActionsQuery,\n useCreateReleaseMutation,\n useCreateReleaseActionMutation,\n useUpdateReleaseMutation,\n useUpdateReleaseActionMutation,\n usePublishReleaseMutation,\n useDeleteReleaseActionMutation,\n useDeleteReleaseMutation,\n releaseApi,\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 { Flex, IconButton, Typography, Icon } from '@strapi/design-system';\nimport { Menu, Link } from '@strapi/design-system/v2';\nimport { CheckPermissions, useAPIErrorHandler, useNotification } from '@strapi/helper-plugin';\nimport { Cross, More, Pencil } from '@strapi/icons';\nimport { isAxiosError } from 'axios';\nimport { useIntl } from 'react-intl';\nimport { NavLink } from 'react-router-dom';\nimport styled from 'styled-components';\n\nimport { DeleteReleaseAction, ReleaseAction } from '../../../shared/contracts/release-actions';\nimport { PERMISSIONS } from '../constants';\nimport { useDeleteReleaseActionMutation } from '../services/release';\nimport { useTypedSelector } from '../store/hooks';\n\nimport type { Permission } from '@strapi/helper-plugin';\n\nconst StyledMenuItem = styled(Menu.Item)<{ variant?: 'neutral' | 'danger' }>`\n &:hover {\n background: ${({ theme, variant = 'neutral' }) => theme.colors[`${variant}100`]};\n\n svg {\n path {\n fill: ${({ theme, variant = 'neutral' }) => theme.colors[`${variant}600`]};\n }\n }\n\n a {\n color: ${({ theme }) => theme.colors.neutral800};\n }\n }\n\n svg {\n path {\n fill: ${({ theme, variant = 'neutral' }) => theme.colors[`${variant}600`]};\n }\n }\n\n a {\n color: ${({ theme }) => theme.colors.neutral800};\n }\n\n span,\n a {\n width: 100%;\n }\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * DeleteReleaseActionItemProps\n * -----------------------------------------------------------------------------------------------*/\nconst StyledIconButton = styled(IconButton)`\n /* Setting this style inline with borderColor will not apply the style */\n border: ${({ theme }) => `1px solid ${theme.colors.neutral200}`};\n`;\ninterface DeleteReleaseActionItemProps {\n releaseId: DeleteReleaseAction.Request['params']['releaseId'];\n actionId: DeleteReleaseAction.Request['params']['actionId'];\n}\n\nconst DeleteReleaseActionItem = ({ releaseId, actionId }: DeleteReleaseActionItemProps) => {\n const { formatMessage } = useIntl();\n const toggleNotification = useNotification();\n const { formatAPIError } = useAPIErrorHandler();\n const [deleteReleaseAction] = useDeleteReleaseActionMutation();\n\n const handleDeleteAction = async () => {\n const response = await deleteReleaseAction({\n params: { releaseId, actionId },\n });\n\n if ('data' in response) {\n // Handle success\n toggleNotification({\n type: 'success',\n message: formatMessage({\n id: 'content-releases.content-manager-edit-view.remove-from-release.notification.success',\n defaultMessage: 'Entry removed from release',\n }),\n });\n\n return;\n }\n\n if ('error' in response) {\n if (isAxiosError(response.error)) {\n // Handle axios error\n toggleNotification({\n type: 'warning',\n message: formatAPIError(response.error),\n });\n } else {\n // Handle generic error\n toggleNotification({\n type: 'warning',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error occurred' }),\n });\n }\n }\n };\n\n return (\n <CheckPermissions permissions={PERMISSIONS.deleteAction}>\n <StyledMenuItem variant=\"danger\" onSelect={handleDeleteAction}>\n <Flex gap={2}>\n <Icon as={Cross} padding={1} />\n <Typography textColor=\"danger600\" variant=\"omega\">\n {formatMessage({\n id: 'content-releases.content-manager-edit-view.remove-from-release',\n defaultMessage: 'Remove from release',\n })}\n </Typography>\n </Flex>\n </StyledMenuItem>\n </CheckPermissions>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ReleaseActionEntryLinkItem\n * -----------------------------------------------------------------------------------------------*/\ninterface ReleaseActionEntryLinkItemProps {\n contentTypeUid: ReleaseAction['contentType'];\n entryId: ReleaseAction['entry']['id'];\n locale: ReleaseAction['locale'];\n}\n\nconst ReleaseActionEntryLinkItem = ({\n contentTypeUid,\n entryId,\n locale,\n}: ReleaseActionEntryLinkItemProps) => {\n const { formatMessage } = useIntl();\n // Confirm user has permissions to access the entry for the given locale\n const collectionTypePermissions = useTypedSelector(\n (state) => state.rbacProvider.collectionTypesRelatedPermissions\n );\n const updatePermissions = contentTypeUid\n ? collectionTypePermissions[contentTypeUid]?.['plugin::content-manager.explorer.update']\n : [];\n const canUpdateEntryForLocale = Boolean(\n !locale ||\n updatePermissions?.find((permission: Permission) =>\n permission.properties?.locales?.includes(locale)\n )\n );\n\n return (\n <CheckPermissions\n permissions={[\n {\n action: 'plugin::content-manager.explorer.update',\n subject: contentTypeUid,\n },\n ]}\n >\n {canUpdateEntryForLocale && (\n <StyledMenuItem>\n <Link\n as={NavLink}\n // @ts-expect-error TODO: This component from DS is not using types from NavLink\n to={{\n pathname: `/content-manager/collection-types/${contentTypeUid}/${entryId}`,\n search: locale && `?plugins[i18n][locale]=${locale}`,\n }}\n startIcon={<Icon as={Pencil} padding={1} />}\n >\n <Typography variant=\"omega\">\n {formatMessage({\n id: 'content-releases.content-manager-edit-view.edit-entry',\n defaultMessage: 'Edit entry',\n })}\n </Typography>\n </Link>\n </StyledMenuItem>\n )}\n </CheckPermissions>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Root\n * -----------------------------------------------------------------------------------------------*/\n\ninterface RootProps {\n children: React.ReactNode;\n hasTriggerBorder?: boolean;\n}\n\nconst Root = ({ children, hasTriggerBorder = false }: RootProps) => {\n const { formatMessage } = useIntl();\n\n return (\n // A user can access the dropdown if they have permissions to delete a release-action OR update a release\n <CheckPermissions permissions={[...PERMISSIONS.deleteAction, ...PERMISSIONS.update]}>\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={hasTriggerBorder ? StyledIconButton : IconButton}\n paddingLeft={2}\n paddingRight={2}\n aria-label={formatMessage({\n id: 'content-releases.content-manager-edit-view.release-action-menu',\n defaultMessage: 'Release action options',\n })}\n // @ts-expect-error See above\n icon={<More />}\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 {children}\n </Menu.Content>\n </Menu.Root>\n </CheckPermissions>\n );\n};\n\nexport const ReleaseActionMenu = {\n Root,\n DeleteReleaseActionItem,\n ReleaseActionEntryLinkItem,\n};\n","import * as React from 'react';\n\nimport {\n FieldInput,\n FieldLabel,\n VisuallyHidden,\n Field,\n Flex,\n type FieldProps,\n} from '@strapi/design-system';\nimport styled from 'styled-components';\n\ninterface FieldWrapperProps extends FieldProps {\n actionType: 'publish' | 'unpublish';\n}\n\nconst getBorderLeftRadiusValue = (actionType: FieldWrapperProps['actionType']) => {\n return actionType === 'publish' ? 1 : 0;\n};\n\nconst getBorderRightRadiusValue = (actionType: FieldWrapperProps['actionType']) => {\n return actionType === 'publish' ? 0 : 1;\n};\n\nconst FieldWrapper = styled(Field)<FieldWrapperProps>`\n border-top-left-radius: ${({ actionType, theme }) =>\n theme.spaces[getBorderLeftRadiusValue(actionType)]};\n border-bottom-left-radius: ${({ actionType, theme }) =>\n theme.spaces[getBorderLeftRadiusValue(actionType)]};\n border-top-right-radius: ${({ actionType, theme }) =>\n theme.spaces[getBorderRightRadiusValue(actionType)]};\n border-bottom-right-radius: ${({ actionType, theme }) =>\n theme.spaces[getBorderRightRadiusValue(actionType)]};\n\n > label {\n color: inherit;\n padding: ${({ theme }) => `${theme.spaces[2]} ${theme.spaces[3]}`};\n text-align: center;\n vertical-align: middle;\n text-transform: capitalize;\n }\n\n &:active,\n &[data-checked='true'] {\n color: ${({ theme }) => theme.colors.primary700};\n background-color: ${({ theme }) => theme.colors.primary100};\n border-color: ${({ theme }) => theme.colors.primary700};\n }\n\n &[data-checked='false'] {\n border-left: ${({ actionType }) => actionType === 'unpublish' && 'none'};\n border-right: ${({ actionType }) => actionType === 'publish' && 'none'};\n }\n`;\n\ninterface ActionOptionProps {\n selected: 'publish' | 'unpublish';\n handleChange: (e: React.ChangeEvent<HTMLInputElement>) => void;\n name: string;\n}\n\ninterface OptionProps extends ActionOptionProps {\n actionType: 'publish' | 'unpublish';\n}\n\nconst ActionOption = ({ selected, actionType, handleChange, name }: OptionProps) => {\n return (\n <FieldWrapper\n actionType={actionType}\n background=\"primary0\"\n borderColor=\"neutral200\"\n color={selected === actionType ? 'primary600' : 'neutral600'}\n position=\"relative\"\n cursor=\"pointer\"\n data-checked={selected === actionType}\n >\n <FieldLabel htmlFor={`${name}-${actionType}`}>\n <VisuallyHidden>\n <FieldInput\n type=\"radio\"\n id={`${name}-${actionType}`}\n name={name}\n checked={selected === actionType}\n onChange={handleChange}\n value={actionType}\n />\n </VisuallyHidden>\n {actionType}\n </FieldLabel>\n </FieldWrapper>\n );\n};\n\nexport const ReleaseActionOptions = ({ selected, handleChange, name }: ActionOptionProps) => {\n return (\n <Flex>\n <ActionOption\n actionType=\"publish\"\n selected={selected}\n handleChange={handleChange}\n name={name}\n />\n <ActionOption\n actionType=\"unpublish\"\n selected={selected}\n handleChange={handleChange}\n name={name}\n />\n </Flex>\n );\n};\n","import * as React from 'react';\n\nimport { skipToken } from '@reduxjs/toolkit/query';\nimport {\n Box,\n Button,\n FieldLabel,\n Flex,\n ModalBody,\n ModalHeader,\n ModalLayout,\n SingleSelect,\n SingleSelectOption,\n Typography,\n ModalFooter,\n} from '@strapi/design-system';\nimport { LinkButton } from '@strapi/design-system/v2';\nimport {\n CheckPermissions,\n NoContent,\n useAPIErrorHandler,\n useCMEditViewDataManager,\n useNotification,\n} from '@strapi/helper-plugin';\nimport { Plus } from '@strapi/icons';\nimport { isAxiosError } from 'axios';\nimport { Formik, Form } from 'formik';\nimport { useIntl } from 'react-intl';\nimport { useParams, Link as ReactRouterLink } from 'react-router-dom';\nimport * as yup from 'yup';\n\nimport { CreateReleaseAction } from '../../../shared/contracts/release-actions';\nimport { GetContentTypeEntryReleases } from '../../../shared/contracts/releases';\nimport { PERMISSIONS } from '../constants';\nimport { useCreateReleaseActionMutation, useGetReleasesForEntryQuery } from '../services/release';\n\nimport { ReleaseActionMenu } from './ReleaseActionMenu';\nimport { ReleaseActionOptions } from './ReleaseActionOptions';\n\n/* -------------------------------------------------------------------------------------------------\n * AddActionToReleaseModal\n * -----------------------------------------------------------------------------------------------*/\n\nconst RELEASE_ACTION_FORM_SCHEMA = yup.object().shape({\n type: yup.string().oneOf(['publish', 'unpublish']).required(),\n releaseId: yup.string().required(),\n});\n\ninterface FormValues {\n type: CreateReleaseAction.Request['body']['type'];\n releaseId: CreateReleaseAction.Request['params']['releaseId'];\n}\n\nconst INITIAL_VALUES = {\n type: 'publish',\n releaseId: '',\n} satisfies FormValues;\n\ninterface AddActionToReleaseModalProps {\n handleClose: () => void;\n contentTypeUid: GetContentTypeEntryReleases.Request['query']['contentTypeUid'];\n entryId: GetContentTypeEntryReleases.Request['query']['entryId'];\n}\n\nconst NoReleases = () => {\n const { formatMessage } = useIntl();\n return (\n <NoContent\n content={{\n id: 'content-releases.content-manager-edit-view.add-to-release.no-releases-message',\n defaultMessage:\n 'No available releases. Open the list of releases and create a new one from there.',\n }}\n action={\n <LinkButton\n // @ts-expect-error - types are not inferred correctly through the as prop.\n to={{\n pathname: '/plugins/content-releases',\n }}\n as={ReactRouterLink}\n variant=\"secondary\"\n >\n {formatMessage({\n id: 'content-releases.content-manager-edit-view.add-to-release.redirect-button',\n defaultMessage: 'Open the list of releases',\n })}\n </LinkButton>\n }\n />\n );\n};\n\nconst AddActionToReleaseModal = ({\n handleClose,\n contentTypeUid,\n entryId,\n}: AddActionToReleaseModalProps) => {\n const { formatMessage } = useIntl();\n const toggleNotification = useNotification();\n const { formatAPIError } = useAPIErrorHandler();\n const { modifiedData } = useCMEditViewDataManager();\n\n // Get all 'pending' releases that do not have the entry attached\n const response = useGetReleasesForEntryQuery({\n contentTypeUid,\n entryId,\n hasEntryAttached: false,\n });\n\n const releases = response.data?.data;\n const [createReleaseAction, { isLoading }] = useCreateReleaseActionMutation();\n\n const handleSubmit = async (values: FormValues) => {\n const locale = modifiedData.locale as string | undefined;\n const releaseActionEntry = {\n contentType: contentTypeUid,\n id: entryId,\n locale,\n };\n const response = await createReleaseAction({\n body: { type: values.type, entry: releaseActionEntry },\n params: { releaseId: values.releaseId },\n });\n\n if ('data' in response) {\n // Handle success\n toggleNotification({\n type: 'success',\n message: formatMessage({\n id: 'content-releases.content-manager-edit-view.add-to-release.notification.success',\n defaultMessage: 'Entry added to release',\n }),\n });\n\n handleClose();\n return;\n }\n\n if ('error' in response) {\n if (isAxiosError(response.error)) {\n // Handle axios error\n toggleNotification({\n type: 'warning',\n message: formatAPIError(response.error),\n });\n } else {\n // Handle generic error\n toggleNotification({\n type: 'warning',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error occurred' }),\n });\n }\n }\n };\n\n return (\n <ModalLayout onClose={handleClose} labelledBy=\"title\">\n <ModalHeader>\n <Typography id=\"title\" fontWeight=\"bold\" textColor=\"neutral800\">\n {formatMessage({\n id: 'content-releases.content-manager-edit-view.add-to-release',\n defaultMessage: 'Add to release',\n })}\n </Typography>\n </ModalHeader>\n <Formik\n onSubmit={handleSubmit}\n validationSchema={RELEASE_ACTION_FORM_SCHEMA}\n initialValues={INITIAL_VALUES}\n >\n {({ values, setFieldValue }) => {\n return (\n <Form>\n {releases?.length === 0 ? (\n <NoReleases />\n ) : (\n <ModalBody>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={2}>\n <Box paddingBottom={6}>\n <SingleSelect\n required\n label={formatMessage({\n id: 'content-releases.content-manager-edit-view.add-to-release.select-label',\n defaultMessage: 'Select a release',\n })}\n placeholder={formatMessage({\n id: 'content-releases.content-manager-edit-view.add-to-release.select-placeholder',\n defaultMessage: 'Select',\n })}\n onChange={(value) => setFieldValue('releaseId', value)}\n value={values.releaseId}\n >\n {releases?.map((release) => (\n <SingleSelectOption key={release.id} value={release.id}>\n {release.name}\n </SingleSelectOption>\n ))}\n </SingleSelect>\n </Box>\n <FieldLabel>\n {formatMessage({\n id: 'content-releases.content-manager-edit-view.add-to-release.action-type-label',\n defaultMessage: 'What do you want to do with this entry?',\n })}\n </FieldLabel>\n <ReleaseActionOptions\n selected={values.type}\n handleChange={(e) => setFieldValue('type', e.target.value)}\n name=\"type\"\n />\n </Flex>\n </ModalBody>\n )}\n <ModalFooter\n startActions={\n <Button onClick={handleClose} variant=\"tertiary\" name=\"cancel\">\n {formatMessage({\n id: 'content-releases.content-manager-edit-view.add-to-release.cancel-button',\n defaultMessage: 'Cancel',\n })}\n </Button>\n }\n endActions={\n /**\n * TODO: Ideally we would use isValid from Formik to disable the button, however currently it always returns true\n * for yup.string().required(), even when the value is falsy (including empty string)\n */\n <Button type=\"submit\" disabled={!values.releaseId} loading={isLoading}>\n {formatMessage({\n id: 'content-releases.content-manager-edit-view.add-to-release.continue-button',\n defaultMessage: 'Continue',\n })}\n </Button>\n }\n />\n </Form>\n );\n }}\n </Formik>\n </ModalLayout>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * CMReleasesContainer\n * -----------------------------------------------------------------------------------------------*/\n\nexport const CMReleasesContainer = () => {\n const [isModalOpen, setIsModalOpen] = React.useState(false);\n const { formatMessage } = useIntl();\n const {\n isCreatingEntry,\n allLayoutData: { contentType },\n } = useCMEditViewDataManager();\n const params = useParams<{ id: string }>();\n\n const canFetch = params?.id != null && contentType?.uid != null;\n const fetchParams = canFetch\n ? {\n contentTypeUid: contentType.uid,\n entryId: params.id,\n hasEntryAttached: true,\n }\n : skipToken;\n // Get all 'pending' releases that have the entry attached\n const response = useGetReleasesForEntryQuery(fetchParams);\n const releases = response.data?.data;\n\n /**\n * If we don't have a contentType.uid or params.id then the data was never fetched\n * TODO: Should we handle this with an error message in the UI or just not show the container?\n */\n if (!canFetch) {\n return null;\n }\n\n /**\n * - Impossible to add entry to release before it exists\n * - Content types without draft and publish cannot add entries to release\n * TODO v5: All contentTypes will have draft and publish enabled\n */\n if (isCreatingEntry || !contentType?.options?.draftAndPublish) {\n return null;\n }\n\n const toggleModal = () => setIsModalOpen((prev) => !prev);\n\n const getReleaseColorVariant = (\n actionType: 'publish' | 'unpublish',\n shade: '100' | '200' | '600'\n ) => {\n if (actionType === 'unpublish') {\n return `secondary${shade}`;\n }\n\n return `success${shade}`;\n };\n\n return (\n <CheckPermissions permissions={PERMISSIONS.main}>\n <Box\n as=\"aside\"\n aria-label={formatMessage({\n id: 'content-releases.plugin.name',\n defaultMessage: 'Releases',\n })}\n background=\"neutral0\"\n borderColor=\"neutral150\"\n hasRadius\n padding={4}\n shadow=\"tableShadow\"\n >\n <Flex direction=\"column\" alignItems=\"stretch\" gap={3}>\n <Typography variant=\"sigma\" textColor=\"neutral600\" textTransform=\"uppercase\">\n {formatMessage({\n id: 'content-releases.plugin.name',\n defaultMessage: 'Releases',\n })}\n </Typography>\n {releases?.map((release) => {\n return (\n <Flex\n key={release.id}\n direction=\"column\"\n alignItems=\"start\"\n borderWidth=\"1px\"\n borderStyle=\"solid\"\n borderColor={getReleaseColorVariant(release.action.type, '200')}\n overflow=\"hidden\"\n hasRadius\n >\n <Box\n paddingTop={3}\n paddingBottom={3}\n paddingLeft={4}\n paddingRight={4}\n background={getReleaseColorVariant(release.action.type, '100')}\n width=\"100%\"\n >\n <Typography\n fontSize={1}\n variant=\"pi\"\n textColor={getReleaseColorVariant(release.action.type, '600')}\n >\n {formatMessage(\n {\n id: 'content-releases.content-manager-edit-view.list-releases.title',\n defaultMessage:\n '{isPublish, select, true {Will be published in} other {Will be unpublished in}}',\n },\n { isPublish: release.action.type === 'publish' }\n )}\n </Typography>\n </Box>\n <Flex padding={4} direction=\"column\" gap={3} width=\"100%\" alignItems=\"flex-start\">\n <Typography fontSize={2} fontWeight=\"bold\" variant=\"omega\" textColor=\"neutral700\">\n {release.name}\n </Typography>\n <CheckPermissions permissions={PERMISSIONS.deleteAction}>\n <ReleaseActionMenu.Root hasTriggerBorder>\n <ReleaseActionMenu.DeleteReleaseActionItem\n releaseId={release.id}\n actionId={release.action.id}\n />\n </ReleaseActionMenu.Root>\n </CheckPermissions>\n </Flex>\n </Flex>\n );\n })}\n <CheckPermissions permissions={PERMISSIONS.createAction}>\n <Button\n justifyContent=\"center\"\n paddingLeft={4}\n paddingRight={4}\n color=\"neutral700\"\n variant=\"tertiary\"\n startIcon={<Plus />}\n onClick={toggleModal}\n >\n {formatMessage({\n id: 'content-releases.content-manager-edit-view.add-to-release',\n defaultMessage: 'Add to release',\n })}\n </Button>\n </CheckPermissions>\n </Flex>\n {isModalOpen && (\n <AddActionToReleaseModal\n handleClose={toggleModal}\n contentTypeUid={contentType.uid}\n entryId={params.id}\n />\n )}\n </Box>\n </CheckPermissions>\n );\n};\n","import { prefixPluginTranslations } from '@strapi/helper-plugin';\nimport { PaperPlane } from '@strapi/icons';\n\nimport { CMReleasesContainer } from './components/CMReleasesContainer';\nimport { PERMISSIONS } from './constants';\nimport { pluginId } from './pluginId';\nimport { releaseApi } from './services/release';\n\nimport type { Plugin } from '@strapi/types';\n\n// eslint-disable-next-line import/no-default-export\nconst admin: Plugin.Config.AdminInput = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n register(app: any) {\n if (window.strapi.features.isEnabled('cms-content-releases')) {\n app.addMenuLink({\n to: `/plugins/${pluginId}`,\n icon: PaperPlane,\n intlLabel: {\n id: `${pluginId}.plugin.name`,\n defaultMessage: 'Releases',\n },\n async Component() {\n const { App } = await import('./pages/App');\n return App;\n },\n permissions: PERMISSIONS.main,\n });\n\n /**\n * For some reason every middleware you pass has to a function\n * that returns the actual middleware. It's annoying but no one knows why....\n */\n app.addMiddlewares([() => releaseApi.middleware]);\n\n app.addReducers({\n [releaseApi.reducerPath]: releaseApi.reducer,\n });\n\n // Insert the Releases container in the 'right-links' zone of the Content Manager's edit view\n app.injectContentManagerComponent('editView', 'right-links', {\n name: `${pluginId}-link`,\n Component: CMReleasesContainer,\n });\n }\n },\n async registerTrads({ locales }: { locales: string[] }) {\n const importedTrads = await Promise.all(\n locales.map((locale) => {\n return import(`./translations/${locale}.json`)\n .then(({ default: data }) => {\n return {\n data: prefixPluginTranslations(data, 'content-releases'),\n locale,\n };\n })\n .catch(() => {\n return {\n data: {},\n locale,\n };\n });\n })\n );\n\n return Promise.resolve(importedTrads);\n },\n};\n\n// eslint-disable-next-line import/no-default-export\nexport default admin;\n"],"names":["result","isAxiosError","ReactRouterLink","response"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const index = require("../_chunks/index-66d129ac.js");
2
+ const index = require("../_chunks/index-KJa1Rb5F.js");
3
3
  require("@strapi/helper-plugin");
4
4
  require("@strapi/icons");
5
5
  require("react/jsx-runtime");
@@ -14,5 +14,6 @@ require("react-router-dom");
14
14
  require("yup");
15
15
  require("@reduxjs/toolkit/query/react");
16
16
  require("styled-components");
17
+ require("react-redux");
17
18
  module.exports = index.admin;
18
19
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;"}
@@ -1,4 +1,4 @@
1
- import { h } from "../_chunks/index-937f8179.mjs";
1
+ import { k } from "../_chunks/index-c4zRX_sg.mjs";
2
2
  import "@strapi/helper-plugin";
3
3
  import "@strapi/icons";
4
4
  import "react/jsx-runtime";
@@ -13,7 +13,8 @@ import "react-router-dom";
13
13
  import "yup";
14
14
  import "@reduxjs/toolkit/query/react";
15
15
  import "styled-components";
16
+ import "react-redux";
16
17
  export {
17
- h as default
18
+ k as default
18
19
  };
19
20
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;"}