mirror of
https://github.com/lingble/twenty.git
synced 2025-10-29 20:02:29 +00:00
fix: Dropdown Overlapping Sidebar on Column Header Click in Horizontal Table When Scrolling (#8287)
fixes : #8272 --------- Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
This commit is contained in:
committed by
GitHub
parent
8b8b9fe55b
commit
5115022355
@@ -10,6 +10,8 @@ import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
|
|||||||
import { useSaveCurrentViewFields } from '@/views/hooks/useSaveCurrentViewFields';
|
import { useSaveCurrentViewFields } from '@/views/hooks/useSaveCurrentViewFields';
|
||||||
import { mapColumnDefinitionsToViewFields } from '@/views/utils/mapColumnDefinitionToViewField';
|
import { mapColumnDefinitionsToViewFields } from '@/views/utils/mapColumnDefinitionToViewField';
|
||||||
|
|
||||||
|
import { isScrollEnabledForRecordTableState } from '@/object-record/record-table/states/isScrollEnabledForRecordTableState';
|
||||||
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { RecordUpdateContext } from '../contexts/EntityUpdateMutationHookContext';
|
import { RecordUpdateContext } from '../contexts/EntityUpdateMutationHookContext';
|
||||||
import { useRecordTable } from '../hooks/useRecordTable';
|
import { useRecordTable } from '../hooks/useRecordTable';
|
||||||
|
|
||||||
@@ -46,6 +48,11 @@ export const RecordTableWithWrappers = ({
|
|||||||
recordTableId,
|
recordTableId,
|
||||||
viewBarId,
|
viewBarId,
|
||||||
}: RecordTableWithWrappersProps) => {
|
}: RecordTableWithWrappersProps) => {
|
||||||
|
const isScrollEnabledForRecordTable = useRecoilComponentValueV2(
|
||||||
|
isScrollEnabledForRecordTableState,
|
||||||
|
recordTableId,
|
||||||
|
);
|
||||||
|
|
||||||
const { resetTableRowSelection, selectAllRows } = useRecordTable({
|
const { resetTableRowSelection, selectAllRows } = useRecordTable({
|
||||||
recordTableId,
|
recordTableId,
|
||||||
});
|
});
|
||||||
@@ -80,7 +87,11 @@ export const RecordTableWithWrappers = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<EntityDeleteContext.Provider value={deleteOneRecord}>
|
<EntityDeleteContext.Provider value={deleteOneRecord}>
|
||||||
<ScrollWrapper contextProviderName="recordTableWithWrappers">
|
<ScrollWrapper
|
||||||
|
enableXScroll={isScrollEnabledForRecordTable.enableXScroll}
|
||||||
|
enableYScroll={isScrollEnabledForRecordTable.enableYScroll}
|
||||||
|
contextProviderName="recordTableWithWrappers"
|
||||||
|
>
|
||||||
<RecordUpdateContext.Provider value={updateRecordMutation}>
|
<RecordUpdateContext.Provider value={updateRecordMutation}>
|
||||||
<StyledTableWithHeader>
|
<StyledTableWithHeader>
|
||||||
<StyledTableContainer>
|
<StyledTableContainer>
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import styled from '@emotion/styled';
|
|
||||||
|
|
||||||
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
||||||
|
import { isScrollEnabledForRecordTableState } from '@/object-record/record-table/states/isScrollEnabledForRecordTableState';
|
||||||
import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
|
import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
|
||||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||||
|
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||||
import { RecordTableColumnHeadDropdownMenu } from './RecordTableColumnHeadDropdownMenu';
|
import styled from '@emotion/styled';
|
||||||
|
import { useCallback } from 'react';
|
||||||
import { RecordTableColumnHead } from './RecordTableColumnHead';
|
import { RecordTableColumnHead } from './RecordTableColumnHead';
|
||||||
|
import { RecordTableColumnHeadDropdownMenu } from './RecordTableColumnHeadDropdownMenu';
|
||||||
|
|
||||||
type RecordTableColumnHeadWithDropdownProps = {
|
type RecordTableColumnHeadWithDropdownProps = {
|
||||||
column: ColumnDefinition<FieldMetadata>;
|
column: ColumnDefinition<FieldMetadata>;
|
||||||
@@ -14,7 +14,6 @@ type RecordTableColumnHeadWithDropdownProps = {
|
|||||||
|
|
||||||
const StyledDropdown = styled(Dropdown)`
|
const StyledDropdown = styled(Dropdown)`
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
flex: 1;
|
flex: 1;
|
||||||
z-index: ${({ theme }) => theme.lastLayerZIndex};
|
z-index: ${({ theme }) => theme.lastLayerZIndex};
|
||||||
`;
|
`;
|
||||||
@@ -22,8 +21,28 @@ const StyledDropdown = styled(Dropdown)`
|
|||||||
export const RecordTableColumnHeadWithDropdown = ({
|
export const RecordTableColumnHeadWithDropdown = ({
|
||||||
column,
|
column,
|
||||||
}: RecordTableColumnHeadWithDropdownProps) => {
|
}: RecordTableColumnHeadWithDropdownProps) => {
|
||||||
|
const setIsScrollEnabledForRecordTable = useSetRecoilComponentStateV2(
|
||||||
|
isScrollEnabledForRecordTableState,
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleDropdownOpen = useCallback(() => {
|
||||||
|
setIsScrollEnabledForRecordTable({
|
||||||
|
enableXScroll: false,
|
||||||
|
enableYScroll: false,
|
||||||
|
});
|
||||||
|
}, [setIsScrollEnabledForRecordTable]);
|
||||||
|
|
||||||
|
const handleDropdownClose = useCallback(() => {
|
||||||
|
setIsScrollEnabledForRecordTable({
|
||||||
|
enableXScroll: true,
|
||||||
|
enableYScroll: true,
|
||||||
|
});
|
||||||
|
}, [setIsScrollEnabledForRecordTable]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledDropdown
|
<StyledDropdown
|
||||||
|
onOpen={handleDropdownOpen}
|
||||||
|
onClose={handleDropdownClose}
|
||||||
dropdownId={column.fieldMetadataId + '-header'}
|
dropdownId={column.fieldMetadataId + '-header'}
|
||||||
clickableComponent={<RecordTableColumnHead column={column} />}
|
clickableComponent={<RecordTableColumnHead column={column} />}
|
||||||
dropdownComponents={<RecordTableColumnHeadDropdownMenu column={column} />}
|
dropdownComponents={<RecordTableColumnHeadDropdownMenu column={column} />}
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { RecordTableComponentInstanceContext } from '@/object-record/record-table/states/context/RecordTableComponentInstanceContext';
|
||||||
|
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
|
||||||
|
|
||||||
|
export type ScrollEnabled = {
|
||||||
|
enableXScroll: boolean;
|
||||||
|
enableYScroll: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const isScrollEnabledForRecordTableState =
|
||||||
|
createComponentStateV2<ScrollEnabled>({
|
||||||
|
key: 'isScrollEnabledForRecordTableState',
|
||||||
|
defaultValue: {
|
||||||
|
enableXScroll: true,
|
||||||
|
enableYScroll: true,
|
||||||
|
},
|
||||||
|
componentInstanceContext: RecordTableComponentInstanceContext,
|
||||||
|
});
|
||||||
@@ -126,7 +126,6 @@ export const Dropdown = ({
|
|||||||
listenerId: dropdownId,
|
listenerId: dropdownId,
|
||||||
callback: () => {
|
callback: () => {
|
||||||
onClickOutside?.();
|
onClickOutside?.();
|
||||||
|
|
||||||
if (isDropdownOpen) {
|
if (isDropdownOpen) {
|
||||||
closeDropdown();
|
closeDropdown();
|
||||||
}
|
}
|
||||||
@@ -141,10 +140,12 @@ export const Dropdown = ({
|
|||||||
useScopedHotkeys(
|
useScopedHotkeys(
|
||||||
[Key.Escape],
|
[Key.Escape],
|
||||||
() => {
|
() => {
|
||||||
closeDropdown();
|
if (isDropdownOpen) {
|
||||||
|
closeDropdown();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
dropdownHotkeyScope.scope,
|
dropdownHotkeyScope.scope,
|
||||||
[closeDropdown],
|
[closeDropdown, isDropdownOpen],
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -45,7 +45,6 @@ export const ScrollWrapper = ({
|
|||||||
useScrollStates(contextProviderName);
|
useScrollStates(contextProviderName);
|
||||||
const setScrollTop = useSetRecoilState(scrollTopComponentState);
|
const setScrollTop = useSetRecoilState(scrollTopComponentState);
|
||||||
const setScrollLeft = useSetRecoilState(scrollLeftComponentState);
|
const setScrollLeft = useSetRecoilState(scrollLeftComponentState);
|
||||||
|
|
||||||
const handleScroll = (overlayScroll: OverlayScrollbars) => {
|
const handleScroll = (overlayScroll: OverlayScrollbars) => {
|
||||||
const target = overlayScroll.elements().scrollOffsetElement;
|
const target = overlayScroll.elements().scrollOffsetElement;
|
||||||
setScrollTop(target.scrollTop);
|
setScrollTop(target.scrollTop);
|
||||||
@@ -78,7 +77,12 @@ export const ScrollWrapper = ({
|
|||||||
}, [instance, setOverlayScrollbars]);
|
}, [instance, setOverlayScrollbars]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Context.Provider value={{ ref: scrollableRef, id: contextProviderName }}>
|
<Context.Provider
|
||||||
|
value={{
|
||||||
|
ref: scrollableRef,
|
||||||
|
id: contextProviderName,
|
||||||
|
}}
|
||||||
|
>
|
||||||
<StyledScrollWrapper ref={scrollableRef} className={className}>
|
<StyledScrollWrapper ref={scrollableRef} className={className}>
|
||||||
{children}
|
{children}
|
||||||
</StyledScrollWrapper>
|
</StyledScrollWrapper>
|
||||||
|
|||||||
Reference in New Issue
Block a user