@strapi/content-releases 0.0.0-next.334c95408abdd9ecc0ece0e8c0fd5eb0024ad027 → 0.0.0-next.34a17e37276130e110099cd4bab2376d323ee689

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-vxli-E-l.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 <ReleaseActionMenu.Root hasTriggerBorder>\n <ReleaseActionMenu.DeleteReleaseActionItem\n releaseId={release.id}\n actionId={release.action.id}\n />\n </ReleaseActionMenu.Root>\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 (\n window.strapi.features.isEnabled('cms-content-releases') &&\n window.strapi.future.isEnabled('contentReleases')\n ) {\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":"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"}
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const index = require("../_chunks/index-FYDbIuRi.js");
2
+ const index = require("../_chunks/index-vxli-E-l.js");
3
3
  require("@strapi/helper-plugin");
4
4
  require("@strapi/icons");
5
5
  require("react/jsx-runtime");
@@ -13,7 +13,7 @@ require("react-intl");
13
13
  require("react-router-dom");
14
14
  require("yup");
15
15
  require("@reduxjs/toolkit/query/react");
16
- require("react-redux");
17
16
  require("styled-components");
17
+ require("react-redux");
18
18
  module.exports = index.admin;
19
19
  //# sourceMappingURL=index.js.map
@@ -1,4 +1,4 @@
1
- import { j } from "../_chunks/index-NFIckO1N.mjs";
1
+ import { k } from "../_chunks/index-ej8MzbQl.mjs";
2
2
  import "@strapi/helper-plugin";
3
3
  import "@strapi/icons";
4
4
  import "react/jsx-runtime";
@@ -12,9 +12,9 @@ import "react-intl";
12
12
  import "react-router-dom";
13
13
  import "yup";
14
14
  import "@reduxjs/toolkit/query/react";
15
- import "react-redux";
16
15
  import "styled-components";
16
+ import "react-redux";
17
17
  export {
18
- j as default
18
+ k as default
19
19
  };
20
20
  //# sourceMappingURL=index.mjs.map
@@ -247,13 +247,13 @@ const createReleaseActionService = ({ strapi: strapi2 }) => ({
247
247
  const getGroupName = (queryValue) => {
248
248
  switch (queryValue) {
249
249
  case "contentType":
250
- return "entry.contentType.displayName";
250
+ return "contentType.displayName";
251
251
  case "action":
252
252
  return "type";
253
253
  case "locale":
254
- return ___default.default.getOr("No locale", "entry.locale.name");
254
+ return ___default.default.getOr("No locale", "locale.name");
255
255
  default:
256
- return "entry.contentType.displayName";
256
+ return "contentType.displayName";
257
257
  }
258
258
  };
259
259
  const createReleaseService = ({ strapi: strapi2 }) => ({
@@ -281,51 +281,66 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
281
281
  }
282
282
  });
283
283
  },
284
- async findManyForContentTypeEntry(contentTypeUid, entryId, {
285
- hasEntryAttached
286
- } = {
287
- hasEntryAttached: false
288
- }) {
289
- const whereActions = hasEntryAttached ? {
290
- // Find all Releases where the content type entry is present
291
- actions: {
292
- target_type: contentTypeUid,
293
- target_id: entryId
294
- }
295
- } : {
296
- // Find all Releases where the content type entry is not present
297
- $or: [
298
- {
299
- $not: {
300
- actions: {
301
- target_type: contentTypeUid,
302
- target_id: entryId
303
- }
304
- }
284
+ async findManyWithContentTypeEntryAttached(contentTypeUid, entryId) {
285
+ const releases = await strapi2.db.query(RELEASE_MODEL_UID).findMany({
286
+ where: {
287
+ actions: {
288
+ target_type: contentTypeUid,
289
+ target_id: entryId
305
290
  },
306
- {
307
- actions: null
291
+ releasedAt: {
292
+ $null: true
308
293
  }
309
- ]
310
- };
311
- const populateAttachedAction = hasEntryAttached ? {
312
- // Filter the action to get only the content type entry
313
- actions: {
314
- where: {
294
+ },
295
+ populate: {
296
+ // Filter the action to get only the content type entry
297
+ actions: {
298
+ where: {
299
+ target_type: contentTypeUid,
300
+ target_id: entryId
301
+ }
302
+ }
303
+ }
304
+ });
305
+ return releases.map((release2) => {
306
+ if (release2.actions?.length) {
307
+ const [actionForEntry] = release2.actions;
308
+ delete release2.actions;
309
+ return {
310
+ ...release2,
311
+ action: actionForEntry
312
+ };
313
+ }
314
+ return release2;
315
+ });
316
+ },
317
+ async findManyWithoutContentTypeEntryAttached(contentTypeUid, entryId) {
318
+ const releasesRelated = await strapi2.db.query(RELEASE_MODEL_UID).findMany({
319
+ where: {
320
+ releasedAt: {
321
+ $null: true
322
+ },
323
+ actions: {
315
324
  target_type: contentTypeUid,
316
325
  target_id: entryId
317
326
  }
318
327
  }
319
- } : {};
328
+ });
320
329
  const releases = await strapi2.db.query(RELEASE_MODEL_UID).findMany({
321
330
  where: {
322
- ...whereActions,
331
+ $or: [
332
+ {
333
+ id: {
334
+ $notIn: releasesRelated.map((release2) => release2.id)
335
+ }
336
+ },
337
+ {
338
+ actions: null
339
+ }
340
+ ],
323
341
  releasedAt: {
324
342
  $null: true
325
343
  }
326
- },
327
- populate: {
328
- ...populateAttachedAction
329
344
  }
330
345
  });
331
346
  return releases.map((release2) => {
@@ -400,7 +415,9 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
400
415
  return strapi2.entityService.findPage(RELEASE_ACTION_MODEL_UID, {
401
416
  ...query,
402
417
  populate: {
403
- entry: true
418
+ entry: {
419
+ populate: "*"
420
+ }
404
421
  },
405
422
  filters: {
406
423
  release: releaseId
@@ -425,14 +442,11 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
425
442
  const { mainField, displayName } = allReleaseContentTypesDictionary[action.contentType];
426
443
  return {
427
444
  ...action,
428
- entry: {
429
- id: action.entry.id,
430
- contentType: {
431
- displayName,
432
- mainFieldValue: action.entry[mainField]
433
- },
434
- locale: action.locale ? allLocalesDictionary[action.locale] : null,
435
- status: action.entry.publishedAt ? "published" : "draft"
445
+ locale: action.locale ? allLocalesDictionary[action.locale] : null,
446
+ contentType: {
447
+ displayName,
448
+ mainFieldValue: action.entry[mainField],
449
+ uid: action.contentType
436
450
  }
437
451
  };
438
452
  });
@@ -463,6 +477,34 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
463
477
  }
464
478
  return contentTypesData;
465
479
  },
480
+ getContentTypeModelsFromActions(actions) {
481
+ const contentTypeUids = actions.reduce((acc, action) => {
482
+ if (!acc.includes(action.contentType)) {
483
+ acc.push(action.contentType);
484
+ }
485
+ return acc;
486
+ }, []);
487
+ const contentTypeModelsMap = contentTypeUids.reduce(
488
+ (acc, contentTypeUid) => {
489
+ acc[contentTypeUid] = strapi2.getModel(contentTypeUid);
490
+ return acc;
491
+ },
492
+ {}
493
+ );
494
+ return contentTypeModelsMap;
495
+ },
496
+ async getAllComponents() {
497
+ const contentManagerComponentsService = strapi2.plugin("content-manager").service("components");
498
+ const components = await contentManagerComponentsService.findAllComponents();
499
+ const componentsMap = components.reduce(
500
+ (acc, component) => {
501
+ acc[component.uid] = component;
502
+ return acc;
503
+ },
504
+ {}
505
+ );
506
+ return componentsMap;
507
+ },
466
508
  async delete(releaseId) {
467
509
  const release2 = await strapi2.entityService.findOne(RELEASE_MODEL_UID, releaseId, {
468
510
  populate: {
@@ -677,9 +719,7 @@ const releaseController = {
677
719
  const contentTypeUid = query.contentTypeUid;
678
720
  const entryId = query.entryId;
679
721
  const hasEntryAttached = typeof query.hasEntryAttached === "string" ? JSON.parse(query.hasEntryAttached) : false;
680
- const data = await releaseService.findManyForContentTypeEntry(contentTypeUid, entryId, {
681
- hasEntryAttached
682
- });
722
+ const data = hasEntryAttached ? await releaseService.findManyWithContentTypeEntryAttached(contentTypeUid, entryId) : await releaseService.findManyWithoutContentTypeEntryAttached(contentTypeUid, entryId);
683
723
  ctx.body = { data };
684
724
  } else {
685
725
  const query = await permissionsManager.sanitizeQuery(ctx.query);
@@ -807,11 +847,30 @@ const releaseActionController = {
807
847
  sort: query.groupBy === "action" ? "type" : query.groupBy,
808
848
  ...query
809
849
  });
810
- const groupedData = await releaseService.groupActions(results, query.groupBy);
850
+ const contentTypeOutputSanitizers = results.reduce((acc, action) => {
851
+ if (acc[action.contentType]) {
852
+ return acc;
853
+ }
854
+ const contentTypePermissionsManager = strapi.admin.services.permission.createPermissionsManager({
855
+ ability: ctx.state.userAbility,
856
+ model: action.contentType
857
+ });
858
+ acc[action.contentType] = contentTypePermissionsManager.sanitizeOutput;
859
+ return acc;
860
+ }, {});
861
+ const sanitizedResults = await utils.mapAsync(results, async (action) => ({
862
+ ...action,
863
+ entry: await contentTypeOutputSanitizers[action.contentType](action.entry)
864
+ }));
865
+ const groupedData = await releaseService.groupActions(sanitizedResults, query.groupBy);
866
+ const contentTypes2 = releaseService.getContentTypeModelsFromActions(results);
867
+ const components = await releaseService.getAllComponents();
811
868
  ctx.body = {
812
869
  data: groupedData,
813
870
  meta: {
814
- pagination
871
+ pagination,
872
+ contentTypes: contentTypes2,
873
+ components
815
874
  }
816
875
  };
817
876
  },