diff --git a/packages/twenty-front/src/modules/action-menu/actions/components/Action.tsx b/packages/twenty-front/src/modules/action-menu/actions/components/Action.tsx index f68f703e6..6129626e2 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/components/Action.tsx +++ b/packages/twenty-front/src/modules/action-menu/actions/components/Action.tsx @@ -23,5 +23,5 @@ export const Action = ({ onClick(); }; - return ; + return ; }; diff --git a/packages/twenty-front/src/modules/action-menu/actions/components/ActionLink.tsx b/packages/twenty-front/src/modules/action-menu/actions/components/ActionLink.tsx index f4cb04f14..02acb2aa0 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/components/ActionLink.tsx +++ b/packages/twenty-front/src/modules/action-menu/actions/components/ActionLink.tsx @@ -1,8 +1,6 @@ import { ActionDisplay } from '@/action-menu/actions/display/components/ActionDisplay'; -import { ActionConfigContext } from '@/action-menu/contexts/ActionConfigContext'; import { useCloseActionMenu } from '@/action-menu/hooks/useCloseActionMenu'; import { AppPath } from '@/types/AppPath'; -import { useContext } from 'react'; import { PathParam } from 'react-router-dom'; import { getAppPath } from '~/utils/navigation/getAppPath'; @@ -15,21 +13,9 @@ export const ActionLink = ({ params?: { [key in PathParam]: string | null }; queryParams?: Record; }) => { - const actionConfig = useContext(ActionConfigContext); - const { closeActionMenu } = useCloseActionMenu(); - if (!actionConfig) { - return null; - } - const path = getAppPath(to, params, queryParams); - return ( - - ); + return ; }; diff --git a/packages/twenty-front/src/modules/action-menu/actions/components/ActionModal.tsx b/packages/twenty-front/src/modules/action-menu/actions/components/ActionModal.tsx index 81c488157..14787efc4 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/components/ActionModal.tsx +++ b/packages/twenty-front/src/modules/action-menu/actions/components/ActionModal.tsx @@ -46,7 +46,7 @@ export const ActionModal = ({ return ( <> - + {isOpen && createPortal( ; + return ; }; diff --git a/packages/twenty-front/src/modules/action-menu/actions/display/components/ActionDisplay.tsx b/packages/twenty-front/src/modules/action-menu/actions/display/components/ActionDisplay.tsx index 2b275c413..7f7563595 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/display/components/ActionDisplay.tsx +++ b/packages/twenty-front/src/modules/action-menu/actions/display/components/ActionDisplay.tsx @@ -1,6 +1,7 @@ import { ActionButton } from '@/action-menu/actions/display/components/ActionButton'; import { ActionDropdownItem } from '@/action-menu/actions/display/components/ActionDropdownItem'; import { ActionListItem } from '@/action-menu/actions/display/components/ActionListItem'; +import { ActionConfigContext } from '@/action-menu/contexts/ActionConfigContext'; import { ActionMenuContext } from '@/action-menu/contexts/ActionMenuContext'; import { MessageDescriptor } from '@lingui/core'; import { useContext } from 'react'; @@ -19,14 +20,13 @@ export type ActionDisplayProps = { }; export const ActionDisplay = ({ - action, onClick, to, }: { - action: ActionDisplayProps; onClick?: (event?: React.MouseEvent) => void; to?: string; }) => { + const action = useContext(ActionConfigContext); const { displayType } = useContext(ActionMenuContext); if (!action) { diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/workflow-run-record-actions/hooks/useWorkflowRunRecordActions.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/run-workflow-actions/hooks/useRunWorkflowRecordActions.tsx similarity index 93% rename from packages/twenty-front/src/modules/action-menu/actions/record-actions/workflow-run-record-actions/hooks/useWorkflowRunRecordActions.tsx rename to packages/twenty-front/src/modules/action-menu/actions/record-actions/run-workflow-actions/hooks/useRunWorkflowRecordActions.tsx index 2aa53da7f..400a28be5 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/workflow-run-record-actions/hooks/useWorkflowRunRecordActions.tsx +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/run-workflow-actions/hooks/useRunWorkflowRecordActions.tsx @@ -13,10 +13,12 @@ import { useRecoilValue } from 'recoil'; import { capitalize, isDefined } from 'twenty-shared/utils'; import { IconSettingsAutomation } from 'twenty-ui/display'; -export const useWorkflowRunRecordActions = ({ +export const useRunWorkflowRecordActions = ({ objectMetadataItem, + skip, }: { objectMetadataItem: ObjectMetadataItem; + skip?: boolean; }) => { const contextStoreTargetedRecordsRule = useRecoilComponentValueV2( contextStoreTargetedRecordsRuleComponentState, @@ -27,17 +29,14 @@ export const useWorkflowRunRecordActions = ({ ? contextStoreTargetedRecordsRule.selectedRecordIds[0] : undefined; - if (!isDefined(selectedRecordId)) { - throw new Error('Selected record ID is required'); - } - const selectedRecord = useRecoilValue( - recordStoreFamilyState(selectedRecordId), + recordStoreFamilyState(selectedRecordId ?? ''), ); const { records: activeWorkflowVersions } = useActiveWorkflowVersionsWithManualTrigger({ objectMetadataItem, + skip, }); const { runWorkflowVersion } = useRunWorkflowVersion(); diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/components/SeeActiveVersionWorkflowSingleRecordAction.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/components/SeeActiveVersionWorkflowSingleRecordAction.tsx index b82082ed0..9fd0032d8 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/components/SeeActiveVersionWorkflowSingleRecordAction.tsx +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/components/SeeActiveVersionWorkflowSingleRecordAction.tsx @@ -1,4 +1,5 @@ import { ActionLink } from '@/action-menu/actions/components/ActionLink'; +import { ActionDisplay } from '@/action-menu/actions/display/components/ActionDisplay'; import { useSelectedRecordIdOrThrow } from '@/action-menu/actions/record-actions/single-record/hooks/useSelectedRecordIdOrThrow'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { AppPath } from '@/types/AppPath'; @@ -7,14 +8,18 @@ import { useActiveWorkflowVersion } from '@/workflow/hooks/useActiveWorkflowVers export const SeeActiveVersionWorkflowSingleRecordAction = () => { const recordId = useSelectedRecordIdOrThrow(); - const workflowActiveVersion = useActiveWorkflowVersion(recordId); + const { workflowVersion, loading } = useActiveWorkflowVersion(recordId); + + if (loading) { + return ; + } return ( ); diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-agnostic-actions/run-workflow-actions/hooks/useRunWorkflowActions.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-agnostic-actions/run-workflow-actions/hooks/useRunWorkflowRecordAgnosticActions.tsx similarity index 68% rename from packages/twenty-front/src/modules/action-menu/actions/record-agnostic-actions/run-workflow-actions/hooks/useRunWorkflowActions.tsx rename to packages/twenty-front/src/modules/action-menu/actions/record-agnostic-actions/run-workflow-actions/hooks/useRunWorkflowRecordAgnosticActions.tsx index 1022ab19b..b68628c0b 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-agnostic-actions/run-workflow-actions/hooks/useRunWorkflowActions.tsx +++ b/packages/twenty-front/src/modules/action-menu/actions/record-agnostic-actions/run-workflow-actions/hooks/useRunWorkflowRecordAgnosticActions.tsx @@ -1,28 +1,37 @@ +import { Action } from '@/action-menu/actions/components/Action'; import { ActionScope } from '@/action-menu/actions/types/ActionScope'; import { ActionType } from '@/action-menu/actions/types/ActionType'; +import { ActionMenuContext } from '@/action-menu/contexts/ActionMenuContext'; import { useActiveWorkflowVersionsWithManualTrigger } from '@/workflow/hooks/useActiveWorkflowVersionsWithManualTrigger'; import { useRunWorkflowVersion } from '@/workflow/hooks/useRunWorkflowVersion'; import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; import { msg } from '@lingui/core/macro'; +import { useContext } from 'react'; import { capitalize, isDefined } from 'twenty-shared/utils'; import { IconSettingsAutomation } from 'twenty-ui/display'; import { FeatureFlagKey } from '~/generated/graphql'; -export const useRunWorkflowActions = () => { +export const useRunWorkflowRecordAgnosticActions = () => { const isWorkflowEnabled = useIsFeatureEnabled( FeatureFlagKey.IsWorkflowEnabled, ); + const { actionMenuType } = useContext(ActionMenuContext); + const { records: activeWorkflowVersions } = - useActiveWorkflowVersionsWithManualTrigger({}); + useActiveWorkflowVersionsWithManualTrigger({ + skip: + actionMenuType !== 'command-menu' && + actionMenuType !== 'command-menu-show-page-action-menu-dropdown', + }); const { runWorkflowVersion } = useRunWorkflowVersion(); if (!isWorkflowEnabled) { - return { runWorkflowActions: [] }; + return []; } - const runWorkflowActions = activeWorkflowVersions + return activeWorkflowVersions .map((activeWorkflowVersion, index) => { if (!isDefined(activeWorkflowVersion.workflow)) { return undefined; @@ -38,18 +47,16 @@ export const useRunWorkflowActions = () => { position: index, Icon: IconSettingsAutomation, shouldBeRegistered: () => true, - useAction: () => { - return { - onClick: async () => { - await runWorkflowVersion({ + component: ( + { + runWorkflowVersion({ workflowVersionId: activeWorkflowVersion.id, }); - }, - }; - }, + }} + /> + ), }; }) .filter(isDefined); - - return { runWorkflowActions }; }; diff --git a/packages/twenty-front/src/modules/action-menu/contexts/ActionMenuContextProvider.tsx b/packages/twenty-front/src/modules/action-menu/contexts/ActionMenuContextProvider.tsx index 60a8bdb82..164c03b60 100644 --- a/packages/twenty-front/src/modules/action-menu/contexts/ActionMenuContextProvider.tsx +++ b/packages/twenty-front/src/modules/action-menu/contexts/ActionMenuContextProvider.tsx @@ -1,10 +1,9 @@ import { ActionMenuContextType } from '@/action-menu/contexts/ActionMenuContext'; +import { ActionMenuContextProviderWorkflowObjects } from '@/action-menu/contexts/ActionMenuContextProviderWorkflowObjects'; import { ActionMenuContextProviderWorkflowsEnabled } from '@/action-menu/contexts/ActionMenuContextProviderWorkflowsEnabled'; -import { ActionMenuContextProviderWorkflowsEnabledSingleRecordSelection } from '@/action-menu/contexts/ActionMenuContextProviderWorkflowsEnabledSingleRecordSelection'; import { ActionMenuContextProviderWorkflowsNotEnabled } from '@/action-menu/contexts/ActionMenuContextProviderWorkflowsNotEnabled'; import { MAIN_CONTEXT_STORE_INSTANCE_ID } from '@/context-store/constants/MainContextStoreInstanceId'; import { contextStoreCurrentObjectMetadataItemIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataItemIdComponentState'; -import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState'; import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; @@ -50,39 +49,30 @@ export const ActionMenuContextProvider = ({ const objectMetadataItem = localContextStoreObjectMetadataItem ?? mainContextStoreObjectMetadataItem; - const contextStoreTargetedRecordsRule = useRecoilComponentValueV2( - contextStoreTargetedRecordsRuleComponentState, - ); - - const isSingleRecordSelection = - contextStoreTargetedRecordsRule.mode === 'selection' && - contextStoreTargetedRecordsRule.selectedRecordIds.length === 1; - const isWorkflowObject = objectMetadataItem?.nameSingular === CoreObjectNameSingular.Workflow || objectMetadataItem?.nameSingular === CoreObjectNameSingular.WorkflowRun || objectMetadataItem?.nameSingular === CoreObjectNameSingular.WorkflowVersion; - if ( - isWorkflowEnabled && - isSingleRecordSelection && - isDefined(objectMetadataItem) && - (actionMenuType === 'command-menu' || - actionMenuType === 'command-menu-show-page-action-menu-dropdown') - ) { + if (isWorkflowEnabled && isDefined(objectMetadataItem) && isWorkflowObject) { return ( - {children} - + ); } - if (isWorkflowEnabled && isDefined(objectMetadataItem) && isWorkflowObject) { + if ( + isWorkflowEnabled && + isDefined(objectMetadataItem) && + (actionMenuType === 'command-menu' || + actionMenuType === 'command-menu-show-page-action-menu-dropdown') + ) { return ( {children} diff --git a/packages/twenty-front/src/modules/action-menu/contexts/ActionMenuContextProviderWorkflowsEnabled.tsx b/packages/twenty-front/src/modules/action-menu/contexts/ActionMenuContextProviderWorkflowsEnabled.tsx index 727969dfa..ae2e6f730 100644 --- a/packages/twenty-front/src/modules/action-menu/contexts/ActionMenuContextProviderWorkflowsEnabled.tsx +++ b/packages/twenty-front/src/modules/action-menu/contexts/ActionMenuContextProviderWorkflowsEnabled.tsx @@ -1,10 +1,14 @@ +import { useRunWorkflowRecordActions } from '@/action-menu/actions/record-actions/run-workflow-actions/hooks/useRunWorkflowRecordActions'; +import { useRunWorkflowRecordAgnosticActions } from '@/action-menu/actions/record-agnostic-actions/run-workflow-actions/hooks/useRunWorkflowRecordAgnosticActions'; import { ActionMenuContext, ActionMenuContextType, } from '@/action-menu/contexts/ActionMenuContext'; import { useRegisteredActions } from '@/action-menu/hooks/useRegisteredActions'; import { useShouldActionBeRegisteredParams } from '@/action-menu/hooks/useShouldActionBeRegisteredParams'; +import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState'; import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; +import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion'; export const ActionMenuContextProviderWorkflowsEnabled = ({ @@ -35,13 +39,33 @@ export const ActionMenuContextProviderWorkflowsEnabled = ({ const actions = useRegisteredActions(shouldBeRegisteredParams); + const contextStoreTargetedRecordsRule = useRecoilComponentValueV2( + contextStoreTargetedRecordsRuleComponentState, + ); + + const isSingleRecordSelection = + contextStoreTargetedRecordsRule.mode === 'selection' && + contextStoreTargetedRecordsRule.selectedRecordIds.length === 1; + + const runWorkflowRecordActions = useRunWorkflowRecordActions({ + objectMetadataItem, + skip: !isSingleRecordSelection, + }); + + const runWorkflowRecordAgnosticActions = + useRunWorkflowRecordAgnosticActions(); + return ( {children} diff --git a/packages/twenty-front/src/modules/workflow/hooks/useActiveWorkflowVersion.ts b/packages/twenty-front/src/modules/workflow/hooks/useActiveWorkflowVersion.ts index 2722deeed..c70aed85f 100644 --- a/packages/twenty-front/src/modules/workflow/hooks/useActiveWorkflowVersion.ts +++ b/packages/twenty-front/src/modules/workflow/hooks/useActiveWorkflowVersion.ts @@ -3,7 +3,7 @@ import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords'; import { Workflow, WorkflowVersion } from '@/workflow/types/Workflow'; export const useActiveWorkflowVersion = (workflowId: string) => { - const { records: workflowVersions } = useFindManyRecords< + const { records: workflowVersions, loading } = useFindManyRecords< WorkflowVersion & { workflow: Omit & { versions: Array<{ __typename: string }>; @@ -39,5 +39,8 @@ export const useActiveWorkflowVersion = (workflowId: string) => { }, }); - return workflowVersions?.[0]; + return { + workflowVersion: workflowVersions?.[0], + loading, + }; }; diff --git a/packages/twenty-front/src/modules/workflow/hooks/useActiveWorkflowVersionsWithManualTrigger.ts b/packages/twenty-front/src/modules/workflow/hooks/useActiveWorkflowVersionsWithManualTrigger.ts index dbc49b004..d1ac17946 100644 --- a/packages/twenty-front/src/modules/workflow/hooks/useActiveWorkflowVersionsWithManualTrigger.ts +++ b/packages/twenty-front/src/modules/workflow/hooks/useActiveWorkflowVersionsWithManualTrigger.ts @@ -8,8 +8,10 @@ import { isDefined } from 'twenty-shared/utils'; export const useActiveWorkflowVersionsWithManualTrigger = ({ objectMetadataItem, + skip, }: { objectMetadataItem?: ObjectMetadataItem; + skip?: boolean; }) => { const filters = [ { @@ -50,6 +52,7 @@ export const useActiveWorkflowVersionsWithManualTrigger = ({ }), workflow: true, }, + skip, }); // TODO: refactor when we can use 'not like' in the RawJson filter