Removed useRecordTable (#13837)
This PR removes useRecordTable barrel-hook and instead use the pattern that enforces one hook per function. This allows to have a easier to maintain React code with small dedicated hooks. This PR also improves the usage of those hooks by cleaning some logic that calls them. We introduce a new hook : `useRecordIndexIdFromCurrentContextStore` that factorizes logic that was duplicated to retrieve the `recordTableId`. Introduced `useHandleColumnsChange`, that saves table columns into view, this could be discussed but is it isolated with a TODO comment so ok for now. Also lowered the coverage because not enough to cover with test here. --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
co-authored by
Charles Bochet
parent
3a1c94147f
commit
6cc947ea01
@@ -60,7 +60,7 @@ const jestConfig: JestConfigWithTsJest = {
|
||||
global: {
|
||||
statements: 55,
|
||||
lines: 54,
|
||||
functions: 45,
|
||||
functions: 44,
|
||||
},
|
||||
},
|
||||
collectCoverageFrom: ['<rootDir>/src/**/*.ts'],
|
||||
|
||||
+5
-10
@@ -1,5 +1,4 @@
|
||||
import { ActionModal } from '@/action-menu/actions/components/ActionModal';
|
||||
import { useContextStoreObjectMetadataItemOrThrow } from '@/context-store/hooks/useContextStoreObjectMetadataItemOrThrow';
|
||||
import { contextStoreAnyFieldFilterValueComponentState } from '@/context-store/states/contextStoreAnyFieldFilterValueComponentState';
|
||||
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
|
||||
import { contextStoreFiltersComponentState } from '@/context-store/states/contextStoreFiltersComponentState';
|
||||
@@ -9,13 +8,14 @@ import { DEFAULT_QUERY_PAGE_SIZE } from '@/object-record/constants/DefaultQueryP
|
||||
import { useDeleteManyRecords } from '@/object-record/hooks/useDeleteManyRecords';
|
||||
import { useLazyFetchAllRecords } from '@/object-record/hooks/useLazyFetchAllRecords';
|
||||
import { useFilterValueDependencies } from '@/object-record/record-filter/hooks/useFilterValueDependencies';
|
||||
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
|
||||
import { getRecordIndexIdFromObjectNamePluralAndViewId } from '@/object-record/utils/getRecordIndexIdFromObjectNamePluralAndViewId';
|
||||
import { useRecordIndexIdFromCurrentContextStore } from '@/object-record/record-index/hooks/useRecordIndexIdFromCurrentContextStore';
|
||||
import { useResetTableRowSelection } from '@/object-record/record-table/hooks/internal/useResetTableRowSelection';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { t } from '@lingui/core/macro';
|
||||
|
||||
export const DeleteMultipleRecordsAction = () => {
|
||||
const { objectMetadataItem } = useContextStoreObjectMetadataItemOrThrow();
|
||||
const { recordIndexId, objectMetadataItem } =
|
||||
useRecordIndexIdFromCurrentContextStore();
|
||||
|
||||
const contextStoreCurrentViewId = useRecoilComponentValue(
|
||||
contextStoreCurrentViewIdComponentState,
|
||||
@@ -25,12 +25,7 @@ export const DeleteMultipleRecordsAction = () => {
|
||||
throw new Error('Current view ID is not defined');
|
||||
}
|
||||
|
||||
const { resetTableRowSelection } = useRecordTable({
|
||||
recordTableId: getRecordIndexIdFromObjectNamePluralAndViewId(
|
||||
objectMetadataItem.namePlural,
|
||||
contextStoreCurrentViewId,
|
||||
),
|
||||
});
|
||||
const { resetTableRowSelection } = useResetTableRowSelection(recordIndexId);
|
||||
|
||||
const { deleteManyRecords } = useDeleteManyRecords({
|
||||
objectNameSingular: objectMetadataItem.nameSingular,
|
||||
|
||||
+5
-10
@@ -1,5 +1,4 @@
|
||||
import { ActionModal } from '@/action-menu/actions/components/ActionModal';
|
||||
import { useContextStoreObjectMetadataItemOrThrow } from '@/context-store/hooks/useContextStoreObjectMetadataItemOrThrow';
|
||||
import { contextStoreAnyFieldFilterValueComponentState } from '@/context-store/states/contextStoreAnyFieldFilterValueComponentState';
|
||||
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
|
||||
import { contextStoreFiltersComponentState } from '@/context-store/states/contextStoreFiltersComponentState';
|
||||
@@ -10,12 +9,13 @@ import { type RecordGqlOperationFilter } from '@/object-record/graphql/types/Rec
|
||||
import { useDestroyManyRecords } from '@/object-record/hooks/useDestroyManyRecords';
|
||||
import { useLazyFetchAllRecords } from '@/object-record/hooks/useLazyFetchAllRecords';
|
||||
import { useFilterValueDependencies } from '@/object-record/record-filter/hooks/useFilterValueDependencies';
|
||||
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
|
||||
import { getRecordIndexIdFromObjectNamePluralAndViewId } from '@/object-record/utils/getRecordIndexIdFromObjectNamePluralAndViewId';
|
||||
import { useRecordIndexIdFromCurrentContextStore } from '@/object-record/record-index/hooks/useRecordIndexIdFromCurrentContextStore';
|
||||
import { useResetTableRowSelection } from '@/object-record/record-table/hooks/internal/useResetTableRowSelection';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
|
||||
export const DestroyMultipleRecordsAction = () => {
|
||||
const { objectMetadataItem } = useContextStoreObjectMetadataItemOrThrow();
|
||||
const { recordIndexId, objectMetadataItem } =
|
||||
useRecordIndexIdFromCurrentContextStore();
|
||||
|
||||
const contextStoreCurrentViewId = useRecoilComponentValue(
|
||||
contextStoreCurrentViewIdComponentState,
|
||||
@@ -25,12 +25,7 @@ export const DestroyMultipleRecordsAction = () => {
|
||||
throw new Error('Current view ID is not defined');
|
||||
}
|
||||
|
||||
const { resetTableRowSelection } = useRecordTable({
|
||||
recordTableId: getRecordIndexIdFromObjectNamePluralAndViewId(
|
||||
objectMetadataItem.namePlural,
|
||||
contextStoreCurrentViewId,
|
||||
),
|
||||
});
|
||||
const { resetTableRowSelection } = useResetTableRowSelection(recordIndexId);
|
||||
|
||||
const { destroyManyRecords } = useDestroyManyRecords({
|
||||
objectNameSingular: objectMetadataItem.nameSingular,
|
||||
|
||||
+5
-10
@@ -1,5 +1,4 @@
|
||||
import { ActionModal } from '@/action-menu/actions/components/ActionModal';
|
||||
import { useContextStoreObjectMetadataItemOrThrow } from '@/context-store/hooks/useContextStoreObjectMetadataItemOrThrow';
|
||||
import { contextStoreAnyFieldFilterValueComponentState } from '@/context-store/states/contextStoreAnyFieldFilterValueComponentState';
|
||||
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
|
||||
import { contextStoreFiltersComponentState } from '@/context-store/states/contextStoreFiltersComponentState';
|
||||
@@ -10,12 +9,13 @@ import { type RecordGqlOperationFilter } from '@/object-record/graphql/types/Rec
|
||||
import { useLazyFetchAllRecords } from '@/object-record/hooks/useLazyFetchAllRecords';
|
||||
import { useRestoreManyRecords } from '@/object-record/hooks/useRestoreManyRecords';
|
||||
import { useFilterValueDependencies } from '@/object-record/record-filter/hooks/useFilterValueDependencies';
|
||||
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
|
||||
import { getRecordIndexIdFromObjectNamePluralAndViewId } from '@/object-record/utils/getRecordIndexIdFromObjectNamePluralAndViewId';
|
||||
import { useRecordIndexIdFromCurrentContextStore } from '@/object-record/record-index/hooks/useRecordIndexIdFromCurrentContextStore';
|
||||
import { useResetTableRowSelection } from '@/object-record/record-table/hooks/internal/useResetTableRowSelection';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
|
||||
export const RestoreMultipleRecordsAction = () => {
|
||||
const { objectMetadataItem } = useContextStoreObjectMetadataItemOrThrow();
|
||||
const { recordIndexId, objectMetadataItem } =
|
||||
useRecordIndexIdFromCurrentContextStore();
|
||||
|
||||
const contextStoreCurrentViewId = useRecoilComponentValue(
|
||||
contextStoreCurrentViewIdComponentState,
|
||||
@@ -25,12 +25,7 @@ export const RestoreMultipleRecordsAction = () => {
|
||||
throw new Error('Current view ID is not defined');
|
||||
}
|
||||
|
||||
const { resetTableRowSelection } = useRecordTable({
|
||||
recordTableId: getRecordIndexIdFromObjectNamePluralAndViewId(
|
||||
objectMetadataItem.namePlural,
|
||||
contextStoreCurrentViewId,
|
||||
),
|
||||
});
|
||||
const { resetTableRowSelection } = useResetTableRowSelection(recordIndexId);
|
||||
|
||||
const { restoreManyRecords } = useRestoreManyRecords({
|
||||
objectNameSingular: objectMetadataItem.nameSingular,
|
||||
|
||||
+5
-6
@@ -1,21 +1,20 @@
|
||||
import { ActionModal } from '@/action-menu/actions/components/ActionModal';
|
||||
import { useSelectedRecordIdOrThrow } from '@/action-menu/actions/record-actions/single-record/hooks/useSelectedRecordIdOrThrow';
|
||||
import { useContextStoreObjectMetadataItemOrThrow } from '@/context-store/hooks/useContextStoreObjectMetadataItemOrThrow';
|
||||
import { useDeleteFavorite } from '@/favorites/hooks/useDeleteFavorite';
|
||||
import { useFavorites } from '@/favorites/hooks/useFavorites';
|
||||
import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord';
|
||||
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
|
||||
import { useRecordIndexIdFromCurrentContextStore } from '@/object-record/record-index/hooks/useRecordIndexIdFromCurrentContextStore';
|
||||
import { useResetTableRowSelection } from '@/object-record/record-table/hooks/internal/useResetTableRowSelection';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const DeleteSingleRecordAction = () => {
|
||||
const { objectMetadataItem } = useContextStoreObjectMetadataItemOrThrow();
|
||||
const { recordIndexId, objectMetadataItem } =
|
||||
useRecordIndexIdFromCurrentContextStore();
|
||||
|
||||
const recordId = useSelectedRecordIdOrThrow();
|
||||
|
||||
const { resetTableRowSelection } = useRecordTable({
|
||||
recordTableId: objectMetadataItem.namePlural,
|
||||
});
|
||||
const { resetTableRowSelection } = useResetTableRowSelection(recordIndexId);
|
||||
|
||||
const { deleteOneRecord } = useDeleteOneRecord({
|
||||
objectNameSingular: objectMetadataItem.nameSingular,
|
||||
|
||||
+5
-6
@@ -1,21 +1,20 @@
|
||||
import { ActionModal } from '@/action-menu/actions/components/ActionModal';
|
||||
import { useSelectedRecordIdOrThrow } from '@/action-menu/actions/record-actions/single-record/hooks/useSelectedRecordIdOrThrow';
|
||||
import { useContextStoreObjectMetadataItemOrThrow } from '@/context-store/hooks/useContextStoreObjectMetadataItemOrThrow';
|
||||
import { useDestroyOneRecord } from '@/object-record/hooks/useDestroyOneRecord';
|
||||
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
|
||||
import { useRecordIndexIdFromCurrentContextStore } from '@/object-record/record-index/hooks/useRecordIndexIdFromCurrentContextStore';
|
||||
import { useResetTableRowSelection } from '@/object-record/record-table/hooks/internal/useResetTableRowSelection';
|
||||
import { AppPath } from '@/types/AppPath';
|
||||
import { useNavigateApp } from '~/hooks/useNavigateApp';
|
||||
|
||||
export const DestroySingleRecordAction = () => {
|
||||
const { objectMetadataItem } = useContextStoreObjectMetadataItemOrThrow();
|
||||
const { recordIndexId, objectMetadataItem } =
|
||||
useRecordIndexIdFromCurrentContextStore();
|
||||
|
||||
const recordId = useSelectedRecordIdOrThrow();
|
||||
|
||||
const navigateApp = useNavigateApp();
|
||||
|
||||
const { resetTableRowSelection } = useRecordTable({
|
||||
recordTableId: objectMetadataItem.namePlural,
|
||||
});
|
||||
const { resetTableRowSelection } = useResetTableRowSelection(recordIndexId);
|
||||
|
||||
const { destroyOneRecord } = useDestroyOneRecord({
|
||||
objectNameSingular: objectMetadataItem.nameSingular,
|
||||
|
||||
+5
-6
@@ -1,17 +1,16 @@
|
||||
import { ActionModal } from '@/action-menu/actions/components/ActionModal';
|
||||
import { useSelectedRecordIdOrThrow } from '@/action-menu/actions/record-actions/single-record/hooks/useSelectedRecordIdOrThrow';
|
||||
import { useContextStoreObjectMetadataItemOrThrow } from '@/context-store/hooks/useContextStoreObjectMetadataItemOrThrow';
|
||||
import { useRestoreManyRecords } from '@/object-record/hooks/useRestoreManyRecords';
|
||||
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
|
||||
import { useRecordIndexIdFromCurrentContextStore } from '@/object-record/record-index/hooks/useRecordIndexIdFromCurrentContextStore';
|
||||
import { useResetTableRowSelection } from '@/object-record/record-table/hooks/internal/useResetTableRowSelection';
|
||||
|
||||
export const RestoreSingleRecordAction = () => {
|
||||
const { objectMetadataItem } = useContextStoreObjectMetadataItemOrThrow();
|
||||
const { recordIndexId, objectMetadataItem } =
|
||||
useRecordIndexIdFromCurrentContextStore();
|
||||
|
||||
const recordId = useSelectedRecordIdOrThrow();
|
||||
|
||||
const { resetTableRowSelection } = useRecordTable({
|
||||
recordTableId: objectMetadataItem.namePlural,
|
||||
});
|
||||
const { resetTableRowSelection } = useResetTableRowSelection(recordIndexId);
|
||||
|
||||
const { restoreManyRecords } = useRestoreManyRecords({
|
||||
objectNameSingular: objectMetadataItem.nameSingular,
|
||||
|
||||
@@ -78,7 +78,7 @@ export const PageChangeEffect = () => {
|
||||
contextStoreCurrentViewId || '',
|
||||
);
|
||||
|
||||
const resetTableSelections = useResetTableRowSelection(recordIndexId);
|
||||
const { resetTableRowSelection } = useResetTableRowSelection(recordIndexId);
|
||||
const { unfocusRecordTableRow } = useFocusedRecordTableRow(recordIndexId);
|
||||
const { deactivateRecordTableRow } = useActiveRecordTableRow(recordIndexId);
|
||||
|
||||
@@ -124,7 +124,7 @@ export const PageChangeEffect = () => {
|
||||
|
||||
if (isLeavingRecordIndexPage) {
|
||||
if (contextStoreCurrentViewType === ContextStoreViewType.Table) {
|
||||
resetTableSelections();
|
||||
resetTableRowSelection();
|
||||
unfocusRecordTableRow();
|
||||
deactivateRecordTableRow();
|
||||
}
|
||||
@@ -289,7 +289,7 @@ export const PageChangeEffect = () => {
|
||||
location,
|
||||
previousLocation,
|
||||
contextStoreCurrentViewType,
|
||||
resetTableSelections,
|
||||
resetTableRowSelection,
|
||||
unfocusRecordTableRow,
|
||||
deactivateRecordTableRow,
|
||||
resetRecordSelection,
|
||||
|
||||
+1
-5
@@ -12,7 +12,6 @@ import { peopleQueryResult } from '~/testing/mock-data/people';
|
||||
|
||||
const recordTableId = 'people';
|
||||
const objectNameSingular = 'person';
|
||||
const onColumnsChange = jest.fn();
|
||||
|
||||
const ObjectNamePluralSetter = ({ children }: { children: ReactNode }) => {
|
||||
return <>{children}</>;
|
||||
@@ -662,10 +661,7 @@ const Wrapper = ({ children }: { children: ReactNode }) => {
|
||||
<ViewComponentInstanceContext.Provider
|
||||
value={{ instanceId: 'instanceId' }}
|
||||
>
|
||||
<RecordTableComponentInstance
|
||||
recordTableId={recordTableId}
|
||||
onColumnsChange={onColumnsChange}
|
||||
>
|
||||
<RecordTableComponentInstance recordTableId={recordTableId}>
|
||||
<RecordGroupContext.Provider value={{ recordGroupId: 'default' }}>
|
||||
{children}
|
||||
</RecordGroupContext.Provider>
|
||||
|
||||
+1
-1
@@ -52,7 +52,7 @@ const meta: Meta<typeof ObjectOptionsDropdownContent> = {
|
||||
value={{ instanceId }}
|
||||
>
|
||||
<RecordTableComponentInstanceContext.Provider
|
||||
value={{ instanceId, onColumnsChange: () => {} }}
|
||||
value={{ instanceId }}
|
||||
>
|
||||
<ViewComponentInstanceContext.Provider value={{ instanceId }}>
|
||||
<MemoryRouter
|
||||
|
||||
-130
@@ -1,130 +0,0 @@
|
||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { useObjectOptionsForTable } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsForTable';
|
||||
import { type FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
||||
import { RecordTableComponentInstanceContext } from '@/object-record/record-table/states/context/RecordTableComponentInstanceContext';
|
||||
import { tableColumnsComponentState } from '@/object-record/record-table/states/tableColumnsComponentState';
|
||||
import { type ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
|
||||
import { type DropResult, type ResponderProvided } from '@hello-pangea/dnd';
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { act } from 'react';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
|
||||
describe('useObjectOptionsForTable', () => {
|
||||
const fieldMetadataItems = [
|
||||
{ id: 'id-1', name: 'field1' },
|
||||
{ id: 'id-2', name: 'field2' },
|
||||
{ id: 'id-3', name: 'field3' },
|
||||
{ id: 'id-4', name: 'field4' },
|
||||
{ id: 'id-5', name: 'field5' },
|
||||
] as FieldMetadataItem[];
|
||||
|
||||
const columnDefinitionsWithMetadata = fieldMetadataItems.map(
|
||||
(field, index) => ({
|
||||
fieldMetadataId: field.id,
|
||||
isVisible: true,
|
||||
position: index + 1,
|
||||
metadata: {
|
||||
fieldName: field.name,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
const renderWithRecoil = () =>
|
||||
renderHook(() => useObjectOptionsForTable('instance-id', 'object-id'), {
|
||||
wrapper: ({ children }) => (
|
||||
<RecordTableComponentInstanceContext.Provider
|
||||
value={{ instanceId: 'instance-id', onColumnsChange: jest.fn() }}
|
||||
>
|
||||
<RecoilRoot
|
||||
initializeState={({ set }) => {
|
||||
set(
|
||||
tableColumnsComponentState.atomFamily({
|
||||
instanceId: 'instance-id',
|
||||
}),
|
||||
columnDefinitionsWithMetadata as ColumnDefinition<FieldMetadata>[],
|
||||
);
|
||||
set(objectMetadataItemsState, [
|
||||
{
|
||||
id: 'object-id',
|
||||
nameSingular: 'Object',
|
||||
namePlural: 'Objects',
|
||||
fields: fieldMetadataItems,
|
||||
readableFields: fieldMetadataItems,
|
||||
updatableFields: fieldMetadataItems,
|
||||
} as ObjectMetadataItem,
|
||||
]);
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</RecoilRoot>
|
||||
</RecordTableComponentInstanceContext.Provider>
|
||||
),
|
||||
});
|
||||
|
||||
it('reorders table columns correctly', () => {
|
||||
const { result } = renderWithRecoil();
|
||||
|
||||
const dropResult = {
|
||||
source: { droppableId: 'droppable', index: 2 },
|
||||
destination: { droppableId: 'droppable', index: 3 },
|
||||
draggableId: 'field2',
|
||||
type: 'TYPE',
|
||||
mode: 'FLUID',
|
||||
reason: 'DROP',
|
||||
combine: null,
|
||||
} as DropResult;
|
||||
|
||||
const responderProvided = {
|
||||
announce: jest.fn(),
|
||||
} as ResponderProvided;
|
||||
|
||||
act(() => {
|
||||
result.current.handleReorderColumns(dropResult, responderProvided);
|
||||
});
|
||||
|
||||
expect(result.current.visibleTableColumns).toEqual([
|
||||
{
|
||||
fieldMetadataId: 'id-1',
|
||||
isVisible: true,
|
||||
metadata: {
|
||||
fieldName: 'field1',
|
||||
},
|
||||
position: 0,
|
||||
},
|
||||
{
|
||||
fieldMetadataId: 'id-3',
|
||||
isVisible: true,
|
||||
metadata: {
|
||||
fieldName: 'field3',
|
||||
},
|
||||
position: 1,
|
||||
},
|
||||
{
|
||||
fieldMetadataId: 'id-2',
|
||||
isVisible: true,
|
||||
metadata: {
|
||||
fieldName: 'field2',
|
||||
},
|
||||
position: 2,
|
||||
},
|
||||
{
|
||||
fieldMetadataId: 'id-4',
|
||||
isVisible: true,
|
||||
metadata: {
|
||||
fieldName: 'field4',
|
||||
},
|
||||
position: 3,
|
||||
},
|
||||
{
|
||||
fieldMetadataId: 'id-5',
|
||||
isVisible: true,
|
||||
metadata: {
|
||||
fieldName: 'field5',
|
||||
},
|
||||
position: 4,
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
+1
-1
@@ -25,7 +25,7 @@ export const useObjectOptionsForTable = (
|
||||
);
|
||||
|
||||
const handleReorderColumns: OnDragEndResponder = useCallback(
|
||||
(result) => {
|
||||
async (result) => {
|
||||
if (
|
||||
!result.destination ||
|
||||
result.destination.index === 1 ||
|
||||
|
||||
-1
@@ -26,7 +26,6 @@ const meta: Meta = {
|
||||
<RecordTableComponentInstanceContext.Provider
|
||||
value={{
|
||||
instanceId,
|
||||
onColumnsChange: () => {},
|
||||
}}
|
||||
>
|
||||
<RecordIndexContextProvider
|
||||
|
||||
+3
-16
@@ -2,9 +2,6 @@ import { RecordIndexContextProvider } from '@/object-record/record-index/context
|
||||
|
||||
import { ActionMenuComponentInstanceContext } from '@/action-menu/states/contexts/ActionMenuComponentInstanceContext';
|
||||
import { getActionMenuIdFromRecordIndexId } from '@/action-menu/utils/getActionMenuIdFromRecordIndexId';
|
||||
import { MAIN_CONTEXT_STORE_INSTANCE_ID } from '@/context-store/constants/MainContextStoreInstanceId';
|
||||
import { useContextStoreObjectMetadataItemOrThrow } from '@/context-store/hooks/useContextStoreObjectMetadataItemOrThrow';
|
||||
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
|
||||
import { getObjectPermissionsForObject } from '@/object-metadata/utils/getObjectPermissionsForObject';
|
||||
import { useObjectPermissions } from '@/object-record/hooks/useObjectPermissions';
|
||||
import { lastShowPageRecordIdState } from '@/object-record/record-field/states/lastShowPageRecordId';
|
||||
@@ -15,12 +12,11 @@ import { RecordIndexContainerContextStoreNumberOfSelectedRecordsEffect } from '@
|
||||
import { RecordIndexLoadBaseOnContextStoreEffect } from '@/object-record/record-index/components/RecordIndexLoadBaseOnContextStoreEffect';
|
||||
import { RecordIndexPageHeader } from '@/object-record/record-index/components/RecordIndexPageHeader';
|
||||
import { useHandleIndexIdentifierClick } from '@/object-record/record-index/hooks/useHandleIndexIdentifierClick';
|
||||
import { useRecordIndexIdFromCurrentContextStore } from '@/object-record/record-index/hooks/useRecordIndexIdFromCurrentContextStore';
|
||||
import { RecordSortsComponentInstanceContext } from '@/object-record/record-sort/states/context/RecordSortsComponentInstanceContext';
|
||||
import { getRecordIndexIdFromObjectNamePluralAndViewId } from '@/object-record/utils/getRecordIndexIdFromObjectNamePluralAndViewId';
|
||||
import { PageBody } from '@/ui/layout/page/components/PageBody';
|
||||
import { RECORD_INDEX_DRAG_SELECT_BOUNDARY_CLASS } from '@/ui/utilities/drag-select/constants/RecordIndecDragSelectBoundaryClass';
|
||||
import { PageTitle } from '@/ui/utilities/page-title/components/PageTitle';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
|
||||
import styled from '@emotion/styled';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
@@ -33,17 +29,8 @@ const StyledIndexContainer = styled.div`
|
||||
`;
|
||||
|
||||
export const RecordIndexContainerGater = () => {
|
||||
const contextStoreCurrentViewId = useRecoilComponentValue(
|
||||
contextStoreCurrentViewIdComponentState,
|
||||
MAIN_CONTEXT_STORE_INSTANCE_ID,
|
||||
);
|
||||
|
||||
const { objectMetadataItem } = useContextStoreObjectMetadataItemOrThrow();
|
||||
|
||||
const recordIndexId = getRecordIndexIdFromObjectNamePluralAndViewId(
|
||||
objectMetadataItem.namePlural,
|
||||
contextStoreCurrentViewId || '',
|
||||
);
|
||||
const { recordIndexId, objectMetadataItem } =
|
||||
useRecordIndexIdFromCurrentContextStore();
|
||||
|
||||
const handleIndexRecordsLoaded = useRecoilCallback(
|
||||
({ set }) =>
|
||||
|
||||
+3
-16
@@ -3,8 +3,7 @@ import { useEffect } from 'react';
|
||||
import { useColumnDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useColumnDefinitionsFromFieldMetadata';
|
||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
|
||||
import { useHandleToggleColumnSort } from '@/object-record/record-index/hooks/useHandleToggleColumnSort';
|
||||
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
|
||||
import { useSetAvailableTableColumns } from '@/object-record/record-table/hooks/useSetAvailableTableColumns';
|
||||
import { viewFieldAggregateOperationState } from '@/object-record/record-table/record-table-footer/states/viewFieldAggregateOperationState';
|
||||
import { convertAggregateOperationToExtendedAggregateOperation } from '@/object-record/utils/convertAggregateOperationToExtendedAggregateOperation';
|
||||
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
|
||||
@@ -15,9 +14,8 @@ import { isDefined } from 'twenty-shared/utils';
|
||||
export const RecordIndexTableContainerEffect = () => {
|
||||
const { recordIndexId, objectNameSingular } = useRecordIndexContextOrThrow();
|
||||
|
||||
const { setAvailableTableColumns, setOnToggleColumnSort } = useRecordTable({
|
||||
recordTableId: recordIndexId,
|
||||
});
|
||||
const { setAvailableTableColumns } =
|
||||
useSetAvailableTableColumns(recordIndexId);
|
||||
|
||||
const { objectMetadataItem } = useObjectMetadataItem({
|
||||
objectNameSingular,
|
||||
@@ -30,19 +28,8 @@ export const RecordIndexTableContainerEffect = () => {
|
||||
setAvailableTableColumns(columnDefinitions);
|
||||
}, [columnDefinitions, setAvailableTableColumns]);
|
||||
|
||||
const handleToggleColumnSort = useHandleToggleColumnSort({
|
||||
objectNameSingular,
|
||||
});
|
||||
|
||||
const { currentView } = useGetCurrentViewOnly();
|
||||
|
||||
useEffect(() => {
|
||||
setOnToggleColumnSort(
|
||||
() => (fieldMetadataId: string) =>
|
||||
handleToggleColumnSort(fieldMetadataId),
|
||||
);
|
||||
}, [setOnToggleColumnSort, handleToggleColumnSort]);
|
||||
|
||||
const setViewFieldAggregateOperation = useRecoilCallback(
|
||||
({ set, snapshot }) =>
|
||||
(viewField: ViewField) => {
|
||||
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
import { useRecordIndexIdFromCurrentContextStore } from '@/object-record/record-index/hooks/useRecordIndexIdFromCurrentContextStore';
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { JestObjectMetadataItemSetter } from '~/testing/jest/JestObjectMetadataItemSetter';
|
||||
import { getJestMetadataAndApolloMocksAndActionMenuWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksAndActionMenuWrapper';
|
||||
|
||||
const testComponentInstanceId = 'test';
|
||||
const testCurrentViewId = 'view-id';
|
||||
const testObjectMetadataItemNameSingular = 'person';
|
||||
const testObjectMetadataItemNamePlural = 'people';
|
||||
|
||||
const Wrapper = getJestMetadataAndApolloMocksAndActionMenuWrapper({
|
||||
apolloMocks: [],
|
||||
componentInstanceId: testComponentInstanceId,
|
||||
contextStoreCurrentObjectMetadataNameSingular:
|
||||
testObjectMetadataItemNameSingular,
|
||||
contextStoreCurrentViewId: testCurrentViewId,
|
||||
});
|
||||
|
||||
describe('useRecordIndexIdFromCurrentContextStore', () => {
|
||||
it('works as expected with context', async () => {
|
||||
const { result } = renderHook(
|
||||
() => {
|
||||
const { objectMetadataItem, recordIndexId } =
|
||||
useRecordIndexIdFromCurrentContextStore();
|
||||
|
||||
return {
|
||||
objectMetadataItem,
|
||||
recordIndexId,
|
||||
};
|
||||
},
|
||||
{
|
||||
wrapper: ({ children }) => {
|
||||
return (
|
||||
<Wrapper>
|
||||
<JestObjectMetadataItemSetter>
|
||||
{children}
|
||||
</JestObjectMetadataItemSetter>
|
||||
</Wrapper>
|
||||
);
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current.recordIndexId).toBe(
|
||||
`${testObjectMetadataItemNamePlural}-${testCurrentViewId}`,
|
||||
);
|
||||
});
|
||||
});
|
||||
+6
-6
@@ -1,21 +1,21 @@
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { useColumnDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useColumnDefinitionsFromFieldMetadata';
|
||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||
import { useObjectMetadataItemById } from '@/object-metadata/hooks/useObjectMetadataItemById';
|
||||
import { useUpsertRecordSort } from '@/object-record/record-sort/hooks/useUpsertRecordSort';
|
||||
import { type RecordSort } from '@/object-record/record-sort/types/RecordSort';
|
||||
import { v4 } from 'uuid';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
type UseHandleToggleColumnSortProps = {
|
||||
objectNameSingular: string;
|
||||
objectMetadataItemId: string;
|
||||
};
|
||||
|
||||
export const useHandleToggleColumnSort = ({
|
||||
objectNameSingular,
|
||||
objectMetadataItemId,
|
||||
}: UseHandleToggleColumnSortProps) => {
|
||||
const { objectMetadataItem } = useObjectMetadataItem({
|
||||
objectNameSingular,
|
||||
const { objectMetadataItem } = useObjectMetadataItemById({
|
||||
objectId: objectMetadataItemId,
|
||||
});
|
||||
|
||||
const { columnDefinitions } =
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
import { useContextStoreObjectMetadataItemOrThrow } from '@/context-store/hooks/useContextStoreObjectMetadataItemOrThrow';
|
||||
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
|
||||
import { getRecordIndexIdFromObjectNamePluralAndViewId } from '@/object-record/utils/getRecordIndexIdFromObjectNamePluralAndViewId';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
|
||||
export const useRecordIndexIdFromCurrentContextStore = () => {
|
||||
const contextStoreCurrentViewId = useRecoilComponentValue(
|
||||
contextStoreCurrentViewIdComponentState,
|
||||
);
|
||||
|
||||
const { objectMetadataItem } = useContextStoreObjectMetadataItemOrThrow();
|
||||
|
||||
const recordIndexId = getRecordIndexIdFromObjectNamePluralAndViewId(
|
||||
objectMetadataItem.namePlural,
|
||||
contextStoreCurrentViewId || '',
|
||||
);
|
||||
|
||||
return {
|
||||
objectMetadataItem,
|
||||
recordIndexId,
|
||||
};
|
||||
};
|
||||
+2
-5
@@ -11,7 +11,7 @@ import { RecordTableScrollToFocusedCellEffect } from '@/object-record/record-tab
|
||||
import { RecordTableScrollToFocusedRowEffect } from '@/object-record/record-table/components/RecordTableScrollToFocusedRowEffect';
|
||||
import { RECORD_TABLE_CLICK_OUTSIDE_LISTENER_ID } from '@/object-record/record-table/constants/RecordTableClickOutsideListenerId';
|
||||
import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext';
|
||||
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
|
||||
import { useResetTableRowSelection } from '@/object-record/record-table/hooks/internal/useResetTableRowSelection';
|
||||
import { isRecordTableInitialLoadingComponentState } from '@/object-record/record-table/states/isRecordTableInitialLoadingComponentState';
|
||||
import { useClickOutsideListener } from '@/ui/utilities/pointer-event/hooks/useClickOutsideListener';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
@@ -45,9 +45,7 @@ export const RecordTable = () => {
|
||||
recordTableId,
|
||||
);
|
||||
|
||||
const { resetTableRowSelection, setRowSelected } = useRecordTable({
|
||||
recordTableId,
|
||||
});
|
||||
const { resetTableRowSelection } = useResetTableRowSelection(recordTableId);
|
||||
|
||||
const recordTableIsEmpty =
|
||||
!isRecordTableInitialLoading && allRecordIds.length === 0;
|
||||
@@ -84,7 +82,6 @@ export const RecordTable = () => {
|
||||
tableBodyRef={tableBodyRef}
|
||||
handleDragSelectionStart={handleDragSelectionStart}
|
||||
handleDragSelectionEnd={handleDragSelectionEnd}
|
||||
setRowSelected={setRowSelected}
|
||||
hasRecordGroups={hasRecordGroups}
|
||||
recordTableId={recordTableId}
|
||||
/>
|
||||
|
||||
-8
@@ -1,30 +1,22 @@
|
||||
import { type ReactNode } from 'react';
|
||||
|
||||
import { type FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
||||
import { type ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
|
||||
|
||||
import { RecordTableComponentInstanceEffect } from '@/object-record/record-table/components/RecordTableComponentInstanceEffect';
|
||||
import { RecordTableComponentInstanceContext } from '@/object-record/record-table/states/context/RecordTableComponentInstanceContext';
|
||||
|
||||
type RecordTableComponentInstanceProps = {
|
||||
children: ReactNode;
|
||||
recordTableId: string;
|
||||
onColumnsChange: (columns: ColumnDefinition<FieldMetadata>[]) => void;
|
||||
};
|
||||
|
||||
export const RecordTableComponentInstance = ({
|
||||
children,
|
||||
recordTableId,
|
||||
onColumnsChange,
|
||||
}: RecordTableComponentInstanceProps) => {
|
||||
return (
|
||||
<RecordTableComponentInstanceContext.Provider
|
||||
value={{
|
||||
instanceId: recordTableId,
|
||||
onColumnsChange,
|
||||
}}
|
||||
>
|
||||
<RecordTableComponentInstanceEffect onColumnsChange={onColumnsChange} />
|
||||
{children}
|
||||
</RecordTableComponentInstanceContext.Provider>
|
||||
);
|
||||
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import { type FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
||||
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
|
||||
import { type ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
|
||||
|
||||
type RecordTableComponentInstanceEffectProps = {
|
||||
onColumnsChange: (columns: ColumnDefinition<FieldMetadata>[]) => void;
|
||||
};
|
||||
|
||||
export const RecordTableComponentInstanceEffect = ({
|
||||
onColumnsChange,
|
||||
}: RecordTableComponentInstanceEffectProps) => {
|
||||
const { setOnColumnsChange } = useRecordTable();
|
||||
|
||||
useEffect(() => {
|
||||
setOnColumnsChange(() => onColumnsChange);
|
||||
}, [onColumnsChange, setOnColumnsChange]);
|
||||
|
||||
return <></>;
|
||||
};
|
||||
+15
-3
@@ -4,10 +4,13 @@ import { StyledTable } from '@/object-record/record-table/components/RecordTable
|
||||
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 { isRowSelectedComponentFamilyState } from '@/object-record/record-table/record-table-row/states/isRowSelectedComponentFamilyState';
|
||||
import { DragSelect } from '@/ui/utilities/drag-select/components/DragSelect';
|
||||
import { RECORD_INDEX_DRAG_SELECT_BOUNDARY_CLASS } from '@/ui/utilities/drag-select/constants/RecordIndecDragSelectBoundaryClass';
|
||||
import { useRecoilComponentFamilyCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyCallbackState';
|
||||
import styled from '@emotion/styled';
|
||||
import { useRef, useState } from 'react';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
|
||||
const StyledTableWithPointerEvents = styled(StyledTable)<{
|
||||
isDragging: boolean;
|
||||
@@ -28,7 +31,6 @@ export interface RecordTableContentProps {
|
||||
tableBodyRef: React.RefObject<HTMLTableElement>;
|
||||
handleDragSelectionStart: () => void;
|
||||
handleDragSelectionEnd: () => void;
|
||||
setRowSelected: (rowId: string, selected: boolean) => void;
|
||||
hasRecordGroups: boolean;
|
||||
recordTableId: string;
|
||||
}
|
||||
@@ -37,7 +39,6 @@ export const RecordTableContent = ({
|
||||
tableBodyRef,
|
||||
handleDragSelectionStart,
|
||||
handleDragSelectionEnd,
|
||||
setRowSelected,
|
||||
hasRecordGroups,
|
||||
recordTableId,
|
||||
}: RecordTableContentProps) => {
|
||||
@@ -54,6 +55,17 @@ export const RecordTableContent = ({
|
||||
handleDragSelectionEnd();
|
||||
};
|
||||
|
||||
const isRowSelectedCallbackFamilyState =
|
||||
useRecoilComponentFamilyCallbackState(isRowSelectedComponentFamilyState);
|
||||
|
||||
const handleDragSelectionChange = useRecoilCallback(
|
||||
({ set }) =>
|
||||
(rowId: string, selected: boolean) => {
|
||||
set(isRowSelectedCallbackFamilyState(rowId), selected);
|
||||
},
|
||||
[isRowSelectedCallbackFamilyState],
|
||||
);
|
||||
|
||||
return (
|
||||
<StyledTableContainer ref={containerRef}>
|
||||
<StyledTableWithPointerEvents ref={tableBodyRef} isDragging={isDragging}>
|
||||
@@ -69,7 +81,7 @@ export const RecordTableContent = ({
|
||||
<DragSelect
|
||||
selectableItemsContainerRef={containerRef}
|
||||
onDragSelectionStart={handleDragStart}
|
||||
onDragSelectionChange={setRowSelected}
|
||||
onDragSelectionChange={handleDragSelectionChange}
|
||||
onDragSelectionEnd={handleDragEnd}
|
||||
scrollWrapperComponentInstanceId={`record-table-scroll-${recordTableId}`}
|
||||
selectionBoundaryClass={RECORD_INDEX_DRAG_SELECT_BOUNDARY_CLASS}
|
||||
|
||||
+3
-27
@@ -1,19 +1,14 @@
|
||||
import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord';
|
||||
import { type FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
||||
import { RecordTable } from '@/object-record/record-table/components/RecordTable';
|
||||
import { RecordTableComponentInstance } from '@/object-record/record-table/components/RecordTableComponentInstance';
|
||||
import { RecordTableContextProvider } from '@/object-record/record-table/components/RecordTableContextProvider';
|
||||
import { EntityDeleteContext } from '@/object-record/record-table/contexts/EntityDeleteHookContext';
|
||||
import { type ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
|
||||
import { useSelectAllRows } from '@/object-record/record-table/hooks/internal/useSelectAllRows';
|
||||
import { PageFocusId } from '@/types/PageFocusId';
|
||||
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
|
||||
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
|
||||
import { useSaveCurrentViewFields } from '@/views/hooks/useSaveCurrentViewFields';
|
||||
import { mapColumnDefinitionsToViewFields } from '@/views/utils/mapColumnDefinitionToViewField';
|
||||
import styled from '@emotion/styled';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { RecordUpdateContext } from '../contexts/EntityUpdateMutationHookContext';
|
||||
import { useRecordTable } from '../hooks/useRecordTable';
|
||||
|
||||
const StyledTableContainer = styled.div`
|
||||
display: flex;
|
||||
@@ -36,12 +31,9 @@ export const RecordTableWithWrappers = ({
|
||||
recordTableId,
|
||||
viewBarId,
|
||||
}: RecordTableWithWrappersProps) => {
|
||||
const { selectAllRows, setHasUserSelectedAllRows } = useRecordTable({
|
||||
recordTableId,
|
||||
});
|
||||
const { selectAllRows } = useSelectAllRows(recordTableId);
|
||||
|
||||
const handleSelectAllRows = () => {
|
||||
setHasUserSelectedAllRows(true);
|
||||
selectAllRows();
|
||||
};
|
||||
|
||||
@@ -55,26 +47,10 @@ export const RecordTableWithWrappers = ({
|
||||
},
|
||||
});
|
||||
|
||||
const { saveViewFields } = useSaveCurrentViewFields();
|
||||
|
||||
const { deleteOneRecord } = useDeleteOneRecord({ objectNameSingular });
|
||||
|
||||
const handleColumnsChange = useRecoilCallback(
|
||||
() => (columns) => {
|
||||
saveViewFields(
|
||||
mapColumnDefinitionsToViewFields(
|
||||
columns as ColumnDefinition<FieldMetadata>[],
|
||||
),
|
||||
);
|
||||
},
|
||||
[saveViewFields],
|
||||
);
|
||||
|
||||
return (
|
||||
<RecordTableComponentInstance
|
||||
recordTableId={recordTableId}
|
||||
onColumnsChange={handleColumnsChange}
|
||||
>
|
||||
<RecordTableComponentInstance recordTableId={recordTableId}>
|
||||
<RecordTableContextProvider
|
||||
recordTableId={recordTableId}
|
||||
viewBarId={viewBarId}
|
||||
|
||||
+1
-4
@@ -75,10 +75,7 @@ const meta: Meta = {
|
||||
},
|
||||
}}
|
||||
>
|
||||
<RecordTableComponentInstance
|
||||
recordTableId="asd"
|
||||
onColumnsChange={() => {}}
|
||||
>
|
||||
<RecordTableComponentInstance recordTableId="asd">
|
||||
<RecordTableBodyContextProvider
|
||||
value={{
|
||||
onOpenTableCell: () => {},
|
||||
|
||||
+1
-3
@@ -14,9 +14,7 @@ export const useLeaveTableFocus = (recordTableId?: string) => {
|
||||
recordTableId,
|
||||
);
|
||||
|
||||
const resetTableRowSelection = useResetTableRowSelection(
|
||||
recordTableIdFromContext,
|
||||
);
|
||||
const { resetTableRowSelection } = useResetTableRowSelection();
|
||||
|
||||
const setRecordTableHoverPosition = useSetRecoilComponentState(
|
||||
recordTableHoverPositionComponentState,
|
||||
|
||||
+5
-1
@@ -41,7 +41,7 @@ export const useResetTableRowSelection = (recordTableId?: string) => {
|
||||
|
||||
const { closeDropdown } = useCloseDropdown();
|
||||
|
||||
return useRecoilCallback(
|
||||
const resetTableRowSelection = useRecoilCallback(
|
||||
({ set, snapshot }) =>
|
||||
() => {
|
||||
const allRecordIds = getSnapshotValue(
|
||||
@@ -72,4 +72,8 @@ export const useResetTableRowSelection = (recordTableId?: string) => {
|
||||
recordTableIdFromContext,
|
||||
],
|
||||
);
|
||||
|
||||
return {
|
||||
resetTableRowSelection,
|
||||
};
|
||||
};
|
||||
|
||||
+11
-1
@@ -2,16 +2,23 @@ import { useRecoilCallback } from 'recoil';
|
||||
|
||||
import { recordIndexAllRecordIdsComponentSelector } from '@/object-record/record-index/states/selectors/recordIndexAllRecordIdsComponentSelector';
|
||||
import { useResetTableRowSelection } from '@/object-record/record-table/hooks/internal/useResetTableRowSelection';
|
||||
import { hasUserSelectedAllRowsComponentState } from '@/object-record/record-table/record-table-row/states/hasUserSelectedAllRowsFamilyState';
|
||||
import { isRowSelectedComponentFamilyState } from '@/object-record/record-table/record-table-row/states/isRowSelectedComponentFamilyState';
|
||||
import { allRowsSelectedStatusComponentSelector } from '@/object-record/record-table/states/selectors/allRowsSelectedStatusComponentSelector';
|
||||
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
|
||||
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
|
||||
|
||||
export const useSelectAllRows = (recordTableId?: string) => {
|
||||
const hasUserSelectedAllRowsCallbackState = useRecoilComponentCallbackState(
|
||||
hasUserSelectedAllRowsComponentState,
|
||||
recordTableId,
|
||||
);
|
||||
|
||||
const allRowsSelectedStatusSelector = useRecoilComponentCallbackState(
|
||||
allRowsSelectedStatusComponentSelector,
|
||||
recordTableId,
|
||||
);
|
||||
|
||||
const isRowSelectedFamilyState = useRecoilComponentCallbackState(
|
||||
isRowSelectedComponentFamilyState,
|
||||
recordTableId,
|
||||
@@ -21,7 +28,7 @@ export const useSelectAllRows = (recordTableId?: string) => {
|
||||
recordTableId,
|
||||
);
|
||||
|
||||
const resetTableRowSelection = useResetTableRowSelection(recordTableId);
|
||||
const { resetTableRowSelection } = useResetTableRowSelection(recordTableId);
|
||||
|
||||
const selectAllRows = useRecoilCallback(
|
||||
({ set, snapshot }) =>
|
||||
@@ -47,12 +54,15 @@ export const useSelectAllRows = (recordTableId?: string) => {
|
||||
|
||||
set(isRowSelectedFamilyState(recordId), isSelected);
|
||||
}
|
||||
|
||||
set(hasUserSelectedAllRowsCallbackState, true);
|
||||
},
|
||||
[
|
||||
allRowsSelectedStatusSelector,
|
||||
recordIndexAllRecordIdsSelector,
|
||||
resetTableRowSelection,
|
||||
isRowSelectedFamilyState,
|
||||
hasUserSelectedAllRowsCallbackState,
|
||||
],
|
||||
);
|
||||
|
||||
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
|
||||
import { isRowSelectedComponentFamilyState } from '@/object-record/record-table/record-table-row/states/isRowSelectedComponentFamilyState';
|
||||
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
|
||||
|
||||
export const useSetRowSelectedState = (recordTableId?: string) => {
|
||||
const isRowSelectedFamilyState = useRecoilComponentCallbackState(
|
||||
isRowSelectedComponentFamilyState,
|
||||
recordTableId,
|
||||
);
|
||||
|
||||
return useRecoilCallback(
|
||||
({ set }) =>
|
||||
(rowId: string, selected: boolean) => {
|
||||
set(isRowSelectedFamilyState(rowId), selected);
|
||||
},
|
||||
[isRowSelectedFamilyState],
|
||||
);
|
||||
};
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
import { type FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
||||
import { useSaveColumnsToView } from '@/object-record/record-table/hooks/useSaveColumnsToView';
|
||||
import { useSetTableColumns } from '@/object-record/record-table/hooks/useSetTableColumns';
|
||||
import { type ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
|
||||
|
||||
// TODO: see how we can better abstract this and set the correct interaction between view and table
|
||||
// but for now it allows to have a cleaner API globally.
|
||||
export const useHandleColumnsChange = () => {
|
||||
const { saveColumnsToView } = useSaveColumnsToView();
|
||||
const { setTableColumns } = useSetTableColumns();
|
||||
|
||||
const handleColumnsChange = async ({
|
||||
columns,
|
||||
recordTableId,
|
||||
objectMetadataId,
|
||||
}: {
|
||||
columns: ColumnDefinition<FieldMetadata>[];
|
||||
recordTableId: string;
|
||||
objectMetadataId: string;
|
||||
}) => {
|
||||
setTableColumns(columns, recordTableId, objectMetadataId);
|
||||
|
||||
await saveColumnsToView(columns);
|
||||
};
|
||||
|
||||
return {
|
||||
handleColumnsChange,
|
||||
};
|
||||
};
|
||||
@@ -1,109 +0,0 @@
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
|
||||
import { type FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
||||
import { useSetHasUserSelectedAllRows } from '@/object-record/record-table/hooks/internal/useSetAllRowSelectedState';
|
||||
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
|
||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||
|
||||
import { type ColumnDefinition } from '../types/ColumnDefinition';
|
||||
|
||||
import { availableTableColumnsComponentState } from '@/object-record/record-table/states/availableTableColumnsComponentState';
|
||||
import { RecordTableComponentInstanceContext } from '@/object-record/record-table/states/context/RecordTableComponentInstanceContext';
|
||||
import { isRecordTableInitialLoadingComponentState } from '@/object-record/record-table/states/isRecordTableInitialLoadingComponentState';
|
||||
import { onColumnsChangeComponentState } from '@/object-record/record-table/states/onColumnsChangeComponentState';
|
||||
|
||||
import { onToggleColumnSortComponentState } from '@/object-record/record-table/states/onToggleColumnSortComponentState';
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
|
||||
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
|
||||
import { useLeaveTableFocus } from './internal/useLeaveTableFocus';
|
||||
import { useResetTableRowSelection } from './internal/useResetTableRowSelection';
|
||||
import { useSelectAllRows } from './internal/useSelectAllRows';
|
||||
import { useSetRowSelectedState } from './internal/useSetRowSelectedState';
|
||||
type useRecordTableProps = {
|
||||
recordTableId?: string;
|
||||
};
|
||||
|
||||
export const useRecordTable = (props?: useRecordTableProps) => {
|
||||
const recordTableId = useAvailableComponentInstanceIdOrThrow(
|
||||
RecordTableComponentInstanceContext,
|
||||
props?.recordTableId,
|
||||
);
|
||||
|
||||
const availableTableColumnsState = useRecoilComponentCallbackState(
|
||||
availableTableColumnsComponentState,
|
||||
recordTableId,
|
||||
);
|
||||
|
||||
const setAvailableTableColumns = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
(columns: ColumnDefinition<FieldMetadata>[]) => {
|
||||
const availableTableColumns = getSnapshotValue(
|
||||
snapshot,
|
||||
availableTableColumnsState,
|
||||
);
|
||||
|
||||
if (isDeeplyEqual(availableTableColumns, columns)) {
|
||||
return;
|
||||
}
|
||||
set(availableTableColumnsState, columns);
|
||||
},
|
||||
[availableTableColumnsState],
|
||||
);
|
||||
|
||||
const setOnColumnsChange = useSetRecoilComponentState(
|
||||
onColumnsChangeComponentState,
|
||||
recordTableId,
|
||||
);
|
||||
|
||||
const setOnToggleColumnSort = useSetRecoilComponentState(
|
||||
onToggleColumnSortComponentState,
|
||||
recordTableId,
|
||||
);
|
||||
|
||||
const setIsRecordTableInitialLoading = useSetRecoilComponentState(
|
||||
isRecordTableInitialLoadingComponentState,
|
||||
recordTableId,
|
||||
);
|
||||
|
||||
const onColumnsChangeState = useRecoilComponentCallbackState(
|
||||
onColumnsChangeComponentState,
|
||||
recordTableId,
|
||||
);
|
||||
|
||||
const onColumnsChange = useRecoilCallback(
|
||||
({ snapshot }) =>
|
||||
(columns: ColumnDefinition<FieldMetadata>[]) => {
|
||||
const onColumnsChange = getSnapshotValue(
|
||||
snapshot,
|
||||
onColumnsChangeState,
|
||||
);
|
||||
|
||||
onColumnsChange?.(columns);
|
||||
},
|
||||
[onColumnsChangeState],
|
||||
);
|
||||
|
||||
const leaveTableFocus = useLeaveTableFocus(recordTableId);
|
||||
|
||||
const setRowSelected = useSetRowSelectedState(recordTableId);
|
||||
|
||||
const setHasUserSelectedAllRows = useSetHasUserSelectedAllRows(recordTableId);
|
||||
|
||||
const resetTableRowSelection = useResetTableRowSelection(recordTableId);
|
||||
|
||||
const { selectAllRows } = useSelectAllRows(recordTableId);
|
||||
|
||||
return {
|
||||
onColumnsChange,
|
||||
setAvailableTableColumns,
|
||||
leaveTableFocus,
|
||||
setRowSelected,
|
||||
resetTableRowSelection,
|
||||
selectAllRows,
|
||||
setOnColumnsChange,
|
||||
setIsRecordTableInitialLoading,
|
||||
setHasUserSelectedAllRows,
|
||||
setOnToggleColumnSort,
|
||||
};
|
||||
};
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
import { type FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
||||
import { type ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
|
||||
import { useSaveCurrentViewFields } from '@/views/hooks/useSaveCurrentViewFields';
|
||||
import { mapColumnDefinitionsToViewFields } from '@/views/utils/mapColumnDefinitionToViewField';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
|
||||
export const useSaveColumnsToView = () => {
|
||||
const { saveViewFields } = useSaveCurrentViewFields();
|
||||
|
||||
const saveColumnsToView = useRecoilCallback(
|
||||
() => async (columns) => {
|
||||
await saveViewFields(
|
||||
mapColumnDefinitionsToViewFields(
|
||||
columns as ColumnDefinition<FieldMetadata>[],
|
||||
),
|
||||
);
|
||||
},
|
||||
[saveViewFields],
|
||||
);
|
||||
|
||||
return { saveColumnsToView };
|
||||
};
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
import { type FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
||||
import { availableTableColumnsComponentState } from '@/object-record/record-table/states/availableTableColumnsComponentState';
|
||||
import { RecordTableComponentInstanceContext } from '@/object-record/record-table/states/context/RecordTableComponentInstanceContext';
|
||||
import { type ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
|
||||
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||
|
||||
export const useSetAvailableTableColumns = (
|
||||
recordTableIdFromProps?: string,
|
||||
) => {
|
||||
const recordTableId = useAvailableComponentInstanceIdOrThrow(
|
||||
RecordTableComponentInstanceContext,
|
||||
recordTableIdFromProps,
|
||||
);
|
||||
|
||||
const availableTableColumnsState = useRecoilComponentCallbackState(
|
||||
availableTableColumnsComponentState,
|
||||
recordTableId,
|
||||
);
|
||||
|
||||
const setAvailableTableColumns = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
(columns: ColumnDefinition<FieldMetadata>[]) => {
|
||||
const availableTableColumns = getSnapshotValue(
|
||||
snapshot,
|
||||
availableTableColumnsState,
|
||||
);
|
||||
|
||||
if (isDeeplyEqual(availableTableColumns, columns)) {
|
||||
return;
|
||||
}
|
||||
set(availableTableColumnsState, columns);
|
||||
},
|
||||
[availableTableColumnsState],
|
||||
);
|
||||
|
||||
return {
|
||||
setAvailableTableColumns,
|
||||
};
|
||||
};
|
||||
+36
-36
@@ -1,64 +1,44 @@
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { type FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
||||
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
|
||||
import { useUnfocusRecordTableCell } from '@/object-record/record-table/record-table-cell/hooks/useUnfocusRecordTableCell';
|
||||
import { useMoveViewColumns } from '@/views/hooks/useMoveViewColumns';
|
||||
|
||||
import { useSetTableColumns } from '@/object-record/record-table/hooks/useSetTableColumns';
|
||||
import { useHandleColumnsChange } from '@/object-record/record-table/hooks/useHandleColumnsChange';
|
||||
import { availableTableColumnsComponentState } from '@/object-record/record-table/states/availableTableColumnsComponentState';
|
||||
import { RecordTableComponentInstanceContext } from '@/object-record/record-table/states/context/RecordTableComponentInstanceContext';
|
||||
import { visibleTableColumnsComponentSelector } from '@/object-record/record-table/states/selectors/visibleTableColumnsComponentSelector';
|
||||
import { tableColumnsComponentState } from '@/object-record/record-table/states/tableColumnsComponentState';
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { type ColumnDefinition } from '../types/ColumnDefinition';
|
||||
|
||||
type useRecordTableProps = {
|
||||
recordTableId?: string;
|
||||
recordTableId: string;
|
||||
objectMetadataId: string;
|
||||
};
|
||||
|
||||
export const useTableColumns = (props: useRecordTableProps) => {
|
||||
const { onColumnsChange } = useRecordTable({
|
||||
recordTableId: props?.recordTableId,
|
||||
});
|
||||
|
||||
const { setTableColumns } = useSetTableColumns();
|
||||
|
||||
export const useTableColumns = ({
|
||||
objectMetadataId,
|
||||
recordTableId,
|
||||
}: useRecordTableProps) => {
|
||||
const availableTableColumns = useRecoilComponentValue(
|
||||
availableTableColumnsComponentState,
|
||||
props?.recordTableId,
|
||||
recordTableId,
|
||||
);
|
||||
|
||||
const tableColumns = useRecoilComponentValue(
|
||||
tableColumnsComponentState,
|
||||
props?.recordTableId,
|
||||
recordTableId,
|
||||
);
|
||||
const visibleTableColumns = useRecoilComponentValue(
|
||||
visibleTableColumnsComponentSelector,
|
||||
props?.recordTableId,
|
||||
recordTableId,
|
||||
);
|
||||
|
||||
const { handleColumnMove } = useMoveViewColumns();
|
||||
|
||||
const { unfocusRecordTableCell } = useUnfocusRecordTableCell(
|
||||
props?.recordTableId,
|
||||
);
|
||||
const { unfocusRecordTableCell } = useUnfocusRecordTableCell(recordTableId);
|
||||
|
||||
const instanceId = useAvailableComponentInstanceIdOrThrow(
|
||||
RecordTableComponentInstanceContext,
|
||||
props?.recordTableId,
|
||||
);
|
||||
|
||||
const handleColumnsChange = useCallback(
|
||||
async (columns: ColumnDefinition<FieldMetadata>[]) => {
|
||||
setTableColumns(columns, instanceId, props.objectMetadataId);
|
||||
|
||||
await onColumnsChange?.(columns);
|
||||
},
|
||||
[setTableColumns, instanceId, onColumnsChange, props.objectMetadataId],
|
||||
);
|
||||
const { handleColumnsChange } = useHandleColumnsChange();
|
||||
|
||||
const handleColumnVisibilityChange = useCallback(
|
||||
async (
|
||||
@@ -88,7 +68,11 @@ export const useTableColumns = (props: useRecordTableProps) => {
|
||||
{ ...newColumn, isVisible: true, position: lastPosition + 1 },
|
||||
];
|
||||
|
||||
await handleColumnsChange(nextColumns);
|
||||
await handleColumnsChange({
|
||||
columns: nextColumns,
|
||||
objectMetadataId,
|
||||
recordTableId,
|
||||
});
|
||||
} else {
|
||||
const nextColumns = visibleTableColumns.map((previousColumn) =>
|
||||
previousColumn.fieldMetadataId === viewField.fieldMetadataId
|
||||
@@ -96,7 +80,11 @@ export const useTableColumns = (props: useRecordTableProps) => {
|
||||
: previousColumn,
|
||||
);
|
||||
|
||||
await handleColumnsChange(nextColumns);
|
||||
await handleColumnsChange({
|
||||
columns: nextColumns,
|
||||
objectMetadataId,
|
||||
recordTableId,
|
||||
});
|
||||
}
|
||||
},
|
||||
[
|
||||
@@ -104,6 +92,8 @@ export const useTableColumns = (props: useRecordTableProps) => {
|
||||
availableTableColumns,
|
||||
handleColumnsChange,
|
||||
visibleTableColumns,
|
||||
objectMetadataId,
|
||||
recordTableId,
|
||||
],
|
||||
);
|
||||
|
||||
@@ -125,13 +115,19 @@ export const useTableColumns = (props: useRecordTableProps) => {
|
||||
visibleTableColumns,
|
||||
);
|
||||
|
||||
await handleColumnsChange(columns);
|
||||
await handleColumnsChange({
|
||||
columns,
|
||||
objectMetadataId,
|
||||
recordTableId,
|
||||
});
|
||||
},
|
||||
[
|
||||
unfocusRecordTableCell,
|
||||
visibleTableColumns,
|
||||
handleColumnMove,
|
||||
handleColumnsChange,
|
||||
objectMetadataId,
|
||||
recordTableId,
|
||||
],
|
||||
);
|
||||
|
||||
@@ -142,9 +138,13 @@ export const useTableColumns = (props: useRecordTableProps) => {
|
||||
position: index,
|
||||
}));
|
||||
|
||||
await handleColumnsChange(updatedColumns);
|
||||
await handleColumnsChange({
|
||||
columns: updatedColumns,
|
||||
objectMetadataId,
|
||||
recordTableId,
|
||||
});
|
||||
},
|
||||
[handleColumnsChange],
|
||||
[handleColumnsChange, objectMetadataId, recordTableId],
|
||||
);
|
||||
|
||||
return {
|
||||
|
||||
+2
-7
@@ -1,18 +1,13 @@
|
||||
import { Key } from 'ts-key-enum';
|
||||
|
||||
import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext';
|
||||
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
|
||||
import { useResetTableRowSelection } from '@/object-record/record-table/hooks/internal/useResetTableRowSelection';
|
||||
import { isAtLeastOneTableRowSelectedSelector } from '@/object-record/record-table/record-table-row/states/isAtLeastOneTableRowSelectedSelector';
|
||||
import { PageFocusId } from '@/types/PageFocusId';
|
||||
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
|
||||
export const RecordTableBodyEscapeHotkeyEffect = () => {
|
||||
const { recordTableId } = useRecordTableContextOrThrow();
|
||||
|
||||
const { resetTableRowSelection } = useRecordTable({
|
||||
recordTableId,
|
||||
});
|
||||
const { resetTableRowSelection } = useResetTableRowSelection();
|
||||
|
||||
const isAtLeastOneRecordSelected = useRecoilComponentValue(
|
||||
isAtLeastOneTableRowSelectedSelector,
|
||||
|
||||
+3
-9
@@ -7,9 +7,8 @@ import { useIsFieldClearable } from '@/object-record/record-field/hooks/useIsFie
|
||||
import { useIsFieldInputOnly } from '@/object-record/record-field/hooks/useIsFieldInputOnly';
|
||||
import { useToggleEditOnlyInput } from '@/object-record/record-field/hooks/useToggleEditOnlyInput';
|
||||
import { useRecordTableBodyContextOrThrow } from '@/object-record/record-table/contexts/RecordTableBodyContext';
|
||||
import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext';
|
||||
import { useSelectAllRows } from '@/object-record/record-table/hooks/internal/useSelectAllRows';
|
||||
import { useFocusedRecordTableRow } from '@/object-record/record-table/hooks/useFocusedRecordTableRow';
|
||||
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
|
||||
import { useCurrentlyFocusedRecordTableCellFocusId } from '@/object-record/record-table/record-table-cell/hooks/useCurrentlyFocusedRecordTableCellFocusId';
|
||||
import { useOpenRecordTableCellFromCell } from '@/object-record/record-table/record-table-cell/hooks/useOpenRecordTableCellFromCell';
|
||||
import { useListenToSidePanelOpening } from '@/ui/layout/right-drawer/hooks/useListenToSidePanelOpening';
|
||||
@@ -68,10 +67,8 @@ export const RecordTableCellHotkeysEffect = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const { recordTableId } = useRecordTableContextOrThrow();
|
||||
|
||||
const { restoreRecordTableRowFocusFromCellPosition } =
|
||||
useFocusedRecordTableRow(recordTableId);
|
||||
useFocusedRecordTableRow();
|
||||
|
||||
const handleEscape = () => {
|
||||
restoreRecordTableRowFocusFromCellPosition();
|
||||
@@ -110,12 +107,9 @@ export const RecordTableCellHotkeysEffect = () => {
|
||||
},
|
||||
});
|
||||
|
||||
const { selectAllRows, setHasUserSelectedAllRows } = useRecordTable({
|
||||
recordTableId,
|
||||
});
|
||||
const { selectAllRows } = useSelectAllRows();
|
||||
|
||||
const handleSelectAllRows = () => {
|
||||
setHasUserSelectedAllRows(true);
|
||||
selectAllRows();
|
||||
};
|
||||
|
||||
|
||||
+1
-4
@@ -16,10 +16,7 @@ import { recordTableHoverPositionComponentState } from '@/object-record/record-t
|
||||
|
||||
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||
<RecoilRoot>
|
||||
<RecordTableComponentInstance
|
||||
recordTableId="test-record-table-instance-id"
|
||||
onColumnsChange={jest.fn()}
|
||||
>
|
||||
<RecordTableComponentInstance recordTableId="test-record-table-instance-id">
|
||||
<RecordTableRowContextProvider value={recordTableRowContextValue}>
|
||||
<RecordTableRowDraggableContextProvider
|
||||
value={recordTableRowDraggableContextValue}
|
||||
|
||||
+1
-4
@@ -35,10 +35,7 @@ const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||
);
|
||||
}}
|
||||
>
|
||||
<RecordTableComponentInstance
|
||||
recordTableId="test-table-id"
|
||||
onColumnsChange={jest.fn()}
|
||||
>
|
||||
<RecordTableComponentInstance recordTableId="test-table-id">
|
||||
{children}
|
||||
</RecordTableComponentInstance>
|
||||
</RecoilRoot>
|
||||
|
||||
+1
-5
@@ -21,7 +21,6 @@ import { useDragSelect } from '@/ui/utilities/drag-select/hooks/useDragSelect';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { generatedMockObjectMetadataItems } from '~/testing/utils/generatedMockObjectMetadataItems';
|
||||
|
||||
const onColumnsChange = jest.fn();
|
||||
const recordTableId = 'record-table-id';
|
||||
|
||||
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||
@@ -30,10 +29,7 @@ const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||
snapshot.set(objectMetadataItemsState, generatedMockObjectMetadataItems);
|
||||
}}
|
||||
>
|
||||
<RecordTableComponentInstance
|
||||
recordTableId={recordTableId}
|
||||
onColumnsChange={onColumnsChange}
|
||||
>
|
||||
<RecordTableComponentInstance recordTableId={recordTableId}>
|
||||
<RecordTableContextProvider
|
||||
recordTableId={recordTableId}
|
||||
viewBarId="viewBarId"
|
||||
|
||||
+1
-5
@@ -21,7 +21,6 @@ import { useDragSelect } from '@/ui/utilities/drag-select/hooks/useDragSelect';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { generatedMockObjectMetadataItems } from '~/testing/utils/generatedMockObjectMetadataItems';
|
||||
|
||||
const onColumnsChange = jest.fn();
|
||||
const recordTableId = 'record-table-id';
|
||||
|
||||
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||
@@ -30,10 +29,7 @@ const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||
snapshot.set(objectMetadataItemsState, generatedMockObjectMetadataItems);
|
||||
}}
|
||||
>
|
||||
<RecordTableComponentInstance
|
||||
recordTableId={recordTableId}
|
||||
onColumnsChange={onColumnsChange}
|
||||
>
|
||||
<RecordTableComponentInstance recordTableId={recordTableId}>
|
||||
<RecordTableContextProvider
|
||||
recordTableId={recordTableId}
|
||||
viewBarId="viewBarId"
|
||||
|
||||
+9
-6
@@ -2,8 +2,9 @@ import { type FieldMetadata } from '@/object-record/record-field/types/FieldMeta
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
||||
|
||||
import { useHandleToggleColumnSort } from '@/object-record/record-index/hooks/useHandleToggleColumnSort';
|
||||
import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext';
|
||||
import { useOpenRecordFilterChipFromTableHeader } from '@/object-record/record-table/record-table-header/hooks/useOpenRecordFilterChipFromTableHeader';
|
||||
import { onToggleColumnSortComponentState } from '@/object-record/record-table/states/onToggleColumnSortComponentState';
|
||||
import { visibleTableColumnsComponentSelector } from '@/object-record/record-table/states/selectors/visibleTableColumnsComponentSelector';
|
||||
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
||||
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||
@@ -53,8 +54,10 @@ export const RecordTableColumnHeadDropdownMenu = ({
|
||||
const canMoveRight =
|
||||
column.fieldMetadataId !== lastVisibleColumn?.fieldMetadataId && canMove;
|
||||
|
||||
const { recordTableId } = useRecordTableContextOrThrow();
|
||||
|
||||
const { handleColumnVisibilityChange, handleMoveTableColumn } =
|
||||
useTableColumns({ objectMetadataId });
|
||||
useTableColumns({ objectMetadataId, recordTableId });
|
||||
|
||||
const dropdownId = column.fieldMetadataId + '-header';
|
||||
|
||||
@@ -86,14 +89,14 @@ export const RecordTableColumnHeadDropdownMenu = ({
|
||||
handleColumnVisibilityChange(column);
|
||||
};
|
||||
|
||||
const onToggleColumnSort = useRecoilComponentValue(
|
||||
onToggleColumnSortComponentState,
|
||||
);
|
||||
const handleToggleColumnSort = useHandleToggleColumnSort({
|
||||
objectMetadataItemId: objectMetadataId,
|
||||
});
|
||||
|
||||
const handleSortClick = () => {
|
||||
closeDropdownAndToggleScroll();
|
||||
|
||||
onToggleColumnSort?.(column.fieldMetadataId);
|
||||
handleToggleColumnSort(column.fieldMetadataId);
|
||||
};
|
||||
|
||||
const { openRecordFilterChipFromTableHeader } =
|
||||
|
||||
+9
-2
@@ -114,7 +114,7 @@ type RecordTableHeaderCellProps = {
|
||||
export const RecordTableHeaderCell = ({
|
||||
column,
|
||||
}: RecordTableHeaderCellProps) => {
|
||||
const { objectMetadataItem, objectPermissions } =
|
||||
const { objectMetadataItem, objectPermissions, recordTableId } =
|
||||
useRecordTableContextOrThrow();
|
||||
|
||||
const resizeFieldOffsetState = useRecoilComponentCallbackState(
|
||||
@@ -139,6 +139,7 @@ export const RecordTableHeaderCell = ({
|
||||
|
||||
const { handleColumnsChange } = useTableColumns({
|
||||
objectMetadataId: objectMetadataItem.id,
|
||||
recordTableId,
|
||||
});
|
||||
|
||||
const handleResizeHandlerStart = useCallback<PointerEventListener>(
|
||||
@@ -186,7 +187,11 @@ export const RecordTableHeaderCell = ({
|
||||
: column,
|
||||
);
|
||||
|
||||
await handleColumnsChange(nextColumns);
|
||||
await handleColumnsChange({
|
||||
columns: nextColumns,
|
||||
objectMetadataId: objectMetadataItem.id,
|
||||
recordTableId,
|
||||
});
|
||||
}
|
||||
},
|
||||
[
|
||||
@@ -196,6 +201,8 @@ export const RecordTableHeaderCell = ({
|
||||
setResizedFieldKey,
|
||||
tableColumns,
|
||||
handleColumnsChange,
|
||||
objectMetadataItem,
|
||||
recordTableId,
|
||||
],
|
||||
);
|
||||
|
||||
|
||||
+7
-5
@@ -2,7 +2,8 @@ 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 { useResetTableRowSelection } from '@/object-record/record-table/hooks/internal/useResetTableRowSelection';
|
||||
import { useSelectAllRows } from '@/object-record/record-table/hooks/internal/useSelectAllRows';
|
||||
import { isRecordTableInitialLoadingComponentState } from '@/object-record/record-table/states/isRecordTableInitialLoadingComponentState';
|
||||
import { isRecordTableRowActiveComponentFamilyState } from '@/object-record/record-table/states/isRecordTableRowActiveComponentFamilyState';
|
||||
import { isRecordTableRowFocusedComponentFamilyState } from '@/object-record/record-table/states/isRecordTableRowFocusedComponentFamilyState';
|
||||
@@ -37,8 +38,11 @@ export const RecordTableHeaderCheckboxColumn = () => {
|
||||
const allRowsSelectedStatus = useRecoilComponentValue(
|
||||
allRowsSelectedStatusComponentSelector,
|
||||
);
|
||||
const { selectAllRows, resetTableRowSelection, setHasUserSelectedAllRows } =
|
||||
useRecordTable();
|
||||
|
||||
const { selectAllRows } = useSelectAllRows();
|
||||
|
||||
const { resetTableRowSelection } = useResetTableRowSelection();
|
||||
|
||||
const checked =
|
||||
allRowsSelectedStatus === 'all' || allRowsSelectedStatus === 'some';
|
||||
const indeterminate = allRowsSelectedStatus === 'some';
|
||||
@@ -60,10 +64,8 @@ export const RecordTableHeaderCheckboxColumn = () => {
|
||||
|
||||
const onChange = () => {
|
||||
if (checked) {
|
||||
setHasUserSelectedAllRows(false);
|
||||
resetTableRowSelection();
|
||||
} else {
|
||||
setHasUserSelectedAllRows(true);
|
||||
selectAllRows();
|
||||
}
|
||||
};
|
||||
|
||||
+2
-1
@@ -21,7 +21,7 @@ import { getSettingsPath } from '~/utils/navigation/getSettingsPath';
|
||||
|
||||
export const RecordTableHeaderPlusButtonContent = () => {
|
||||
const { t } = useLingui();
|
||||
const { objectMetadataItem } = useRecordTableContextOrThrow();
|
||||
const { objectMetadataItem, recordTableId } = useRecordTableContextOrThrow();
|
||||
|
||||
const { closeDropdown } = useCloseDropdown();
|
||||
|
||||
@@ -32,6 +32,7 @@ export const RecordTableHeaderPlusButtonContent = () => {
|
||||
const { getIcon } = useIcons();
|
||||
const { handleColumnVisibilityChange } = useTableColumns({
|
||||
objectMetadataId: objectMetadataItem.id,
|
||||
recordTableId,
|
||||
});
|
||||
|
||||
const handleAddColumn = useCallback(
|
||||
|
||||
+4
-8
@@ -1,9 +1,10 @@
|
||||
import { useOpenRecordInCommandMenu } from '@/command-menu/hooks/useOpenRecordInCommandMenu';
|
||||
import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext';
|
||||
import { useRecordTableRowContextOrThrow } from '@/object-record/record-table/contexts/RecordTableRowContext';
|
||||
import { useResetTableRowSelection } from '@/object-record/record-table/hooks/internal/useResetTableRowSelection';
|
||||
import { useSelectAllRows } from '@/object-record/record-table/hooks/internal/useSelectAllRows';
|
||||
import { useActiveRecordTableRow } from '@/object-record/record-table/hooks/useActiveRecordTableRow';
|
||||
import { useFocusedRecordTableRow } from '@/object-record/record-table/hooks/useFocusedRecordTableRow';
|
||||
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
|
||||
import { useFocusRecordTableCell } from '@/object-record/record-table/record-table-cell/hooks/useFocusRecordTableCell';
|
||||
import { getRecordTableCellFocusId } from '@/object-record/record-table/record-table-cell/utils/getRecordTableCellFocusId';
|
||||
import { useSetCurrentRowSelected } from '@/object-record/record-table/record-table-row/hooks/useSetCurrentRowSelected';
|
||||
@@ -81,9 +82,7 @@ export const useRecordTableRowHotkeys = (focusId: string) => {
|
||||
});
|
||||
};
|
||||
|
||||
const { resetTableRowSelection } = useRecordTable({
|
||||
recordTableId,
|
||||
});
|
||||
const { resetTableRowSelection } = useResetTableRowSelection(recordTableId);
|
||||
|
||||
const { unfocusRecordTableRow } = useFocusedRecordTableRow(recordTableId);
|
||||
|
||||
@@ -133,12 +132,9 @@ export const useRecordTableRowHotkeys = (focusId: string) => {
|
||||
dependencies: [handleEscape],
|
||||
});
|
||||
|
||||
const { selectAllRows, setHasUserSelectedAllRows } = useRecordTable({
|
||||
recordTableId,
|
||||
});
|
||||
const { selectAllRows } = useSelectAllRows();
|
||||
|
||||
const handleSelectAllRows = () => {
|
||||
setHasUserSelectedAllRows(true);
|
||||
selectAllRows();
|
||||
};
|
||||
|
||||
|
||||
+1
-9
@@ -1,12 +1,4 @@
|
||||
import { type FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
||||
|
||||
import { type ComponentStateKey } from '@/ui/utilities/state/component-state/types/ComponentStateKey';
|
||||
import { createComponentInstanceContext } from '@/ui/utilities/state/component-state/utils/createComponentInstanceContext';
|
||||
import { type ColumnDefinition } from '../../types/ColumnDefinition';
|
||||
|
||||
type RecordTableComponentInstanceContextProps = ComponentStateKey & {
|
||||
onColumnsChange: (columns: ColumnDefinition<FieldMetadata>[]) => void;
|
||||
};
|
||||
|
||||
export const RecordTableComponentInstanceContext =
|
||||
createComponentInstanceContext<RecordTableComponentInstanceContextProps>();
|
||||
createComponentInstanceContext();
|
||||
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
import { type FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
||||
import { RecordTableComponentInstanceContext } from '@/object-record/record-table/states/context/RecordTableComponentInstanceContext';
|
||||
import { type ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
|
||||
export const onColumnsChangeComponentState = createComponentState<
|
||||
((columns: ColumnDefinition<FieldMetadata>[]) => void) | undefined
|
||||
>({
|
||||
key: 'onColumnsChangeComponentState',
|
||||
defaultValue: undefined,
|
||||
componentInstanceContext: RecordTableComponentInstanceContext,
|
||||
});
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
import { RecordTableComponentInstanceContext } from '@/object-record/record-table/states/context/RecordTableComponentInstanceContext';
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
|
||||
export const onToggleColumnSortComponentState = createComponentState<
|
||||
((fieldMetadataId: string) => void) | undefined
|
||||
>({
|
||||
key: 'onToggleColumnSortComponentState',
|
||||
defaultValue: undefined,
|
||||
componentInstanceContext: RecordTableComponentInstanceContext,
|
||||
});
|
||||
+3
-4
@@ -4,7 +4,7 @@ import { MAIN_CONTEXT_STORE_INSTANCE_ID } from '@/context-store/constants/MainCo
|
||||
import { contextStoreCurrentObjectMetadataItemIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataItemIdComponentState';
|
||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||
import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObjectNameSingularFromPlural';
|
||||
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
|
||||
import { useSetAvailableTableColumns } from '@/object-record/record-table/hooks/useSetAvailableTableColumns';
|
||||
import { useSetTableColumns } from '@/object-record/record-table/hooks/useSetTableColumns';
|
||||
import { SIGN_IN_BACKGROUND_MOCK_COLUMN_DEFINITIONS } from '@/sign-in-background-mock/constants/SignInBackgroundMockColumnDefinitions';
|
||||
import { SIGN_IN_BACKGROUND_MOCK_VIEW_FIELDS } from '@/sign-in-background-mock/constants/SignInBackgroundMockViewFields';
|
||||
@@ -31,9 +31,8 @@ export const SignInBackgroundMockContainerEffect = ({
|
||||
MAIN_CONTEXT_STORE_INSTANCE_ID,
|
||||
);
|
||||
|
||||
const { setAvailableTableColumns } = useRecordTable({
|
||||
recordTableId,
|
||||
});
|
||||
const { setAvailableTableColumns } =
|
||||
useSetAvailableTableColumns(recordTableId);
|
||||
|
||||
const { setTableColumns } = useSetTableColumns();
|
||||
|
||||
|
||||
-1
@@ -121,7 +121,6 @@ const meta: Meta<typeof ViewBarFilterDropdown> = {
|
||||
<RecordTableComponentInstanceContext.Provider
|
||||
value={{
|
||||
instanceId: instanceId,
|
||||
onColumnsChange: () => {},
|
||||
}}
|
||||
>
|
||||
<ViewComponentInstanceContext.Provider
|
||||
|
||||
@@ -140,7 +140,7 @@ export const RecordTableDecorator: Decorator = (Story, context) => {
|
||||
|
||||
return (
|
||||
<RecordTableComponentInstanceContext.Provider
|
||||
value={{ instanceId: recordIndexId, onColumnsChange: () => {} }}
|
||||
value={{ instanceId: recordIndexId }}
|
||||
>
|
||||
<ViewComponentInstanceContext.Provider
|
||||
value={{ instanceId: recordIndexId }}
|
||||
|
||||
Reference in New Issue
Block a user