add multiple filters of same FieldMetadataType (#5892)

fixes: #5378
This commit is contained in:
Aditya Pimpalkar
2024-06-18 09:49:33 +01:00
committed by GitHub
parent de2b0527a3
commit 14abd99bb7
19 changed files with 91 additions and 180 deletions

View File

@ -1,4 +1,5 @@
import { useRecoilValue } from 'recoil';
import { v4 } from 'uuid';
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { InternalDatePicker } from '@/ui/input/components/internal/date/components/InternalDatePicker';
@ -8,6 +9,7 @@ export const ObjectFilterDropdownDateInput = () => {
const {
filterDefinitionUsedInDropdownState,
selectedOperandInDropdownState,
selectedFilterState,
setIsObjectFilterDropdownUnfolded,
selectFilter,
} = useFilterDropdown();
@ -19,10 +21,13 @@ export const ObjectFilterDropdownDateInput = () => {
selectedOperandInDropdownState,
);
const selectedFilter = useRecoilValue(selectedFilterState);
const handleChange = (date: Date | null) => {
if (!filterDefinitionUsedInDropdown || !selectedOperandInDropdown) return;
selectFilter?.({
id: selectedFilter?.id ? selectedFilter.id : v4(),
fieldMetadataId: filterDefinitionUsedInDropdown.fieldMetadataId,
value: isDefined(date) ? date.toISOString() : '',
operand: selectedOperandInDropdown,

View File

@ -1,127 +0,0 @@
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';
import { SingleEntitySelectMenuItems } from '@/object-record/relation-picker/components/SingleEntitySelectMenuItems';
import { EntitiesForMultipleEntitySelect } from '@/object-record/relation-picker/types/EntitiesForMultipleEntitySelect';
import { EntityForSelect } from '@/object-record/relation-picker/types/EntityForSelect';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
export const ObjectFilterDropdownEntitySearchSelect = ({
entitiesForSelect,
}: {
entitiesForSelect: EntitiesForMultipleEntitySelect<EntityForSelect>;
}) => {
const {
setObjectFilterDropdownSelectedEntityId,
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);
const handleRecordSelected = (
selectedEntity: EntityForSelect | null | undefined,
) => {
if (
!filterDefinitionUsedInDropdown ||
!selectedOperandInDropdown ||
!selectedEntity
) {
return;
}
if (isAllEntitySelected) {
setIsAllEntitySelected(false);
}
setObjectFilterDropdownSelectedEntityId(selectedEntity.id);
selectFilter?.({
displayValue: selectedEntity.name,
fieldMetadataId: filterDefinitionUsedInDropdown.fieldMetadataId,
operand: selectedOperandInDropdown,
value: selectedEntity.id,
displayAvatarUrl: selectedEntity.avatarUrl,
definition: filterDefinitionUsedInDropdown,
});
closeDropdown();
};
const isAllEntitySelectShown =
!!filterDefinitionUsedInDropdown?.selectAllLabel &&
!!filterDefinitionUsedInDropdown?.SelectAllIcon &&
(isAllEntitySelected ||
filterDefinitionUsedInDropdown?.selectAllLabel
.toLocaleLowerCase()
.includes(objectFilterDropdownSearchInput.toLocaleLowerCase()));
const handleAllEntitySelectClick = () => {
if (
!filterDefinitionUsedInDropdown ||
!selectedOperandInDropdown ||
!filterDefinitionUsedInDropdown.selectAllLabel
) {
return;
}
setIsAllEntitySelected(true);
setObjectFilterDropdownSelectedEntityId(null);
closeDropdown();
selectFilter?.({
displayValue: filterDefinitionUsedInDropdown.selectAllLabel,
fieldMetadataId: filterDefinitionUsedInDropdown.fieldMetadataId,
operand: ViewFilterOperand.IsNotNull,
value: '',
definition: filterDefinitionUsedInDropdown,
});
};
useEffect(() => {
if (!selectedFilter) {
setObjectFilterDropdownSelectedEntityId(null);
} else {
setObjectFilterDropdownSelectedEntityId(selectedFilter.value);
setIsAllEntitySelected(
selectedFilter.operand === ViewFilterOperand.IsNotNull,
);
}
}, [
selectedFilter,
setObjectFilterDropdownSelectedEntityId,
entitiesForSelect.selectedEntities,
]);
return (
<SingleEntitySelectMenuItems
entitiesToSelect={entitiesForSelect.entitiesToSelect}
selectedEntity={entitiesForSelect.selectedEntities[0]}
loading={entitiesForSelect.loading}
onEntitySelected={handleRecordSelected}
SelectAllIcon={filterDefinitionUsedInDropdown?.SelectAllIcon}
selectAllLabel={filterDefinitionUsedInDropdown?.selectAllLabel}
isAllEntitySelected={isAllEntitySelected}
isAllEntitySelectShown={isAllEntitySelectShown}
onAllEntitySelected={handleAllEntitySelectClick}
/>
);
};

View File

@ -1,5 +1,6 @@
import { ChangeEvent } from 'react';
import { useRecoilValue } from 'recoil';
import { v4 } from 'uuid';
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { DropdownMenuInput } from '@/ui/layout/dropdown/components/DropdownMenuInput';
@ -8,6 +9,7 @@ export const ObjectFilterDropdownNumberInput = () => {
const {
selectedOperandInDropdownState,
filterDefinitionUsedInDropdownState,
selectedFilterState,
selectFilter,
} = useFilterDropdown();
@ -18,6 +20,8 @@ export const ObjectFilterDropdownNumberInput = () => {
selectedOperandInDropdownState,
);
const selectedFilter = useRecoilValue(selectedFilterState);
return (
filterDefinitionUsedInDropdown &&
selectedOperandInDropdown && (
@ -27,6 +31,7 @@ export const ObjectFilterDropdownNumberInput = () => {
placeholder={filterDefinitionUsedInDropdown.label}
onChange={(event: ChangeEvent<HTMLInputElement>) => {
selectFilter?.({
id: selectedFilter?.id ? selectedFilter.id : v4(),
fieldMetadataId: filterDefinitionUsedInDropdown.fieldMetadataId,
value: event.target.value,
operand: selectedOperandInDropdown,

View File

@ -1,4 +1,5 @@
import { useRecoilValue } from 'recoil';
import { v4 } from 'uuid';
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
@ -42,6 +43,7 @@ export const ObjectFilterDropdownOperandSelect = () => {
isDefined(selectedFilter)
) {
selectFilter?.({
id: selectedFilter.id ? selectedFilter.id : v4(),
fieldMetadataId: selectedFilter.fieldMetadataId,
displayValue: selectedFilter.displayValue,
operand: newOperand,

View File

@ -1,5 +1,6 @@
import { useEffect, useState } from 'react';
import { useRecoilValue } from 'recoil';
import { v4 } from 'uuid';
import { FieldMetadataItemOption } from '@/object-metadata/types/FieldMetadataItem';
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
@ -22,6 +23,7 @@ export const ObjectFilterDropdownOptionSelect = () => {
objectFilterDropdownSearchInputState,
selectedOperandInDropdownState,
objectFilterDropdownSelectedOptionValuesState,
selectedFilterState,
selectFilter,
} = useFilterDropdown();
@ -38,6 +40,8 @@ export const ObjectFilterDropdownOptionSelect = () => {
objectFilterDropdownSelectedOptionValuesState,
);
const selectedFilter = useRecoilValue(selectedFilterState);
const fieldMetaDataId = filterDefinitionUsedInDropdown?.fieldMetadataId ?? '';
const { selectOptions } = useOptionsForSelect(fieldMetaDataId);
@ -96,6 +100,7 @@ export const ObjectFilterDropdownOptionSelect = () => {
: EMPTY_FILTER_VALUE;
selectFilter({
id: selectedFilter?.id ? selectedFilter.id : v4(),
definition: filterDefinitionUsedInDropdown,
operand: selectedOperandInDropdown,
displayValue: filterDisplayValue,

View File

@ -1,9 +1,13 @@
import { useState } from 'react';
import { useRecoilValue } from 'recoil';
import { v4 } from 'uuid';
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';
import { SelectableRecord } from '@/object-record/select/types/SelectableRecord';
import { useCombinedViewFilters } from '@/views/hooks/useCombinedViewFilters';
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
import { isDefined } from '~/utils/isDefined';
export const EMPTY_FILTER_VALUE = '[]';
@ -14,12 +18,16 @@ export const ObjectFilterDropdownRecordSelect = () => {
filterDefinitionUsedInDropdownState,
objectFilterDropdownSearchInputState,
selectedOperandInDropdownState,
selectedFilterState,
setObjectFilterDropdownSelectedRecordIds,
objectFilterDropdownSelectedRecordIdsState,
selectFilter,
emptyFilterButKeepDefinition,
} = useFilterDropdown();
const { removeCombinedViewFilter } = useCombinedViewFilters();
const { currentViewWithCombinedFiltersAndSorts } = useGetCurrentView();
const filterDefinitionUsedInDropdown = useRecoilValue(
filterDefinitionUsedInDropdownState,
);
@ -32,6 +40,9 @@ export const ObjectFilterDropdownRecordSelect = () => {
const objectFilterDropdownSelectedRecordIds = useRecoilValue(
objectFilterDropdownSelectedRecordIdsState,
);
const [fieldId] = useState(v4());
const selectedFilter = useRecoilValue(selectedFilterState);
const objectNameSingular =
filterDefinitionUsedInDropdown?.relationObjectMetadataNameSingular ?? '';
@ -60,6 +71,7 @@ export const ObjectFilterDropdownRecordSelect = () => {
if (newSelectedRecordIds.length === 0) {
emptyFilterButKeepDefinition();
removeCombinedViewFilter(fieldId);
return;
}
@ -91,7 +103,17 @@ export const ObjectFilterDropdownRecordSelect = () => {
? JSON.stringify(newSelectedRecordIds)
: EMPTY_FILTER_VALUE;
const viewFilter =
currentViewWithCombinedFiltersAndSorts?.viewFilters.find(
(viewFilter) =>
viewFilter.fieldMetadataId ===
filterDefinitionUsedInDropdown.fieldMetadataId,
);
const filterId = viewFilter?.id ?? fieldId;
selectFilter({
id: selectedFilter?.id ? selectedFilter.id : filterId,
definition: filterDefinitionUsedInDropdown,
operand: selectedOperandInDropdown,
displayValue: filterDisplayValue,

View File

@ -1,5 +1,6 @@
import { ChangeEvent } from 'react';
import { ChangeEvent, useState } from 'react';
import { useRecoilValue } from 'recoil';
import { v4 } from 'uuid';
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
@ -14,6 +15,8 @@ export const ObjectFilterDropdownTextSearchInput = () => {
selectFilter,
} = useFilterDropdown();
const [filterId] = useState(v4());
const filterDefinitionUsedInDropdown = useRecoilValue(
filterDefinitionUsedInDropdownState,
);
@ -37,6 +40,7 @@ export const ObjectFilterDropdownTextSearchInput = () => {
setObjectFilterDropdownSearchInput(event.target.value);
selectFilter?.({
id: selectedFilter?.id ? selectedFilter.id : filterId,
fieldMetadataId: filterDefinitionUsedInDropdown.fieldMetadataId,
value: event.target.value,
operand: selectedOperandInDropdown,

View File

@ -23,6 +23,7 @@ const filterDefinitions: FilterDefinition[] = [
];
const mockFilter: Filter = {
id: 'id',
definition: filterDefinitions[0],
displayValue: '',
fieldMetadataId: '',

View File

@ -3,6 +3,7 @@ import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { FilterDefinition } from './FilterDefinition';
export type Filter = {
id: string;
fieldMetadataId: string;
value: string;
displayValue: string;

View File

@ -1,4 +1,5 @@
import { useCallback } from 'react';
import { v4 } from 'uuid';
import { useColumnDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useColumnDefinitionsFromFieldMetadata';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
@ -46,6 +47,7 @@ export const useHandleToggleColumnFilter = ({
const defaultOperand = availableOperandsForFilter[0];
const newFilter: Filter = {
id: v4(),
fieldMetadataId,
operand: defaultOperand,
displayValue: '',