diff --git a/packages/client/.storybook/preview.tsx b/packages/client/.storybook/preview.tsx index 632628c4737..2152b7eceb4 100644 --- a/packages/client/.storybook/preview.tsx +++ b/packages/client/.storybook/preview.tsx @@ -172,7 +172,7 @@ const tennisClubMembershipEventWithCustomAction = { actions: tennisClubMembershipEvent.actions.concat([ { type: ActionType.CUSTOM, - customActionType: 'CONFIRM', + customActionType: 'Approve', label: { id: 'event.tennis-club-membership.action.confirm.label', defaultMessage: 'Confirm', diff --git a/packages/client/src/v2-events/features/workqueues/EventOverview/components/useAllowedActionConfigurations.tsx b/packages/client/src/v2-events/features/workqueues/EventOverview/components/useAllowedActionConfigurations.tsx index 3e97ea41c8d..7853ddf5953 100644 --- a/packages/client/src/v2-events/features/workqueues/EventOverview/components/useAllowedActionConfigurations.tsx +++ b/packages/client/src/v2-events/features/workqueues/EventOverview/components/useAllowedActionConfigurations.tsx @@ -577,6 +577,7 @@ function useCustomActionConfigs( customActionModal: React.ReactNode customActionConfigs: ActionMenuItem[] } { + // eslint-disable-next-line react-hooks/exhaustive-deps const scopes = useSelector(getScope) ?? [] const { eventConfiguration } = useEventConfiguration(event.type) const { customActionModal, onCustomAction } = useCustomActionModal(event) @@ -593,6 +594,14 @@ function useCustomActionConfigs( (action): action is CustomActionConfig => action.type === ActionType.CUSTOM ) + .filter((action) => + configurableEventScopeAllowed( + scopes, + ['record.custom-action'], + event.type, + action.customActionType + ) + ) .map((action) => ({ label: action.label, icon: action.icon ?? ('PencilLine' as const), @@ -603,7 +612,13 @@ function useCustomActionConfigs( type: ActionType.CUSTOM, customActionType: action.customActionType })) - }, [eventConfiguration, onCustomAction, isDownloadedAndAssignedToUser]) + }, [ + eventConfiguration.actions, + scopes, + event.type, + isDownloadedAndAssignedToUser, + onCustomAction + ]) const hasCustomActionScope = configurableEventScopeAllowed( scopes, diff --git a/packages/commons/src/events/scopes.ts b/packages/commons/src/events/scopes.ts index d75da355d15..07710db5c66 100644 --- a/packages/commons/src/events/scopes.ts +++ b/packages/commons/src/events/scopes.ts @@ -13,8 +13,8 @@ import { ConfigurableScopeType, findScope, getAuthorizedEventsFromScopes, - RecordScopeType, - Scope + Scope, + RecordScopeType } from '../scopes' import { ClientSpecificAction, @@ -65,7 +65,8 @@ export function hasAnyOfScopes(a: Scope[], b: Scope[]) { export function configurableEventScopeAllowed( scopes: Scope[], allowedConfigurableScopes: ConfigurableScopeType[], - eventType: string + eventType: string, + customActionType?: string ) { // Find the scopes that are authorized for the given action const parsedScopes = allowedConfigurableScopes @@ -74,6 +75,17 @@ export function configurableEventScopeAllowed( // Ensure that the given event type is authorized in the found scopes const authorizedEvents = getAuthorizedEventsFromScopes(parsedScopes) + const firstScope = parsedScopes[0] + if ( + parsedScopes.length > 0 && + firstScope.type === 'record.custom-action' && + customActionType + ) { + const allowedCustomActionTypes = firstScope.options.customActionType + if (!allowedCustomActionTypes.includes(customActionType)) { + return false + } + } return authorizedEvents.includes(eventType) } diff --git a/packages/commons/src/icons.ts b/packages/commons/src/icons.ts index b15d9384ab5..f801319531f 100644 --- a/packages/commons/src/icons.ts +++ b/packages/commons/src/icons.ts @@ -94,6 +94,7 @@ export const AvailableIcons = z.enum([ 'Users', 'WarningCircle', 'X', + 'ChatText', 'CircleWavyCheck', 'CircleWavyQuestion', 'ArchiveBox', diff --git a/packages/commons/src/scopes.ts b/packages/commons/src/scopes.ts index 0746b0fabbe..28f1c476e33 100644 --- a/packages/commons/src/scopes.ts +++ b/packages/commons/src/scopes.ts @@ -333,7 +333,7 @@ export const ConfigurableActionScopes = z.discriminatedUnion('type', [ CustomActionScope ]) -type ConfigurableRawScopes = z.infer +export type ConfigurableRawScopes = z.infer export type ConfigurableScopeType = ConfigurableRawScopes['type'] type FlattenedSearchScope = { diff --git a/packages/components/src/Icon/all-icons.ts b/packages/components/src/Icon/all-icons.ts index 11ff11811a9..0c1d8c381ee 100644 --- a/packages/components/src/Icon/all-icons.ts +++ b/packages/components/src/Icon/all-icons.ts @@ -92,6 +92,7 @@ export { WarningCircle, Webcam, X, - Stamp + Stamp, + ChatText } from 'phosphor-react' export * from './custom-icons' diff --git a/packages/components/src/Pagination/Pagination.tsx b/packages/components/src/Pagination/Pagination.tsx index 3cb56cf5375..18e8cc13520 100644 --- a/packages/components/src/Pagination/Pagination.tsx +++ b/packages/components/src/Pagination/Pagination.tsx @@ -187,6 +187,7 @@ export const Pagination = ({ })}