diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/components/RecordActionMenuEntriesSetter.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/components/RecordActionMenuEntriesSetter.tsx
index 7d64ec72c0..b259f23eb4 100644
--- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/components/RecordActionMenuEntriesSetter.tsx
+++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/components/RecordActionMenuEntriesSetter.tsx
@@ -1,24 +1,10 @@
-import { DeleteRecordsActionEffect } from '@/action-menu/actions/record-actions/components/DeleteRecordsActionEffect';
-import { ExportRecordsActionEffect } from '@/action-menu/actions/record-actions/components/ExportRecordsActionEffect';
-import { ManageFavoritesActionEffect } from '@/action-menu/actions/record-actions/components/ManageFavoritesActionEffect';
-import { WorkflowRunRecordActionEffect } from '@/action-menu/actions/record-actions/workflow-run-record-actions/components/WorkflowRunRecordActionEffect';
+import { MultipleRecordsActionMenuEntrySetterEffect } from '@/action-menu/actions/record-actions/multiple-records/components/MultipleRecordsActionMenuEntrySetterEffect';
+import { NoSelectionActionMenuEntrySetterEffect } from '@/action-menu/actions/record-actions/no-selection/components/NoSelectionActionMenuEntrySetterEffect';
+import { SingleRecordActionMenuEntrySetterEffect } from '@/action-menu/actions/record-actions/single-record/components/SingleRecordActionMenuEntrySetterEffect';
import { contextStoreCurrentObjectMetadataIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataIdComponentState';
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
import { useObjectMetadataItemById } from '@/object-metadata/hooks/useObjectMetadataItemById';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
-import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
-
-const noSelectionRecordActionEffects = [ExportRecordsActionEffect];
-
-const singleRecordActionEffects = [
- ManageFavoritesActionEffect,
- DeleteRecordsActionEffect,
-];
-
-const multipleRecordActionEffects = [
- ExportRecordsActionEffect,
- DeleteRecordsActionEffect,
-];
export const RecordActionMenuEntriesSetter = () => {
const contextStoreNumberOfSelectedRecords = useRecoilComponentValueV2(
@@ -33,32 +19,26 @@ export const RecordActionMenuEntriesSetter = () => {
objectId: contextStoreCurrentObjectMetadataId ?? '',
});
- const isWorkflowEnabled = useIsFeatureEnabled('IS_WORKFLOW_ENABLED');
-
if (!objectMetadataItem) {
throw new Error(
`Object metadata item not found for id ${contextStoreCurrentObjectMetadataId}`,
);
}
- const actions =
- contextStoreNumberOfSelectedRecords === 0
- ? noSelectionRecordActionEffects
- : contextStoreNumberOfSelectedRecords === 1
- ? singleRecordActionEffects
- : multipleRecordActionEffects;
-
return (
<>
- {actions.map((ActionEffect, index) => (
-
- ))}
- {contextStoreNumberOfSelectedRecords === 1 && isWorkflowEnabled && (
-
+ )}
+ {contextStoreNumberOfSelectedRecords > 1 && (
+
)}
diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/components/MultipleRecordsActionMenuEntrySetterEffect.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/components/MultipleRecordsActionMenuEntrySetterEffect.tsx
new file mode 100644
index 0000000000..67b96f1b7a
--- /dev/null
+++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/components/MultipleRecordsActionMenuEntrySetterEffect.tsx
@@ -0,0 +1,24 @@
+import { useMultipleRecordsActions } from '@/action-menu/actions/record-actions/multiple-records/hooks/useMultipleRecordsActions';
+import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
+import { useEffect } from 'react';
+
+export const MultipleRecordsActionMenuEntrySetterEffect = ({
+ objectMetadataItem,
+}: {
+ objectMetadataItem: ObjectMetadataItem;
+}) => {
+ const { registerMultipleRecordsActions, unregisterMultipleRecordsActions } =
+ useMultipleRecordsActions({
+ objectMetadataItem,
+ });
+
+ useEffect(() => {
+ registerMultipleRecordsActions();
+
+ return () => {
+ unregisterMultipleRecordsActions();
+ };
+ }, [registerMultipleRecordsActions, unregisterMultipleRecordsActions]);
+
+ return null;
+};
diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/components/DeleteRecordsActionEffect.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/hooks/useDeleteMultipleRecordsAction.tsx
similarity index 79%
rename from packages/twenty-front/src/modules/action-menu/actions/record-actions/components/DeleteRecordsActionEffect.tsx
rename to packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/hooks/useDeleteMultipleRecordsAction.tsx
index 4f6d4f9142..4ca83af95a 100644
--- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/components/DeleteRecordsActionEffect.tsx
+++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/hooks/useDeleteMultipleRecordsAction.tsx
@@ -14,10 +14,10 @@ import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTabl
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
import { useRightDrawer } from '@/ui/layout/right-drawer/hooks/useRightDrawer';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
-import { useCallback, useContext, useEffect, useState } from 'react';
+import { useCallback, useContext, useState } from 'react';
import { IconTrash, isDefined } from 'twenty-ui';
-export const DeleteRecordsActionEffect = ({
+export const useDeleteMultipleRecordsAction = ({
position,
objectMetadataItem,
}: {
@@ -102,12 +102,12 @@ export const DeleteRecordsActionEffect = ({
const { isInRightDrawer, onActionExecutedCallback } =
useContext(ActionMenuContext);
- useEffect(() => {
+ const registerDeleteMultipleRecordsAction = () => {
if (canDelete) {
addActionMenuEntry({
type: 'standard',
scope: 'record-selection',
- key: 'delete',
+ key: 'delete-multiple-records',
label: 'Delete',
position,
Icon: IconTrash,
@@ -120,16 +120,8 @@ export const DeleteRecordsActionEffect = ({
{
handleDeleteClick();
onActionExecutedCallback?.();
@@ -137,31 +129,19 @@ export const DeleteRecordsActionEffect = ({
closeRightDrawer();
}
}}
- deleteButtonText={`Delete ${
- contextStoreNumberOfSelectedRecords > 1 ? 'Records' : 'Record'
- }`}
+ deleteButtonText={'Delete Records'}
/>
),
});
- } else {
- removeActionMenuEntry('delete');
}
+ };
- return () => {
- removeActionMenuEntry('delete');
- };
- }, [
- addActionMenuEntry,
- canDelete,
- closeRightDrawer,
- contextStoreNumberOfSelectedRecords,
- handleDeleteClick,
- isDeleteRecordsModalOpen,
- isInRightDrawer,
- onActionExecutedCallback,
- position,
- removeActionMenuEntry,
- ]);
+ const unregisterDeleteMultipleRecordsAction = () => {
+ removeActionMenuEntry('delete-multiple-records');
+ };
- return null;
+ return {
+ registerDeleteMultipleRecordsAction,
+ unregisterDeleteMultipleRecordsAction,
+ };
};
diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/components/ExportRecordsActionEffect.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/hooks/useExportMultipleRecordsAction.tsx
similarity index 57%
rename from packages/twenty-front/src/modules/action-menu/actions/record-actions/components/ExportRecordsActionEffect.tsx
rename to packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/hooks/useExportMultipleRecordsAction.tsx
index 602aa96234..102e745e58 100644
--- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/components/ExportRecordsActionEffect.tsx
+++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/hooks/useExportMultipleRecordsAction.tsx
@@ -1,16 +1,13 @@
import { useActionMenuEntries } from '@/action-menu/hooks/useActionMenuEntries';
-import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
-import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { IconDatabaseExport } from 'twenty-ui';
import {
displayedExportProgress,
useExportRecords,
} from '@/object-record/record-index/export/hooks/useExportRecords';
-import { useEffect } from 'react';
-export const ExportRecordsActionEffect = ({
+export const useExportMultipleRecordsAction = ({
position,
objectMetadataItem,
}: {
@@ -18,9 +15,6 @@ export const ExportRecordsActionEffect = ({
objectMetadataItem: ObjectMetadataItem;
}) => {
const { addActionMenuEntry, removeActionMenuEntry } = useActionMenuEntries();
- const contextStoreNumberOfSelectedRecords = useRecoilComponentValueV2(
- contextStoreNumberOfSelectedRecordsComponentState,
- );
const { progress, download } = useExportRecords({
delayMs: 100,
@@ -29,29 +23,25 @@ export const ExportRecordsActionEffect = ({
filename: `${objectMetadataItem.nameSingular}.csv`,
});
- useEffect(() => {
+ const registerExportMultipleRecordsAction = () => {
addActionMenuEntry({
type: 'standard',
scope: 'record-selection',
- key: 'export',
+ key: 'export-multiple-records',
position,
label: displayedExportProgress(progress),
Icon: IconDatabaseExport,
accent: 'default',
onClick: () => download(),
});
+ };
- return () => {
- removeActionMenuEntry('export');
- };
- }, [
- contextStoreNumberOfSelectedRecords,
- download,
- progress,
- addActionMenuEntry,
- removeActionMenuEntry,
- position,
- ]);
+ const unregisterExportMultipleRecordsAction = () => {
+ removeActionMenuEntry('export-multiple-records');
+ };
- return null;
+ return {
+ registerExportMultipleRecordsAction,
+ unregisterExportMultipleRecordsAction,
+ };
};
diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/hooks/useMultipleRecordsActions.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/hooks/useMultipleRecordsActions.tsx
new file mode 100644
index 0000000000..78e459e23d
--- /dev/null
+++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/hooks/useMultipleRecordsActions.tsx
@@ -0,0 +1,40 @@
+import { useDeleteMultipleRecordsAction } from '@/action-menu/actions/record-actions/multiple-records/hooks/useDeleteMultipleRecordsAction';
+import { useExportViewNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/hooks/useExportMultipleRecordsAction';
+import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
+
+export const useMultipleRecordsActions = ({
+ objectMetadataItem,
+}: {
+ objectMetadataItem: ObjectMetadataItem;
+}) => {
+ const {
+ registerDeleteMultipleRecordsAction,
+ unregisterDeleteMultipleRecordsAction,
+ } = useDeleteMultipleRecordsAction({
+ position: 0,
+ objectMetadataItem,
+ });
+
+ const {
+ registerExportViewNoSelectionRecordsAction,
+ unregisterExportViewNoSelectionRecordsAction,
+ } = useExportViewNoSelectionRecordAction({
+ position: 1,
+ objectMetadataItem,
+ });
+
+ const registerMultipleRecordsActions = () => {
+ registerDeleteMultipleRecordsAction();
+ registerExportViewNoSelectionRecordsAction();
+ };
+
+ const unregisterMultipleRecordsActions = () => {
+ unregisterDeleteMultipleRecordsAction();
+ unregisterExportViewNoSelectionRecordsAction();
+ };
+
+ return {
+ registerMultipleRecordsActions,
+ unregisterMultipleRecordsActions,
+ };
+};
diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/no-selection/components/NoSelectionActionMenuEntrySetterEffect.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/no-selection/components/NoSelectionActionMenuEntrySetterEffect.tsx
new file mode 100644
index 0000000000..2cba158291
--- /dev/null
+++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/no-selection/components/NoSelectionActionMenuEntrySetterEffect.tsx
@@ -0,0 +1,26 @@
+import { useNoSelectionRecordActions } from '@/action-menu/actions/record-actions/no-selection/hooks/useNoSelectionRecordActions';
+import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
+import { useEffect } from 'react';
+
+export const NoSelectionActionMenuEntrySetterEffect = ({
+ objectMetadataItem,
+}: {
+ objectMetadataItem: ObjectMetadataItem;
+}) => {
+ const {
+ registerNoSelectionRecordActions,
+ unregisterNoSelectionRecordActions,
+ } = useNoSelectionRecordActions({
+ objectMetadataItem,
+ });
+
+ useEffect(() => {
+ registerNoSelectionRecordActions();
+
+ return () => {
+ unregisterNoSelectionRecordActions();
+ };
+ }, [registerNoSelectionRecordActions, unregisterNoSelectionRecordActions]);
+
+ return null;
+};
diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/no-selection/hooks/useExportMultipleRecordsAction.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/no-selection/hooks/useExportMultipleRecordsAction.tsx
new file mode 100644
index 0000000000..f3c9e4bcdf
--- /dev/null
+++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/no-selection/hooks/useExportMultipleRecordsAction.tsx
@@ -0,0 +1,47 @@
+import { useActionMenuEntries } from '@/action-menu/hooks/useActionMenuEntries';
+import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
+import { IconDatabaseExport } from 'twenty-ui';
+
+import {
+ displayedExportProgress,
+ useExportRecords,
+} from '@/object-record/record-index/export/hooks/useExportRecords';
+
+export const useExportViewNoSelectionRecordAction = ({
+ position,
+ objectMetadataItem,
+}: {
+ position: number;
+ objectMetadataItem: ObjectMetadataItem;
+}) => {
+ const { addActionMenuEntry, removeActionMenuEntry } = useActionMenuEntries();
+
+ const { progress, download } = useExportRecords({
+ delayMs: 100,
+ objectMetadataItem,
+ recordIndexId: objectMetadataItem.namePlural,
+ filename: `${objectMetadataItem.nameSingular}.csv`,
+ });
+
+ const registerExportViewNoSelectionRecordsAction = () => {
+ addActionMenuEntry({
+ type: 'standard',
+ scope: 'record-selection',
+ key: 'export-view-no-selection',
+ position,
+ label: displayedExportProgress(progress),
+ Icon: IconDatabaseExport,
+ accent: 'default',
+ onClick: () => download(),
+ });
+ };
+
+ const unregisterExportViewNoSelectionRecordsAction = () => {
+ removeActionMenuEntry('export-view-no-selection');
+ };
+
+ return {
+ registerExportViewNoSelectionRecordsAction,
+ unregisterExportViewNoSelectionRecordsAction,
+ };
+};
diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/no-selection/hooks/useNoSelectionRecordActions.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/no-selection/hooks/useNoSelectionRecordActions.tsx
new file mode 100644
index 0000000000..a647e449b7
--- /dev/null
+++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/no-selection/hooks/useNoSelectionRecordActions.tsx
@@ -0,0 +1,29 @@
+import { useExportViewNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/hooks/useExportMultipleRecordsAction';
+import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
+
+export const useNoSelectionRecordActions = ({
+ objectMetadataItem,
+}: {
+ objectMetadataItem: ObjectMetadataItem;
+}) => {
+ const {
+ registerExportViewNoSelectionRecordsAction,
+ unregisterExportViewNoSelectionRecordsAction,
+ } = useExportViewNoSelectionRecordAction({
+ position: 0,
+ objectMetadataItem,
+ });
+
+ const registerNoSelectionRecordActions = () => {
+ registerExportViewNoSelectionRecordsAction();
+ };
+
+ const unregisterNoSelectionRecordActions = () => {
+ unregisterExportViewNoSelectionRecordsAction();
+ };
+
+ return {
+ registerNoSelectionRecordActions,
+ unregisterNoSelectionRecordActions,
+ };
+};
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
new file mode 100644
index 0000000000..ef190808be
--- /dev/null
+++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/components/SingleRecordActionMenuEntrySetterEffect.tsx
@@ -0,0 +1,24 @@
+import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
+import { useEffect } from 'react';
+import { useSingleRecordActions } from '../hooks/useSingleRecordActions';
+
+export const SingleRecordActionMenuEntrySetterEffect = ({
+ objectMetadataItem,
+}: {
+ objectMetadataItem: ObjectMetadataItem;
+}) => {
+ const { registerSingleRecordActions, unregisterSingleRecordActions } =
+ useSingleRecordActions({
+ objectMetadataItem,
+ });
+
+ useEffect(() => {
+ registerSingleRecordActions();
+
+ return () => {
+ unregisterSingleRecordActions();
+ };
+ }, [registerSingleRecordActions, unregisterSingleRecordActions]);
+
+ return null;
+};
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
new file mode 100644
index 0000000000..19057895bf
--- /dev/null
+++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useDeleteSingleRecordAction.tsx
@@ -0,0 +1,124 @@
+import { ActionMenuContext } from '@/action-menu/contexts/ActionMenuContext';
+import { useActionMenuEntries } from '@/action-menu/hooks/useActionMenuEntries';
+import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
+import { useDeleteFavorite } from '@/favorites/hooks/useDeleteFavorite';
+import { useFavorites } from '@/favorites/hooks/useFavorites';
+import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
+import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord';
+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';
+import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
+import { useCallback, useContext, useState } from 'react';
+import { IconTrash, isDefined } from 'twenty-ui';
+
+export const useDeleteSingleRecordAction = ({
+ position,
+ objectMetadataItem,
+}: {
+ position: number;
+ objectMetadataItem: ObjectMetadataItem;
+}) => {
+ const { addActionMenuEntry, removeActionMenuEntry } = useActionMenuEntries();
+
+ const [isDeleteRecordsModalOpen, setIsDeleteRecordsModalOpen] =
+ useState(false);
+
+ const { resetTableRowSelection } = useRecordTable({
+ recordTableId: objectMetadataItem.namePlural,
+ });
+
+ const { deleteOneRecord } = useDeleteOneRecord({
+ objectNameSingular: objectMetadataItem.nameSingular,
+ });
+
+ const { sortedFavorites: favorites } = useFavorites();
+ const { deleteFavorite } = useDeleteFavorite();
+
+ const contextStoreTargetedRecordsRule = useRecoilComponentValueV2(
+ contextStoreTargetedRecordsRuleComponentState,
+ );
+
+ const { closeRightDrawer } = useRightDrawer();
+
+ const recordIdToDelete =
+ contextStoreTargetedRecordsRule.mode === 'selection'
+ ? contextStoreTargetedRecordsRule.selectedRecordIds?.[0]
+ : undefined;
+
+ const handleDeleteClick = useCallback(async () => {
+ if (!isDefined(recordIdToDelete)) {
+ return;
+ }
+
+ resetTableRowSelection();
+
+ const foundFavorite = favorites?.find(
+ (favorite) => favorite.recordId === recordIdToDelete,
+ );
+
+ if (isDefined(foundFavorite)) {
+ deleteFavorite(foundFavorite.id);
+ }
+
+ await deleteOneRecord(recordIdToDelete);
+ }, [
+ deleteFavorite,
+ deleteOneRecord,
+ favorites,
+ recordIdToDelete,
+ resetTableRowSelection,
+ ]);
+
+ const isRemoteObject = objectMetadataItem.isRemote;
+
+ const { isInRightDrawer, onActionExecutedCallback } =
+ useContext(ActionMenuContext);
+
+ const registerDeleteSingleRecordAction = () => {
+ if (isRemoteObject || !isDefined(recordIdToDelete)) {
+ return;
+ }
+
+ addActionMenuEntry({
+ type: 'standard',
+ scope: 'record-selection',
+ key: 'delete-single-record',
+ label: 'Delete',
+ position,
+ Icon: IconTrash,
+ accent: 'danger',
+ isPinned: true,
+ onClick: () => {
+ setIsDeleteRecordsModalOpen(true);
+ },
+ ConfirmationModal: (
+ {
+ handleDeleteClick();
+ onActionExecutedCallback?.();
+ if (isInRightDrawer) {
+ closeRightDrawer();
+ }
+ }}
+ deleteButtonText={'Delete Record'}
+ />
+ ),
+ });
+ };
+
+ const unregisterDeleteSingleRecordAction = () => {
+ removeActionMenuEntry('delete-single-record');
+ };
+
+ return {
+ registerDeleteSingleRecordAction,
+ unregisterDeleteSingleRecordAction,
+ };
+};
diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/components/ManageFavoritesActionEffect.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useManageFavoritesSingleRecordAction.tsx
similarity index 84%
rename from packages/twenty-front/src/modules/action-menu/actions/record-actions/components/ManageFavoritesActionEffect.tsx
rename to packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useManageFavoritesSingleRecordAction.tsx
index ecb31f1975..812143e772 100644
--- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/components/ManageFavoritesActionEffect.tsx
+++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useManageFavoritesSingleRecordAction.tsx
@@ -6,11 +6,10 @@ import { useFavorites } from '@/favorites/hooks/useFavorites';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
-import { useEffect } from 'react';
import { useRecoilValue } from 'recoil';
import { IconHeart, IconHeartOff, isDefined } from 'twenty-ui';
-export const ManageFavoritesActionEffect = ({
+export const useManageFavoritesSingleRecordAction = ({
position,
objectMetadataItem,
}: {
@@ -44,7 +43,7 @@ export const ManageFavoritesActionEffect = ({
const isFavorite = !!selectedRecordId && !!foundFavorite;
- useEffect(() => {
+ const registerManageFavoritesSingleRecordAction = () => {
if (!isDefined(objectMetadataItem) || objectMetadataItem.isRemote) {
return;
}
@@ -52,7 +51,7 @@ export const ManageFavoritesActionEffect = ({
addActionMenuEntry({
type: 'standard',
scope: 'record-selection',
- key: 'manage-favorites',
+ key: 'manage-favorites-single-record',
label: isFavorite ? 'Remove from favorites' : 'Add to favorites',
position,
Icon: isFavorite ? IconHeartOff : IconHeart,
@@ -64,21 +63,14 @@ export const ManageFavoritesActionEffect = ({
}
},
});
+ };
- return () => {
- removeActionMenuEntry('manage-favorites');
- };
- }, [
- addActionMenuEntry,
- createFavorite,
- deleteFavorite,
- foundFavorite?.id,
- isFavorite,
- objectMetadataItem,
- position,
- removeActionMenuEntry,
- selectedRecord,
- ]);
+ const unregisterManageFavoritesSingleRecordAction = () => {
+ removeActionMenuEntry('manage-favorites-single-record');
+ };
- return null;
+ return {
+ registerManageFavoritesSingleRecordAction,
+ unregisterManageFavoritesSingleRecordAction,
+ };
};
diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useSingleRecordActions.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useSingleRecordActions.tsx
new file mode 100644
index 0000000000..4b6a3763c6
--- /dev/null
+++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useSingleRecordActions.tsx
@@ -0,0 +1,40 @@
+import { useDeleteSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useDeleteSingleRecordAction';
+import { useManageFavoritesSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useManageFavoritesSingleRecordAction';
+import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
+
+export const useSingleRecordActions = ({
+ objectMetadataItem,
+}: {
+ objectMetadataItem: ObjectMetadataItem;
+}) => {
+ const {
+ registerManageFavoritesSingleRecordAction,
+ unregisterManageFavoritesSingleRecordAction,
+ } = useManageFavoritesSingleRecordAction({
+ position: 0,
+ objectMetadataItem,
+ });
+
+ const {
+ registerDeleteSingleRecordAction,
+ unregisterDeleteSingleRecordAction,
+ } = useDeleteSingleRecordAction({
+ position: 1,
+ objectMetadataItem,
+ });
+
+ const registerSingleRecordActions = () => {
+ registerManageFavoritesSingleRecordAction();
+ registerDeleteSingleRecordAction();
+ };
+
+ const unregisterSingleRecordActions = () => {
+ unregisterManageFavoritesSingleRecordAction();
+ unregisterDeleteSingleRecordAction();
+ };
+
+ return {
+ registerSingleRecordActions,
+ unregisterSingleRecordActions,
+ };
+};