Refactored object filter dropdown input state management (#11838)
This PR refactors the generic module object dropdown filter input. We have multiple components for each filter type and each one was using selectedFilterState and the applyRecordFilter hook to read and set its value. The main issue was that each component was forced to pass every property of a RecordFilter to applyRecordFilter to only modify the value property, thus creating a lot of unnecessary dependencies and tight coupling between every component and hook that used the record filters. Now we have each component only reading from a new objectFilterDropdownCurrentRecordFilterComponentState, scoped to a ObjectFilterDropdownComponentInstanceContext, thus whether we're in a view bar dropdown, an editable filter chip dropdown or an advanced filter dropdown, we know where to read the filter value from. This component state might even be simplified by only storing the record filter id, thus avoiding having to synchronize this state with its counterpart in currentRecordFilterComponentState, but we should try after the main refactor effort, as those two states aren't in the same instance context. We implement a new applyObjectFilterDropdownFilterValue hook to handle the value setting from an object filter dropdown input component. There's also a new useApplyObjectFilterDropdownOperand for doing the same but for operand. Another important thing that had to be done to keep a synchronous code path was to set the states of each advanced filter row at the advanced filter dropdown onOpen event, using useSetAdvancedFilterDropdownStates. Finally we remove : useApplyRecordFilter, useSelectFilterUsedInDropdown and selectedFilterComponentState which were making all of this zone difficult to work with. Closes https://github.com/twentyhq/core-team-issues/issues/718 Closes https://github.com/twentyhq/core-team-issues/issues/720
This commit is contained in:
@ -1,122 +0,0 @@
|
|||||||
import { v4 } from 'uuid';
|
|
||||||
|
|
||||||
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
|
||||||
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
|
|
||||||
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
|
|
||||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
|
||||||
import { getRelativeDateDisplayValue } from '@/object-record/object-filter-dropdown/utils/getRelativeDateDisplayValue';
|
|
||||||
import { useApplyRecordFilter } from '@/object-record/record-filter/hooks/useApplyRecordFilter';
|
|
||||||
import { DateTimePicker } from '@/ui/input/components/internal/date/components/InternalDatePicker';
|
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
|
||||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
|
||||||
import { computeVariableDateViewFilterValue } from '@/views/view-filter-value/utils/computeVariableDateViewFilterValue';
|
|
||||||
import {
|
|
||||||
resolveDateViewFilterValue,
|
|
||||||
VariableDateViewFilterValueDirection,
|
|
||||||
VariableDateViewFilterValueUnit,
|
|
||||||
} from '@/views/view-filter-value/utils/resolveDateViewFilterValue';
|
|
||||||
import { useState } from 'react';
|
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
|
||||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
|
||||||
|
|
||||||
export const AdvancedFilterDropdownDateInput = () => {
|
|
||||||
const fieldMetadataItemUsedInDropdown = useRecoilComponentValueV2(
|
|
||||||
fieldMetadataItemUsedInDropdownComponentSelector,
|
|
||||||
);
|
|
||||||
|
|
||||||
const selectedOperandInDropdown = useRecoilComponentValueV2(
|
|
||||||
selectedOperandInDropdownComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const selectedFilter = useRecoilComponentValueV2(
|
|
||||||
selectedFilterComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const { applyRecordFilter } = useApplyRecordFilter();
|
|
||||||
|
|
||||||
const initialFilterValue = selectedFilter
|
|
||||||
? resolveDateViewFilterValue(selectedFilter)
|
|
||||||
: null;
|
|
||||||
const [internalDate, setInternalDate] = useState<Date | null>(
|
|
||||||
initialFilterValue instanceof Date ? initialFilterValue : null,
|
|
||||||
);
|
|
||||||
|
|
||||||
const isDateTimeInput =
|
|
||||||
fieldMetadataItemUsedInDropdown?.type === FieldMetadataType.DATE_TIME;
|
|
||||||
|
|
||||||
const handleAbsoluteDateChange = (newDate: Date | null) => {
|
|
||||||
setInternalDate(newDate);
|
|
||||||
|
|
||||||
if (!fieldMetadataItemUsedInDropdown || !selectedOperandInDropdown) return;
|
|
||||||
|
|
||||||
const newDisplayValue = isDefined(newDate)
|
|
||||||
? newDate.toLocaleDateString()
|
|
||||||
: '';
|
|
||||||
|
|
||||||
applyRecordFilter({
|
|
||||||
id: selectedFilter?.id ? selectedFilter.id : v4(),
|
|
||||||
fieldMetadataId: fieldMetadataItemUsedInDropdown.id,
|
|
||||||
value: newDate?.toISOString() ?? '',
|
|
||||||
operand: selectedOperandInDropdown,
|
|
||||||
displayValue: newDisplayValue,
|
|
||||||
recordFilterGroupId: selectedFilter?.recordFilterGroupId,
|
|
||||||
positionInRecordFilterGroup: selectedFilter?.positionInRecordFilterGroup,
|
|
||||||
type: getFilterTypeFromFieldType(fieldMetadataItemUsedInDropdown.type),
|
|
||||||
label: fieldMetadataItemUsedInDropdown.label,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleRelativeDateChange = (
|
|
||||||
relativeDate: {
|
|
||||||
direction: VariableDateViewFilterValueDirection;
|
|
||||||
amount?: number;
|
|
||||||
unit: VariableDateViewFilterValueUnit;
|
|
||||||
} | null,
|
|
||||||
) => {
|
|
||||||
if (!fieldMetadataItemUsedInDropdown || !selectedOperandInDropdown) return;
|
|
||||||
|
|
||||||
const value = relativeDate
|
|
||||||
? computeVariableDateViewFilterValue(
|
|
||||||
relativeDate.direction,
|
|
||||||
relativeDate.amount,
|
|
||||||
relativeDate.unit,
|
|
||||||
)
|
|
||||||
: '';
|
|
||||||
|
|
||||||
applyRecordFilter({
|
|
||||||
id: selectedFilter?.id ? selectedFilter.id : v4(),
|
|
||||||
fieldMetadataId: fieldMetadataItemUsedInDropdown.id,
|
|
||||||
value,
|
|
||||||
operand: selectedOperandInDropdown,
|
|
||||||
displayValue: getRelativeDateDisplayValue(relativeDate),
|
|
||||||
recordFilterGroupId: selectedFilter?.recordFilterGroupId,
|
|
||||||
positionInRecordFilterGroup: selectedFilter?.positionInRecordFilterGroup,
|
|
||||||
type: getFilterTypeFromFieldType(fieldMetadataItemUsedInDropdown.type),
|
|
||||||
label: fieldMetadataItemUsedInDropdown.label,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const isRelativeOperand =
|
|
||||||
selectedOperandInDropdown === ViewFilterOperand.IsRelative;
|
|
||||||
|
|
||||||
const resolvedValue = selectedFilter
|
|
||||||
? resolveDateViewFilterValue(selectedFilter)
|
|
||||||
: null;
|
|
||||||
|
|
||||||
const relativeDate =
|
|
||||||
resolvedValue && !(resolvedValue instanceof Date)
|
|
||||||
? resolvedValue
|
|
||||||
: undefined;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<DateTimePicker
|
|
||||||
relativeDate={relativeDate}
|
|
||||||
highlightedDateRange={relativeDate}
|
|
||||||
isRelative={isRelativeOperand}
|
|
||||||
date={internalDate}
|
|
||||||
onChange={handleAbsoluteDateChange}
|
|
||||||
onRelativeDateChange={handleRelativeDateChange}
|
|
||||||
isDateTimeInput={isDateTimeInput}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@ -5,9 +5,9 @@ import { ObjectFilterDropdownSearchInput } from '@/object-record/object-filter-d
|
|||||||
import { ObjectFilterDropdownSourceSelect } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownSourceSelect';
|
import { ObjectFilterDropdownSourceSelect } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownSourceSelect';
|
||||||
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
||||||
|
|
||||||
import { AdvancedFilterDropdownDateInput } from '@/object-record/advanced-filter/components/AdvancedFilterDropdownDateInput';
|
|
||||||
import { ObjectFilterDropdownBooleanSelect } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownBooleanSelect';
|
import { ObjectFilterDropdownBooleanSelect } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownBooleanSelect';
|
||||||
import { ObjectFilterDropdownCurrencySelect } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownCurrencySelect';
|
import { ObjectFilterDropdownCurrencySelect } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownCurrencySelect';
|
||||||
|
import { ObjectFilterDropdownDateInput } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownDateInput';
|
||||||
import { ObjectFilterDropdownTextInput } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownTextInput';
|
import { ObjectFilterDropdownTextInput } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownTextInput';
|
||||||
import { DATE_FILTER_TYPES } from '@/object-record/object-filter-dropdown/constants/DateFilterTypes';
|
import { DATE_FILTER_TYPES } from '@/object-record/object-filter-dropdown/constants/DateFilterTypes';
|
||||||
import { subFieldNameUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/subFieldNameUsedInDropdownComponentState';
|
import { subFieldNameUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/subFieldNameUsedInDropdownComponentState';
|
||||||
@ -41,7 +41,7 @@ export const AdvancedFilterDropdownFilterInput = ({
|
|||||||
<>
|
<>
|
||||||
{filterType === 'RATING' && <ObjectFilterDropdownRatingInput />}
|
{filterType === 'RATING' && <ObjectFilterDropdownRatingInput />}
|
||||||
{DATE_FILTER_TYPES.includes(filterType) && (
|
{DATE_FILTER_TYPES.includes(filterType) && (
|
||||||
<AdvancedFilterDropdownDateInput />
|
<ObjectFilterDropdownDateInput />
|
||||||
)}
|
)}
|
||||||
{filterType === 'RELATION' && (
|
{filterType === 'RELATION' && (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@ -1,13 +1,9 @@
|
|||||||
import { useState } from 'react';
|
import { useApplyObjectFilterDropdownFilterValue } from '@/object-record/object-filter-dropdown/hooks/useApplyObjectFilterDropdownFilterValue';
|
||||||
|
import { useObjectFilterDropdownFilterValue } from '@/object-record/object-filter-dropdown/hooks/useObjectFilterDropdownFilterValue';
|
||||||
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
|
||||||
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
|
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
|
||||||
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
|
|
||||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
||||||
import { useApplyRecordFilter } from '@/object-record/record-filter/hooks/useApplyRecordFilter';
|
|
||||||
import { TextInputV2 } from '@/ui/input/components/TextInputV2';
|
import { TextInputV2 } from '@/ui/input/components/TextInputV2';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { v4 } from 'uuid';
|
|
||||||
|
|
||||||
export const AdvancedFilterDropdownNumberInput = () => {
|
export const AdvancedFilterDropdownNumberInput = () => {
|
||||||
const selectedOperandInDropdown = useRecoilComponentValueV2(
|
const selectedOperandInDropdown = useRecoilComponentValueV2(
|
||||||
@ -18,34 +14,14 @@ export const AdvancedFilterDropdownNumberInput = () => {
|
|||||||
fieldMetadataItemUsedInDropdownComponentSelector,
|
fieldMetadataItemUsedInDropdownComponentSelector,
|
||||||
);
|
);
|
||||||
|
|
||||||
const selectedFilter = useRecoilComponentValueV2(
|
const { objectFilterDropdownFilterValue } =
|
||||||
selectedFilterComponentState,
|
useObjectFilterDropdownFilterValue();
|
||||||
);
|
|
||||||
|
|
||||||
const { applyRecordFilter } = useApplyRecordFilter();
|
const { applyObjectFilterDropdownFilterValue } =
|
||||||
|
useApplyObjectFilterDropdownFilterValue();
|
||||||
const [inputValue, setInputValue] = useState(
|
|
||||||
() => selectedFilter?.value || '',
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleChange = (newValue: string) => {
|
const handleChange = (newValue: string) => {
|
||||||
if (!fieldMetadataItemUsedInDropdown || !selectedOperandInDropdown) {
|
applyObjectFilterDropdownFilterValue(newValue);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setInputValue(newValue);
|
|
||||||
|
|
||||||
applyRecordFilter({
|
|
||||||
id: selectedFilter?.id ? selectedFilter.id : v4(),
|
|
||||||
fieldMetadataId: fieldMetadataItemUsedInDropdown?.id ?? '',
|
|
||||||
value: newValue,
|
|
||||||
operand: selectedOperandInDropdown,
|
|
||||||
displayValue: newValue,
|
|
||||||
type: getFilterTypeFromFieldType(fieldMetadataItemUsedInDropdown.type),
|
|
||||||
label: fieldMetadataItemUsedInDropdown.label,
|
|
||||||
recordFilterGroupId: selectedFilter?.recordFilterGroupId,
|
|
||||||
positionInRecordFilterGroup: selectedFilter?.positionInRecordFilterGroup,
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!selectedOperandInDropdown || !fieldMetadataItemUsedInDropdown) {
|
if (!selectedOperandInDropdown || !fieldMetadataItemUsedInDropdown) {
|
||||||
@ -54,7 +30,7 @@ export const AdvancedFilterDropdownNumberInput = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<TextInputV2
|
<TextInputV2
|
||||||
value={inputValue}
|
value={objectFilterDropdownFilterValue}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
placeholder="Enter value"
|
placeholder="Enter value"
|
||||||
fullWidth
|
fullWidth
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { useApplyRecordFilter } from '@/object-record/record-filter/hooks/useApplyRecordFilter';
|
import { useApplyObjectFilterDropdownFilterValue } from '@/object-record/object-filter-dropdown/hooks/useApplyObjectFilterDropdownFilterValue';
|
||||||
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||||
import { TextInputV2 } from '@/ui/input/components/TextInputV2';
|
import { TextInputV2 } from '@/ui/input/components/TextInputV2';
|
||||||
|
|
||||||
@ -9,21 +9,11 @@ type AdvancedFilterDropdownTextInputProps = {
|
|||||||
export const AdvancedFilterDropdownTextInput = ({
|
export const AdvancedFilterDropdownTextInput = ({
|
||||||
recordFilter,
|
recordFilter,
|
||||||
}: AdvancedFilterDropdownTextInputProps) => {
|
}: AdvancedFilterDropdownTextInputProps) => {
|
||||||
const { applyRecordFilter } = useApplyRecordFilter();
|
const { applyObjectFilterDropdownFilterValue } =
|
||||||
|
useApplyObjectFilterDropdownFilterValue();
|
||||||
|
|
||||||
const handleChange = (newValue: string) => {
|
const handleChange = (newValue: string) => {
|
||||||
applyRecordFilter({
|
applyObjectFilterDropdownFilterValue(newValue);
|
||||||
id: recordFilter.id,
|
|
||||||
fieldMetadataId: recordFilter.fieldMetadataId,
|
|
||||||
value: newValue,
|
|
||||||
operand: recordFilter.operand,
|
|
||||||
displayValue: newValue,
|
|
||||||
type: recordFilter.type,
|
|
||||||
label: recordFilter.label,
|
|
||||||
recordFilterGroupId: recordFilter.recordFilterGroupId,
|
|
||||||
positionInRecordFilterGroup: recordFilter.positionInRecordFilterGroup,
|
|
||||||
subFieldName: recordFilter.subFieldName,
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -4,6 +4,8 @@ import { AdvancedFilterValueInputDropdownButtonClickableSelect } from '@/object-
|
|||||||
import { DEFAULT_ADVANCED_FILTER_DROPDOWN_OFFSET } from '@/object-record/advanced-filter/constants/DefaultAdvancedFilterDropdownOffset';
|
import { DEFAULT_ADVANCED_FILTER_DROPDOWN_OFFSET } from '@/object-record/advanced-filter/constants/DefaultAdvancedFilterDropdownOffset';
|
||||||
import { NUMBER_FILTER_TYPES } from '@/object-record/object-filter-dropdown/constants/NumberFilterTypes';
|
import { NUMBER_FILTER_TYPES } from '@/object-record/object-filter-dropdown/constants/NumberFilterTypes';
|
||||||
import { TEXT_FILTER_TYPES } from '@/object-record/object-filter-dropdown/constants/TextFilterTypes';
|
import { TEXT_FILTER_TYPES } from '@/object-record/object-filter-dropdown/constants/TextFilterTypes';
|
||||||
|
import { fieldMetadataItemIdUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemIdUsedInDropdownComponentState';
|
||||||
|
import { objectFilterDropdownCurrentRecordFilterComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownCurrentRecordFilterComponentState';
|
||||||
import { objectFilterDropdownSearchInputComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputComponentState';
|
import { objectFilterDropdownSearchInputComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputComponentState';
|
||||||
import { configurableViewFilterOperands } from '@/object-record/object-filter-dropdown/utils/configurableViewFilterOperands';
|
import { configurableViewFilterOperands } from '@/object-record/object-filter-dropdown/utils/configurableViewFilterOperands';
|
||||||
import { isExpectedSubFieldName } from '@/object-record/object-filter-dropdown/utils/isExpectedSubFieldName';
|
import { isExpectedSubFieldName } from '@/object-record/object-filter-dropdown/utils/isExpectedSubFieldName';
|
||||||
@ -44,6 +46,15 @@ export const AdvancedFilterValueInput = ({
|
|||||||
objectFilterDropdownSearchInputComponentState,
|
objectFilterDropdownSearchInputComponentState,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const setFieldMetadataItemIdUsedInDropdown = useSetRecoilComponentStateV2(
|
||||||
|
fieldMetadataItemIdUsedInDropdownComponentState,
|
||||||
|
);
|
||||||
|
|
||||||
|
const setObjectFilterDropdownCurrentRecordFilter =
|
||||||
|
useSetRecoilComponentStateV2(
|
||||||
|
objectFilterDropdownCurrentRecordFilterComponentState,
|
||||||
|
);
|
||||||
|
|
||||||
const operandHasNoInput =
|
const operandHasNoInput =
|
||||||
recordFilter && !configurableViewFilterOperands.has(recordFilter.operand);
|
recordFilter && !configurableViewFilterOperands.has(recordFilter.operand);
|
||||||
|
|
||||||
@ -55,6 +66,11 @@ export const AdvancedFilterValueInput = ({
|
|||||||
setObjectFilterDropdownSearchInput('');
|
setObjectFilterDropdownSearchInput('');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleFilterValueDropdownOpen = () => {
|
||||||
|
setObjectFilterDropdownCurrentRecordFilter(recordFilter);
|
||||||
|
setFieldMetadataItemIdUsedInDropdown(recordFilter.fieldMetadataId);
|
||||||
|
};
|
||||||
|
|
||||||
const filterType = recordFilter.type;
|
const filterType = recordFilter.type;
|
||||||
|
|
||||||
const dropdownContentOffset =
|
const dropdownContentOffset =
|
||||||
@ -98,6 +114,7 @@ export const AdvancedFilterValueInput = ({
|
|||||||
dropdownPlacement="bottom-start"
|
dropdownPlacement="bottom-start"
|
||||||
dropdownWidth={280}
|
dropdownWidth={280}
|
||||||
onClose={handleFilterValueDropdownClose}
|
onClose={handleFilterValueDropdownClose}
|
||||||
|
onOpen={handleFilterValueDropdownOpen}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</StyledValueDropdownContainer>
|
</StyledValueDropdownContainer>
|
||||||
|
|||||||
@ -1,12 +1,14 @@
|
|||||||
import { useGetFieldMetadataItemById } from '@/object-metadata/hooks/useGetFieldMetadataItemById';
|
import { useGetFieldMetadataItemById } from '@/object-metadata/hooks/useGetFieldMetadataItemById';
|
||||||
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
||||||
import { fieldMetadataItemIdUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemIdUsedInDropdownComponentState';
|
import { fieldMetadataItemIdUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemIdUsedInDropdownComponentState';
|
||||||
|
import { objectFilterDropdownCurrentRecordFilterComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownCurrentRecordFilterComponentState';
|
||||||
import { objectFilterDropdownSearchInputComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputComponentState';
|
import { objectFilterDropdownSearchInputComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputComponentState';
|
||||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
||||||
import { subFieldNameUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/subFieldNameUsedInDropdownComponentState';
|
import { subFieldNameUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/subFieldNameUsedInDropdownComponentState';
|
||||||
import { getInitialFilterValue } from '@/object-record/object-filter-dropdown/utils/getInitialFilterValue';
|
import { getInitialFilterValue } from '@/object-record/object-filter-dropdown/utils/getInitialFilterValue';
|
||||||
import { useApplyRecordFilter } from '@/object-record/record-filter/hooks/useApplyRecordFilter';
|
import { useUpsertRecordFilter } from '@/object-record/record-filter/hooks/useUpsertRecordFilter';
|
||||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||||
|
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||||
import { getRecordFilterOperands } from '@/object-record/record-filter/utils/getRecordFilterOperands';
|
import { getRecordFilterOperands } from '@/object-record/record-filter/utils/getRecordFilterOperands';
|
||||||
import { SingleRecordPickerHotkeyScope } from '@/object-record/record-picker/single-record-picker/types/SingleRecordPickerHotkeyScope';
|
import { SingleRecordPickerHotkeyScope } from '@/object-record/record-picker/single-record-picker/types/SingleRecordPickerHotkeyScope';
|
||||||
|
|
||||||
@ -40,14 +42,19 @@ export const useSelectFieldUsedInAdvancedFilterDropdown = () => {
|
|||||||
|
|
||||||
const setHotkeyScope = useSetHotkeyScope();
|
const setHotkeyScope = useSetHotkeyScope();
|
||||||
|
|
||||||
const { applyRecordFilter } = useApplyRecordFilter();
|
|
||||||
|
|
||||||
const { getFieldMetadataItemById } = useGetFieldMetadataItemById();
|
const { getFieldMetadataItemById } = useGetFieldMetadataItemById();
|
||||||
|
|
||||||
const setSubFieldNameUsedInDropdown = useSetRecoilComponentStateV2(
|
const setSubFieldNameUsedInDropdown = useSetRecoilComponentStateV2(
|
||||||
subFieldNameUsedInDropdownComponentState,
|
subFieldNameUsedInDropdownComponentState,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const setObjectFilterDropdownCurrentRecordFilter =
|
||||||
|
useSetRecoilComponentStateV2(
|
||||||
|
objectFilterDropdownCurrentRecordFilterComponentState,
|
||||||
|
);
|
||||||
|
|
||||||
|
const { upsertRecordFilter } = useUpsertRecordFilter();
|
||||||
|
|
||||||
const selectFieldUsedInAdvancedFilterDropdown = ({
|
const selectFieldUsedInAdvancedFilterDropdown = ({
|
||||||
fieldMetadataItemId,
|
fieldMetadataItemId,
|
||||||
recordFilterId,
|
recordFilterId,
|
||||||
@ -86,7 +93,7 @@ export const useSelectFieldUsedInAdvancedFilterDropdown = () => {
|
|||||||
(recordFilter) => recordFilter.id === recordFilterId,
|
(recordFilter) => recordFilter.id === recordFilterId,
|
||||||
);
|
);
|
||||||
|
|
||||||
applyRecordFilter({
|
const newAdvancedFilter = {
|
||||||
id: recordFilterId,
|
id: recordFilterId,
|
||||||
fieldMetadataId: fieldMetadataItem.id,
|
fieldMetadataId: fieldMetadataItem.id,
|
||||||
displayValue,
|
displayValue,
|
||||||
@ -97,12 +104,15 @@ export const useSelectFieldUsedInAdvancedFilterDropdown = () => {
|
|||||||
existingRecordFilter?.positionInRecordFilterGroup,
|
existingRecordFilter?.positionInRecordFilterGroup,
|
||||||
type: filterType,
|
type: filterType,
|
||||||
label: fieldMetadataItem.label,
|
label: fieldMetadataItem.label,
|
||||||
subFieldName: subFieldName ?? null,
|
subFieldName,
|
||||||
});
|
} satisfies RecordFilter;
|
||||||
|
|
||||||
setSubFieldNameUsedInDropdown(subFieldName);
|
setSubFieldNameUsedInDropdown(subFieldName);
|
||||||
|
|
||||||
setObjectFilterDropdownSearchInput('');
|
setObjectFilterDropdownSearchInput('');
|
||||||
|
|
||||||
|
setObjectFilterDropdownCurrentRecordFilter(newAdvancedFilter);
|
||||||
|
upsertRecordFilter(newAdvancedFilter);
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -0,0 +1,98 @@
|
|||||||
|
import { rootLevelRecordFilterGroupComponentSelector } from '@/object-record/advanced-filter/states/rootLevelRecordFilterGroupComponentSelector';
|
||||||
|
import { getAdvancedFilterObjectFilterDropdownComponentInstanceId } from '@/object-record/advanced-filter/utils/getAdvancedFilterObjectFilterDropdownComponentInstanceId';
|
||||||
|
import { fieldMetadataItemIdUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemIdUsedInDropdownComponentState';
|
||||||
|
import { objectFilterDropdownCurrentRecordFilterComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownCurrentRecordFilterComponentState';
|
||||||
|
import { currentRecordFilterGroupsComponentState } from '@/object-record/record-filter-group/states/currentRecordFilterGroupsComponentState';
|
||||||
|
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||||
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
|
||||||
|
export const useSetAdvancedFilterDropdownStates = () => {
|
||||||
|
const rootLevelRecordFilterGroup = useRecoilComponentValueV2(
|
||||||
|
rootLevelRecordFilterGroupComponentSelector,
|
||||||
|
);
|
||||||
|
|
||||||
|
const currentRecordFilters = useRecoilComponentValueV2(
|
||||||
|
currentRecordFiltersComponentState,
|
||||||
|
);
|
||||||
|
|
||||||
|
const currentRecordFilterGroups = useRecoilComponentValueV2(
|
||||||
|
currentRecordFilterGroupsComponentState,
|
||||||
|
);
|
||||||
|
|
||||||
|
const setAdvancedFilterDropdownStates = useRecoilCallback(
|
||||||
|
({ set }) =>
|
||||||
|
() => {
|
||||||
|
const rootLevelRecordFilters = currentRecordFilters.filter(
|
||||||
|
(recordFilter) =>
|
||||||
|
recordFilter.recordFilterGroupId === rootLevelRecordFilterGroup?.id,
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const rootLevelRecordFilter of rootLevelRecordFilters) {
|
||||||
|
set(
|
||||||
|
objectFilterDropdownCurrentRecordFilterComponentState.atomFamily({
|
||||||
|
instanceId:
|
||||||
|
getAdvancedFilterObjectFilterDropdownComponentInstanceId(
|
||||||
|
rootLevelRecordFilter.id,
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
rootLevelRecordFilter,
|
||||||
|
);
|
||||||
|
|
||||||
|
set(
|
||||||
|
fieldMetadataItemIdUsedInDropdownComponentState.atomFamily({
|
||||||
|
instanceId:
|
||||||
|
getAdvancedFilterObjectFilterDropdownComponentInstanceId(
|
||||||
|
rootLevelRecordFilter.id,
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
rootLevelRecordFilter.fieldMetadataId,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const childRecordFilterGroups = currentRecordFilterGroups.filter(
|
||||||
|
(currentRecordGroupToFilter) =>
|
||||||
|
currentRecordGroupToFilter.parentRecordFilterGroupId ===
|
||||||
|
rootLevelRecordFilterGroup?.id,
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const childRecordFilterGroup of childRecordFilterGroups) {
|
||||||
|
const recordFiltersInThisGroup = currentRecordFilters.filter(
|
||||||
|
(recordFilter) =>
|
||||||
|
recordFilter.recordFilterGroupId === childRecordFilterGroup.id,
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const recordFilterInThisGroup of recordFiltersInThisGroup) {
|
||||||
|
set(
|
||||||
|
objectFilterDropdownCurrentRecordFilterComponentState.atomFamily({
|
||||||
|
instanceId:
|
||||||
|
getAdvancedFilterObjectFilterDropdownComponentInstanceId(
|
||||||
|
recordFilterInThisGroup.id,
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
recordFilterInThisGroup,
|
||||||
|
);
|
||||||
|
|
||||||
|
set(
|
||||||
|
fieldMetadataItemIdUsedInDropdownComponentState.atomFamily({
|
||||||
|
instanceId:
|
||||||
|
getAdvancedFilterObjectFilterDropdownComponentInstanceId(
|
||||||
|
recordFilterInThisGroup.id,
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
recordFilterInThisGroup.fieldMetadataId,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[
|
||||||
|
currentRecordFilterGroups,
|
||||||
|
currentRecordFilters,
|
||||||
|
rootLevelRecordFilterGroup,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
setAdvancedFilterDropdownStates,
|
||||||
|
};
|
||||||
|
};
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import { getAdvancedFilterObjectFilterDropdownComponentInstanceId } from '@/object-record/advanced-filter/utils/getAdvancedFilterObjectFilterDropdownComponentInstanceId';
|
import { getAdvancedFilterObjectFilterDropdownComponentInstanceId } from '@/object-record/advanced-filter/utils/getAdvancedFilterObjectFilterDropdownComponentInstanceId';
|
||||||
import { fieldMetadataItemIdUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemIdUsedInDropdownComponentState';
|
import { fieldMetadataItemIdUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemIdUsedInDropdownComponentState';
|
||||||
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
|
import { objectFilterDropdownCurrentRecordFilterComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownCurrentRecordFilterComponentState';
|
||||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
||||||
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||||
import { useRecoilCallback } from 'recoil';
|
import { useRecoilCallback } from 'recoil';
|
||||||
@ -31,7 +31,7 @@ export const useSetRecordFilterUsedInAdvancedFilterDropdownRow = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
set(
|
set(
|
||||||
selectedFilterComponentState.atomFamily({
|
objectFilterDropdownCurrentRecordFilterComponentState.atomFamily({
|
||||||
instanceId:
|
instanceId:
|
||||||
advancedFilterRowObjectFilterDropdownComponentInstanceId,
|
advancedFilterRowObjectFilterDropdownComponentInstanceId,
|
||||||
}),
|
}),
|
||||||
|
|||||||
@ -1,20 +1,13 @@
|
|||||||
import { useTheme } from '@emotion/react';
|
import { useTheme } from '@emotion/react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
import { v4 } from 'uuid';
|
|
||||||
|
|
||||||
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
import { useApplyObjectFilterDropdownFilterValue } from '@/object-record/object-filter-dropdown/hooks/useApplyObjectFilterDropdownFilterValue';
|
||||||
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
|
import { useObjectFilterDropdownFilterValue } from '@/object-record/object-filter-dropdown/hooks/useObjectFilterDropdownFilterValue';
|
||||||
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
|
|
||||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
|
||||||
import { useApplyRecordFilter } from '@/object-record/record-filter/hooks/useApplyRecordFilter';
|
|
||||||
import { SingleRecordPickerHotkeyScope } from '@/object-record/record-picker/single-record-picker/types/SingleRecordPickerHotkeyScope';
|
import { SingleRecordPickerHotkeyScope } from '@/object-record/record-picker/single-record-picker/types/SingleRecordPickerHotkeyScope';
|
||||||
import { BooleanDisplay } from '@/ui/field/display/components/BooleanDisplay';
|
import { BooleanDisplay } from '@/ui/field/display/components/BooleanDisplay';
|
||||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||||
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
|
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
|
||||||
import { IconCheck } from 'twenty-ui/display';
|
import { IconCheck } from 'twenty-ui/display';
|
||||||
|
|
||||||
const StyledBooleanSelectContainer = styled.div<{ selected?: boolean }>`
|
const StyledBooleanSelectContainer = styled.div<{ selected?: boolean }>`
|
||||||
@ -40,52 +33,20 @@ export const ObjectFilterDropdownBooleanSelect = () => {
|
|||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const options = [true, false];
|
const options = [true, false];
|
||||||
|
|
||||||
const fieldMetadataItemUsedInDropdown = useRecoilComponentValueV2(
|
const { objectFilterDropdownFilterValue } =
|
||||||
fieldMetadataItemUsedInDropdownComponentSelector,
|
useObjectFilterDropdownFilterValue();
|
||||||
);
|
|
||||||
|
|
||||||
const selectedOperandInDropdown = useRecoilComponentValueV2(
|
const { applyObjectFilterDropdownFilterValue } =
|
||||||
selectedOperandInDropdownComponentState,
|
useApplyObjectFilterDropdownFilterValue();
|
||||||
);
|
|
||||||
|
|
||||||
const selectedFilter = useRecoilComponentValueV2(
|
|
||||||
selectedFilterComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const { applyRecordFilter } = useApplyRecordFilter();
|
|
||||||
|
|
||||||
const { closeDropdown } = useDropdown();
|
const { closeDropdown } = useDropdown();
|
||||||
|
|
||||||
const [selectedValue, setSelectedValue] = useState<boolean | undefined>(
|
const handleOptionSelect = (newValue: boolean) => {
|
||||||
selectedFilter?.value === 'true',
|
applyObjectFilterDropdownFilterValue(
|
||||||
);
|
newValue.toString(),
|
||||||
|
newValue ? 'True' : 'False',
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setSelectedValue(selectedFilter?.value === 'true');
|
|
||||||
}, [selectedFilter?.value]);
|
|
||||||
|
|
||||||
const handleOptionSelect = (value: boolean) => {
|
|
||||||
if (
|
|
||||||
!isDefined(fieldMetadataItemUsedInDropdown) ||
|
|
||||||
!isDefined(selectedOperandInDropdown)
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
applyRecordFilter({
|
|
||||||
id: selectedFilter?.id ?? v4(),
|
|
||||||
operand: selectedOperandInDropdown,
|
|
||||||
displayValue: value ? 'True' : 'False',
|
|
||||||
fieldMetadataId: fieldMetadataItemUsedInDropdown.id,
|
|
||||||
value: value.toString(),
|
|
||||||
recordFilterGroupId: selectedFilter?.recordFilterGroupId,
|
|
||||||
positionInRecordFilterGroup: selectedFilter?.positionInRecordFilterGroup,
|
|
||||||
type: getFilterTypeFromFieldType(fieldMetadataItemUsedInDropdown.type),
|
|
||||||
label: fieldMetadataItemUsedInDropdown.label,
|
|
||||||
subFieldName: selectedFilter?.subFieldName,
|
|
||||||
});
|
|
||||||
|
|
||||||
setSelectedValue(value);
|
|
||||||
closeDropdown();
|
closeDropdown();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -100,10 +61,10 @@ export const ObjectFilterDropdownBooleanSelect = () => {
|
|||||||
<StyledBooleanSelectContainer
|
<StyledBooleanSelectContainer
|
||||||
key={String(option)}
|
key={String(option)}
|
||||||
onClick={() => handleOptionSelect(option)}
|
onClick={() => handleOptionSelect(option)}
|
||||||
selected={selectedValue === option}
|
selected={objectFilterDropdownFilterValue === option.toString()}
|
||||||
>
|
>
|
||||||
<BooleanDisplay value={option} />
|
<BooleanDisplay value={option} />
|
||||||
{selectedFilter?.value === option.toString() && (
|
{objectFilterDropdownFilterValue === option.toString() && (
|
||||||
<StyledIconCheckContainer>
|
<StyledIconCheckContainer>
|
||||||
<IconCheck color={theme.grayScale.gray50} size={16} />
|
<IconCheck color={theme.grayScale.gray50} size={16} />
|
||||||
</StyledIconCheckContainer>
|
</StyledIconCheckContainer>
|
||||||
|
|||||||
@ -1,12 +1,7 @@
|
|||||||
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
import { useApplyObjectFilterDropdownFilterValue } from '@/object-record/object-filter-dropdown/hooks/useApplyObjectFilterDropdownFilterValue';
|
||||||
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
|
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
|
||||||
import { objectFilterDropdownSelectedRecordIdsComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedRecordIdsComponentState';
|
import { objectFilterDropdownCurrentRecordFilterComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownCurrentRecordFilterComponentState';
|
||||||
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
|
|
||||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
|
||||||
import { turnCurrencyIntoSelectableItem } from '@/object-record/object-filter-dropdown/utils/turnCurrencyIntoSelectableItem';
|
import { turnCurrencyIntoSelectableItem } from '@/object-record/object-filter-dropdown/utils/turnCurrencyIntoSelectableItem';
|
||||||
import { useApplyRecordFilter } from '@/object-record/record-filter/hooks/useApplyRecordFilter';
|
|
||||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
|
||||||
import { findDuplicateRecordFilterInNonAdvancedRecordFilters } from '@/object-record/record-filter/utils/findDuplicateRecordFilterInNonAdvancedRecordFilters';
|
|
||||||
import { StyledMultipleSelectDropdownAvatarChip } from '@/object-record/select/components/StyledMultipleSelectDropdownAvatarChip';
|
import { StyledMultipleSelectDropdownAvatarChip } from '@/object-record/select/components/StyledMultipleSelectDropdownAvatarChip';
|
||||||
import { SelectableItem } from '@/object-record/select/types/SelectableItem';
|
import { SelectableItem } from '@/object-record/select/types/SelectableItem';
|
||||||
import { CURRENCIES } from '@/settings/data-model/constants/Currencies';
|
import { CURRENCIES } from '@/settings/data-model/constants/Currencies';
|
||||||
@ -14,70 +9,55 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop
|
|||||||
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
|
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
|
||||||
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
|
||||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
|
||||||
import { useLingui } from '@lingui/react/macro';
|
import { useLingui } from '@lingui/react/macro';
|
||||||
|
import { isNonEmptyString } from '@sniptt/guards';
|
||||||
import { ChangeEvent, useState } from 'react';
|
import { ChangeEvent, useState } from 'react';
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
import { MenuItem, MenuItemMultiSelectAvatar } from 'twenty-ui/navigation';
|
import { MenuItem, MenuItemMultiSelectAvatar } from 'twenty-ui/navigation';
|
||||||
import { v4 } from 'uuid';
|
|
||||||
|
|
||||||
export const EMPTY_FILTER_VALUE = '[]';
|
export const EMPTY_FILTER_VALUE = '[]';
|
||||||
export const MAX_ITEMS_TO_DISPLAY = 3;
|
export const MAX_ITEMS_TO_DISPLAY = 3;
|
||||||
|
|
||||||
type ObjectFilterDropdownCurrencySelectProps = {
|
type ObjectFilterDropdownCurrencySelectProps = {
|
||||||
viewComponentId?: string;
|
|
||||||
dropdownWidth?: number;
|
dropdownWidth?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ObjectFilterDropdownCurrencySelect = ({
|
export const ObjectFilterDropdownCurrencySelect = ({
|
||||||
viewComponentId,
|
|
||||||
dropdownWidth,
|
dropdownWidth,
|
||||||
}: ObjectFilterDropdownCurrencySelectProps) => {
|
}: ObjectFilterDropdownCurrencySelectProps) => {
|
||||||
const [searchText, setSearchText] = useState('');
|
const [searchText, setSearchText] = useState('');
|
||||||
|
|
||||||
const selectedFilter = useRecoilComponentValueV2(
|
const objectFilterDropdownCurrentRecordFilter = useRecoilComponentValueV2(
|
||||||
selectedFilterComponentState,
|
objectFilterDropdownCurrentRecordFilterComponentState,
|
||||||
);
|
);
|
||||||
|
|
||||||
const setObjectFilterDropdownSelectedRecordIds = useSetRecoilComponentStateV2(
|
const { applyObjectFilterDropdownFilterValue } =
|
||||||
objectFilterDropdownSelectedRecordIdsComponentState,
|
useApplyObjectFilterDropdownFilterValue();
|
||||||
selectedFilter?.id,
|
|
||||||
);
|
|
||||||
|
|
||||||
const objectFilterDropdownSelectedRecordIds = useRecoilComponentValueV2(
|
|
||||||
objectFilterDropdownSelectedRecordIdsComponentState,
|
|
||||||
selectedFilter?.id,
|
|
||||||
);
|
|
||||||
|
|
||||||
const selectedOperandInDropdown = useRecoilComponentValueV2(
|
|
||||||
selectedOperandInDropdownComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const fieldMetadataItemUsedInFilterDropdown = useRecoilComponentValueV2(
|
const fieldMetadataItemUsedInFilterDropdown = useRecoilComponentValueV2(
|
||||||
fieldMetadataItemUsedInDropdownComponentSelector,
|
fieldMetadataItemUsedInDropdownComponentSelector,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { applyRecordFilter } = useApplyRecordFilter(viewComponentId);
|
|
||||||
|
|
||||||
const currenciesAsSelectableItems = CURRENCIES.map(
|
const currenciesAsSelectableItems = CURRENCIES.map(
|
||||||
turnCurrencyIntoSelectableItem,
|
turnCurrencyIntoSelectableItem,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const selectedCurrencies = isNonEmptyString(
|
||||||
|
objectFilterDropdownCurrentRecordFilter?.value,
|
||||||
|
)
|
||||||
|
? (JSON.parse(objectFilterDropdownCurrentRecordFilter.value) as string[]) // TODO: replace by a safe parse
|
||||||
|
: [];
|
||||||
|
|
||||||
const filteredSelectableItems = currenciesAsSelectableItems.filter(
|
const filteredSelectableItems = currenciesAsSelectableItems.filter(
|
||||||
(selectableItem) =>
|
(selectableItem) =>
|
||||||
selectableItem.name.toLowerCase().includes(searchText.toLowerCase()) &&
|
selectableItem.name.toLowerCase().includes(searchText.toLowerCase()) &&
|
||||||
!objectFilterDropdownSelectedRecordIds.includes(selectableItem.id),
|
!selectedCurrencies.includes(selectableItem.id),
|
||||||
);
|
);
|
||||||
|
|
||||||
const filteredSelectedItems = currenciesAsSelectableItems.filter(
|
const filteredSelectedItems = currenciesAsSelectableItems.filter(
|
||||||
(selectableItem) =>
|
(selectableItem) =>
|
||||||
selectableItem.name.toLowerCase().includes(searchText.toLowerCase()) &&
|
selectableItem.name.toLowerCase().includes(searchText.toLowerCase()) &&
|
||||||
objectFilterDropdownSelectedRecordIds.includes(selectableItem.id),
|
selectedCurrencies.includes(selectableItem.id),
|
||||||
);
|
|
||||||
|
|
||||||
const currentRecordFilters = useRecoilComponentValueV2(
|
|
||||||
currentRecordFiltersComponentState,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleMultipleItemSelectChange = (
|
const handleMultipleItemSelectChange = (
|
||||||
@ -85,10 +65,8 @@ export const ObjectFilterDropdownCurrencySelect = ({
|
|||||||
newSelectedValue: boolean,
|
newSelectedValue: boolean,
|
||||||
) => {
|
) => {
|
||||||
const newSelectedItemIds = newSelectedValue
|
const newSelectedItemIds = newSelectedValue
|
||||||
? [...objectFilterDropdownSelectedRecordIds, itemToSelect.id]
|
? [...selectedCurrencies, itemToSelect.id]
|
||||||
: objectFilterDropdownSelectedRecordIds.filter(
|
: selectedCurrencies.filter((id) => id !== itemToSelect.id);
|
||||||
(id) => id !== itemToSelect.id,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!isDefined(fieldMetadataItemUsedInFilterDropdown)) {
|
if (!isDefined(fieldMetadataItemUsedInFilterDropdown)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
@ -96,8 +74,6 @@ export const ObjectFilterDropdownCurrencySelect = ({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
setObjectFilterDropdownSelectedRecordIds(newSelectedItemIds);
|
|
||||||
|
|
||||||
const selectedItemNames = currenciesAsSelectableItems
|
const selectedItemNames = currenciesAsSelectableItems
|
||||||
.filter((option) => newSelectedItemIds.includes(option.id))
|
.filter((option) => newSelectedItemIds.includes(option.id))
|
||||||
.map((option) => option.name);
|
.map((option) => option.name);
|
||||||
@ -107,46 +83,12 @@ export const ObjectFilterDropdownCurrencySelect = ({
|
|||||||
? `${selectedItemNames.length} currencies`
|
? `${selectedItemNames.length} currencies`
|
||||||
: selectedItemNames.join(', ');
|
: selectedItemNames.join(', ');
|
||||||
|
|
||||||
if (
|
const newFilterValue =
|
||||||
isDefined(fieldMetadataItemUsedInFilterDropdown) &&
|
newSelectedItemIds.length > 0
|
||||||
isDefined(selectedOperandInDropdown)
|
? JSON.stringify(newSelectedItemIds)
|
||||||
) {
|
: EMPTY_FILTER_VALUE;
|
||||||
const newFilterValue =
|
|
||||||
newSelectedItemIds.length > 0
|
|
||||||
? JSON.stringify(newSelectedItemIds)
|
|
||||||
: EMPTY_FILTER_VALUE;
|
|
||||||
|
|
||||||
const duplicateFilterInCurrentRecordFilters =
|
applyObjectFilterDropdownFilterValue(newFilterValue, filterDisplayValue);
|
||||||
findDuplicateRecordFilterInNonAdvancedRecordFilters({
|
|
||||||
recordFilters: currentRecordFilters,
|
|
||||||
fieldMetadataItemId: fieldMetadataItemUsedInFilterDropdown.id,
|
|
||||||
subFieldName: 'currencyCode',
|
|
||||||
});
|
|
||||||
|
|
||||||
const filterIsAlreadyInCurrentRecordFilters = isDefined(
|
|
||||||
duplicateFilterInCurrentRecordFilters,
|
|
||||||
);
|
|
||||||
|
|
||||||
const filterId = filterIsAlreadyInCurrentRecordFilters
|
|
||||||
? duplicateFilterInCurrentRecordFilters?.id
|
|
||||||
: v4();
|
|
||||||
|
|
||||||
applyRecordFilter({
|
|
||||||
id: selectedFilter?.id ? selectedFilter.id : filterId,
|
|
||||||
type: getFilterTypeFromFieldType(
|
|
||||||
fieldMetadataItemUsedInFilterDropdown.type,
|
|
||||||
),
|
|
||||||
label: fieldMetadataItemUsedInFilterDropdown.label,
|
|
||||||
operand: selectedOperandInDropdown || ViewFilterOperand.Is,
|
|
||||||
displayValue: filterDisplayValue,
|
|
||||||
fieldMetadataId: fieldMetadataItemUsedInFilterDropdown.id,
|
|
||||||
value: newFilterValue,
|
|
||||||
recordFilterGroupId: selectedFilter?.recordFilterGroupId,
|
|
||||||
subFieldName: 'currencyCode',
|
|
||||||
positionInRecordFilterGroup:
|
|
||||||
selectedFilter?.positionInRecordFilterGroup,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const showNoResult =
|
const showNoResult =
|
||||||
|
|||||||
@ -1,11 +1,8 @@
|
|||||||
import { v4 } from 'uuid';
|
import { useApplyObjectFilterDropdownFilterValue } from '@/object-record/object-filter-dropdown/hooks/useApplyObjectFilterDropdownFilterValue';
|
||||||
|
|
||||||
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
|
||||||
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
|
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
|
||||||
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
|
import { objectFilterDropdownCurrentRecordFilterComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownCurrentRecordFilterComponentState';
|
||||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
||||||
import { getRelativeDateDisplayValue } from '@/object-record/object-filter-dropdown/utils/getRelativeDateDisplayValue';
|
import { getRelativeDateDisplayValue } from '@/object-record/object-filter-dropdown/utils/getRelativeDateDisplayValue';
|
||||||
import { useApplyRecordFilter } from '@/object-record/record-filter/hooks/useApplyRecordFilter';
|
|
||||||
import { DateTimePicker } from '@/ui/input/components/internal/date/components/InternalDatePicker';
|
import { DateTimePicker } from '@/ui/input/components/internal/date/components/InternalDatePicker';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
||||||
@ -28,15 +25,17 @@ export const ObjectFilterDropdownDateInput = () => {
|
|||||||
selectedOperandInDropdownComponentState,
|
selectedOperandInDropdownComponentState,
|
||||||
);
|
);
|
||||||
|
|
||||||
const selectedFilter = useRecoilComponentValueV2(
|
const objectFilterDropdownCurrentRecordFilter = useRecoilComponentValueV2(
|
||||||
selectedFilterComponentState,
|
objectFilterDropdownCurrentRecordFilterComponentState,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { applyRecordFilter } = useApplyRecordFilter();
|
const { applyObjectFilterDropdownFilterValue } =
|
||||||
|
useApplyObjectFilterDropdownFilterValue();
|
||||||
|
|
||||||
const initialFilterValue = selectedFilter
|
const initialFilterValue = isDefined(objectFilterDropdownCurrentRecordFilter)
|
||||||
? resolveDateViewFilterValue(selectedFilter)
|
? resolveDateViewFilterValue(objectFilterDropdownCurrentRecordFilter)
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
const [internalDate, setInternalDate] = useState<Date | null>(
|
const [internalDate, setInternalDate] = useState<Date | null>(
|
||||||
initialFilterValue instanceof Date ? initialFilterValue : null,
|
initialFilterValue instanceof Date ? initialFilterValue : null,
|
||||||
);
|
);
|
||||||
@ -47,24 +46,14 @@ export const ObjectFilterDropdownDateInput = () => {
|
|||||||
const handleAbsoluteDateChange = (newDate: Date | null) => {
|
const handleAbsoluteDateChange = (newDate: Date | null) => {
|
||||||
setInternalDate(newDate);
|
setInternalDate(newDate);
|
||||||
|
|
||||||
if (!fieldMetadataItemUsedInDropdown || !selectedOperandInDropdown) return;
|
const newFilterValue = newDate?.toISOString() ?? '';
|
||||||
|
const newDisplayValue = isDefined(newDate)
|
||||||
|
? isDateTimeInput
|
||||||
|
? newDate.toLocaleString()
|
||||||
|
: newDate.toLocaleDateString()
|
||||||
|
: '';
|
||||||
|
|
||||||
applyRecordFilter({
|
applyObjectFilterDropdownFilterValue(newFilterValue, newDisplayValue);
|
||||||
id: selectedFilter?.id ? selectedFilter.id : v4(),
|
|
||||||
fieldMetadataId: fieldMetadataItemUsedInDropdown.id,
|
|
||||||
value: newDate?.toISOString() ?? '',
|
|
||||||
operand: selectedOperandInDropdown,
|
|
||||||
displayValue: isDefined(newDate)
|
|
||||||
? isDateTimeInput
|
|
||||||
? newDate.toLocaleString()
|
|
||||||
: newDate.toLocaleDateString()
|
|
||||||
: '',
|
|
||||||
recordFilterGroupId: selectedFilter?.recordFilterGroupId,
|
|
||||||
positionInRecordFilterGroup: selectedFilter?.positionInRecordFilterGroup,
|
|
||||||
type: getFilterTypeFromFieldType(fieldMetadataItemUsedInDropdown.type),
|
|
||||||
label: fieldMetadataItemUsedInDropdown.label,
|
|
||||||
subFieldName: selectedFilter?.subFieldName,
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRelativeDateChange = (
|
const handleRelativeDateChange = (
|
||||||
@ -74,9 +63,7 @@ export const ObjectFilterDropdownDateInput = () => {
|
|||||||
unit: VariableDateViewFilterValueUnit;
|
unit: VariableDateViewFilterValueUnit;
|
||||||
} | null,
|
} | null,
|
||||||
) => {
|
) => {
|
||||||
if (!fieldMetadataItemUsedInDropdown || !selectedOperandInDropdown) return;
|
const newFilterValue = relativeDate
|
||||||
|
|
||||||
const value = relativeDate
|
|
||||||
? computeVariableDateViewFilterValue(
|
? computeVariableDateViewFilterValue(
|
||||||
relativeDate.direction,
|
relativeDate.direction,
|
||||||
relativeDate.amount,
|
relativeDate.amount,
|
||||||
@ -84,24 +71,18 @@ export const ObjectFilterDropdownDateInput = () => {
|
|||||||
)
|
)
|
||||||
: '';
|
: '';
|
||||||
|
|
||||||
applyRecordFilter({
|
const newDisplayValue = relativeDate
|
||||||
id: selectedFilter?.id ? selectedFilter.id : v4(),
|
? getRelativeDateDisplayValue(relativeDate)
|
||||||
fieldMetadataId: fieldMetadataItemUsedInDropdown.id,
|
: '';
|
||||||
value,
|
|
||||||
operand: selectedOperandInDropdown,
|
applyObjectFilterDropdownFilterValue(newFilterValue, newDisplayValue);
|
||||||
displayValue: getRelativeDateDisplayValue(relativeDate),
|
|
||||||
recordFilterGroupId: selectedFilter?.recordFilterGroupId,
|
|
||||||
positionInRecordFilterGroup: selectedFilter?.positionInRecordFilterGroup,
|
|
||||||
type: getFilterTypeFromFieldType(fieldMetadataItemUsedInDropdown.type),
|
|
||||||
label: fieldMetadataItemUsedInDropdown.label,
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const isRelativeOperand =
|
const isRelativeOperand =
|
||||||
selectedOperandInDropdown === ViewFilterOperand.IsRelative;
|
selectedOperandInDropdown === ViewFilterOperand.IsRelative;
|
||||||
|
|
||||||
const resolvedValue = selectedFilter
|
const resolvedValue = objectFilterDropdownCurrentRecordFilter
|
||||||
? resolveDateViewFilterValue(selectedFilter)
|
? resolveDateViewFilterValue(objectFilterDropdownCurrentRecordFilter)
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
const relativeDate =
|
const relativeDate =
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
|||||||
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
||||||
import { FILTER_FIELD_LIST_ID } from '@/object-record/object-filter-dropdown/constants/FilterFieldListId';
|
import { FILTER_FIELD_LIST_ID } from '@/object-record/object-filter-dropdown/constants/FilterFieldListId';
|
||||||
import { objectFilterDropdownCurrentRecordFilterComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownCurrentRecordFilterComponentState';
|
import { objectFilterDropdownCurrentRecordFilterComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownCurrentRecordFilterComponentState';
|
||||||
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
|
|
||||||
import { isCompositeFieldType } from '@/object-record/object-filter-dropdown/utils/isCompositeFieldType';
|
import { isCompositeFieldType } from '@/object-record/object-filter-dropdown/utils/isCompositeFieldType';
|
||||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||||
import { findDuplicateRecordFilterInNonAdvancedRecordFilters } from '@/object-record/record-filter/utils/findDuplicateRecordFilterInNonAdvancedRecordFilters';
|
import { findDuplicateRecordFilterInNonAdvancedRecordFilters } from '@/object-record/record-filter/utils/findDuplicateRecordFilterInNonAdvancedRecordFilters';
|
||||||
@ -68,10 +67,6 @@ export const ObjectFilterDropdownFilterSelectMenuItem = ({
|
|||||||
currentRecordFiltersComponentState,
|
currentRecordFiltersComponentState,
|
||||||
);
|
);
|
||||||
|
|
||||||
const setSelectedFilter = useSetRecoilComponentStateV2(
|
|
||||||
selectedFilterComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const setObjectFilterDropdownCurrentRecordFilter =
|
const setObjectFilterDropdownCurrentRecordFilter =
|
||||||
useSetRecoilComponentStateV2(
|
useSetRecoilComponentStateV2(
|
||||||
objectFilterDropdownCurrentRecordFilterComponentState,
|
objectFilterDropdownCurrentRecordFilterComponentState,
|
||||||
@ -103,8 +98,6 @@ export const ObjectFilterDropdownFilterSelectMenuItem = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (filterIsAlreadyInCurrentRecordFilters) {
|
if (filterIsAlreadyInCurrentRecordFilters) {
|
||||||
setSelectedFilter(duplicateFilterInCurrentRecordFilters);
|
|
||||||
|
|
||||||
setObjectFilterDropdownCurrentRecordFilter(
|
setObjectFilterDropdownCurrentRecordFilter(
|
||||||
duplicateFilterInCurrentRecordFilters,
|
duplicateFilterInCurrentRecordFilters,
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,41 +1,25 @@
|
|||||||
import { ChangeEvent, useCallback, useState } from 'react';
|
import { ChangeEvent, useCallback, useState } from 'react';
|
||||||
import { v4 } from 'uuid';
|
|
||||||
|
|
||||||
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
import { useApplyObjectFilterDropdownFilterValue } from '@/object-record/object-filter-dropdown/hooks/useApplyObjectFilterDropdownFilterValue';
|
||||||
|
import { useObjectFilterDropdownFilterValue } from '@/object-record/object-filter-dropdown/hooks/useObjectFilterDropdownFilterValue';
|
||||||
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
|
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
|
||||||
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
|
|
||||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
|
||||||
import { subFieldNameUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/subFieldNameUsedInDropdownComponentState';
|
|
||||||
import { useApplyRecordFilter } from '@/object-record/record-filter/hooks/useApplyRecordFilter';
|
|
||||||
import { DropdownMenuInput } from '@/ui/layout/dropdown/components/DropdownMenuInput';
|
import { DropdownMenuInput } from '@/ui/layout/dropdown/components/DropdownMenuInput';
|
||||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
|
|
||||||
export const ObjectFilterDropdownNumberInput = () => {
|
export const ObjectFilterDropdownNumberInput = () => {
|
||||||
const selectedOperandInDropdown = useRecoilComponentValueV2(
|
|
||||||
selectedOperandInDropdownComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const fieldMetadataItemUsedInDropdown = useRecoilComponentValueV2(
|
const fieldMetadataItemUsedInDropdown = useRecoilComponentValueV2(
|
||||||
fieldMetadataItemUsedInDropdownComponentSelector,
|
fieldMetadataItemUsedInDropdownComponentSelector,
|
||||||
);
|
);
|
||||||
|
|
||||||
const selectedFilter = useRecoilComponentValueV2(
|
const { objectFilterDropdownFilterValue } =
|
||||||
selectedFilterComponentState,
|
useObjectFilterDropdownFilterValue();
|
||||||
);
|
|
||||||
|
|
||||||
const subFieldNameUsedInDropdown = useRecoilComponentValueV2(
|
const { applyObjectFilterDropdownFilterValue } =
|
||||||
subFieldNameUsedInDropdownComponentState,
|
useApplyObjectFilterDropdownFilterValue();
|
||||||
);
|
|
||||||
|
|
||||||
const { applyRecordFilter } = useApplyRecordFilter();
|
|
||||||
|
|
||||||
const [hasFocused, setHasFocused] = useState(false);
|
const [hasFocused, setHasFocused] = useState(false);
|
||||||
|
|
||||||
const [inputValue, setInputValue] = useState(
|
|
||||||
() => selectedFilter?.value || '',
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleInputRef = useCallback(
|
const handleInputRef = useCallback(
|
||||||
(node: HTMLInputElement | null) => {
|
(node: HTMLInputElement | null) => {
|
||||||
if (Boolean(node) && !hasFocused) {
|
if (Boolean(node) && !hasFocused) {
|
||||||
@ -47,39 +31,22 @@ export const ObjectFilterDropdownNumberInput = () => {
|
|||||||
[hasFocused],
|
[hasFocused],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const newValue = event.target.value;
|
||||||
|
|
||||||
|
applyObjectFilterDropdownFilterValue(newValue);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
fieldMetadataItemUsedInDropdown &&
|
<DropdownMenuItemsContainer>
|
||||||
selectedOperandInDropdown && (
|
<DropdownMenuInput
|
||||||
<DropdownMenuItemsContainer>
|
ref={handleInputRef}
|
||||||
<DropdownMenuInput
|
value={objectFilterDropdownFilterValue}
|
||||||
ref={handleInputRef}
|
autoFocus
|
||||||
value={inputValue}
|
type="number"
|
||||||
autoFocus
|
placeholder={fieldMetadataItemUsedInDropdown?.label}
|
||||||
type="number"
|
onChange={handleInputChange}
|
||||||
placeholder={fieldMetadataItemUsedInDropdown.label}
|
/>
|
||||||
onChange={(event: ChangeEvent<HTMLInputElement>) => {
|
</DropdownMenuItemsContainer>
|
||||||
const newValue = event.target.value;
|
|
||||||
|
|
||||||
setInputValue(newValue);
|
|
||||||
|
|
||||||
applyRecordFilter({
|
|
||||||
id: selectedFilter?.id ? selectedFilter.id : v4(),
|
|
||||||
fieldMetadataId: fieldMetadataItemUsedInDropdown?.id ?? '',
|
|
||||||
value: newValue,
|
|
||||||
operand: selectedOperandInDropdown,
|
|
||||||
displayValue: newValue,
|
|
||||||
type: getFilterTypeFromFieldType(
|
|
||||||
fieldMetadataItemUsedInDropdown.type,
|
|
||||||
),
|
|
||||||
label: fieldMetadataItemUsedInDropdown.label,
|
|
||||||
recordFilterGroupId: selectedFilter?.recordFilterGroupId,
|
|
||||||
positionInRecordFilterGroup:
|
|
||||||
selectedFilter?.positionInRecordFilterGroup,
|
|
||||||
subFieldName: subFieldNameUsedInDropdown,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</DropdownMenuItemsContainer>
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,22 +1,16 @@
|
|||||||
import { v4 } from 'uuid';
|
|
||||||
|
|
||||||
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
||||||
|
import { useApplyObjectFilterDropdownOperand } from '@/object-record/object-filter-dropdown/hooks/useApplyObjectFilterDropdownOperand';
|
||||||
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
|
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
|
||||||
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
|
|
||||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
|
||||||
import { subFieldNameUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/subFieldNameUsedInDropdownComponentState';
|
import { subFieldNameUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/subFieldNameUsedInDropdownComponentState';
|
||||||
import { getInitialFilterValue } from '@/object-record/object-filter-dropdown/utils/getInitialFilterValue';
|
|
||||||
import { useApplyRecordFilter } from '@/object-record/record-filter/hooks/useApplyRecordFilter';
|
|
||||||
import { getRecordFilterOperands } from '@/object-record/record-filter/utils/getRecordFilterOperands';
|
import { getRecordFilterOperands } from '@/object-record/record-filter/utils/getRecordFilterOperands';
|
||||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
|
||||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
import { getOperandLabel } from '../utils/getOperandLabel';
|
|
||||||
import { MenuItem } from 'twenty-ui/navigation';
|
import { MenuItem } from 'twenty-ui/navigation';
|
||||||
|
import { getOperandLabel } from '../utils/getOperandLabel';
|
||||||
|
|
||||||
const StyledDropdownMenuItemsContainer = styled(DropdownMenuItemsContainer)`
|
const StyledDropdownMenuItemsContainer = styled(DropdownMenuItemsContainer)`
|
||||||
background-color: ${({ theme }) => theme.background.primary};
|
background-color: ${({ theme }) => theme.background.primary};
|
||||||
@ -28,19 +22,12 @@ export const ObjectFilterDropdownOperandSelect = () => {
|
|||||||
fieldMetadataItemUsedInDropdownComponentSelector,
|
fieldMetadataItemUsedInDropdownComponentSelector,
|
||||||
);
|
);
|
||||||
|
|
||||||
const setSelectedOperandInDropdown = useSetRecoilComponentStateV2(
|
|
||||||
selectedOperandInDropdownComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const selectedFilter = useRecoilComponentValueV2(
|
|
||||||
selectedFilterComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const subFieldNameUsedInDropdown = useRecoilComponentValueV2(
|
const subFieldNameUsedInDropdown = useRecoilComponentValueV2(
|
||||||
subFieldNameUsedInDropdownComponentState,
|
subFieldNameUsedInDropdownComponentState,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { applyRecordFilter } = useApplyRecordFilter();
|
const { applyObjectFilterDropdownOperand } =
|
||||||
|
useApplyObjectFilterDropdownOperand();
|
||||||
|
|
||||||
const { closeDropdown } = useDropdown();
|
const { closeDropdown } = useDropdown();
|
||||||
|
|
||||||
@ -54,56 +41,7 @@ export const ObjectFilterDropdownOperandSelect = () => {
|
|||||||
: [];
|
: [];
|
||||||
|
|
||||||
const handleOperandChange = (newOperand: ViewFilterOperand) => {
|
const handleOperandChange = (newOperand: ViewFilterOperand) => {
|
||||||
const isValuelessOperand = [
|
applyObjectFilterDropdownOperand(newOperand);
|
||||||
ViewFilterOperand.IsEmpty,
|
|
||||||
ViewFilterOperand.IsNotEmpty,
|
|
||||||
ViewFilterOperand.IsInPast,
|
|
||||||
ViewFilterOperand.IsInFuture,
|
|
||||||
ViewFilterOperand.IsToday,
|
|
||||||
].includes(newOperand);
|
|
||||||
|
|
||||||
setSelectedOperandInDropdown(newOperand);
|
|
||||||
|
|
||||||
if (isValuelessOperand && isDefined(fieldMetadataItemUsedInDropdown)) {
|
|
||||||
applyRecordFilter({
|
|
||||||
id: selectedFilter?.id ? selectedFilter.id : v4(),
|
|
||||||
fieldMetadataId: fieldMetadataItemUsedInDropdown.id,
|
|
||||||
displayValue: '',
|
|
||||||
operand: newOperand,
|
|
||||||
value: '',
|
|
||||||
type: getFilterTypeFromFieldType(fieldMetadataItemUsedInDropdown.type),
|
|
||||||
label: fieldMetadataItemUsedInDropdown.label,
|
|
||||||
subFieldName: subFieldNameUsedInDropdown,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
isDefined(fieldMetadataItemUsedInDropdown) &&
|
|
||||||
isDefined(selectedFilter)
|
|
||||||
) {
|
|
||||||
const filterType = getFilterTypeFromFieldType(
|
|
||||||
fieldMetadataItemUsedInDropdown.type,
|
|
||||||
);
|
|
||||||
|
|
||||||
const { value, displayValue } = getInitialFilterValue(
|
|
||||||
filterType,
|
|
||||||
newOperand,
|
|
||||||
selectedFilter.value,
|
|
||||||
selectedFilter.displayValue,
|
|
||||||
);
|
|
||||||
|
|
||||||
applyRecordFilter({
|
|
||||||
id: selectedFilter.id ? selectedFilter.id : v4(),
|
|
||||||
fieldMetadataId: selectedFilter.fieldMetadataId,
|
|
||||||
displayValue,
|
|
||||||
operand: newOperand,
|
|
||||||
value,
|
|
||||||
type: filterType,
|
|
||||||
label: fieldMetadataItemUsedInDropdown.label,
|
|
||||||
subFieldName: subFieldNameUsedInDropdown,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
import { Key } from 'ts-key-enum';
|
import { Key } from 'ts-key-enum';
|
||||||
import { v4 } from 'uuid';
|
|
||||||
|
|
||||||
import { FieldMetadataItemOption } from '@/object-metadata/types/FieldMetadataItem';
|
import { FieldMetadataItemOption } from '@/object-metadata/types/FieldMetadataItem';
|
||||||
import { useOptionsForSelect } from '@/object-record/object-filter-dropdown/hooks/useOptionsForSelect';
|
import { useOptionsForSelect } from '@/object-record/object-filter-dropdown/hooks/useOptionsForSelect';
|
||||||
@ -10,19 +9,17 @@ import { SelectableList } from '@/ui/layout/selectable-list/components/Selectabl
|
|||||||
|
|
||||||
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
|
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
|
||||||
|
|
||||||
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
import { useApplyObjectFilterDropdownFilterValue } from '@/object-record/object-filter-dropdown/hooks/useApplyObjectFilterDropdownFilterValue';
|
||||||
import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext';
|
import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext';
|
||||||
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
|
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
|
||||||
|
import { objectFilterDropdownCurrentRecordFilterComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownCurrentRecordFilterComponentState';
|
||||||
import { objectFilterDropdownSearchInputComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputComponentState';
|
import { objectFilterDropdownSearchInputComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputComponentState';
|
||||||
import { objectFilterDropdownSelectedOptionValuesComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedOptionValuesComponentState';
|
|
||||||
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
|
|
||||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
|
||||||
import { useApplyRecordFilter } from '@/object-record/record-filter/hooks/useApplyRecordFilter';
|
|
||||||
import { SingleRecordPickerHotkeyScope } from '@/object-record/record-picker/single-record-picker/types/SingleRecordPickerHotkeyScope';
|
import { SingleRecordPickerHotkeyScope } from '@/object-record/record-picker/single-record-picker/types/SingleRecordPickerHotkeyScope';
|
||||||
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
|
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
|
||||||
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
||||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
|
import { isNonEmptyString } from '@sniptt/guards';
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
import { MenuItem, MenuItemMultiSelect } from 'twenty-ui/navigation';
|
import { MenuItem, MenuItemMultiSelect } from 'twenty-ui/navigation';
|
||||||
|
|
||||||
@ -38,27 +35,30 @@ export const ObjectFilterDropdownOptionSelect = () => {
|
|||||||
fieldMetadataItemUsedInDropdownComponentSelector,
|
fieldMetadataItemUsedInDropdownComponentSelector,
|
||||||
);
|
);
|
||||||
|
|
||||||
const objectFilterDropdownSelectedOptionValues = useRecoilComponentValueV2(
|
|
||||||
objectFilterDropdownSelectedOptionValuesComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const selectedFilter = useRecoilComponentValueV2(
|
|
||||||
selectedFilterComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const objectFilterDropdownSearchInput = useRecoilComponentValueV2(
|
const objectFilterDropdownSearchInput = useRecoilComponentValueV2(
|
||||||
objectFilterDropdownSearchInputComponentState,
|
objectFilterDropdownSearchInputComponentState,
|
||||||
);
|
);
|
||||||
|
|
||||||
const selectedOperandInDropdown = useRecoilComponentValueV2(
|
|
||||||
selectedOperandInDropdownComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const componentInstanceId = useAvailableComponentInstanceIdOrThrow(
|
const componentInstanceId = useAvailableComponentInstanceIdOrThrow(
|
||||||
ObjectFilterDropdownComponentInstanceContext,
|
ObjectFilterDropdownComponentInstanceContext,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { applyRecordFilter } = useApplyRecordFilter();
|
const objectFilterDropdownCurrentRecordFilter = useRecoilComponentValueV2(
|
||||||
|
objectFilterDropdownCurrentRecordFilterComponentState,
|
||||||
|
);
|
||||||
|
|
||||||
|
const { applyObjectFilterDropdownFilterValue } =
|
||||||
|
useApplyObjectFilterDropdownFilterValue();
|
||||||
|
|
||||||
|
const selectedOptions = useMemo(
|
||||||
|
() =>
|
||||||
|
isNonEmptyString(objectFilterDropdownCurrentRecordFilter?.value)
|
||||||
|
? (JSON.parse(
|
||||||
|
objectFilterDropdownCurrentRecordFilter.value,
|
||||||
|
) as string[]) // TODO: replace by a safe parse
|
||||||
|
: [],
|
||||||
|
[objectFilterDropdownCurrentRecordFilter?.value],
|
||||||
|
);
|
||||||
|
|
||||||
const { closeDropdown } = useDropdown();
|
const { closeDropdown } = useDropdown();
|
||||||
|
|
||||||
@ -80,9 +80,7 @@ export const ObjectFilterDropdownOptionSelect = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isDefined(selectOptions)) {
|
if (isDefined(selectOptions)) {
|
||||||
const options = selectOptions.map((option) => {
|
const options = selectOptions.map((option) => {
|
||||||
const isSelected =
|
const isSelected = selectedOptions?.includes(option.value) ?? false;
|
||||||
objectFilterDropdownSelectedOptionValues?.includes(option.value) ??
|
|
||||||
false;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...option,
|
...option,
|
||||||
@ -92,7 +90,7 @@ export const ObjectFilterDropdownOptionSelect = () => {
|
|||||||
|
|
||||||
setSelectableOptions(options);
|
setSelectableOptions(options);
|
||||||
}
|
}
|
||||||
}, [objectFilterDropdownSelectedOptionValues, selectOptions]);
|
}, [selectedOptions, selectOptions]);
|
||||||
|
|
||||||
useScopedHotkeys(
|
useScopedHotkeys(
|
||||||
[Key.Escape],
|
[Key.Escape],
|
||||||
@ -127,29 +125,13 @@ export const ObjectFilterDropdownOptionSelect = () => {
|
|||||||
? `${selectedOptions.length} options`
|
? `${selectedOptions.length} options`
|
||||||
: selectedOptions.map((option) => option.label).join(', ');
|
: selectedOptions.map((option) => option.label).join(', ');
|
||||||
|
|
||||||
if (
|
const newFilterValue =
|
||||||
isDefined(fieldMetadataItemUsedInDropdown) &&
|
selectedOptions.length > 0
|
||||||
isDefined(selectedOperandInDropdown)
|
? JSON.stringify(selectedOptions.map((option) => option.value))
|
||||||
) {
|
: EMPTY_FILTER_VALUE;
|
||||||
const newFilterValue =
|
|
||||||
selectedOptions.length > 0
|
applyObjectFilterDropdownFilterValue(newFilterValue, filterDisplayValue);
|
||||||
? JSON.stringify(selectedOptions.map((option) => option.value))
|
|
||||||
: EMPTY_FILTER_VALUE;
|
|
||||||
|
|
||||||
applyRecordFilter({
|
|
||||||
id: selectedFilter?.id ? selectedFilter.id : v4(),
|
|
||||||
type: getFilterTypeFromFieldType(fieldMetadataItemUsedInDropdown.type),
|
|
||||||
label: fieldMetadataItemUsedInDropdown.label,
|
|
||||||
operand: selectedOperandInDropdown,
|
|
||||||
displayValue: filterDisplayValue,
|
|
||||||
fieldMetadataId: fieldMetadataItemUsedInDropdown.id,
|
|
||||||
value: newFilterValue,
|
|
||||||
recordFilterGroupId: selectedFilter?.recordFilterGroupId,
|
|
||||||
positionInRecordFilterGroup:
|
|
||||||
selectedFilter?.positionInRecordFilterGroup,
|
|
||||||
subFieldName: selectedFilter?.subFieldName,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
resetSelectedItem();
|
resetSelectedItem();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,15 +1,9 @@
|
|||||||
import { v4 } from 'uuid';
|
|
||||||
|
|
||||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
|
||||||
import { RATING_VALUES } from '@/object-record/record-field/meta-types/constants/RatingValues';
|
import { RATING_VALUES } from '@/object-record/record-field/meta-types/constants/RatingValues';
|
||||||
import { FieldRatingValue } from '@/object-record/record-field/types/FieldMetadata';
|
import { FieldRatingValue } from '@/object-record/record-field/types/FieldMetadata';
|
||||||
import { useApplyRecordFilter } from '@/object-record/record-filter/hooks/useApplyRecordFilter';
|
|
||||||
import { RatingInput } from '@/ui/field/input/components/RatingInput';
|
import { RatingInput } from '@/ui/field/input/components/RatingInput';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
|
||||||
|
|
||||||
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
import { useApplyObjectFilterDropdownFilterValue } from '@/object-record/object-filter-dropdown/hooks/useApplyObjectFilterDropdownFilterValue';
|
||||||
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
|
import { useObjectFilterDropdownFilterValue } from '@/object-record/object-filter-dropdown/hooks/useObjectFilterDropdownFilterValue';
|
||||||
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
|
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
const StyledRatingInputContainer = styled.div`
|
const StyledRatingInputContainer = styled.div`
|
||||||
@ -35,53 +29,37 @@ export const convertLessThanRatingToArrayOfRatingValues = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const convertRatingToRatingValue = (rating: number) => {
|
export const convertRatingToRatingValue = (rating: number) => {
|
||||||
return `RATING_${rating}`;
|
return `RATING_${rating}` as FieldRatingValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ObjectFilterDropdownRatingInput = () => {
|
export const ObjectFilterDropdownRatingInput = () => {
|
||||||
const selectedOperandInDropdown = useRecoilComponentValueV2(
|
const { applyObjectFilterDropdownFilterValue } =
|
||||||
selectedOperandInDropdownComponentState,
|
useApplyObjectFilterDropdownFilterValue();
|
||||||
);
|
|
||||||
|
|
||||||
const fieldMetadataItemUsedInDropdown = useRecoilComponentValueV2(
|
const { objectFilterDropdownFilterValue } =
|
||||||
fieldMetadataItemUsedInDropdownComponentSelector,
|
useObjectFilterDropdownFilterValue();
|
||||||
);
|
|
||||||
|
|
||||||
const selectedFilter = useRecoilComponentValueV2(
|
const handleInputChange = (newRatingValue: FieldRatingValue) => {
|
||||||
selectedFilterComponentState,
|
if (!newRatingValue) {
|
||||||
);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const { applyRecordFilter } = useApplyRecordFilter();
|
const ratingValueConverted =
|
||||||
|
convertFieldRatingValueToNumber(newRatingValue);
|
||||||
|
|
||||||
|
applyObjectFilterDropdownFilterValue(ratingValueConverted);
|
||||||
|
};
|
||||||
|
|
||||||
|
const currentFilterValueConvertedToRatingValue = convertRatingToRatingValue(
|
||||||
|
Number(objectFilterDropdownFilterValue),
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
fieldMetadataItemUsedInDropdown &&
|
<StyledRatingInputContainer>
|
||||||
selectedOperandInDropdown && (
|
<RatingInput
|
||||||
<StyledRatingInputContainer>
|
value={currentFilterValueConvertedToRatingValue}
|
||||||
<RatingInput
|
onChange={handleInputChange}
|
||||||
value={selectedFilter?.value as FieldRatingValue}
|
/>
|
||||||
onChange={(newValue: FieldRatingValue) => {
|
</StyledRatingInputContainer>
|
||||||
if (!newValue) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
applyRecordFilter?.({
|
|
||||||
id: selectedFilter?.id ? selectedFilter.id : v4(),
|
|
||||||
fieldMetadataId: fieldMetadataItemUsedInDropdown.id,
|
|
||||||
value: convertFieldRatingValueToNumber(newValue),
|
|
||||||
operand: selectedOperandInDropdown,
|
|
||||||
displayValue: convertFieldRatingValueToNumber(newValue),
|
|
||||||
recordFilterGroupId: selectedFilter?.recordFilterGroupId,
|
|
||||||
positionInRecordFilterGroup:
|
|
||||||
selectedFilter?.positionInRecordFilterGroup,
|
|
||||||
type: getFilterTypeFromFieldType(
|
|
||||||
fieldMetadataItemUsedInDropdown.type,
|
|
||||||
),
|
|
||||||
label: fieldMetadataItemUsedInDropdown.label,
|
|
||||||
subFieldName: selectedFilter?.subFieldName,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</StyledRatingInputContainer>
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,17 +1,13 @@
|
|||||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||||
import {
|
import { getRelationObjectMetadataNameSingular } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
||||||
getFilterTypeFromFieldType,
|
|
||||||
getRelationObjectMetadataNameSingular,
|
|
||||||
} from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
|
||||||
import { ObjectFilterDropdownRecordPinnedItems } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownRecordPinnedItems';
|
import { ObjectFilterDropdownRecordPinnedItems } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownRecordPinnedItems';
|
||||||
import { CURRENT_WORKSPACE_MEMBER_SELECTABLE_ITEM_ID } from '@/object-record/object-filter-dropdown/constants/CurrentWorkspaceMemberSelectableItemId';
|
import { CURRENT_WORKSPACE_MEMBER_SELECTABLE_ITEM_ID } from '@/object-record/object-filter-dropdown/constants/CurrentWorkspaceMemberSelectableItemId';
|
||||||
|
import { useApplyObjectFilterDropdownFilterValue } from '@/object-record/object-filter-dropdown/hooks/useApplyObjectFilterDropdownFilterValue';
|
||||||
|
import { useObjectFilterDropdownFilterValue } from '@/object-record/object-filter-dropdown/hooks/useObjectFilterDropdownFilterValue';
|
||||||
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
|
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
|
||||||
import { objectFilterDropdownSearchInputComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputComponentState';
|
import { objectFilterDropdownSearchInputComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputComponentState';
|
||||||
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
|
|
||||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
||||||
import { useApplyRecordFilter } from '@/object-record/record-filter/hooks/useApplyRecordFilter';
|
|
||||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||||
import { findDuplicateRecordFilterInNonAdvancedRecordFilters } from '@/object-record/record-filter/utils/findDuplicateRecordFilterInNonAdvancedRecordFilters';
|
|
||||||
import { SingleRecordPickerHotkeyScope } from '@/object-record/record-picker/single-record-picker/types/SingleRecordPickerHotkeyScope';
|
import { SingleRecordPickerHotkeyScope } from '@/object-record/record-picker/single-record-picker/types/SingleRecordPickerHotkeyScope';
|
||||||
import { MultipleSelectDropdown } from '@/object-record/select/components/MultipleSelectDropdown';
|
import { MultipleSelectDropdown } from '@/object-record/select/components/MultipleSelectDropdown';
|
||||||
import { useRecordsForSelect } from '@/object-record/select/hooks/useRecordsForSelect';
|
import { useRecordsForSelect } from '@/object-record/select/hooks/useRecordsForSelect';
|
||||||
@ -23,7 +19,6 @@ import { jsonRelationFilterValueSchema } from '@/views/view-filter-value/validat
|
|||||||
import { simpleRelationFilterValueSchema } from '@/views/view-filter-value/validation-schemas/simpleRelationFilterValueSchema';
|
import { simpleRelationFilterValueSchema } from '@/views/view-filter-value/validation-schemas/simpleRelationFilterValueSchema';
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
import { IconUserCircle } from 'twenty-ui/display';
|
import { IconUserCircle } from 'twenty-ui/display';
|
||||||
import { v4 } from 'uuid';
|
|
||||||
|
|
||||||
export const EMPTY_FILTER_VALUE: string = JSON.stringify({
|
export const EMPTY_FILTER_VALUE: string = JSON.stringify({
|
||||||
isCurrentWorkspaceMemberSelected: false,
|
isCurrentWorkspaceMemberSelected: false,
|
||||||
@ -33,26 +28,26 @@ export const EMPTY_FILTER_VALUE: string = JSON.stringify({
|
|||||||
export const MAX_RECORDS_TO_DISPLAY = 3;
|
export const MAX_RECORDS_TO_DISPLAY = 3;
|
||||||
|
|
||||||
type ObjectFilterDropdownRecordSelectProps = {
|
type ObjectFilterDropdownRecordSelectProps = {
|
||||||
viewComponentId?: string;
|
|
||||||
recordFilterId?: string;
|
recordFilterId?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ObjectFilterDropdownRecordSelect = ({
|
export const ObjectFilterDropdownRecordSelect = ({
|
||||||
viewComponentId,
|
|
||||||
recordFilterId,
|
recordFilterId,
|
||||||
}: ObjectFilterDropdownRecordSelectProps) => {
|
}: ObjectFilterDropdownRecordSelectProps) => {
|
||||||
const fieldMetadataItemUsedInFilterDropdown = useRecoilComponentValueV2(
|
const fieldMetadataItemUsedInFilterDropdown = useRecoilComponentValueV2(
|
||||||
fieldMetadataItemUsedInDropdownComponentSelector,
|
fieldMetadataItemUsedInDropdownComponentSelector,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { objectFilterDropdownFilterValue } =
|
||||||
|
useObjectFilterDropdownFilterValue();
|
||||||
|
|
||||||
|
const { applyObjectFilterDropdownFilterValue } =
|
||||||
|
useApplyObjectFilterDropdownFilterValue();
|
||||||
|
|
||||||
const selectedOperandInDropdown = useRecoilComponentValueV2(
|
const selectedOperandInDropdown = useRecoilComponentValueV2(
|
||||||
selectedOperandInDropdownComponentState,
|
selectedOperandInDropdownComponentState,
|
||||||
);
|
);
|
||||||
|
|
||||||
const selectedFilter = useRecoilComponentValueV2(
|
|
||||||
selectedFilterComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const objectFilterDropdownSearchInput = useRecoilComponentValueV2(
|
const objectFilterDropdownSearchInput = useRecoilComponentValueV2(
|
||||||
objectFilterDropdownSearchInputComponentState,
|
objectFilterDropdownSearchInputComponentState,
|
||||||
);
|
);
|
||||||
@ -61,16 +56,14 @@ export const ObjectFilterDropdownRecordSelect = ({
|
|||||||
currentRecordFiltersComponentState,
|
currentRecordFiltersComponentState,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { applyRecordFilter } = useApplyRecordFilter(viewComponentId);
|
|
||||||
|
|
||||||
const { isCurrentWorkspaceMemberSelected } = jsonRelationFilterValueSchema
|
const { isCurrentWorkspaceMemberSelected } = jsonRelationFilterValueSchema
|
||||||
.catch({
|
.catch({
|
||||||
isCurrentWorkspaceMemberSelected: false,
|
isCurrentWorkspaceMemberSelected: false,
|
||||||
selectedRecordIds: simpleRelationFilterValueSchema.parse(
|
selectedRecordIds: simpleRelationFilterValueSchema.parse(
|
||||||
selectedFilter?.value,
|
objectFilterDropdownFilterValue,
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
.parse(selectedFilter?.value);
|
.parse(objectFilterDropdownFilterValue);
|
||||||
|
|
||||||
if (!isDefined(fieldMetadataItemUsedInFilterDropdown)) {
|
if (!isDefined(fieldMetadataItemUsedInFilterDropdown)) {
|
||||||
throw new Error('fieldMetadataItemUsedInFilterDropdown is not defined');
|
throw new Error('fieldMetadataItemUsedInFilterDropdown is not defined');
|
||||||
@ -210,50 +203,7 @@ export const ObjectFilterDropdownRecordSelect = ({
|
|||||||
} satisfies RelationFilterValue)
|
} satisfies RelationFilterValue)
|
||||||
: '';
|
: '';
|
||||||
|
|
||||||
const duplicateFilterInCurrentRecordFilters =
|
applyObjectFilterDropdownFilterValue(newFilterValue, filterDisplayValue);
|
||||||
findDuplicateRecordFilterInNonAdvancedRecordFilters({
|
|
||||||
recordFilters: currentRecordFilters,
|
|
||||||
fieldMetadataItemId: fieldMetadataItemUsedInFilterDropdown.id,
|
|
||||||
});
|
|
||||||
|
|
||||||
const filterIsAlreadyInCurrentRecordFilters = isDefined(
|
|
||||||
duplicateFilterInCurrentRecordFilters,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (filterIsAlreadyInCurrentRecordFilters && !isDefined(recordFilterId)) {
|
|
||||||
applyRecordFilter({
|
|
||||||
id: duplicateFilterInCurrentRecordFilters.id,
|
|
||||||
type: getFilterTypeFromFieldType(
|
|
||||||
fieldMetadataItemUsedInFilterDropdown.type,
|
|
||||||
),
|
|
||||||
label: fieldMetadataItemUsedInFilterDropdown.label,
|
|
||||||
operand: selectedOperandInDropdown,
|
|
||||||
displayValue: filterDisplayValue,
|
|
||||||
fieldMetadataId: fieldMetadataItemUsedInFilterDropdown.id,
|
|
||||||
value: newFilterValue,
|
|
||||||
recordFilterGroupId:
|
|
||||||
duplicateFilterInCurrentRecordFilters.recordFilterGroupId,
|
|
||||||
positionInRecordFilterGroup:
|
|
||||||
duplicateFilterInCurrentRecordFilters.positionInRecordFilterGroup,
|
|
||||||
subFieldName: duplicateFilterInCurrentRecordFilters.subFieldName,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
applyRecordFilter({
|
|
||||||
id: selectedFilter?.id ? selectedFilter.id : v4(),
|
|
||||||
type: getFilterTypeFromFieldType(
|
|
||||||
fieldMetadataItemUsedInFilterDropdown.type,
|
|
||||||
),
|
|
||||||
label: fieldMetadataItemUsedInFilterDropdown.label,
|
|
||||||
operand: selectedOperandInDropdown,
|
|
||||||
displayValue: filterDisplayValue,
|
|
||||||
fieldMetadataId: fieldMetadataItemUsedInFilterDropdown.id,
|
|
||||||
value: newFilterValue,
|
|
||||||
recordFilterGroupId: selectedFilter?.recordFilterGroupId,
|
|
||||||
positionInRecordFilterGroup:
|
|
||||||
selectedFilter?.positionInRecordFilterGroup,
|
|
||||||
subFieldName: selectedFilter?.subFieldName,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,68 +1,44 @@
|
|||||||
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
import { useApplyObjectFilterDropdownFilterValue } from '@/object-record/object-filter-dropdown/hooks/useApplyObjectFilterDropdownFilterValue';
|
||||||
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
|
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
|
||||||
|
import { objectFilterDropdownCurrentRecordFilterComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownCurrentRecordFilterComponentState';
|
||||||
import { objectFilterDropdownSearchInputComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputComponentState';
|
import { objectFilterDropdownSearchInputComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputComponentState';
|
||||||
import { objectFilterDropdownSelectedRecordIdsComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedRecordIdsComponentState';
|
|
||||||
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
|
|
||||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
|
||||||
import { getActorSourceMultiSelectOptions } from '@/object-record/object-filter-dropdown/utils/getActorSourceMultiSelectOptions';
|
import { getActorSourceMultiSelectOptions } from '@/object-record/object-filter-dropdown/utils/getActorSourceMultiSelectOptions';
|
||||||
import { useApplyRecordFilter } from '@/object-record/record-filter/hooks/useApplyRecordFilter';
|
|
||||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
|
||||||
import { findDuplicateRecordFilterInNonAdvancedRecordFilters } from '@/object-record/record-filter/utils/findDuplicateRecordFilterInNonAdvancedRecordFilters';
|
|
||||||
import { SingleRecordPickerHotkeyScope } from '@/object-record/record-picker/single-record-picker/types/SingleRecordPickerHotkeyScope';
|
import { SingleRecordPickerHotkeyScope } from '@/object-record/record-picker/single-record-picker/types/SingleRecordPickerHotkeyScope';
|
||||||
import { MultipleSelectDropdown } from '@/object-record/select/components/MultipleSelectDropdown';
|
import { MultipleSelectDropdown } from '@/object-record/select/components/MultipleSelectDropdown';
|
||||||
import { SelectableItem } from '@/object-record/select/types/SelectableItem';
|
import { SelectableItem } from '@/object-record/select/types/SelectableItem';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
import { isNonEmptyString } from '@sniptt/guards';
|
||||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
import { v4 } from 'uuid';
|
|
||||||
|
|
||||||
export const EMPTY_FILTER_VALUE = '[]';
|
export const EMPTY_FILTER_VALUE = '[]';
|
||||||
export const MAX_ITEMS_TO_DISPLAY = 3;
|
export const MAX_ITEMS_TO_DISPLAY = 3;
|
||||||
|
|
||||||
type ObjectFilterDropdownSourceSelectProps = {
|
export const ObjectFilterDropdownSourceSelect = () => {
|
||||||
viewComponentId?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const ObjectFilterDropdownSourceSelect = ({
|
|
||||||
viewComponentId,
|
|
||||||
}: ObjectFilterDropdownSourceSelectProps) => {
|
|
||||||
const objectFilterDropdownSearchInput = useRecoilComponentValueV2(
|
const objectFilterDropdownSearchInput = useRecoilComponentValueV2(
|
||||||
objectFilterDropdownSearchInputComponentState,
|
objectFilterDropdownSearchInputComponentState,
|
||||||
);
|
);
|
||||||
|
|
||||||
const setObjectFilterDropdownSelectedRecordIds = useSetRecoilComponentStateV2(
|
|
||||||
objectFilterDropdownSelectedRecordIdsComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const objectFilterDropdownSelectedRecordIds = useRecoilComponentValueV2(
|
|
||||||
objectFilterDropdownSelectedRecordIdsComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const selectedFilter = useRecoilComponentValueV2(
|
|
||||||
selectedFilterComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const selectedOperandInDropdown = useRecoilComponentValueV2(
|
|
||||||
selectedOperandInDropdownComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const fieldMetadataItemUsedInFilterDropdown = useRecoilComponentValueV2(
|
const fieldMetadataItemUsedInFilterDropdown = useRecoilComponentValueV2(
|
||||||
fieldMetadataItemUsedInDropdownComponentSelector,
|
fieldMetadataItemUsedInDropdownComponentSelector,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { applyRecordFilter } = useApplyRecordFilter(viewComponentId);
|
const objectFilterDropdownCurrentRecordFilter = useRecoilComponentValueV2(
|
||||||
|
objectFilterDropdownCurrentRecordFilterComponentState,
|
||||||
const sourceTypes = getActorSourceMultiSelectOptions(
|
|
||||||
objectFilterDropdownSelectedRecordIds,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { applyObjectFilterDropdownFilterValue } =
|
||||||
|
useApplyObjectFilterDropdownFilterValue();
|
||||||
|
|
||||||
|
const selectedSources = isNonEmptyString(
|
||||||
|
objectFilterDropdownCurrentRecordFilter?.value,
|
||||||
|
)
|
||||||
|
? (JSON.parse(objectFilterDropdownCurrentRecordFilter.value) as string[]) // TODO: replace by a safe parse
|
||||||
|
: [];
|
||||||
|
|
||||||
|
const sourceTypes = getActorSourceMultiSelectOptions(selectedSources);
|
||||||
|
|
||||||
const filteredSelectedItems = sourceTypes.filter((option) =>
|
const filteredSelectedItems = sourceTypes.filter((option) =>
|
||||||
objectFilterDropdownSelectedRecordIds.includes(option.id),
|
selectedSources.includes(option.id),
|
||||||
);
|
|
||||||
|
|
||||||
const currentRecordFilters = useRecoilComponentValueV2(
|
|
||||||
currentRecordFiltersComponentState,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleMultipleItemSelectChange = (
|
const handleMultipleItemSelectChange = (
|
||||||
@ -70,10 +46,8 @@ export const ObjectFilterDropdownSourceSelect = ({
|
|||||||
newSelectedValue: boolean,
|
newSelectedValue: boolean,
|
||||||
) => {
|
) => {
|
||||||
const newSelectedItemIds = newSelectedValue
|
const newSelectedItemIds = newSelectedValue
|
||||||
? [...objectFilterDropdownSelectedRecordIds, itemToSelect.id]
|
? [...selectedSources, itemToSelect.id]
|
||||||
: objectFilterDropdownSelectedRecordIds.filter(
|
: selectedSources.filter((id) => id !== itemToSelect.id);
|
||||||
(id) => id !== itemToSelect.id,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!isDefined(fieldMetadataItemUsedInFilterDropdown)) {
|
if (!isDefined(fieldMetadataItemUsedInFilterDropdown)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
@ -81,8 +55,6 @@ export const ObjectFilterDropdownSourceSelect = ({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
setObjectFilterDropdownSelectedRecordIds(newSelectedItemIds);
|
|
||||||
|
|
||||||
const selectedItemNames = sourceTypes
|
const selectedItemNames = sourceTypes
|
||||||
.filter((option) => newSelectedItemIds.includes(option.id))
|
.filter((option) => newSelectedItemIds.includes(option.id))
|
||||||
.map((option) => option.name);
|
.map((option) => option.name);
|
||||||
@ -92,46 +64,12 @@ export const ObjectFilterDropdownSourceSelect = ({
|
|||||||
? `${selectedItemNames.length} source types`
|
? `${selectedItemNames.length} source types`
|
||||||
: selectedItemNames.join(', ');
|
: selectedItemNames.join(', ');
|
||||||
|
|
||||||
if (
|
const newFilterValue =
|
||||||
isDefined(fieldMetadataItemUsedInFilterDropdown) &&
|
newSelectedItemIds.length > 0
|
||||||
isDefined(selectedOperandInDropdown)
|
? JSON.stringify(newSelectedItemIds)
|
||||||
) {
|
: EMPTY_FILTER_VALUE;
|
||||||
const newFilterValue =
|
|
||||||
newSelectedItemIds.length > 0
|
|
||||||
? JSON.stringify(newSelectedItemIds)
|
|
||||||
: EMPTY_FILTER_VALUE;
|
|
||||||
|
|
||||||
const duplicateFilterInCurrentRecordFilters =
|
applyObjectFilterDropdownFilterValue(newFilterValue, filterDisplayValue);
|
||||||
findDuplicateRecordFilterInNonAdvancedRecordFilters({
|
|
||||||
recordFilters: currentRecordFilters,
|
|
||||||
fieldMetadataItemId: fieldMetadataItemUsedInFilterDropdown.id,
|
|
||||||
subFieldName: 'source',
|
|
||||||
});
|
|
||||||
|
|
||||||
const filterIsAlreadyInCurrentRecordFilters = isDefined(
|
|
||||||
duplicateFilterInCurrentRecordFilters,
|
|
||||||
);
|
|
||||||
|
|
||||||
const filterId = filterIsAlreadyInCurrentRecordFilters
|
|
||||||
? duplicateFilterInCurrentRecordFilters?.id
|
|
||||||
: v4();
|
|
||||||
|
|
||||||
applyRecordFilter({
|
|
||||||
id: selectedFilter?.id ? selectedFilter.id : filterId,
|
|
||||||
type: getFilterTypeFromFieldType(
|
|
||||||
fieldMetadataItemUsedInFilterDropdown.type,
|
|
||||||
),
|
|
||||||
label: fieldMetadataItemUsedInFilterDropdown.label,
|
|
||||||
operand: selectedOperandInDropdown || ViewFilterOperand.Is,
|
|
||||||
displayValue: filterDisplayValue,
|
|
||||||
fieldMetadataId: fieldMetadataItemUsedInFilterDropdown.id,
|
|
||||||
value: newFilterValue,
|
|
||||||
recordFilterGroupId: selectedFilter?.recordFilterGroupId,
|
|
||||||
subFieldName: 'source',
|
|
||||||
positionInRecordFilterGroup:
|
|
||||||
selectedFilter?.positionInRecordFilterGroup,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import { objectFilterDropdownFilterIsSelectedComponentState } from '@/object-rec
|
|||||||
import { objectFilterDropdownIsSelectingCompositeFieldComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownIsSelectingCompositeFieldComponentState';
|
import { objectFilterDropdownIsSelectingCompositeFieldComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownIsSelectingCompositeFieldComponentState';
|
||||||
import { objectFilterDropdownSearchInputComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputComponentState';
|
import { objectFilterDropdownSearchInputComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputComponentState';
|
||||||
import { objectFilterDropdownSubMenuFieldTypeComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSubMenuFieldTypeComponentState';
|
import { objectFilterDropdownSubMenuFieldTypeComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSubMenuFieldTypeComponentState';
|
||||||
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
|
|
||||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
||||||
import { subFieldNameUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/subFieldNameUsedInDropdownComponentState';
|
import { subFieldNameUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/subFieldNameUsedInDropdownComponentState';
|
||||||
import { FiltersHotkeyScope } from '@/object-record/object-filter-dropdown/types/FiltersHotkeyScope';
|
import { FiltersHotkeyScope } from '@/object-record/object-filter-dropdown/types/FiltersHotkeyScope';
|
||||||
@ -81,10 +80,6 @@ export const ObjectFilterDropdownSubFieldSelect = () => {
|
|||||||
currentRecordFiltersComponentState,
|
currentRecordFiltersComponentState,
|
||||||
);
|
);
|
||||||
|
|
||||||
const setSelectedFilter = useSetRecoilComponentStateV2(
|
|
||||||
selectedFilterComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const setObjectFilterDropdownCurrentRecordFilter =
|
const setObjectFilterDropdownCurrentRecordFilter =
|
||||||
useSetRecoilComponentStateV2(
|
useSetRecoilComponentStateV2(
|
||||||
objectFilterDropdownCurrentRecordFilterComponentState,
|
objectFilterDropdownCurrentRecordFilterComponentState,
|
||||||
@ -125,8 +120,6 @@ export const ObjectFilterDropdownSubFieldSelect = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (filterIsAlreadyInCurrentRecordFilters) {
|
if (filterIsAlreadyInCurrentRecordFilters) {
|
||||||
setSelectedFilter(duplicateFilterInCurrentRecordFilters);
|
|
||||||
|
|
||||||
setObjectFilterDropdownCurrentRecordFilter(
|
setObjectFilterDropdownCurrentRecordFilter(
|
||||||
duplicateFilterInCurrentRecordFilters,
|
duplicateFilterInCurrentRecordFilters,
|
||||||
);
|
);
|
||||||
|
|||||||
@ -31,6 +31,12 @@ export const ObjectFilterDropdownTextInput = () => {
|
|||||||
[hasFocused],
|
[hasFocused],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const newValue = event.target.value;
|
||||||
|
|
||||||
|
applyObjectFilterDropdownFilterValue(newValue);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownMenuItemsContainer>
|
<DropdownMenuItemsContainer>
|
||||||
<DropdownMenuInput
|
<DropdownMenuInput
|
||||||
@ -39,11 +45,7 @@ export const ObjectFilterDropdownTextInput = () => {
|
|||||||
autoFocus
|
autoFocus
|
||||||
type="text"
|
type="text"
|
||||||
placeholder={fieldMetadataItemUsedInDropdown?.label}
|
placeholder={fieldMetadataItemUsedInDropdown?.label}
|
||||||
onChange={(event: ChangeEvent<HTMLInputElement>) => {
|
onChange={handleInputChange}
|
||||||
const newValue = event.target.value;
|
|
||||||
|
|
||||||
applyObjectFilterDropdownFilterValue(newValue);
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</DropdownMenuItemsContainer>
|
</DropdownMenuItemsContainer>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,80 +0,0 @@
|
|||||||
import { ChangeEvent, useCallback, useState } from 'react';
|
|
||||||
|
|
||||||
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
|
||||||
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
|
|
||||||
import { objectFilterDropdownSearchInputComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputComponentState';
|
|
||||||
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
|
|
||||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
|
||||||
import { useApplyRecordFilter } from '@/object-record/record-filter/hooks/useApplyRecordFilter';
|
|
||||||
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
|
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
|
||||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
|
||||||
import { v4 } from 'uuid';
|
|
||||||
|
|
||||||
export const ObjectFilterDropdownTextSearchInput = () => {
|
|
||||||
const [hasFocused, setHasFocused] = useState(false);
|
|
||||||
|
|
||||||
const fieldMetadataItemUsedInDropdown = useRecoilComponentValueV2(
|
|
||||||
fieldMetadataItemUsedInDropdownComponentSelector,
|
|
||||||
);
|
|
||||||
|
|
||||||
const selectedOperandInDropdown = useRecoilComponentValueV2(
|
|
||||||
selectedOperandInDropdownComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const objectFilterDropdownSearchInput = useRecoilComponentValueV2(
|
|
||||||
objectFilterDropdownSearchInputComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const selectedFilter = useRecoilComponentValueV2(
|
|
||||||
selectedFilterComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const setObjectFilterDropdownSearchInput = useSetRecoilComponentStateV2(
|
|
||||||
objectFilterDropdownSearchInputComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const { applyRecordFilter } = useApplyRecordFilter();
|
|
||||||
|
|
||||||
const handleInputRef = useCallback(
|
|
||||||
(node: HTMLInputElement | null) => {
|
|
||||||
if (Boolean(node) && !hasFocused) {
|
|
||||||
node?.focus();
|
|
||||||
node?.select();
|
|
||||||
setHasFocused(true);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[hasFocused],
|
|
||||||
);
|
|
||||||
return (
|
|
||||||
fieldMetadataItemUsedInDropdown &&
|
|
||||||
selectedOperandInDropdown && (
|
|
||||||
<DropdownMenuSearchInput
|
|
||||||
ref={handleInputRef}
|
|
||||||
autoFocus
|
|
||||||
type="text"
|
|
||||||
placeholder={fieldMetadataItemUsedInDropdown.label}
|
|
||||||
value={selectedFilter?.value ?? objectFilterDropdownSearchInput}
|
|
||||||
onChange={(event: ChangeEvent<HTMLInputElement>) => {
|
|
||||||
setObjectFilterDropdownSearchInput(event.target.value);
|
|
||||||
|
|
||||||
applyRecordFilter({
|
|
||||||
id: selectedFilter?.id ?? v4(),
|
|
||||||
fieldMetadataId: fieldMetadataItemUsedInDropdown.id,
|
|
||||||
value: event.target.value,
|
|
||||||
operand: selectedOperandInDropdown,
|
|
||||||
displayValue: event.target.value,
|
|
||||||
recordFilterGroupId: selectedFilter?.recordFilterGroupId,
|
|
||||||
type: getFilterTypeFromFieldType(
|
|
||||||
fieldMetadataItemUsedInDropdown.type,
|
|
||||||
),
|
|
||||||
label: fieldMetadataItemUsedInDropdown.label,
|
|
||||||
positionInRecordFilterGroup:
|
|
||||||
selectedFilter?.positionInRecordFilterGroup,
|
|
||||||
subFieldName: selectedFilter?.subFieldName,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@ -25,7 +25,10 @@ export const useApplyObjectFilterDropdownFilterValue = () => {
|
|||||||
const { upsertObjectFilterDropdownCurrentFilter } =
|
const { upsertObjectFilterDropdownCurrentFilter } =
|
||||||
useUpsertObjectFilterDropdownCurrentFilter();
|
useUpsertObjectFilterDropdownCurrentFilter();
|
||||||
|
|
||||||
const applyObjectFilterDropdownFilterValue = (newFilterValue: string) => {
|
const applyObjectFilterDropdownFilterValue = (
|
||||||
|
newFilterValue: string,
|
||||||
|
newDisplayValue?: string,
|
||||||
|
) => {
|
||||||
if (objectFilterDropdownFilterNotYetCreated) {
|
if (objectFilterDropdownFilterNotYetCreated) {
|
||||||
if (!isDefined(fieldMetadataItemUsedInDropdown)) {
|
if (!isDefined(fieldMetadataItemUsedInDropdown)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
@ -41,7 +44,7 @@ export const useApplyObjectFilterDropdownFilterValue = () => {
|
|||||||
const newCurrentRecordFilter = {
|
const newCurrentRecordFilter = {
|
||||||
...newRecordFilterFromObjectFilterDropdownStates,
|
...newRecordFilterFromObjectFilterDropdownStates,
|
||||||
value: newFilterValue,
|
value: newFilterValue,
|
||||||
displayValue: newFilterValue,
|
displayValue: newDisplayValue ?? newFilterValue,
|
||||||
} satisfies RecordFilter;
|
} satisfies RecordFilter;
|
||||||
|
|
||||||
upsertObjectFilterDropdownCurrentFilter(newCurrentRecordFilter);
|
upsertObjectFilterDropdownCurrentFilter(newCurrentRecordFilter);
|
||||||
@ -49,7 +52,7 @@ export const useApplyObjectFilterDropdownFilterValue = () => {
|
|||||||
const newCurrentRecordFilter = {
|
const newCurrentRecordFilter = {
|
||||||
...objectFilterDropdownCurrentRecordFilter,
|
...objectFilterDropdownCurrentRecordFilter,
|
||||||
value: newFilterValue,
|
value: newFilterValue,
|
||||||
displayValue: newFilterValue,
|
displayValue: newDisplayValue ?? newFilterValue,
|
||||||
} satisfies RecordFilter;
|
} satisfies RecordFilter;
|
||||||
|
|
||||||
upsertObjectFilterDropdownCurrentFilter(newCurrentRecordFilter);
|
upsertObjectFilterDropdownCurrentFilter(newCurrentRecordFilter);
|
||||||
|
|||||||
@ -0,0 +1,79 @@
|
|||||||
|
import { useUpsertObjectFilterDropdownCurrentFilter } from '@/object-record/object-filter-dropdown/hooks/useUpsertObjectFilterDropdownCurrentFilter';
|
||||||
|
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
|
||||||
|
import { objectFilterDropdownCurrentRecordFilterComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownCurrentRecordFilterComponentState';
|
||||||
|
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
||||||
|
import { useCreateEmptyRecordFilterFromFieldMetadataItem } from '@/object-record/record-filter/hooks/useCreateEmptyRecordFilterFromFieldMetadataItem';
|
||||||
|
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||||
|
import { RecordFilterOperand } from '@/object-record/record-filter/types/RecordFilterOperand';
|
||||||
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
|
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||||
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
|
|
||||||
|
export const useApplyObjectFilterDropdownOperand = () => {
|
||||||
|
const objectFilterDropdownCurrentRecordFilter = useRecoilComponentValueV2(
|
||||||
|
objectFilterDropdownCurrentRecordFilterComponentState,
|
||||||
|
);
|
||||||
|
|
||||||
|
const setSelectedOperandInDropdown = useSetRecoilComponentStateV2(
|
||||||
|
selectedOperandInDropdownComponentState,
|
||||||
|
);
|
||||||
|
|
||||||
|
const objectFilterDropdownFilterIsCreated = isDefined(
|
||||||
|
objectFilterDropdownCurrentRecordFilter,
|
||||||
|
);
|
||||||
|
|
||||||
|
const fieldMetadataItemUsedInDropdown = useRecoilComponentValueV2(
|
||||||
|
fieldMetadataItemUsedInDropdownComponentSelector,
|
||||||
|
);
|
||||||
|
|
||||||
|
const { upsertObjectFilterDropdownCurrentFilter } =
|
||||||
|
useUpsertObjectFilterDropdownCurrentFilter();
|
||||||
|
|
||||||
|
const { createEmptyRecordFilterFromFieldMetadataItem } =
|
||||||
|
useCreateEmptyRecordFilterFromFieldMetadataItem();
|
||||||
|
|
||||||
|
const applyObjectFilterDropdownOperand = (
|
||||||
|
newOperand: RecordFilterOperand,
|
||||||
|
) => {
|
||||||
|
const isValuelessOperand = [
|
||||||
|
RecordFilterOperand.IsEmpty,
|
||||||
|
RecordFilterOperand.IsNotEmpty,
|
||||||
|
RecordFilterOperand.IsInPast,
|
||||||
|
RecordFilterOperand.IsInFuture,
|
||||||
|
RecordFilterOperand.IsToday,
|
||||||
|
].includes(newOperand);
|
||||||
|
|
||||||
|
if (objectFilterDropdownFilterIsCreated) {
|
||||||
|
const newCurrentRecordFilter = {
|
||||||
|
...objectFilterDropdownCurrentRecordFilter,
|
||||||
|
operand: newOperand,
|
||||||
|
} satisfies RecordFilter;
|
||||||
|
|
||||||
|
upsertObjectFilterDropdownCurrentFilter(newCurrentRecordFilter);
|
||||||
|
} else if (isValuelessOperand) {
|
||||||
|
if (!isDefined(fieldMetadataItemUsedInDropdown)) {
|
||||||
|
throw new Error(
|
||||||
|
'FieldMetadataItemUsedInDropdown is not defined, cannot create empty record filter, this should not happen',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { newRecordFilter: emptyRecordFilter } =
|
||||||
|
createEmptyRecordFilterFromFieldMetadataItem(
|
||||||
|
fieldMetadataItemUsedInDropdown,
|
||||||
|
);
|
||||||
|
|
||||||
|
const recordFilterToCreate = {
|
||||||
|
...emptyRecordFilter,
|
||||||
|
operand: newOperand,
|
||||||
|
} satisfies RecordFilter;
|
||||||
|
|
||||||
|
upsertObjectFilterDropdownCurrentFilter(recordFilterToCreate);
|
||||||
|
}
|
||||||
|
|
||||||
|
setSelectedOperandInDropdown(newOperand);
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
applyObjectFilterDropdownOperand,
|
||||||
|
};
|
||||||
|
};
|
||||||
@ -1,6 +1,6 @@
|
|||||||
|
import { objectFilterDropdownCurrentRecordFilterComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownCurrentRecordFilterComponentState';
|
||||||
import { objectFilterDropdownSearchInputComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputComponentState';
|
import { objectFilterDropdownSearchInputComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputComponentState';
|
||||||
import { objectFilterDropdownSelectedRecordIdsComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedRecordIdsComponentState';
|
import { objectFilterDropdownSelectedRecordIdsComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedRecordIdsComponentState';
|
||||||
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
|
|
||||||
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
||||||
import { useRecoilCallback } from 'recoil';
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
|
||||||
@ -17,22 +17,23 @@ export const useEmptyRecordFilter = (componentInstanceId?: string) => {
|
|||||||
componentInstanceId,
|
componentInstanceId,
|
||||||
);
|
);
|
||||||
|
|
||||||
const selectedFilterCallbackState = useRecoilComponentCallbackStateV2(
|
const objectFilterDropdownCurrentRecordFilter =
|
||||||
selectedFilterComponentState,
|
useRecoilComponentCallbackStateV2(
|
||||||
componentInstanceId,
|
objectFilterDropdownCurrentRecordFilterComponentState,
|
||||||
);
|
componentInstanceId,
|
||||||
|
);
|
||||||
|
|
||||||
const emptyRecordFilter = useRecoilCallback(
|
const emptyRecordFilter = useRecoilCallback(
|
||||||
({ set }) =>
|
({ set }) =>
|
||||||
() => {
|
() => {
|
||||||
set(objectFilterDropdownSearchInputCallbackState, '');
|
set(objectFilterDropdownSearchInputCallbackState, '');
|
||||||
set(objectFilterDropdownSelectedRecordIdsCallbackState, []);
|
set(objectFilterDropdownSelectedRecordIdsCallbackState, []);
|
||||||
set(selectedFilterCallbackState, undefined);
|
set(objectFilterDropdownCurrentRecordFilter, undefined);
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
objectFilterDropdownSearchInputCallbackState,
|
objectFilterDropdownSearchInputCallbackState,
|
||||||
objectFilterDropdownSelectedRecordIdsCallbackState,
|
objectFilterDropdownSelectedRecordIdsCallbackState,
|
||||||
selectedFilterCallbackState,
|
objectFilterDropdownCurrentRecordFilter,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,6 @@ import { objectFilterDropdownFilterIsSelectedComponentState } from '@/object-rec
|
|||||||
import { objectFilterDropdownIsSelectingCompositeFieldComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownIsSelectingCompositeFieldComponentState';
|
import { objectFilterDropdownIsSelectingCompositeFieldComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownIsSelectingCompositeFieldComponentState';
|
||||||
import { objectFilterDropdownSearchInputComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputComponentState';
|
import { objectFilterDropdownSearchInputComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputComponentState';
|
||||||
import { objectFilterDropdownSelectedRecordIdsComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedRecordIdsComponentState';
|
import { objectFilterDropdownSelectedRecordIdsComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedRecordIdsComponentState';
|
||||||
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
|
|
||||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
||||||
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
||||||
import { useRecoilCallback } from 'recoil';
|
import { useRecoilCallback } from 'recoil';
|
||||||
@ -28,11 +27,6 @@ export const useResetFilterDropdown = (componentInstanceId?: string) => {
|
|||||||
componentInstanceId,
|
componentInstanceId,
|
||||||
);
|
);
|
||||||
|
|
||||||
const selectedFilterCallbackState = useRecoilComponentCallbackStateV2(
|
|
||||||
selectedFilterComponentState,
|
|
||||||
componentInstanceId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const selectedOperandInDropdownCallbackState =
|
const selectedOperandInDropdownCallbackState =
|
||||||
useRecoilComponentCallbackStateV2(
|
useRecoilComponentCallbackStateV2(
|
||||||
selectedOperandInDropdownComponentState,
|
selectedOperandInDropdownComponentState,
|
||||||
@ -62,7 +56,6 @@ export const useResetFilterDropdown = (componentInstanceId?: string) => {
|
|||||||
() => {
|
() => {
|
||||||
set(objectFilterDropdownSearchInputCallbackState, '');
|
set(objectFilterDropdownSearchInputCallbackState, '');
|
||||||
set(objectFilterDropdownSelectedRecordIdsCallbackState, []);
|
set(objectFilterDropdownSelectedRecordIdsCallbackState, []);
|
||||||
set(selectedFilterCallbackState, undefined);
|
|
||||||
set(selectedOperandInDropdownCallbackState, null);
|
set(selectedOperandInDropdownCallbackState, null);
|
||||||
set(objectFilterDropdownFilterIsSelectedCallbackState, false);
|
set(objectFilterDropdownFilterIsSelectedCallbackState, false);
|
||||||
set(objectFilterDropdownIsSelectingCompositeFieldCallbackState, false);
|
set(objectFilterDropdownIsSelectingCompositeFieldCallbackState, false);
|
||||||
@ -72,7 +65,6 @@ export const useResetFilterDropdown = (componentInstanceId?: string) => {
|
|||||||
[
|
[
|
||||||
objectFilterDropdownSearchInputCallbackState,
|
objectFilterDropdownSearchInputCallbackState,
|
||||||
objectFilterDropdownSelectedRecordIdsCallbackState,
|
objectFilterDropdownSelectedRecordIdsCallbackState,
|
||||||
selectedFilterCallbackState,
|
|
||||||
selectedOperandInDropdownCallbackState,
|
selectedOperandInDropdownCallbackState,
|
||||||
objectFilterDropdownFilterIsSelectedCallbackState,
|
objectFilterDropdownFilterIsSelectedCallbackState,
|
||||||
objectFilterDropdownIsSelectingCompositeFieldCallbackState,
|
objectFilterDropdownIsSelectingCompositeFieldCallbackState,
|
||||||
|
|||||||
@ -1,97 +0,0 @@
|
|||||||
import { useGetFieldMetadataItemById } from '@/object-metadata/hooks/useGetFieldMetadataItemById';
|
|
||||||
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
|
||||||
import { fieldMetadataItemIdUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemIdUsedInDropdownComponentState';
|
|
||||||
import { objectFilterDropdownSearchInputComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputComponentState';
|
|
||||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
|
||||||
import { getInitialFilterValue } from '@/object-record/object-filter-dropdown/utils/getInitialFilterValue';
|
|
||||||
import { useApplyRecordFilter } from '@/object-record/record-filter/hooks/useApplyRecordFilter';
|
|
||||||
import { getRecordFilterOperands } from '@/object-record/record-filter/utils/getRecordFilterOperands';
|
|
||||||
import { SingleRecordPickerHotkeyScope } from '@/object-record/record-picker/single-record-picker/types/SingleRecordPickerHotkeyScope';
|
|
||||||
|
|
||||||
import { getDefaultSubFieldNameForCompositeFilterableFieldType } from '@/object-record/record-filter/utils/getDefaultSubFieldNameForCompositeFilterableFieldType';
|
|
||||||
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
|
||||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
|
||||||
import { v4 } from 'uuid';
|
|
||||||
|
|
||||||
type SelectFilterParams = {
|
|
||||||
fieldMetadataItemId: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useSelectFilterUsedInDropdown = (componentInstanceId?: string) => {
|
|
||||||
const setSelectedOperandInDropdown = useSetRecoilComponentStateV2(
|
|
||||||
selectedOperandInDropdownComponentState,
|
|
||||||
componentInstanceId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const setFieldMetadataItemIdUsedInDropdown = useSetRecoilComponentStateV2(
|
|
||||||
fieldMetadataItemIdUsedInDropdownComponentState,
|
|
||||||
componentInstanceId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const setObjectFilterDropdownSearchInput = useSetRecoilComponentStateV2(
|
|
||||||
objectFilterDropdownSearchInputComponentState,
|
|
||||||
componentInstanceId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const setHotkeyScope = useSetHotkeyScope();
|
|
||||||
|
|
||||||
const { applyRecordFilter } = useApplyRecordFilter(componentInstanceId);
|
|
||||||
|
|
||||||
const { getFieldMetadataItemById } = useGetFieldMetadataItemById();
|
|
||||||
|
|
||||||
const selectFilterUsedInDropdown = ({
|
|
||||||
fieldMetadataItemId,
|
|
||||||
}: SelectFilterParams) => {
|
|
||||||
setFieldMetadataItemIdUsedInDropdown(fieldMetadataItemId);
|
|
||||||
|
|
||||||
const fieldMetadataItem = getFieldMetadataItemById(fieldMetadataItemId);
|
|
||||||
|
|
||||||
if (!isDefined(fieldMetadataItem)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
fieldMetadataItem.type === 'RELATION' ||
|
|
||||||
fieldMetadataItem.type === 'SELECT'
|
|
||||||
) {
|
|
||||||
setHotkeyScope(SingleRecordPickerHotkeyScope.SingleRecordPicker);
|
|
||||||
}
|
|
||||||
|
|
||||||
const filterType = getFilterTypeFromFieldType(fieldMetadataItem.type);
|
|
||||||
|
|
||||||
const defaultSubFieldName =
|
|
||||||
getDefaultSubFieldNameForCompositeFilterableFieldType(filterType);
|
|
||||||
|
|
||||||
const firstOperand = getRecordFilterOperands({
|
|
||||||
filterType,
|
|
||||||
subFieldName: defaultSubFieldName,
|
|
||||||
})[0];
|
|
||||||
|
|
||||||
setSelectedOperandInDropdown(firstOperand);
|
|
||||||
|
|
||||||
const { value, displayValue } = getInitialFilterValue(
|
|
||||||
filterType,
|
|
||||||
firstOperand,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (value !== '') {
|
|
||||||
applyRecordFilter({
|
|
||||||
id: v4(),
|
|
||||||
fieldMetadataId: fieldMetadataItem.id,
|
|
||||||
displayValue,
|
|
||||||
operand: firstOperand,
|
|
||||||
value,
|
|
||||||
type: filterType,
|
|
||||||
label: fieldMetadataItem.label,
|
|
||||||
subFieldName: defaultSubFieldName,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
setObjectFilterDropdownSearchInput('');
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
selectFilterUsedInDropdown,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@ -1,5 +1,4 @@
|
|||||||
import { objectFilterDropdownCurrentRecordFilterComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownCurrentRecordFilterComponentState';
|
import { objectFilterDropdownCurrentRecordFilterComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownCurrentRecordFilterComponentState';
|
||||||
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
|
|
||||||
import { useUpsertRecordFilter } from '@/object-record/record-filter/hooks/useUpsertRecordFilter';
|
import { useUpsertRecordFilter } from '@/object-record/record-filter/hooks/useUpsertRecordFilter';
|
||||||
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||||
@ -10,10 +9,6 @@ export const useUpsertObjectFilterDropdownCurrentFilter = () => {
|
|||||||
objectFilterDropdownCurrentRecordFilterComponentState,
|
objectFilterDropdownCurrentRecordFilterComponentState,
|
||||||
);
|
);
|
||||||
|
|
||||||
const setSelectedFilter = useSetRecoilComponentStateV2(
|
|
||||||
selectedFilterComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const { upsertRecordFilter } = useUpsertRecordFilter();
|
const { upsertRecordFilter } = useUpsertRecordFilter();
|
||||||
|
|
||||||
const upsertObjectFilterDropdownCurrentFilter = (
|
const upsertObjectFilterDropdownCurrentFilter = (
|
||||||
@ -22,7 +17,6 @@ export const useUpsertObjectFilterDropdownCurrentFilter = () => {
|
|||||||
upsertRecordFilter(recordFilterToUpsert);
|
upsertRecordFilter(recordFilterToUpsert);
|
||||||
|
|
||||||
setObjectFilterDropdownCurrentRecordFilter(recordFilterToUpsert);
|
setObjectFilterDropdownCurrentRecordFilter(recordFilterToUpsert);
|
||||||
setSelectedFilter(recordFilterToUpsert);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -1,11 +0,0 @@
|
|||||||
import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext';
|
|
||||||
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
|
|
||||||
import { RecordFilter } from '../../record-filter/types/RecordFilter';
|
|
||||||
|
|
||||||
export const onFilterSelectComponentState = createComponentStateV2<
|
|
||||||
((filter: RecordFilter | null) => void) | undefined
|
|
||||||
>({
|
|
||||||
key: 'onFilterSelectComponentState',
|
|
||||||
defaultValue: undefined,
|
|
||||||
componentInstanceContext: ObjectFilterDropdownComponentInstanceContext,
|
|
||||||
});
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext';
|
|
||||||
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
|
|
||||||
import { RecordFilter } from '../../record-filter/types/RecordFilter';
|
|
||||||
|
|
||||||
export const selectedFilterComponentState = createComponentStateV2<
|
|
||||||
RecordFilter | undefined | null
|
|
||||||
>({
|
|
||||||
key: 'selectedFilterComponentState',
|
|
||||||
defaultValue: undefined,
|
|
||||||
componentInstanceContext: ObjectFilterDropdownComponentInstanceContext,
|
|
||||||
});
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
|
|
||||||
import { useUpsertRecordFilter } from '@/object-record/record-filter/hooks/useUpsertRecordFilter';
|
|
||||||
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
|
||||||
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
|
||||||
|
|
||||||
import { useRecoilCallback } from 'recoil';
|
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
|
||||||
|
|
||||||
export const useApplyRecordFilter = (componentInstanceId?: string) => {
|
|
||||||
const selectedFilterCallbackState = useRecoilComponentCallbackStateV2(
|
|
||||||
selectedFilterComponentState,
|
|
||||||
componentInstanceId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const { upsertRecordFilter } = useUpsertRecordFilter();
|
|
||||||
|
|
||||||
const applyRecordFilter = useRecoilCallback(
|
|
||||||
({ set }) =>
|
|
||||||
(filter: RecordFilter | null) => {
|
|
||||||
set(selectedFilterCallbackState, filter);
|
|
||||||
|
|
||||||
if (isDefined(filter)) {
|
|
||||||
upsertRecordFilter(filter);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[selectedFilterCallbackState, upsertRecordFilter],
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
applyRecordFilter,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@ -1,23 +1,16 @@
|
|||||||
import { useSelectFilterUsedInDropdown } from '@/object-record/object-filter-dropdown/hooks/useSelectFilterUsedInDropdown';
|
|
||||||
import { useCreateEmptyRecordFilterFromFieldMetadataItem } from '@/object-record/record-filter/hooks/useCreateEmptyRecordFilterFromFieldMetadataItem';
|
import { useCreateEmptyRecordFilterFromFieldMetadataItem } from '@/object-record/record-filter/hooks/useCreateEmptyRecordFilterFromFieldMetadataItem';
|
||||||
import { useFilterableFieldMetadataItemsInRecordIndexContext } from '@/object-record/record-filter/hooks/useFilterableFieldMetadataItemsInRecordIndexContext';
|
import { useFilterableFieldMetadataItemsInRecordIndexContext } from '@/object-record/record-filter/hooks/useFilterableFieldMetadataItemsInRecordIndexContext';
|
||||||
import { useUpsertRecordFilter } from '@/object-record/record-filter/hooks/useUpsertRecordFilter';
|
import { useUpsertRecordFilter } from '@/object-record/record-filter/hooks/useUpsertRecordFilter';
|
||||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||||
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
|
|
||||||
import { useOpenDropdownFromOutside } from '@/ui/layout/dropdown/hooks/useOpenDropdownFromOutside';
|
import { useOpenDropdownFromOutside } from '@/ui/layout/dropdown/hooks/useOpenDropdownFromOutside';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { useSetEditableFilterChipDropdownStates } from '@/views/hooks/useSetEditableFilterChipDropdownStates';
|
import { useSetEditableFilterChipDropdownStates } from '@/views/hooks/useSetEditableFilterChipDropdownStates';
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
|
|
||||||
export const useOpenRecordFilterChipFromTableHeader = () => {
|
export const useOpenRecordFilterChipFromTableHeader = () => {
|
||||||
const { recordIndexId } = useRecordIndexContextOrThrow();
|
|
||||||
|
|
||||||
const { filterableFieldMetadataItems } =
|
const { filterableFieldMetadataItems } =
|
||||||
useFilterableFieldMetadataItemsInRecordIndexContext();
|
useFilterableFieldMetadataItemsInRecordIndexContext();
|
||||||
|
|
||||||
const { selectFilterUsedInDropdown } =
|
|
||||||
useSelectFilterUsedInDropdown(recordIndexId);
|
|
||||||
|
|
||||||
const currentRecordFilters = useRecoilComponentValueV2(
|
const currentRecordFilters = useRecoilComponentValueV2(
|
||||||
currentRecordFiltersComponentState,
|
currentRecordFiltersComponentState,
|
||||||
);
|
);
|
||||||
@ -60,8 +53,6 @@ export const useOpenRecordFilterChipFromTableHeader = () => {
|
|||||||
|
|
||||||
upsertRecordFilter(newRecordFilter);
|
upsertRecordFilter(newRecordFilter);
|
||||||
|
|
||||||
selectFilterUsedInDropdown({ fieldMetadataItemId });
|
|
||||||
|
|
||||||
setEditableFilterChipDropdownStates(newRecordFilter);
|
setEditableFilterChipDropdownStates(newRecordFilter);
|
||||||
openDropdownFromOutside(newRecordFilter.id);
|
openDropdownFromOutside(newRecordFilter.id);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -69,8 +69,10 @@ export const RelativeDatePickerHeader = (
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
options={RELATIVE_DATE_DIRECTION_SELECT_OPTIONS}
|
options={RELATIVE_DATE_DIRECTION_SELECT_OPTIONS}
|
||||||
|
fullWidth
|
||||||
/>
|
/>
|
||||||
<TextInput
|
<TextInput
|
||||||
|
width={50}
|
||||||
value={textInputValue}
|
value={textInputValue}
|
||||||
onChange={(text) => {
|
onChange={(text) => {
|
||||||
const amountString = text.replace(/[^0-9]|^0+/g, '');
|
const amountString = text.replace(/[^0-9]|^0+/g, '');
|
||||||
@ -106,6 +108,7 @@ export const RelativeDatePickerHeader = (
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
options={unitSelectOptions}
|
options={unitSelectOptions}
|
||||||
|
fullWidth
|
||||||
/>
|
/>
|
||||||
</StyledContainer>
|
</StyledContainer>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||||
|
|
||||||
import { AdvancedFilterRootRecordFilterGroup } from '@/object-record/advanced-filter/components/AdvancedFilterRootRecordFilterGroup';
|
import { AdvancedFilterRootRecordFilterGroup } from '@/object-record/advanced-filter/components/AdvancedFilterRootRecordFilterGroup';
|
||||||
|
import { useSetAdvancedFilterDropdownStates } from '@/object-record/advanced-filter/hooks/useSetAdvancedFilterDropdownAllRowsStates';
|
||||||
import { rootLevelRecordFilterGroupComponentSelector } from '@/object-record/advanced-filter/states/rootLevelRecordFilterGroupComponentSelector';
|
import { rootLevelRecordFilterGroupComponentSelector } from '@/object-record/advanced-filter/states/rootLevelRecordFilterGroupComponentSelector';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { AdvancedFilterChip } from '@/views/components/AdvancedFilterChip';
|
import { AdvancedFilterChip } from '@/views/components/AdvancedFilterChip';
|
||||||
@ -12,6 +13,13 @@ export const AdvancedFilterDropdownButton = () => {
|
|||||||
rootLevelRecordFilterGroupComponentSelector,
|
rootLevelRecordFilterGroupComponentSelector,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { setAdvancedFilterDropdownStates } =
|
||||||
|
useSetAdvancedFilterDropdownStates();
|
||||||
|
|
||||||
|
const handleOpenAdvancedFilterDropdown = () => {
|
||||||
|
setAdvancedFilterDropdownStates();
|
||||||
|
};
|
||||||
|
|
||||||
if (!isDefined(rootLevelRecordFilterGroup)) {
|
if (!isDefined(rootLevelRecordFilterGroup)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -25,6 +33,7 @@ export const AdvancedFilterDropdownButton = () => {
|
|||||||
dropdownOffset={{ y: 8, x: 0 }}
|
dropdownOffset={{ y: 8, x: 0 }}
|
||||||
dropdownPlacement="bottom-start"
|
dropdownPlacement="bottom-start"
|
||||||
dropdownWidth="100%"
|
dropdownWidth="100%"
|
||||||
|
onOpen={handleOpenAdvancedFilterDropdown}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
|||||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||||
import { VIEW_BAR_FILTER_DROPDOWN_ID } from '@/views/constants/ViewBarFilterDropdownId';
|
import { VIEW_BAR_FILTER_DROPDOWN_ID } from '@/views/constants/ViewBarFilterDropdownId';
|
||||||
|
|
||||||
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
|
import { objectFilterDropdownCurrentRecordFilterComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownCurrentRecordFilterComponentState';
|
||||||
import { useRemoveRecordFilter } from '@/object-record/record-filter/hooks/useRemoveRecordFilter';
|
import { useRemoveRecordFilter } from '@/object-record/record-filter/hooks/useRemoveRecordFilter';
|
||||||
import { isRecordFilterConsideredEmpty } from '@/object-record/record-filter/utils/isRecordFilterConsideredEmpty';
|
import { isRecordFilterConsideredEmpty } from '@/object-record/record-filter/utils/isRecordFilterConsideredEmpty';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
@ -22,17 +22,19 @@ export const ViewBarFilterDropdown = ({
|
|||||||
|
|
||||||
const { removeRecordFilter } = useRemoveRecordFilter();
|
const { removeRecordFilter } = useRemoveRecordFilter();
|
||||||
|
|
||||||
const selectedFilter = useRecoilComponentValueV2(
|
const objectFilterDropdownCurrentRecordFilter = useRecoilComponentValueV2(
|
||||||
selectedFilterComponentState,
|
objectFilterDropdownCurrentRecordFilterComponentState,
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleDropdownClickOutside = () => {
|
const handleDropdownClickOutside = () => {
|
||||||
const recordFilterIsEmpty =
|
const recordFilterIsEmpty =
|
||||||
isDefined(selectedFilter) &&
|
isDefined(objectFilterDropdownCurrentRecordFilter) &&
|
||||||
isRecordFilterConsideredEmpty(selectedFilter);
|
isRecordFilterConsideredEmpty(objectFilterDropdownCurrentRecordFilter);
|
||||||
|
|
||||||
if (recordFilterIsEmpty) {
|
if (recordFilterIsEmpty) {
|
||||||
removeRecordFilter({ recordFilterId: selectedFilter.id });
|
removeRecordFilter({
|
||||||
|
recordFilterId: objectFilterDropdownCurrentRecordFilter.id,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import { fieldMetadataItemIdUsedInDropdownComponentState } from '@/object-record
|
|||||||
import { objectFilterDropdownCurrentRecordFilterComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownCurrentRecordFilterComponentState';
|
import { objectFilterDropdownCurrentRecordFilterComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownCurrentRecordFilterComponentState';
|
||||||
import { objectFilterDropdownSelectedOptionValuesComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedOptionValuesComponentState';
|
import { objectFilterDropdownSelectedOptionValuesComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedOptionValuesComponentState';
|
||||||
import { objectFilterDropdownSelectedRecordIdsComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedRecordIdsComponentState';
|
import { objectFilterDropdownSelectedRecordIdsComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedRecordIdsComponentState';
|
||||||
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
|
|
||||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
||||||
import { subFieldNameUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/subFieldNameUsedInDropdownComponentState';
|
import { subFieldNameUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/subFieldNameUsedInDropdownComponentState';
|
||||||
import { useFilterableFieldMetadataItemsInRecordIndexContext } from '@/object-record/record-filter/hooks/useFilterableFieldMetadataItemsInRecordIndexContext';
|
import { useFilterableFieldMetadataItemsInRecordIndexContext } from '@/object-record/record-filter/hooks/useFilterableFieldMetadataItemsInRecordIndexContext';
|
||||||
@ -42,13 +41,6 @@ export const useSetEditableFilterChipDropdownStates = () => {
|
|||||||
recordFilter.operand,
|
recordFilter.operand,
|
||||||
);
|
);
|
||||||
|
|
||||||
set(
|
|
||||||
selectedFilterComponentState.atomFamily({
|
|
||||||
instanceId: recordFilter.id,
|
|
||||||
}),
|
|
||||||
recordFilter,
|
|
||||||
);
|
|
||||||
|
|
||||||
set(
|
set(
|
||||||
objectFilterDropdownCurrentRecordFilterComponentState.atomFamily({
|
objectFilterDropdownCurrentRecordFilterComponentState.atomFamily({
|
||||||
instanceId: recordFilter.id,
|
instanceId: recordFilter.id,
|
||||||
|
|||||||
Reference in New Issue
Block a user