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 a7ca5c948..3e792cc2b 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
@@ -1,36 +1,17 @@
-import styled from '@emotion/styled';
import { isNonEmptyString } from '@sniptt/guards';
+import { useRef } from 'react';
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 { RecordTableBodyEffectsWrapper } from '@/object-record/record-table/components/RecordTableBodyEffectsWrapper';
+import { RecordTableContent } from '@/object-record/record-table/components/RecordTableContent';
+import { RecordTableEmpty } from '@/object-record/record-table/components/RecordTableEmpty';
import { RECORD_TABLE_CLICK_OUTSIDE_LISTENER_ID } from '@/object-record/record-table/constants/RecordTableClickOutsideListenerId';
import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext';
-import { RecordTableEmptyState } from '@/object-record/record-table/empty-state/components/RecordTableEmptyState';
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
-import { RecordTableBodyUnselectEffect } from '@/object-record/record-table/record-table-body/components/RecordTableBodyUnselectEffect';
-import { RecordTableNoRecordGroupBody } from '@/object-record/record-table/record-table-body/components/RecordTableNoRecordGroupBody';
-import { RecordTableNoRecordGroupBodyEffect } from '@/object-record/record-table/record-table-body/components/RecordTableNoRecordGroupBodyEffect';
-import { RecordTableRecordGroupBodyEffects } from '@/object-record/record-table/record-table-body/components/RecordTableRecordGroupBodyEffects';
-import { RecordTableRecordGroupsBody } from '@/object-record/record-table/record-table-body/components/RecordTableRecordGroupsBody';
-import { RecordTableHeader } from '@/object-record/record-table/record-table-header/components/RecordTableHeader';
import { isRecordTableInitialLoadingComponentState } from '@/object-record/record-table/states/isRecordTableInitialLoadingComponentState';
-import { DragSelect } from '@/ui/utilities/drag-select/components/DragSelect';
import { useClickOutsideListener } from '@/ui/utilities/pointer-event/hooks/useClickOutsideListener';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
-import { useRef } from 'react';
-
-const StyledTable = styled.table`
- border-radius: ${({ theme }) => theme.border.radius.sm};
- border-spacing: 0;
- table-layout: fixed;
- width: 100%;
-
- .footer-sticky tr:nth-last-of-type(2) td {
- border-bottom-color: ${({ theme }) => theme.background.transparent};
- }
-`;
export const RecordTable = () => {
const { recordTableId, objectNameSingular } = useRecordTableContextOrThrow();
@@ -56,51 +37,46 @@ export const RecordTable = () => {
recordTableId,
);
- const recordTableIsEmpty =
- !isRecordTableInitialLoading && allRecordIds.length === 0;
-
const { resetTableRowSelection, setRowSelected } = useRecordTable({
recordTableId,
});
+ const recordTableIsEmpty =
+ !isRecordTableInitialLoading && allRecordIds.length === 0;
+
if (!isNonEmptyString(objectNameSingular)) {
return <>>;
}
+ const handleDragSelectionStart = () => {
+ resetTableRowSelection();
+ toggleClickOutsideListener(false);
+ };
+
+ const handleDragSelectionEnd = () => {
+ toggleClickOutsideListener(true);
+ };
+
return (
<>
- {!hasRecordGroups ? (
-
- ) : (
-
- )}
-
+
+
{recordTableIsEmpty ? (
-
+
) : (
- <>
-
-
- {!hasRecordGroups ? (
-
- ) : (
-
- )}
-
-
-
- {
- resetTableRowSelection();
- toggleClickOutsideListener(false);
- }}
- onDragSelectionChange={setRowSelected}
- onDragSelectionEnd={() => {
- toggleClickOutsideListener(true);
- }}
- />
- >
+
)}
>
);
diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableBodyEffectsWrapper.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableBodyEffectsWrapper.tsx
new file mode 100644
index 000000000..3d2954312
--- /dev/null
+++ b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableBodyEffectsWrapper.tsx
@@ -0,0 +1,22 @@
+import { RecordTableBodyUnselectEffect } from '@/object-record/record-table/record-table-body/components/RecordTableBodyUnselectEffect';
+import { RecordTableNoRecordGroupBodyEffect } from '@/object-record/record-table/record-table-body/components/RecordTableNoRecordGroupBodyEffect';
+import { RecordTableRecordGroupBodyEffects } from '@/object-record/record-table/record-table-body/components/RecordTableRecordGroupBodyEffects';
+
+export interface RecordTableBodyEffectsWrapperProps {
+ hasRecordGroups: boolean;
+ tableBodyRef: React.RefObject;
+}
+
+export const RecordTableBodyEffectsWrapper = ({
+ hasRecordGroups,
+ tableBodyRef,
+}: RecordTableBodyEffectsWrapperProps) => (
+ <>
+ {hasRecordGroups ? (
+
+ ) : (
+
+ )}
+
+ >
+);
diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableContent.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableContent.tsx
new file mode 100644
index 000000000..d5dc7425f
--- /dev/null
+++ b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableContent.tsx
@@ -0,0 +1,42 @@
+import { RecordTableStickyBottomEffect } from '@/object-record/record-table/components/RecordTableStickyBottomEffect';
+import { RecordTableStickyEffect } from '@/object-record/record-table/components/RecordTableStickyEffect';
+import { StyledTable } from '@/object-record/record-table/components/RecordTableStyles';
+import { RecordTableNoRecordGroupBody } from '@/object-record/record-table/record-table-body/components/RecordTableNoRecordGroupBody';
+import { RecordTableRecordGroupsBody } from '@/object-record/record-table/record-table-body/components/RecordTableRecordGroupsBody';
+import { RecordTableHeader } from '@/object-record/record-table/record-table-header/components/RecordTableHeader';
+import { DragSelect } from '@/ui/utilities/drag-select/components/DragSelect';
+
+export interface RecordTableContentProps {
+ tableBodyRef: React.RefObject;
+ handleDragSelectionStart: () => void;
+ handleDragSelectionEnd: () => void;
+ setRowSelected: (rowId: string, selected: boolean) => void;
+ hasRecordGroups: boolean;
+}
+
+export const RecordTableContent = ({
+ tableBodyRef,
+ handleDragSelectionStart,
+ handleDragSelectionEnd,
+ setRowSelected,
+ hasRecordGroups,
+}: RecordTableContentProps) => (
+ <>
+
+
+ {hasRecordGroups ? (
+
+ ) : (
+
+ )}
+
+
+
+
+ >
+);
diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableEmpty.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableEmpty.tsx
new file mode 100644
index 000000000..89887fa10
--- /dev/null
+++ b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableEmpty.tsx
@@ -0,0 +1,25 @@
+import { StyledTable } from '@/object-record/record-table/components/RecordTableStyles';
+import { RecordTableEmptyState } from '@/object-record/record-table/empty-state/components/RecordTableEmptyState';
+import { RecordTableRecordGroupsBody } from '@/object-record/record-table/record-table-body/components/RecordTableRecordGroupsBody';
+import { RecordTableHeader } from '@/object-record/record-table/record-table-header/components/RecordTableHeader';
+
+export interface RecordTableEmptyProps {
+ tableBodyRef: React.RefObject;
+ hasRecordGroups: boolean;
+}
+
+export const RecordTableEmpty = ({
+ tableBodyRef,
+ hasRecordGroups,
+}: RecordTableEmptyProps) => (
+ <>
+
+
+
+ {hasRecordGroups ? (
+
+ ) : (
+
+ )}
+ >
+);
diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableStyles.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableStyles.tsx
new file mode 100644
index 000000000..bcf481903
--- /dev/null
+++ b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableStyles.tsx
@@ -0,0 +1,12 @@
+import styled from '@emotion/styled';
+
+export const StyledTable = styled.table`
+ border-radius: ${({ theme }) => theme.border.radius.sm};
+ border-spacing: 0;
+ table-layout: fixed;
+ width: 100%;
+
+ .footer-sticky tr:nth-last-of-type(2) td {
+ border-bottom-color: ${({ theme }) => theme.background.transparent};
+ }
+`;
diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderCheckboxColumn.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderCheckboxColumn.tsx
index 4008c0aed..5cdd9ce4e 100644
--- a/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderCheckboxColumn.tsx
+++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderCheckboxColumn.tsx
@@ -1,6 +1,9 @@
import styled from '@emotion/styled';
+import { recordIndexAllRecordIdsComponentSelector } from '@/object-record/record-index/states/selectors/recordIndexAllRecordIdsComponentSelector';
+import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext';
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
+import { isRecordTableInitialLoadingComponentState } from '@/object-record/record-table/states/isRecordTableInitialLoadingComponentState';
import { allRowsSelectedStatusComponentSelector } from '@/object-record/record-table/states/selectors/allRowsSelectedStatusComponentSelector';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { Checkbox } from 'twenty-ui/input';
@@ -30,6 +33,21 @@ export const RecordTableHeaderCheckboxColumn = () => {
allRowsSelectedStatus === 'all' || allRowsSelectedStatus === 'some';
const indeterminate = allRowsSelectedStatus === 'some';
+ const { recordTableId } = useRecordTableContextOrThrow();
+
+ const isRecordTableInitialLoading = useRecoilComponentValueV2(
+ isRecordTableInitialLoadingComponentState,
+ recordTableId,
+ );
+
+ const allRecordIds = useRecoilComponentValueV2(
+ recordIndexAllRecordIdsComponentSelector,
+ recordTableId,
+ );
+
+ const recordTableIsEmpty =
+ !isRecordTableInitialLoading && allRecordIds.length === 0;
+
const onChange = () => {
if (checked) {
setHasUserSelectedAllRows(false);
@@ -48,6 +66,7 @@ export const RecordTableHeaderCheckboxColumn = () => {
checked={checked}
onChange={onChange}
indeterminate={indeterminate}
+ disabled={recordTableIsEmpty}
/>