Search action - Add variables to select and relations + other fixes (#12604)
- Variables can now be handled for select/multiselect/relations - Hide field not supported in forms (source, rating) - Add tests for schemas Remaning issues: - country/currency pickers not working - stories for components - variable picker hidden for dates
This commit is contained in:
@ -1,10 +0,0 @@
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
const StyledColumn = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
gap: ${({ theme }) => theme.spacing(1)};
|
||||
`;
|
||||
|
||||
export const AdvancedFilterDropdownColumn = StyledColumn;
|
||||
@ -1,18 +1,15 @@
|
||||
import { AdvancedFilterLogicalOperatorDropdown } from '@/object-record/advanced-filter/components/AdvancedFilterLogicalOperatorDropdown';
|
||||
import { AdvancedFilterContext } from '@/object-record/advanced-filter/states/context/AdvancedFilterContext';
|
||||
import { RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup';
|
||||
|
||||
import styled from '@emotion/styled';
|
||||
import { useContext } from 'react';
|
||||
import { capitalize } from 'twenty-shared/utils';
|
||||
|
||||
const StyledText = styled.div<{ noPadding?: boolean }>`
|
||||
const StyledText = styled.div`
|
||||
height: ${({ theme }) => theme.spacing(8)};
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
padding-left: ${({ theme, noPadding }) =>
|
||||
noPadding ? 0 : theme.spacing(2.25)};
|
||||
padding-left: ${({ theme }) => theme.spacing(2.25)};
|
||||
`;
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
@ -31,18 +28,16 @@ export const AdvancedFilterLogicalOperatorCell = ({
|
||||
index,
|
||||
recordFilterGroup,
|
||||
}: AdvancedFilterLogicalOperatorCellProps) => {
|
||||
const { isColumn } = useContext(AdvancedFilterContext);
|
||||
|
||||
return (
|
||||
<StyledContainer>
|
||||
{index === 0 ? (
|
||||
<StyledText noPadding={isColumn}>Where</StyledText>
|
||||
<StyledText>Where</StyledText>
|
||||
) : index === 1 ? (
|
||||
<AdvancedFilterLogicalOperatorDropdown
|
||||
recordFilterGroup={recordFilterGroup}
|
||||
/>
|
||||
) : (
|
||||
<StyledText noPadding={isColumn}>
|
||||
<StyledText>
|
||||
{capitalize(recordFilterGroup.logicalOperator.toLowerCase())}
|
||||
</StyledText>
|
||||
)}
|
||||
|
||||
@ -1,36 +0,0 @@
|
||||
import { AdvancedFilterRecordFilterColumn } from '@/object-record/advanced-filter/components/AdvancedFilterRecordFilterColumn';
|
||||
import { AdvancedFilterRecordFilterRow } from '@/object-record/advanced-filter/components/AdvancedFilterRecordFilterRow';
|
||||
import { AdvancedFilterContext } from '@/object-record/advanced-filter/states/context/AdvancedFilterContext';
|
||||
import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
|
||||
import { RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup';
|
||||
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||
import { useContext } from 'react';
|
||||
|
||||
export const AdvancedFilterRecordFilter = ({
|
||||
recordFilterGroup,
|
||||
recordFilter,
|
||||
recordFilterIndex,
|
||||
VariablePicker,
|
||||
}: {
|
||||
recordFilterGroup: RecordFilterGroup;
|
||||
recordFilter: RecordFilter;
|
||||
recordFilterIndex: number;
|
||||
VariablePicker?: VariablePickerComponent;
|
||||
}) => {
|
||||
const { isColumn } = useContext(AdvancedFilterContext);
|
||||
|
||||
return isColumn ? (
|
||||
<AdvancedFilterRecordFilterColumn
|
||||
recordFilterGroup={recordFilterGroup}
|
||||
recordFilter={recordFilter}
|
||||
recordFilterIndex={recordFilterIndex}
|
||||
VariablePicker={VariablePicker}
|
||||
/>
|
||||
) : (
|
||||
<AdvancedFilterRecordFilterRow
|
||||
recordFilterGroup={recordFilterGroup}
|
||||
recordFilter={recordFilter}
|
||||
recordFilterIndex={recordFilterIndex}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@ -1,63 +0,0 @@
|
||||
import { AdvancedFilterDropdownColumn } from '@/object-record/advanced-filter/components/AdvancedFilterDropdownColumn';
|
||||
import { AdvancedFilterFieldSelectDropdownButton } from '@/object-record/advanced-filter/components/AdvancedFilterFieldSelectDropdownButton';
|
||||
import { AdvancedFilterLogicalOperatorCell } from '@/object-record/advanced-filter/components/AdvancedFilterLogicalOperatorCell';
|
||||
import { AdvancedFilterRecordFilterOperandSelect } from '@/object-record/advanced-filter/components/AdvancedFilterRecordFilterOperandSelect';
|
||||
import { AdvancedFilterRecordFilterOptionsDropdown } from '@/object-record/advanced-filter/components/AdvancedFilterRecordFilterOptionsDropdown';
|
||||
import { AdvancedFilterValueFormInput } from '@/object-record/advanced-filter/components/AdvancedFilterValueFormInput';
|
||||
import { getAdvancedFilterObjectFilterDropdownComponentInstanceId } from '@/object-record/advanced-filter/utils/getAdvancedFilterObjectFilterDropdownComponentInstanceId';
|
||||
import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext';
|
||||
import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
|
||||
import { RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup';
|
||||
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
gap: ${({ theme }) => theme.spacing(1)};
|
||||
`;
|
||||
|
||||
export const AdvancedFilterRecordFilterColumn = ({
|
||||
recordFilterGroup,
|
||||
recordFilter,
|
||||
recordFilterIndex,
|
||||
VariablePicker,
|
||||
}: {
|
||||
recordFilterGroup: RecordFilterGroup;
|
||||
recordFilter: RecordFilter;
|
||||
recordFilterIndex: number;
|
||||
VariablePicker?: VariablePickerComponent;
|
||||
}) => {
|
||||
return (
|
||||
<ObjectFilterDropdownComponentInstanceContext.Provider
|
||||
value={{
|
||||
instanceId: getAdvancedFilterObjectFilterDropdownComponentInstanceId(
|
||||
recordFilter.id,
|
||||
),
|
||||
}}
|
||||
>
|
||||
<AdvancedFilterDropdownColumn>
|
||||
<StyledContainer>
|
||||
<AdvancedFilterLogicalOperatorCell
|
||||
index={recordFilterIndex}
|
||||
recordFilterGroup={recordFilterGroup}
|
||||
/>
|
||||
<AdvancedFilterRecordFilterOptionsDropdown
|
||||
recordFilterId={recordFilter.id}
|
||||
/>
|
||||
</StyledContainer>
|
||||
<AdvancedFilterFieldSelectDropdownButton
|
||||
recordFilterId={recordFilter.id}
|
||||
/>
|
||||
<AdvancedFilterRecordFilterOperandSelect
|
||||
recordFilterId={recordFilter.id}
|
||||
/>
|
||||
<AdvancedFilterValueFormInput
|
||||
recordFilterId={recordFilter.id}
|
||||
VariablePicker={VariablePicker}
|
||||
/>
|
||||
</AdvancedFilterDropdownColumn>
|
||||
</ObjectFilterDropdownComponentInstanceContext.Provider>
|
||||
);
|
||||
};
|
||||
@ -1,36 +0,0 @@
|
||||
import { AdvancedFilterRecordFilterGroupColumn } from '@/object-record/advanced-filter/components/AdvancedFilterRecordFilterGroupColumn';
|
||||
import { AdvancedFilterRecordFilterGroupRow } from '@/object-record/advanced-filter/components/AdvancedFilterRecordFilterGroupRow';
|
||||
import { AdvancedFilterContext } from '@/object-record/advanced-filter/states/context/AdvancedFilterContext';
|
||||
import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
|
||||
import { RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup';
|
||||
import { useContext } from 'react';
|
||||
|
||||
export const AdvancedFilterRecordFilterGroup = ({
|
||||
parentRecordFilterGroup,
|
||||
recordFilterGroup,
|
||||
recordFilterGroupIndex,
|
||||
VariablePicker,
|
||||
}: {
|
||||
parentRecordFilterGroup: RecordFilterGroup;
|
||||
recordFilterGroup: RecordFilterGroup;
|
||||
recordFilterGroupIndex: number;
|
||||
VariablePicker?: VariablePickerComponent;
|
||||
}) => {
|
||||
const { isColumn } = useContext(AdvancedFilterContext);
|
||||
|
||||
return isColumn ? (
|
||||
<AdvancedFilterRecordFilterGroupColumn
|
||||
parentRecordFilterGroup={parentRecordFilterGroup}
|
||||
recordFilterGroup={recordFilterGroup}
|
||||
recordFilterGroupIndex={recordFilterGroupIndex}
|
||||
VariablePicker={VariablePicker}
|
||||
/>
|
||||
) : (
|
||||
<AdvancedFilterRecordFilterGroupRow
|
||||
parentRecordFilterGroup={parentRecordFilterGroup}
|
||||
recordFilterGroup={recordFilterGroup}
|
||||
recordFilterGroupIndex={recordFilterGroupIndex}
|
||||
VariablePicker={VariablePicker}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@ -1,8 +1,7 @@
|
||||
import { AdvancedFilterAddFilterRuleSelect } from '@/object-record/advanced-filter/components/AdvancedFilterAddFilterRuleSelect';
|
||||
import { AdvancedFilterRecordFilter } from '@/object-record/advanced-filter/components/AdvancedFilterRecordFilter';
|
||||
import { AdvancedFilterRecordFilterRow } from '@/object-record/advanced-filter/components/AdvancedFilterRecordFilterRow';
|
||||
|
||||
import { useChildRecordFiltersAndRecordFilterGroups } from '@/object-record/advanced-filter/hooks/useChildRecordFiltersAndRecordFilterGroups';
|
||||
import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
|
||||
import styled from '@emotion/styled';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
@ -17,17 +16,14 @@ const StyledContainer = styled.div<{ isGrayBackground?: boolean }>`
|
||||
flex-direction: column;
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
padding: ${({ theme }) => theme.spacing(2)};
|
||||
overflow: hidden;
|
||||
`;
|
||||
|
||||
type AdvancedFilterRecordFilterGroupChildrenProps = {
|
||||
recordFilterGroupId: string;
|
||||
VariablePicker?: VariablePickerComponent;
|
||||
};
|
||||
|
||||
export const AdvancedFilterRecordFilterGroupChildren = ({
|
||||
recordFilterGroupId,
|
||||
VariablePicker,
|
||||
}: AdvancedFilterRecordFilterGroupChildrenProps) => {
|
||||
const { currentRecordFilterGroup, childRecordFilters } =
|
||||
useChildRecordFiltersAndRecordFilterGroups({
|
||||
@ -45,12 +41,11 @@ export const AdvancedFilterRecordFilterGroupChildren = ({
|
||||
return (
|
||||
<StyledContainer isGrayBackground={hasParentRecordFilterGroup}>
|
||||
{childRecordFilters.map((childRecordFilter, childRecordFilterIndex) => (
|
||||
<AdvancedFilterRecordFilter
|
||||
<AdvancedFilterRecordFilterRow
|
||||
key={childRecordFilter.id}
|
||||
recordFilter={childRecordFilter}
|
||||
recordFilterIndex={childRecordFilterIndex}
|
||||
recordFilterGroup={currentRecordFilterGroup}
|
||||
VariablePicker={VariablePicker}
|
||||
/>
|
||||
))}
|
||||
<AdvancedFilterAddFilterRuleSelect
|
||||
|
||||
@ -1,44 +0,0 @@
|
||||
import { AdvancedFilterDropdownColumn } from '@/object-record/advanced-filter/components/AdvancedFilterDropdownColumn';
|
||||
import { AdvancedFilterLogicalOperatorCell } from '@/object-record/advanced-filter/components/AdvancedFilterLogicalOperatorCell';
|
||||
import { AdvancedFilterRecordFilterGroupChildren } from '@/object-record/advanced-filter/components/AdvancedFilterRecordFilterGroupChildren';
|
||||
import { AdvancedFilterRecordFilterGroupOptionsDropdown } from '@/object-record/advanced-filter/components/AdvancedFilterRecordFilterGroupOptionsDropdown';
|
||||
import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
|
||||
import { RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
gap: ${({ theme }) => theme.spacing(1)};
|
||||
`;
|
||||
|
||||
export const AdvancedFilterRecordFilterGroupColumn = ({
|
||||
parentRecordFilterGroup,
|
||||
recordFilterGroup,
|
||||
recordFilterGroupIndex,
|
||||
VariablePicker,
|
||||
}: {
|
||||
parentRecordFilterGroup: RecordFilterGroup;
|
||||
recordFilterGroup: RecordFilterGroup;
|
||||
recordFilterGroupIndex: number;
|
||||
VariablePicker?: VariablePickerComponent;
|
||||
}) => {
|
||||
return (
|
||||
<AdvancedFilterDropdownColumn>
|
||||
<StyledContainer>
|
||||
<AdvancedFilterLogicalOperatorCell
|
||||
index={recordFilterGroupIndex}
|
||||
recordFilterGroup={parentRecordFilterGroup}
|
||||
/>
|
||||
<AdvancedFilterRecordFilterGroupOptionsDropdown
|
||||
recordFilterGroupId={recordFilterGroup.id}
|
||||
/>
|
||||
</StyledContainer>
|
||||
<AdvancedFilterRecordFilterGroupChildren
|
||||
recordFilterGroupId={recordFilterGroup.id}
|
||||
VariablePicker={VariablePicker}
|
||||
/>
|
||||
</AdvancedFilterDropdownColumn>
|
||||
);
|
||||
};
|
||||
@ -2,19 +2,16 @@ import { AdvancedFilterDropdownRow } from '@/object-record/advanced-filter/compo
|
||||
import { AdvancedFilterLogicalOperatorCell } from '@/object-record/advanced-filter/components/AdvancedFilterLogicalOperatorCell';
|
||||
import { AdvancedFilterRecordFilterGroupChildren } from '@/object-record/advanced-filter/components/AdvancedFilterRecordFilterGroupChildren';
|
||||
import { AdvancedFilterRecordFilterGroupOptionsDropdown } from '@/object-record/advanced-filter/components/AdvancedFilterRecordFilterGroupOptionsDropdown';
|
||||
import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
|
||||
import { RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup';
|
||||
|
||||
export const AdvancedFilterRecordFilterGroupRow = ({
|
||||
parentRecordFilterGroup,
|
||||
recordFilterGroup,
|
||||
recordFilterGroupIndex,
|
||||
VariablePicker,
|
||||
}: {
|
||||
parentRecordFilterGroup: RecordFilterGroup;
|
||||
recordFilterGroup: RecordFilterGroup;
|
||||
recordFilterGroupIndex: number;
|
||||
VariablePicker?: VariablePickerComponent;
|
||||
}) => {
|
||||
return (
|
||||
<AdvancedFilterDropdownRow>
|
||||
@ -24,7 +21,6 @@ export const AdvancedFilterRecordFilterGroupRow = ({
|
||||
/>
|
||||
<AdvancedFilterRecordFilterGroupChildren
|
||||
recordFilterGroupId={recordFilterGroup.id}
|
||||
VariablePicker={VariablePicker}
|
||||
/>
|
||||
<AdvancedFilterRecordFilterGroupOptionsDropdown
|
||||
recordFilterGroupId={recordFilterGroup.id}
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import { DEFAULT_ADVANCED_FILTER_DROPDOWN_OFFSET } from '@/object-record/advanced-filter/constants/DefaultAdvancedFilterDropdownOffset';
|
||||
import { AdvancedFilterContext } from '@/object-record/advanced-filter/states/context/AdvancedFilterContext';
|
||||
import { useApplyObjectFilterDropdownOperand } from '@/object-record/object-filter-dropdown/hooks/useApplyObjectFilterDropdownOperand';
|
||||
|
||||
import { getOperandLabel } from '@/object-record/object-filter-dropdown/utils/getOperandLabel';
|
||||
@ -17,20 +16,21 @@ import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
||||
import styled from '@emotion/styled';
|
||||
import { useContext } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { MenuItem } from 'twenty-ui/navigation';
|
||||
|
||||
const StyledContainer = styled.div<{ isColumn?: boolean }>`
|
||||
width: ${({ isColumn }) => (isColumn ? 'auto' : '100px')};
|
||||
const StyledContainer = styled.div<{ width?: string }>`
|
||||
width: ${({ width }) => width ?? '100px'};
|
||||
`;
|
||||
|
||||
type AdvancedFilterRecordFilterOperandSelectProps = {
|
||||
recordFilterId: string;
|
||||
widthFromProps?: string;
|
||||
};
|
||||
|
||||
export const AdvancedFilterRecordFilterOperandSelect = ({
|
||||
recordFilterId,
|
||||
widthFromProps,
|
||||
}: AdvancedFilterRecordFilterOperandSelectProps) => {
|
||||
const dropdownId = `advanced-filter-view-filter-operand-${recordFilterId}`;
|
||||
|
||||
@ -38,8 +38,6 @@ export const AdvancedFilterRecordFilterOperandSelect = ({
|
||||
currentRecordFiltersComponentState,
|
||||
);
|
||||
|
||||
const { isColumn } = useContext(AdvancedFilterContext);
|
||||
|
||||
const filter = currentRecordFilters.find(
|
||||
(recordFilter) => recordFilter.id === recordFilterId,
|
||||
);
|
||||
@ -86,7 +84,7 @@ export const AdvancedFilterRecordFilterOperandSelect = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<StyledContainer isColumn={isColumn}>
|
||||
<StyledContainer width={widthFromProps}>
|
||||
<Dropdown
|
||||
dropdownId={dropdownId}
|
||||
clickableComponent={
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { AdvancedFilterAddFilterRuleSelect } from '@/object-record/advanced-filter/components/AdvancedFilterAddFilterRuleSelect';
|
||||
import { AdvancedFilterRecordFilter } from '@/object-record/advanced-filter/components/AdvancedFilterRecordFilter';
|
||||
import { AdvancedFilterRecordFilterGroup } from '@/object-record/advanced-filter/components/AdvancedFilterRecordFilterGroup';
|
||||
import { AdvancedFilterRecordFilterGroupRow } from '@/object-record/advanced-filter/components/AdvancedFilterRecordFilterGroupRow';
|
||||
import { AdvancedFilterRecordFilterRow } from '@/object-record/advanced-filter/components/AdvancedFilterRecordFilterRow';
|
||||
|
||||
import { ADVANCED_FILTER_DROPDOWN_CONTENT_WIDTH } from '@/object-record/advanced-filter/constants/AdvancedFilterDropdownContentWidth';
|
||||
import { useChildRecordFiltersAndRecordFilterGroups } from '@/object-record/advanced-filter/hooks/useChildRecordFiltersAndRecordFilterGroups';
|
||||
@ -45,14 +45,14 @@ export const AdvancedFilterRootRecordFilterGroup = () => {
|
||||
isRecordFilterGroupChildARecordFilterGroup(
|
||||
recordFilterGroupChild,
|
||||
) ? (
|
||||
<AdvancedFilterRecordFilterGroup
|
||||
<AdvancedFilterRecordFilterGroupRow
|
||||
key={recordFilterGroupChild.id}
|
||||
parentRecordFilterGroup={rootRecordFilterGroup}
|
||||
recordFilterGroup={recordFilterGroupChild}
|
||||
recordFilterGroupIndex={recordFilterGroupChildIndex}
|
||||
/>
|
||||
) : (
|
||||
<AdvancedFilterRecordFilter
|
||||
<AdvancedFilterRecordFilterRow
|
||||
key={recordFilterGroupChild.id}
|
||||
recordFilterGroup={rootRecordFilterGroup}
|
||||
recordFilter={recordFilterGroupChild}
|
||||
|
||||
@ -1,79 +0,0 @@
|
||||
import { subFieldNameUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/subFieldNameUsedInDropdownComponentState';
|
||||
import { FormCountryCodeSelectInput } from '@/object-record/record-field/form-types/components/FormCountryCodeSelectInput';
|
||||
import { FormCountrySelectInput } from '@/object-record/record-field/form-types/components/FormCountrySelectInput';
|
||||
import { FormNumberFieldInput } from '@/object-record/record-field/form-types/components/FormNumberFieldInput';
|
||||
import { FormTextFieldInput } from '@/object-record/record-field/form-types/components/FormTextFieldInput';
|
||||
import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
|
||||
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { JsonValue } from 'type-fest';
|
||||
|
||||
export const AdvancedFilterValueFormCompositeFieldInput = ({
|
||||
recordFilter,
|
||||
onChange,
|
||||
VariablePicker,
|
||||
}: {
|
||||
recordFilter: RecordFilter;
|
||||
onChange: (newValue: JsonValue) => void;
|
||||
VariablePicker?: VariablePickerComponent;
|
||||
}) => {
|
||||
const subFieldNameUsedInDropdown = useRecoilComponentValueV2(
|
||||
subFieldNameUsedInDropdownComponentState,
|
||||
);
|
||||
|
||||
const filterType = recordFilter.type;
|
||||
|
||||
return (
|
||||
<>
|
||||
{filterType === 'ADDRESS' ? (
|
||||
subFieldNameUsedInDropdown === 'addressCountry' ? (
|
||||
<FormCountrySelectInput
|
||||
selectedCountryName={recordFilter.value}
|
||||
onChange={onChange}
|
||||
VariablePicker={VariablePicker}
|
||||
/>
|
||||
) : (
|
||||
<FormTextFieldInput
|
||||
defaultValue={recordFilter.value}
|
||||
onChange={onChange}
|
||||
VariablePicker={VariablePicker}
|
||||
/>
|
||||
)
|
||||
) : filterType === 'CURRENCY' ? (
|
||||
recordFilter.subFieldName === 'currencyCode' ? (
|
||||
<FormCountryCodeSelectInput
|
||||
selectedCountryCode={recordFilter.value}
|
||||
onChange={onChange}
|
||||
VariablePicker={VariablePicker}
|
||||
/>
|
||||
) : recordFilter.subFieldName === 'amountMicros' ? (
|
||||
<FormNumberFieldInput
|
||||
defaultValue={recordFilter.value}
|
||||
onChange={onChange}
|
||||
VariablePicker={VariablePicker}
|
||||
/>
|
||||
) : null
|
||||
) : filterType === 'PHONES' ? (
|
||||
recordFilter.subFieldName === 'primaryPhoneNumber' ? (
|
||||
<FormNumberFieldInput
|
||||
defaultValue={recordFilter.value}
|
||||
onChange={onChange}
|
||||
VariablePicker={VariablePicker}
|
||||
/>
|
||||
) : (
|
||||
<FormTextFieldInput
|
||||
defaultValue={recordFilter.value}
|
||||
onChange={onChange}
|
||||
VariablePicker={VariablePicker}
|
||||
/>
|
||||
)
|
||||
) : (
|
||||
<FormTextFieldInput
|
||||
defaultValue={recordFilter.value}
|
||||
onChange={onChange}
|
||||
VariablePicker={VariablePicker}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@ -1,92 +0,0 @@
|
||||
import { formatFieldMetadataItemAsFieldDefinition } from '@/object-metadata/utils/formatFieldMetadataItemAsFieldDefinition';
|
||||
import { AdvancedFilterValueFormCompositeFieldInput } from '@/object-record/advanced-filter/components/AdvancedFilterValueFormCompositeFieldInput';
|
||||
import { useApplyObjectFilterDropdownFilterValue } from '@/object-record/object-filter-dropdown/hooks/useApplyObjectFilterDropdownFilterValue';
|
||||
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
|
||||
import { subFieldNameUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/subFieldNameUsedInDropdownComponentState';
|
||||
import { FormFieldInput } from '@/object-record/record-field/components/FormFieldInput';
|
||||
import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
|
||||
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { isObject } from '@sniptt/guards';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { JsonValue } from 'type-fest';
|
||||
|
||||
export const AdvancedFilterValueFormInput = ({
|
||||
recordFilterId,
|
||||
VariablePicker,
|
||||
}: {
|
||||
recordFilterId: string;
|
||||
VariablePicker?: VariablePickerComponent;
|
||||
}) => {
|
||||
const currentRecordFilters = useRecoilComponentValueV2(
|
||||
currentRecordFiltersComponentState,
|
||||
);
|
||||
|
||||
const { objectMetadataItem } = useRecordIndexContextOrThrow();
|
||||
|
||||
const subFieldNameUsedInDropdown = useRecoilComponentValueV2(
|
||||
subFieldNameUsedInDropdownComponentState,
|
||||
);
|
||||
|
||||
const recordFilter = currentRecordFilters.find(
|
||||
(recordFilter) => recordFilter.id === recordFilterId,
|
||||
);
|
||||
|
||||
const isDisabled = !recordFilter?.fieldMetadataId || !recordFilter.operand;
|
||||
|
||||
const { applyObjectFilterDropdownFilterValue } =
|
||||
useApplyObjectFilterDropdownFilterValue();
|
||||
|
||||
const handleChange = (newValue: JsonValue) => {
|
||||
if (typeof newValue === 'string') {
|
||||
applyObjectFilterDropdownFilterValue(newValue);
|
||||
} else if (Array.isArray(newValue) || isObject(newValue)) {
|
||||
applyObjectFilterDropdownFilterValue(JSON.stringify(newValue));
|
||||
} else {
|
||||
applyObjectFilterDropdownFilterValue(String(newValue));
|
||||
}
|
||||
};
|
||||
|
||||
const fieldMetadataItemUsedInDropdown = useRecoilComponentValueV2(
|
||||
fieldMetadataItemUsedInDropdownComponentSelector,
|
||||
);
|
||||
|
||||
const fieldDefinition = fieldMetadataItemUsedInDropdown
|
||||
? formatFieldMetadataItemAsFieldDefinition({
|
||||
field: fieldMetadataItemUsedInDropdown,
|
||||
objectMetadataItem: objectMetadataItem,
|
||||
})
|
||||
: null;
|
||||
|
||||
if (isDisabled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isDefined(subFieldNameUsedInDropdown)) {
|
||||
return (
|
||||
<AdvancedFilterValueFormCompositeFieldInput
|
||||
recordFilter={recordFilter}
|
||||
VariablePicker={VariablePicker}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const field = {
|
||||
type: recordFilter.type as FieldMetadataType,
|
||||
label: '',
|
||||
metadata: fieldDefinition?.metadata as FieldMetadata,
|
||||
};
|
||||
|
||||
return (
|
||||
<FormFieldInput
|
||||
field={field}
|
||||
defaultValue={recordFilter.value}
|
||||
onChange={handleChange}
|
||||
VariablePicker={VariablePicker}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@ -2,14 +2,12 @@ import { AdvancedFilterDropdownFilterInput } from '@/object-record/advanced-filt
|
||||
import { AdvancedFilterDropdownTextInput } from '@/object-record/advanced-filter/components/AdvancedFilterDropdownTextInput';
|
||||
import { AdvancedFilterValueInputDropdownButtonClickableSelect } from '@/object-record/advanced-filter/components/AdvancedFilterValueInputDropdownButtonClickableSelect';
|
||||
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 { TEXT_FILTER_TYPES } from '@/object-record/object-filter-dropdown/constants/TextFilterTypes';
|
||||
import { shouldShowFilterTextInput } from '@/object-record/advanced-filter/utils/shouldShowFilterTextInput';
|
||||
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 { subFieldNameUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/subFieldNameUsedInDropdownComponentState';
|
||||
import { configurableViewFilterOperands } from '@/object-record/object-filter-dropdown/utils/configurableViewFilterOperands';
|
||||
import { isExpectedSubFieldName } from '@/object-record/object-filter-dropdown/utils/isExpectedSubFieldName';
|
||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { DropdownOffset } from '@/ui/layout/dropdown/types/DropdownOffset';
|
||||
@ -17,7 +15,6 @@ import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||
|
||||
import styled from '@emotion/styled';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
const StyledValueDropdownContainer = styled.div`
|
||||
@ -83,31 +80,10 @@ export const AdvancedFilterValueInput = ({
|
||||
? ({ y: -33, x: 0 } satisfies DropdownOffset)
|
||||
: DEFAULT_ADVANCED_FILTER_DROPDOWN_OFFSET;
|
||||
|
||||
const isFilterableByTextValue =
|
||||
isDefined(filterType) &&
|
||||
(TEXT_FILTER_TYPES.includes(filterType) ||
|
||||
NUMBER_FILTER_TYPES.includes(filterType));
|
||||
|
||||
const isCurrencyAmountMicrosFilter = isExpectedSubFieldName(
|
||||
FieldMetadataType.CURRENCY,
|
||||
'amountMicros',
|
||||
recordFilter.subFieldName,
|
||||
);
|
||||
|
||||
const isAddressFilterOnSubFieldOtherThanCountry =
|
||||
filterType === 'ADDRESS' && subFieldNameUsedInDropdown !== 'addressCountry';
|
||||
|
||||
const isActorNameFilter = isExpectedSubFieldName(
|
||||
FieldMetadataType.ACTOR,
|
||||
'name',
|
||||
recordFilter.subFieldName,
|
||||
);
|
||||
|
||||
const showFilterTextInputInsteadOfDropdown =
|
||||
isFilterableByTextValue ||
|
||||
isCurrencyAmountMicrosFilter ||
|
||||
isAddressFilterOnSubFieldOtherThanCountry ||
|
||||
isActorNameFilter;
|
||||
const showFilterTextInputInsteadOfDropdown = shouldShowFilterTextInput({
|
||||
recordFilter,
|
||||
subFieldNameUsedInDropdown,
|
||||
});
|
||||
|
||||
return (
|
||||
<StyledValueDropdownContainer>
|
||||
|
||||
@ -2,7 +2,7 @@ import { createContext } from 'react';
|
||||
|
||||
type AdvancedFilterContextType = {
|
||||
onUpdate?: () => void;
|
||||
isColumn?: boolean;
|
||||
isWorkflowFindRecords?: boolean;
|
||||
};
|
||||
|
||||
export const AdvancedFilterContext = createContext<AdvancedFilterContextType>(
|
||||
|
||||
@ -0,0 +1,42 @@
|
||||
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 { isExpectedSubFieldName } from '@/object-record/object-filter-dropdown/utils/isExpectedSubFieldName';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
import { RecordFilter } from '../../record-filter/types/RecordFilter';
|
||||
|
||||
import { CompositeFieldSubFieldName } from '@/settings/data-model/types/CompositeFieldSubFieldName';
|
||||
|
||||
export const shouldShowFilterTextInput = ({
|
||||
recordFilter,
|
||||
subFieldNameUsedInDropdown,
|
||||
}: {
|
||||
recordFilter: RecordFilter;
|
||||
subFieldNameUsedInDropdown: CompositeFieldSubFieldName | null | undefined;
|
||||
}) => {
|
||||
const isFilterableByTextValue =
|
||||
TEXT_FILTER_TYPES.includes(recordFilter.type) ||
|
||||
NUMBER_FILTER_TYPES.includes(recordFilter.type);
|
||||
|
||||
const isCurrencyAmountMicrosFilter = isExpectedSubFieldName(
|
||||
FieldMetadataType.CURRENCY,
|
||||
'amountMicros',
|
||||
recordFilter.subFieldName,
|
||||
);
|
||||
|
||||
const isAddressFilterOnSubFieldOtherThanCountry =
|
||||
recordFilter.type === 'ADDRESS' &&
|
||||
subFieldNameUsedInDropdown !== 'addressCountry';
|
||||
|
||||
const isActorNameFilter = isExpectedSubFieldName(
|
||||
FieldMetadataType.ACTOR,
|
||||
'name',
|
||||
recordFilter.subFieldName,
|
||||
);
|
||||
|
||||
return (
|
||||
isFilterableByTextValue ||
|
||||
isCurrencyAmountMicrosFilter ||
|
||||
isAddressFilterOnSubFieldOtherThanCountry ||
|
||||
isActorNameFilter
|
||||
);
|
||||
};
|
||||
@ -15,8 +15,8 @@ import { SelectableItem } from '@/object-record/select/types/SelectableItem';
|
||||
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { RelationFilterValue } from '@/views/view-filter-value/types/RelationFilterValue';
|
||||
import { arrayOfUuidOrVariableSchema } from '@/views/view-filter-value/validation-schemas/arrayOfUuidsOrVariablesSchema';
|
||||
import { jsonRelationFilterValueSchema } from '@/views/view-filter-value/validation-schemas/jsonRelationFilterValueSchema';
|
||||
import { simpleRelationFilterValueSchema } from '@/views/view-filter-value/validation-schemas/simpleRelationFilterValueSchema';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IconUserCircle } from 'twenty-ui/display';
|
||||
|
||||
@ -59,7 +59,7 @@ export const ObjectFilterDropdownRecordSelect = ({
|
||||
const { isCurrentWorkspaceMemberSelected } = jsonRelationFilterValueSchema
|
||||
.catch({
|
||||
isCurrentWorkspaceMemberSelected: false,
|
||||
selectedRecordIds: simpleRelationFilterValueSchema.parse(
|
||||
selectedRecordIds: arrayOfUuidOrVariableSchema.parse(
|
||||
objectFilterDropdownFilterValue,
|
||||
),
|
||||
})
|
||||
@ -105,7 +105,7 @@ export const ObjectFilterDropdownRecordSelect = ({
|
||||
const { selectedRecordIds } = jsonRelationFilterValueSchema
|
||||
.catch({
|
||||
isCurrentWorkspaceMemberSelected: false,
|
||||
selectedRecordIds: simpleRelationFilterValueSchema.parse(
|
||||
selectedRecordIds: arrayOfUuidOrVariableSchema.parse(
|
||||
recordFilterUsedInDropdown?.value,
|
||||
),
|
||||
})
|
||||
|
||||
@ -12,11 +12,13 @@ export type FormCountryCodeSelectInputUpdatedValue = CountryCode | '';
|
||||
export const FormCountryCodeSelectInput = ({
|
||||
selectedCountryCode,
|
||||
onChange,
|
||||
label,
|
||||
readonly = false,
|
||||
VariablePicker,
|
||||
}: {
|
||||
selectedCountryCode: string;
|
||||
onChange: (countryCode: FormCountryCodeSelectInputUpdatedValue) => void;
|
||||
label?: string;
|
||||
readonly?: boolean;
|
||||
VariablePicker?: VariablePickerComponent;
|
||||
}) => {
|
||||
@ -55,7 +57,7 @@ export const FormCountryCodeSelectInput = ({
|
||||
|
||||
return (
|
||||
<FormSelectFieldInput
|
||||
label="Country Code"
|
||||
label={label}
|
||||
onChange={onCountryCodeChange}
|
||||
options={options}
|
||||
defaultValue={selectedCountryCode}
|
||||
|
||||
@ -55,13 +55,14 @@ export const FormPhoneFieldInput = ({
|
||||
{label && <InputLabel>{label}</InputLabel>}
|
||||
<FormNestedFieldInputContainer>
|
||||
<FormCountryCodeSelectInput
|
||||
selectedCountryCode={defaultValue?.primaryPhoneCountryCode || ''}
|
||||
label="Country Code"
|
||||
selectedCountryCode={defaultValue?.primaryPhoneCountryCode ?? ''}
|
||||
onChange={handleCountryChange}
|
||||
readonly={readonly}
|
||||
/>
|
||||
<FormNumberFieldInput
|
||||
label="Phone Number"
|
||||
defaultValue={defaultValue?.primaryPhoneNumber || ''}
|
||||
defaultValue={defaultValue?.primaryPhoneNumber ?? ''}
|
||||
onChange={handleNumberChange}
|
||||
VariablePicker={VariablePicker}
|
||||
placeholder="Enter phone number"
|
||||
|
||||
@ -6,7 +6,9 @@ import { FormCountryCodeSelectInput } from '../FormCountryCodeSelectInput';
|
||||
const meta: Meta<typeof FormCountryCodeSelectInput> = {
|
||||
title: 'UI/Data/Field/Form/Input/FormCountryCodeSelectInput',
|
||||
component: FormCountryCodeSelectInput,
|
||||
args: {},
|
||||
args: {
|
||||
label: 'Country Code',
|
||||
},
|
||||
argTypes: {},
|
||||
};
|
||||
|
||||
|
||||
@ -1,12 +1,25 @@
|
||||
import { AdvancedFilterContext } from '@/object-record/advanced-filter/states/context/AdvancedFilterContext';
|
||||
import { useFilterableFieldMetadataItems } from '@/object-record/record-filter/hooks/useFilterableFieldMetadataItems';
|
||||
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
|
||||
import { shouldDisplayFormField } from '@/workflow/workflow-steps/workflow-actions/utils/shouldDisplayFormField';
|
||||
import { useContext } from 'react';
|
||||
|
||||
export const useFilterableFieldMetadataItemsInRecordIndexContext = () => {
|
||||
const { objectMetadataItem } = useRecordIndexContextOrThrow();
|
||||
const { isWorkflowFindRecords } = useContext(AdvancedFilterContext);
|
||||
|
||||
const { filterableFieldMetadataItems } = useFilterableFieldMetadataItems(
|
||||
objectMetadataItem.id,
|
||||
);
|
||||
const {
|
||||
filterableFieldMetadataItems: filterableFieldMetadataItemsForRecordIndex,
|
||||
} = useFilterableFieldMetadataItems(objectMetadataItem.id);
|
||||
|
||||
const filterableFieldMetadataItems = isWorkflowFindRecords
|
||||
? filterableFieldMetadataItemsForRecordIndex.filter((fieldMetadataItem) =>
|
||||
shouldDisplayFormField({
|
||||
fieldMetadataItem,
|
||||
actionType: 'FIND_RECORDS',
|
||||
}),
|
||||
)
|
||||
: filterableFieldMetadataItemsForRecordIndex;
|
||||
|
||||
return { filterableFieldMetadataItems };
|
||||
};
|
||||
|
||||
@ -33,9 +33,7 @@ import { RecordFilterValueDependencies } from '@/object-record/record-filter/typ
|
||||
import { getEmptyRecordGqlOperationFilter } from '@/object-record/record-filter/utils/getEmptyRecordGqlOperationFilter';
|
||||
|
||||
import { resolveDateViewFilterValue } from '@/views/view-filter-value/utils/resolveDateViewFilterValue';
|
||||
import { resolveSelectViewFilterValue } from '@/views/view-filter-value/utils/resolveSelectViewFilterValue';
|
||||
import { jsonRelationFilterValueSchema } from '@/views/view-filter-value/validation-schemas/jsonRelationFilterValueSchema';
|
||||
import { simpleRelationFilterValueSchema } from '@/views/view-filter-value/validation-schemas/simpleRelationFilterValueSchema';
|
||||
import { endOfDay, roundToNearestMinutes, startOfDay } from 'date-fns';
|
||||
import { z } from 'zod';
|
||||
|
||||
@ -44,6 +42,8 @@ import { checkIfShouldComputeEmptinessFilter } from '@/object-record/record-filt
|
||||
import { checkIfShouldSkipFiltering } from '@/object-record/record-filter/utils/compute-record-gql-operation-filter/checkIfShouldSkipFiltering';
|
||||
import { computeGqlOperationFilterForEmails } from '@/object-record/record-filter/utils/compute-record-gql-operation-filter/for-composite-field/computeGqlOperationFilterForEmails';
|
||||
import { computeGqlOperationFilterForLinks } from '@/object-record/record-filter/utils/compute-record-gql-operation-filter/for-composite-field/computeGqlOperationFilterForLinks';
|
||||
import { arrayOfStringsOrVariablesSchema } from '@/views/view-filter-value/validation-schemas/arrayOfStringsOrVariablesSchema';
|
||||
import { arrayOfUuidOrVariableSchema } from '@/views/view-filter-value/validation-schemas/arrayOfUuidsOrVariablesSchema';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
@ -312,7 +312,7 @@ export const turnRecordFilterIntoRecordGqlOperationFilter = ({
|
||||
jsonRelationFilterValueSchema
|
||||
.catch({
|
||||
isCurrentWorkspaceMemberSelected: false,
|
||||
selectedRecordIds: simpleRelationFilterValueSchema.parse(
|
||||
selectedRecordIds: arrayOfUuidOrVariableSchema.parse(
|
||||
recordFilter.value,
|
||||
),
|
||||
})
|
||||
@ -759,7 +759,7 @@ export const turnRecordFilterIntoRecordGqlOperationFilter = ({
|
||||
);
|
||||
}
|
||||
case 'MULTI_SELECT': {
|
||||
const options = resolveSelectViewFilterValue(recordFilter);
|
||||
const options = arrayOfStringsOrVariablesSchema.parse(recordFilter.value);
|
||||
|
||||
if (options.length === 0) return;
|
||||
|
||||
@ -817,7 +817,7 @@ export const turnRecordFilterIntoRecordGqlOperationFilter = ({
|
||||
}
|
||||
}
|
||||
case 'SELECT': {
|
||||
const options = resolveSelectViewFilterValue(recordFilter);
|
||||
const options = arrayOfStringsOrVariablesSchema.parse(recordFilter.value);
|
||||
|
||||
if (options.length === 0) return;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user