Fixed bugs in ViewBar filtering (#7608)
- Fixed CSS for SortOrFilter chips - Fixed bug when refreshing with an actor source filter set --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@ -1,7 +1,7 @@
|
||||
import { StyledInput } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelect';
|
||||
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
|
||||
import { objectFilterDropdownFilterIsSelectedComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownFilterIsSelectedComponentState';
|
||||
import { objectFilterDropdownFirstLevelFilterDefinitionComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownFirstLevelFilterDefinitionComponentState';
|
||||
import { objectFilterDropdownIsSelectingCompositeFieldComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownIsSelectingCompositeFieldComponentState';
|
||||
import { objectFilterDropdownSubMenuFieldTypeComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSubMenuFieldTypeComponentState';
|
||||
import { FilterDefinition } from '@/object-record/object-filter-dropdown/types/FilterDefinition';
|
||||
import { getCompositeSubFieldLabel } from '@/object-record/object-filter-dropdown/utils/getCompositeSubFieldLabel';
|
||||
@ -16,7 +16,7 @@ import { useState } from 'react';
|
||||
import { IconApps, IconChevronLeft, isDefined, useIcons } from 'twenty-ui';
|
||||
|
||||
export const ObjectFilterDropdownFilterSelectCompositeFieldSubMenu = () => {
|
||||
const [searchText, setSearchText] = useState('');
|
||||
const [searchText] = useState('');
|
||||
|
||||
const { getIcon } = useIcons();
|
||||
|
||||
@ -31,6 +31,11 @@ export const ObjectFilterDropdownFilterSelectCompositeFieldSubMenu = () => {
|
||||
objectFilterDropdownFilterIsSelectedComponentState,
|
||||
);
|
||||
|
||||
const [, setObjectFilterDropdownIsSelectingCompositeField] =
|
||||
useRecoilComponentStateV2(
|
||||
objectFilterDropdownIsSelectingCompositeFieldComponentState,
|
||||
);
|
||||
|
||||
const [
|
||||
objectFilterDropdownSubMenuFieldType,
|
||||
setObjectFilterDropdownSubMenuFieldType,
|
||||
@ -62,6 +67,8 @@ export const ObjectFilterDropdownFilterSelectCompositeFieldSubMenu = () => {
|
||||
setFilterDefinitionUsedInDropdown(null);
|
||||
setObjectFilterDropdownSubMenuFieldType(null);
|
||||
setObjectFilterDropdownFirstLevelFilterDefinition(null);
|
||||
setObjectFilterDropdownIsSelectingCompositeField(false);
|
||||
setObjectFilterDropdownFilterIsSelected(false);
|
||||
};
|
||||
|
||||
if (
|
||||
@ -87,14 +94,14 @@ export const ObjectFilterDropdownFilterSelectCompositeFieldSubMenu = () => {
|
||||
>
|
||||
{getFilterableFieldTypeLabel(objectFilterDropdownSubMenuFieldType)}
|
||||
</DropdownMenuHeader>
|
||||
<StyledInput
|
||||
{/* <StyledInput
|
||||
value={searchText}
|
||||
autoFocus
|
||||
placeholder="Search fields"
|
||||
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
|
||||
setSearchText(event.target.value)
|
||||
}
|
||||
/>
|
||||
/> */}
|
||||
<DropdownMenuItemsContainer>
|
||||
<MenuItem
|
||||
key={`select-filter-${-1}`}
|
||||
@ -105,31 +112,33 @@ export const ObjectFilterDropdownFilterSelectCompositeFieldSubMenu = () => {
|
||||
LeftIcon={IconApps}
|
||||
text={`Any ${getFilterableFieldTypeLabel(objectFilterDropdownSubMenuFieldType)} field`}
|
||||
/>
|
||||
{options.map((subFieldName, index) => (
|
||||
<MenuItem
|
||||
key={`select-filter-${index}`}
|
||||
testId={`select-filter-${index}`}
|
||||
onClick={() => {
|
||||
if (isDefined(objectFilterDropdownFirstLevelFilterDefinition)) {
|
||||
handleSelectFilter({
|
||||
...objectFilterDropdownFirstLevelFilterDefinition,
|
||||
label: getCompositeSubFieldLabel(
|
||||
objectFilterDropdownSubMenuFieldType,
|
||||
subFieldName,
|
||||
),
|
||||
compositeFieldName: subFieldName,
|
||||
});
|
||||
}
|
||||
}}
|
||||
text={getCompositeSubFieldLabel(
|
||||
objectFilterDropdownSubMenuFieldType,
|
||||
subFieldName,
|
||||
)}
|
||||
LeftIcon={getIcon(
|
||||
objectFilterDropdownFirstLevelFilterDefinition?.iconName,
|
||||
)}
|
||||
/>
|
||||
))}
|
||||
{/* TODO: fix this with a backend field on ViewFilter for composite field filter */}
|
||||
{objectFilterDropdownFirstLevelFilterDefinition.type === 'ACTOR' &&
|
||||
options.map((subFieldName, index) => (
|
||||
<MenuItem
|
||||
key={`select-filter-${index}`}
|
||||
testId={`select-filter-${index}`}
|
||||
onClick={() => {
|
||||
if (isDefined(objectFilterDropdownFirstLevelFilterDefinition)) {
|
||||
handleSelectFilter({
|
||||
...objectFilterDropdownFirstLevelFilterDefinition,
|
||||
label: getCompositeSubFieldLabel(
|
||||
objectFilterDropdownSubMenuFieldType,
|
||||
subFieldName,
|
||||
),
|
||||
compositeFieldName: subFieldName,
|
||||
});
|
||||
}
|
||||
}}
|
||||
text={getCompositeSubFieldLabel(
|
||||
objectFilterDropdownSubMenuFieldType,
|
||||
subFieldName,
|
||||
)}
|
||||
LeftIcon={getIcon(
|
||||
objectFilterDropdownFirstLevelFilterDefinition?.iconName,
|
||||
)}
|
||||
/>
|
||||
))}
|
||||
</DropdownMenuItemsContainer>
|
||||
</>
|
||||
);
|
||||
|
||||
@ -24,7 +24,6 @@ import {
|
||||
convertRatingToRatingValue,
|
||||
} from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownRatingInput';
|
||||
import { Filter } from '@/object-record/object-filter-dropdown/types/Filter';
|
||||
import { isActorSourceCompositeFilter } from '@/object-record/object-filter-dropdown/utils/isActorSourceCompositeFilter';
|
||||
import { applyEmptyFilters } from '@/object-record/record-filter/utils/applyEmptyFilters';
|
||||
import { resolveFilterValue } from '@/views/utils/view-filter-value/resolveFilterValue';
|
||||
import { endOfDay, roundToNearestMinutes, startOfDay } from 'date-fns';
|
||||
@ -677,81 +676,83 @@ export const turnObjectDropdownFilterIntoQueryFilter = (
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'ACTOR':
|
||||
if (isActorSourceCompositeFilter(rawUIFilter.definition)) {
|
||||
const parsedRecordIds = JSON.parse(rawUIFilter.value) as string[];
|
||||
// TODO: fix this with a new composite field in ViewFilter entity
|
||||
case 'ACTOR': {
|
||||
switch (rawUIFilter.operand) {
|
||||
case ViewFilterOperand.Is: {
|
||||
const parsedRecordIds = JSON.parse(rawUIFilter.value) as string[];
|
||||
|
||||
switch (rawUIFilter.operand) {
|
||||
case ViewFilterOperand.Is:
|
||||
objectRecordFilters.push({
|
||||
[correspondingField.name]: {
|
||||
source: {
|
||||
in: parsedRecordIds,
|
||||
} as RelationFilter,
|
||||
},
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
case ViewFilterOperand.IsNot: {
|
||||
const parsedRecordIds = JSON.parse(rawUIFilter.value) as string[];
|
||||
|
||||
if (parsedRecordIds.length > 0) {
|
||||
objectRecordFilters.push({
|
||||
[correspondingField.name]: {
|
||||
source: {
|
||||
in: parsedRecordIds,
|
||||
} as RelationFilter,
|
||||
not: {
|
||||
[correspondingField.name]: {
|
||||
source: {
|
||||
in: parsedRecordIds,
|
||||
} as RelationFilter,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
break;
|
||||
case ViewFilterOperand.IsNot:
|
||||
if (parsedRecordIds.length > 0) {
|
||||
objectRecordFilters.push({
|
||||
not: {
|
||||
[correspondingField.name]: {
|
||||
source: {
|
||||
in: parsedRecordIds,
|
||||
} as RelationFilter,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (rawUIFilter.operand) {
|
||||
case ViewFilterOperand.Contains:
|
||||
objectRecordFilters.push({
|
||||
or: [
|
||||
{
|
||||
case ViewFilterOperand.Contains:
|
||||
objectRecordFilters.push({
|
||||
or: [
|
||||
{
|
||||
[correspondingField.name]: {
|
||||
name: {
|
||||
ilike: `%${rawUIFilter.value}%`,
|
||||
},
|
||||
} as ActorFilter,
|
||||
},
|
||||
],
|
||||
});
|
||||
break;
|
||||
case ViewFilterOperand.DoesNotContain:
|
||||
objectRecordFilters.push({
|
||||
and: [
|
||||
{
|
||||
not: {
|
||||
[correspondingField.name]: {
|
||||
name: {
|
||||
ilike: `%${rawUIFilter.value}%`,
|
||||
},
|
||||
} as ActorFilter,
|
||||
},
|
||||
],
|
||||
});
|
||||
break;
|
||||
case ViewFilterOperand.DoesNotContain:
|
||||
objectRecordFilters.push({
|
||||
and: [
|
||||
{
|
||||
not: {
|
||||
[correspondingField.name]: {
|
||||
name: {
|
||||
ilike: `%${rawUIFilter.value}%`,
|
||||
},
|
||||
} as ActorFilter,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
break;
|
||||
case ViewFilterOperand.IsEmpty:
|
||||
case ViewFilterOperand.IsNotEmpty:
|
||||
applyEmptyFilters(
|
||||
rawUIFilter.operand,
|
||||
correspondingField,
|
||||
objectRecordFilters,
|
||||
rawUIFilter.definition,
|
||||
);
|
||||
break;
|
||||
default:
|
||||
throw new Error(
|
||||
`Unknown operand ${rawUIFilter.operand} for ${rawUIFilter.definition.label} filter`,
|
||||
);
|
||||
}
|
||||
},
|
||||
],
|
||||
});
|
||||
break;
|
||||
case ViewFilterOperand.IsEmpty:
|
||||
case ViewFilterOperand.IsNotEmpty:
|
||||
applyEmptyFilters(
|
||||
rawUIFilter.operand,
|
||||
correspondingField,
|
||||
objectRecordFilters,
|
||||
rawUIFilter.definition,
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error(
|
||||
`Unknown operand ${rawUIFilter.operand} for ${rawUIFilter.definition.label} filter`,
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'EMAILS':
|
||||
switch (rawUIFilter.operand) {
|
||||
case ViewFilterOperand.Contains:
|
||||
|
||||
Reference in New Issue
Block a user