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 254a0f20e..7081c310c 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,9 +1,12 @@
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 { ShowPageSingleRecordActionMenuEntrySetterEffect } from '@/action-menu/actions/record-actions/single-record/components/ShowPageSingleRecordActionMenuEntrySetterEffect';
import { SingleRecordActionMenuEntrySetterEffect } from '@/action-menu/actions/record-actions/single-record/components/SingleRecordActionMenuEntrySetterEffect';
import { WorkflowRunRecordActionMenuEntrySetterEffect } from '@/action-menu/actions/record-actions/workflow-run-record-actions/components/WorkflowRunRecordActionMenuEntrySetter';
import { contextStoreCurrentObjectMetadataIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataIdComponentState';
+import { contextStoreCurrentViewTypeComponentState } from '@/context-store/states/contextStoreCurrentViewTypeComponentState';
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
+import { ContextStoreViewType } from '@/context-store/types/ContextStoreViewType';
import { useObjectMetadataItemById } from '@/object-metadata/hooks/useObjectMetadataItemById';
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
@@ -46,6 +49,10 @@ const ActionEffects = ({
contextStoreTargetedRecordsRuleComponentState,
);
+ const contextStoreCurrentViewType = useRecoilComponentValueV2(
+ contextStoreCurrentViewTypeComponentState,
+ );
+
const isWorkflowEnabled = useIsFeatureEnabled('IS_WORKFLOW_ENABLED');
return (
@@ -59,9 +66,17 @@ const ActionEffects = ({
{contextStoreTargetedRecordsRule.mode === 'selection' &&
contextStoreTargetedRecordsRule.selectedRecordIds.length === 1 && (
<>
-
+ {contextStoreCurrentViewType === ContextStoreViewType.ShowPage && (
+
+ )}
+ {(contextStoreCurrentViewType === ContextStoreViewType.Table ||
+ contextStoreCurrentViewType === ContextStoreViewType.Kanban) && (
+
+ )}
{isWorkflowEnabled && (
{
+ const isPageHeaderV2Enabled = useIsFeatureEnabled(
+ 'IS_PAGE_HEADER_V2_ENABLED',
+ );
+
+ const actionConfig = getActionConfig(
+ objectMetadataItem,
+ isPageHeaderV2Enabled,
+ );
+
+ const { addActionMenuEntry, removeActionMenuEntry } = useActionMenuEntries();
+
+ const contextStoreTargetedRecordsRule = useRecoilComponentValueV2(
+ contextStoreTargetedRecordsRuleComponentState,
+ );
+
+ const selectedRecordId =
+ contextStoreTargetedRecordsRule.mode === 'selection'
+ ? contextStoreTargetedRecordsRule.selectedRecordIds[0]
+ : undefined;
+
+ if (!isDefined(selectedRecordId)) {
+ throw new Error('Selected record ID is required');
+ }
+
+ const actionMenuEntries = Object.values(actionConfig ?? {})
+ .filter((action) =>
+ action.availableOn?.includes(ActionAvailableOn.SHOW_PAGE),
+ )
+ .map((action) => {
+ const { shouldBeRegistered, onClick, ConfirmationModal } =
+ action.actionHook({
+ recordId: selectedRecordId,
+ objectMetadataItem,
+ });
+
+ if (shouldBeRegistered) {
+ return {
+ ...action,
+ onClick,
+ ConfirmationModal,
+ };
+ }
+
+ return undefined;
+ })
+ .filter(isDefined);
+
+ useEffect(() => {
+ for (const action of actionMenuEntries) {
+ addActionMenuEntry(action);
+ }
+
+ return () => {
+ for (const action of actionMenuEntries) {
+ removeActionMenuEntry(action.key);
+ }
+ };
+ }, [actionMenuEntries, addActionMenuEntry, removeActionMenuEntry]);
+
+ return null;
+};
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 f2e803d30..9238772a6 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,4 +1,5 @@
import { getActionConfig } from '@/action-menu/actions/record-actions/single-record/utils/getActionConfig';
+import { ActionAvailableOn } from '@/action-menu/actions/types/actionAvailableOn';
import { useActionMenuEntries } from '@/action-menu/hooks/useActionMenuEntries';
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
@@ -37,6 +38,11 @@ export const SingleRecordActionMenuEntrySetterEffect = ({
}
const actionMenuEntries = Object.values(actionConfig ?? {})
+ .filter((action) =>
+ action.availableOn?.includes(
+ ActionAvailableOn.INDEX_PAGE_SINGLE_RECORD_SELECTION,
+ ),
+ )
.map((action) => {
const { shouldBeRegistered, onClick, ConfirmationModal } =
action.actionHook({
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 269b5f585..db6512154 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
@@ -1,6 +1,7 @@
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 { useRemoveFromFavoritesSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/hooks/useRemoveFromFavoritesSingleRecordAction';
+import { ActionAvailableOn } from '@/action-menu/actions/types/actionAvailableOn';
import { SingleRecordActionHook } from '@/action-menu/actions/types/singleRecordActionHook';
import {
ActionMenuEntry,
@@ -22,6 +23,10 @@ export const DEFAULT_SINGLE_RECORD_ACTIONS_CONFIG_V1: Record<
label: 'Add to favorites',
position: 0,
Icon: IconHeart,
+ availableOn: [
+ ActionAvailableOn.SHOW_PAGE,
+ ActionAvailableOn.INDEX_PAGE_SINGLE_RECORD_SELECTION,
+ ],
actionHook: useAddToFavoritesSingleRecordAction,
},
removeFromFavoritesSingleRecord: {
@@ -31,6 +36,10 @@ export const DEFAULT_SINGLE_RECORD_ACTIONS_CONFIG_V1: Record<
label: 'Remove from favorites',
position: 1,
Icon: IconHeartOff,
+ availableOn: [
+ ActionAvailableOn.SHOW_PAGE,
+ ActionAvailableOn.INDEX_PAGE_SINGLE_RECORD_SELECTION,
+ ],
actionHook: useRemoveFromFavoritesSingleRecordAction,
},
deleteSingleRecord: {
@@ -42,6 +51,10 @@ export const DEFAULT_SINGLE_RECORD_ACTIONS_CONFIG_V1: Record<
Icon: IconTrash,
accent: 'danger',
isPinned: true,
+ availableOn: [
+ ActionAvailableOn.SHOW_PAGE,
+ ActionAvailableOn.INDEX_PAGE_SINGLE_RECORD_SELECTION,
+ ],
actionHook: useDeleteSingleRecordAction,
},
};
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 dbfc40569..984771456 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
@@ -1,13 +1,22 @@
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 { 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 { ActionAvailableOn } from '@/action-menu/actions/types/actionAvailableOn';
import { SingleRecordActionHook } from '@/action-menu/actions/types/singleRecordActionHook';
import {
ActionMenuEntry,
ActionMenuEntryScope,
ActionMenuEntryType,
} from '@/action-menu/types/ActionMenuEntry';
-import { IconHeart, IconHeartOff, IconTrash } from 'twenty-ui';
+import {
+ IconChevronDown,
+ IconChevronUp,
+ IconHeart,
+ IconHeartOff,
+ IconTrash,
+} from 'twenty-ui';
export const DEFAULT_SINGLE_RECORD_ACTIONS_CONFIG_V2: Record<
string,
@@ -20,9 +29,14 @@ export const DEFAULT_SINGLE_RECORD_ACTIONS_CONFIG_V2: Record<
scope: ActionMenuEntryScope.RecordSelection,
key: 'add-to-favorites-single-record',
label: 'Add to favorites',
+ shortLabel: 'Add to favorites',
position: 0,
isPinned: true,
Icon: IconHeart,
+ availableOn: [
+ ActionAvailableOn.INDEX_PAGE_SINGLE_RECORD_SELECTION,
+ ActionAvailableOn.SHOW_PAGE,
+ ],
actionHook: useAddToFavoritesSingleRecordAction,
},
removeFromFavoritesSingleRecord: {
@@ -30,20 +44,54 @@ export const DEFAULT_SINGLE_RECORD_ACTIONS_CONFIG_V2: Record<
scope: ActionMenuEntryScope.RecordSelection,
key: 'remove-from-favorites-single-record',
label: 'Remove from favorites',
+ shortLabel: 'Remove from favorites',
isPinned: true,
position: 1,
Icon: IconHeartOff,
+ availableOn: [
+ ActionAvailableOn.INDEX_PAGE_SINGLE_RECORD_SELECTION,
+ ActionAvailableOn.SHOW_PAGE,
+ ],
actionHook: useRemoveFromFavoritesSingleRecordAction,
},
deleteSingleRecord: {
type: ActionMenuEntryType.Standard,
scope: ActionMenuEntryScope.RecordSelection,
key: 'delete-single-record',
- label: 'Delete',
+ label: 'Delete record',
+ shortLabel: 'Delete',
position: 2,
Icon: IconTrash,
accent: 'danger',
isPinned: true,
+ availableOn: [
+ ActionAvailableOn.INDEX_PAGE_SINGLE_RECORD_SELECTION,
+ ActionAvailableOn.SHOW_PAGE,
+ ],
actionHook: useDeleteSingleRecordAction,
},
+ navigateToPreviousRecord: {
+ type: ActionMenuEntryType.Standard,
+ scope: ActionMenuEntryScope.RecordSelection,
+ key: 'navigate-to-previous-record',
+ label: 'Navigate to previous record',
+ shortLabel: '',
+ position: 3,
+ isPinned: true,
+ Icon: IconChevronUp,
+ availableOn: [ActionAvailableOn.SHOW_PAGE],
+ actionHook: useNavigateToPreviousRecordSingleRecordAction,
+ },
+ navigateToNextRecord: {
+ type: ActionMenuEntryType.Standard,
+ scope: ActionMenuEntryScope.RecordSelection,
+ key: 'navigate-to-next-record',
+ label: 'Navigate to next record',
+ shortLabel: '',
+ position: 4,
+ isPinned: true,
+ Icon: IconChevronDown,
+ availableOn: [ActionAvailableOn.SHOW_PAGE],
+ actionHook: useNavigateToNextRecordSingleRecordAction,
+ },
};
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
new file mode 100644
index 000000000..a775d5275
--- /dev/null
+++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useNavigateToNextRecordSingleRecordAction.ts
@@ -0,0 +1,15 @@
+import { SingleRecordActionHookWithObjectMetadataItem } from '@/action-menu/actions/types/singleRecordActionHook';
+import { useRecordShowPagePagination } from '@/object-record/record-show/hooks/useRecordShowPagePagination';
+
+export const useNavigateToNextRecordSingleRecordAction: SingleRecordActionHookWithObjectMetadataItem =
+ ({ recordId, objectMetadataItem }) => {
+ const { navigateToNextRecord } = useRecordShowPagePagination(
+ objectMetadataItem.nameSingular,
+ recordId,
+ );
+
+ return {
+ shouldBeRegistered: true,
+ onClick: navigateToNextRecord,
+ };
+ };
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
new file mode 100644
index 000000000..f1287a68f
--- /dev/null
+++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useNavigateToPreviousRecordSingleRecordAction.ts
@@ -0,0 +1,15 @@
+import { SingleRecordActionHookWithObjectMetadataItem } from '@/action-menu/actions/types/singleRecordActionHook';
+import { useRecordShowPagePagination } from '@/object-record/record-show/hooks/useRecordShowPagePagination';
+
+export const useNavigateToPreviousRecordSingleRecordAction: SingleRecordActionHookWithObjectMetadataItem =
+ ({ recordId, objectMetadataItem }) => {
+ const { navigateToPreviousRecord } = useRecordShowPagePagination(
+ objectMetadataItem.nameSingular,
+ recordId,
+ );
+
+ return {
+ shouldBeRegistered: true,
+ onClick: navigateToPreviousRecord,
+ };
+ };
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 fcad03ea9..c168ffe54 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,3 +1,5 @@
+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 { 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';
import { useDeactivateWorkflowSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useDeactivateWorkflowSingleRecordAction';
@@ -6,6 +8,7 @@ import { useSeeActiveVersionWorkflowSingleRecordAction } from '@/action-menu/act
import { useSeeRunsWorkflowSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/workflow-actions/hooks/useSeeRunsWorkflowSingleRecordAction';
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 { ActionAvailableOn } from '@/action-menu/actions/types/actionAvailableOn';
import { SingleRecordActionHook } from '@/action-menu/actions/types/singleRecordActionHook';
import {
ActionMenuEntry,
@@ -13,6 +16,8 @@ import {
ActionMenuEntryType,
} from '@/action-menu/types/ActionMenuEntry';
import {
+ IconChevronDown,
+ IconChevronUp,
IconHistory,
IconHistoryToggle,
IconPlayerPause,
@@ -30,81 +35,143 @@ export const WORKFLOW_SINGLE_RECORD_ACTIONS_CONFIG: Record<
activateWorkflowDraftSingleRecord: {
key: 'activate-workflow-draft-single-record',
label: 'Activate Draft',
+ shortLabel: 'Activate Draft',
isPinned: true,
position: 1,
Icon: IconPower,
type: ActionMenuEntryType.Standard,
scope: ActionMenuEntryScope.RecordSelection,
+ availableOn: [
+ ActionAvailableOn.SHOW_PAGE,
+ ActionAvailableOn.INDEX_PAGE_SINGLE_RECORD_SELECTION,
+ ],
actionHook: useActivateDraftWorkflowSingleRecordAction,
},
activateWorkflowLastPublishedVersionSingleRecord: {
key: 'activate-workflow-last-published-version-single-record',
label: 'Activate last published version',
+ shortLabel: 'Activate last version',
isPinned: true,
position: 2,
Icon: IconPower,
type: ActionMenuEntryType.Standard,
scope: ActionMenuEntryScope.RecordSelection,
+ availableOn: [
+ ActionAvailableOn.SHOW_PAGE,
+ ActionAvailableOn.INDEX_PAGE_SINGLE_RECORD_SELECTION,
+ ],
actionHook: useActivateLastPublishedVersionWorkflowSingleRecordAction,
},
deactivateWorkflowSingleRecord: {
key: 'deactivate-workflow-single-record',
label: 'Deactivate Workflow',
+ shortLabel: 'Deactivate',
isPinned: true,
position: 3,
Icon: IconPlayerPause,
type: ActionMenuEntryType.Standard,
scope: ActionMenuEntryScope.RecordSelection,
+ availableOn: [
+ ActionAvailableOn.SHOW_PAGE,
+ ActionAvailableOn.INDEX_PAGE_SINGLE_RECORD_SELECTION,
+ ],
actionHook: useDeactivateWorkflowSingleRecordAction,
},
discardWorkflowDraftSingleRecord: {
key: 'discard-workflow-draft-single-record',
label: 'Discard Draft',
+ shortLabel: 'Discard Draft',
isPinned: true,
position: 4,
Icon: IconTrash,
type: ActionMenuEntryType.Standard,
scope: ActionMenuEntryScope.RecordSelection,
+ availableOn: [
+ ActionAvailableOn.SHOW_PAGE,
+ ActionAvailableOn.INDEX_PAGE_SINGLE_RECORD_SELECTION,
+ ],
actionHook: useDiscardDraftWorkflowSingleRecordAction,
},
seeWorkflowActiveVersionSingleRecord: {
key: 'see-workflow-active-version-single-record',
label: 'See active version',
+ shortLabel: 'See active version',
isPinned: false,
position: 5,
Icon: IconHistory,
type: ActionMenuEntryType.Standard,
scope: ActionMenuEntryScope.RecordSelection,
+ availableOn: [
+ ActionAvailableOn.SHOW_PAGE,
+ ActionAvailableOn.INDEX_PAGE_SINGLE_RECORD_SELECTION,
+ ],
actionHook: useSeeActiveVersionWorkflowSingleRecordAction,
},
seeWorkflowRunsSingleRecord: {
key: 'see-workflow-runs-single-record',
label: 'See runs',
+ shortLabel: 'See runs',
isPinned: false,
position: 6,
Icon: IconHistoryToggle,
type: ActionMenuEntryType.Standard,
scope: ActionMenuEntryScope.RecordSelection,
+ availableOn: [
+ ActionAvailableOn.SHOW_PAGE,
+ ActionAvailableOn.INDEX_PAGE_SINGLE_RECORD_SELECTION,
+ ],
actionHook: useSeeRunsWorkflowSingleRecordAction,
},
seeWorkflowVersionsHistorySingleRecord: {
key: 'see-workflow-versions-history-single-record',
label: 'See versions history',
+ shortLabel: 'See versions',
isPinned: false,
position: 7,
Icon: IconHistory,
type: ActionMenuEntryType.Standard,
scope: ActionMenuEntryScope.RecordSelection,
+ availableOn: [
+ ActionAvailableOn.SHOW_PAGE,
+ ActionAvailableOn.INDEX_PAGE_SINGLE_RECORD_SELECTION,
+ ],
actionHook: useSeeVersionsWorkflowSingleRecordAction,
},
testWorkflowSingleRecord: {
key: 'test-workflow-single-record',
label: 'Test Workflow',
+ shortLabel: 'Test',
isPinned: true,
position: 8,
Icon: IconPlayerPlay,
type: ActionMenuEntryType.Standard,
scope: ActionMenuEntryScope.RecordSelection,
+ availableOn: [
+ ActionAvailableOn.SHOW_PAGE,
+ ActionAvailableOn.INDEX_PAGE_SINGLE_RECORD_SELECTION,
+ ],
actionHook: useTestWorkflowSingleRecordAction,
},
+ navigateToPreviousRecord: {
+ type: ActionMenuEntryType.Standard,
+ scope: ActionMenuEntryScope.RecordSelection,
+ key: 'navigate-to-previous-record',
+ label: 'Navigate to previous workflow',
+ shortLabel: '',
+ position: 9,
+ Icon: IconChevronUp,
+ availableOn: [ActionAvailableOn.SHOW_PAGE],
+ actionHook: useNavigateToPreviousRecordSingleRecordAction,
+ },
+ navigateToNextRecord: {
+ type: ActionMenuEntryType.Standard,
+ scope: ActionMenuEntryScope.RecordSelection,
+ key: 'navigate-to-next-record',
+ label: 'Navigate to next workflow',
+ shortLabel: '',
+ position: 10,
+ Icon: IconChevronDown,
+ availableOn: [ActionAvailableOn.SHOW_PAGE],
+ actionHook: useNavigateToNextRecordSingleRecordAction,
+ },
};
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 7e9480914..659d0e166 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,13 +1,22 @@
+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 { useSeeExecutionsWorkflowVersionSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/workflow-version-actions/hooks/useSeeExecutionsWorkflowVersionSingleRecordAction';
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 { ActionAvailableOn } from '@/action-menu/actions/types/actionAvailableOn';
import { SingleRecordActionHook } from '@/action-menu/actions/types/singleRecordActionHook';
import {
ActionMenuEntry,
ActionMenuEntryScope,
ActionMenuEntryType,
} from '@/action-menu/types/ActionMenuEntry';
-import { IconHistory, IconHistoryToggle, IconPencil } from 'twenty-ui';
+import {
+ IconChevronDown,
+ IconChevronUp,
+ IconHistory,
+ IconHistoryToggle,
+ IconPencil,
+} from 'twenty-ui';
export const WORKFLOW_VERSIONS_SINGLE_RECORD_ACTIONS_CONFIG: Record<
string,
@@ -23,6 +32,10 @@ export const WORKFLOW_VERSIONS_SINGLE_RECORD_ACTIONS_CONFIG: Record<
type: ActionMenuEntryType.Standard,
scope: ActionMenuEntryScope.RecordSelection,
Icon: IconPencil,
+ availableOn: [
+ ActionAvailableOn.SHOW_PAGE,
+ ActionAvailableOn.INDEX_PAGE_SINGLE_RECORD_SELECTION,
+ ],
actionHook: useUseAsDraftWorkflowVersionSingleRecordAction,
},
seeWorkflowExecutionsSingleRecord: {
@@ -32,6 +45,10 @@ export const WORKFLOW_VERSIONS_SINGLE_RECORD_ACTIONS_CONFIG: Record<
type: ActionMenuEntryType.Standard,
scope: ActionMenuEntryScope.RecordSelection,
Icon: IconHistoryToggle,
+ availableOn: [
+ ActionAvailableOn.SHOW_PAGE,
+ ActionAvailableOn.INDEX_PAGE_SINGLE_RECORD_SELECTION,
+ ],
actionHook: useSeeExecutionsWorkflowVersionSingleRecordAction,
},
seeWorkflowVersionsHistorySingleRecord: {
@@ -41,6 +58,32 @@ export const WORKFLOW_VERSIONS_SINGLE_RECORD_ACTIONS_CONFIG: Record<
type: ActionMenuEntryType.Standard,
scope: ActionMenuEntryScope.RecordSelection,
Icon: IconHistory,
+ availableOn: [
+ ActionAvailableOn.SHOW_PAGE,
+ ActionAvailableOn.INDEX_PAGE_SINGLE_RECORD_SELECTION,
+ ],
actionHook: useSeeVersionsWorkflowVersionSingleRecordAction,
},
+ navigateToPreviousRecord: {
+ type: ActionMenuEntryType.Standard,
+ scope: ActionMenuEntryScope.RecordSelection,
+ key: 'navigate-to-previous-record',
+ label: 'Navigate to previous version',
+ shortLabel: '',
+ position: 9,
+ Icon: IconChevronUp,
+ availableOn: [ActionAvailableOn.SHOW_PAGE],
+ actionHook: useNavigateToPreviousRecordSingleRecordAction,
+ },
+ navigateToNextRecord: {
+ type: ActionMenuEntryType.Standard,
+ scope: ActionMenuEntryScope.RecordSelection,
+ key: 'navigate-to-next-record',
+ label: 'Navigate to next version',
+ shortLabel: '',
+ position: 10,
+ Icon: IconChevronDown,
+ availableOn: [ActionAvailableOn.SHOW_PAGE],
+ actionHook: useNavigateToNextRecordSingleRecordAction,
+ },
};
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
new file mode 100644
index 000000000..fafc2a1e3
--- /dev/null
+++ b/packages/twenty-front/src/modules/action-menu/actions/types/actionAvailableOn.ts
@@ -0,0 +1,6 @@
+export enum ActionAvailableOn {
+ INDEX_PAGE_BULK_SELECTION = 'INDEX_PAGE_BULK_SELECTION',
+ INDEX_PAGE_SINGLE_RECORD_SELECTION = 'INDEX_PAGE_SINGLE_RECORD_SELECTION',
+ INDEX_PAGE_NO_SELECTION = 'INDEX_PAGE_NO_SELECTION',
+ SHOW_PAGE = 'SHOW_PAGE',
+}
diff --git a/packages/twenty-front/src/modules/action-menu/components/RecordShowActionMenuButtons.tsx b/packages/twenty-front/src/modules/action-menu/components/RecordShowActionMenuButtons.tsx
index 3f827c609..5a95f2c1f 100644
--- a/packages/twenty-front/src/modules/action-menu/components/RecordShowActionMenuButtons.tsx
+++ b/packages/twenty-front/src/modules/action-menu/components/RecordShowActionMenuButtons.tsx
@@ -1,7 +1,7 @@
import { actionMenuEntriesComponentSelector } from '@/action-menu/states/actionMenuEntriesComponentSelector';
import { PageHeaderOpenCommandMenuButton } from '@/ui/layout/page-header/components/PageHeaderOpenCommandMenuButton';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
-import { Button, useIsMobile } from 'twenty-ui';
+import { Button, IconButton, useIsMobile } from 'twenty-ui';
export const RecordShowActionMenuButtons = () => {
const actionMenuEntries = useRecoilComponentValueV2(
@@ -15,18 +15,29 @@ export const RecordShowActionMenuButtons = () => {
return (
<>
{!isMobile &&
- pinnedEntries.map((entry, index) => (
-