Refactor Views by cleaning the code, relying on apolloCache and improving performances (#4516)

* Wip refactoring view

* Post merge conflicts

* Fix review

* Add create view capability

* Fix create object missing view

* Fix tests
This commit is contained in:
Charles Bochet
2024-03-20 14:21:58 +01:00
committed by GitHub
parent 20e14cb455
commit cfb0cce9b8
392 changed files with 3474 additions and 4410 deletions

View File

@ -15,7 +15,7 @@ export const useAddRecordInCache = ({
}: {
objectMetadataItem: ObjectMetadataItem;
}) => {
const objectMetadataItems = useRecoilValue(objectMetadataItemsState());
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
const apolloClient = useApolloClient();
const { injectIntoFindOneRecordQueryCache } =

View File

@ -1,3 +1,4 @@
import { useCallback } from 'react';
import { gql, useApolloClient } from '@apollo/client';
import { useRecoilValue } from 'recoil';
@ -13,21 +14,22 @@ export const useGetRecordFromCache = ({
}: {
objectMetadataItem: ObjectMetadataItem;
}) => {
const objectMetadataItems = useRecoilValue(objectMetadataItemsState());
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
const apolloClient = useApolloClient();
return <CachedObjectRecord extends ObjectRecord = ObjectRecord>(
recordId: string,
cache = apolloClient.cache,
) => {
if (isUndefinedOrNull(objectMetadataItem)) {
return null;
}
return useCallback(
<CachedObjectRecord extends ObjectRecord = ObjectRecord>(
recordId: string,
cache = apolloClient.cache,
) => {
if (isUndefinedOrNull(objectMetadataItem)) {
return null;
}
const capitalizedObjectName = capitalize(objectMetadataItem.nameSingular);
const capitalizedObjectName = capitalize(objectMetadataItem.nameSingular);
const cacheReadFragment = gql`
const cacheReadFragment = gql`
fragment ${capitalizedObjectName}Fragment on ${capitalizedObjectName} ${mapObjectMetadataToGraphQLQuery(
{
objectMetadataItems,
@ -36,14 +38,16 @@ export const useGetRecordFromCache = ({
)}
`;
const cachedRecordId = cache.identify({
__typename: capitalize(objectMetadataItem.nameSingular),
id: recordId,
});
const cachedRecordId = cache.identify({
__typename: capitalize(objectMetadataItem.nameSingular),
id: recordId,
});
return cache.readFragment<CachedObjectRecord & { __typename: string }>({
id: cachedRecordId,
fragment: cacheReadFragment,
});
};
return cache.readFragment<CachedObjectRecord & { __typename: string }>({
id: cachedRecordId,
fragment: cacheReadFragment,
});
},
[objectMetadataItem, objectMetadataItems, apolloClient],
);
};

View File

@ -17,7 +17,8 @@ export const getRecordEdgeFromRecord = <T extends ObjectRecord>({
return [
key,
getRecordConnectionFromRecords({
objectNameSingular: key,
// Todo: this is a ugly and broken hack to get the singular, we need to infer this from metadata
objectNameSingular: key.slice(0, -1),
records: value as ObjectRecord[],
}),
];

View File

@ -57,7 +57,7 @@ describe('useFindManyRecords', () => {
const { result } = renderHook(
() => {
const setCurrentWorkspaceMember = useSetRecoilState(
currentWorkspaceMemberState(),
currentWorkspaceMemberState,
);
setCurrentWorkspaceMember({
id: '32219445-f587-4c40-b2b1-6d3205ed96da',
@ -67,7 +67,7 @@ describe('useFindManyRecords', () => {
const mockObjectMetadataItems = getObjectMetadataItemsMock();
const setMetadataItems = useSetRecoilState(objectMetadataItemsState());
const setMetadataItems = useSetRecoilState(objectMetadataItemsState);
setMetadataItems(mockObjectMetadataItems);

View File

@ -16,7 +16,7 @@ describe('useGenerateFindManyRecordsForMultipleMetadataItemsQuery', () => {
const mockObjectMetadataItems = getObjectMetadataItemsMock();
return useGenerateFindManyRecordsForMultipleMetadataItemsQuery({
objectMetadataItems: mockObjectMetadataItems.slice(0, 2),
targetObjectMetadataItems: mockObjectMetadataItems.slice(0, 2),
});
},
{

View File

@ -18,7 +18,7 @@ import { isDefined } from '~/utils/isDefined';
const Wrapper = getJestHookWrapper({
apolloMocks: [],
onInitializeRecoilSnapshot: (snapshot) => {
snapshot.set(objectMetadataItemsState(), getObjectMetadataItemsMock());
snapshot.set(objectMetadataItemsState, getObjectMetadataItemsMock());
},
});

View File

@ -69,7 +69,7 @@ export const useFindManyRecords = <T extends ObjectRecord = ObjectRecord>({
);
const { enqueueSnackBar } = useSnackBar();
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState());
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);
const { data, loading, error, fetchMore } = useQuery<
ObjectRecordQueryResult<T>

View File

@ -17,7 +17,7 @@ export const useGenerateCreateManyRecordMutation = ({
}: {
objectMetadataItem: ObjectMetadataItem;
}) => {
const objectMetadataItems = useRecoilValue(objectMetadataItemsState());
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
if (isUndefinedOrNull(objectMetadataItem)) {
return EMPTY_MUTATION;

View File

@ -17,7 +17,7 @@ export const useGenerateCreateOneRecordMutation = ({
}: {
objectMetadataItem: ObjectMetadataItem;
}) => {
const objectMetadataItems = useRecoilValue(objectMetadataItemsState());
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
if (isUndefinedOrNull(objectMetadataItem)) {
return EMPTY_MUTATION;

View File

@ -21,7 +21,7 @@ export const useGenerateExecuteQuickActionOnOneRecordMutation = ({
}: {
objectMetadataItem: ObjectMetadataItem;
}) => {
const objectMetadataItems = useRecoilValue(objectMetadataItemsState());
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
if (isUndefinedOrNull(objectMetadataItem)) {
return EMPTY_MUTATION;

View File

@ -11,7 +11,7 @@ export const getFindDuplicateRecordsQueryResponseField = (
) => `${objectNameSingular}Duplicates`;
export const useGenerateFindDuplicateRecordsQuery = () => {
const objectMetadataItems = useRecoilValue(objectMetadataItemsState());
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
return ({
objectMetadataItem,

View File

@ -8,14 +8,14 @@ import { isNonEmptyArray } from '~/utils/isNonEmptyArray';
import { capitalize } from '~/utils/string/capitalize';
export const useGenerateFindManyRecordsForMultipleMetadataItemsQuery = ({
objectMetadataItems,
targetObjectMetadataItems,
depth,
}: {
objectMetadataItems: ObjectMetadataItem[];
targetObjectMetadataItems: ObjectMetadataItem[];
depth?: number;
}) => {
const allObjectMetadataItems = useRecoilValue(objectMetadataItemsState());
const capitalizedObjectNameSingulars = objectMetadataItems.map(
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
const capitalizedObjectNameSingulars = targetObjectMetadataItems.map(
({ nameSingular }) => capitalize(nameSingular),
);
@ -58,7 +58,7 @@ export const useGenerateFindManyRecordsForMultipleMetadataItemsQuery = ({
${lastCursorPerMetadataItemArray},
${limitPerMetadataItemArray}
) {
${objectMetadataItems
${targetObjectMetadataItems
.map(
(objectMetadataItem) =>
`${objectMetadataItem.namePlural}(filter: $filter${capitalize(
@ -72,7 +72,7 @@ export const useGenerateFindManyRecordsForMultipleMetadataItemsQuery = ({
)}){
edges {
node ${mapObjectMetadataToGraphQLQuery({
objectMetadataItems: allObjectMetadataItems,
objectMetadataItems: objectMetadataItems,
objectMetadataItem,
depth,
})}

View File

@ -7,7 +7,7 @@ import { mapObjectMetadataToGraphQLQuery } from '@/object-metadata/utils/mapObje
import { capitalize } from '~/utils/string/capitalize';
export const useGenerateFindManyRecordsQuery = () => {
const objectMetadataItems = useRecoilValue(objectMetadataItemsState());
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
return ({
objectMetadataItem,

View File

@ -7,7 +7,7 @@ import { mapObjectMetadataToGraphQLQuery } from '@/object-metadata/utils/mapObje
import { capitalize } from '~/utils/string/capitalize';
export const useGenerateFindOneRecordQuery = () => {
const objectMetadataItems = useRecoilValue(objectMetadataItemsState());
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
return ({
objectMetadataItem,

View File

@ -17,7 +17,7 @@ export const useGenerateUpdateOneRecordMutation = ({
}: {
objectMetadataItem: ObjectMetadataItem;
}) => {
const objectMetadataItems = useRecoilValue(objectMetadataItemsState());
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
if (isUndefinedOrNull(objectMetadataItem)) {
return EMPTY_MUTATION;

View File

@ -11,7 +11,7 @@ import { FieldMetadataType } from '~/generated/graphql';
import { isDefined } from '~/utils/isDefined';
export const useMapConnectionToRecords = () => {
const objectMetadataItems = useRecoilValue(objectMetadataItemsState());
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
const mapConnectionToRecords = useCallback(
<T extends ObjectRecord>({

View File

@ -1,3 +1,5 @@
import { useRecoilValue } from 'recoil';
import { ObjectFilterDropdownSearchInput } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownSearchInput';
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
@ -20,11 +22,21 @@ export const MultipleFiltersDropdownContent = ({
filterDropdownId,
}: MultipleFiltersDropdownContentProps) => {
const {
isObjectFilterDropdownOperandSelectUnfolded,
filterDefinitionUsedInDropdown,
selectedOperandInDropdown,
isObjectFilterDropdownOperandSelectUnfoldedState,
filterDefinitionUsedInDropdownState,
selectedOperandInDropdownState,
} = useFilterDropdown({ filterDropdownId });
const isObjectFilterDropdownOperandSelectUnfolded = useRecoilValue(
isObjectFilterDropdownOperandSelectUnfoldedState,
);
const filterDefinitionUsedInDropdown = useRecoilValue(
filterDefinitionUsedInDropdownState,
);
const selectedOperandInDropdown = useRecoilValue(
selectedOperandInDropdownState,
);
return (
<>
{!filterDefinitionUsedInDropdown ? (

View File

@ -1,3 +1,5 @@
import { useRecoilValue } from 'recoil';
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { ObjectFilterDropdownScope } from '@/object-record/object-filter-dropdown/scopes/ObjectFilterDropdownScope';
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
@ -14,9 +16,14 @@ export const ObjectFilterDropdownButton = ({
filterDropdownId,
hotkeyScope,
}: ObjectFilterDropdownButtonProps) => {
const { availableFilterDefinitions } = useFilterDropdown({
const { availableFilterDefinitionsState } = useFilterDropdown({
filterDropdownId: filterDropdownId,
});
const availableFilterDefinitions = useRecoilValue(
availableFilterDefinitionsState,
);
const hasOnlyOneEntityFilter =
availableFilterDefinitions.length === 1 &&
availableFilterDefinitions[0].type === 'RELATION';

View File

@ -1,15 +1,24 @@
import { useRecoilValue } from 'recoil';
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { InternalDatePicker } from '@/ui/input/components/internal/date/components/InternalDatePicker';
import { isDefined } from '~/utils/isDefined';
export const ObjectFilterDropdownDateInput = () => {
const {
filterDefinitionUsedInDropdown,
selectedOperandInDropdown,
filterDefinitionUsedInDropdownState,
selectedOperandInDropdownState,
setIsObjectFilterDropdownUnfolded,
selectFilter,
} = useFilterDropdown();
const filterDefinitionUsedInDropdown = useRecoilValue(
filterDefinitionUsedInDropdownState,
);
const selectedOperandInDropdown = useRecoilValue(
selectedOperandInDropdownState,
);
const handleChange = (date: Date | null) => {
if (!filterDefinitionUsedInDropdown || !selectedOperandInDropdown) return;

View File

@ -1,4 +1,5 @@
import { useEffect, useState } from 'react';
import { useRecoilValue } from 'recoil';
import { OBJECT_FILTER_DROPDOWN_ID } from '@/object-record/object-filter-dropdown/constants/ObjectFilterDropdownId';
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
@ -15,13 +16,24 @@ export const ObjectFilterDropdownEntitySearchSelect = ({
}) => {
const {
setObjectFilterDropdownSelectedEntityId,
filterDefinitionUsedInDropdown,
selectedOperandInDropdown,
objectFilterDropdownSearchInput,
selectedFilter,
filterDefinitionUsedInDropdownState,
selectedOperandInDropdownState,
objectFilterDropdownSearchInputState,
selectedFilterState,
selectFilter,
} = useFilterDropdown();
const filterDefinitionUsedInDropdown = useRecoilValue(
filterDefinitionUsedInDropdownState,
);
const selectedOperandInDropdown = useRecoilValue(
selectedOperandInDropdownState,
);
const objectFilterDropdownSearchInput = useRecoilValue(
objectFilterDropdownSearchInputState,
);
const selectedFilter = useRecoilValue(selectedFilterState);
const { closeDropdown } = useDropdown(OBJECT_FILTER_DROPDOWN_ID);
const [isAllEntitySelected, setIsAllEntitySelected] = useState(false);

View File

@ -1,3 +1,5 @@
import { useRecoilValue } from 'recoil';
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
import { useIcons } from '@/ui/display/icon/hooks/useIcons';
@ -12,9 +14,13 @@ export const ObjectFilterDropdownFilterSelect = () => {
setFilterDefinitionUsedInDropdown,
setSelectedOperandInDropdown,
setObjectFilterDropdownSearchInput,
availableFilterDefinitions,
availableFilterDefinitionsState,
} = useFilterDropdown();
const availableFilterDefinitions = useRecoilValue(
availableFilterDefinitionsState,
);
const { getIcon } = useIcons();
const setHotkeyScope = useSetHotkeyScope();

View File

@ -1,15 +1,23 @@
import { ChangeEvent } from 'react';
import { useRecoilValue } from 'recoil';
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { DropdownMenuInput } from '@/ui/layout/dropdown/components/DropdownMenuInput';
export const ObjectFilterDropdownNumberInput = () => {
const {
selectedOperandInDropdown,
filterDefinitionUsedInDropdown,
selectedOperandInDropdownState,
filterDefinitionUsedInDropdownState,
selectFilter,
} = useFilterDropdown();
const filterDefinitionUsedInDropdown = useRecoilValue(
filterDefinitionUsedInDropdownState,
);
const selectedOperandInDropdown = useRecoilValue(
selectedOperandInDropdownState,
);
return (
filterDefinitionUsedInDropdown &&
selectedOperandInDropdown && (

View File

@ -1,3 +1,5 @@
import { useRecoilValue } from 'recoil';
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { IconChevronDown } from '@/ui/display/icon';
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader';
@ -6,11 +8,18 @@ import { getOperandLabel } from '../utils/getOperandLabel';
export const ObjectFilterDropdownOperandButton = () => {
const {
selectedOperandInDropdown,
selectedOperandInDropdownState,
setIsObjectFilterDropdownOperandSelectUnfolded,
isObjectFilterDropdownOperandSelectUnfolded,
isObjectFilterDropdownOperandSelectUnfoldedState,
} = useFilterDropdown();
const selectedOperandInDropdown = useRecoilValue(
selectedOperandInDropdownState,
);
const isObjectFilterDropdownOperandSelectUnfolded = useRecoilValue(
isObjectFilterDropdownOperandSelectUnfoldedState,
);
if (isObjectFilterDropdownOperandSelectUnfolded) {
return null;
}

View File

@ -1,3 +1,5 @@
import { useRecoilValue } from 'recoil';
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
@ -9,14 +11,24 @@ import { getOperandsForFilterType } from '../utils/getOperandsForFilterType';
export const ObjectFilterDropdownOperandSelect = () => {
const {
filterDefinitionUsedInDropdown,
filterDefinitionUsedInDropdownState,
setSelectedOperandInDropdown,
isObjectFilterDropdownOperandSelectUnfolded,
isObjectFilterDropdownOperandSelectUnfoldedState,
setIsObjectFilterDropdownOperandSelectUnfolded,
selectedFilter,
selectedFilterState,
selectFilter,
} = useFilterDropdown();
const filterDefinitionUsedInDropdown = useRecoilValue(
filterDefinitionUsedInDropdownState,
);
const isObjectFilterDropdownOperandSelectUnfolded = useRecoilValue(
isObjectFilterDropdownOperandSelectUnfoldedState,
);
const selectedFilter = useRecoilValue(selectedFilterState);
const operandsForFilterType = getOperandsForFilterType(
filterDefinitionUsedInDropdown?.type,
);

View File

@ -1,4 +1,5 @@
import { useEffect, useState } from 'react';
import { useRecoilValue } from 'recoil';
import { MenuItem, MenuItemMultiSelect } from 'tsup.ui.index';
import { FieldMetadataItemOption } from '@/object-metadata/types/FieldMetadataItem';
@ -16,13 +17,26 @@ type SelectOptionForFilter = FieldMetadataItemOption & {
export const ObjectFilterDropdownOptionSelect = () => {
const {
filterDefinitionUsedInDropdown,
objectFilterDropdownSearchInput,
selectedOperandInDropdown,
objectFilterDropdownSelectedOptionValues,
filterDefinitionUsedInDropdownState,
objectFilterDropdownSearchInputState,
selectedOperandInDropdownState,
objectFilterDropdownSelectedOptionValuesState,
selectFilter,
} = useFilterDropdown();
const filterDefinitionUsedInDropdown = useRecoilValue(
filterDefinitionUsedInDropdownState,
);
const selectedOperandInDropdown = useRecoilValue(
selectedOperandInDropdownState,
);
const objectFilterDropdownSearchInput = useRecoilValue(
objectFilterDropdownSearchInputState,
);
const objectFilterDropdownSelectedOptionValues = useRecoilValue(
objectFilterDropdownSelectedOptionValuesState,
);
const fieldMetaDataId = filterDefinitionUsedInDropdown?.fieldMetadataId ?? '';
const { selectOptions } = useOptionsForSelect(fieldMetaDataId);

View File

@ -1,3 +1,5 @@
import { useRecoilValue } from 'recoil';
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { MultipleRecordSelectDropdown } from '@/object-record/select/components/MultipleRecordSelectDropdown';
import { useRecordsForSelect } from '@/object-record/select/hooks/useRecordsForSelect';
@ -9,15 +11,28 @@ export const MAX_RECORDS_TO_DISPLAY = 3;
export const ObjectFilterDropdownRecordSelect = () => {
const {
filterDefinitionUsedInDropdown,
objectFilterDropdownSearchInput,
selectedOperandInDropdown,
filterDefinitionUsedInDropdownState,
objectFilterDropdownSearchInputState,
selectedOperandInDropdownState,
setObjectFilterDropdownSelectedRecordIds,
objectFilterDropdownSelectedRecordIds,
objectFilterDropdownSelectedRecordIdsState,
selectFilter,
emptyFilterButKeepDefinition,
} = useFilterDropdown();
const filterDefinitionUsedInDropdown = useRecoilValue(
filterDefinitionUsedInDropdownState,
);
const objectFilterDropdownSearchInput = useRecoilValue(
objectFilterDropdownSearchInputState,
);
const selectedOperandInDropdown = useRecoilValue(
selectedOperandInDropdownState,
);
const objectFilterDropdownSelectedRecordIds = useRecoilValue(
objectFilterDropdownSelectedRecordIdsState,
);
const objectNameSingular =
filterDefinitionUsedInDropdown?.relationObjectMetadataNameSingular ?? '';

View File

@ -1,16 +1,27 @@
import { ChangeEvent } from 'react';
import { useRecoilValue } from 'recoil';
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
export const ObjectFilterDropdownSearchInput = () => {
const {
filterDefinitionUsedInDropdown,
selectedOperandInDropdown,
objectFilterDropdownSearchInput,
filterDefinitionUsedInDropdownState,
selectedOperandInDropdownState,
objectFilterDropdownSearchInputState,
setObjectFilterDropdownSearchInput,
} = useFilterDropdown();
const filterDefinitionUsedInDropdown = useRecoilValue(
filterDefinitionUsedInDropdownState,
);
const selectedOperandInDropdown = useRecoilValue(
selectedOperandInDropdownState,
);
const objectFilterDropdownSearchInput = useRecoilValue(
objectFilterDropdownSearchInputState,
);
return (
filterDefinitionUsedInDropdown &&
selectedOperandInDropdown && (

View File

@ -1,18 +1,30 @@
import { ChangeEvent } from 'react';
import { useRecoilValue } from 'recoil';
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
export const ObjectFilterDropdownTextSearchInput = () => {
const {
filterDefinitionUsedInDropdown,
selectedOperandInDropdown,
objectFilterDropdownSearchInput,
filterDefinitionUsedInDropdownState,
selectedOperandInDropdownState,
objectFilterDropdownSearchInputState,
setObjectFilterDropdownSearchInput,
selectedFilter,
selectedFilterState,
selectFilter,
} = useFilterDropdown();
const filterDefinitionUsedInDropdown = useRecoilValue(
filterDefinitionUsedInDropdownState,
);
const selectedOperandInDropdown = useRecoilValue(
selectedOperandInDropdownState,
);
const objectFilterDropdownSearchInput = useRecoilValue(
objectFilterDropdownSearchInputState,
);
const selectedFilter = useRecoilValue(selectedFilterState);
return (
filterDefinitionUsedInDropdown &&
selectedOperandInDropdown && (

View File

@ -1,5 +1,6 @@
import React from 'react';
import { useTheme } from '@emotion/react';
import { useRecoilValue } from 'recoil';
import { ObjectFilterDropdownRecordRemoveFilterMenuItem } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownRecordRemoveFilterMenuItem';
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
@ -22,12 +23,17 @@ export const SingleEntityObjectFilterDropdownButton = ({
hotkeyScope: HotkeyScope;
}) => {
const {
availableFilterDefinitions,
selectedFilter,
availableFilterDefinitionsState,
selectedFilterState,
setFilterDefinitionUsedInDropdown,
setSelectedOperandInDropdown,
} = useFilterDropdown();
const availableFilterDefinitions = useRecoilValue(
availableFilterDefinitionsState,
);
const selectedFilter = useRecoilValue(selectedFilterState);
const availableFilter = availableFilterDefinitions[0];
React.useEffect(() => {

View File

@ -1,8 +1,9 @@
import { expect } from '@storybook/test';
import { act, renderHook, waitFor } from '@testing-library/react';
import { RecoilRoot } from 'recoil';
import { RecoilRoot, useRecoilState } from 'recoil';
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { useFilterDropdownStates } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdownStates';
import { Filter } from '@/object-record/object-filter-dropdown/types/Filter';
import { FilterDefinition } from '@/object-record/object-filter-dropdown/types/FilterDefinition';
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
@ -31,10 +32,15 @@ const mockFilter: Filter = {
describe('useFilterDropdown', () => {
it('should set availableFilterDefinitions', async () => {
const { result } = renderHook(
() => useFilterDropdown({ filterDropdownId }),
renderHookConfig,
);
const { result } = renderHook(() => {
useFilterDropdown({ filterDropdownId });
const { availableFilterDefinitionsState } =
useFilterDropdownStates(filterDropdownId);
const [availableFilterDefinitions, setAvailableFilterDefinitions] =
useRecoilState(availableFilterDefinitionsState);
return { availableFilterDefinitions, setAvailableFilterDefinitions };
}, renderHookConfig);
expect(result.current.availableFilterDefinitions).toEqual([]);
@ -50,10 +56,14 @@ describe('useFilterDropdown', () => {
});
it('should set onFilterSelect', async () => {
const { result } = renderHook(
() => useFilterDropdown({ filterDropdownId }),
renderHookConfig,
);
const { result } = renderHook(() => {
useFilterDropdown({ filterDropdownId });
const { onFilterSelectState } = useFilterDropdownStates(filterDropdownId);
const [onFilterSelect, setOnFilterSelect] =
useRecoilState(onFilterSelectState);
return { onFilterSelect, setOnFilterSelect };
}, renderHookConfig);
expect(result.current.onFilterSelect).toBeUndefined();
@ -68,10 +78,16 @@ describe('useFilterDropdown', () => {
});
it('should set selectedOperandInDropdown', async () => {
const { result } = renderHook(
() => useFilterDropdown({ filterDropdownId }),
renderHookConfig,
);
const { result } = renderHook(() => {
useFilterDropdown({ filterDropdownId });
const { selectedOperandInDropdownState } =
useFilterDropdownStates(filterDropdownId);
const [selectedOperandInDropdown, setSelectedOperandInDropdown] =
useRecoilState(selectedOperandInDropdownState);
return { selectedOperandInDropdown, setSelectedOperandInDropdown };
}, renderHookConfig);
const mockOperand = ViewFilterOperand.Contains;
expect(result.current.selectedOperandInDropdown).toBeNull();
@ -84,10 +100,14 @@ describe('useFilterDropdown', () => {
});
it('should set selectedFilter', async () => {
const { result } = renderHook(
() => useFilterDropdown({ filterDropdownId }),
renderHookConfig,
);
const { result } = renderHook(() => {
useFilterDropdown({ filterDropdownId });
const { selectedFilterState } = useFilterDropdownStates(filterDropdownId);
const [selectedFilter, setSelectedFilter] =
useRecoilState(selectedFilterState);
return { selectedFilter, setSelectedFilter };
}, renderHookConfig);
expect(result.current.selectedFilter).toBeUndefined();
@ -101,10 +121,20 @@ describe('useFilterDropdown', () => {
});
it('should set filterDefinitionUsedInDropdown', async () => {
const { result } = renderHook(
() => useFilterDropdown({ filterDropdownId }),
renderHookConfig,
);
const { result } = renderHook(() => {
useFilterDropdown({ filterDropdownId });
const { filterDefinitionUsedInDropdownState } =
useFilterDropdownStates(filterDropdownId);
const [
filterDefinitionUsedInDropdown,
setFilterDefinitionUsedInDropdown,
] = useRecoilState(filterDefinitionUsedInDropdownState);
return {
filterDefinitionUsedInDropdown,
setFilterDefinitionUsedInDropdown,
};
}, renderHookConfig);
expect(result.current.filterDefinitionUsedInDropdown).toBeNull();
@ -121,10 +151,20 @@ describe('useFilterDropdown', () => {
it('should set objectFilterDropdownSearchInput', async () => {
const mockResult = 'value';
const { result } = renderHook(
() => useFilterDropdown({ filterDropdownId }),
renderHookConfig,
);
const { result } = renderHook(() => {
useFilterDropdown({ filterDropdownId });
const { objectFilterDropdownSearchInputState } =
useFilterDropdownStates(filterDropdownId);
const [
objectFilterDropdownSearchInput,
setObjectFilterDropdownSearchInput,
] = useRecoilState(objectFilterDropdownSearchInputState);
return {
objectFilterDropdownSearchInput,
setObjectFilterDropdownSearchInput,
};
}, renderHookConfig);
expect(result.current.objectFilterDropdownSearchInput).toBe('');
@ -139,10 +179,20 @@ describe('useFilterDropdown', () => {
it('should set objectFilterDropdownSelectedEntityId', async () => {
const mockResult = 'value';
const { result } = renderHook(
() => useFilterDropdown({ filterDropdownId }),
renderHookConfig,
);
const { result } = renderHook(() => {
useFilterDropdown({ filterDropdownId });
const { objectFilterDropdownSelectedEntityIdState } =
useFilterDropdownStates(filterDropdownId);
const [
objectFilterDropdownSelectedEntityId,
setObjectFilterDropdownSelectedEntityId,
] = useRecoilState(objectFilterDropdownSelectedEntityIdState);
return {
objectFilterDropdownSelectedEntityId,
setObjectFilterDropdownSelectedEntityId,
};
}, renderHookConfig);
expect(result.current.objectFilterDropdownSelectedEntityId).toBeNull();
@ -159,10 +209,20 @@ describe('useFilterDropdown', () => {
it('should set objectFilterDropdownSelectedRecordIds', async () => {
const mockResult = ['id-0', 'id-1', 'id-2'];
const { result } = renderHook(
() => useFilterDropdown({ filterDropdownId }),
renderHookConfig,
);
const { result } = renderHook(() => {
useFilterDropdown({ filterDropdownId });
const { objectFilterDropdownSelectedRecordIdsState } =
useFilterDropdownStates(filterDropdownId);
const [
objectFilterDropdownSelectedRecordIds,
setObjectFilterDropdownSelectedRecordIds,
] = useRecoilState(objectFilterDropdownSelectedRecordIdsState);
return {
objectFilterDropdownSelectedRecordIds,
setObjectFilterDropdownSelectedRecordIds,
};
}, renderHookConfig);
expect(result.current.objectFilterDropdownSelectedRecordIds).toHaveLength(
0,
@ -180,10 +240,20 @@ describe('useFilterDropdown', () => {
});
it('should set isObjectFilterDropdownOperandSelectUnfolded', async () => {
const { result } = renderHook(
() => useFilterDropdown({ filterDropdownId }),
renderHookConfig,
);
const { result } = renderHook(() => {
useFilterDropdown({ filterDropdownId });
const { isObjectFilterDropdownOperandSelectUnfoldedState } =
useFilterDropdownStates(filterDropdownId);
const [
isObjectFilterDropdownOperandSelectUnfolded,
setIsObjectFilterDropdownOperandSelectUnfolded,
] = useRecoilState(isObjectFilterDropdownOperandSelectUnfoldedState);
return {
isObjectFilterDropdownOperandSelectUnfolded,
setIsObjectFilterDropdownOperandSelectUnfolded,
};
}, renderHookConfig);
expect(result.current.isObjectFilterDropdownOperandSelectUnfolded).toBe(
false,
@ -201,10 +271,20 @@ describe('useFilterDropdown', () => {
});
it('should set isObjectFilterDropdownUnfolded', async () => {
const { result } = renderHook(
() => useFilterDropdown({ filterDropdownId }),
renderHookConfig,
);
const { result } = renderHook(() => {
useFilterDropdown({ filterDropdownId });
const { isObjectFilterDropdownUnfoldedState } =
useFilterDropdownStates(filterDropdownId);
const [
isObjectFilterDropdownUnfolded,
setIsObjectFilterDropdownUnfolded,
] = useRecoilState(isObjectFilterDropdownUnfoldedState);
return {
isObjectFilterDropdownUnfolded,
setIsObjectFilterDropdownUnfolded,
};
}, renderHookConfig);
expect(result.current.isObjectFilterDropdownUnfolded).toBe(false);
@ -218,10 +298,16 @@ describe('useFilterDropdown', () => {
});
it('should reset filter', async () => {
const { result } = renderHook(
() => useFilterDropdown({ filterDropdownId }),
renderHookConfig,
);
const { result } = renderHook(() => {
const { selectFilter, resetFilter } = useFilterDropdown({
filterDropdownId,
});
const { selectedFilterState } = useFilterDropdownStates(filterDropdownId);
const [selectedFilter, setSelectedFilter] =
useRecoilState(selectedFilterState);
return { selectedFilter, setSelectedFilter, selectFilter, resetFilter };
}, renderHookConfig);
act(() => {
result.current.selectFilter(mockFilter);
@ -241,10 +327,14 @@ describe('useFilterDropdown', () => {
});
it('should call onFilterSelect when a filter option is set', async () => {
const { result } = renderHook(
() => useFilterDropdown({ filterDropdownId }),
renderHookConfig,
);
const { result } = renderHook(() => {
const { selectFilter } = useFilterDropdown({ filterDropdownId });
const { onFilterSelectState } = useFilterDropdownStates(filterDropdownId);
const [onFilterSelect, setOnFilterSelect] =
useRecoilState(onFilterSelectState);
return { onFilterSelect, setOnFilterSelect, selectFilter };
}, renderHookConfig);
const onFilterSelectMock = jest.fn();
expect(result.current.onFilterSelect).toBeUndefined();

View File

@ -1,7 +1,8 @@
import { useCallback } from 'react';
import { useRecoilCallback, useSetRecoilState } from 'recoil';
import { useFilterDropdownStates } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdownStates';
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
import { ObjectFilterDropdownScopeInternalContext } from '../scopes/scope-internal-context/ObjectFilterDropdownScopeInternalContext';
import { Filter } from '../types/Filter';
@ -17,92 +18,122 @@ export const useFilterDropdown = (props?: UseFilterDropdownProps) => {
);
const {
availableFilterDefinitions,
setAvailableFilterDefinitions,
filterDefinitionUsedInDropdown,
setFilterDefinitionUsedInDropdown,
objectFilterDropdownSearchInput,
setObjectFilterDropdownSearchInput,
objectFilterDropdownSelectedEntityId,
setObjectFilterDropdownSelectedEntityId,
objectFilterDropdownSelectedRecordIds,
setObjectFilterDropdownSelectedRecordIds,
objectFilterDropdownSelectedOptionValues,
setObjectFilterDropdownSelectedOptionValues,
isObjectFilterDropdownOperandSelectUnfolded,
setIsObjectFilterDropdownOperandSelectUnfolded,
isObjectFilterDropdownUnfolded,
setIsObjectFilterDropdownUnfolded,
selectedFilter,
setSelectedFilter,
selectedOperandInDropdown,
setSelectedOperandInDropdown,
onFilterSelect,
setOnFilterSelect,
availableFilterDefinitionsState,
filterDefinitionUsedInDropdownState,
objectFilterDropdownSearchInputState,
objectFilterDropdownSelectedEntityIdState,
objectFilterDropdownSelectedRecordIdsState,
objectFilterDropdownSelectedOptionValuesState,
isObjectFilterDropdownOperandSelectUnfoldedState,
isObjectFilterDropdownUnfoldedState,
selectedFilterState,
selectedOperandInDropdownState,
onFilterSelectState,
} = useFilterDropdownStates(scopeId);
const selectFilter = useCallback(
(filter: Filter | null) => {
setSelectedFilter(filter);
onFilterSelect?.(filter);
},
[setSelectedFilter, onFilterSelect],
const selectFilter = useRecoilCallback(
({ set, snapshot }) =>
(filter: Filter | null) => {
set(selectedFilterState, filter);
const onFilterSelect = getSnapshotValue(snapshot, onFilterSelectState);
onFilterSelect?.(filter);
},
[selectedFilterState, onFilterSelectState],
);
const emptyFilterButKeepDefinition = useCallback(() => {
setObjectFilterDropdownSearchInput('');
setObjectFilterDropdownSelectedEntityId(null);
setObjectFilterDropdownSelectedRecordIds([]);
setSelectedFilter(undefined);
}, [
setSelectedFilter,
setObjectFilterDropdownSelectedRecordIds,
setObjectFilterDropdownSelectedEntityId,
setObjectFilterDropdownSearchInput,
]);
const emptyFilterButKeepDefinition = useRecoilCallback(
({ set }) =>
() => {
set(objectFilterDropdownSearchInputState, '');
set(objectFilterDropdownSelectedEntityIdState, null);
set(objectFilterDropdownSelectedRecordIdsState, []);
set(selectedFilterState, undefined);
},
[
objectFilterDropdownSearchInputState,
objectFilterDropdownSelectedEntityIdState,
objectFilterDropdownSelectedRecordIdsState,
selectedFilterState,
],
);
const resetFilter = useCallback(() => {
setObjectFilterDropdownSearchInput('');
setObjectFilterDropdownSelectedEntityId(null);
setObjectFilterDropdownSelectedRecordIds([]);
setSelectedFilter(undefined);
setFilterDefinitionUsedInDropdown(null);
setSelectedOperandInDropdown(null);
}, [
setFilterDefinitionUsedInDropdown,
setObjectFilterDropdownSearchInput,
setObjectFilterDropdownSelectedEntityId,
setObjectFilterDropdownSelectedRecordIds,
setSelectedFilter,
setSelectedOperandInDropdown,
]);
const resetFilter = useRecoilCallback(
({ set }) =>
() => {
set(objectFilterDropdownSearchInputState, '');
set(objectFilterDropdownSelectedEntityIdState, null);
set(objectFilterDropdownSelectedRecordIdsState, []);
set(selectedFilterState, undefined);
set(filterDefinitionUsedInDropdownState, null);
set(selectedOperandInDropdownState, null);
},
[
filterDefinitionUsedInDropdownState,
objectFilterDropdownSearchInputState,
objectFilterDropdownSelectedEntityIdState,
objectFilterDropdownSelectedRecordIdsState,
selectedFilterState,
selectedOperandInDropdownState,
],
);
const setAvailableFilterDefinitions = useSetRecoilState(
availableFilterDefinitionsState,
);
const setSelectedFilter = useSetRecoilState(selectedFilterState);
const setSelectedOperandInDropdown = useSetRecoilState(
selectedOperandInDropdownState,
);
const setFilterDefinitionUsedInDropdown = useSetRecoilState(
filterDefinitionUsedInDropdownState,
);
const setObjectFilterDropdownSearchInput = useSetRecoilState(
objectFilterDropdownSearchInputState,
);
const setObjectFilterDropdownSelectedEntityId = useSetRecoilState(
objectFilterDropdownSelectedEntityIdState,
);
const setObjectFilterDropdownSelectedRecordIds = useSetRecoilState(
objectFilterDropdownSelectedRecordIdsState,
);
const setObjectFilterDropdownSelectedOptionValues = useSetRecoilState(
objectFilterDropdownSelectedOptionValuesState,
);
const setIsObjectFilterDropdownOperandSelectUnfolded = useSetRecoilState(
isObjectFilterDropdownOperandSelectUnfoldedState,
);
const setIsObjectFilterDropdownUnfolded = useSetRecoilState(
isObjectFilterDropdownUnfoldedState,
);
const setOnFilterSelect = useSetRecoilState(onFilterSelectState);
return {
scopeId,
availableFilterDefinitions,
setAvailableFilterDefinitions,
filterDefinitionUsedInDropdown,
setFilterDefinitionUsedInDropdown,
objectFilterDropdownSearchInput,
setObjectFilterDropdownSearchInput,
objectFilterDropdownSelectedEntityId,
setObjectFilterDropdownSelectedEntityId,
objectFilterDropdownSelectedRecordIds,
setObjectFilterDropdownSelectedRecordIds,
objectFilterDropdownSelectedOptionValues,
setObjectFilterDropdownSelectedOptionValues,
isObjectFilterDropdownOperandSelectUnfolded,
setIsObjectFilterDropdownOperandSelectUnfolded,
isObjectFilterDropdownUnfolded,
setIsObjectFilterDropdownUnfolded,
selectedFilter,
setSelectedFilter,
selectedOperandInDropdown,
setSelectedOperandInDropdown,
selectFilter,
resetFilter,
onFilterSelect,
setSelectedFilter,
setSelectedOperandInDropdown,
setAvailableFilterDefinitions,
setFilterDefinitionUsedInDropdown,
setObjectFilterDropdownSearchInput,
setObjectFilterDropdownSelectedEntityId,
setObjectFilterDropdownSelectedRecordIds,
setObjectFilterDropdownSelectedOptionValues,
setIsObjectFilterDropdownOperandSelectUnfolded,
setIsObjectFilterDropdownUnfolded,
setOnFilterSelect,
emptyFilterButKeepDefinition,
availableFilterDefinitionsState,
filterDefinitionUsedInDropdownState,
objectFilterDropdownSearchInputState,
objectFilterDropdownSelectedEntityIdState,
objectFilterDropdownSelectedRecordIdsState,
objectFilterDropdownSelectedOptionValuesState,
isObjectFilterDropdownOperandSelectUnfoldedState,
isObjectFilterDropdownUnfoldedState,
selectedFilterState,
selectedOperandInDropdownState,
onFilterSelectState,
};
};

View File

@ -1,97 +1,84 @@
import { objectFilterDropdownSelectedRecordIdsScopedState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedRecordIdsScopedState';
import { onFilterSelectScopedState } from '@/object-record/object-filter-dropdown/states/onFilterSelectScopedState';
import { useRecoilScopedStateV2 } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedStateV2';
import { availableFilterDefinitionsScopedState } from '../states/availableFilterDefinitionsScopedState';
import { filterDefinitionUsedInDropdownScopedState } from '../states/filterDefinitionUsedInDropdownScopedState';
import { isObjectFilterDropdownOperandSelectUnfoldedScopedState } from '../states/isObjectFilterDropdownOperandSelectUnfoldedScopedState';
import { isObjectFilterDropdownUnfoldedScopedState } from '../states/isObjectFilterDropdownUnfoldedScopedState';
import { objectFilterDropdownSearchInputScopedState } from '../states/objectFilterDropdownSearchInputScopedState';
import { objectFilterDropdownSelectedEntityIdScopedState } from '../states/objectFilterDropdownSelectedEntityIdScopedState';
import { objectFilterDropdownSelectedOptionValuesScopedState } from '../states/objectFilterDropdownSelectedOptionValuesScopedState';
import { selectedFilterScopedState } from '../states/selectedFilterScopedState';
import { selectedOperandInDropdownScopedState } from '../states/selectedOperandInDropdownScopedState';
import { filterDefinitionUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/filterDefinitionUsedInDropdownComponentState';
import { isObjectFilterDropdownOperandSelectUnfoldedComponentState } from '@/object-record/object-filter-dropdown/states/isObjectFilterDropdownOperandSelectUnfoldedComponentState';
import { isObjectFilterDropdownUnfoldedComponentState } from '@/object-record/object-filter-dropdown/states/isObjectFilterDropdownUnfoldedComponentState';
import { objectFilterDropdownSearchInputComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputComponentState';
import { objectFilterDropdownSelectedEntityIdComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedEntityIdComponentState';
import { objectFilterDropdownSelectedOptionValuesComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedOptionValuesComponentState';
import { objectFilterDropdownSelectedRecordIdsComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedRecordIdsComponentState';
import { onFilterSelectComponentState } from '@/object-record/object-filter-dropdown/states/onFilterSelectComponentState';
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState';
import { availableFilterDefinitionsComponentState } from '@/views/states/availableFilterDefinitionsComponentState';
export const useFilterDropdownStates = (scopeId: string) => {
const [availableFilterDefinitions, setAvailableFilterDefinitions] =
useRecoilScopedStateV2(availableFilterDefinitionsScopedState, scopeId);
const [filterDefinitionUsedInDropdown, setFilterDefinitionUsedInDropdown] =
useRecoilScopedStateV2(filterDefinitionUsedInDropdownScopedState, scopeId);
const [objectFilterDropdownSearchInput, setObjectFilterDropdownSearchInput] =
useRecoilScopedStateV2(objectFilterDropdownSearchInputScopedState, scopeId);
const [
objectFilterDropdownSelectedEntityId,
setObjectFilterDropdownSelectedEntityId,
] = useRecoilScopedStateV2(
objectFilterDropdownSelectedEntityIdScopedState,
const availableFilterDefinitionsState = extractComponentState(
availableFilterDefinitionsComponentState,
scopeId,
);
const [
objectFilterDropdownSelectedRecordIds,
setObjectFilterDropdownSelectedRecordIds,
] = useRecoilScopedStateV2(
objectFilterDropdownSelectedRecordIdsScopedState,
const filterDefinitionUsedInDropdownState = extractComponentState(
filterDefinitionUsedInDropdownComponentState,
scopeId,
);
const [
objectFilterDropdownSelectedOptionValues,
setObjectFilterDropdownSelectedOptionValues,
] = useRecoilScopedStateV2(
objectFilterDropdownSelectedOptionValuesScopedState,
const objectFilterDropdownSearchInputState = extractComponentState(
objectFilterDropdownSearchInputComponentState,
scopeId,
);
const [
isObjectFilterDropdownOperandSelectUnfolded,
setIsObjectFilterDropdownOperandSelectUnfolded,
] = useRecoilScopedStateV2(
isObjectFilterDropdownOperandSelectUnfoldedScopedState,
const objectFilterDropdownSelectedEntityIdState = extractComponentState(
objectFilterDropdownSelectedEntityIdComponentState,
scopeId,
);
const [isObjectFilterDropdownUnfolded, setIsObjectFilterDropdownUnfolded] =
useRecoilScopedStateV2(isObjectFilterDropdownUnfoldedScopedState, scopeId);
const [selectedFilter, setSelectedFilter] = useRecoilScopedStateV2(
selectedFilterScopedState,
const objectFilterDropdownSelectedRecordIdsState = extractComponentState(
objectFilterDropdownSelectedRecordIdsComponentState,
scopeId,
);
const [selectedOperandInDropdown, setSelectedOperandInDropdown] =
useRecoilScopedStateV2(selectedOperandInDropdownScopedState, scopeId);
const objectFilterDropdownSelectedOptionValuesState = extractComponentState(
objectFilterDropdownSelectedOptionValuesComponentState,
scopeId,
);
const [onFilterSelect, setOnFilterSelect] = useRecoilScopedStateV2(
onFilterSelectScopedState,
const isObjectFilterDropdownOperandSelectUnfoldedState =
extractComponentState(
isObjectFilterDropdownOperandSelectUnfoldedComponentState,
scopeId,
);
const isObjectFilterDropdownUnfoldedState = extractComponentState(
isObjectFilterDropdownUnfoldedComponentState,
scopeId,
);
const selectedFilterState = extractComponentState(
selectedFilterComponentState,
scopeId,
);
const selectedOperandInDropdownState = extractComponentState(
selectedOperandInDropdownComponentState,
scopeId,
);
const onFilterSelectState = extractComponentState(
onFilterSelectComponentState,
scopeId,
);
return {
availableFilterDefinitions,
setAvailableFilterDefinitions,
filterDefinitionUsedInDropdown,
setFilterDefinitionUsedInDropdown,
objectFilterDropdownSearchInput,
setObjectFilterDropdownSearchInput,
objectFilterDropdownSelectedEntityId,
setObjectFilterDropdownSelectedEntityId,
objectFilterDropdownSelectedRecordIds,
objectFilterDropdownSelectedOptionValues,
setObjectFilterDropdownSelectedOptionValues,
setObjectFilterDropdownSelectedRecordIds,
isObjectFilterDropdownOperandSelectUnfolded,
setIsObjectFilterDropdownOperandSelectUnfolded,
isObjectFilterDropdownUnfolded,
setIsObjectFilterDropdownUnfolded,
selectedFilter,
setSelectedFilter,
selectedOperandInDropdown,
setSelectedOperandInDropdown,
onFilterSelect,
setOnFilterSelect,
availableFilterDefinitionsState,
filterDefinitionUsedInDropdownState,
objectFilterDropdownSearchInputState,
objectFilterDropdownSelectedEntityIdState,
objectFilterDropdownSelectedRecordIdsState,
objectFilterDropdownSelectedOptionValuesState,
isObjectFilterDropdownOperandSelectUnfoldedState,
isObjectFilterDropdownUnfoldedState,
selectedFilterState,
selectedOperandInDropdownState,
onFilterSelectState,
};
};

View File

@ -1,9 +1,9 @@
import { FilterDefinition } from '@/object-record/object-filter-dropdown/types/FilterDefinition';
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
export const availableFilterDefinitionsScopedState = createComponentState<
export const availableFilterDefinitionsComponentState = createComponentState<
FilterDefinition[]
>({
key: 'availableFilterDefinitionsScopedState',
key: 'availableFilterDefinitionsComponentState',
defaultValue: [],
});

View File

@ -2,8 +2,8 @@ import { createComponentState } from '@/ui/utilities/state/component-state/utils
import { FilterDefinition } from '../types/FilterDefinition';
export const filterDefinitionUsedInDropdownScopedState =
export const filterDefinitionUsedInDropdownComponentState =
createComponentState<FilterDefinition | null>({
key: 'filterDefinitionUsedInDropdownScopedState',
key: 'filterDefinitionUsedInDropdownComponentState',
defaultValue: null,
});

View File

@ -1,7 +1,7 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
export const isObjectFilterDropdownOperandSelectUnfoldedScopedState =
export const isObjectFilterDropdownOperandSelectUnfoldedComponentState =
createComponentState<boolean>({
key: 'isObjectFilterDropdownOperandSelectUnfoldedScopedState',
key: 'isObjectFilterDropdownOperandSelectUnfoldedComponentState',
defaultValue: false,
});

View File

@ -1,6 +1,6 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
export const isObjectFilterDropdownUnfoldedScopedState =
export const isObjectFilterDropdownUnfoldedComponentState =
createComponentState<boolean>({
key: 'isObjectFilterDropdownUnfoldedScopedState',
defaultValue: false,

View File

@ -1,7 +1,7 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
export const objectFilterDropdownSearchInputScopedState =
export const objectFilterDropdownSearchInputComponentState =
createComponentState<string>({
key: 'objectFilterDropdownSearchInputScopedState',
key: 'objectFilterDropdownSearchInputComponentState',
defaultValue: '',
});

View File

@ -1,7 +1,7 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
export const objectFilterDropdownSelectedEntityIdScopedState =
export const objectFilterDropdownSelectedEntityIdComponentState =
createComponentState<string | null>({
key: 'objectFilterDropdownSelectedEntityIdScopedState',
key: 'objectFilterDropdownSelectedEntityIdComponentState',
defaultValue: null,
});

View File

@ -1,7 +1,7 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
export const objectFilterDropdownSelectedRecordIdsScopedState =
export const objectFilterDropdownSelectedOptionValuesComponentState =
createComponentState<string[]>({
key: 'objectFilterDropdownSelectedRecordIdsScopedState',
key: 'objectFilterDropdownSelectedOptionValuesComponentState',
defaultValue: [],
});

View File

@ -1,7 +1,7 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
export const objectFilterDropdownSelectedOptionValuesScopedState =
export const objectFilterDropdownSelectedRecordIdsComponentState =
createComponentState<string[]>({
key: 'objectFilterDropdownSelectedOptionValuesScopedState',
key: 'objectFilterDropdownSelectedRecordIdsComponentState',
defaultValue: [],
});

View File

@ -2,9 +2,9 @@ import { createComponentState } from '@/ui/utilities/state/component-state/utils
import { Filter } from '../types/Filter';
export const onFilterSelectScopedState = createComponentState<
export const onFilterSelectComponentState = createComponentState<
((filter: Filter | null) => void) | undefined
>({
key: 'onFilterSelectScopedState',
key: 'onFilterSelectComponentState',
defaultValue: undefined,
});

View File

@ -2,9 +2,9 @@ import { createComponentState } from '@/ui/utilities/state/component-state/utils
import { Filter } from '../types/Filter';
export const selectedFilterScopedState = createComponentState<
export const selectedFilterComponentState = createComponentState<
Filter | undefined | null
>({
key: 'selectedFilterScopedState',
key: 'selectedFilterComponentState',
defaultValue: undefined,
});

View File

@ -1,8 +1,8 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
export const selectedOperandInDropdownScopedState =
export const selectedOperandInDropdownComponentState =
createComponentState<ViewFilterOperand | null>({
key: 'selectedOperandInDropdownScopedState',
key: 'selectedOperandInDropdownComponentState',
defaultValue: null,
});

View File

@ -1,4 +1,5 @@
import { useCallback, useState } from 'react';
import { useRecoilValue } from 'recoil';
import { OBJECT_SORT_DROPDOWN_ID } from '@/object-record/object-sort-dropdown/constants/ObjectSortDropdownId';
import { useSortDropdown } from '@/object-record/object-sort-dropdown/hooks/useSortDropdown';
@ -37,7 +38,7 @@ export const ObjectSortDropdownButton = ({
setSelectedSortDirection('asc');
}, []);
const { isSortSelected } = useSortDropdown({
const { isSortSelectedState } = useSortDropdown({
sortDropdownId: sortDropdownId,
});
@ -48,10 +49,16 @@ export const ObjectSortDropdownButton = ({
resetState();
};
const { availableSortDefinitions, onSortSelect } = useSortDropdown({
const { availableSortDefinitionsState, onSortSelectState } = useSortDropdown({
sortDropdownId: sortDropdownId,
});
const isSortSelected = useRecoilValue(isSortSelectedState);
const availableSortDefinitions = useRecoilValue(
availableSortDefinitionsState,
);
const onSortSelect = useRecoilValue(onSortSelectState);
const handleAddSort = (selectedSortDefinition: SortDefinition) => {
toggleDropdown();
onSortSelect?.({

View File

@ -1,7 +1,9 @@
import { expect } from '@storybook/test';
import { act, renderHook, waitFor } from '@testing-library/react';
import { RecoilRoot } from 'recoil';
import { RecoilRoot, useRecoilState } from 'recoil';
import { useSortDropdown } from '@/object-record/object-sort-dropdown/hooks/useSortDropdown';
import { useSortDropdownStates } from '@/object-record/object-sort-dropdown/hooks/useSortDropdownStates';
import { Sort } from '@/object-record/object-sort-dropdown/types/Sort';
import { SortDefinition } from '@/object-record/object-sort-dropdown/types/SortDefinition';
@ -20,10 +22,19 @@ const sortDefinitions: SortDefinition[] = [
describe('useSortDropdown', () => {
it('should set availableSortDefinitions', async () => {
const { result } = renderHook(
() => useSortDropdown({ sortDropdownId }),
renderHookConfig,
);
const { result } = renderHook(() => {
useSortDropdown({ sortDropdownId });
const { availableSortDefinitionsState } =
useSortDropdownStates(sortDropdownId);
const [availableSortDefinitions, setAvailableSortDefinitions] =
useRecoilState(availableSortDefinitionsState);
return {
availableSortDefinitions,
setAvailableSortDefinitions,
};
}, renderHookConfig);
expect(result.current.availableSortDefinitions).toEqual([]);
act(() => {
result.current.setAvailableSortDefinitions(sortDefinitions);
@ -35,10 +46,18 @@ describe('useSortDropdown', () => {
});
it('should set isSortSelected', async () => {
const { result } = renderHook(
() => useSortDropdown({ sortDropdownId }),
renderHookConfig,
);
const { result } = renderHook(() => {
useSortDropdown({ sortDropdownId });
const { isSortSelectedState } = useSortDropdownStates(sortDropdownId);
const [isSortSelected, setIsSortSelected] =
useRecoilState(isSortSelectedState);
return {
isSortSelected,
setIsSortSelected,
};
}, renderHookConfig);
expect(result.current.isSortSelected).toBe(false);
@ -54,10 +73,17 @@ describe('useSortDropdown', () => {
it('should set onSortSelect', async () => {
const OnSortSelectFunction = () => {};
const mockOnSortSelect = jest.fn(() => OnSortSelectFunction);
const { result } = renderHook(
() => useSortDropdown({ sortDropdownId }),
renderHookConfig,
);
const { result } = renderHook(() => {
useSortDropdown({ sortDropdownId });
const { onSortSelectState } = useSortDropdownStates(sortDropdownId);
const [onSortSelect, setOnSortSelect] = useRecoilState(onSortSelectState);
return {
onSortSelect,
setOnSortSelect,
};
}, renderHookConfig);
expect(result.current.onSortSelect).toBeUndefined();
@ -78,10 +104,17 @@ describe('useSortDropdown', () => {
definition: sortDefinitions[0],
};
const { result } = renderHook(
() => useSortDropdown({ sortDropdownId }),
renderHookConfig,
);
const { result } = renderHook(() => {
useSortDropdown({ sortDropdownId });
const { onSortSelectState } = useSortDropdownStates(sortDropdownId);
const [onSortSelect, setOnSortSelect] = useRecoilState(onSortSelectState);
return {
onSortSelect,
setOnSortSelect,
};
}, renderHookConfig);
act(() => {
result.current.setOnSortSelect(mockOnSortSelect);

View File

@ -13,21 +13,15 @@ export const useSortDropdown = (props?: UseSortProps) => {
props?.sortDropdownId,
);
const {
availableSortDefinitions,
setAvailableSortDefinitions,
isSortSelected,
setIsSortSelected,
onSortSelect,
setOnSortSelect,
availableSortDefinitionsState,
isSortSelectedState,
onSortSelectState,
} = useSortDropdownStates(scopeId);
return {
scopeId,
availableSortDefinitions,
isSortSelected,
setIsSortSelected,
setAvailableSortDefinitions,
onSortSelect,
setOnSortSelect,
availableSortDefinitionsState,
isSortSelectedState,
onSortSelectState,
};
};

View File

@ -1,29 +1,27 @@
import { onSortSelectScopedState } from '@/object-record/object-sort-dropdown/states/onSortSelectScopedState';
import { useRecoilScopedStateV2 } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedStateV2';
import { availableSortDefinitionsScopedState } from '../states/availableSortDefinitionsScopedState';
import { isSortSelectedScopedState } from '../states/isSortSelectedScopedState';
import { isSortSelectedComponentState } from '@/object-record/object-sort-dropdown/states/isSortSelectedScopedState';
import { onSortSelectComponentState } from '@/object-record/object-sort-dropdown/states/onSortSelectScopedState';
import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState';
import { availableSortDefinitionsComponentState } from '@/views/states/availableSortDefinitionsComponentState';
export const useSortDropdownStates = (scopeId: string) => {
const [availableSortDefinitions, setAvailableSortDefinitions] =
useRecoilScopedStateV2(availableSortDefinitionsScopedState, scopeId);
const [isSortSelected, setIsSortSelected] = useRecoilScopedStateV2(
isSortSelectedScopedState,
const availableSortDefinitionsState = extractComponentState(
availableSortDefinitionsComponentState,
scopeId,
);
const [onSortSelect, setOnSortSelect] = useRecoilScopedStateV2(
onSortSelectScopedState,
const isSortSelectedState = extractComponentState(
isSortSelectedComponentState,
scopeId,
);
const onSortSelectState = extractComponentState(
onSortSelectComponentState,
scopeId,
);
return {
availableSortDefinitions,
setAvailableSortDefinitions,
isSortSelected,
setIsSortSelected,
onSortSelect,
setOnSortSelect,
availableSortDefinitionsState,
isSortSelectedState,
onSortSelectState,
};
};

View File

@ -2,9 +2,9 @@ import { createComponentState } from '@/ui/utilities/state/component-state/utils
import { SortDefinition } from '../types/SortDefinition';
export const availableSortDefinitionsScopedState = createComponentState<
export const availableSortDefinitionsComponentState = createComponentState<
SortDefinition[]
>({
key: 'availableSortDefinitionsScopedState',
key: 'availableSortDefinitionsComponentState',
defaultValue: [],
});

View File

@ -1,6 +1,6 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
export const isSortSelectedScopedState = createComponentState<boolean>({
key: 'isSortSelectedScopedState',
export const isSortSelectedComponentState = createComponentState<boolean>({
key: 'isSortSelectedComponentState',
defaultValue: false,
});

View File

@ -2,9 +2,9 @@ import { createComponentState } from '@/ui/utilities/state/component-state/utils
import { Sort } from '../types/Sort';
export const onSortSelectScopedState = createComponentState<
export const onSortSelectComponentState = createComponentState<
((sort: Sort) => void) | undefined
>({
key: 'onSortSelectScopedState',
key: 'onSortSelectComponentState',
defaultValue: undefined,
});

View File

@ -55,7 +55,7 @@ describe('turnSortsIntoOrderBy', () => {
});
});
it('should throw error if field not found', () => {
it('should ignore if field not found', () => {
const sorts: Sort[] = [
{
fieldMetadataId: 'invalidField',
@ -63,8 +63,8 @@ describe('turnSortsIntoOrderBy', () => {
definition: sortDefinition,
},
];
expect(() => turnSortsIntoOrderBy(sorts, [])).toThrow(
'Could not find field invalidField in metadata object',
);
expect(turnSortsIntoOrderBy(sorts, [])).toEqual({
position: 'AscNullsFirst',
});
});
});

View File

@ -2,6 +2,7 @@ import { OrderBy } from '@/object-metadata/types/OrderBy';
import { OrderByField } from '@/object-metadata/types/OrderByField';
import { Field } from '~/generated/graphql';
import { mapArrayToObject } from '~/utils/array/mapArrayToObject';
import { isDefined } from '~/utils/isDefined';
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
import { Sort } from '../types/Sort';
@ -12,20 +13,20 @@ export const turnSortsIntoOrderBy = (
): OrderByField => {
const fieldsById = mapArrayToObject(fields, ({ id }) => id);
const sortsOrderBy = Object.fromEntries(
sorts.map((sort) => {
const correspondingField = fieldsById[sort.fieldMetadataId];
sorts
.map((sort) => {
const correspondingField = fieldsById[sort.fieldMetadataId];
if (isUndefinedOrNull(correspondingField)) {
throw new Error(
`Could not find field ${sort.fieldMetadataId} in metadata object`,
);
}
if (isUndefinedOrNull(correspondingField)) {
return undefined;
}
const direction: OrderBy =
sort.direction === 'asc' ? 'AscNullsFirst' : 'DescNullsLast';
const direction: OrderBy =
sort.direction === 'asc' ? 'AscNullsFirst' : 'DescNullsLast';
return [correspondingField.name, direction];
}),
return [correspondingField.name, direction];
})
.filter(isDefined),
);
return {

View File

@ -34,8 +34,8 @@ export const useRecordActionBar = ({
selectedRecordIds,
callback,
}: useRecordActionBarProps) => {
const setContextMenuEntries = useSetRecoilState(contextMenuEntriesState());
const setActionBarEntriesState = useSetRecoilState(actionBarEntriesState());
const setContextMenuEntries = useSetRecoilState(contextMenuEntriesState);
const setActionBarEntriesState = useSetRecoilState(actionBarEntriesState);
const { createFavorite, favorites, deleteFavorite } = useFavorites();

View File

@ -10,9 +10,9 @@ type RecordBoardActionBarProps = {
export const RecordBoardActionBar = ({
recordBoardId,
}: RecordBoardActionBarProps) => {
const { getSelectedRecordIdsSelector } = useRecordBoardStates(recordBoardId);
const { selectedRecordIdsSelector } = useRecordBoardStates(recordBoardId);
const selectedRecordIds = useRecoilValue(getSelectedRecordIdsSelector());
const selectedRecordIds = useRecoilValue(selectedRecordIdsSelector());
if (!selectedRecordIds.length) {
return null;

View File

@ -50,12 +50,12 @@ export const RecordBoard = ({ recordBoardId }: RecordBoardProps) => {
const boardRef = useRef<HTMLDivElement>(null);
const {
getColumnIdsState,
columnIdsState,
columnsFamilySelector,
recordIdsByColumnIdFamilyState,
} = useRecordBoardStates(recordBoardId);
const columnIds = useRecoilValue(getColumnIdsState());
const columnIds = useRecoilValue(columnIdsState);
const { resetRecordSelection, setRecordAsSelected } =
useRecordBoardSelection(recordBoardId);

View File

@ -10,9 +10,9 @@ type RecordBoardContextMenuProps = {
export const RecordBoardContextMenu = ({
recordBoardId,
}: RecordBoardContextMenuProps) => {
const { getSelectedRecordIdsSelector } = useRecordBoardStates(recordBoardId);
const { selectedRecordIdsSelector } = useRecordBoardStates(recordBoardId);
const selectedRecordIds = useRecoilValue(getSelectedRecordIdsSelector());
const selectedRecordIds = useRecoilValue(selectedRecordIdsSelector());
if (!selectedRecordIds.length) {
return null;

View File

@ -28,15 +28,15 @@ export const useRecordBoardStates = (recordBoardId?: string) => {
return {
scopeId,
getObjectSingularNameState: extractComponentState(
objectSingularNameState: extractComponentState(
recordBoardObjectSingularNameComponentState,
scopeId,
),
getIsFetchingRecordState: extractComponentState(
isFetchingRecordState: extractComponentState(
isRecordBoardFetchingRecordsComponentState,
scopeId,
),
getColumnIdsState: extractComponentState(
columnIdsState: extractComponentState(
recordBoardColumnIdsComponentState,
scopeId,
),
@ -53,19 +53,16 @@ export const useRecordBoardStates = (recordBoardId?: string) => {
scopeId,
),
getFiltersState: extractComponentState(
filtersState: extractComponentState(
recordBoardFiltersComponentState,
scopeId,
),
getSortsState: extractComponentState(
recordBoardSortsComponentState,
scopeId,
),
getFieldDefinitionsState: extractComponentState(
sortsState: extractComponentState(recordBoardSortsComponentState, scopeId),
fieldDefinitionsState: extractComponentState(
recordBoardFieldDefinitionsComponentState,
scopeId,
),
getVisibleFieldDefinitionsState: extractComponentReadOnlySelector(
visibleFieldDefinitionsState: extractComponentReadOnlySelector(
recordBoardVisibleFieldDefinitionsComponentSelector,
scopeId,
),
@ -78,17 +75,17 @@ export const useRecordBoardStates = (recordBoardId?: string) => {
isRecordBoardCardSelectedComponentFamilyState,
scopeId,
),
getSelectedRecordIdsSelector: extractComponentReadOnlySelector(
selectedRecordIdsSelector: extractComponentReadOnlySelector(
recordBoardSelectedRecordIdsComponentSelector,
scopeId,
),
getIsCompactModeActiveState: extractComponentState(
isCompactModeActiveState: extractComponentState(
isRecordBoardCompactModeActiveComponentState,
scopeId,
),
getOnFetchMoreVisibilityChangeState: extractComponentState(
onFetchMoreVisibilityChangeState: extractComponentState(
onRecordBoardFetchMoreVisibilityChangeComponentState,
scopeId,
),

View File

@ -5,14 +5,14 @@ import { RecordBoardColumnDefinition } from '@/object-record/record-board/types/
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
export const useSetRecordBoardColumns = (recordBoardId?: string) => {
const { scopeId, getColumnIdsState, columnsFamilySelector } =
const { scopeId, columnIdsState, columnsFamilySelector } =
useRecordBoardStates(recordBoardId);
const setColumns = useRecoilCallback(
({ set, snapshot }) =>
(columns: RecordBoardColumnDefinition[]) => {
const currentColumnsIds = snapshot
.getLoadable(getColumnIdsState())
.getLoadable(columnIdsState)
.getValue();
const columnIds = columns.map(({ id }) => id);
@ -22,7 +22,7 @@ export const useSetRecordBoardColumns = (recordBoardId?: string) => {
}
set(
getColumnIdsState(),
columnIdsState,
columns.map((column) => column.id),
);
@ -38,7 +38,7 @@ export const useSetRecordBoardColumns = (recordBoardId?: string) => {
set(columnsFamilySelector(column.id), column);
});
},
[columnsFamilySelector, getColumnIdsState],
[columnsFamilySelector, columnIdsState],
);
return {

View File

@ -9,13 +9,13 @@ export const useSetRecordBoardRecordIds = (recordBoardId?: string) => {
scopeId,
recordIdsByColumnIdFamilyState,
columnsFamilySelector,
getColumnIdsState,
columnIdsState,
} = useRecordBoardStates(recordBoardId);
const setRecordIds = useRecoilCallback(
({ set, snapshot }) =>
(records: ObjectRecord[]) => {
const columnIds = snapshot.getLoadable(getColumnIdsState()).getValue();
const columnIds = snapshot.getLoadable(columnIdsState).getValue();
columnIds.forEach((columnId) => {
const column = snapshot
@ -36,7 +36,7 @@ export const useSetRecordBoardRecordIds = (recordBoardId?: string) => {
}
});
},
[columnsFamilySelector, getColumnIdsState, recordIdsByColumnIdFamilyState],
[columnsFamilySelector, columnIdsState, recordIdsByColumnIdFamilyState],
);
return {

View File

@ -7,17 +7,17 @@ import { useSetRecordBoardRecordIds } from '@/object-record/record-board/hooks/i
export const useRecordBoard = (recordBoardId?: string) => {
const {
scopeId,
getFieldDefinitionsState,
getObjectSingularNameState,
getSelectedRecordIdsSelector,
getIsCompactModeActiveState,
getOnFetchMoreVisibilityChangeState,
fieldDefinitionsState,
objectSingularNameState,
selectedRecordIdsSelector,
isCompactModeActiveState,
onFetchMoreVisibilityChangeState,
} = useRecordBoardStates(recordBoardId);
const { setColumns } = useSetRecordBoardColumns(recordBoardId);
const { setRecordIds } = useSetRecordBoardRecordIds(recordBoardId);
const setFieldDefinitions = useSetRecoilState(getFieldDefinitionsState());
const setObjectSingularName = useSetRecoilState(getObjectSingularNameState());
const setFieldDefinitions = useSetRecoilState(fieldDefinitionsState);
const setObjectSingularName = useSetRecoilState(objectSingularNameState);
return {
scopeId,
@ -25,8 +25,8 @@ export const useRecordBoard = (recordBoardId?: string) => {
setRecordIds,
setFieldDefinitions,
setObjectSingularName,
getSelectedRecordIdsSelector,
getIsCompactModeActiveState,
getOnFetchMoreVisibilityChangeState,
selectedRecordIdsSelector,
isCompactModeActiveState,
onFetchMoreVisibilityChangeState,
};
};

View File

@ -3,21 +3,21 @@ import { useRecoilCallback } from 'recoil';
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
export const useRecordBoardSelection = (recordBoardId?: string) => {
const { getSelectedRecordIdsSelector, isRecordBoardCardSelectedFamilyState } =
const { selectedRecordIdsSelector, isRecordBoardCardSelectedFamilyState } =
useRecordBoardStates(recordBoardId);
const resetRecordSelection = useRecoilCallback(
({ snapshot, set }) =>
() => {
const recordIds = snapshot
.getLoadable(getSelectedRecordIdsSelector())
.getLoadable(selectedRecordIdsSelector())
.getValue();
for (const recordId of recordIds) {
set(isRecordBoardCardSelectedFamilyState(recordId), false);
}
},
[getSelectedRecordIdsSelector, isRecordBoardCardSelectedFamilyState],
[selectedRecordIdsSelector, isRecordBoardCardSelectedFamilyState],
);
const setRecordAsSelected = useRecoilCallback(

View File

@ -133,12 +133,12 @@ export const RecordBoardCard = () => {
const { updateOneRecord, objectMetadataItem } =
useContext(RecordBoardContext);
const {
getIsCompactModeActiveState,
isCompactModeActiveState,
isRecordBoardCardSelectedFamilyState,
getVisibleFieldDefinitionsState,
visibleFieldDefinitionsState,
} = useRecordBoardStates();
const isCompactModeActive = useRecoilValue(getIsCompactModeActiveState());
const isCompactModeActive = useRecoilValue(isCompactModeActiveState);
const [isCardInCompactMode, setIsCardInCompactMode] = useState(true);
@ -146,14 +146,14 @@ export const RecordBoardCard = () => {
isRecordBoardCardSelectedFamilyState(recordId),
);
const visibleBoardCardFieldDefinitions = useRecoilValue(
getVisibleFieldDefinitionsState(),
const visibleFieldDefinitions = useRecoilValue(
visibleFieldDefinitionsState(),
);
const record = useRecoilValue(recordStoreFamilyState(recordId));
const setContextMenuPosition = useSetRecoilState(contextMenuPositionState());
const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState());
const setContextMenuPosition = useSetRecoilState(contextMenuPositionState);
const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState);
const handleContextMenu = (event: React.MouseEvent) => {
event.preventDefault();
@ -247,7 +247,7 @@ export const RecordBoardCard = () => {
isOpen={!isCardInCompactMode || !isCompactModeActive}
initial={false}
>
{visibleBoardCardFieldDefinitions.map((fieldDefinition) => (
{visibleFieldDefinitions.map((fieldDefinition) => (
<PreventSelectOnClickContainer
key={fieldDefinition.fieldMetadataId}
>

View File

@ -16,12 +16,12 @@ const StyledText = styled.div`
`;
export const RecordBoardColumnFetchMoreLoader = () => {
const { getIsFetchingRecordState, getOnFetchMoreVisibilityChangeState } =
const { isFetchingRecordState, onFetchMoreVisibilityChangeState } =
useRecordBoardStates();
const isFetchingRecords = useRecoilValue(getIsFetchingRecordState());
const isFetchingRecord = useRecoilValue(isFetchingRecordState);
const onFetchMoreVisibilityChange = useRecoilValue(
getOnFetchMoreVisibilityChangeState(),
onFetchMoreVisibilityChangeState,
);
const { ref } = useInView({
@ -30,7 +30,7 @@ export const RecordBoardColumnFetchMoreLoader = () => {
return (
<div ref={ref}>
{isFetchingRecords && <StyledText>Loading more...</StyledText>}
{isFetchingRecord && <StyledText>Loading more...</StyledText>}
</div>
);
};

View File

@ -20,7 +20,7 @@ export const useClearField = () => {
({ snapshot, set }) =>
() => {
const objectMetadataItems = snapshot
.getLoadable(objectMetadataItemsState())
.getLoadable(objectMetadataItemsState)
.getValue();
const foundObjectMetadataItem = objectMetadataItems.find(

View File

@ -30,9 +30,9 @@ import {
} from '../RelationFieldInput';
const RelationWorkspaceSetterEffect = () => {
const setCurrentWorkspace = useSetRecoilState(currentWorkspaceState());
const setCurrentWorkspace = useSetRecoilState(currentWorkspaceState);
const setCurrentWorkspaceMember = useSetRecoilState(
currentWorkspaceMemberState(),
currentWorkspaceMemberState,
);
useEffect(() => {

View File

@ -35,13 +35,11 @@ export const turnObjectDropdownFilterIntoQueryFilter = (
);
if (!correspondingField) {
throw new Error(
`Could not find field ${rawUIFilter.fieldMetadataId} in metadata object`,
);
continue;
}
if (!isDefined(rawUIFilter.value) || rawUIFilter.value === '') {
return undefined;
continue;
}
switch (rawUIFilter.definition.type) {

View File

@ -28,9 +28,9 @@ export const RecordIndexBoardContainerEffect = ({
const {
setColumns,
setObjectSingularName,
getSelectedRecordIdsSelector,
selectedRecordIdsSelector,
setFieldDefinitions,
getOnFetchMoreVisibilityChangeState,
onFetchMoreVisibilityChangeState,
} = useRecordBoard(recordBoardId);
const { fetchMoreRecords, loading } = useLoadRecordIndexBoard({
@ -40,7 +40,7 @@ export const RecordIndexBoardContainerEffect = ({
});
const setOnFetchMoreVisibilityChange = useSetRecoilState(
getOnFetchMoreVisibilityChangeState(),
onFetchMoreVisibilityChangeState,
);
useEffect(() => {
@ -78,14 +78,14 @@ export const RecordIndexBoardContainerEffect = ({
]);
const recordIndexFieldDefinitions = useRecoilValue(
recordIndexFieldDefinitionsState(),
recordIndexFieldDefinitionsState,
);
useEffect(() => {
setFieldDefinitions(recordIndexFieldDefinitions);
}, [objectMetadataItem, setFieldDefinitions, recordIndexFieldDefinitions]);
const selectedRecordIds = useRecoilValue(getSelectedRecordIdsSelector());
const selectedRecordIds = useRecoilValue(selectedRecordIdsSelector());
const { setActionBarEntries, setContextMenuEntries } = useRecordActionBar({
objectMetadataItem,

View File

@ -47,7 +47,7 @@ export const RecordIndexContainer = ({
objectNamePlural,
}: RecordIndexContainerProps) => {
const [recordIndexViewType, setRecordIndexViewType] = useRecoilState(
recordIndexViewTypeState(),
recordIndexViewTypeState,
);
const { objectNameSingular } = useObjectNameSingularFromPlural({
objectNamePlural,
@ -57,13 +57,13 @@ export const RecordIndexContainer = ({
objectNameSingular,
});
const { columnDefinitions } =
const { columnDefinitions, filterDefinitions, sortDefinitions } =
useColumnDefinitionsFromFieldMetadata(objectMetadataItem);
const setRecordIndexFilters = useSetRecoilState(recordIndexFiltersState());
const setRecordIndexSorts = useSetRecoilState(recordIndexSortsState());
const setRecordIndexFilters = useSetRecoilState(recordIndexFiltersState);
const setRecordIndexSorts = useSetRecoilState(recordIndexSortsState);
const setRecordIndexIsCompactModeActive = useSetRecoilState(
recordIndexIsCompactModeActiveState(),
recordIndexIsCompactModeActiveState,
);
const { setTableFilters, setTableSorts, setTableColumns } = useRecordTable({
@ -85,7 +85,7 @@ export const RecordIndexContainer = ({
);
const existingRecordIndexFieldDefinitions = snapshot
.getLoadable(recordIndexFieldDefinitionsState())
.getLoadable(recordIndexFieldDefinitionsState)
.getValue();
if (
@ -94,10 +94,7 @@ export const RecordIndexContainer = ({
newRecordIndexFieldDefinitions,
)
) {
set(
recordIndexFieldDefinitionsState(),
newRecordIndexFieldDefinitions,
);
set(recordIndexFieldDefinitionsState, newRecordIndexFieldDefinitions);
}
},
[columnDefinitions, setTableColumns],
@ -115,22 +112,26 @@ export const RecordIndexContainer = ({
viewType={recordIndexViewType ?? ViewType.Table}
/>
}
onCurrentViewChange={(view) => {
if (!view) {
return;
}
onViewFieldsChange(view.viewFields);
setTableFilters(
mapViewFiltersToFilters(view.viewFilters, filterDefinitions),
);
setRecordIndexFilters(
mapViewFiltersToFilters(view.viewFilters, filterDefinitions),
);
setTableSorts(mapViewSortsToSorts(view.viewSorts, sortDefinitions));
setRecordIndexSorts(
mapViewSortsToSorts(view.viewSorts, sortDefinitions),
);
setRecordIndexViewType(view.type);
setRecordIndexIsCompactModeActive(view.isCompact);
}}
optionsDropdownScopeId={RECORD_INDEX_OPTIONS_DROPDOWN_ID}
onViewFieldsChange={onViewFieldsChange}
onViewFiltersChange={(viewFilters) => {
setTableFilters(mapViewFiltersToFilters(viewFilters));
setRecordIndexFilters(mapViewFiltersToFilters(viewFilters));
}}
onViewSortsChange={(viewSorts) => {
setTableSorts(mapViewSortsToSorts(viewSorts));
setRecordIndexSorts(mapViewSortsToSorts(viewSorts));
}}
onViewTypeChange={(viewType: ViewType) => {
setRecordIndexViewType(viewType);
}}
onViewCompactModeChange={(isCompactModeActive: boolean) => {
setRecordIndexIsCompactModeActive(isCompactModeActive);
}}
/>
<RecordIndexViewBarEffect
objectNamePlural={objectNamePlural}

View File

@ -5,7 +5,7 @@ import { useColumnDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/u
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { useRecordActionBar } from '@/object-record/record-action-bar/hooks/useRecordActionBar';
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
import { useViewBar } from '@/views/hooks/useViewBar';
import { useSetRecordCountInCurrentView } from '@/views/hooks/useSetRecordCountInCurrentView';
type RecordIndexTableContainerEffectProps = {
objectNameSingular: string;
@ -22,7 +22,7 @@ export const RecordIndexTableContainerEffect = ({
setAvailableTableColumns,
setOnEntityCountChange,
resetTableRowSelection,
getSelectedRowIdsSelector,
selectedRowIdsSelector,
} = useRecordTable({
recordTableId,
});
@ -34,15 +34,14 @@ export const RecordIndexTableContainerEffect = ({
const { columnDefinitions } =
useColumnDefinitionsFromFieldMetadata(objectMetadataItem);
const { setEntityCountInCurrentView } = useViewBar({
viewBarId,
});
const { setRecordCountInCurrentView } =
useSetRecordCountInCurrentView(viewBarId);
useEffect(() => {
setAvailableTableColumns(columnDefinitions);
}, [columnDefinitions, setAvailableTableColumns]);
const selectedRowIds = useRecoilValue(getSelectedRowIdsSelector());
const selectedRowIds = useRecoilValue(selectedRowIdsSelector());
const { setActionBarEntries, setContextMenuEntries } = useRecordActionBar({
objectMetadataItem,
@ -57,9 +56,9 @@ export const RecordIndexTableContainerEffect = ({
useEffect(() => {
setOnEntityCountChange(
() => (entityCount: number) => setEntityCountInCurrentView(entityCount),
() => (entityCount: number) => setRecordCountInCurrentView(entityCount),
);
}, [setEntityCountInCurrentView, setOnEntityCountChange]);
}, [setRecordCountInCurrentView, setOnEntityCountChange]);
return <></>;
};

View File

@ -3,7 +3,7 @@ import { useEffect } from 'react';
import { useColumnDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useColumnDefinitionsFromFieldMetadata';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObjectNameSingularFromPlural';
import { useViewBar } from '@/views/hooks/useViewBar';
import { useInitViewBar } from '@/views/hooks/useInitViewBar';
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
type RecordIndexViewBarEffectProps = {
@ -31,7 +31,7 @@ export const RecordIndexViewBarEffect = ({
setAvailableSortDefinitions,
setAvailableFilterDefinitions,
setAvailableFieldDefinitions,
} = useViewBar({ viewBarId });
} = useInitViewBar(viewBarId);
useEffect(() => {
if (isUndefinedOrNull(objectMetadataItem)) {

View File

@ -11,7 +11,7 @@ import { recordIndexFiltersState } from '@/object-record/record-index/states/rec
import { recordIndexIsCompactModeActiveState } from '@/object-record/record-index/states/recordIndexIsCompactModeActiveState';
import { recordIndexSortsState } from '@/object-record/record-index/states/recordIndexSortsState';
import { useSetRecordInStore } from '@/object-record/record-store/hooks/useSetRecordInStore';
import { useViewBar } from '@/views/hooks/useViewBar';
import { useSetRecordCountInCurrentView } from '@/views/hooks/useSetRecordCountInCurrentView';
type UseLoadRecordIndexBoardProps = {
objectNameSingular: string;
@ -30,19 +30,19 @@ export const useLoadRecordIndexBoard = ({
const {
setRecordIds: setRecordIdsInBoard,
setFieldDefinitions,
getIsCompactModeActiveState,
isCompactModeActiveState,
} = useRecordBoard(recordBoardId);
const { setRecords: setRecordsInStore } = useSetRecordInStore();
const recordIndexFieldDefinitions = useRecoilValue(
recordIndexFieldDefinitionsState(),
recordIndexFieldDefinitionsState,
);
useEffect(() => {
setFieldDefinitions(recordIndexFieldDefinitions);
}, [recordIndexFieldDefinitions, setFieldDefinitions]);
const recordIndexFilters = useRecoilValue(recordIndexFiltersState());
const recordIndexSorts = useRecoilValue(recordIndexSortsState());
const recordIndexFilters = useRecoilValue(recordIndexFiltersState);
const recordIndexSorts = useRecoilValue(recordIndexSortsState);
const requestFilters = turnObjectDropdownFilterIntoQueryFilter(
recordIndexFilters,
objectMetadataItem?.fields ?? [],
@ -53,7 +53,7 @@ export const useLoadRecordIndexBoard = ({
);
const recordIndexIsCompactModeActive = useRecoilValue(
recordIndexIsCompactModeActiveState(),
recordIndexIsCompactModeActiveState,
);
const {
@ -68,13 +68,10 @@ export const useLoadRecordIndexBoard = ({
orderBy,
});
const { setEntityCountInCurrentView } = useViewBar({
viewBarId,
});
const { setRecordCountInCurrentView } =
useSetRecordCountInCurrentView(viewBarId);
const setIsCompactModeActive = useSetRecoilState(
getIsCompactModeActiveState(),
);
const setIsCompactModeActive = useSetRecoilState(isCompactModeActiveState);
useEffect(() => {
setRecordIdsInBoard(records);
@ -85,8 +82,8 @@ export const useLoadRecordIndexBoard = ({
}, [records, setRecordsInStore]);
useEffect(() => {
setEntityCountInCurrentView(totalCount);
}, [totalCount, setEntityCountInCurrentView]);
setRecordCountInCurrentView(totalCount);
}, [totalCount, setRecordCountInCurrentView]);
useEffect(() => {
setIsCompactModeActive(recordIndexIsCompactModeActive);

View File

@ -18,11 +18,11 @@ export const useFindManyParams = (
objectNameSingular,
});
const { getTableFiltersState, getTableSortsState } =
const { tableFiltersState, tableSortsState } =
useRecordTableStates(recordTableId);
const tableFilters = useRecoilValue(getTableFiltersState());
const tableSorts = useRecoilValue(getTableSortsState());
const tableFilters = useRecoilValue(tableFiltersState);
const tableSorts = useRecoilValue(tableSortsState);
const filter = turnObjectDropdownFilterIntoQueryFilter(
tableFilters,
@ -40,9 +40,9 @@ export const useFindManyParams = (
export const useLoadRecordIndexTable = (objectNameSingular: string) => {
const { setRecordTableData, setIsRecordTableInitialLoading } =
useRecordTable();
const { getTableLastRowVisibleState } = useRecordTableStates();
const setLastRowVisible = useSetRecoilState(getTableLastRowVisibleState());
const currentWorkspace = useRecoilValue(currentWorkspaceState());
const { tableLastRowVisibleState } = useRecordTableStates();
const setLastRowVisible = useSetRecoilState(tableLastRowVisibleState);
const currentWorkspace = useRecoilValue(currentWorkspaceState);
const params = useFindManyParams(objectNameSingular);
const {

View File

@ -1,11 +1,9 @@
import { RecordIndexOptionsDropdownButton } from '@/object-record/record-index/options/components/RecordIndexOptionsDropdownButton';
import { RecordIndexOptionsDropdownContent } from '@/object-record/record-index/options/components/RecordIndexOptionsDropdownContent';
import { RECORD_INDEX_OPTIONS_DROPDOWN_ID } from '@/object-record/record-index/options/constants/RecordIndexOptionsDropdownId';
import { useRecordTableStates } from '@/object-record/record-table/hooks/internal/useRecordTableStates';
import { RecordTableScope } from '@/object-record/record-table/scopes/RecordTableScope';
import { TableOptionsHotkeyScope } from '@/object-record/record-table/types/TableOptionsHotkeyScope';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { useViewBar } from '@/views/hooks/useViewBar';
import { useViewBarEditMode } from '@/views/hooks/useViewBarEditMode';
import { ViewType } from '@/views/types/ViewType';
type RecordIndexOptionsDropdownProps = {
@ -19,28 +17,22 @@ export const RecordIndexOptionsDropdown = ({
objectNameSingular,
viewType,
}: RecordIndexOptionsDropdownProps) => {
const { setViewEditMode } = useViewBar();
const { scopeId } = useRecordTableStates(recordIndexId);
const { setViewEditMode } = useViewBarEditMode(recordIndexId);
return (
<RecordTableScope
recordTableScopeId={scopeId}
onColumnsChange={() => false}
>
<Dropdown
dropdownId={RECORD_INDEX_OPTIONS_DROPDOWN_ID}
clickableComponent={<RecordIndexOptionsDropdownButton />}
dropdownHotkeyScope={{ scope: TableOptionsHotkeyScope.Dropdown }}
dropdownOffset={{ y: 8 }}
dropdownComponents={
<RecordIndexOptionsDropdownContent
viewType={viewType}
objectNameSingular={objectNameSingular}
recordIndexId={recordIndexId}
/>
}
onClickOutside={() => setViewEditMode('none')}
/>
</RecordTableScope>
<Dropdown
dropdownId={RECORD_INDEX_OPTIONS_DROPDOWN_ID}
clickableComponent={<RecordIndexOptionsDropdownButton />}
dropdownHotkeyScope={{ scope: TableOptionsHotkeyScope.Dropdown }}
dropdownOffset={{ y: 8 }}
dropdownComponents={
<RecordIndexOptionsDropdownContent
viewType={viewType}
objectNameSingular={objectNameSingular}
recordIndexId={recordIndexId}
/>
}
onClickOutside={() => setViewEditMode('none')}
/>
);
};

View File

@ -1,6 +1,6 @@
import { useRef, useState } from 'react';
import { useRecoilValue } from 'recoil';
import { Key } from 'ts-key-enum';
import { v4 } from 'uuid';
import { RECORD_INDEX_OPTIONS_DROPDOWN_ID } from '@/object-record/record-index/options/constants/RecordIndexOptionsDropdownId';
import { useRecordIndexOptionsForBoard } from '@/object-record/record-index/options/hooks/useRecordIndexOptionsForBoard';
@ -22,8 +22,9 @@ import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
import { MenuItemToggle } from '@/ui/navigation/menu-item/components/MenuItemToggle';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { ViewFieldsVisibilityDropdownSection } from '@/views/components/ViewFieldsVisibilityDropdownSection';
import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates';
import { useViewBar } from '@/views/hooks/useViewBar';
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
import { useHandleViews } from '@/views/hooks/useHandleViews';
import { useViewBarEditMode } from '@/views/hooks/useViewBarEditMode';
import { ViewType } from '@/views/types/ViewType';
type RecordIndexOptionsMenu = 'fields';
@ -39,13 +40,11 @@ export const RecordIndexOptionsDropdownContent = ({
recordIndexId,
objectNameSingular,
}: RecordIndexOptionsDropdownContentProps) => {
const { setViewEditMode, handleViewNameSubmit } = useViewBar({
viewBarId: recordIndexId,
});
const { viewEditModeState, currentViewSelector } = useViewScopedStates();
const { updateCurrentView, createEmptyView, selectView } =
useHandleViews(recordIndexId);
const { viewEditMode, setViewEditMode } = useViewBarEditMode(recordIndexId);
const { currentViewWithCombinedFiltersAndSorts } = useGetCurrentView();
const viewEditMode = useRecoilValue(viewEditModeState);
const currentView = useRecoilValue(currentViewSelector);
const { closeDropdown } = useDropdown(RECORD_INDEX_OPTIONS_DROPDOWN_ID);
const [currentMenu, setCurrentMenu] = useState<
@ -70,9 +69,16 @@ export const RecordIndexOptionsDropdownContent = ({
useScopedHotkeys(
Key.Enter,
() => {
async () => {
const name = viewEditInputRef.current?.value;
handleViewNameSubmit(name);
if (viewEditMode === 'create') {
const id = v4();
await createEmptyView(id, name ?? '');
selectView(id);
} else {
updateCurrentView({ name });
}
resetMenu();
setViewEditMode('none');
closeDropdown();
@ -133,7 +139,11 @@ export const RecordIndexOptionsDropdownContent = ({
? 'View name'
: ''
}
defaultValue={viewEditMode === 'create' ? '' : currentView?.name}
defaultValue={
viewEditMode === 'create'
? ''
: currentViewWithCombinedFiltersAndSorts?.name
}
/>
<DropdownMenuSeparator />
<DropdownMenuItemsContainer>
@ -185,7 +195,7 @@ export const RecordIndexOptionsDropdownContent = ({
onToggleChange={() =>
setAndPersistIsCompactModeActive(
!isCompactModeActive,
currentView,
currentViewWithCombinedFiltersAndSorts,
)
}
toggled={isCompactModeActive}

View File

@ -109,11 +109,11 @@ export const useExportTableData = ({
const [progress, setProgress] = useState<number | undefined>(undefined);
const [hasNextPage, setHasNextPage] = useState(true);
const { getVisibleTableColumnsSelector, getSelectedRowIdsSelector } =
const { visibleTableColumnsSelector, selectedRowIdsSelector } =
useRecordTableStates(recordIndexId);
const columns = useRecoilValue(getVisibleTableColumnsSelector());
const selectedRowIds = useRecoilValue(getSelectedRowIdsSelector());
const columns = useRecoilValue(visibleTableColumnsSelector());
const selectedRowIds = useRecoilValue(selectedRowIdsSelector());
const hasSelectedRows = selectedRowIds.length > 0;

View File

@ -8,8 +8,8 @@ import { useRecordBoard } from '@/object-record/record-board/hooks/useRecordBoar
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
import { recordIndexFieldDefinitionsState } from '@/object-record/record-index/states/recordIndexFieldDefinitionsState';
import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
import { useViewFields } from '@/views/hooks/internal/useViewFields';
import { useViews } from '@/views/hooks/internal/useViews';
import { useHandleViews } from '@/views/hooks/useHandleViews';
import { useSaveCurrentViewFields } from '@/views/hooks/useSaveCurrentViewFields';
import { GraphQLView } from '@/views/types/GraphQLView';
import { mapBoardFieldDefinitionsToViewFields } from '@/views/utils/mapBoardFieldDefinitionsToViewFields';
import { mapArrayToObject } from '~/utils/array/mapArrayToObject';
@ -28,14 +28,14 @@ export const useRecordIndexOptionsForBoard = ({
viewBarId,
}: useRecordIndexOptionsForBoardParams) => {
const [recordIndexFieldDefinitions, setRecordIndexFieldDefinitions] =
useRecoilState(recordIndexFieldDefinitionsState());
useRecoilState(recordIndexFieldDefinitionsState);
const { persistViewFields } = useViewFields(viewBarId);
const { updateView } = useViews(viewBarId);
const { getIsCompactModeActiveState } = useRecordBoard(recordBoardId);
const { saveViewFields } = useSaveCurrentViewFields(viewBarId);
const { updateCurrentView } = useHandleViews(viewBarId);
const { isCompactModeActiveState } = useRecordBoard(recordBoardId);
const [isCompactModeActive, setIsCompactModeActive] = useRecoilState(
getIsCompactModeActiveState(),
isCompactModeActiveState,
);
const { objectMetadataItem } = useObjectMetadataItemOnly({
@ -105,20 +105,14 @@ export const useRecordIndexOptionsForBoard = ({
if (isDeeplyEqual(visibleBoardFields, reorderedVisibleBoardFields))
return;
const updatedFields = [
...reorderedVisibleBoardFields,
...hiddenBoardFields,
].map((field, index) => ({ ...field, position: index }));
const updatedFields = [...reorderedVisibleBoardFields].map(
(field, index) => ({ ...field, position: index }),
);
setRecordIndexFieldDefinitions(updatedFields);
persistViewFields(mapBoardFieldDefinitionsToViewFields(updatedFields));
saveViewFields(mapBoardFieldDefinitionsToViewFields(updatedFields));
},
[
hiddenBoardFields,
persistViewFields,
setRecordIndexFieldDefinitions,
visibleBoardFields,
],
[saveViewFields, setRecordIndexFieldDefinitions, visibleBoardFields],
);
// Todo : this seems over complex and should at least be extracted to an util with unit test.
@ -172,14 +166,14 @@ export const useRecordIndexOptionsForBoard = ({
setRecordIndexFieldDefinitions(updatedFieldsDefinitions);
persistViewFields(
saveViewFields(
mapBoardFieldDefinitionsToViewFields(updatedFieldsDefinitions),
);
},
[
recordIndexFieldDefinitionsByKey,
setRecordIndexFieldDefinitions,
persistViewFields,
saveViewFields,
availableColumnDefinitions,
visibleBoardFields,
recordIndexFieldDefinitions,
@ -190,12 +184,11 @@ export const useRecordIndexOptionsForBoard = ({
(isCompactModeActive: boolean, view: GraphQLView | undefined) => {
if (!view) return;
setIsCompactModeActive(isCompactModeActive);
updateView({
...view,
updateCurrentView({
isCompact: isCompactModeActive,
});
},
[setIsCompactModeActive, updateView],
[setIsCompactModeActive, updateCurrentView],
);
return {

View File

@ -7,11 +7,11 @@ import { useTableColumns } from '@/object-record/record-table/hooks/useTableColu
import { moveArrayItem } from '~/utils/array/moveArrayItem';
export const useRecordIndexOptionsForTable = (recordTableId: string) => {
const { getHiddenTableColumnsSelector, getVisibleTableColumnsSelector } =
const { hiddenTableColumnsSelector, visibleTableColumnsSelector } =
useRecordTableStates(recordTableId);
const hiddenTableColumns = useRecoilValue(getHiddenTableColumnsSelector());
const visibleTableColumns = useRecoilValue(getVisibleTableColumnsSelector());
const hiddenTableColumns = useRecoilValue(hiddenTableColumnsSelector());
const visibleTableColumns = useRecoilValue(visibleTableColumnsSelector());
const { handleColumnVisibilityChange, handleColumnReorder } = useTableColumns(
{ recordTableId: recordTableId },

View File

@ -24,7 +24,7 @@ import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
import { FilterQueryParams } from '@/views/hooks/internal/useFiltersFromQueryParams';
import { FilterQueryParams } from '@/views/hooks/internal/useViewFromQueryParams';
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
const StyledAddDropdown = styled(Dropdown)`

View File

@ -17,7 +17,7 @@ export const recordStoreIdentifierFamilySelector = selectorFamily({
({ get }) => {
const recordFromStore = get(recordStoreFamilyState(recordId));
const objectMetadataItems = get(objectMetadataItemsState());
const objectMetadataItems = get(objectMetadataItemsState);
const objectMetadataItem = objectMetadataItems.find(
(item) => item.nameSingular === objectNameSingular,

View File

@ -8,9 +8,9 @@ export const RecordTableActionBar = ({
}: {
recordTableId: string;
}) => {
const { getSelectedRowIdsSelector } = useRecordTableStates(recordTableId);
const { selectedRowIdsSelector } = useRecordTableStates(recordTableId);
const selectedRowIds = useRecoilValue(getSelectedRowIdsSelector());
const selectedRowIds = useRecoilValue(selectedRowIdsSelector());
if (!selectedRowIds.length) {
return null;

View File

@ -22,7 +22,7 @@ const StyledContainer = styled.div`
export const CheckboxCell = () => {
const { recordId } = useContext(RecordTableRowContext);
const { isRowSelectedFamilyState } = useRecordTableStates();
const setActionBarOpenState = useSetRecoilState(actionBarOpenState());
const setActionBarOpenState = useSetRecoilState(actionBarOpenState);
const { setCurrentRowSelected } = useSetCurrentRowSelected();
const currentRowSelected = useRecoilValue(isRowSelectedFamilyState(recordId));

View File

@ -53,7 +53,7 @@ export const ColumnHead = ({ column }: ColumnHeadProps) => {
const { getIcon } = useIcons();
const Icon = getIcon(column.iconName);
const scrollLeft = useRecoilValue(scrollLeftState());
const scrollLeft = useRecoilValue(scrollLeftState);
return (
<StyledTitle hideTitle={!!column.isLabelIdentifier && scrollLeft > 0}>

View File

@ -122,7 +122,7 @@ export const RecordTable = ({
createRecord,
}: RecordTableProps) => {
const { scopeId } = useRecordTableStates(recordTableId);
const scrollLeft = useRecoilValue(scrollLeftState());
const scrollLeft = useRecoilValue(scrollLeftState);
const { objectMetadataItem } = useObjectMetadataItemOnly({
objectNameSingular,

View File

@ -11,9 +11,9 @@ type RecordTableBodyProps = {
export const RecordTableBody = ({
objectNameSingular,
}: RecordTableBodyProps) => {
const { getTableRowIdsState } = useRecordTableStates();
const { tableRowIdsState } = useRecordTableStates();
const tableRowIds = useRecoilValue(getTableRowIdsState());
const tableRowIds = useRecoilValue(tableRowIdsState);
return (
<>

View File

@ -21,10 +21,10 @@ export const RecordTableBodyEffect = ({
loading,
} = useLoadRecordIndexTable(objectNameSingular);
const { getTableLastRowVisibleState } = useRecordTableStates();
const { tableLastRowVisibleState } = useRecordTableStates();
const [tableLastRowVisible, setTableLastRowVisible] = useRecoilState(
getTableLastRowVisibleState(),
tableLastRowVisibleState,
);
const isFetchingMoreObjects = useRecoilValue(

View File

@ -23,8 +23,8 @@ const StyledContainer = styled.td<{ isSelected: boolean }>`
`;
export const RecordTableCellContainer = () => {
const setContextMenuPosition = useSetRecoilState(contextMenuPositionState());
const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState());
const setContextMenuPosition = useSetRecoilState(contextMenuPositionState);
const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState);
const { setCurrentRowSelected } = useSetCurrentRowSelected();

View File

@ -17,9 +17,9 @@ export type RecordTableColumnDropdownMenuProps = {
export const RecordTableColumnDropdownMenu = ({
column,
}: RecordTableColumnDropdownMenuProps) => {
const { getVisibleTableColumnsSelector } = useRecordTableStates();
const { visibleTableColumnsSelector } = useRecordTableStates();
const visibleTableColumns = useRecoilValue(getVisibleTableColumnsSelector());
const visibleTableColumns = useRecoilValue(visibleTableColumnsSelector());
const secondVisibleColumn = visibleTableColumns[1];
const canMoveLeft =

View File

@ -56,16 +56,15 @@ export const RecordTableHeader = ({
}: {
createRecord: () => void;
}) => {
const { getHiddenTableColumnsSelector, getVisibleTableColumnsSelector } =
useRecordTableStates();
const { visibleTableColumnsSelector } = useRecordTableStates();
const scrollWrapper = useScrollWrapperScopedRef();
const isTableWiderThanScreen =
(scrollWrapper.current?.clientWidth ?? 0) <
(scrollWrapper.current?.scrollWidth ?? 0);
const visibleTableColumns = useRecoilValue(getVisibleTableColumnsSelector());
const hiddenTableColumns = useRecoilValue(getHiddenTableColumnsSelector());
const visibleTableColumns = useRecoilValue(visibleTableColumnsSelector());
const hiddenTableColumns = useRecoilValue(visibleTableColumnsSelector());
const theme = useTheme();

View File

@ -82,14 +82,13 @@ export const RecordTableHeaderCell = ({
column: ColumnDefinition<FieldMetadata>;
createRecord: () => void;
}) => {
const { getResizeFieldOffsetState, getTableColumnsState } =
useRecordTableStates();
const { resizeFieldOffsetState, tableColumnsState } = useRecordTableStates();
const [resizeFieldOffset, setResizeFieldOffset] = useRecoilState(
getResizeFieldOffsetState(),
resizeFieldOffsetState,
);
const tableColumns = useRecoilValue(getTableColumnsState());
const tableColumns = useRecoilValue(tableColumnsState);
const tableColumnsByKey = useMemo(
() =>
mapArrayToObject(tableColumns, ({ fieldMetadataId }) => fieldMetadataId),
@ -124,7 +123,7 @@ export const RecordTableHeaderCell = ({
const resizeFieldOffset = getSnapshotValue(
snapshot,
getResizeFieldOffsetState(),
resizeFieldOffsetState,
);
const nextWidth = Math.round(
@ -134,7 +133,7 @@ export const RecordTableHeaderCell = ({
),
);
set(getResizeFieldOffsetState(), 0);
set(resizeFieldOffsetState, 0);
setInitialPointerPositionX(null);
setResizedFieldKey(null);
@ -150,7 +149,7 @@ export const RecordTableHeaderCell = ({
},
[
resizedFieldKey,
getResizeFieldOffsetState,
resizeFieldOffsetState,
tableColumnsByKey,
tableColumns,
handleColumnsChange,
@ -165,7 +164,7 @@ export const RecordTableHeaderCell = ({
});
const isMobile = useIsMobile();
const scrollLeft = useRecoilValue(scrollLeftState());
const scrollLeft = useRecoilValue(scrollLeftState);
const disableColumnResize =
column.isLabelIdentifier && isMobile && scrollLeft > 0;

View File

@ -17,9 +17,9 @@ import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
export const RecordTableHeaderPlusButtonContent = () => {
const { closeDropdown } = useDropdown();
const { getHiddenTableColumnsSelector } = useRecordTableStates();
const { hiddenTableColumnsSelector } = useRecordTableStates();
const hiddenTableColumns = useRecoilValue(getHiddenTableColumnsSelector());
const hiddenTableColumns = useRecoilValue(hiddenTableColumnsSelector());
const { getIcon } = useIcons();
const { handleColumnVisibilityChange } = useTableColumns();

View File

@ -23,12 +23,12 @@ const StyledTd = styled.td`
`;
export const RecordTableRow = ({ recordId, rowIndex }: RecordTableRowProps) => {
const { getVisibleTableColumnsSelector, isRowSelectedFamilyState } =
const { visibleTableColumnsSelector, isRowSelectedFamilyState } =
useRecordTableStates();
const currentRowSelected = useRecoilValue(isRowSelectedFamilyState(recordId));
const { objectMetadataItem } = useContext(RecordTableContext);
const visibleTableColumns = useRecoilValue(getVisibleTableColumnsSelector());
const visibleTableColumns = useRecoilValue(visibleTableColumnsSelector());
const scrollWrapperRef = useContext(ScrollWrapperContext);

View File

@ -20,7 +20,7 @@ import {
} from '@/ui/layout/animated-placeholder/components/EmptyPlaceholderStyled';
import { DragSelect } from '@/ui/utilities/drag-select/components/DragSelect';
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
import { useViewFields } from '@/views/hooks/internal/useViewFields';
import { useSaveCurrentViewFields } from '@/views/hooks/useSaveCurrentViewFields';
import { mapColumnDefinitionsToViewFields } from '@/views/utils/mapColumnDefinitionToViewField';
import { RecordUpdateContext } from '../contexts/EntityUpdateMutationHookContext';
@ -59,13 +59,13 @@ export const RecordTableWithWrappers = ({
}: RecordTableWithWrappersProps) => {
const tableBodyRef = useRef<HTMLDivElement>(null);
const { getNumberOfTableRowsState, getIsRecordTableInitialLoadingState } =
const { numberOfTableRowsState, isRecordTableInitialLoadingState } =
useRecordTableStates(recordTableId);
const numberOfTableRows = useRecoilValue(getNumberOfTableRowsState());
const numberOfTableRows = useRecoilValue(numberOfTableRowsState);
const isRecordTableInitialLoading = useRecoilValue(
getIsRecordTableInitialLoadingState(),
isRecordTableInitialLoadingState,
);
const { resetTableRowSelection, setRowSelectedState } = useRecordTable({
@ -78,7 +78,7 @@ export const RecordTableWithWrappers = ({
},
);
const { persistViewFields } = useViewFields(viewBarId);
const { saveViewFields } = useSaveCurrentViewFields(viewBarId);
const { deleteOneRecord } = useDeleteOneRecord({ objectNameSingular });
@ -96,13 +96,13 @@ export const RecordTableWithWrappers = ({
objectNameSingular={objectNameSingular}
onColumnsChange={useRecoilCallback(
() => (columns) => {
persistViewFields(
saveViewFields(
mapColumnDefinitionsToViewFields(
columns as ColumnDefinition<FieldMetadata>[],
),
);
},
[persistViewFields],
[saveViewFields],
)}
createRecord={createRecord}
/>

View File

@ -17,11 +17,9 @@ const StyledContainer = styled.div`
`;
export const SelectAllCheckbox = () => {
const { getAllRowsSelectedStatusSelector } = useRecordTableStates();
const { allRowsSelectedStatusSelector } = useRecordTableStates();
const allRowsSelectedStatus = useRecoilValue(
getAllRowsSelectedStatusSelector(),
);
const allRowsSelectedStatus = useRecoilValue(allRowsSelectedStatusSelector());
const { selectAllRows } = useRecordTable();
const checked = allRowsSelectedStatus === 'all';

View File

@ -8,9 +8,9 @@ export const RecordTableContextMenu = ({
}: {
recordTableId: string;
}) => {
const { getSelectedRowIdsSelector } = useRecordTableStates(recordTableId);
const { selectedRowIdsSelector } = useRecordTableStates(recordTableId);
const selectedRowIds = useRecoilValue(getSelectedRowIdsSelector());
const selectedRowIds = useRecoilValue(selectedRowIdsSelector());
if (!selectedRowIds.length) {
return null;

View File

@ -5,7 +5,7 @@ import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotV
export const useCloseCurrentTableCellInEditMode = (recordTableId?: string) => {
const {
getCurrentTableCellInEditModePositionState,
currentTableCellInEditModePositionState,
isTableCellInEditModeFamilyState,
} = useRecordTableStates(recordTableId);
@ -14,7 +14,7 @@ export const useCloseCurrentTableCellInEditMode = (recordTableId?: string) => {
return async () => {
const currentTableCellInEditModePosition = getSnapshotValue(
snapshot,
getCurrentTableCellInEditModePositionState(),
currentTableCellInEditModePositionState,
);
set(
@ -23,9 +23,6 @@ export const useCloseCurrentTableCellInEditMode = (recordTableId?: string) => {
);
};
},
[
getCurrentTableCellInEditModePositionState,
isTableCellInEditModeFamilyState,
],
[currentTableCellInEditModePositionState, isTableCellInEditModeFamilyState],
);
};

View File

@ -5,8 +5,8 @@ import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotV
export const useDisableSoftFocus = (recordTableId?: string) => {
const {
getSoftFocusPositionState,
getIsSoftFocusActiveState,
softFocusPositionState,
isSoftFocusActiveState,
isSoftFocusOnTableCellFamilyState,
} = useRecordTableStates(recordTableId);
@ -15,17 +15,17 @@ export const useDisableSoftFocus = (recordTableId?: string) => {
return () => {
const currentPosition = getSnapshotValue(
snapshot,
getSoftFocusPositionState(),
softFocusPositionState,
);
set(getIsSoftFocusActiveState(), false);
set(isSoftFocusActiveState, false);
set(isSoftFocusOnTableCellFamilyState(currentPosition), false);
};
},
[
getIsSoftFocusActiveState,
getSoftFocusPositionState,
isSoftFocusActiveState,
softFocusPositionState,
isSoftFocusOnTableCellFamilyState,
],
);

View File

@ -5,7 +5,7 @@ import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotV
export const useGetIsSomeCellInEditModeState = (recordTableId?: string) => {
const {
getCurrentTableCellInEditModePositionState,
currentTableCellInEditModePositionState,
isTableCellInEditModeFamilyState,
} = useRecordTableStates(recordTableId);
@ -14,7 +14,7 @@ export const useGetIsSomeCellInEditModeState = (recordTableId?: string) => {
() => {
const currentTableCellInEditModePosition = getSnapshotValue(
snapshot,
getCurrentTableCellInEditModePositionState(),
currentTableCellInEditModePositionState,
);
const isSomeCellInEditModeState = isTableCellInEditModeFamilyState(
@ -23,9 +23,6 @@ export const useGetIsSomeCellInEditModeState = (recordTableId?: string) => {
return isSomeCellInEditModeState;
},
[
getCurrentTableCellInEditModePositionState,
isTableCellInEditModeFamilyState,
],
[currentTableCellInEditModePositionState, isTableCellInEditModeFamilyState],
);
};

View File

@ -14,18 +14,18 @@ export const useLeaveTableFocus = (recordTableId?: string) => {
const closeCurrentCellInEditMode =
useCloseCurrentTableCellInEditMode(recordTableId);
const { getIsSoftFocusActiveState } = useRecordTableStates(recordTableId);
const { isSoftFocusActiveState } = useRecordTableStates(recordTableId);
return useRecoilCallback(
({ snapshot }) =>
() => {
const isSoftFocusActive = getSnapshotValue(
snapshot,
getIsSoftFocusActiveState(),
isSoftFocusActiveState,
);
const currentHotkeyScope = snapshot
.getLoadable(currentHotkeyScopeState())
.getLoadable(currentHotkeyScopeState)
.getValue();
if (!isSoftFocusActive) {
@ -39,6 +39,6 @@ export const useLeaveTableFocus = (recordTableId?: string) => {
closeCurrentCellInEditMode();
disableSoftFocus();
},
[closeCurrentCellInEditMode, disableSoftFocus, getIsSoftFocusActiveState],
[closeCurrentCellInEditMode, disableSoftFocus, isSoftFocusActiveState],
);
};

View File

@ -8,7 +8,7 @@ import { TableCellPosition } from '../../types/TableCellPosition';
export const useMoveEditModeToTableCellPosition = (recordTableId?: string) => {
const {
isTableCellInEditModeFamilyState,
getCurrentTableCellInEditModePositionState,
currentTableCellInEditModePositionState,
} = useRecordTableStates(recordTableId);
return useRecoilCallback(
@ -16,7 +16,7 @@ export const useMoveEditModeToTableCellPosition = (recordTableId?: string) => {
return (newPosition: TableCellPosition) => {
const currentTableCellInEditModePosition = getSnapshotValue(
snapshot,
getCurrentTableCellInEditModePositionState(),
currentTableCellInEditModePositionState,
);
set(
@ -24,14 +24,11 @@ export const useMoveEditModeToTableCellPosition = (recordTableId?: string) => {
false,
);
set(getCurrentTableCellInEditModePositionState(), newPosition);
set(currentTableCellInEditModePositionState, newPosition);
set(isTableCellInEditModeFamilyState(newPosition), true);
};
},
[
getCurrentTableCellInEditModePositionState,
isTableCellInEditModeFamilyState,
],
[currentTableCellInEditModePositionState, isTableCellInEditModeFamilyState],
);
};

View File

@ -35,44 +35,41 @@ export const useRecordTableStates = (recordTableId?: string) => {
return {
scopeId,
getAvailableTableColumnsState: extractComponentState(
availableTableColumnsState: extractComponentState(
availableTableColumnsComponentState,
scopeId,
),
getTableFiltersState: extractComponentState(
tableFiltersState: extractComponentState(
tableFiltersComponentState,
scopeId,
),
getTableSortsState: extractComponentState(
tableSortsComponentState,
scopeId,
),
getTableColumnsState: extractComponentState(
tableSortsState: extractComponentState(tableSortsComponentState, scopeId),
tableColumnsState: extractComponentState(
tableColumnsComponentState,
scopeId,
),
getOnColumnsChangeState: extractComponentState(
onColumnsChangeState: extractComponentState(
onColumnsChangeComponentState,
scopeId,
),
getOnEntityCountChangeState: extractComponentState(
onEntityCountChangeState: extractComponentState(
onEntityCountChangeComponentState,
scopeId,
),
getTableLastRowVisibleState: extractComponentState(
tableLastRowVisibleState: extractComponentState(
tableLastRowVisibleComponentState,
scopeId,
),
getSoftFocusPositionState: extractComponentState(
softFocusPositionState: extractComponentState(
softFocusPositionComponentState,
scopeId,
),
getNumberOfTableRowsState: extractComponentState(
numberOfTableRowsState: extractComponentState(
numberOfTableRowsComponentState,
scopeId,
),
getCurrentTableCellInEditModePositionState: extractComponentState(
currentTableCellInEditModePositionState: extractComponentState(
currentTableCellInEditModePositionComponentState,
scopeId,
),
@ -80,19 +77,16 @@ export const useRecordTableStates = (recordTableId?: string) => {
isTableCellInEditModeComponentFamilyState,
scopeId,
),
getIsSoftFocusActiveState: extractComponentState(
isSoftFocusActiveState: extractComponentState(
isSoftFocusActiveComponentState,
scopeId,
),
getTableRowIdsState: extractComponentState(
tableRowIdsComponentState,
scopeId,
),
getIsRecordTableInitialLoadingState: extractComponentState(
tableRowIdsState: extractComponentState(tableRowIdsComponentState, scopeId),
isRecordTableInitialLoadingState: extractComponentState(
isRecordTableInitialLoadingComponentState,
scopeId,
),
getResizeFieldOffsetState: extractComponentState(
resizeFieldOffsetState: extractComponentState(
resizeFieldOffsetComponentState,
scopeId,
),
@ -104,23 +98,23 @@ export const useRecordTableStates = (recordTableId?: string) => {
isRowSelectedComponentFamilyState,
scopeId,
),
getAllRowsSelectedStatusSelector: extractComponentReadOnlySelector(
allRowsSelectedStatusSelector: extractComponentReadOnlySelector(
allRowsSelectedStatusComponentSelector,
scopeId,
),
getHiddenTableColumnsSelector: extractComponentReadOnlySelector(
hiddenTableColumnsSelector: extractComponentReadOnlySelector(
hiddenTableColumnsComponentSelector,
scopeId,
),
getNumberOfTableColumnsSelector: extractComponentReadOnlySelector(
numberOfTableColumnsSelector: extractComponentReadOnlySelector(
numberOfTableColumnsComponentSelector,
scopeId,
),
getSelectedRowIdsSelector: extractComponentReadOnlySelector(
selectedRowIdsSelector: extractComponentReadOnlySelector(
selectedRowIdsComponentSelector,
scopeId,
),
getVisibleTableColumnsSelector: extractComponentReadOnlySelector(
visibleTableColumnsSelector: extractComponentReadOnlySelector(
visibleTableColumnsComponentSelector,
scopeId,
),

Some files were not shown because too many files have changed in this diff Show More