Minor fixes on context menu (#9340)
- Fixed click outside for kanban not working (changed strategy) - Tried a different approach for setting the context menu position - Fixes https://github.com/twentyhq/twenty/issues/9336
This commit is contained in:
@ -4,7 +4,9 @@ import { useContext, useRef } from 'react';
|
|||||||
import { useRecoilCallback } from 'recoil';
|
import { useRecoilCallback } from 'recoil';
|
||||||
import { Key } from 'ts-key-enum';
|
import { Key } from 'ts-key-enum';
|
||||||
|
|
||||||
|
import { useActionMenu } from '@/action-menu/hooks/useActionMenu';
|
||||||
import { ActionBarHotkeyScope } from '@/action-menu/types/ActionBarHotKeyScope';
|
import { ActionBarHotkeyScope } from '@/action-menu/types/ActionBarHotKeyScope';
|
||||||
|
import { getActionMenuIdFromRecordIndexId } from '@/action-menu/utils/getActionMenuIdFromRecordIndexId';
|
||||||
import { RecordBoardHeader } from '@/object-record/record-board/components/RecordBoardHeader';
|
import { RecordBoardHeader } from '@/object-record/record-board/components/RecordBoardHeader';
|
||||||
import { RecordBoardStickyHeaderEffect } from '@/object-record/record-board/components/RecordBoardStickyHeaderEffect';
|
import { RecordBoardStickyHeaderEffect } from '@/object-record/record-board/components/RecordBoardStickyHeaderEffect';
|
||||||
import { RECORD_BOARD_CLICK_OUTSIDE_LISTENER_ID } from '@/object-record/record-board/constants/RecordBoardClickOutsideListenerId';
|
import { RECORD_BOARD_CLICK_OUTSIDE_LISTENER_ID } from '@/object-record/record-board/constants/RecordBoardClickOutsideListenerId';
|
||||||
@ -22,6 +24,7 @@ import { recordStoreFamilyState } from '@/object-record/record-store/states/reco
|
|||||||
import { TableHotkeyScope } from '@/object-record/record-table/types/TableHotkeyScope';
|
import { TableHotkeyScope } from '@/object-record/record-table/types/TableHotkeyScope';
|
||||||
import { DragSelect } from '@/ui/utilities/drag-select/components/DragSelect';
|
import { DragSelect } from '@/ui/utilities/drag-select/components/DragSelect';
|
||||||
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
||||||
|
import { useClickOutsideListener } from '@/ui/utilities/pointer-event/hooks/useClickOutsideListener';
|
||||||
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
||||||
import { getScopeIdFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdFromComponentId';
|
import { getScopeIdFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdFromComponentId';
|
||||||
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
|
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
|
||||||
@ -65,6 +68,23 @@ export const RecordBoard = () => {
|
|||||||
useContext(RecordBoardContext);
|
useContext(RecordBoardContext);
|
||||||
const boardRef = useRef<HTMLDivElement>(null);
|
const boardRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
const { toggleClickOutsideListener } = useClickOutsideListener(
|
||||||
|
RECORD_BOARD_CLICK_OUTSIDE_LISTENER_ID,
|
||||||
|
);
|
||||||
|
|
||||||
|
const actionMenuId = getActionMenuIdFromRecordIndexId(recordBoardId);
|
||||||
|
const { closeActionMenuDropdown } = useActionMenu(actionMenuId);
|
||||||
|
|
||||||
|
const handleDragSelectionStart = () => {
|
||||||
|
closeActionMenuDropdown();
|
||||||
|
|
||||||
|
toggleClickOutsideListener(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDragSelectionEnd = () => {
|
||||||
|
toggleClickOutsideListener(true);
|
||||||
|
};
|
||||||
|
|
||||||
const visibleRecordGroupIds = useRecoilComponentFamilyValueV2(
|
const visibleRecordGroupIds = useRecoilComponentFamilyValueV2(
|
||||||
visibleRecordGroupIdsComponentFamilySelector,
|
visibleRecordGroupIdsComponentFamilySelector,
|
||||||
ViewType.Kanban,
|
ViewType.Kanban,
|
||||||
@ -89,10 +109,13 @@ export const RecordBoard = () => {
|
|||||||
'command-menu',
|
'command-menu',
|
||||||
'modal-backdrop',
|
'modal-backdrop',
|
||||||
'page-action-container',
|
'page-action-container',
|
||||||
|
'record-board-card',
|
||||||
],
|
],
|
||||||
listenerId: RECORD_BOARD_CLICK_OUTSIDE_LISTENER_ID,
|
listenerId: RECORD_BOARD_CLICK_OUTSIDE_LISTENER_ID,
|
||||||
refs: [boardRef],
|
refs: [],
|
||||||
callback: resetRecordSelection,
|
callback: () => {
|
||||||
|
resetRecordSelection();
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const selectAll = useRecoilCallback(
|
const selectAll = useRecoilCallback(
|
||||||
@ -219,8 +242,9 @@ export const RecordBoard = () => {
|
|||||||
<RecordBoardScrollRestoreEffect />
|
<RecordBoardScrollRestoreEffect />
|
||||||
<DragSelect
|
<DragSelect
|
||||||
dragSelectable={boardRef}
|
dragSelectable={boardRef}
|
||||||
onDragSelectionStart={resetRecordSelection}
|
onDragSelectionEnd={handleDragSelectionEnd}
|
||||||
onDragSelectionChange={setRecordAsSelected}
|
onDragSelectionChange={setRecordAsSelected}
|
||||||
|
onDragSelectionStart={handleDragSelectionStart}
|
||||||
/>
|
/>
|
||||||
</StyledBoardContentContainer>
|
</StyledBoardContentContainer>
|
||||||
</StyledContainerContainer>
|
</StyledContainerContainer>
|
||||||
|
|||||||
@ -66,5 +66,23 @@ export const useRecordBoardSelection = (recordBoardId: string) => {
|
|||||||
[isRecordBoardCardSelectedFamilyState],
|
[isRecordBoardCardSelectedFamilyState],
|
||||||
);
|
);
|
||||||
|
|
||||||
return { resetRecordSelection, setRecordAsSelected };
|
const checkIfLastUnselectAndCloseDropdown = useRecoilCallback(
|
||||||
|
({ snapshot, set }) =>
|
||||||
|
() => {
|
||||||
|
const recordIds = getSnapshotValue(
|
||||||
|
snapshot,
|
||||||
|
recordBoardSelectedRecordIdsSelector,
|
||||||
|
);
|
||||||
|
if (recordIds.length === 0) {
|
||||||
|
set(isActionMenuDropdownOpenState, false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[recordBoardSelectedRecordIdsSelector, isActionMenuDropdownOpenState],
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
resetRecordSelection,
|
||||||
|
setRecordAsSelected,
|
||||||
|
checkIfLastUnselectAndCloseDropdown,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { recordIndexActionMenuDropdownPositionComponentState } from '@/action-me
|
|||||||
import { getActionMenuDropdownIdFromActionMenuId } from '@/action-menu/utils/getActionMenuDropdownIdFromActionMenuId';
|
import { getActionMenuDropdownIdFromActionMenuId } from '@/action-menu/utils/getActionMenuDropdownIdFromActionMenuId';
|
||||||
import { getActionMenuIdFromRecordIndexId } from '@/action-menu/utils/getActionMenuIdFromRecordIndexId';
|
import { getActionMenuIdFromRecordIndexId } from '@/action-menu/utils/getActionMenuIdFromRecordIndexId';
|
||||||
import { RecordBoardContext } from '@/object-record/record-board/contexts/RecordBoardContext';
|
import { RecordBoardContext } from '@/object-record/record-board/contexts/RecordBoardContext';
|
||||||
|
import { useRecordBoardSelection } from '@/object-record/record-board/hooks/useRecordBoardSelection';
|
||||||
import { RecordBoardCardContext } from '@/object-record/record-board/record-board-card/contexts/RecordBoardCardContext';
|
import { RecordBoardCardContext } from '@/object-record/record-board/record-board-card/contexts/RecordBoardCardContext';
|
||||||
import { RecordBoardScopeInternalContext } from '@/object-record/record-board/scopes/scope-internal-context/RecordBoardScopeInternalContext';
|
import { RecordBoardScopeInternalContext } from '@/object-record/record-board/scopes/scope-internal-context/RecordBoardScopeInternalContext';
|
||||||
import { isRecordBoardCardSelectedComponentFamilyState } from '@/object-record/record-board/states/isRecordBoardCardSelectedComponentFamilyState';
|
import { isRecordBoardCardSelectedComponentFamilyState } from '@/object-record/record-board/states/isRecordBoardCardSelectedComponentFamilyState';
|
||||||
@ -191,6 +192,9 @@ export const RecordBoardCard = ({
|
|||||||
RecordBoardScopeInternalContext,
|
RecordBoardScopeInternalContext,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { checkIfLastUnselectAndCloseDropdown } =
|
||||||
|
useRecordBoardSelection(recordBoardId);
|
||||||
|
|
||||||
const actionMenuId = getActionMenuIdFromRecordIndexId(recordBoardId);
|
const actionMenuId = getActionMenuIdFromRecordIndexId(recordBoardId);
|
||||||
|
|
||||||
const actionMenuDropdownId =
|
const actionMenuDropdownId =
|
||||||
@ -215,6 +219,13 @@ export const RecordBoardCard = ({
|
|||||||
openActionMenuDropdown();
|
openActionMenuDropdown();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleCardClick = () => {
|
||||||
|
if (!isCreating) {
|
||||||
|
setIsCurrentCardSelected(!isCurrentCardSelected);
|
||||||
|
checkIfLastUnselectAndCloseDropdown();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const PreventSelectOnClickContainer = ({
|
const PreventSelectOnClickContainer = ({
|
||||||
children,
|
children,
|
||||||
}: {
|
}: {
|
||||||
@ -262,18 +273,17 @@ export const RecordBoardCard = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledBoardCardWrapper onContextMenu={handleActionMenuDropdown}>
|
<StyledBoardCardWrapper
|
||||||
|
className="record-board-card"
|
||||||
|
onContextMenu={handleActionMenuDropdown}
|
||||||
|
>
|
||||||
{!isCreating && <RecordValueSetterEffect recordId={recordId} />}
|
{!isCreating && <RecordValueSetterEffect recordId={recordId} />}
|
||||||
<InView>
|
<InView>
|
||||||
<StyledBoardCard
|
<StyledBoardCard
|
||||||
ref={cardRef}
|
ref={cardRef}
|
||||||
selected={isCurrentCardSelected}
|
selected={isCurrentCardSelected}
|
||||||
onMouseLeave={onMouseLeaveBoard}
|
onMouseLeave={onMouseLeaveBoard}
|
||||||
onClick={() => {
|
onClick={handleCardClick}
|
||||||
if (!isCreating) {
|
|
||||||
setIsCurrentCardSelected(!isCurrentCardSelected);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<StyledBoardCardHeader showCompactView={isCompactModeActive}>
|
<StyledBoardCardHeader showCompactView={isCompactModeActive}>
|
||||||
{isCreating && position !== undefined ? (
|
{isCreating && position !== undefined ? (
|
||||||
|
|||||||
@ -50,8 +50,8 @@ export const useTriggerActionMenuDropdown = ({
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
set(recordIndexActionMenuDropdownPositionState, {
|
set(recordIndexActionMenuDropdownPositionState, {
|
||||||
x: event.clientX,
|
x: event.pageX,
|
||||||
y: event.clientY,
|
y: event.pageY,
|
||||||
});
|
});
|
||||||
|
|
||||||
const isRowSelected = getSnapshotValue(
|
const isRowSelected = getSnapshotValue(
|
||||||
|
|||||||
Reference in New Issue
Block a user