mirror of
https://github.com/twentyhq/twenty.git
synced 2024-12-23 03:51:36 +03:00
fix: can't properly drag and drop in empty record group (#9039)
Fix #8968 Fix issue with drag and drop when record group are empty. Happy to discuss the implementation, as it's limited to the `@hello-pangea/dnd` api. --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
parent
d56c815897
commit
07aaf0801c
@ -1,14 +1,6 @@
|
|||||||
import React, { Ref, RefCallback } from 'react';
|
import { Ref, RefCallback } from 'react';
|
||||||
import { isFunction } from '@sniptt/guards';
|
import { combineRefs } from '~/utils/combineRefs';
|
||||||
|
|
||||||
export const useCombinedRefs =
|
export const useCombinedRefs = <T>(
|
||||||
<T>(...refs: (Ref<T> | undefined)[]): RefCallback<T> =>
|
...refs: (Ref<T> | undefined)[]
|
||||||
(node: T) => {
|
): RefCallback<T> => combineRefs<T>(...refs);
|
||||||
for (const ref of refs) {
|
|
||||||
if (isFunction(ref)) {
|
|
||||||
ref(node);
|
|
||||||
} else if (ref !== null && ref !== undefined) {
|
|
||||||
(ref as React.MutableRefObject<T | null>).current = node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
@ -14,13 +14,14 @@ import {
|
|||||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||||
import { RecordTableComponentInstance } from '@/object-record/record-table/components/RecordTableComponentInstance';
|
import { RecordTableComponentInstance } from '@/object-record/record-table/components/RecordTableComponentInstance';
|
||||||
import { RecordTableCellContext } from '@/object-record/record-table/contexts/RecordTableCellContext';
|
import { RecordTableCellContext } from '@/object-record/record-table/contexts/RecordTableCellContext';
|
||||||
import { RecordTableRowContext } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
|
||||||
import { ChipGeneratorsDecorator } from '~/testing/decorators/ChipGeneratorsDecorator';
|
import { ChipGeneratorsDecorator } from '~/testing/decorators/ChipGeneratorsDecorator';
|
||||||
import { MemoryRouterDecorator } from '~/testing/decorators/MemoryRouterDecorator';
|
import { MemoryRouterDecorator } from '~/testing/decorators/MemoryRouterDecorator';
|
||||||
import { getProfilingStory } from '~/testing/profiling/utils/getProfilingStory';
|
import { getProfilingStory } from '~/testing/profiling/utils/getProfilingStory';
|
||||||
|
|
||||||
import { RecordTableBodyContextProvider } from '@/object-record/record-table/contexts/RecordTableBodyContext';
|
import { RecordTableBodyContextProvider } from '@/object-record/record-table/contexts/RecordTableBodyContext';
|
||||||
import { RecordTableContextProvider } from '@/object-record/record-table/contexts/RecordTableContext';
|
import { RecordTableContextProvider } from '@/object-record/record-table/contexts/RecordTableContext';
|
||||||
|
import { RecordTableRowContextProvider } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
||||||
|
import { RecordTableRowDraggableContextProvider } from '@/object-record/record-table/contexts/RecordTableRowDraggableContext';
|
||||||
import { RecordTableCellFieldContextWrapper } from '@/object-record/record-table/record-table-cell/components/RecordTableCellFieldContextWrapper';
|
import { RecordTableCellFieldContextWrapper } from '@/object-record/record-table/record-table-cell/components/RecordTableCellFieldContextWrapper';
|
||||||
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
|
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
|
||||||
import { mockPerformance } from './mock';
|
import { mockPerformance } from './mock';
|
||||||
@ -87,7 +88,7 @@ const meta: Meta = {
|
|||||||
onCellMouseEnter: () => {},
|
onCellMouseEnter: () => {},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<RecordTableRowContext.Provider
|
<RecordTableRowContextProvider
|
||||||
value={{
|
value={{
|
||||||
objectNameSingular:
|
objectNameSingular:
|
||||||
mockPerformance.entityValue.__typename.toLocaleLowerCase(),
|
mockPerformance.entityValue.__typename.toLocaleLowerCase(),
|
||||||
@ -99,10 +100,14 @@ const meta: Meta = {
|
|||||||
mockPerformance.entityValue.__typename.toLocaleLowerCase(),
|
mockPerformance.entityValue.__typename.toLocaleLowerCase(),
|
||||||
}) + mockPerformance.recordId,
|
}) + mockPerformance.recordId,
|
||||||
isSelected: false,
|
isSelected: false,
|
||||||
|
isPendingRow: false,
|
||||||
|
inView: true,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<RecordTableRowDraggableContextProvider
|
||||||
|
value={{
|
||||||
isDragging: false,
|
isDragging: false,
|
||||||
dragHandleProps: null,
|
dragHandleProps: null,
|
||||||
inView: true,
|
|
||||||
isPendingRow: false,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<RecordTableCellContext.Provider
|
<RecordTableCellContext.Provider
|
||||||
@ -135,7 +140,8 @@ const meta: Meta = {
|
|||||||
</table>
|
</table>
|
||||||
</FieldContext.Provider>
|
</FieldContext.Provider>
|
||||||
</RecordTableCellContext.Provider>
|
</RecordTableCellContext.Provider>
|
||||||
</RecordTableRowContext.Provider>
|
</RecordTableRowDraggableContextProvider>
|
||||||
|
</RecordTableRowContextProvider>
|
||||||
</RecordTableBodyContextProvider>
|
</RecordTableBodyContextProvider>
|
||||||
</RecordTableComponentInstance>
|
</RecordTableComponentInstance>
|
||||||
</RecordTableContextProvider>
|
</RecordTableContextProvider>
|
||||||
|
@ -4,7 +4,7 @@ import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata'
|
|||||||
import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
|
import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
|
||||||
import { TableCellPosition } from '@/object-record/record-table/types/TableCellPosition';
|
import { TableCellPosition } from '@/object-record/record-table/types/TableCellPosition';
|
||||||
|
|
||||||
export type RecordTableCellContextProps = {
|
export type RecordTableCellContextValue = {
|
||||||
columnDefinition: ColumnDefinition<FieldMetadata>;
|
columnDefinition: ColumnDefinition<FieldMetadata>;
|
||||||
columnIndex: number;
|
columnIndex: number;
|
||||||
isInEditMode: boolean;
|
isInEditMode: boolean;
|
||||||
@ -13,4 +13,4 @@ export type RecordTableCellContextProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const RecordTableCellContext =
|
export const RecordTableCellContext =
|
||||||
createContext<RecordTableCellContextProps>({} as RecordTableCellContextProps);
|
createContext<RecordTableCellContextValue>({} as RecordTableCellContextValue);
|
||||||
|
@ -1,19 +1,14 @@
|
|||||||
import { DraggableProvidedDragHandleProps } from '@hello-pangea/dnd';
|
import { createRequiredContext } from '~/utils/createRequiredContext';
|
||||||
import { createContext } from 'react';
|
|
||||||
|
|
||||||
export type RecordTableRowContextProps = {
|
export type RecordTableRowContextValue = {
|
||||||
pathToShowPage: string;
|
pathToShowPage: string;
|
||||||
objectNameSingular: string;
|
objectNameSingular: string;
|
||||||
recordId: string;
|
recordId: string;
|
||||||
rowIndex: number;
|
rowIndex: number;
|
||||||
isSelected: boolean;
|
isSelected: boolean;
|
||||||
|
inView: boolean;
|
||||||
isPendingRow?: boolean;
|
isPendingRow?: boolean;
|
||||||
isDragging: boolean;
|
|
||||||
dragHandleProps: DraggableProvidedDragHandleProps | null;
|
|
||||||
inView?: boolean;
|
|
||||||
isDragDisabled?: boolean;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const RecordTableRowContext = createContext<RecordTableRowContextProps>(
|
export const [RecordTableRowContextProvider, useRecordTableRowContextOrThrow] =
|
||||||
{} as RecordTableRowContextProps,
|
createRequiredContext<RecordTableRowContextValue>('RecordTableRowContext');
|
||||||
);
|
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
import { DraggableProvidedDragHandleProps } from '@hello-pangea/dnd';
|
||||||
|
import { createRequiredContext } from '~/utils/createRequiredContext';
|
||||||
|
|
||||||
|
export type RecordTableRowDraggableContextValue = {
|
||||||
|
isDragging: boolean;
|
||||||
|
dragHandleProps: DraggableProvidedDragHandleProps | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const [
|
||||||
|
RecordTableRowDraggableContextProvider,
|
||||||
|
useRecordTableRowDraggableContextOrThrow,
|
||||||
|
] = createRequiredContext<RecordTableRowDraggableContextValue>(
|
||||||
|
'RecordTableRowDraggableContext',
|
||||||
|
);
|
@ -1,3 +1,5 @@
|
|||||||
|
import { RecordTableRowContextProvider } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
||||||
|
import { RecordTableRowDraggableContextProvider } from '@/object-record/record-table/contexts/RecordTableRowDraggableContext';
|
||||||
import { RecordTableCellCheckbox } from '@/object-record/record-table/record-table-cell/components/RecordTableCellCheckbox';
|
import { RecordTableCellCheckbox } from '@/object-record/record-table/record-table-cell/components/RecordTableCellCheckbox';
|
||||||
import { RecordTableCellGrip } from '@/object-record/record-table/record-table-cell/components/RecordTableCellGrip';
|
import { RecordTableCellGrip } from '@/object-record/record-table/record-table-cell/components/RecordTableCellGrip';
|
||||||
import { RecordTableCellLoading } from '@/object-record/record-table/record-table-cell/components/RecordTableCellLoading';
|
import { RecordTableCellLoading } from '@/object-record/record-table/record-table-cell/components/RecordTableCellLoading';
|
||||||
@ -13,11 +15,27 @@ export const RecordTableBodyLoading = () => {
|
|||||||
return (
|
return (
|
||||||
<tbody>
|
<tbody>
|
||||||
{Array.from({ length: 8 }).map((_, rowIndex) => (
|
{Array.from({ length: 8 }).map((_, rowIndex) => (
|
||||||
|
<RecordTableRowContextProvider
|
||||||
|
key={rowIndex}
|
||||||
|
value={{
|
||||||
|
pathToShowPage: '',
|
||||||
|
objectNameSingular: '',
|
||||||
|
recordId: `${rowIndex}`,
|
||||||
|
rowIndex,
|
||||||
|
isSelected: false,
|
||||||
|
inView: true,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<RecordTableRowDraggableContextProvider
|
||||||
|
value={{
|
||||||
|
dragHandleProps: {} as any,
|
||||||
|
isDragging: false,
|
||||||
|
}}
|
||||||
|
>
|
||||||
<RecordTableTr
|
<RecordTableTr
|
||||||
isDragging={false}
|
isDragging={false}
|
||||||
data-testid={`row-id-${rowIndex}`}
|
data-testid={`row-id-${rowIndex}`}
|
||||||
data-selectable-id={`row-id-${rowIndex}`}
|
data-selectable-id={`row-id-${rowIndex}`}
|
||||||
key={rowIndex}
|
|
||||||
>
|
>
|
||||||
<RecordTableCellGrip />
|
<RecordTableCellGrip />
|
||||||
<RecordTableCellCheckbox />
|
<RecordTableCellCheckbox />
|
||||||
@ -25,6 +43,8 @@ export const RecordTableBodyLoading = () => {
|
|||||||
<RecordTableCellLoading key={column.fieldMetadataId} />
|
<RecordTableCellLoading key={column.fieldMetadataId} />
|
||||||
))}
|
))}
|
||||||
</RecordTableTr>
|
</RecordTableTr>
|
||||||
|
</RecordTableRowDraggableContextProvider>
|
||||||
|
</RecordTableRowContextProvider>
|
||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
);
|
);
|
||||||
|
@ -35,9 +35,9 @@ export const RecordTableRecordGroupsBody = () => {
|
|||||||
key={recordGroupId}
|
key={recordGroupId}
|
||||||
recordGroupId={recordGroupId}
|
recordGroupId={recordGroupId}
|
||||||
>
|
>
|
||||||
{index > 0 && <RecordTableRecordGroupEmptyRow />}
|
|
||||||
<RecordGroupContext.Provider value={{ recordGroupId }}>
|
<RecordGroupContext.Provider value={{ recordGroupId }}>
|
||||||
<RecordTableBodyDroppable recordGroupId={recordGroupId}>
|
<RecordTableBodyDroppable recordGroupId={recordGroupId}>
|
||||||
|
{index > 0 && <RecordTableRecordGroupEmptyRow />}
|
||||||
<RecordTableRecordGroupSection />
|
<RecordTableRecordGroupSection />
|
||||||
<RecordTableRecordGroupRows />
|
<RecordTableRecordGroupRows />
|
||||||
</RecordTableBodyDroppable>
|
</RecordTableBodyDroppable>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { useCallback, useContext } from 'react';
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
import { RecordTableRowContext } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
import { useRecordTableRowContextOrThrow } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
||||||
import { RecordTableTd } from '@/object-record/record-table/record-table-cell/components/RecordTableTd';
|
import { RecordTableTd } from '@/object-record/record-table/record-table-cell/components/RecordTableTd';
|
||||||
import { useSetCurrentRowSelected } from '@/object-record/record-table/record-table-row/hooks/useSetCurrentRowSelected';
|
import { useSetCurrentRowSelected } from '@/object-record/record-table/record-table-row/hooks/useSetCurrentRowSelected';
|
||||||
import { Checkbox } from 'twenty-ui';
|
import { Checkbox } from 'twenty-ui';
|
||||||
@ -16,7 +16,7 @@ const StyledContainer = styled.div`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
export const RecordTableCellCheckbox = () => {
|
export const RecordTableCellCheckbox = () => {
|
||||||
const { isSelected } = useContext(RecordTableRowContext);
|
const { isSelected } = useRecordTableRowContextOrThrow();
|
||||||
|
|
||||||
const { setCurrentRowSelected } = useSetCurrentRowSelected();
|
const { setCurrentRowSelected } = useSetCurrentRowSelected();
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import { isFieldSelect } from '@/object-record/record-field/types/guards/isField
|
|||||||
import { RecordUpdateContext } from '@/object-record/record-table/contexts/EntityUpdateMutationHookContext';
|
import { RecordUpdateContext } from '@/object-record/record-table/contexts/EntityUpdateMutationHookContext';
|
||||||
import { RecordTableCellContext } from '@/object-record/record-table/contexts/RecordTableCellContext';
|
import { RecordTableCellContext } from '@/object-record/record-table/contexts/RecordTableCellContext';
|
||||||
import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext';
|
import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext';
|
||||||
import { RecordTableRowContext } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
import { useRecordTableRowContextOrThrow } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
||||||
import { TableHotkeyScope } from '@/object-record/record-table/types/TableHotkeyScope';
|
import { TableHotkeyScope } from '@/object-record/record-table/types/TableHotkeyScope';
|
||||||
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
|
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
|
||||||
import { SelectFieldHotkeyScope } from '@/object-record/select/types/SelectFieldHotkeyScope';
|
import { SelectFieldHotkeyScope } from '@/object-record/select/types/SelectFieldHotkeyScope';
|
||||||
@ -22,7 +22,7 @@ export const RecordTableCellFieldContextWrapper = ({
|
|||||||
|
|
||||||
const { columnDefinition } = useContext(RecordTableCellContext);
|
const { columnDefinition } = useContext(RecordTableCellContext);
|
||||||
|
|
||||||
const { recordId, pathToShowPage } = useContext(RecordTableRowContext);
|
const { recordId, pathToShowPage } = useRecordTableRowContextOrThrow();
|
||||||
|
|
||||||
const updateRecord = useContext(RecordUpdateContext);
|
const updateRecord = useContext(RecordUpdateContext);
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { useContext } from 'react';
|
|
||||||
|
|
||||||
import { RecordTableRowContext } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
import { useRecordTableRowContextOrThrow } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
||||||
|
import { useRecordTableRowDraggableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableRowDraggableContext';
|
||||||
import { RecordTableTd } from '@/object-record/record-table/record-table-cell/components/RecordTableTd';
|
import { RecordTableTd } from '@/object-record/record-table/record-table-cell/components/RecordTableTd';
|
||||||
import { css } from '@emotion/react';
|
import { css } from '@emotion/react';
|
||||||
import { IconListViewGrip } from 'twenty-ui';
|
import { IconListViewGrip } from 'twenty-ui';
|
||||||
@ -30,9 +30,10 @@ const StyledIconWrapper = styled.div<{ isDragging: boolean }>`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
export const RecordTableCellGrip = () => {
|
export const RecordTableCellGrip = () => {
|
||||||
const { dragHandleProps, isDragging, isPendingRow } = useContext(
|
const { isPendingRow } = useRecordTableRowContextOrThrow();
|
||||||
RecordTableRowContext,
|
|
||||||
);
|
const { dragHandleProps, isDragging } =
|
||||||
|
useRecordTableRowDraggableContextOrThrow();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RecordTableTd
|
<RecordTableTd
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { useContext, useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
||||||
import { RecordTableCellContext } from '@/object-record/record-table/contexts/RecordTableCellContext';
|
import { RecordTableCellContext } from '@/object-record/record-table/contexts/RecordTableCellContext';
|
||||||
import { RecordTableRowContext } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
import { useRecordTableRowContextOrThrow } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
||||||
import { RecordTableCellFieldContextWrapper } from '@/object-record/record-table/record-table-cell/components/RecordTableCellFieldContextWrapper';
|
import { RecordTableCellFieldContextWrapper } from '@/object-record/record-table/record-table-cell/components/RecordTableCellFieldContextWrapper';
|
||||||
import { isSoftFocusOnTableCellComponentFamilyState } from '@/object-record/record-table/states/isSoftFocusOnTableCellComponentFamilyState';
|
import { isSoftFocusOnTableCellComponentFamilyState } from '@/object-record/record-table/states/isSoftFocusOnTableCellComponentFamilyState';
|
||||||
import { isTableCellInEditModeComponentFamilyState } from '@/object-record/record-table/states/isTableCellInEditModeComponentFamilyState';
|
import { isTableCellInEditModeComponentFamilyState } from '@/object-record/record-table/states/isTableCellInEditModeComponentFamilyState';
|
||||||
@ -19,7 +19,7 @@ export const RecordTableCellWrapper = ({
|
|||||||
columnIndex: number;
|
columnIndex: number;
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}) => {
|
}) => {
|
||||||
const { rowIndex } = useContext(RecordTableRowContext);
|
const { rowIndex } = useRecordTableRowContextOrThrow();
|
||||||
|
|
||||||
const currentTableCellPosition: TableCellPosition = useMemo(
|
const currentTableCellPosition: TableCellPosition = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
import { useContext } from 'react';
|
import { useRecordTableRowContextOrThrow } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
||||||
|
|
||||||
import { RecordTableRowContext } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
|
||||||
import { RecordTableTd } from '@/object-record/record-table/record-table-cell/components/RecordTableTd';
|
import { RecordTableTd } from '@/object-record/record-table/record-table-cell/components/RecordTableTd';
|
||||||
|
|
||||||
export const RecordTableLastEmptyCell = () => {
|
export const RecordTableLastEmptyCell = () => {
|
||||||
const { isSelected } = useContext(RecordTableRowContext);
|
const { isSelected } = useRecordTableRowContextOrThrow();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -1,20 +1,24 @@
|
|||||||
import { RecordTableCellContextProps } from '@/object-record/record-table/contexts/RecordTableCellContext';
|
import { RecordTableCellContextValue } from '@/object-record/record-table/contexts/RecordTableCellContext';
|
||||||
import { RecordTableRowContextProps } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
import { RecordTableRowContextValue } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
||||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
import { RecordTableRowDraggableContextValue } from '@/object-record/record-table/contexts/RecordTableRowDraggableContext';
|
||||||
|
import { FieldMetadataType } from '~/generated/graphql';
|
||||||
|
|
||||||
export const recordTableRow: RecordTableRowContextProps = {
|
export const recordTableRowContextValue: RecordTableRowContextValue = {
|
||||||
rowIndex: 2,
|
rowIndex: 2,
|
||||||
isSelected: false,
|
isSelected: false,
|
||||||
recordId: 'recordId',
|
recordId: 'recordId',
|
||||||
pathToShowPage: '/',
|
pathToShowPage: '/',
|
||||||
objectNameSingular: 'objectNameSingular',
|
objectNameSingular: 'objectNameSingular',
|
||||||
dragHandleProps: {} as any,
|
|
||||||
isDragging: false,
|
|
||||||
inView: true,
|
|
||||||
isPendingRow: false,
|
isPendingRow: false,
|
||||||
|
inView: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const recordTableCell: RecordTableCellContextProps = {
|
export const recordTableRowDraggableContextValue: RecordTableRowDraggableContextValue = {
|
||||||
|
dragHandleProps: {} as any,
|
||||||
|
isDragging: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const recordTableCellContextValue: RecordTableCellContextValue = {
|
||||||
columnIndex: 3,
|
columnIndex: 3,
|
||||||
columnDefinition: {
|
columnDefinition: {
|
||||||
size: 1,
|
size: 1,
|
||||||
|
@ -1,19 +1,28 @@
|
|||||||
import { renderHook } from '@testing-library/react';
|
import { renderHook } from '@testing-library/react';
|
||||||
|
|
||||||
import { RecordTableCellContext } from '@/object-record/record-table/contexts/RecordTableCellContext';
|
import { RecordTableCellContext } from '@/object-record/record-table/contexts/RecordTableCellContext';
|
||||||
import { RecordTableRowContext } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
import { RecordTableRowContextProvider } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
||||||
|
|
||||||
import { recordTableCell, recordTableRow } from '../__mocks__/cell';
|
import { RecordTableRowDraggableContextProvider } from '@/object-record/record-table/contexts/RecordTableRowDraggableContext';
|
||||||
|
import {
|
||||||
|
recordTableCellContextValue,
|
||||||
|
recordTableRowContextValue,
|
||||||
|
recordTableRowDraggableContextValue,
|
||||||
|
} from '@/object-record/record-table/record-table-cell/hooks/__mocks__/cell';
|
||||||
import { useCurrentTableCellPosition } from '../useCurrentCellPosition';
|
import { useCurrentTableCellPosition } from '../useCurrentCellPosition';
|
||||||
|
|
||||||
describe('useCurrentTableCellPosition', () => {
|
describe('useCurrentTableCellPosition', () => {
|
||||||
it('should return the current table cell position', () => {
|
it('should return the current table cell position', () => {
|
||||||
const wrapper = ({ children }: { children: React.ReactNode }) => (
|
const wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||||
<RecordTableRowContext.Provider value={recordTableRow}>
|
<RecordTableRowContextProvider value={recordTableRowContextValue}>
|
||||||
<RecordTableCellContext.Provider value={recordTableCell}>
|
<RecordTableRowDraggableContextProvider
|
||||||
|
value={recordTableRowDraggableContextValue}
|
||||||
|
>
|
||||||
|
<RecordTableCellContext.Provider value={recordTableCellContextValue}>
|
||||||
{children}
|
{children}
|
||||||
</RecordTableCellContext.Provider>
|
</RecordTableCellContext.Provider>
|
||||||
</RecordTableRowContext.Provider>
|
</RecordTableRowDraggableContextProvider>
|
||||||
|
</RecordTableRowContextProvider>
|
||||||
);
|
);
|
||||||
|
|
||||||
const { result } = renderHook(() => useCurrentTableCellPosition(), {
|
const { result } = renderHook(() => useCurrentTableCellPosition(), {
|
||||||
|
@ -3,10 +3,12 @@ import { RecoilRoot } from 'recoil';
|
|||||||
|
|
||||||
import { RecordTableComponentInstance } from '@/object-record/record-table/components/RecordTableComponentInstance';
|
import { RecordTableComponentInstance } from '@/object-record/record-table/components/RecordTableComponentInstance';
|
||||||
import { RecordTableCellContext } from '@/object-record/record-table/contexts/RecordTableCellContext';
|
import { RecordTableCellContext } from '@/object-record/record-table/contexts/RecordTableCellContext';
|
||||||
import { RecordTableRowContext } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
import { RecordTableRowContextProvider } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
||||||
|
import { RecordTableRowDraggableContextProvider } from '@/object-record/record-table/contexts/RecordTableRowDraggableContext';
|
||||||
import {
|
import {
|
||||||
recordTableCell,
|
recordTableCellContextValue,
|
||||||
recordTableRow,
|
recordTableRowContextValue,
|
||||||
|
recordTableRowDraggableContextValue,
|
||||||
} from '@/object-record/record-table/record-table-cell/hooks/__mocks__/cell';
|
} from '@/object-record/record-table/record-table-cell/hooks/__mocks__/cell';
|
||||||
import { useIsSoftFocusOnCurrentTableCell } from '@/object-record/record-table/record-table-cell/hooks/useIsSoftFocusOnCurrentTableCell';
|
import { useIsSoftFocusOnCurrentTableCell } from '@/object-record/record-table/record-table-cell/hooks/useIsSoftFocusOnCurrentTableCell';
|
||||||
|
|
||||||
@ -16,11 +18,15 @@ const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
|||||||
recordTableId="scopeId"
|
recordTableId="scopeId"
|
||||||
onColumnsChange={jest.fn()}
|
onColumnsChange={jest.fn()}
|
||||||
>
|
>
|
||||||
<RecordTableRowContext.Provider value={recordTableRow}>
|
<RecordTableRowContextProvider value={recordTableRowContextValue}>
|
||||||
<RecordTableCellContext.Provider value={recordTableCell}>
|
<RecordTableRowDraggableContextProvider
|
||||||
|
value={recordTableRowDraggableContextValue}
|
||||||
|
>
|
||||||
|
<RecordTableCellContext.Provider value={recordTableCellContextValue}>
|
||||||
{children}
|
{children}
|
||||||
</RecordTableCellContext.Provider>
|
</RecordTableCellContext.Provider>
|
||||||
</RecordTableRowContext.Provider>
|
</RecordTableRowDraggableContextProvider>
|
||||||
|
</RecordTableRowContextProvider>
|
||||||
</RecordTableComponentInstance>
|
</RecordTableComponentInstance>
|
||||||
</RecoilRoot>
|
</RecoilRoot>
|
||||||
);
|
);
|
||||||
|
@ -3,10 +3,12 @@ import { CallbackInterface, RecoilRoot } from 'recoil';
|
|||||||
|
|
||||||
import { RecordTableComponentInstance } from '@/object-record/record-table/components/RecordTableComponentInstance';
|
import { RecordTableComponentInstance } from '@/object-record/record-table/components/RecordTableComponentInstance';
|
||||||
import { RecordTableCellContext } from '@/object-record/record-table/contexts/RecordTableCellContext';
|
import { RecordTableCellContext } from '@/object-record/record-table/contexts/RecordTableCellContext';
|
||||||
import { RecordTableRowContext } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
import { RecordTableRowContextProvider } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
||||||
|
import { RecordTableRowDraggableContextProvider } from '@/object-record/record-table/contexts/RecordTableRowDraggableContext';
|
||||||
import {
|
import {
|
||||||
recordTableCell,
|
recordTableCellContextValue,
|
||||||
recordTableRow,
|
recordTableRowContextValue,
|
||||||
|
recordTableRowDraggableContextValue,
|
||||||
} from '@/object-record/record-table/record-table-cell/hooks/__mocks__/cell';
|
} from '@/object-record/record-table/record-table-cell/hooks/__mocks__/cell';
|
||||||
import { useMoveSoftFocusToCurrentCellOnHover } from '@/object-record/record-table/record-table-cell/hooks/useMoveSoftFocusToCurrentCellOnHover';
|
import { useMoveSoftFocusToCurrentCellOnHover } from '@/object-record/record-table/record-table-cell/hooks/useMoveSoftFocusToCurrentCellOnHover';
|
||||||
import { TableCellPosition } from '@/object-record/record-table/types/TableCellPosition';
|
import { TableCellPosition } from '@/object-record/record-table/types/TableCellPosition';
|
||||||
@ -80,11 +82,15 @@ const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
|||||||
recordTableId="scopeId"
|
recordTableId="scopeId"
|
||||||
onColumnsChange={jest.fn()}
|
onColumnsChange={jest.fn()}
|
||||||
>
|
>
|
||||||
<RecordTableRowContext.Provider value={recordTableRow}>
|
<RecordTableRowContextProvider value={recordTableRowContextValue}>
|
||||||
<RecordTableCellContext.Provider value={recordTableCell}>
|
<RecordTableRowDraggableContextProvider
|
||||||
|
value={recordTableRowDraggableContextValue}
|
||||||
|
>
|
||||||
|
<RecordTableCellContext.Provider value={recordTableCellContextValue}>
|
||||||
{children}
|
{children}
|
||||||
</RecordTableCellContext.Provider>
|
</RecordTableCellContext.Provider>
|
||||||
</RecordTableRowContext.Provider>
|
</RecordTableRowDraggableContextProvider>
|
||||||
|
</RecordTableRowContextProvider>
|
||||||
</RecordTableComponentInstance>
|
</RecordTableComponentInstance>
|
||||||
</RecoilRoot>
|
</RecoilRoot>
|
||||||
);
|
);
|
||||||
|
@ -8,10 +8,12 @@ import { FieldContext } from '@/object-record/record-field/contexts/FieldContext
|
|||||||
import { RecordTableComponentInstance } from '@/object-record/record-table/components/RecordTableComponentInstance';
|
import { RecordTableComponentInstance } from '@/object-record/record-table/components/RecordTableComponentInstance';
|
||||||
import { RecordTableContextProvider } from '@/object-record/record-table/components/RecordTableContextProvider';
|
import { RecordTableContextProvider } from '@/object-record/record-table/components/RecordTableContextProvider';
|
||||||
import { RecordTableCellContext } from '@/object-record/record-table/contexts/RecordTableCellContext';
|
import { RecordTableCellContext } from '@/object-record/record-table/contexts/RecordTableCellContext';
|
||||||
import { RecordTableRowContext } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
import { RecordTableRowContextProvider } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
||||||
|
import { RecordTableRowDraggableContextProvider } from '@/object-record/record-table/contexts/RecordTableRowDraggableContext';
|
||||||
import {
|
import {
|
||||||
recordTableCell,
|
recordTableCellContextValue,
|
||||||
recordTableRow,
|
recordTableRowContextValue,
|
||||||
|
recordTableRowDraggableContextValue,
|
||||||
} from '@/object-record/record-table/record-table-cell/hooks/__mocks__/cell';
|
} from '@/object-record/record-table/record-table-cell/hooks/__mocks__/cell';
|
||||||
import { useCloseRecordTableCellInGroup } from '@/object-record/record-table/record-table-cell/hooks/internal/useCloseRecordTableCellInGroup';
|
import { useCloseRecordTableCellInGroup } from '@/object-record/record-table/record-table-cell/hooks/internal/useCloseRecordTableCellInGroup';
|
||||||
import { currentTableCellInEditModePositionComponentState } from '@/object-record/record-table/states/currentTableCellInEditModePositionComponentState';
|
import { currentTableCellInEditModePositionComponentState } from '@/object-record/record-table/states/currentTableCellInEditModePositionComponentState';
|
||||||
@ -55,13 +57,17 @@ const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
|||||||
isLabelIdentifier: false,
|
isLabelIdentifier: false,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<RecordTableRowContext.Provider value={recordTableRow}>
|
<RecordTableRowContextProvider value={recordTableRowContextValue}>
|
||||||
|
<RecordTableRowDraggableContextProvider
|
||||||
|
value={recordTableRowDraggableContextValue}
|
||||||
|
>
|
||||||
<RecordTableCellContext.Provider
|
<RecordTableCellContext.Provider
|
||||||
value={{ ...recordTableCell, columnIndex: 0 }}
|
value={{ ...recordTableCellContextValue, columnIndex: 0 }}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</RecordTableCellContext.Provider>
|
</RecordTableCellContext.Provider>
|
||||||
</RecordTableRowContext.Provider>
|
</RecordTableRowDraggableContextProvider>
|
||||||
|
</RecordTableRowContextProvider>
|
||||||
</FieldContext.Provider>
|
</FieldContext.Provider>
|
||||||
</RecordTableContextProvider>
|
</RecordTableContextProvider>
|
||||||
</RecordTableComponentInstance>
|
</RecordTableComponentInstance>
|
||||||
|
@ -8,10 +8,12 @@ import { FieldContext } from '@/object-record/record-field/contexts/FieldContext
|
|||||||
import { RecordTableComponentInstance } from '@/object-record/record-table/components/RecordTableComponentInstance';
|
import { RecordTableComponentInstance } from '@/object-record/record-table/components/RecordTableComponentInstance';
|
||||||
import { RecordTableContextProvider } from '@/object-record/record-table/components/RecordTableContextProvider';
|
import { RecordTableContextProvider } from '@/object-record/record-table/components/RecordTableContextProvider';
|
||||||
import { RecordTableCellContext } from '@/object-record/record-table/contexts/RecordTableCellContext';
|
import { RecordTableCellContext } from '@/object-record/record-table/contexts/RecordTableCellContext';
|
||||||
import { RecordTableRowContext } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
import { RecordTableRowContextProvider } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
||||||
|
import { RecordTableRowDraggableContextProvider } from '@/object-record/record-table/contexts/RecordTableRowDraggableContext';
|
||||||
import {
|
import {
|
||||||
recordTableCell,
|
recordTableCellContextValue,
|
||||||
recordTableRow,
|
recordTableRowContextValue,
|
||||||
|
recordTableRowDraggableContextValue,
|
||||||
} from '@/object-record/record-table/record-table-cell/hooks/__mocks__/cell';
|
} from '@/object-record/record-table/record-table-cell/hooks/__mocks__/cell';
|
||||||
import { useCloseRecordTableCellNoGroup } from '@/object-record/record-table/record-table-cell/hooks/internal/useCloseRecordTableCellNoGroup';
|
import { useCloseRecordTableCellNoGroup } from '@/object-record/record-table/record-table-cell/hooks/internal/useCloseRecordTableCellNoGroup';
|
||||||
import { currentTableCellInEditModePositionComponentState } from '@/object-record/record-table/states/currentTableCellInEditModePositionComponentState';
|
import { currentTableCellInEditModePositionComponentState } from '@/object-record/record-table/states/currentTableCellInEditModePositionComponentState';
|
||||||
@ -54,13 +56,17 @@ const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
|||||||
isLabelIdentifier: false,
|
isLabelIdentifier: false,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<RecordTableRowContext.Provider value={recordTableRow}>
|
<RecordTableRowContextProvider value={recordTableRowContextValue}>
|
||||||
|
<RecordTableRowDraggableContextProvider
|
||||||
|
value={recordTableRowDraggableContextValue}
|
||||||
|
>
|
||||||
<RecordTableCellContext.Provider
|
<RecordTableCellContext.Provider
|
||||||
value={{ ...recordTableCell, columnIndex: 0 }}
|
value={{ ...recordTableCellContextValue, columnIndex: 0 }}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</RecordTableCellContext.Provider>
|
</RecordTableCellContext.Provider>
|
||||||
</RecordTableRowContext.Provider>
|
</RecordTableRowDraggableContextProvider>
|
||||||
|
</RecordTableRowContextProvider>
|
||||||
</FieldContext.Provider>
|
</FieldContext.Provider>
|
||||||
</RecordTableContextProvider>
|
</RecordTableContextProvider>
|
||||||
</RecordTableComponentInstance>
|
</RecordTableComponentInstance>
|
||||||
|
@ -5,7 +5,7 @@ import { useIsFieldValueReadOnly } from '@/object-record/record-field/hooks/useI
|
|||||||
import { FieldDefinition } from '@/object-record/record-field/types/FieldDefinition';
|
import { FieldDefinition } from '@/object-record/record-field/types/FieldDefinition';
|
||||||
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
||||||
import { CellHotkeyScopeContext } from '@/object-record/record-table/contexts/CellHotkeyScopeContext';
|
import { CellHotkeyScopeContext } from '@/object-record/record-table/contexts/CellHotkeyScopeContext';
|
||||||
import { RecordTableRowContext } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
import { useRecordTableRowContextOrThrow } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
||||||
import { useCurrentTableCellPosition } from '@/object-record/record-table/record-table-cell/hooks/useCurrentCellPosition';
|
import { useCurrentTableCellPosition } from '@/object-record/record-table/record-table-cell/hooks/useCurrentCellPosition';
|
||||||
import { TableCellPosition } from '@/object-record/record-table/types/TableCellPosition';
|
import { TableCellPosition } from '@/object-record/record-table/types/TableCellPosition';
|
||||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||||
@ -30,9 +30,9 @@ export type OpenTableCellArgs = {
|
|||||||
export const useOpenRecordTableCellFromCell = () => {
|
export const useOpenRecordTableCellFromCell = () => {
|
||||||
const customCellHotkeyScope = useContext(CellHotkeyScopeContext);
|
const customCellHotkeyScope = useContext(CellHotkeyScopeContext);
|
||||||
const { recordId, fieldDefinition } = useContext(FieldContext);
|
const { recordId, fieldDefinition } = useContext(FieldContext);
|
||||||
const { pathToShowPage, objectNameSingular } = useContext(
|
|
||||||
RecordTableRowContext,
|
const { pathToShowPage, objectNameSingular } =
|
||||||
);
|
useRecordTableRowContextOrThrow();
|
||||||
|
|
||||||
const { onOpenTableCell } = useRecordTableBodyContextOrThrow();
|
const { onOpenTableCell } = useRecordTableBodyContextOrThrow();
|
||||||
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
|
import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext';
|
||||||
import { RecordTableTd } from '@/object-record/record-table/record-table-cell/components/RecordTableTd';
|
import { RecordTableTd } from '@/object-record/record-table/record-table-cell/components/RecordTableTd';
|
||||||
import { visibleTableColumnsComponentSelector } from '@/object-record/record-table/states/selectors/visibleTableColumnsComponentSelector';
|
import { RecordTableDraggableTr } from '@/object-record/record-table/record-table-row/components/RecordTableDraggableTr';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
|
||||||
import { useTheme } from '@emotion/react';
|
import { useTheme } from '@emotion/react';
|
||||||
import { IconComponent } from 'twenty-ui';
|
import { IconComponent } from 'twenty-ui';
|
||||||
|
|
||||||
const StyledTrContainer = styled.tr`
|
const StyledRecordTableDraggableTr = styled(RecordTableDraggableTr)`
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@ -36,33 +36,40 @@ const StyledEmptyTd = styled.td`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
type RecordTableActionRowProps = {
|
type RecordTableActionRowProps = {
|
||||||
|
draggableId: string;
|
||||||
|
draggableIndex: number;
|
||||||
LeftIcon: IconComponent;
|
LeftIcon: IconComponent;
|
||||||
text: string;
|
text: string;
|
||||||
onClick?: (event?: React.MouseEvent<HTMLTableRowElement>) => void;
|
onClick?: (event?: React.MouseEvent<HTMLTableRowElement>) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const RecordTableActionRow = ({
|
export const RecordTableActionRow = ({
|
||||||
|
draggableId,
|
||||||
|
draggableIndex,
|
||||||
LeftIcon,
|
LeftIcon,
|
||||||
text,
|
text,
|
||||||
onClick,
|
onClick,
|
||||||
}: RecordTableActionRowProps) => {
|
}: RecordTableActionRowProps) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
const visibleColumns = useRecoilComponentValueV2(
|
const { visibleTableColumns } = useRecordTableContextOrThrow();
|
||||||
visibleTableColumnsComponentSelector,
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledTrContainer onClick={onClick}>
|
<StyledRecordTableDraggableTr
|
||||||
|
draggableId={draggableId}
|
||||||
|
draggableIndex={draggableIndex}
|
||||||
|
onClick={onClick}
|
||||||
|
isDragDisabled
|
||||||
|
>
|
||||||
<td aria-hidden />
|
<td aria-hidden />
|
||||||
<StyledIconContainer>
|
<StyledIconContainer>
|
||||||
<LeftIcon size={theme.icon.size.sm} color={theme.font.color.tertiary} />
|
<LeftIcon size={theme.icon.size.sm} color={theme.font.color.tertiary} />
|
||||||
</StyledIconContainer>
|
</StyledIconContainer>
|
||||||
<StyledRecordTableTdTextContainer colSpan={visibleColumns.length}>
|
<StyledRecordTableTdTextContainer colSpan={visibleTableColumns.length}>
|
||||||
<StyledText>{text}</StyledText>
|
<StyledText>{text}</StyledText>
|
||||||
</StyledRecordTableTdTextContainer>
|
</StyledRecordTableTdTextContainer>
|
||||||
<StyledEmptyTd />
|
<StyledEmptyTd />
|
||||||
<StyledEmptyTd />
|
<StyledEmptyTd />
|
||||||
</StyledTrContainer>
|
</StyledRecordTableDraggableTr>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import { useContext } from 'react';
|
import { useRecordTableRowContextOrThrow } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
||||||
|
import { useRecordTableRowDraggableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableRowDraggableContext';
|
||||||
import { RecordTableRowContext } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
|
||||||
import { RecordTableCellsEmpty } from '@/object-record/record-table/record-table-row/components/RecordTableCellsEmpty';
|
import { RecordTableCellsEmpty } from '@/object-record/record-table/record-table-row/components/RecordTableCellsEmpty';
|
||||||
import { RecordTableCellsVisible } from '@/object-record/record-table/record-table-row/components/RecordTableCellsVisible';
|
import { RecordTableCellsVisible } from '@/object-record/record-table/record-table-row/components/RecordTableCellsVisible';
|
||||||
|
|
||||||
export const RecordTableCells = () => {
|
export const RecordTableCells = () => {
|
||||||
const { inView, isDragging } = useContext(RecordTableRowContext);
|
const { inView } = useRecordTableRowContextOrThrow();
|
||||||
|
|
||||||
|
const { isDragging } = useRecordTableRowDraggableContextOrThrow();
|
||||||
|
|
||||||
const areCellsVisible = inView || isDragging;
|
const areCellsVisible = inView || isDragging;
|
||||||
|
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import { RecordTableRowContext } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
import { useRecordTableRowContextOrThrow } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
||||||
import { RecordTableTd } from '@/object-record/record-table/record-table-cell/components/RecordTableTd';
|
import { RecordTableTd } from '@/object-record/record-table/record-table-cell/components/RecordTableTd';
|
||||||
import { visibleTableColumnsComponentSelector } from '@/object-record/record-table/states/selectors/visibleTableColumnsComponentSelector';
|
import { visibleTableColumnsComponentSelector } from '@/object-record/record-table/states/selectors/visibleTableColumnsComponentSelector';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { useContext } from 'react';
|
|
||||||
|
|
||||||
export const RecordTableCellsEmpty = () => {
|
export const RecordTableCellsEmpty = () => {
|
||||||
const { isSelected } = useContext(RecordTableRowContext);
|
const { isSelected } = useRecordTableRowContextOrThrow();
|
||||||
|
|
||||||
const visibleTableColumns = useRecoilComponentValueV2(
|
const visibleTableColumns = useRecoilComponentValueV2(
|
||||||
visibleTableColumnsComponentSelector,
|
visibleTableColumnsComponentSelector,
|
||||||
|
@ -1,20 +1,15 @@
|
|||||||
import { useContext } from 'react';
|
import { useRecordTableRowContextOrThrow } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
||||||
|
import { useRecordTableRowDraggableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableRowDraggableContext';
|
||||||
import { RecordTableRowContext } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
|
||||||
import { RecordTableCell } from '@/object-record/record-table/record-table-cell/components/RecordTableCell';
|
import { RecordTableCell } from '@/object-record/record-table/record-table-cell/components/RecordTableCell';
|
||||||
import { RecordTableCellWrapper } from '@/object-record/record-table/record-table-cell/components/RecordTableCellWrapper';
|
import { RecordTableCellWrapper } from '@/object-record/record-table/record-table-cell/components/RecordTableCellWrapper';
|
||||||
import { RecordTableTd } from '@/object-record/record-table/record-table-cell/components/RecordTableTd';
|
import { RecordTableTd } from '@/object-record/record-table/record-table-cell/components/RecordTableTd';
|
||||||
import { visibleTableColumnsComponentSelector } from '@/object-record/record-table/states/selectors/visibleTableColumnsComponentSelector';
|
import { visibleTableColumnsComponentSelector } from '@/object-record/record-table/states/selectors/visibleTableColumnsComponentSelector';
|
||||||
import { tableCellWidthsComponentState } from '@/object-record/record-table/states/tableCellWidthsComponentState';
|
|
||||||
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentStateV2';
|
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
|
|
||||||
export const RecordTableCellsVisible = () => {
|
export const RecordTableCellsVisible = () => {
|
||||||
const { isSelected, isDragging } = useContext(RecordTableRowContext);
|
const { isSelected } = useRecordTableRowContextOrThrow();
|
||||||
|
|
||||||
const [tableCellWidths] = useRecoilComponentStateV2(
|
const { isDragging } = useRecordTableRowDraggableContextOrThrow();
|
||||||
tableCellWidthsComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const visibleTableColumns = useRecoilComponentValueV2(
|
const visibleTableColumns = useRecoilComponentValueV2(
|
||||||
visibleTableColumnsComponentSelector,
|
visibleTableColumnsComponentSelector,
|
||||||
@ -28,7 +23,7 @@ export const RecordTableCellsVisible = () => {
|
|||||||
<RecordTableTd
|
<RecordTableTd
|
||||||
isSelected={isSelected}
|
isSelected={isSelected}
|
||||||
isDragging={isDragging}
|
isDragging={isDragging}
|
||||||
width={tableCellWidths[2]}
|
width={visibleTableColumns[0].size}
|
||||||
>
|
>
|
||||||
<RecordTableCell />
|
<RecordTableCell />
|
||||||
</RecordTableTd>
|
</RecordTableTd>
|
||||||
@ -42,7 +37,7 @@ export const RecordTableCellsVisible = () => {
|
|||||||
<RecordTableTd
|
<RecordTableTd
|
||||||
isSelected={isSelected}
|
isSelected={isSelected}
|
||||||
isDragging={isDragging}
|
isDragging={isDragging}
|
||||||
width={tableCellWidths[columnIndex + 3]}
|
width={column.size}
|
||||||
>
|
>
|
||||||
<RecordTableCell />
|
<RecordTableCell />
|
||||||
</RecordTableTd>
|
</RecordTableTd>
|
||||||
|
@ -0,0 +1,63 @@
|
|||||||
|
import { useTheme } from '@emotion/react';
|
||||||
|
import { Draggable, DraggableId } from '@hello-pangea/dnd';
|
||||||
|
import { forwardRef, ReactNode } from 'react';
|
||||||
|
|
||||||
|
import { RecordTableRowDraggableContextProvider } from '@/object-record/record-table/contexts/RecordTableRowDraggableContext';
|
||||||
|
import { RecordTableTr } from '@/object-record/record-table/record-table-row/components/RecordTableTr';
|
||||||
|
import { combineRefs } from '~/utils/combineRefs';
|
||||||
|
|
||||||
|
type RecordTableDraggableTrProps = {
|
||||||
|
draggableId: DraggableId;
|
||||||
|
draggableIndex: number;
|
||||||
|
isDragDisabled?: boolean;
|
||||||
|
onClick?: (event: React.MouseEvent<HTMLTableRowElement>) => void;
|
||||||
|
children: ReactNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const RecordTableDraggableTr = forwardRef<
|
||||||
|
HTMLTableRowElement,
|
||||||
|
RecordTableDraggableTrProps
|
||||||
|
>(({ draggableId, draggableIndex, isDragDisabled, onClick, children }, ref) => {
|
||||||
|
const theme = useTheme();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Draggable
|
||||||
|
draggableId={draggableId}
|
||||||
|
index={draggableIndex}
|
||||||
|
isDragDisabled={isDragDisabled}
|
||||||
|
>
|
||||||
|
{(draggableProvided, draggableSnapshot) => (
|
||||||
|
<RecordTableTr
|
||||||
|
ref={combineRefs<HTMLTableRowElement>(
|
||||||
|
ref,
|
||||||
|
draggableProvided.innerRef,
|
||||||
|
)}
|
||||||
|
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||||
|
{...draggableProvided.draggableProps}
|
||||||
|
style={{
|
||||||
|
...draggableProvided.draggableProps.style,
|
||||||
|
background: draggableSnapshot.isDragging
|
||||||
|
? theme.background.transparent.light
|
||||||
|
: 'none',
|
||||||
|
borderColor: draggableSnapshot.isDragging
|
||||||
|
? `${theme.border.color.medium}`
|
||||||
|
: 'transparent',
|
||||||
|
}}
|
||||||
|
isDragging={draggableSnapshot.isDragging}
|
||||||
|
data-testid={`row-id-${draggableId}`}
|
||||||
|
data-selectable-id={draggableId}
|
||||||
|
onClick={onClick}
|
||||||
|
>
|
||||||
|
<RecordTableRowDraggableContextProvider
|
||||||
|
value={{
|
||||||
|
isDragging: draggableSnapshot.isDragging,
|
||||||
|
dragHandleProps: draggableProvided.dragHandleProps,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</RecordTableRowDraggableContextProvider>
|
||||||
|
</RecordTableTr>
|
||||||
|
)}
|
||||||
|
</Draggable>
|
||||||
|
);
|
||||||
|
});
|
@ -1,18 +1,14 @@
|
|||||||
import { useTheme } from '@emotion/react';
|
import { ReactNode, useContext, useEffect } from 'react';
|
||||||
import { Draggable } from '@hello-pangea/dnd';
|
|
||||||
import { ReactNode, useContext, useEffect, useRef } from 'react';
|
|
||||||
import { useInView } from 'react-intersection-observer';
|
|
||||||
|
|
||||||
import { getBasePathToShowPage } from '@/object-metadata/utils/getBasePathToShowPage';
|
import { getBasePathToShowPage } from '@/object-metadata/utils/getBasePathToShowPage';
|
||||||
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
|
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
|
||||||
import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext';
|
import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext';
|
||||||
import { RecordTableRowContext } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
import { RecordTableRowContextProvider } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
||||||
import { RecordTableTr } from '@/object-record/record-table/record-table-row/components/RecordTableTr';
|
import { RecordTableDraggableTr } from '@/object-record/record-table/record-table-row/components/RecordTableDraggableTr';
|
||||||
import { isRowSelectedComponentFamilyState } from '@/object-record/record-table/record-table-row/states/isRowSelectedComponentFamilyState';
|
import { isRowSelectedComponentFamilyState } from '@/object-record/record-table/record-table-row/states/isRowSelectedComponentFamilyState';
|
||||||
import { tableCellWidthsComponentState } from '@/object-record/record-table/states/tableCellWidthsComponentState';
|
|
||||||
import { RecordTableWithWrappersScrollWrapperContext } from '@/ui/utilities/scroll/contexts/ScrollWrapperContexts';
|
import { RecordTableWithWrappersScrollWrapperContext } from '@/ui/utilities/scroll/contexts/ScrollWrapperContexts';
|
||||||
import { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValueV2';
|
import { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValueV2';
|
||||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
import { useInView } from 'react-intersection-observer';
|
||||||
|
|
||||||
type RecordTableRowWrapperProps = {
|
type RecordTableRowWrapperProps = {
|
||||||
recordId: string;
|
recordId: string;
|
||||||
@ -29,18 +25,15 @@ export const RecordTableRowWrapper = ({
|
|||||||
isPendingRow,
|
isPendingRow,
|
||||||
children,
|
children,
|
||||||
}: RecordTableRowWrapperProps) => {
|
}: RecordTableRowWrapperProps) => {
|
||||||
const trRef = useRef<HTMLTableRowElement>(null);
|
|
||||||
|
|
||||||
const { objectMetadataItem } = useRecordTableContextOrThrow();
|
const { objectMetadataItem } = useRecordTableContextOrThrow();
|
||||||
const { onIndexRecordsLoaded } = useRecordIndexContextOrThrow();
|
|
||||||
|
|
||||||
const theme = useTheme();
|
|
||||||
|
|
||||||
const currentRowSelected = useRecoilComponentFamilyValueV2(
|
const currentRowSelected = useRecoilComponentFamilyValueV2(
|
||||||
isRowSelectedComponentFamilyState,
|
isRowSelectedComponentFamilyState,
|
||||||
recordId,
|
recordId,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { onIndexRecordsLoaded } = useRecordIndexContextOrThrow();
|
||||||
|
|
||||||
const scrollWrapperRef = useContext(
|
const scrollWrapperRef = useContext(
|
||||||
RecordTableWithWrappersScrollWrapperContext,
|
RecordTableWithWrappersScrollWrapperContext,
|
||||||
);
|
);
|
||||||
@ -52,24 +45,6 @@ export const RecordTableRowWrapper = ({
|
|||||||
rootMargin: '1000px',
|
rootMargin: '1000px',
|
||||||
});
|
});
|
||||||
|
|
||||||
const setTableCellWidths = useSetRecoilComponentStateV2(
|
|
||||||
tableCellWidthsComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (rowIndexForFocus === 0) {
|
|
||||||
const tdArray = Array.from(
|
|
||||||
trRef.current?.getElementsByTagName('td') ?? [],
|
|
||||||
);
|
|
||||||
|
|
||||||
const tdWidths = tdArray.map((td) => {
|
|
||||||
return td.getBoundingClientRect().width;
|
|
||||||
});
|
|
||||||
|
|
||||||
setTableCellWidths(tdWidths);
|
|
||||||
}
|
|
||||||
}, [trRef, rowIndexForFocus, setTableCellWidths]);
|
|
||||||
|
|
||||||
// TODO: find a better way to emit this event
|
// TODO: find a better way to emit this event
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (inView) {
|
if (inView) {
|
||||||
@ -78,36 +53,14 @@ export const RecordTableRowWrapper = ({
|
|||||||
}, [inView, onIndexRecordsLoaded]);
|
}, [inView, onIndexRecordsLoaded]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Draggable
|
<RecordTableDraggableTr
|
||||||
|
ref={elementRef}
|
||||||
key={recordId}
|
key={recordId}
|
||||||
draggableId={recordId}
|
draggableId={recordId}
|
||||||
index={rowIndexForDrag}
|
draggableIndex={rowIndexForDrag}
|
||||||
isDragDisabled={isPendingRow}
|
isDragDisabled={isPendingRow}
|
||||||
>
|
>
|
||||||
{(draggableProvided, draggableSnapshot) => (
|
<RecordTableRowContextProvider
|
||||||
<RecordTableTr
|
|
||||||
ref={(node) => {
|
|
||||||
// @ts-expect-error - TS doesn't know that node.current is assignable
|
|
||||||
trRef.current = node;
|
|
||||||
elementRef(node);
|
|
||||||
draggableProvided.innerRef(node);
|
|
||||||
}}
|
|
||||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
|
||||||
{...draggableProvided.draggableProps}
|
|
||||||
style={{
|
|
||||||
...draggableProvided.draggableProps.style,
|
|
||||||
background: draggableSnapshot.isDragging
|
|
||||||
? theme.background.transparent.light
|
|
||||||
: 'none',
|
|
||||||
borderColor: draggableSnapshot.isDragging
|
|
||||||
? `${theme.border.color.medium}`
|
|
||||||
: 'transparent',
|
|
||||||
}}
|
|
||||||
isDragging={draggableSnapshot.isDragging}
|
|
||||||
data-testid={`row-id-${recordId}`}
|
|
||||||
data-selectable-id={recordId}
|
|
||||||
>
|
|
||||||
<RecordTableRowContext.Provider
|
|
||||||
value={{
|
value={{
|
||||||
recordId,
|
recordId,
|
||||||
rowIndex: rowIndexForFocus,
|
rowIndex: rowIndexForFocus,
|
||||||
@ -118,15 +71,11 @@ export const RecordTableRowWrapper = ({
|
|||||||
objectNameSingular: objectMetadataItem.nameSingular,
|
objectNameSingular: objectMetadataItem.nameSingular,
|
||||||
isSelected: currentRowSelected,
|
isSelected: currentRowSelected,
|
||||||
isPendingRow,
|
isPendingRow,
|
||||||
isDragging: draggableSnapshot.isDragging,
|
|
||||||
dragHandleProps: draggableProvided.dragHandleProps,
|
|
||||||
inView,
|
inView,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</RecordTableRowContext.Provider>
|
</RecordTableRowContextProvider>
|
||||||
</RecordTableTr>
|
</RecordTableDraggableTr>
|
||||||
)}
|
|
||||||
</Draggable>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
import { useContext } from 'react';
|
|
||||||
import { useRecoilCallback } from 'recoil';
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
|
||||||
import { RecordTableRowContext } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
import { useRecordTableRowContextOrThrow } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
||||||
import { isRowSelectedComponentFamilyState } from '@/object-record/record-table/record-table-row/states/isRowSelectedComponentFamilyState';
|
import { isRowSelectedComponentFamilyState } from '@/object-record/record-table/record-table-row/states/isRowSelectedComponentFamilyState';
|
||||||
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
|
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
|
||||||
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
||||||
|
|
||||||
export const useSetCurrentRowSelected = () => {
|
export const useSetCurrentRowSelected = () => {
|
||||||
const { recordId } = useContext(RecordTableRowContext);
|
const { recordId } = useRecordTableRowContextOrThrow();
|
||||||
|
|
||||||
const isRowSelectedFamilyState = useRecoilComponentCallbackStateV2(
|
const isRowSelectedFamilyState = useRecoilComponentCallbackStateV2(
|
||||||
isRowSelectedComponentFamilyState,
|
isRowSelectedComponentFamilyState,
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
import { useCurrentRecordGroupId } from '@/object-record/record-group/hooks/useCurrentRecordGroupId';
|
import { useCurrentRecordGroupId } from '@/object-record/record-group/hooks/useCurrentRecordGroupId';
|
||||||
|
import { recordIndexAllRecordIdsComponentSelector } from '@/object-record/record-index/states/selectors/recordIndexAllRecordIdsComponentSelector';
|
||||||
import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext';
|
import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext';
|
||||||
import { useCreateNewTableRecord } from '@/object-record/record-table/hooks/useCreateNewTableRecords';
|
import { useCreateNewTableRecord } from '@/object-record/record-table/hooks/useCreateNewTableRecords';
|
||||||
import { RecordTableActionRow } from '@/object-record/record-table/record-table-row/components/RecordTableActionRow';
|
import { RecordTableActionRow } from '@/object-record/record-table/record-table-row/components/RecordTableActionRow';
|
||||||
import { recordTablePendingRecordIdByGroupComponentFamilyState } from '@/object-record/record-table/states/recordTablePendingRecordIdByGroupComponentFamilyState';
|
import { recordTablePendingRecordIdByGroupComponentFamilyState } from '@/object-record/record-table/states/recordTablePendingRecordIdByGroupComponentFamilyState';
|
||||||
import { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValueV2';
|
import { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValueV2';
|
||||||
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { IconPlus } from 'twenty-ui';
|
import { IconPlus } from 'twenty-ui';
|
||||||
import { isDefined } from '~/utils/isDefined';
|
import { isDefined } from '~/utils/isDefined';
|
||||||
|
|
||||||
@ -17,6 +19,10 @@ export const RecordTableRecordGroupSectionAddNew = () => {
|
|||||||
currentRecordGroupId,
|
currentRecordGroupId,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const recordIds = useRecoilComponentValueV2(
|
||||||
|
recordIndexAllRecordIdsComponentSelector,
|
||||||
|
);
|
||||||
|
|
||||||
const { createNewTableRecordInGroup } =
|
const { createNewTableRecordInGroup } =
|
||||||
useCreateNewTableRecord(recordTableId);
|
useCreateNewTableRecord(recordTableId);
|
||||||
|
|
||||||
@ -28,6 +34,8 @@ export const RecordTableRecordGroupSectionAddNew = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<RecordTableActionRow
|
<RecordTableActionRow
|
||||||
|
draggableId={`add-new-record-${currentRecordGroupId}`}
|
||||||
|
draggableIndex={recordIds.length + 2}
|
||||||
LeftIcon={IconPlus}
|
LeftIcon={IconPlus}
|
||||||
text="Add new"
|
text="Add new"
|
||||||
onClick={handleAddNewRecord}
|
onClick={handleAddNewRecord}
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
import { useCurrentRecordGroupId } from '@/object-record/record-group/hooks/useCurrentRecordGroupId';
|
import { useCurrentRecordGroupId } from '@/object-record/record-group/hooks/useCurrentRecordGroupId';
|
||||||
import { useLazyLoadRecordIndexTable } from '@/object-record/record-index/hooks/useLazyLoadRecordIndexTable';
|
import { useLazyLoadRecordIndexTable } from '@/object-record/record-index/hooks/useLazyLoadRecordIndexTable';
|
||||||
import { recordIndexHasFetchedAllRecordsByGroupComponentState } from '@/object-record/record-index/states/recordIndexHasFetchedAllRecordsByGroupComponentState';
|
import { recordIndexHasFetchedAllRecordsByGroupComponentState } from '@/object-record/record-index/states/recordIndexHasFetchedAllRecordsByGroupComponentState';
|
||||||
|
import { recordIndexAllRecordIdsComponentSelector } from '@/object-record/record-index/states/selectors/recordIndexAllRecordIdsComponentSelector';
|
||||||
import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext';
|
import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext';
|
||||||
import { RecordTableActionRow } from '@/object-record/record-table/record-table-row/components/RecordTableActionRow';
|
import { RecordTableActionRow } from '@/object-record/record-table/record-table-row/components/RecordTableActionRow';
|
||||||
import { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValueV2';
|
import { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValueV2';
|
||||||
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { IconArrowDown } from 'twenty-ui';
|
import { IconArrowDown } from 'twenty-ui';
|
||||||
|
|
||||||
export const RecordTableRecordGroupSectionLoadMore = () => {
|
export const RecordTableRecordGroupSectionLoadMore = () => {
|
||||||
@ -18,6 +20,10 @@ export const RecordTableRecordGroupSectionLoadMore = () => {
|
|||||||
currentRecordGroupId,
|
currentRecordGroupId,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const recordIds = useRecoilComponentValueV2(
|
||||||
|
recordIndexAllRecordIdsComponentSelector,
|
||||||
|
);
|
||||||
|
|
||||||
const handleLoadMore = () => {
|
const handleLoadMore = () => {
|
||||||
fetchMoreRecords();
|
fetchMoreRecords();
|
||||||
};
|
};
|
||||||
@ -28,6 +34,8 @@ export const RecordTableRecordGroupSectionLoadMore = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<RecordTableActionRow
|
<RecordTableActionRow
|
||||||
|
draggableId={`load-more-records-${currentRecordGroupId}`}
|
||||||
|
draggableIndex={recordIds.length + 1}
|
||||||
LeftIcon={IconArrowDown}
|
LeftIcon={IconArrowDown}
|
||||||
text="Load more"
|
text="Load more"
|
||||||
onClick={handleLoadMore}
|
onClick={handleLoadMore}
|
||||||
|
15
packages/twenty-front/src/utils/combineRefs.ts
Normal file
15
packages/twenty-front/src/utils/combineRefs.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { isFunction } from '@sniptt/guards';
|
||||||
|
import { MutableRefObject, Ref } from 'react';
|
||||||
|
import { isDefined } from '~/utils/isDefined';
|
||||||
|
|
||||||
|
export const combineRefs = <T>(...refs: (Ref<T> | undefined)[]) => {
|
||||||
|
return (node: T) => {
|
||||||
|
for (const ref of refs) {
|
||||||
|
if (isFunction(ref)) {
|
||||||
|
ref(node);
|
||||||
|
} else if (isDefined(ref) && 'current' in ref) {
|
||||||
|
(ref as MutableRefObject<T | null>).current = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user