From d08075f610b92296114ffb4292a5a9927159b5f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Bosi?= <71827178+bosiraphael@users.noreply.github.com> Date: Fri, 20 Dec 2024 14:42:01 +0100 Subject: [PATCH] Command menu actions fixes (#9169) - Fix command menu not closing after executing an action - Add delete and favorite actions to workflow and workflow versions --- .../hooks/useExportMultipleRecordsAction.tsx | 15 +++- ...ingleRecordActionMenuEntrySetterEffect.tsx | 24 ++++-- ...ingleRecordActionMenuEntrySetterEffect.tsx | 25 ++++-- .../DefaultSingleRecordActionsConfigV1.ts | 4 +- .../DefaultSingleRecordActionsConfigV2.ts | 4 +- .../useAddToFavoritesSingleRecordAction.ts | 2 +- .../hooks/useDeleteSingleRecordAction.tsx | 2 +- .../hooks/useDestroySingleRecordAction.tsx | 6 +- ...eNavigateToNextRecordSingleRecordAction.ts | 2 +- ...igateToPreviousRecordSingleRecordAction.ts | 2 +- ...seRemoveFromFavoritesSingleRecordAction.ts | 2 +- .../WorkflowSingleRecordActionsConfig.ts | 73 ++++++++++++++++- ...ActivateDraftWorkflowSingleRecordAction.ts | 2 +- ...lishedVersionWorkflowSingleRecordAction.ts | 2 +- ...useDeactivateWorkflowSingleRecordAction.ts | 2 +- ...eDiscardDraftWorkflowSingleRecordAction.ts | 2 +- ...ActiveVersionWorkflowSingleRecordAction.ts | 2 +- .../useSeeRunsWorkflowSingleRecordAction.ts | 2 +- ...seSeeVersionsWorkflowSingleRecordAction.ts | 2 +- .../useTestWorkflowSingleRecordAction.ts | 2 +- ...rkflowVersionsSingleRecordActionsConfig.ts | 78 ++++++++++++++++++- ...eeRunsWorkflowVersionSingleRecordAction.ts | 2 +- ...rsionsWorkflowVersionSingleRecordAction.ts | 2 +- ...DraftWorkflowVersionSingleRecordAction.tsx | 2 +- ...ionAvailableOn.ts => ActionAvailableOn.ts} | 0 .../actions/types/ActionHookResult.ts | 7 ++ ...ctionHook.ts => SingleRecordActionHook.ts} | 2 +- .../actions/types/actionHookResult.ts | 5 -- .../actions/utils/wrapActionInCallbacks.ts | 40 ++++++++++ .../action-menu/contexts/ActionMenuContext.ts | 4 +- .../action-menu/types/ActionMenuEntry.ts | 5 +- 31 files changed, 269 insertions(+), 55 deletions(-) rename packages/twenty-front/src/modules/action-menu/actions/types/{actionAvailableOn.ts => ActionAvailableOn.ts} (100%) create mode 100644 packages/twenty-front/src/modules/action-menu/actions/types/ActionHookResult.ts rename packages/twenty-front/src/modules/action-menu/actions/types/{singleRecordActionHook.ts => SingleRecordActionHook.ts} (89%) delete mode 100644 packages/twenty-front/src/modules/action-menu/actions/types/actionHookResult.ts create mode 100644 packages/twenty-front/src/modules/action-menu/actions/utils/wrapActionInCallbacks.ts diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/hooks/useExportMultipleRecordsAction.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/hooks/useExportMultipleRecordsAction.tsx index 67d6482dbdb1..3b4d10bec890 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/hooks/useExportMultipleRecordsAction.tsx +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/hooks/useExportMultipleRecordsAction.tsx @@ -3,6 +3,7 @@ import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { IconDatabaseExport } from 'twenty-ui'; import { MultipleRecordsActionKeys } from '@/action-menu/actions/record-actions/multiple-records/types/MultipleRecordsActionKeys'; +import { ActionMenuContext } from '@/action-menu/contexts/ActionMenuContext'; import { ActionMenuEntryScope, ActionMenuEntryType, @@ -11,6 +12,7 @@ import { displayedExportProgress, useExportRecords, } from '@/object-record/record-index/export/hooks/useExportRecords'; +import { useContext } from 'react'; export const useExportMultipleRecordsAction = ({ objectMetadataItem, @@ -26,6 +28,9 @@ export const useExportMultipleRecordsAction = ({ filename: `${objectMetadataItem.nameSingular}.csv`, }); + const { onActionStartedCallback, onActionExecutedCallback } = + useContext(ActionMenuContext); + const registerExportMultipleRecordsAction = ({ position, }: { @@ -40,7 +45,15 @@ export const useExportMultipleRecordsAction = ({ shortLabel: 'Export', Icon: IconDatabaseExport, accent: 'default', - onClick: () => download(), + onClick: async () => { + await onActionStartedCallback?.({ + key: MultipleRecordsActionKeys.EXPORT, + }); + await download(); + await onActionExecutedCallback?.({ + key: MultipleRecordsActionKeys.EXPORT, + }); + }, }); }; diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/components/ShowPageSingleRecordActionMenuEntrySetterEffect.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/components/ShowPageSingleRecordActionMenuEntrySetterEffect.tsx index 65ad1000cb5c..c97b1d1df112 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/components/ShowPageSingleRecordActionMenuEntrySetterEffect.tsx +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/components/ShowPageSingleRecordActionMenuEntrySetterEffect.tsx @@ -1,11 +1,13 @@ import { getActionConfig } from '@/action-menu/actions/record-actions/single-record/utils/getActionConfig'; -import { ActionAvailableOn } from '@/action-menu/actions/types/actionAvailableOn'; +import { ActionAvailableOn } from '@/action-menu/actions/types/ActionAvailableOn'; +import { wrapActionInCallbacks } from '@/action-menu/actions/utils/wrapActionInCallbacks'; +import { ActionMenuContext } from '@/action-menu/contexts/ActionMenuContext'; import { useActionMenuEntries } from '@/action-menu/hooks/useActionMenuEntries'; 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 { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; -import { useEffect } from 'react'; +import { useContext, useEffect } from 'react'; import { isDefined } from 'twenty-ui'; export const ShowPageSingleRecordActionMenuEntrySetterEffect = ({ @@ -36,6 +38,8 @@ export const ShowPageSingleRecordActionMenuEntrySetterEffect = ({ if (!isDefined(selectedRecordId)) { throw new Error('Selected record ID is required'); } + const { onActionStartedCallback, onActionExecutedCallback } = + useContext(ActionMenuContext); const actionMenuEntries = Object.values(actionConfig ?? {}) .filter((action) => @@ -48,15 +52,21 @@ export const ShowPageSingleRecordActionMenuEntrySetterEffect = ({ objectMetadataItem, }); - if (shouldBeRegistered) { - return { + if (!shouldBeRegistered) { + return undefined; + } + + const wrappedAction = wrapActionInCallbacks({ + action: { ...action, onClick, ConfirmationModal, - }; - } + }, + onActionStartedCallback, + onActionExecutedCallback, + }); - return undefined; + return wrappedAction; }) .filter(isDefined); diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/components/SingleRecordActionMenuEntrySetterEffect.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/components/SingleRecordActionMenuEntrySetterEffect.tsx index 9238772a669c..296459dc5751 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/components/SingleRecordActionMenuEntrySetterEffect.tsx +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/components/SingleRecordActionMenuEntrySetterEffect.tsx @@ -1,11 +1,13 @@ import { getActionConfig } from '@/action-menu/actions/record-actions/single-record/utils/getActionConfig'; -import { ActionAvailableOn } from '@/action-menu/actions/types/actionAvailableOn'; +import { ActionAvailableOn } from '@/action-menu/actions/types/ActionAvailableOn'; +import { wrapActionInCallbacks } from '@/action-menu/actions/utils/wrapActionInCallbacks'; +import { ActionMenuContext } from '@/action-menu/contexts/ActionMenuContext'; import { useActionMenuEntries } from '@/action-menu/hooks/useActionMenuEntries'; 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 { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; -import { useEffect } from 'react'; +import { useContext, useEffect } from 'react'; import { isDefined } from 'twenty-ui'; export const SingleRecordActionMenuEntrySetterEffect = ({ @@ -37,6 +39,9 @@ export const SingleRecordActionMenuEntrySetterEffect = ({ throw new Error('Selected record ID is required'); } + const { onActionStartedCallback, onActionExecutedCallback } = + useContext(ActionMenuContext); + const actionMenuEntries = Object.values(actionConfig ?? {}) .filter((action) => action.availableOn?.includes( @@ -50,15 +55,21 @@ export const SingleRecordActionMenuEntrySetterEffect = ({ objectMetadataItem, }); - if (shouldBeRegistered) { - return { + if (!shouldBeRegistered) { + return undefined; + } + + const wrappedAction = wrapActionInCallbacks({ + action: { ...action, onClick, ConfirmationModal, - }; - } + }, + onActionStartedCallback, + onActionExecutedCallback, + }); - return undefined; + return wrappedAction; }) .filter(isDefined); diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/constants/DefaultSingleRecordActionsConfigV1.ts b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/constants/DefaultSingleRecordActionsConfigV1.ts index 727ff0255831..778fdea06a73 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/constants/DefaultSingleRecordActionsConfigV1.ts +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/constants/DefaultSingleRecordActionsConfigV1.ts @@ -2,8 +2,8 @@ import { useAddToFavoritesSingleRecordAction } from '@/action-menu/actions/recor import { useDeleteSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useDeleteSingleRecordAction'; import { useRemoveFromFavoritesSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useRemoveFromFavoritesSingleRecordAction'; import { SingleRecordActionKeys } from '@/action-menu/actions/record-actions/single-record/types/SingleRecordActionsKey'; -import { ActionAvailableOn } from '@/action-menu/actions/types/actionAvailableOn'; -import { SingleRecordActionHook } from '@/action-menu/actions/types/singleRecordActionHook'; +import { ActionAvailableOn } from '@/action-menu/actions/types/ActionAvailableOn'; +import { SingleRecordActionHook } from '@/action-menu/actions/types/SingleRecordActionHook'; import { ActionMenuEntry, ActionMenuEntryScope, diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/constants/DefaultSingleRecordActionsConfigV2.ts b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/constants/DefaultSingleRecordActionsConfigV2.ts index d55a4b1e7699..1cf13d116321 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/constants/DefaultSingleRecordActionsConfigV2.ts +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/constants/DefaultSingleRecordActionsConfigV2.ts @@ -5,8 +5,8 @@ import { useNavigateToNextRecordSingleRecordAction } from '@/action-menu/actions import { useNavigateToPreviousRecordSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useNavigateToPreviousRecordSingleRecordAction'; import { useRemoveFromFavoritesSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useRemoveFromFavoritesSingleRecordAction'; import { SingleRecordActionKeys } from '@/action-menu/actions/record-actions/single-record/types/SingleRecordActionsKey'; -import { ActionAvailableOn } from '@/action-menu/actions/types/actionAvailableOn'; -import { SingleRecordActionHook } from '@/action-menu/actions/types/singleRecordActionHook'; +import { ActionAvailableOn } from '@/action-menu/actions/types/ActionAvailableOn'; +import { SingleRecordActionHook } from '@/action-menu/actions/types/SingleRecordActionHook'; import { ActionMenuEntry, ActionMenuEntryScope, diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useAddToFavoritesSingleRecordAction.ts b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useAddToFavoritesSingleRecordAction.ts index 88c8f4c1928e..ec3f6ddf042d 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useAddToFavoritesSingleRecordAction.ts +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useAddToFavoritesSingleRecordAction.ts @@ -1,4 +1,4 @@ -import { SingleRecordActionHookWithObjectMetadataItem } from '@/action-menu/actions/types/singleRecordActionHook'; +import { SingleRecordActionHookWithObjectMetadataItem } from '@/action-menu/actions/types/SingleRecordActionHook'; import { useCreateFavorite } from '@/favorites/hooks/useCreateFavorite'; import { useFavorites } from '@/favorites/hooks/useFavorites'; import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useDeleteSingleRecordAction.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useDeleteSingleRecordAction.tsx index 6adbbab02db7..e499c72d062a 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useDeleteSingleRecordAction.tsx +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useDeleteSingleRecordAction.tsx @@ -1,4 +1,4 @@ -import { SingleRecordActionHookWithObjectMetadataItem } from '@/action-menu/actions/types/singleRecordActionHook'; +import { SingleRecordActionHookWithObjectMetadataItem } from '@/action-menu/actions/types/SingleRecordActionHook'; import { ActionMenuContext } from '@/action-menu/contexts/ActionMenuContext'; import { useDeleteFavorite } from '@/favorites/hooks/useDeleteFavorite'; import { useFavorites } from '@/favorites/hooks/useFavorites'; diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useDestroySingleRecordAction.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useDestroySingleRecordAction.tsx index e9e37d822e86..85bcf89e861f 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useDestroySingleRecordAction.tsx +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useDestroySingleRecordAction.tsx @@ -1,4 +1,4 @@ -import { SingleRecordActionHookWithObjectMetadataItem } from '@/action-menu/actions/types/singleRecordActionHook'; +import { SingleRecordActionHookWithObjectMetadataItem } from '@/action-menu/actions/types/SingleRecordActionHook'; import { ActionMenuContext } from '@/action-menu/contexts/ActionMenuContext'; import { useDestroyOneRecord } from '@/object-record/hooks/useDestroyOneRecord'; import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; @@ -34,8 +34,7 @@ export const useDestroySingleRecordAction: SingleRecordActionHookWithObjectMetad const isRemoteObject = objectMetadataItem.isRemote; - const { isInRightDrawer, onActionExecutedCallback } = - useContext(ActionMenuContext); + const { isInRightDrawer } = useContext(ActionMenuContext); const shouldBeRegistered = !isRemoteObject && isDefined(selectedRecord?.deletedAt); @@ -61,7 +60,6 @@ export const useDestroySingleRecordAction: SingleRecordActionHookWithObjectMetad } onConfirmClick={async () => { await handleDeleteClick(); - onActionExecutedCallback?.({ key: 'destroy-single-record' }); if (isInRightDrawer) { closeRightDrawer(); } diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useNavigateToNextRecordSingleRecordAction.ts b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useNavigateToNextRecordSingleRecordAction.ts index a775d5275b79..77a4f9acff95 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useNavigateToNextRecordSingleRecordAction.ts +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useNavigateToNextRecordSingleRecordAction.ts @@ -1,4 +1,4 @@ -import { SingleRecordActionHookWithObjectMetadataItem } from '@/action-menu/actions/types/singleRecordActionHook'; +import { SingleRecordActionHookWithObjectMetadataItem } from '@/action-menu/actions/types/SingleRecordActionHook'; import { useRecordShowPagePagination } from '@/object-record/record-show/hooks/useRecordShowPagePagination'; export const useNavigateToNextRecordSingleRecordAction: SingleRecordActionHookWithObjectMetadataItem = diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useNavigateToPreviousRecordSingleRecordAction.ts b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useNavigateToPreviousRecordSingleRecordAction.ts index f1287a68fee4..25000420c928 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useNavigateToPreviousRecordSingleRecordAction.ts +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useNavigateToPreviousRecordSingleRecordAction.ts @@ -1,4 +1,4 @@ -import { SingleRecordActionHookWithObjectMetadataItem } from '@/action-menu/actions/types/singleRecordActionHook'; +import { SingleRecordActionHookWithObjectMetadataItem } from '@/action-menu/actions/types/SingleRecordActionHook'; import { useRecordShowPagePagination } from '@/object-record/record-show/hooks/useRecordShowPagePagination'; export const useNavigateToPreviousRecordSingleRecordAction: SingleRecordActionHookWithObjectMetadataItem = diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useRemoveFromFavoritesSingleRecordAction.ts b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useRemoveFromFavoritesSingleRecordAction.ts index 28382e42528e..57802d53957d 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useRemoveFromFavoritesSingleRecordAction.ts +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useRemoveFromFavoritesSingleRecordAction.ts @@ -1,4 +1,4 @@ -import { SingleRecordActionHookWithObjectMetadataItem } from '@/action-menu/actions/types/singleRecordActionHook'; +import { SingleRecordActionHookWithObjectMetadataItem } from '@/action-menu/actions/types/SingleRecordActionHook'; import { useDeleteFavorite } from '@/favorites/hooks/useDeleteFavorite'; import { useFavorites } from '@/favorites/hooks/useFavorites'; import { isDefined } from 'twenty-ui'; diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/constants/WorkflowSingleRecordActionsConfig.ts b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/constants/WorkflowSingleRecordActionsConfig.ts index da1176161215..b672ec5e82c8 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/constants/WorkflowSingleRecordActionsConfig.ts +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/constants/WorkflowSingleRecordActionsConfig.ts @@ -1,5 +1,9 @@ +import { useAddToFavoritesSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useAddToFavoritesSingleRecordAction'; +import { useDeleteSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useDeleteSingleRecordAction'; +import { useDestroySingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useDestroySingleRecordAction'; import { useNavigateToNextRecordSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useNavigateToNextRecordSingleRecordAction'; import { useNavigateToPreviousRecordSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useNavigateToPreviousRecordSingleRecordAction'; +import { useRemoveFromFavoritesSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useRemoveFromFavoritesSingleRecordAction'; import { SingleRecordActionKeys } from '@/action-menu/actions/record-actions/single-record/types/SingleRecordActionsKey'; import { useActivateDraftWorkflowSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useActivateDraftWorkflowSingleRecordAction'; import { useActivateLastPublishedVersionWorkflowSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useActivateLastPublishedVersionWorkflowSingleRecordAction'; @@ -10,8 +14,8 @@ import { useSeeRunsWorkflowSingleRecordAction } from '@/action-menu/actions/reco import { useSeeVersionsWorkflowSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useSeeVersionsWorkflowSingleRecordAction'; import { useTestWorkflowSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useTestWorkflowSingleRecordAction'; import { WorkflowSingleRecordActionKeys } from '@/action-menu/actions/record-actions/single-record/workflow-actions/types/WorkflowSingleRecordActionsKeys'; -import { ActionAvailableOn } from '@/action-menu/actions/types/actionAvailableOn'; -import { SingleRecordActionHook } from '@/action-menu/actions/types/singleRecordActionHook'; +import { ActionAvailableOn } from '@/action-menu/actions/types/ActionAvailableOn'; +import { SingleRecordActionHook } from '@/action-menu/actions/types/SingleRecordActionHook'; import { ActionMenuEntry, ActionMenuEntryScope, @@ -20,12 +24,15 @@ import { import { IconChevronDown, IconChevronUp, + IconHeart, + IconHeartOff, IconHistory, IconHistoryToggle, IconPlayerPause, IconPlayerPlay, IconPower, IconTrash, + IconTrashX, } from 'twenty-ui'; export const WORKFLOW_SINGLE_RECORD_ACTIONS_CONFIG: Record< @@ -176,4 +183,66 @@ export const WORKFLOW_SINGLE_RECORD_ACTIONS_CONFIG: Record< availableOn: [ActionAvailableOn.SHOW_PAGE], actionHook: useNavigateToNextRecordSingleRecordAction, }, + addToFavoritesSingleRecord: { + type: ActionMenuEntryType.Standard, + scope: ActionMenuEntryScope.RecordSelection, + key: SingleRecordActionKeys.ADD_TO_FAVORITES, + label: 'Add to favorites', + shortLabel: 'Add to favorites', + position: 11, + isPinned: false, + Icon: IconHeart, + availableOn: [ + ActionAvailableOn.INDEX_PAGE_SINGLE_RECORD_SELECTION, + ActionAvailableOn.SHOW_PAGE, + ], + actionHook: useAddToFavoritesSingleRecordAction, + }, + removeFromFavoritesSingleRecord: { + type: ActionMenuEntryType.Standard, + scope: ActionMenuEntryScope.RecordSelection, + key: SingleRecordActionKeys.REMOVE_FROM_FAVORITES, + label: 'Remove from favorites', + shortLabel: 'Remove from favorites', + isPinned: false, + position: 12, + Icon: IconHeartOff, + availableOn: [ + ActionAvailableOn.INDEX_PAGE_SINGLE_RECORD_SELECTION, + ActionAvailableOn.SHOW_PAGE, + ], + actionHook: useRemoveFromFavoritesSingleRecordAction, + }, + deleteSingleRecord: { + type: ActionMenuEntryType.Standard, + scope: ActionMenuEntryScope.RecordSelection, + key: SingleRecordActionKeys.DELETE, + label: 'Delete record', + shortLabel: 'Delete', + position: 13, + Icon: IconTrash, + accent: 'danger', + isPinned: false, + availableOn: [ + ActionAvailableOn.INDEX_PAGE_SINGLE_RECORD_SELECTION, + ActionAvailableOn.SHOW_PAGE, + ], + actionHook: useDeleteSingleRecordAction, + }, + destroySingleRecord: { + type: ActionMenuEntryType.Standard, + scope: ActionMenuEntryScope.RecordSelection, + key: SingleRecordActionKeys.DESTROY, + label: 'Permanently destroy record', + shortLabel: 'Destroy', + position: 14, + Icon: IconTrashX, + accent: 'danger', + isPinned: false, + availableOn: [ + ActionAvailableOn.INDEX_PAGE_SINGLE_RECORD_SELECTION, + ActionAvailableOn.SHOW_PAGE, + ], + actionHook: useDestroySingleRecordAction, + }, }; diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useActivateDraftWorkflowSingleRecordAction.ts b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useActivateDraftWorkflowSingleRecordAction.ts index 79bf61a3c07a..280aa8019c04 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useActivateDraftWorkflowSingleRecordAction.ts +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useActivateDraftWorkflowSingleRecordAction.ts @@ -1,4 +1,4 @@ -import { SingleRecordActionHookWithoutObjectMetadataItem } from '@/action-menu/actions/types/singleRecordActionHook'; +import { SingleRecordActionHookWithoutObjectMetadataItem } from '@/action-menu/actions/types/SingleRecordActionHook'; import { useActivateWorkflowVersion } from '@/workflow/hooks/useActivateWorkflowVersion'; import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion'; import { isDefined } from 'twenty-ui'; diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useActivateLastPublishedVersionWorkflowSingleRecordAction.ts b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useActivateLastPublishedVersionWorkflowSingleRecordAction.ts index c107d3d51fd1..32f84f6736cb 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useActivateLastPublishedVersionWorkflowSingleRecordAction.ts +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useActivateLastPublishedVersionWorkflowSingleRecordAction.ts @@ -1,4 +1,4 @@ -import { SingleRecordActionHookWithoutObjectMetadataItem } from '@/action-menu/actions/types/singleRecordActionHook'; +import { SingleRecordActionHookWithoutObjectMetadataItem } from '@/action-menu/actions/types/SingleRecordActionHook'; import { useActivateWorkflowVersion } from '@/workflow/hooks/useActivateWorkflowVersion'; import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion'; import { isDefined } from 'twenty-ui'; diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useDeactivateWorkflowSingleRecordAction.ts b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useDeactivateWorkflowSingleRecordAction.ts index 731bd6a4f4d6..dd61f50de5eb 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useDeactivateWorkflowSingleRecordAction.ts +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useDeactivateWorkflowSingleRecordAction.ts @@ -1,4 +1,4 @@ -import { SingleRecordActionHookWithoutObjectMetadataItem } from '@/action-menu/actions/types/singleRecordActionHook'; +import { SingleRecordActionHookWithoutObjectMetadataItem } from '@/action-menu/actions/types/SingleRecordActionHook'; import { useDeactivateWorkflowVersion } from '@/workflow/hooks/useDeactivateWorkflowVersion'; import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion'; import { isDefined } from 'twenty-ui'; diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useDiscardDraftWorkflowSingleRecordAction.ts b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useDiscardDraftWorkflowSingleRecordAction.ts index d91532c3bac6..a1fe61b51eca 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useDiscardDraftWorkflowSingleRecordAction.ts +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useDiscardDraftWorkflowSingleRecordAction.ts @@ -1,4 +1,4 @@ -import { SingleRecordActionHookWithoutObjectMetadataItem } from '@/action-menu/actions/types/singleRecordActionHook'; +import { SingleRecordActionHookWithoutObjectMetadataItem } from '@/action-menu/actions/types/SingleRecordActionHook'; import { useDeleteOneWorkflowVersion } from '@/workflow/hooks/useDeleteOneWorkflowVersion'; import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion'; import { isDefined } from 'twenty-ui'; diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useSeeActiveVersionWorkflowSingleRecordAction.ts b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useSeeActiveVersionWorkflowSingleRecordAction.ts index 95264cf29d27..678a197f8917 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useSeeActiveVersionWorkflowSingleRecordAction.ts +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useSeeActiveVersionWorkflowSingleRecordAction.ts @@ -1,4 +1,4 @@ -import { SingleRecordActionHookWithoutObjectMetadataItem } from '@/action-menu/actions/types/singleRecordActionHook'; +import { SingleRecordActionHookWithoutObjectMetadataItem } from '@/action-menu/actions/types/SingleRecordActionHook'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { useActiveWorkflowVersion } from '@/workflow/hooks/useActiveWorkflowVersion'; import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion'; diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useSeeRunsWorkflowSingleRecordAction.ts b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useSeeRunsWorkflowSingleRecordAction.ts index 4c7da08932d8..6eb4bda1e707 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useSeeRunsWorkflowSingleRecordAction.ts +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useSeeRunsWorkflowSingleRecordAction.ts @@ -1,4 +1,4 @@ -import { SingleRecordActionHookWithoutObjectMetadataItem } from '@/action-menu/actions/types/singleRecordActionHook'; +import { SingleRecordActionHookWithoutObjectMetadataItem } from '@/action-menu/actions/types/SingleRecordActionHook'; import { CoreObjectNamePlural } from '@/object-metadata/types/CoreObjectNamePlural'; import { FilterQueryParams } from '@/views/hooks/internal/useViewFromQueryParams'; import { ViewFilterOperand } from '@/views/types/ViewFilterOperand'; diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useSeeVersionsWorkflowSingleRecordAction.ts b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useSeeVersionsWorkflowSingleRecordAction.ts index 4ff30bc4351f..f1170edcb04a 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useSeeVersionsWorkflowSingleRecordAction.ts +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useSeeVersionsWorkflowSingleRecordAction.ts @@ -1,4 +1,4 @@ -import { SingleRecordActionHookWithoutObjectMetadataItem } from '@/action-menu/actions/types/singleRecordActionHook'; +import { SingleRecordActionHookWithoutObjectMetadataItem } from '@/action-menu/actions/types/SingleRecordActionHook'; import { CoreObjectNamePlural } from '@/object-metadata/types/CoreObjectNamePlural'; import { FilterQueryParams } from '@/views/hooks/internal/useViewFromQueryParams'; import { ViewFilterOperand } from '@/views/types/ViewFilterOperand'; diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useTestWorkflowSingleRecordAction.ts b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useTestWorkflowSingleRecordAction.ts index 4df8e533bbdc..dd1daeba24f4 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useTestWorkflowSingleRecordAction.ts +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useTestWorkflowSingleRecordAction.ts @@ -1,4 +1,4 @@ -import { SingleRecordActionHookWithoutObjectMetadataItem } from '@/action-menu/actions/types/singleRecordActionHook'; +import { SingleRecordActionHookWithoutObjectMetadataItem } from '@/action-menu/actions/types/SingleRecordActionHook'; import { useRunWorkflowVersion } from '@/workflow/hooks/useRunWorkflowVersion'; import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion'; import { isDefined } from 'twenty-ui'; diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-version-actions/constants/WorkflowVersionsSingleRecordActionsConfig.ts b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-version-actions/constants/WorkflowVersionsSingleRecordActionsConfig.ts index c12d9ea6aaf3..fa6174ed3877 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-version-actions/constants/WorkflowVersionsSingleRecordActionsConfig.ts +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-version-actions/constants/WorkflowVersionsSingleRecordActionsConfig.ts @@ -1,12 +1,16 @@ +import { useAddToFavoritesSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useAddToFavoritesSingleRecordAction'; +import { useDeleteSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useDeleteSingleRecordAction'; +import { useDestroySingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useDestroySingleRecordAction'; import { useNavigateToNextRecordSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useNavigateToNextRecordSingleRecordAction'; import { useNavigateToPreviousRecordSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useNavigateToPreviousRecordSingleRecordAction'; +import { useRemoveFromFavoritesSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useRemoveFromFavoritesSingleRecordAction'; import { SingleRecordActionKeys } from '@/action-menu/actions/record-actions/single-record/types/SingleRecordActionsKey'; import { useSeeRunsWorkflowVersionSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/workflow-version-actions/hooks/useSeeRunsWorkflowVersionSingleRecordAction'; import { useSeeVersionsWorkflowVersionSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/workflow-version-actions/hooks/useSeeVersionsWorkflowVersionSingleRecordAction'; import { useUseAsDraftWorkflowVersionSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/workflow-version-actions/hooks/useUseAsDraftWorkflowVersionSingleRecordAction'; import { WorkflowVersionSingleRecordActionKeys } from '@/action-menu/actions/record-actions/single-record/workflow-version-actions/types/WorkflowVersionSingleRecordActionsKeys'; -import { ActionAvailableOn } from '@/action-menu/actions/types/actionAvailableOn'; -import { SingleRecordActionHook } from '@/action-menu/actions/types/singleRecordActionHook'; +import { ActionAvailableOn } from '@/action-menu/actions/types/ActionAvailableOn'; +import { SingleRecordActionHook } from '@/action-menu/actions/types/SingleRecordActionHook'; import { ActionMenuEntry, ActionMenuEntryScope, @@ -15,9 +19,13 @@ import { import { IconChevronDown, IconChevronUp, + IconHeart, + IconHeartOff, IconHistory, IconHistoryToggle, IconPencil, + IconTrash, + IconTrashX, } from 'twenty-ui'; export const WORKFLOW_VERSIONS_SINGLE_RECORD_ACTIONS_CONFIG: Record< @@ -72,7 +80,7 @@ export const WORKFLOW_VERSIONS_SINGLE_RECORD_ACTIONS_CONFIG: Record< key: SingleRecordActionKeys.NAVIGATE_TO_PREVIOUS_RECORD, label: 'Navigate to previous version', shortLabel: '', - position: 9, + position: 4, Icon: IconChevronUp, availableOn: [ActionAvailableOn.SHOW_PAGE], actionHook: useNavigateToPreviousRecordSingleRecordAction, @@ -83,9 +91,71 @@ export const WORKFLOW_VERSIONS_SINGLE_RECORD_ACTIONS_CONFIG: Record< key: SingleRecordActionKeys.NAVIGATE_TO_NEXT_RECORD, label: 'Navigate to next version', shortLabel: '', - position: 10, + position: 5, Icon: IconChevronDown, availableOn: [ActionAvailableOn.SHOW_PAGE], actionHook: useNavigateToNextRecordSingleRecordAction, }, + addToFavoritesSingleRecord: { + type: ActionMenuEntryType.Standard, + scope: ActionMenuEntryScope.RecordSelection, + key: SingleRecordActionKeys.ADD_TO_FAVORITES, + label: 'Add to favorites', + shortLabel: 'Add to favorites', + position: 6, + isPinned: false, + Icon: IconHeart, + availableOn: [ + ActionAvailableOn.INDEX_PAGE_SINGLE_RECORD_SELECTION, + ActionAvailableOn.SHOW_PAGE, + ], + actionHook: useAddToFavoritesSingleRecordAction, + }, + removeFromFavoritesSingleRecord: { + type: ActionMenuEntryType.Standard, + scope: ActionMenuEntryScope.RecordSelection, + key: SingleRecordActionKeys.REMOVE_FROM_FAVORITES, + label: 'Remove from favorites', + shortLabel: 'Remove from favorites', + isPinned: false, + position: 7, + Icon: IconHeartOff, + availableOn: [ + ActionAvailableOn.INDEX_PAGE_SINGLE_RECORD_SELECTION, + ActionAvailableOn.SHOW_PAGE, + ], + actionHook: useRemoveFromFavoritesSingleRecordAction, + }, + deleteSingleRecord: { + type: ActionMenuEntryType.Standard, + scope: ActionMenuEntryScope.RecordSelection, + key: SingleRecordActionKeys.DELETE, + label: 'Delete record', + shortLabel: 'Delete', + position: 8, + Icon: IconTrash, + accent: 'danger', + isPinned: false, + availableOn: [ + ActionAvailableOn.INDEX_PAGE_SINGLE_RECORD_SELECTION, + ActionAvailableOn.SHOW_PAGE, + ], + actionHook: useDeleteSingleRecordAction, + }, + destroySingleRecord: { + type: ActionMenuEntryType.Standard, + scope: ActionMenuEntryScope.RecordSelection, + key: SingleRecordActionKeys.DESTROY, + label: 'Permanently destroy record', + shortLabel: 'Destroy', + position: 9, + Icon: IconTrashX, + accent: 'danger', + isPinned: false, + availableOn: [ + ActionAvailableOn.INDEX_PAGE_SINGLE_RECORD_SELECTION, + ActionAvailableOn.SHOW_PAGE, + ], + actionHook: useDestroySingleRecordAction, + }, }; diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-version-actions/hooks/useSeeRunsWorkflowVersionSingleRecordAction.ts b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-version-actions/hooks/useSeeRunsWorkflowVersionSingleRecordAction.ts index a4359d929a42..290317ea4081 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-version-actions/hooks/useSeeRunsWorkflowVersionSingleRecordAction.ts +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-version-actions/hooks/useSeeRunsWorkflowVersionSingleRecordAction.ts @@ -1,4 +1,4 @@ -import { SingleRecordActionHookWithoutObjectMetadataItem } from '@/action-menu/actions/types/singleRecordActionHook'; +import { SingleRecordActionHookWithoutObjectMetadataItem } from '@/action-menu/actions/types/SingleRecordActionHook'; import { CoreObjectNamePlural } from '@/object-metadata/types/CoreObjectNamePlural'; import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; import { FilterQueryParams } from '@/views/hooks/internal/useViewFromQueryParams'; diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-version-actions/hooks/useSeeVersionsWorkflowVersionSingleRecordAction.ts b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-version-actions/hooks/useSeeVersionsWorkflowVersionSingleRecordAction.ts index 8b90991c80a6..738b11fb7d9d 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-version-actions/hooks/useSeeVersionsWorkflowVersionSingleRecordAction.ts +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-version-actions/hooks/useSeeVersionsWorkflowVersionSingleRecordAction.ts @@ -1,5 +1,5 @@ import { useSeeVersionsWorkflowSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useSeeVersionsWorkflowSingleRecordAction'; -import { SingleRecordActionHookWithoutObjectMetadataItem } from '@/action-menu/actions/types/singleRecordActionHook'; +import { SingleRecordActionHookWithoutObjectMetadataItem } from '@/action-menu/actions/types/SingleRecordActionHook'; import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; import { useRecoilValue } from 'recoil'; import { isDefined } from 'twenty-ui'; diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-version-actions/hooks/useUseAsDraftWorkflowVersionSingleRecordAction.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-version-actions/hooks/useUseAsDraftWorkflowVersionSingleRecordAction.tsx index c4c09530be2e..f4ba205de1a2 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-version-actions/hooks/useUseAsDraftWorkflowVersionSingleRecordAction.tsx +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-version-actions/hooks/useUseAsDraftWorkflowVersionSingleRecordAction.tsx @@ -1,4 +1,4 @@ -import { SingleRecordActionHookWithoutObjectMetadataItem } from '@/action-menu/actions/types/singleRecordActionHook'; +import { SingleRecordActionHookWithoutObjectMetadataItem } from '@/action-menu/actions/types/SingleRecordActionHook'; import { OverrideWorkflowDraftConfirmationModal } from '@/workflow/components/OverrideWorkflowDraftConfirmationModal'; import { useCreateNewWorkflowVersion } from '@/workflow/hooks/useCreateNewWorkflowVersion'; import { useWorkflowVersion } from '@/workflow/hooks/useWorkflowVersion'; diff --git a/packages/twenty-front/src/modules/action-menu/actions/types/actionAvailableOn.ts b/packages/twenty-front/src/modules/action-menu/actions/types/ActionAvailableOn.ts similarity index 100% rename from packages/twenty-front/src/modules/action-menu/actions/types/actionAvailableOn.ts rename to packages/twenty-front/src/modules/action-menu/actions/types/ActionAvailableOn.ts diff --git a/packages/twenty-front/src/modules/action-menu/actions/types/ActionHookResult.ts b/packages/twenty-front/src/modules/action-menu/actions/types/ActionHookResult.ts new file mode 100644 index 000000000000..7fa7c3a689b7 --- /dev/null +++ b/packages/twenty-front/src/modules/action-menu/actions/types/ActionHookResult.ts @@ -0,0 +1,7 @@ +import { ConfirmationModalProps } from '@/ui/layout/modal/components/ConfirmationModal'; + +export type ActionHookResult = { + shouldBeRegistered: boolean; + onClick: () => Promise | void; + ConfirmationModal?: React.ReactElement; +}; diff --git a/packages/twenty-front/src/modules/action-menu/actions/types/singleRecordActionHook.ts b/packages/twenty-front/src/modules/action-menu/actions/types/SingleRecordActionHook.ts similarity index 89% rename from packages/twenty-front/src/modules/action-menu/actions/types/singleRecordActionHook.ts rename to packages/twenty-front/src/modules/action-menu/actions/types/SingleRecordActionHook.ts index 9446939883c8..4bf981332905 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/types/singleRecordActionHook.ts +++ b/packages/twenty-front/src/modules/action-menu/actions/types/SingleRecordActionHook.ts @@ -1,4 +1,4 @@ -import { ActionHookResult } from '@/action-menu/actions/types/actionHookResult'; +import { ActionHookResult } from '@/action-menu/actions/types/ActionHookResult'; import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; export type SingleRecordActionHook = diff --git a/packages/twenty-front/src/modules/action-menu/actions/types/actionHookResult.ts b/packages/twenty-front/src/modules/action-menu/actions/types/actionHookResult.ts deleted file mode 100644 index aa72e8879151..000000000000 --- a/packages/twenty-front/src/modules/action-menu/actions/types/actionHookResult.ts +++ /dev/null @@ -1,5 +0,0 @@ -export type ActionHookResult = { - shouldBeRegistered: boolean; - onClick: () => void; - ConfirmationModal?: React.ReactElement; -}; diff --git a/packages/twenty-front/src/modules/action-menu/actions/utils/wrapActionInCallbacks.ts b/packages/twenty-front/src/modules/action-menu/actions/utils/wrapActionInCallbacks.ts new file mode 100644 index 000000000000..be82a371c437 --- /dev/null +++ b/packages/twenty-front/src/modules/action-menu/actions/utils/wrapActionInCallbacks.ts @@ -0,0 +1,40 @@ +import { ActionMenuEntry } from '@/action-menu/types/ActionMenuEntry'; +import { isDefined } from 'twenty-ui'; + +export const wrapActionInCallbacks = ({ + action, + onActionStartedCallback, + onActionExecutedCallback, +}: { + action: ActionMenuEntry; + onActionStartedCallback?: (action: { key: string }) => Promise | void; + onActionExecutedCallback?: (action: { key: string }) => Promise | void; +}) => { + const onClickWithCallbacks = isDefined(action.ConfirmationModal) + ? action.onClick + : async () => { + await onActionStartedCallback?.({ key: action.key }); + await action.onClick?.(); + await onActionExecutedCallback?.({ key: action.key }); + }; + + const ConfirmationModalWithCallbacks = isDefined(action.ConfirmationModal) + ? { + ...action.ConfirmationModal, + props: { + ...action.ConfirmationModal.props, + onConfirmClick: async () => { + await onActionStartedCallback?.({ key: action.key }); + await action.ConfirmationModal?.props.onConfirmClick?.(); + await onActionExecutedCallback?.({ key: action.key }); + }, + }, + } + : undefined; + + return { + ...action, + onClick: onClickWithCallbacks, + ConfirmationModal: ConfirmationModalWithCallbacks, + }; +}; diff --git a/packages/twenty-front/src/modules/action-menu/contexts/ActionMenuContext.ts b/packages/twenty-front/src/modules/action-menu/contexts/ActionMenuContext.ts index 65355f11f205..2ddf67be666a 100644 --- a/packages/twenty-front/src/modules/action-menu/contexts/ActionMenuContext.ts +++ b/packages/twenty-front/src/modules/action-menu/contexts/ActionMenuContext.ts @@ -2,8 +2,8 @@ import { createContext } from 'react'; type ActionMenuContextType = { isInRightDrawer: boolean; - onActionStartedCallback?: (action: { key: string }) => void; - onActionExecutedCallback?: (action: { key: string }) => void; + onActionStartedCallback?: (action: { key: string }) => Promise | void; + onActionExecutedCallback?: (action: { key: string }) => Promise | void; }; export const ActionMenuContext = createContext({ diff --git a/packages/twenty-front/src/modules/action-menu/types/ActionMenuEntry.ts b/packages/twenty-front/src/modules/action-menu/types/ActionMenuEntry.ts index cec68dd396c1..2b955d0ca475 100644 --- a/packages/twenty-front/src/modules/action-menu/types/ActionMenuEntry.ts +++ b/packages/twenty-front/src/modules/action-menu/types/ActionMenuEntry.ts @@ -1,4 +1,5 @@ -import { ActionAvailableOn } from '@/action-menu/actions/types/actionAvailableOn'; +import { ActionAvailableOn } from '@/action-menu/actions/types/ActionAvailableOn'; +import { ConfirmationModalProps } from '@/ui/layout/modal/components/ConfirmationModal'; import { MouseEvent, ReactElement } from 'react'; import { IconComponent, MenuItemAccent } from 'twenty-ui'; @@ -24,5 +25,5 @@ export type ActionMenuEntry = { accent?: MenuItemAccent; availableOn?: ActionAvailableOn[]; onClick?: (event?: MouseEvent) => void; - ConfirmationModal?: ReactElement; + ConfirmationModal?: ReactElement; };