Set hotkey scope when navigating in side panel's history (#12634)
This PR fixes a bug where the side panel couldn't be closed after the execution of a workflow with a form. After the execution of the workflow, `goBackFromCommandMenu` is called to show the workflow run. The hotkey scope wasn't reset properly, and the click outside listener from the side panel is only triggered when the scope is `CommandMenuFocused`. This PR sets the hotkey scope to `CommandMenuFocused` when going back or when navigating inside the command menu history. Note: (we don't use `setHotkeyScopeAndMemorizePreviousScope` here because we don't need to memorize the active hotkey scope of the page we are leaving) Before: https://github.com/user-attachments/assets/09edf97b-7520-46ce-ade3-6bb6b15ef435 After: https://github.com/user-attachments/assets/16c288cb-1d42-4099-8925-74a673f7a479
This commit is contained in:
@ -6,12 +6,15 @@ import { commandMenuNavigationStackState } from '@/command-menu/states/commandMe
|
|||||||
import { commandMenuPageInfoState } from '@/command-menu/states/commandMenuPageInfoState';
|
import { commandMenuPageInfoState } from '@/command-menu/states/commandMenuPageInfoState';
|
||||||
import { commandMenuPageState } from '@/command-menu/states/commandMenuPageState';
|
import { commandMenuPageState } from '@/command-menu/states/commandMenuPageState';
|
||||||
import { hasUserSelectedCommandState } from '@/command-menu/states/hasUserSelectedCommandState';
|
import { hasUserSelectedCommandState } from '@/command-menu/states/hasUserSelectedCommandState';
|
||||||
|
import { CommandMenuHotkeyScope } from '@/command-menu/types/CommandMenuHotkeyScope';
|
||||||
import { getShowPageTabListComponentId } from '@/ui/layout/show-page/utils/getShowPageTabListComponentId';
|
import { getShowPageTabListComponentId } from '@/ui/layout/show-page/utils/getShowPageTabListComponentId';
|
||||||
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
|
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
|
||||||
|
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
|
|
||||||
export const useCommandMenuHistory = () => {
|
export const useCommandMenuHistory = () => {
|
||||||
const { closeCommandMenu } = useCommandMenu();
|
const { closeCommandMenu } = useCommandMenu();
|
||||||
|
const setHotkeyScope = useSetHotkeyScope();
|
||||||
|
|
||||||
const goBackFromCommandMenu = useRecoilCallback(
|
const goBackFromCommandMenu = useRecoilCallback(
|
||||||
({ snapshot, set }) => {
|
({ snapshot, set }) => {
|
||||||
@ -66,64 +69,78 @@ export const useCommandMenuHistory = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
set(hasUserSelectedCommandState, false);
|
set(hasUserSelectedCommandState, false);
|
||||||
|
|
||||||
|
setHotkeyScope(CommandMenuHotkeyScope.CommandMenuFocused, {
|
||||||
|
commandMenuOpen: true,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
[closeCommandMenu],
|
[closeCommandMenu, setHotkeyScope],
|
||||||
);
|
);
|
||||||
|
|
||||||
const navigateCommandMenuHistory = useRecoilCallback(({ snapshot, set }) => {
|
const navigateCommandMenuHistory = useRecoilCallback(
|
||||||
return (pageIndex: number) => {
|
({ snapshot, set }) => {
|
||||||
const currentNavigationStack = snapshot
|
return (pageIndex: number) => {
|
||||||
.getLoadable(commandMenuNavigationStackState)
|
const currentNavigationStack = snapshot
|
||||||
.getValue();
|
.getLoadable(commandMenuNavigationStackState)
|
||||||
|
.getValue();
|
||||||
|
|
||||||
const newNavigationStack = currentNavigationStack.slice(0, pageIndex + 1);
|
const newNavigationStack = currentNavigationStack.slice(
|
||||||
|
0,
|
||||||
set(commandMenuNavigationStackState, newNavigationStack);
|
pageIndex + 1,
|
||||||
|
|
||||||
const newNavigationStackItem = newNavigationStack.at(-1);
|
|
||||||
|
|
||||||
if (!isDefined(newNavigationStackItem)) {
|
|
||||||
throw new Error(
|
|
||||||
`No command menu navigation stack item found for index ${pageIndex}`,
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
set(commandMenuPageState, newNavigationStackItem.page);
|
set(commandMenuNavigationStackState, newNavigationStack);
|
||||||
set(commandMenuPageInfoState, {
|
|
||||||
title: newNavigationStackItem.pageTitle,
|
|
||||||
Icon: newNavigationStackItem.pageIcon,
|
|
||||||
instanceId: newNavigationStackItem.pageId,
|
|
||||||
});
|
|
||||||
const currentMorphItems = snapshot
|
|
||||||
.getLoadable(commandMenuNavigationMorphItemByPageState)
|
|
||||||
.getValue();
|
|
||||||
|
|
||||||
for (const [pageId, morphItem] of currentMorphItems.entries()) {
|
const newNavigationStackItem = newNavigationStack.at(-1);
|
||||||
if (!newNavigationStack.some((item) => item.pageId === pageId)) {
|
|
||||||
set(
|
if (!isDefined(newNavigationStackItem)) {
|
||||||
activeTabIdComponentState.atomFamily({
|
throw new Error(
|
||||||
instanceId: getShowPageTabListComponentId({
|
`No command menu navigation stack item found for index ${pageIndex}`,
|
||||||
pageId,
|
|
||||||
targetObjectId: morphItem.recordId,
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
null,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const newMorphItems = new Map(
|
set(commandMenuPageState, newNavigationStackItem.page);
|
||||||
Array.from(currentMorphItems.entries()).filter(([pageId]) =>
|
set(commandMenuPageInfoState, {
|
||||||
newNavigationStack.some((item) => item.pageId === pageId),
|
title: newNavigationStackItem.pageTitle,
|
||||||
),
|
Icon: newNavigationStackItem.pageIcon,
|
||||||
);
|
instanceId: newNavigationStackItem.pageId,
|
||||||
|
});
|
||||||
|
const currentMorphItems = snapshot
|
||||||
|
.getLoadable(commandMenuNavigationMorphItemByPageState)
|
||||||
|
.getValue();
|
||||||
|
|
||||||
set(commandMenuNavigationMorphItemByPageState, newMorphItems);
|
for (const [pageId, morphItem] of currentMorphItems.entries()) {
|
||||||
|
if (!newNavigationStack.some((item) => item.pageId === pageId)) {
|
||||||
|
set(
|
||||||
|
activeTabIdComponentState.atomFamily({
|
||||||
|
instanceId: getShowPageTabListComponentId({
|
||||||
|
pageId,
|
||||||
|
targetObjectId: morphItem.recordId,
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
set(hasUserSelectedCommandState, false);
|
const newMorphItems = new Map(
|
||||||
};
|
Array.from(currentMorphItems.entries()).filter(([pageId]) =>
|
||||||
}, []);
|
newNavigationStack.some((item) => item.pageId === pageId),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
set(commandMenuNavigationMorphItemByPageState, newMorphItems);
|
||||||
|
|
||||||
|
set(hasUserSelectedCommandState, false);
|
||||||
|
|
||||||
|
setHotkeyScope(CommandMenuHotkeyScope.CommandMenuFocused, {
|
||||||
|
commandMenuOpen: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
},
|
||||||
|
[setHotkeyScope],
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
goBackFromCommandMenu,
|
goBackFromCommandMenu,
|
||||||
|
|||||||
Reference in New Issue
Block a user