Feat/multi relation filter (#2858)

* WIP

* Finished multi select filter

* Cleaned console log

* Fix naming

* Fixed naming
This commit is contained in:
Lucas Bordeau
2023-12-07 12:08:48 +01:00
committed by GitHub
parent b2912f4b4b
commit 06936c3c2a
18 changed files with 516 additions and 93 deletions

View File

@ -12,7 +12,9 @@ import { useGenerateFindOneRecordQuery } from '@/object-record/hooks/useGenerate
import { useGenerateUpdateOneRecordMutation } from '@/object-record/hooks/useGenerateUpdateOneRecordMutation';
import { useGetRecordFromCache } from '@/object-record/hooks/useGetRecordFromCache';
import { useModifyRecordFromCache } from '@/object-record/hooks/useModifyRecordFromCache';
import { ObjectRecordIdentifier } from '@/object-record/types/ObjectRecordIdentifier';
import { generateDeleteOneRecordMutation } from '@/object-record/utils/generateDeleteOneRecordMutation';
import { getLogoUrlFromDomainName } from '~/utils';
import { isDefined } from '~/utils/isDefined';
import { ObjectMetadataItemIdentifier } from '../types/ObjectMetadataItemIdentifier';
@ -61,6 +63,43 @@ export const useObjectMetadataItem = (
);
}
const mapToObjectRecordIdentifier = (record: any): ObjectRecordIdentifier => {
if (objectNameSingular === 'company') {
return {
id: record.id,
name: record.name,
avatarUrl: getLogoUrlFromDomainName(record.domainName ?? ''),
avatarType: 'squared',
};
}
if (['workspaceMember', 'person'].includes(objectNameSingular)) {
return {
id: record.id,
name:
(record.name?.firstName ?? '') + ' ' + (record.name?.lastName ?? ''),
avatarUrl: record.avatarUrl,
avatarType: 'rounded',
};
}
if (['opportunity'].includes(objectNameSingular)) {
return {
id: record.id,
name: record?.company?.name,
avatarUrl: record.avatarUrl,
avatarType: 'rounded',
};
}
return {
id: record.id,
name: record.name,
avatarUrl: record.avatarUrl,
avatarType: 'rounded',
};
};
const getRecordFromCache = useGetRecordFromCache({
objectMetadataItem,
});
@ -108,5 +147,6 @@ export const useObjectMetadataItem = (
createOneRecordMutation,
updateOneRecordMutation,
deleteOneRecordMutation,
mapToObjectRecordIdentifier,
};
};

View File

@ -0,0 +1,85 @@
import { useEffect, useState } from 'react';
import { SelectableRecord } from '@/object-record/select/types/SelectableRecord';
import { DropdownMenuSkeletonItem } from '@/ui/input/relation-picker/components/skeletons/DropdownMenuSkeletonItem';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
import { MenuItemMultiSelectAvatar } from '@/ui/navigation/menu-item/components/MenuItemMultiSelectAvatar';
import { Avatar } from '@/users/components/Avatar';
export const MultipleRecordSelectDropdown = ({
recordsToSelect,
loadingRecords,
filteredSelectedRecords,
onChange,
searchFilter,
}: {
recordsToSelect: SelectableRecord[];
filteredSelectedRecords: SelectableRecord[];
selectedRecords: SelectableRecord[];
searchFilter: string;
onChange: (
changedRecordToSelect: SelectableRecord,
newSelectedValue: boolean,
) => void;
loadingRecords: boolean;
}) => {
const handleRecordSelectChange = (
recordToSelect: SelectableRecord,
newSelectedValue: boolean,
) => {
onChange(
{
...recordToSelect,
isSelected: newSelectedValue,
},
newSelectedValue,
);
};
const [recordsInDropdown, setRecordInDropdown] = useState([
...(filteredSelectedRecords ?? []),
...(recordsToSelect ?? []),
]);
useEffect(() => {
if (!loadingRecords) {
setRecordInDropdown([
...(filteredSelectedRecords ?? []),
...(recordsToSelect ?? []),
]);
}
}, [recordsToSelect, filteredSelectedRecords, loadingRecords]);
const showNoResult =
recordsToSelect?.length === 0 &&
searchFilter !== '' &&
filteredSelectedRecords?.length === 0 &&
!loadingRecords;
return (
<DropdownMenuItemsContainer hasMaxHeight>
{recordsInDropdown?.map((record) => (
<MenuItemMultiSelectAvatar
key={record.id}
selected={record.isSelected}
onSelectChange={(newCheckedValue) =>
handleRecordSelectChange(record, newCheckedValue)
}
avatar={
<Avatar
avatarUrl={record.avatarUrl}
colorId={record.id}
placeholder={record.name}
size="md"
type={record.avatarType ?? 'rounded'}
/>
}
text={record.name}
/>
))}
{showNoResult && <MenuItem text="No result" />}
{loadingRecords && <DropdownMenuSkeletonItem />}
</DropdownMenuItemsContainer>
);
};

View File

@ -0,0 +1,159 @@
import { isNonEmptyString } from '@sniptt/guards';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
import { SelectableRecord } from '@/object-record/select/types/SelectableRecord';
import { getObjectFilterFields } from '@/object-record/select/utils/getObjectFilterFields';
import { getObjectOrderByField } from '@/object-record/select/utils/getObjectOrderByField';
import { isDefined } from '~/utils/isDefined';
export type OrderBy =
| 'AscNullsLast'
| 'DescNullsLast'
| 'AscNullsFirst'
| 'DescNullsFirst';
export const DEFAULT_SEARCH_REQUEST_LIMIT = 60;
export const useRecordsForSelect = ({
searchFilterText,
sortOrder = 'AscNullsLast',
selectedIds,
limit,
excludeEntityIds = [],
objectNameSingular,
}: {
searchFilterText: string;
sortOrder?: OrderBy;
selectedIds: string[];
limit?: number;
excludeEntityIds?: string[];
objectNameSingular: string;
}) => {
const { mapToObjectRecordIdentifier } = useObjectMetadataItem({
objectNameSingular,
});
const filters = [
{
fieldNames: getObjectFilterFields(objectNameSingular) ?? [],
filter: searchFilterText,
},
];
const orderByField = getObjectOrderByField(objectNameSingular);
const { loading: selectedRecordsLoading, records: selectedRecordsData } =
useFindManyRecords({
filter: {
id: {
in: selectedIds,
},
},
orderBy: {
[orderByField]: sortOrder,
},
objectNameSingular,
});
const searchFilter = filters
.map(({ fieldNames, filter }) => {
if (!isNonEmptyString(filter)) {
return undefined;
}
return {
or: fieldNames.map((fieldName) => {
const fieldNameParts = fieldName.split('.');
if (fieldNameParts.length > 1) {
// Composite field
return {
[fieldNameParts[0]]: {
[fieldNameParts[1]]: {
ilike: `%${filter}%`,
},
},
};
}
return {
[fieldName]: {
ilike: `%${filter}%`,
},
};
}),
};
})
.filter(isDefined);
const {
loading: filteredSelectedRecordsLoading,
records: filteredSelectedRecordsData,
} = useFindManyRecords({
filter: {
and: [
{
and: searchFilter,
},
{
id: {
in: selectedIds,
},
},
],
},
orderBy: {
[orderByField]: sortOrder,
},
objectNameSingular,
});
const { loading: recordsToSelectLoading, records: recordsToSelectData } =
useFindManyRecords({
filter: {
and: [
{
and: searchFilter,
},
{
not: {
id: {
in: [...selectedIds, ...excludeEntityIds],
},
},
},
],
},
limit: limit ?? DEFAULT_SEARCH_REQUEST_LIMIT,
orderBy: {
[orderByField]: sortOrder,
},
objectNameSingular,
});
return {
selectedRecords: selectedRecordsData
.map(mapToObjectRecordIdentifier)
.map((record) => ({
...record,
isSelected: true,
})) as SelectableRecord[],
filteredSelectedRecords: filteredSelectedRecordsData
.map(mapToObjectRecordIdentifier)
.map((record) => ({
...record,
isSelected: true,
})) as SelectableRecord[],
recordsToSelect: recordsToSelectData
.map(mapToObjectRecordIdentifier)
.map((record) => ({
...record,
isSelected: false,
})) as SelectableRecord[],
loading:
recordsToSelectLoading ||
filteredSelectedRecordsLoading ||
selectedRecordsLoading,
};
};

View File

@ -0,0 +1,10 @@
import { AvatarType } from '@/users/components/Avatar';
export type SelectableRecord = {
id: string;
name: string;
avatarUrl?: string;
avatarType?: AvatarType;
record: any;
isSelected: boolean;
};

View File

@ -0,0 +1,11 @@
export const getObjectFilterFields = (objectSingleName: string) => {
if (objectSingleName === 'company') {
return ['name'];
}
if (['workspaceMember', 'person'].includes(objectSingleName)) {
return ['name.firstName', 'name.lastName'];
}
return ['name'];
};

View File

@ -0,0 +1,11 @@
export const getObjectOrderByField = (objectSingleName: string): string => {
if (objectSingleName === 'company') {
return 'name';
}
if (['workspaceMember', 'person'].includes(objectSingleName)) {
return 'name.firstName';
}
return 'createdAt';
};

View File

@ -0,0 +1,8 @@
import { AvatarType } from '@/users/components/Avatar';
export type ObjectRecordIdentifier = {
id: string;
name: string;
avatarUrl?: string;
avatarType?: AvatarType;
};

View File

@ -1,14 +1,14 @@
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
import { ObjectFilterDropdownRecordSearchInput } from '@/ui/object/object-filter-dropdown/components/ObjectFilterDropdownEntitySearchInput';
import { useFilterDropdown } from '@/ui/object/object-filter-dropdown/hooks/useFilterDropdown';
import { MultipleFiltersDropdownFilterOnFilterChangedEffect } from './MultipleFiltersDropdownFilterOnFilterChangedEffect';
import { ObjectFilterDropdownDateSearchInput } from './ObjectFilterDropdownDateSearchInput';
import { ObjectFilterDropdownEntitySearchInput } from './ObjectFilterDropdownEntitySearchInput';
import { ObjectFilterDropdownEntitySelect } from './ObjectFilterDropdownEntitySelect';
import { ObjectFilterDropdownFilterSelect } from './ObjectFilterDropdownFilterSelect';
import { ObjectFilterDropdownNumberSearchInput } from './ObjectFilterDropdownNumberSearchInput';
import { ObjectFilterDropdownOperandButton } from './ObjectFilterDropdownOperandButton';
import { ObjectFilterDropdownOperandSelect } from './ObjectFilterDropdownOperandSelect';
import { ObjectFilterDropdownRecordSelect } from './ObjectFilterDropdownRecordSelect';
import { ObjectFilterDropdownTextSearchInput } from './ObjectFilterDropdownTextSearchInput';
export const MultipleFiltersDropdownContent = () => {
@ -39,10 +39,11 @@ export const MultipleFiltersDropdownContent = () => {
<ObjectFilterDropdownDateSearchInput />
)}
{filterDefinitionUsedInDropdown.type === 'RELATION' && (
<ObjectFilterDropdownEntitySearchInput />
)}
{filterDefinitionUsedInDropdown.type === 'RELATION' && (
<ObjectFilterDropdownEntitySelect />
<>
<ObjectFilterDropdownRecordSearchInput />
<DropdownMenuSeparator />
<ObjectFilterDropdownRecordSelect />
</>
)}
</>
)

View File

@ -3,7 +3,7 @@ import { ChangeEvent } from 'react';
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
import { useFilterDropdown } from '@/ui/object/object-filter-dropdown/hooks/useFilterDropdown';
export const ObjectFilterDropdownEntitySearchInput = () => {
export const ObjectFilterDropdownRecordSearchInput = () => {
const {
filterDefinitionUsedInDropdown,
selectedOperandInDropdown,

View File

@ -1,58 +0,0 @@
import { useQuery } from '@apollo/client';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { useFilteredSearchEntityQuery } from '@/search/hooks/useFilteredSearchEntityQuery';
import { useRelationPicker } from '@/ui/input/components/internal/relation-picker/hooks/useRelationPicker';
import { ObjectFilterDropdownEntitySearchSelect } from '@/ui/object/object-filter-dropdown/components/ObjectFilterDropdownEntitySearchSelect';
import { useFilterDropdown } from '@/ui/object/object-filter-dropdown/hooks/useFilterDropdown';
export const ObjectFilterDropdownEntitySelect = () => {
const {
filterDefinitionUsedInDropdown,
objectFilterDropdownSearchInput,
objectFilterDropdownSelectedEntityId,
} = useFilterDropdown();
const objectMetadataNameSingular =
filterDefinitionUsedInDropdown?.relationObjectMetadataNameSingular ?? '';
// TODO: refactor useFilteredSearchEntityQuery
const { findManyRecordsQuery } = useObjectMetadataItem({
objectNameSingular: objectMetadataNameSingular,
});
const useFindManyQuery = (options: any) =>
useQuery(findManyRecordsQuery, options);
const { identifiersMapper, searchQuery } = useRelationPicker();
const filteredSearchEntityResults = useFilteredSearchEntityQuery({
queryHook: useFindManyQuery,
filters: [
{
fieldNames:
searchQuery?.computeFilterFields?.(objectMetadataNameSingular) ?? [],
filter: objectFilterDropdownSearchInput,
},
],
orderByField: 'createdAt',
selectedIds: objectFilterDropdownSelectedEntityId
? [objectFilterDropdownSelectedEntityId]
: [],
mappingFunction: (record: any) =>
identifiersMapper?.(record, objectMetadataNameSingular),
objectNameSingular: objectMetadataNameSingular,
});
if (filterDefinitionUsedInDropdown?.type !== 'RELATION') {
return null;
}
return (
<>
<ObjectFilterDropdownEntitySearchSelect
entitiesForSelect={filteredSearchEntityResults}
/>
</>
);
};

View File

@ -0,0 +1,85 @@
import { MultipleRecordSelectDropdown } from '@/object-record/select/components/MultipleRecordSelectDropdown';
import { useRecordsForSelect } from '@/object-record/select/hooks/useRecordsForSelect';
import { SelectableRecord } from '@/object-record/select/types/SelectableRecord';
import { useFilterDropdown } from '@/ui/object/object-filter-dropdown/hooks/useFilterDropdown';
export const EMPTY_FILTER_VALUE = '';
export const MAX_RECORDS_TO_DISPLAY = 3;
export const ObjectFilterDropdownRecordSelect = () => {
const {
filterDefinitionUsedInDropdown,
objectFilterDropdownSearchInput,
selectedOperandInDropdown,
setObjectFilterDropdownSelectedRecordIds,
objectFilterDropdownSelectedRecordIds,
selectFilter,
} = useFilterDropdown();
const objectNameSingular =
filterDefinitionUsedInDropdown?.relationObjectMetadataNameSingular ?? '';
const { loading, filteredSelectedRecords, recordsToSelect, selectedRecords } =
useRecordsForSelect({
searchFilterText: objectFilterDropdownSearchInput,
selectedIds: objectFilterDropdownSelectedRecordIds,
objectNameSingular,
limit: 10,
});
const handleMultipleRecordSelectChange = (
recordToSelect: SelectableRecord,
newSelectedValue: boolean,
) => {
const newSelectedRecordIds = newSelectedValue
? [...objectFilterDropdownSelectedRecordIds, recordToSelect.id]
: objectFilterDropdownSelectedRecordIds.filter(
(id) => id !== recordToSelect.id,
);
setObjectFilterDropdownSelectedRecordIds(newSelectedRecordIds);
const selectedRecordNames = [
...recordsToSelect,
...selectedRecords,
...filteredSelectedRecords,
]
.filter(
(record, index, self) =>
self.findIndex((r) => r.id === record.id) === index,
)
.filter((record) => newSelectedRecordIds.includes(record.id))
.map((record) => record.name);
const filterDisplayValue =
selectedRecordNames.length > MAX_RECORDS_TO_DISPLAY
? `${selectedRecordNames.length} companies`
: selectedRecordNames.join(', ');
if (filterDefinitionUsedInDropdown && selectedOperandInDropdown) {
const newFilterValue =
newSelectedRecordIds.length > 0
? JSON.stringify(newSelectedRecordIds)
: EMPTY_FILTER_VALUE;
selectFilter({
definition: filterDefinitionUsedInDropdown,
operand: selectedOperandInDropdown,
displayValue: filterDisplayValue,
fieldMetadataId: filterDefinitionUsedInDropdown.fieldMetadataId,
value: newFilterValue,
});
}
};
return (
<MultipleRecordSelectDropdown
recordsToSelect={recordsToSelect}
filteredSelectedRecords={filteredSelectedRecords}
selectedRecords={selectedRecords}
onChange={handleMultipleRecordSelectChange}
searchFilter={objectFilterDropdownSearchInput}
loadingRecords={loading}
/>
);
};

View File

@ -12,8 +12,8 @@ import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { getOperandsForFilterType } from '../utils/getOperandsForFilterType';
import { GenericEntityFilterChip } from './GenericEntityFilterChip';
import { ObjectFilterDropdownEntitySearchInput } from './ObjectFilterDropdownEntitySearchInput';
import { ObjectFilterDropdownEntitySelect } from './ObjectFilterDropdownEntitySelect';
import { ObjectFilterDropdownRecordSearchInput } from './ObjectFilterDropdownEntitySearchInput';
import { ObjectFilterDropdownRecordSelect } from './ObjectFilterDropdownRecordSelect';
export const SingleEntityObjectFilterDropdownButton = ({
hotkeyScope,
@ -65,8 +65,8 @@ export const SingleEntityObjectFilterDropdownButton = ({
}
dropdownComponents={
<>
<ObjectFilterDropdownEntitySearchInput />
<ObjectFilterDropdownEntitySelect />
<ObjectFilterDropdownRecordSearchInput />
<ObjectFilterDropdownRecordSelect />
</>
}
/>

View File

@ -25,6 +25,8 @@ export const useFilterDropdown = (props?: UseFilterDropdownProps) => {
setObjectFilterDropdownSearchInput,
objectFilterDropdownSelectedEntityId,
setObjectFilterDropdownSelectedEntityId,
objectFilterDropdownSelectedRecordIds,
setObjectFilterDropdownSelectedRecordIds,
isObjectFilterDropdownOperandSelectUnfolded,
setIsObjectFilterDropdownOperandSelectUnfolded,
isObjectFilterDropdownUnfolded,
@ -48,6 +50,7 @@ export const useFilterDropdown = (props?: UseFilterDropdownProps) => {
const resetFilter = useCallback(() => {
setObjectFilterDropdownSearchInput('');
setObjectFilterDropdownSelectedEntityId(null);
setObjectFilterDropdownSelectedRecordIds([]);
setSelectedFilter(undefined);
setFilterDefinitionUsedInDropdown(null);
setSelectedOperandInDropdown(null);
@ -55,6 +58,7 @@ export const useFilterDropdown = (props?: UseFilterDropdownProps) => {
setFilterDefinitionUsedInDropdown,
setObjectFilterDropdownSearchInput,
setObjectFilterDropdownSelectedEntityId,
setObjectFilterDropdownSelectedRecordIds,
setSelectedFilter,
setSelectedOperandInDropdown,
]);
@ -69,6 +73,8 @@ export const useFilterDropdown = (props?: UseFilterDropdownProps) => {
setObjectFilterDropdownSearchInput,
objectFilterDropdownSelectedEntityId,
setObjectFilterDropdownSelectedEntityId,
objectFilterDropdownSelectedRecordIds,
setObjectFilterDropdownSelectedRecordIds,
isObjectFilterDropdownOperandSelectUnfolded,
setIsObjectFilterDropdownOperandSelectUnfolded,
isObjectFilterDropdownUnfolded,

View File

@ -1,3 +1,4 @@
import { objectFilterDropdownSelectedRecordIdsScopedState } from '@/ui/object/object-filter-dropdown/states/objectFilterDropdownSelectedRecordIdsScopedState';
import { onFilterSelectScopedState } from '@/ui/object/object-filter-dropdown/states/onFilterSelectScopedState';
import { useRecoilScopedStateV2 } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedStateV2';
@ -28,6 +29,14 @@ export const useFilterDropdownStates = (scopeId: string) => {
scopeId,
);
const [
objectFilterDropdownSelectedRecordIds,
setObjectFilterDropdownSelectedRecordIds,
] = useRecoilScopedStateV2(
objectFilterDropdownSelectedRecordIdsScopedState,
scopeId,
);
const [
isObjectFilterDropdownOperandSelectUnfolded,
setIsObjectFilterDropdownOperandSelectUnfolded,
@ -61,6 +70,8 @@ export const useFilterDropdownStates = (scopeId: string) => {
setObjectFilterDropdownSearchInput,
objectFilterDropdownSelectedEntityId,
setObjectFilterDropdownSelectedEntityId,
objectFilterDropdownSelectedRecordIds,
setObjectFilterDropdownSelectedRecordIds,
isObjectFilterDropdownOperandSelectUnfolded,
setIsObjectFilterDropdownOperandSelectUnfolded,
isObjectFilterDropdownUnfolded,

View File

@ -0,0 +1,7 @@
import { createScopedState } from '@/ui/utilities/recoil-scope/utils/createScopedState';
export const objectFilterDropdownSelectedRecordIdsScopedState =
createScopedState<string[]>({
key: 'objectFilterDropdownSelectedRecordIdsScopedState',
defaultValue: [],
});

View File

@ -94,26 +94,41 @@ export const turnFiltersIntoWhereClause = (
);
}
case 'RELATION':
switch (filter.operand) {
case ViewFilterOperand.Is:
whereClause.push({
[correspondingField.name + 'Id']: {
eq: filter.value,
},
});
return;
case ViewFilterOperand.IsNot:
whereClause.push({
[correspondingField.name + 'Id']: {
neq: filter.value,
},
});
return;
default:
throw new Error(
`Unknown operand ${filter.operand} for ${filter.definition.type} filter`,
);
try {
JSON.parse(filter.value);
} catch (e) {
throw new Error(
`Cannot parse filter value for RELATION filter : "${filter.value}"`,
);
}
const parsedRecordIds = JSON.parse(filter.value) as string[];
if (parsedRecordIds.length > 0) {
switch (filter.operand) {
case ViewFilterOperand.Is:
whereClause.push({
[correspondingField.name + 'Id']: {
in: parsedRecordIds,
},
});
return;
case ViewFilterOperand.IsNot:
whereClause.push({
not: {
[correspondingField.name + 'Id']: {
in: parsedRecordIds,
},
},
});
return;
default:
throw new Error(
`Unknown operand ${filter.operand} for ${filter.definition.type} filter`,
);
}
}
break;
case 'CURRENCY':
switch (filter.operand) {
case ViewFilterOperand.GreaterThan:

View File

@ -11,6 +11,7 @@ export const RecordTableBodyEffect = () => {
records,
setRecordTableData,
queryStateIdentifier,
loading,
} = useObjectRecordTable();
const { tableLastRowVisibleState } = useRecordTableScopedStates();
const [tableLastRowVisible, setTableLastRowVisible] = useRecoilState(
@ -22,8 +23,10 @@ export const RecordTableBodyEffect = () => {
);
useEffect(() => {
setRecordTableData(records);
}, [records, setRecordTableData]);
if (!loading) {
setRecordTableData(records);
}
}, [records, setRecordTableData, loading]);
useEffect(() => {
if (tableLastRowVisible && !isFetchingMoreObjects) {

View File

@ -14,13 +14,19 @@ export const ViewBarFilterEffect = ({
filterDropdownId,
onFilterSelect,
}: ViewBarFilterEffectProps) => {
const { availableFilterDefinitionsState } = useViewScopedStates();
const { availableFilterDefinitionsState, currentViewFiltersState } =
useViewScopedStates();
const availableFilterDefinitions = useRecoilValue(
availableFilterDefinitionsState,
);
const { setAvailableFilterDefinitions, setOnFilterSelect } =
useFilterDropdown({ filterDropdownId: filterDropdownId });
const {
setAvailableFilterDefinitions,
setOnFilterSelect,
filterDefinitionUsedInDropdown,
setObjectFilterDropdownSelectedRecordIds,
isObjectFilterDropdownUnfolded,
} = useFilterDropdown({ filterDropdownId: filterDropdownId });
useEffect(() => {
if (availableFilterDefinitions) {
@ -37,5 +43,28 @@ export const ViewBarFilterEffect = ({
setOnFilterSelect,
]);
const currentViewFilters = useRecoilValue(currentViewFiltersState);
useEffect(() => {
if (filterDefinitionUsedInDropdown?.type === 'RELATION') {
const viewFilterUsedInDropdown = currentViewFilters.find(
(filter) =>
filter.fieldMetadataId ===
filterDefinitionUsedInDropdown.fieldMetadataId,
);
const viewFilterSelectedRecordIds = JSON.parse(
viewFilterUsedInDropdown?.value ?? '[]',
);
setObjectFilterDropdownSelectedRecordIds(viewFilterSelectedRecordIds);
}
}, [
filterDefinitionUsedInDropdown,
currentViewFilters,
setObjectFilterDropdownSelectedRecordIds,
isObjectFilterDropdownUnfolded,
]);
return <></>;
};