fix: Edit Layout keeping the command menu open (#21161)
## Summary - Fixes https://github.com/twentyhq/core-team-issues/issues/2460 - Engine/headless commands always skipped closing the menu (`closeSidePanelOnCommandMenuListExecution: false`), even when the item was not pinned. Edit Layout is `isPinned: false`, so the menu should close like other list-only actions. ## Approach - Option 1 (I chose this one): Derive close behavior from `item.isPinned` -> pinned commands keep the menu open; non-pinned ones close it. - Option 2 (not chosen): remove the engine command override totally and use the default close behavior for all commands. Option 1 is more targeted: it fixed Edit Layout without changing pinned commands (e.g. Export progress in the menu list). Option 2 is simpler but widens the blast radius to every engine command clicked from the side panel list. ## Screenshots ### Before https://github.com/user-attachments/assets/70b8dc75-af00-4917-81a1-646381f571d5 ### After https://github.com/user-attachments/assets/f733d696-9330-4e6c-993b-8a8133c53e0d --------- Signed-off-by: Parship Chowdhury <parshipchowdhury@gmail.com> Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
committed by
GitHub
parent
1ec59beb8b
commit
4de9f45015
+7
-3
@@ -1,13 +1,17 @@
|
||||
import { useResetLocationHash } from 'twenty-ui/utilities';
|
||||
|
||||
import { HeadlessEngineCommandWrapperEffect } from '@/command-menu-item/engine-command/components/HeadlessEngineCommandWrapperEffect';
|
||||
import { useEnterLayoutCustomizationMode } from '@/layout-customization/hooks/useEnterLayoutCustomizationMode';
|
||||
import { useResetLocationHash } from 'twenty-ui/utilities';
|
||||
import { useSidePanelMenu } from '@/side-panel/hooks/useSidePanelMenu';
|
||||
|
||||
export const EditRecordPageLayoutSingleRecordCommand = () => {
|
||||
const { enterLayoutCustomizationMode } = useEnterLayoutCustomizationMode();
|
||||
|
||||
const { closeSidePanelMenu } = useSidePanelMenu();
|
||||
const { resetLocationHash } = useResetLocationHash();
|
||||
|
||||
const handleExecute = () => {
|
||||
const handleExecute = async () => {
|
||||
await closeSidePanelMenu();
|
||||
|
||||
enterLayoutCustomizationMode();
|
||||
resetLocationHash();
|
||||
};
|
||||
|
||||
@@ -11,6 +11,7 @@ import { sidePanelSearchObjectFilterState } from '@/side-panel/states/sidePanelS
|
||||
import { sidePanelSearchState } from '@/side-panel/states/sidePanelSearchState';
|
||||
import { useCloseAnyOpenDropdown } from '@/ui/layout/dropdown/hooks/useCloseAnyOpenDropdown';
|
||||
import { emitSidePanelOpenEvent } from '@/ui/layout/side-panel/utils/emitSidePanelOpenEvent';
|
||||
import { waitForSidePanelClose } from '@/ui/layout/side-panel/utils/waitForSidePanelClose';
|
||||
import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks/useRemoveFocusItemFromFocusStackById';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useStore } from 'jotai';
|
||||
@@ -30,26 +31,30 @@ export const useSidePanelMenu = () => {
|
||||
const { removeFocusItemFromFocusStackById } =
|
||||
useRemoveFocusItemFromFocusStackById();
|
||||
|
||||
const closeSidePanelMenu = useCallback(() => {
|
||||
const closeSidePanelMenu = useCallback(async () => {
|
||||
const isSidePanelOpened = store.get(isSidePanelOpenedState.atom);
|
||||
|
||||
if (isSidePanelOpened) {
|
||||
const isLayoutCustomizationModeEnabled = store.get(
|
||||
isLayoutCustomizationModeEnabledState.atom,
|
||||
);
|
||||
|
||||
if (isLayoutCustomizationModeEnabled) {
|
||||
resetRecordIndexSelection();
|
||||
}
|
||||
|
||||
store.set(sidePanelNavigationStackState.atom, []);
|
||||
store.set(isSidePanelOpenedState.atom, false);
|
||||
store.set(isSidePanelClosingState.atom, true);
|
||||
closeAnyOpenDropdown();
|
||||
removeFocusItemFromFocusStackById({
|
||||
focusId: SIDE_PANEL_FOCUS_ID,
|
||||
});
|
||||
if (!isSidePanelOpened) {
|
||||
return;
|
||||
}
|
||||
|
||||
const isLayoutCustomizationModeEnabled = store.get(
|
||||
isLayoutCustomizationModeEnabledState.atom,
|
||||
);
|
||||
|
||||
if (isLayoutCustomizationModeEnabled) {
|
||||
resetRecordIndexSelection();
|
||||
}
|
||||
|
||||
store.set(sidePanelNavigationStackState.atom, []);
|
||||
store.set(isSidePanelOpenedState.atom, false);
|
||||
store.set(isSidePanelClosingState.atom, true);
|
||||
closeAnyOpenDropdown();
|
||||
removeFocusItemFromFocusStackById({
|
||||
focusId: SIDE_PANEL_FOCUS_ID,
|
||||
});
|
||||
|
||||
await waitForSidePanelClose();
|
||||
}, [
|
||||
closeAnyOpenDropdown,
|
||||
removeFocusItemFromFocusStackById,
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import { SIDE_PANEL_CLOSE_EVENT_NAME } from '@/ui/layout/side-panel/utils/emitSidePanelCloseEvent';
|
||||
|
||||
const SIDE_PANEL_CLOSE_TIMEOUT_MS = 500;
|
||||
|
||||
export const waitForSidePanelClose = (): Promise<void> => {
|
||||
return new Promise((resolve) => {
|
||||
const handler = () => {
|
||||
window.removeEventListener(SIDE_PANEL_CLOSE_EVENT_NAME, handler);
|
||||
clearTimeout(timeoutId);
|
||||
resolve();
|
||||
};
|
||||
|
||||
const timeoutId = setTimeout(() => {
|
||||
window.removeEventListener(SIDE_PANEL_CLOSE_EVENT_NAME, handler);
|
||||
resolve();
|
||||
}, SIDE_PANEL_CLOSE_TIMEOUT_MS);
|
||||
|
||||
window.addEventListener(SIDE_PANEL_CLOSE_EVENT_NAME, handler);
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user