diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/hooks/useDeleteMultipleRecordsAction.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/hooks/useDeleteMultipleRecordsAction.tsx index 4499caacd0ba..e89b97691538 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/hooks/useDeleteMultipleRecordsAction.tsx +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/hooks/useDeleteMultipleRecordsAction.tsx @@ -14,6 +14,7 @@ import { DEFAULT_QUERY_PAGE_SIZE } from '@/object-record/constants/DefaultQueryP import { DELETE_MAX_COUNT } from '@/object-record/constants/DeleteMaxCount'; import { useDeleteManyRecords } from '@/object-record/hooks/useDeleteManyRecords'; import { useLazyFetchAllRecords } from '@/object-record/hooks/useLazyFetchAllRecords'; +import { FilterOperand } from '@/object-record/object-filter-dropdown/types/FilterOperand'; import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable'; import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal'; import { useRightDrawer } from '@/ui/layout/right-drawer/hooks/useRightDrawer'; @@ -57,6 +58,16 @@ export const useDeleteMultipleRecordsAction = ({ objectMetadataItem, ); + const deletedAtFieldMetadata = objectMetadataItem.fields.find( + (field) => field.name === 'deletedAt', + ); + + const isDeletedFilterActive = contextStoreFilters.some( + (filter) => + filter.fieldMetadataId === deletedAtFieldMetadata?.id && + filter.operand === FilterOperand.IsNotEmpty, + ); + const { fetchAllRecords: fetchAllRecordIds } = useLazyFetchAllRecords({ objectNameSingular: objectMetadataItem.nameSingular, filter: graphqlFilter, @@ -79,6 +90,7 @@ export const useDeleteMultipleRecordsAction = ({ const canDelete = !isRemoteObject && + !isDeletedFilterActive && isDefined(contextStoreNumberOfSelectedRecords) && contextStoreNumberOfSelectedRecords < DELETE_MAX_COUNT && contextStoreNumberOfSelectedRecords > 0; 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; }; diff --git a/packages/twenty-front/src/modules/settings/data-model/fields/forms/select/components/SettingsDataModelFieldSelectFormOptionRow.tsx b/packages/twenty-front/src/modules/settings/data-model/fields/forms/select/components/SettingsDataModelFieldSelectFormOptionRow.tsx index 6f3002e7850e..c55fb4e0acdb 100644 --- a/packages/twenty-front/src/modules/settings/data-model/fields/forms/select/components/SettingsDataModelFieldSelectFormOptionRow.tsx +++ b/packages/twenty-front/src/modules/settings/data-model/fields/forms/select/components/SettingsDataModelFieldSelectFormOptionRow.tsx @@ -79,8 +79,8 @@ export const SettingsDataModelFieldSelectFormOptionRow = ({ }: SettingsDataModelFieldSelectFormOptionRowProps) => { const theme = useTheme(); - const SELECT_COLOR_DROPDOWN_ID = 'select-color-dropdown'; - const SELECT_ACTIONS_DROPDOWN_ID = 'select-actions-dropdown'; + const SELECT_COLOR_DROPDOWN_ID = `select-color-dropdown-${option.id}`; + const SELECT_ACTIONS_DROPDOWN_ID = `select-actions-dropdown-${option.id}`; const { closeDropdown: closeColorDropdown } = useDropdown( SELECT_COLOR_DROPDOWN_ID, diff --git a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawer.tsx b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawer.tsx index 823fc3d4a007..20aba86a6f8e 100644 --- a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawer.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawer.tsx @@ -111,15 +111,15 @@ export const NavigationDrawer = ({ onMouseEnter={handleHover} onMouseLeave={handleMouseLeave} > - {isSettingsDrawer && title - ? !isMobile && - : logo && ( - - )} + {isSettingsDrawer && title ? ( + !isMobile && + ) : ( + + )} {children} diff --git a/packages/twenty-server/src/database/commands/database-command.module.ts b/packages/twenty-server/src/database/commands/database-command.module.ts index 1ab5b849f46b..e25e01cdb03c 100644 --- a/packages/twenty-server/src/database/commands/database-command.module.ts +++ b/packages/twenty-server/src/database/commands/database-command.module.ts @@ -10,7 +10,7 @@ import { ConfirmationQuestion } from 'src/database/commands/questions/confirmati import { UpgradeTo0_32CommandModule } from 'src/database/commands/upgrade-version/0-32/0-32-upgrade-version.module'; import { UpgradeTo0_33CommandModule } from 'src/database/commands/upgrade-version/0-33/0-33-upgrade-version.module'; import { UpgradeTo0_34CommandModule } from 'src/database/commands/upgrade-version/0-34/0-34-upgrade-version.module'; -import { UpgradeTo0_40CommandModule } from 'src/database/commands/upgrade-version/0-40/0-40-upgrade-version.module'; +import { UpgradeTo0_35CommandModule } from 'src/database/commands/upgrade-version/0-35/0-35-upgrade-version.module'; import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; import { BillingSubscription } from 'src/engine/core-modules/billing/entities/billing-subscription.entity'; import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity'; @@ -52,7 +52,7 @@ import { WorkspaceSyncMetadataModule } from 'src/engine/workspace-manager/worksp UpgradeTo0_32CommandModule, UpgradeTo0_33CommandModule, UpgradeTo0_34CommandModule, - UpgradeTo0_40CommandModule, + UpgradeTo0_35CommandModule, FeatureFlagModule, ], providers: [ diff --git a/packages/twenty-server/src/database/commands/logger.ts b/packages/twenty-server/src/database/commands/logger.ts index 9bd2ebb02011..722cdb224461 100644 --- a/packages/twenty-server/src/database/commands/logger.ts +++ b/packages/twenty-server/src/database/commands/logger.ts @@ -5,42 +5,44 @@ interface CommandLoggerOptions { constructorName: string; } +export const isCommandLogger = ( + logger: Logger | CommandLogger, +): logger is CommandLogger => { + return typeof logger['setVerbose'] === 'function'; +}; + export class CommandLogger { private logger: Logger; - private verbose: boolean; + private verboseFlag: boolean; constructor(options: CommandLoggerOptions) { this.logger = new Logger(options.constructorName); - this.verbose = options.verbose ?? true; + this.verboseFlag = options.verbose ?? false; } - log(message: string, context?: string) { - if (this.verbose) { - this.logger.log(message, context); - } + log(message: string, ...optionalParams: [...any, string?]) { + this.logger.log(message, ...optionalParams); } error(message: string, stack?: string, context?: string) { - if (this.verbose) { - this.logger.error(message, stack, context); - } + this.logger.error(message, stack, context); } warn(message: string, context?: string) { - if (this.verbose) { - this.logger.warn(message, context); - } + this.logger.warn(message, context); } debug(message: string, context?: string) { - if (this.verbose) { - this.logger.debug(message, context); - } + this.logger.debug(message, context); } - verboseLog(message: string, context?: string) { - if (this.verbose) { - this.logger.verbose(message, context); + verbose(message: string, ...optionalParams: [...any, string?]) { + if (this.verboseFlag) { + this.logger.log(message, ...optionalParams); } } + + setVerbose(flag: boolean) { + this.verboseFlag = flag; + } } diff --git a/packages/twenty-server/src/database/commands/upgrade-version/0-40/0-40-phone-calling-code-create-column.command.ts b/packages/twenty-server/src/database/commands/upgrade-version/0-35/0-35-phone-calling-code-create-column.command.ts similarity index 88% rename from packages/twenty-server/src/database/commands/upgrade-version/0-40/0-40-phone-calling-code-create-column.command.ts rename to packages/twenty-server/src/database/commands/upgrade-version/0-35/0-35-phone-calling-code-create-column.command.ts index ea3750ab32e8..21fe77a6de86 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version/0-40/0-40-phone-calling-code-create-column.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version/0-35/0-35-phone-calling-code-create-column.command.ts @@ -9,12 +9,12 @@ import { ActiveWorkspacesCommandOptions, ActiveWorkspacesCommandRunner, } from 'src/database/commands/active-workspaces.command'; +import { isCommandLogger } from 'src/database/commands/logger'; import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { FieldMetadataEntity, FieldMetadataType, } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; -import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { WorkspaceMetadataVersionService } from 'src/engine/metadata-modules/workspace-metadata-version/services/workspace-metadata-version.service'; import { generateMigrationName } from 'src/engine/metadata-modules/workspace-migration/utils/generate-migration-name.util'; import { @@ -29,7 +29,7 @@ import { WorkspaceMigrationRunnerService } from 'src/engine/workspace-manager/wo import { isDefined } from 'src/utils/is-defined'; @Command({ - name: 'upgrade-0.40:phone-calling-code-create-column', + name: 'upgrade-0.35:phone-calling-code-create-column', description: 'Create the callingCode column', }) export class PhoneCallingCodeCreateColumnCommand extends ActiveWorkspacesCommandRunner { @@ -38,8 +38,6 @@ export class PhoneCallingCodeCreateColumnCommand extends ActiveWorkspacesCommand protected readonly workspaceRepository: Repository, @InjectRepository(FieldMetadataEntity, 'metadata') private readonly fieldMetadataRepository: Repository, - @InjectRepository(ObjectMetadataEntity, 'metadata') - private readonly objectMetadataRepository: Repository, private readonly workspaceMigrationService: WorkspaceMigrationService, private readonly workspaceMigrationFactory: WorkspaceMigrationFactory, private readonly workspaceMigrationRunnerService: WorkspaceMigrationRunnerService, @@ -56,16 +54,19 @@ export class PhoneCallingCodeCreateColumnCommand extends ActiveWorkspacesCommand this.logger.log( 'Running command to add calling code and change country code with default one', ); + if (isCommandLogger(this.logger)) { + this.logger.setVerbose(options.verbose ?? false); + } - this.logger.log(`Part 1 - Workspace`); + this.logger.verbose(`Part 1 - Workspace`); let workspaceIterator = 1; for (const workspaceId of workspaceIds) { - this.logger.log( + this.logger.verbose( `Running command for workspace ${workspaceId} ${workspaceIterator}/${workspaceIds.length}`, ); - this.logger.log( + this.logger.verbose( `P1 Step 1 - let's find all the fieldsMetadata that have the PHONES type, and extract the objectMetadataId`, ); @@ -80,19 +81,20 @@ export class PhoneCallingCodeCreateColumnCommand extends ActiveWorkspacesCommand for (const phoneFieldMetadata of phonesFieldMetadata) { if ( - isDefined(phoneFieldMetadata?.name && phoneFieldMetadata.object) + isDefined(phoneFieldMetadata?.name) && + isDefined(phoneFieldMetadata.object) ) { - this.logger.log( + this.logger.verbose( `P1 Step 1 - Let's find the "nameSingular" of this objectMetadata: ${phoneFieldMetadata.object.nameSingular || 'not found'}`, ); if (!phoneFieldMetadata.object?.nameSingular) continue; - this.logger.log( + this.logger.verbose( `P1 Step 1 - Create migration for field ${phoneFieldMetadata.name}`, ); - if (options.dryRun === true) { + if (options.dryRun) { continue; } await this.workspaceMigrationService.createCustomMigration( @@ -123,7 +125,7 @@ export class PhoneCallingCodeCreateColumnCommand extends ActiveWorkspacesCommand } } - this.logger.log( + this.logger.verbose( `P1 Step 1 - RUN migration to create callingCodes for ${workspaceId.slice(0, 5)}`, ); await this.workspaceMigrationRunnerService.executeMigrationFromPendingMigrations( @@ -134,7 +136,7 @@ export class PhoneCallingCodeCreateColumnCommand extends ActiveWorkspacesCommand workspaceId, ); } catch (error) { - console.log(`Error in workspace ${workspaceId} : ${error}`); + this.logger.log(`Error in workspace ${workspaceId} : ${error}`); } workspaceIterator++; } diff --git a/packages/twenty-server/src/database/commands/upgrade-version/0-40/0-40-phone-calling-code-migrate-data.command.ts b/packages/twenty-server/src/database/commands/upgrade-version/0-35/0-35-phone-calling-code-migrate-data.command.ts similarity index 87% rename from packages/twenty-server/src/database/commands/upgrade-version/0-40/0-40-phone-calling-code-migrate-data.command.ts rename to packages/twenty-server/src/database/commands/upgrade-version/0-35/0-35-phone-calling-code-migrate-data.command.ts index ac60af59bc90..67bf658918d0 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version/0-40/0-40-phone-calling-code-migrate-data.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version/0-35/0-35-phone-calling-code-migrate-data.command.ts @@ -10,6 +10,7 @@ import { ActiveWorkspacesCommandOptions, ActiveWorkspacesCommandRunner, } from 'src/database/commands/active-workspaces.command'; +import { isCommandLogger } from 'src/database/commands/logger'; import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { FieldMetadataEntity, @@ -53,7 +54,7 @@ const isCallingCode = (callingCode: string): boolean => { }; @Command({ - name: 'upgrade-0.40:phone-calling-code-migrate-data', + name: 'upgrade-0.35:phone-calling-code-migrate-data', description: 'Add calling code and change country code with default one', }) export class PhoneCallingCodeMigrateDataCommand extends ActiveWorkspacesCommandRunner { @@ -82,7 +83,10 @@ export class PhoneCallingCodeMigrateDataCommand extends ActiveWorkspacesCommandR 'Running command to add calling code and change country code with default one', ); - this.logger.log(`Part 1 - Workspace`); + if (isCommandLogger(this.logger)) { + this.logger.setVerbose(options.verbose ?? false); + } + this.logger.verbose(`Part 1 - Workspace`); let workspaceIterator = 1; @@ -91,7 +95,7 @@ export class PhoneCallingCodeMigrateDataCommand extends ActiveWorkspacesCommandR `Running command for workspace ${workspaceId} ${workspaceIterator}/${workspaceIds.length}`, ); - this.logger.log( + this.logger.verbose( `P1 Step 1 - let's find all the fieldsMetadata that have the PHONES type, and extract the objectMetadataId`, ); @@ -109,16 +113,16 @@ export class PhoneCallingCodeMigrateDataCommand extends ActiveWorkspacesCommandR isDefined(phoneFieldMetadata?.name) && isDefined(phoneFieldMetadata.object) ) { - this.logger.log( + this.logger.verbose( `P1 Step 1 - Let's find the "nameSingular" of this objectMetadata: ${phoneFieldMetadata.object.nameSingular || 'not found'}`, ); if (!phoneFieldMetadata.object?.nameSingular) continue; - this.logger.log( + this.logger.verbose( `P1 Step 1 - Create migration for field ${phoneFieldMetadata.name}`, ); - if (options.dryRun === false) { + if (!options.dryRun) { await this.workspaceMigrationService.createCustomMigration( generateMigrationName( `create-${phoneFieldMetadata.object.nameSingular}PrimaryPhoneCallingCode-for-field-${phoneFieldMetadata.name}`, @@ -148,7 +152,7 @@ export class PhoneCallingCodeMigrateDataCommand extends ActiveWorkspacesCommandR } } - this.logger.log( + this.logger.verbose( `P1 Step 1 - RUN migration to create callingCodes for ${workspaceId.slice(0, 5)}`, ); await this.workspaceMigrationRunnerService.executeMigrationFromPendingMigrations( @@ -159,20 +163,20 @@ export class PhoneCallingCodeMigrateDataCommand extends ActiveWorkspacesCommandR workspaceId, ); - this.logger.log( + this.logger.verbose( `P1 Step 2 - Migrations for callingCode must be first. Now can use twentyORMGlobalManager to update countryCode`, ); - this.logger.log( + this.logger.verbose( `P1 Step 3 (same time) - update CountryCode to letters: +33 => FR || +1 => US (if mulitple, first one)`, ); - this.logger.log( + this.logger.verbose( `P1 Step 4 (same time) - update all additioanl phones to add a country code following the same logic`, ); for (const phoneFieldMetadata of phonesFieldMetadata) { - this.logger.log(`P1 Step 2 - for ${phoneFieldMetadata.name}`); + this.logger.verbose(`P1 Step 2 - for ${phoneFieldMetadata.name}`); if ( isDefined(phoneFieldMetadata) && isDefined(phoneFieldMetadata.name) @@ -209,7 +213,7 @@ export class PhoneCallingCodeMigrateDataCommand extends ActiveWorkspacesCommandR }; }); } - if (options.dryRun === false) { + if (!options.dryRun) { await repository.update(record.id, { [`${phoneFieldMetadata.name}PrimaryPhoneCallingCode`]: record[phoneFieldMetadata.name].primaryPhoneCountryCode, @@ -226,12 +230,12 @@ export class PhoneCallingCodeMigrateDataCommand extends ActiveWorkspacesCommandR } } } catch (error) { - console.log(`Error in workspace ${workspaceId} : ${error}`); + this.logger.log(`Error in workspace ${workspaceId} : ${error}`); } workspaceIterator++; } - this.logger.log(` + this.logger.verbose(` Part 2 - FieldMetadata`); @@ -241,7 +245,7 @@ export class PhoneCallingCodeMigrateDataCommand extends ActiveWorkspacesCommandR `Running command for workspace ${workspaceId} ${workspaceIterator}/${workspaceIds.length}`, ); - this.logger.log( + this.logger.verbose( `P2 Step 1 - let's find all the fieldsMetadata that have the PHONES type, and extract the objectMetadataId`, ); @@ -276,24 +280,26 @@ export class PhoneCallingCodeMigrateDataCommand extends ActiveWorkspacesCommandR primaryPhoneCountryCode.replace(/["']/g, ''), ); - if (options.dryRun === false) { - await this.fieldMetadataRepository.update(phoneFieldMetadata.id, { - defaultValue: { - ...defaultValue, - primaryPhoneCountryCode: countryCode - ? `'${countryCode}'` - : "''", - primaryPhoneCallingCode: isCallingCode( - primaryPhoneCountryCode.replace(/["']/g, ''), - ) - ? primaryPhoneCountryCode - : "''", - }, - }); + if (!options.dryRun) { + if (!defaultValue.primaryPhoneCallingCode) { + await this.fieldMetadataRepository.update(phoneFieldMetadata.id, { + defaultValue: { + ...defaultValue, + primaryPhoneCountryCode: countryCode + ? `'${countryCode}'` + : "''", + primaryPhoneCallingCode: isCallingCode( + primaryPhoneCountryCode.replace(/["']/g, ''), + ) + ? primaryPhoneCountryCode + : "''", + }, + }); + } } } } catch (error) { - console.log(`Error in workspace ${workspaceId} : ${error}`); + this.logger.log(`Error in workspace ${workspaceId} : ${error}`); } workspaceIterator++; } diff --git a/packages/twenty-server/src/database/commands/upgrade-version/0-40/0-40-record-position-backfill.command.ts b/packages/twenty-server/src/database/commands/upgrade-version/0-35/0-35-record-position-backfill.command.ts similarity index 96% rename from packages/twenty-server/src/database/commands/upgrade-version/0-40/0-40-record-position-backfill.command.ts rename to packages/twenty-server/src/database/commands/upgrade-version/0-35/0-35-record-position-backfill.command.ts index f0804e873077..7a342b920eb4 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version/0-40/0-40-record-position-backfill.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version/0-35/0-35-record-position-backfill.command.ts @@ -9,7 +9,7 @@ import { RecordPositionBackfillService } from 'src/engine/api/graphql/workspace- import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; @Command({ - name: 'upgrade-0.40:record-position-backfill', + name: 'upgrade-0.35:record-position-backfill', description: 'Backfill record position', }) export class RecordPositionBackfillCommand extends ActiveWorkspacesCommandRunner { diff --git a/packages/twenty-server/src/database/commands/upgrade-version/0-40/0-40-upgrade-version.command.ts b/packages/twenty-server/src/database/commands/upgrade-version/0-35/0-35-upgrade-version.command.ts similarity index 86% rename from packages/twenty-server/src/database/commands/upgrade-version/0-40/0-40-upgrade-version.command.ts rename to packages/twenty-server/src/database/commands/upgrade-version/0-35/0-35-upgrade-version.command.ts index e60b537bb398..7f0d7cdb08ba 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version/0-40/0-40-upgrade-version.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version/0-35/0-35-upgrade-version.command.ts @@ -5,18 +5,18 @@ import { Repository } from 'typeorm'; import { ActiveWorkspacesCommandRunner } from 'src/database/commands/active-workspaces.command'; import { BaseCommandOptions } from 'src/database/commands/base.command'; -import { PhoneCallingCodeCreateColumnCommand } from 'src/database/commands/upgrade-version/0-40/0-40-phone-calling-code-create-column.command'; -import { PhoneCallingCodeMigrateDataCommand } from 'src/database/commands/upgrade-version/0-40/0-40-phone-calling-code-migrate-data.command'; -import { RecordPositionBackfillCommand } from 'src/database/commands/upgrade-version/0-40/0-40-record-position-backfill.command'; -import { ViewGroupNoValueBackfillCommand } from 'src/database/commands/upgrade-version/0-40/0-40-view-group-no-value-backfill.command'; +import { PhoneCallingCodeCreateColumnCommand } from 'src/database/commands/upgrade-version/0-35/0-35-phone-calling-code-create-column.command'; +import { PhoneCallingCodeMigrateDataCommand } from 'src/database/commands/upgrade-version/0-35/0-35-phone-calling-code-migrate-data.command'; +import { RecordPositionBackfillCommand } from 'src/database/commands/upgrade-version/0-35/0-35-record-position-backfill.command'; +import { ViewGroupNoValueBackfillCommand } from 'src/database/commands/upgrade-version/0-35/0-35-view-group-no-value-backfill.command'; import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { SyncWorkspaceMetadataCommand } from 'src/engine/workspace-manager/workspace-sync-metadata/commands/sync-workspace-metadata.command'; @Command({ - name: 'upgrade-0.40', - description: 'Upgrade to 0.40', + name: 'upgrade-0.35', + description: 'Upgrade to 0.35', }) -export class UpgradeTo0_40Command extends ActiveWorkspacesCommandRunner { +export class UpgradeTo0_35Command extends ActiveWorkspacesCommandRunner { constructor( @InjectRepository(Workspace, 'core') protected readonly workspaceRepository: Repository, diff --git a/packages/twenty-server/src/database/commands/upgrade-version/0-40/0-40-upgrade-version.module.ts b/packages/twenty-server/src/database/commands/upgrade-version/0-35/0-35-upgrade-version.module.ts similarity index 84% rename from packages/twenty-server/src/database/commands/upgrade-version/0-40/0-40-upgrade-version.module.ts rename to packages/twenty-server/src/database/commands/upgrade-version/0-35/0-35-upgrade-version.module.ts index b19780ed8a17..aba95d1bb4d2 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version/0-40/0-40-upgrade-version.module.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version/0-35/0-35-upgrade-version.module.ts @@ -1,11 +1,11 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { PhoneCallingCodeCreateColumnCommand } from 'src/database/commands/upgrade-version/0-40/0-40-phone-calling-code-create-column.command'; -import { PhoneCallingCodeMigrateDataCommand } from 'src/database/commands/upgrade-version/0-40/0-40-phone-calling-code-migrate-data.command'; -import { RecordPositionBackfillCommand } from 'src/database/commands/upgrade-version/0-40/0-40-record-position-backfill.command'; -import { UpgradeTo0_40Command } from 'src/database/commands/upgrade-version/0-40/0-40-upgrade-version.command'; -import { ViewGroupNoValueBackfillCommand } from 'src/database/commands/upgrade-version/0-40/0-40-view-group-no-value-backfill.command'; +import { PhoneCallingCodeCreateColumnCommand } from 'src/database/commands/upgrade-version/0-35/0-35-phone-calling-code-create-column.command'; +import { PhoneCallingCodeMigrateDataCommand } from 'src/database/commands/upgrade-version/0-35/0-35-phone-calling-code-migrate-data.command'; +import { RecordPositionBackfillCommand } from 'src/database/commands/upgrade-version/0-35/0-35-record-position-backfill.command'; +import { UpgradeTo0_35Command } from 'src/database/commands/upgrade-version/0-35/0-35-upgrade-version.command'; +import { ViewGroupNoValueBackfillCommand } from 'src/database/commands/upgrade-version/0-35/0-35-view-group-no-value-backfill.command'; import { RecordPositionBackfillModule } from 'src/engine/api/graphql/workspace-query-runner/services/record-position-backfill-module'; import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; @@ -35,12 +35,12 @@ import { WorkspaceSyncMetadataCommandsModule } from 'src/engine/workspace-manage FieldMetadataModule, ], providers: [ - UpgradeTo0_40Command, - PhoneCallingCodeMigrateDataCommand, + UpgradeTo0_35Command, PhoneCallingCodeCreateColumnCommand, + PhoneCallingCodeMigrateDataCommand, WorkspaceMigrationFactory, RecordPositionBackfillCommand, ViewGroupNoValueBackfillCommand, ], }) -export class UpgradeTo0_40CommandModule {} +export class UpgradeTo0_35CommandModule {} diff --git a/packages/twenty-server/src/database/commands/upgrade-version/0-40/0-40-view-group-no-value-backfill.command.ts b/packages/twenty-server/src/database/commands/upgrade-version/0-35/0-35-view-group-no-value-backfill.command.ts similarity index 98% rename from packages/twenty-server/src/database/commands/upgrade-version/0-40/0-40-view-group-no-value-backfill.command.ts rename to packages/twenty-server/src/database/commands/upgrade-version/0-35/0-35-view-group-no-value-backfill.command.ts index 63662563dd67..fabdf1154b7c 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version/0-40/0-40-view-group-no-value-backfill.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version/0-35/0-35-view-group-no-value-backfill.command.ts @@ -13,7 +13,7 @@ import { ViewGroupWorkspaceEntity } from 'src/modules/view/standard-objects/view import { ViewWorkspaceEntity } from 'src/modules/view/standard-objects/view.workspace-entity'; @Command({ - name: 'migrate-0.40:backfill-view-group-no-value', + name: 'migrate-0.35:backfill-view-group-no-value', description: 'Backfill view group no value', }) export class ViewGroupNoValueBackfillCommand extends ActiveWorkspacesCommandRunner { diff --git a/packages/twenty-website/public/images/releases/0.35/0.35-Favorites.png b/packages/twenty-website/public/images/releases/0.35/0.35-Favorites.png new file mode 100644 index 000000000000..06a80e1f0ed5 Binary files /dev/null and b/packages/twenty-website/public/images/releases/0.35/0.35-Favorites.png differ diff --git a/packages/twenty-website/src/content/releases/0.35.0.mdx b/packages/twenty-website/src/content/releases/0.35.0.mdx new file mode 100644 index 000000000000..31ba912ca563 --- /dev/null +++ b/packages/twenty-website/src/content/releases/0.35.0.mdx @@ -0,0 +1,10 @@ +--- +release: 0.35.0 +Date: December 20th 2024 +--- + +# Favorites Views and Favorites Folders + +You can now add your views to favorites for quick access and organize your favorites into folders for better management. + +![](/images/releases/0.35/0.35-Favorites.png) \ No newline at end of file