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 4a8fde833..a0787d1ce 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
@@ -3,6 +3,7 @@ import { isNonEmptyString } from '@sniptt/guards';
import { hasRecordGroupsComponentSelector } from '@/object-record/record-group/states/selectors/hasRecordGroupsComponentSelector';
import { recordIndexAllRecordIdsComponentSelector } from '@/object-record/record-index/states/selectors/recordIndexAllRecordIdsComponentSelector';
+import { RecordTableStickyBottomEffect } from '@/object-record/record-table/components/RecordTableStickyBottomEffect';
import { RecordTableStickyEffect } from '@/object-record/record-table/components/RecordTableStickyEffect';
import { RECORD_TABLE_CLICK_OUTSIDE_LISTENER_ID } from '@/object-record/record-table/constants/RecordTableClickOutsideListenerId';
import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext';
@@ -26,6 +27,10 @@ const StyledTable = styled.table`
border-spacing: 0;
table-layout: fixed;
width: 100%;
+
+ .footer-sticky tr:nth-last-child(2) td {
+ border-bottom-color: ${({ theme }) => theme.background.transparent};
+ }
`;
export const RecordTable = () => {
@@ -90,6 +95,7 @@ export const RecordTable = () => {
)}
+
{
})}
{!isRecordTableInitialLoading && allRecordIds.length > 0 && (
-
+
)}
>
);
diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableStickyBottomEffect.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableStickyBottomEffect.tsx
new file mode 100644
index 000000000..7e259e825
--- /dev/null
+++ b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableStickyBottomEffect.tsx
@@ -0,0 +1,30 @@
+import { useEffect } from 'react';
+
+import { scrollWrapperScrollBottomComponentState } from '@/ui/utilities/scroll/states/scrollWrappeScrollBottomComponentState';
+import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
+
+export const RecordTableStickyBottomEffect = () => {
+ const scrollBottom = useRecoilComponentValueV2(
+ scrollWrapperScrollBottomComponentState,
+ );
+
+ useEffect(() => {
+ if (scrollBottom > 1) {
+ document
+ .getElementById('record-table-body')
+ ?.classList.add('footer-sticky');
+ document
+ .getElementById('record-table-footer')
+ ?.classList.add('footer-sticky');
+ } else {
+ document
+ .getElementById('record-table-body')
+ ?.classList.remove('footer-sticky');
+ document
+ .getElementById('record-table-footer')
+ ?.classList.remove('footer-sticky');
+ }
+ }, [scrollBottom]);
+
+ return <>>;
+};
diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableTd.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableTd.tsx
index 1c95f0287..4f558161f 100644
--- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableTd.tsx
+++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableTd.tsx
@@ -3,12 +3,9 @@ import { styled } from '@linaria/react';
import { ReactNode, useContext } from 'react';
import { MOBILE_VIEWPORT, ThemeContext } from 'twenty-ui';
-import { isDefined } from '~/utils/isDefined';
-
export const RECORD_TABLE_TD_WIDTH = '32px';
const StyledTd = styled.td<{
- zIndex?: number;
backgroundColor: string;
borderColor: string;
isDragging?: boolean;
@@ -33,7 +30,6 @@ const StyledTd = styled.td<{
text-align: left;
background: ${({ backgroundColor }) => backgroundColor};
- z-index: ${({ zIndex }) => (isDefined(zIndex) ? zIndex : 'auto')};
${({ isDragging }) =>
isDragging
? `
@@ -53,7 +49,6 @@ const StyledTd = styled.td<{
export const RecordTableTd = ({
children,
- zIndex,
isSelected,
isDragging,
sticky,
@@ -67,7 +62,6 @@ export const RecordTableTd = ({
}: {
className?: string;
children?: ReactNode;
- zIndex?: number;
isSelected?: boolean;
isDragging?: boolean;
sticky?: boolean;
@@ -90,7 +84,6 @@ export const RecordTableTd = ({
return (
`
- td {
- border-top: 1px solid ${({ theme }) => theme.border.color.light};
+ z-index: 5;
+ position: sticky;
+ border: none;
+
+ &.footer-sticky {
+ td {
+ border-top: ${({ theme }) => `1px solid ${theme.border.color.light}`};
+ z-index: 5;
+ position: sticky;
+ bottom: 0;
+ }
}
cursor: pointer;
td:nth-of-type(1) {
width: ${FIRST_TH_WIDTH};
left: 0;
- border-right-color: ${({ theme }) => theme.background.primary};
border-top: none;
}
- td:nth-of-type(2) {
- border-right-color: ${({ theme }) => theme.background.primary};
- }
&.first-columns-sticky {
td:nth-of-type(2) {
position: sticky;
- z-index: 5;
+ z-index: 10;
transition: 0.3s ease;
&::after {
content: '';
@@ -50,37 +55,32 @@ const StyledTableRow = styled.tr<{
}
}
}
- position: sticky;
- z-index: 5;
background: ${({ theme }) => theme.background.primary};
- ${({ endOfTableSticky, hasHorizontalOverflow }) =>
- endOfTableSticky &&
- `
- bottom: ${hasHorizontalOverflow ? '10px' : '0'};
- ${
- hasHorizontalOverflow &&
- `
- &::after {
- content: '';
- position: absolute;
- bottom: -10px;
- left: 0;
- right: 0;
- height: 10px;
- background: inherit;
+ ${({ hasHorizontalOverflow }) =>
+ `.footer-sticky {
+ bottom: ${hasHorizontalOverflow ? '10px' : '0'};
+ ${
+ hasHorizontalOverflow &&
+ `
+ &::after {
+ content: '';
+ position: absolute;
+ bottom: -10px;
+ left: 0;
+ right: 0;
+ height: 10px;
+ background: inherit;
+ }
}
`
- }
+ }
`}
`;
export const RecordTableAggregateFooter = ({
currentRecordGroupId,
- endOfTableSticky,
}: {
currentRecordGroupId?: string;
-
- endOfTableSticky?: boolean;
}) => {
const visibleTableColumns = useRecoilComponentValueV2(
visibleTableColumnsComponentSelector,
@@ -99,8 +99,9 @@ export const RecordTableAggregateFooter = ({