From cdc3e01473f1c67900fd36640a6a913b9ccf78bc Mon Sep 17 00:00:00 2001 From: Nil20 Date: Wed, 10 Dec 2025 13:13:39 +0600 Subject: [PATCH 1/5] chore: add new icon to components and toolkit --- packages/commons/src/icons.ts | 1 + packages/components/src/Icon/all-icons.ts | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) 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/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' From 1e99cfd1cd34c1eb69c46a1f351ed0d029865d2f Mon Sep 17 00:00:00 2001 From: Nil20 Date: Wed, 10 Dec 2025 17:12:12 +0600 Subject: [PATCH 2/5] fix: handle multiple custom action scope types --- .../useAllowedActionConfigurations.tsx | 17 +++++++++++++- packages/commons/src/events/scopes.ts | 23 ++++++++++++++++--- packages/commons/src/scopes.ts | 2 +- 3 files changed, 37 insertions(+), 5 deletions(-) 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..7e006037ec4 100644 --- a/packages/commons/src/events/scopes.ts +++ b/packages/commons/src/events/scopes.ts @@ -13,8 +13,9 @@ import { ConfigurableScopeType, findScope, getAuthorizedEventsFromScopes, - RecordScopeType, - Scope + ConfigurableRawScopes, + Scope, + RecordScopeType } from '../scopes' import { ClientSpecificAction, @@ -65,7 +66,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 +76,21 @@ export function configurableEventScopeAllowed( // Ensure that the given event type is authorized in the found scopes const authorizedEvents = getAuthorizedEventsFromScopes(parsedScopes) + const firstScope = parsedScopes[0] as Extract< + ConfigurableRawScopes, + { type: 'record.custom-action' } + > + if ( + firstScope && + firstScope.type === 'record.custom-action' && + customActionType + ) { + // Type guard: only access customActionType if type is 'record.custom-action' + const allowedCustomActionTypes = firstScope.options.customActionType || [] + if (!allowedCustomActionTypes.includes(customActionType)) { + return false + } + } return authorizedEvents.includes(eventType) } 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 = { From 20696667a43d46093766401a3d22a2b066c4d549 Mon Sep 17 00:00:00 2001 From: Nil20 Date: Wed, 10 Dec 2025 18:21:49 +0600 Subject: [PATCH 3/5] fix: remove redundant type assertion --- packages/commons/src/events/scopes.ts | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/packages/commons/src/events/scopes.ts b/packages/commons/src/events/scopes.ts index 7e006037ec4..07710db5c66 100644 --- a/packages/commons/src/events/scopes.ts +++ b/packages/commons/src/events/scopes.ts @@ -13,7 +13,6 @@ import { ConfigurableScopeType, findScope, getAuthorizedEventsFromScopes, - ConfigurableRawScopes, Scope, RecordScopeType } from '../scopes' @@ -76,17 +75,13 @@ export function configurableEventScopeAllowed( // Ensure that the given event type is authorized in the found scopes const authorizedEvents = getAuthorizedEventsFromScopes(parsedScopes) - const firstScope = parsedScopes[0] as Extract< - ConfigurableRawScopes, - { type: 'record.custom-action' } - > + const firstScope = parsedScopes[0] if ( - firstScope && + parsedScopes.length > 0 && firstScope.type === 'record.custom-action' && customActionType ) { - // Type guard: only access customActionType if type is 'record.custom-action' - const allowedCustomActionTypes = firstScope.options.customActionType || [] + const allowedCustomActionTypes = firstScope.options.customActionType if (!allowedCustomActionTypes.includes(customActionType)) { return false } From f541439907b8c7f18d6241671e172cf7464839e9 Mon Sep 17 00:00:00 2001 From: Nil20 Date: Wed, 10 Dec 2025 18:46:05 +0600 Subject: [PATCH 4/5] fix: amend custom action type in event config for stories --- packages/client/.storybook/preview.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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', From 25b7b863eb3b6bcc3e6c3720dfc73aea46df6bae Mon Sep 17 00:00:00 2001 From: Nil20 Date: Thu, 11 Dec 2025 19:01:35 +0600 Subject: [PATCH 5/5] fix: add button id for next page id --- packages/components/src/Pagination/Pagination.tsx | 1 + 1 file changed, 1 insertion(+) 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 = ({ })}