From 81a20c8acd96fa228ce4fff647cd5fc07ddee71e Mon Sep 17 00:00:00 2001 From: Marie Stoppa Date: Thu, 19 Dec 2024 12:23:23 +0100 Subject: [PATCH] Fix stickiness --- .../record-table/components/RecordTable.tsx | 2 +- .../components/RecordTableRecordGroupRows.tsx | 11 ----- .../components/RecordTableBodyDroppable.tsx | 3 +- .../RecordTableRecordGroupsBody.tsx | 47 +++++++++++------- .../components/RecordTableFooter.tsx | 25 ++++------ .../RecordTableRecordGroupSection.tsx | 2 + .../RecordTableRecordGroupStickyEffect.tsx | 48 +++++++++++++++++++ 7 files changed, 93 insertions(+), 45 deletions(-) create mode 100644 packages/twenty-front/src/modules/object-record/record-table/record-table-section/components/RecordTableRecordGroupStickyEffect.tsx diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTable.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTable.tsx index 090e44006d6c..aab93ff82d6e 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTable.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTable.tsx @@ -97,7 +97,7 @@ export const RecordTable = () => { )} {isAggregateQueryEnabled && !hasRecordGroups && ( - + )} { - const isAggregateQueryEnabled = useIsFeatureEnabled( - 'IS_AGGREGATE_QUERY_ENABLED', - ); const currentRecordGroupId = useCurrentRecordGroupId(); const allRecordIds = useRecoilComponentValueV2( @@ -63,12 +58,6 @@ export const RecordTableRecordGroupRows = () => { })} - {isAggregateQueryEnabled && ( - - )} ); diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-body/components/RecordTableBodyDroppable.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-body/components/RecordTableBodyDroppable.tsx index f2e19d7506af..8e731aaf5a1b 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-body/components/RecordTableBodyDroppable.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-body/components/RecordTableBodyDroppable.tsx @@ -15,6 +15,7 @@ export const RecordTableBodyDroppable = ({ isDropDisabled, }: RecordTableBodyDroppableProps) => { const [v4Persistable] = useState(v4()); + const recordTableBodyId = `record-table-body${recordGroupId ? '-' + recordGroupId : ''}`; return ( {(provided) => ( { + const isAggregateQueryEnabled = useIsFeatureEnabled( + 'IS_AGGREGATE_QUERY_ENABLED', + ); const allRecordIds = useRecoilComponentValueV2( recordIndexAllRecordIdsComponentSelector, ); @@ -29,21 +34,31 @@ export const RecordTableRecordGroupsBody = () => { } return ( - - {visibleRecordGroupIds.map((recordGroupId, index) => ( - - - - {index > 0 && } - - - - - - ))} - + <> + + {visibleRecordGroupIds.map((recordGroupId, index) => ( + <> + + + + {index > 0 && } + + + + {isAggregateQueryEnabled && ( + + )} + + + + ))} + + ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableFooter.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableFooter.tsx index 8e76e751301d..11b24f0bb481 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableFooter.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableFooter.tsx @@ -1,14 +1,12 @@ import styled from '@emotion/styled'; import { MOBILE_VIEWPORT } from 'twenty-ui'; -import { TABLE_CELL_CHECKBOX_MIN_WIDTH } from '@/object-record/record-table/record-table-cell/components/RecordTableCellCheckbox'; -import { TABLE_CELL_GRIP_WIDTH } from '@/object-record/record-table/record-table-cell/components/RecordTableCellGrip'; import { RecordTableFooterCell } from '@/object-record/record-table/record-table-footer/components/RecordTableFooterCell'; import { FIRST_TH_WIDTH } from '@/object-record/record-table/record-table-header/components/RecordTableHeader'; import { visibleTableColumnsComponentSelector } from '@/object-record/record-table/states/selectors/visibleTableColumnsComponentSelector'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; -const StyledTableFoot = styled.thead` +const StyledTableFoot = styled.thead<{ endOfTableSticky?: boolean }>` cursor: pointer; th:nth-of-type(1) { @@ -62,27 +60,21 @@ const StyledTableFoot = styled.thead` tr { position: sticky; - bottom: 0; z-index: 5; - } - - &.first-columns-sticky { - th:nth-of-type(1), - th:nth-of-type(2), - th:nth-of-type(3) { - z-index: 10; - } + ${({ endOfTableSticky }) => endOfTableSticky && `bottom: 0;`} } `; -const StyledDiv = styled.div` - width: calc(${TABLE_CELL_GRIP_WIDTH} + ${TABLE_CELL_CHECKBOX_MIN_WIDTH}); +const StyledTh = styled.th` + background-color: ${({ theme }) => theme.background.primary}; `; export const RecordTableFooter = ({ currentRecordGroupId, + endOfTableSticky, }: { currentRecordGroupId?: string; + endOfTableSticky?: boolean; }) => { const visibleTableColumns = useRecoilComponentValueV2( visibleTableColumnsComponentSelector, @@ -92,10 +84,11 @@ export const RecordTableFooter = ({ - - + + {visibleTableColumns.map((column, index) => ( { weight="medium" /> {recordIdsByGroup.length} + diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-section/components/RecordTableRecordGroupStickyEffect.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-section/components/RecordTableRecordGroupStickyEffect.tsx new file mode 100644 index 000000000000..889730417cb6 --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-section/components/RecordTableRecordGroupStickyEffect.tsx @@ -0,0 +1,48 @@ +import { useEffect } from 'react'; + +import { useCurrentRecordGroupId } from '@/object-record/record-group/hooks/useCurrentRecordGroupId'; +import { isRecordTableScrolledLeftComponentState } from '@/object-record/record-table/states/isRecordTableScrolledLeftComponentState'; +import { scrollWrapperScrollLeftComponentState } from '@/ui/utilities/scroll/states/scrollWrapperScrollLeftComponentState'; +import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; +import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2'; + +export const RecordTableRecordGroupStickyEffect = () => { + const scrollLeft = useRecoilComponentValueV2( + scrollWrapperScrollLeftComponentState, + ); + + const setIsRecordTableScrolledLeft = useSetRecoilComponentStateV2( + isRecordTableScrolledLeftComponentState, + ); + + const currentRecordGroupId = useCurrentRecordGroupId(); + + useEffect(() => { + setIsRecordTableScrolledLeft(scrollLeft === 0); + if (scrollLeft > 0) { + document + .getElementById( + `record-table-footer${currentRecordGroupId ? '-' + currentRecordGroupId : ''}`, + ) + ?.classList.add('first-columns-sticky'); + document + .getElementById( + `record-table-body${currentRecordGroupId ? '-' + currentRecordGroupId : ''}`, + ) + ?.classList.add('first-columns-sticky'); + } else { + document + .getElementById( + `record-table-footer${currentRecordGroupId ? '-' + currentRecordGroupId : ''}`, + ) + ?.classList.remove('first-columns-sticky'); + document + .getElementById( + `record-table-body${currentRecordGroupId ? '-' + currentRecordGroupId : ''}`, + ) + ?.classList.remove('first-columns-sticky'); + } + }, [currentRecordGroupId, scrollLeft, setIsRecordTableScrolledLeft]); + + return <>; +};