Manage composite fields in step filters (#13407)
- add to step output schema the information that field is a composite sub field - from output schema, when selecting the variable, copy all info required to stepFilter - from stepFilter, when selecting a value, display a special component for composites
This commit is contained in:
+26
-8
@@ -1,3 +1,4 @@
|
||||
import { useGetFieldMetadataItemById } from '@/object-metadata/hooks/useGetFieldMetadataItemById';
|
||||
import { SelectControl } from '@/ui/input/components/SelectControl';
|
||||
import { useWorkflowStepContextOrThrow } from '@/workflow/states/context/WorkflowStepContext';
|
||||
import { stepsOutputSchemaFamilySelector } from '@/workflow/states/selectors/stepsOutputSchemaFamilySelector';
|
||||
@@ -38,6 +39,8 @@ export const WorkflowStepFilterFieldSelect = ({
|
||||
}),
|
||||
);
|
||||
|
||||
const { getFieldMetadataItemById } = useGetFieldMetadataItemById();
|
||||
|
||||
const handleChange = useRecoilCallback(
|
||||
({ snapshot }) =>
|
||||
(variableName: string) => {
|
||||
@@ -54,24 +57,39 @@ export const WorkflowStepFilterFieldSelect = ({
|
||||
)
|
||||
.getValue();
|
||||
|
||||
const { variableLabel, variableType } =
|
||||
searchVariableThroughOutputSchema({
|
||||
stepOutputSchema: currentStepOutputSchema?.[0],
|
||||
rawVariableName: variableName,
|
||||
isFullRecord: false,
|
||||
});
|
||||
const {
|
||||
variableLabel,
|
||||
variableType,
|
||||
fieldMetadataId,
|
||||
compositeFieldSubFieldName,
|
||||
} = searchVariableThroughOutputSchema({
|
||||
stepOutputSchema: currentStepOutputSchema?.[0],
|
||||
rawVariableName: variableName,
|
||||
isFullRecord: false,
|
||||
});
|
||||
|
||||
const filterType = isDefined(fieldMetadataId)
|
||||
? getFieldMetadataItemById(fieldMetadataId).type
|
||||
: variableType;
|
||||
|
||||
upsertStepFilterSettings({
|
||||
stepFilterToUpsert: {
|
||||
...stepFilter,
|
||||
stepOutputKey: variableName,
|
||||
displayValue: variableLabel ?? '',
|
||||
type: variableType ?? 'unknown',
|
||||
type: filterType ?? 'unknown',
|
||||
value: '',
|
||||
fieldMetadataId,
|
||||
compositeFieldSubFieldName,
|
||||
},
|
||||
});
|
||||
},
|
||||
[upsertStepFilterSettings, stepFilter, workflowVersionId],
|
||||
[
|
||||
upsertStepFilterSettings,
|
||||
stepFilter,
|
||||
workflowVersionId,
|
||||
getFieldMetadataItemById,
|
||||
],
|
||||
);
|
||||
|
||||
if (!isDefined(stepId)) {
|
||||
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
import { FormCountryMultiSelectInput } from '@/object-record/record-field/form-types/components/FormCountryMultiSelectInput';
|
||||
import { FormMultiSelectFieldInput } from '@/object-record/record-field/form-types/components/FormMultiSelectFieldInput';
|
||||
import { FormNumberFieldInput } from '@/object-record/record-field/form-types/components/FormNumberFieldInput';
|
||||
import { FormTextFieldInput } from '@/object-record/record-field/form-types/components/FormTextFieldInput';
|
||||
import { CURRENCIES } from '@/settings/data-model/constants/Currencies';
|
||||
import { WorkflowStepFilterContext } from '@/workflow/workflow-steps/workflow-actions/filter-action/states/context/WorkflowStepFilterContext';
|
||||
import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components/WorkflowVariablePicker';
|
||||
import { useContext } from 'react';
|
||||
import { StepFilter } from 'twenty-shared/types';
|
||||
import { JsonValue } from 'type-fest';
|
||||
|
||||
export const WorkflowStepFilterValueCompositeInput = ({
|
||||
stepFilter,
|
||||
onChange,
|
||||
}: {
|
||||
stepFilter: StepFilter;
|
||||
onChange: (newValue: JsonValue) => void;
|
||||
}) => {
|
||||
const { readonly } = useContext(WorkflowStepFilterContext);
|
||||
const { type: filterType, compositeFieldSubFieldName: subFieldName } =
|
||||
stepFilter;
|
||||
|
||||
return (
|
||||
<>
|
||||
{filterType === 'ADDRESS' ? (
|
||||
subFieldName === 'addressCountry' ? (
|
||||
<FormCountryMultiSelectInput
|
||||
defaultValue={stepFilter.value}
|
||||
onChange={onChange}
|
||||
VariablePicker={WorkflowVariablePicker}
|
||||
readonly={readonly}
|
||||
/>
|
||||
) : (
|
||||
<FormTextFieldInput
|
||||
defaultValue={stepFilter.value}
|
||||
onChange={onChange}
|
||||
VariablePicker={WorkflowVariablePicker}
|
||||
readonly={readonly}
|
||||
/>
|
||||
)
|
||||
) : filterType === 'CURRENCY' ? (
|
||||
subFieldName === 'currencyCode' ? (
|
||||
<FormMultiSelectFieldInput
|
||||
defaultValue={stepFilter.value}
|
||||
onChange={onChange}
|
||||
VariablePicker={WorkflowVariablePicker}
|
||||
options={CURRENCIES}
|
||||
readonly={readonly}
|
||||
/>
|
||||
) : subFieldName === 'amountMicros' ? (
|
||||
<FormNumberFieldInput
|
||||
defaultValue={stepFilter.value}
|
||||
onChange={onChange}
|
||||
VariablePicker={WorkflowVariablePicker}
|
||||
readonly={readonly}
|
||||
/>
|
||||
) : null
|
||||
) : filterType === 'PHONES' ? (
|
||||
subFieldName === 'primaryPhoneNumber' ? (
|
||||
<FormNumberFieldInput
|
||||
defaultValue={stepFilter.value}
|
||||
onChange={onChange}
|
||||
VariablePicker={WorkflowVariablePicker}
|
||||
readonly={readonly}
|
||||
/>
|
||||
) : (
|
||||
<FormTextFieldInput
|
||||
defaultValue={stepFilter.value}
|
||||
onChange={onChange}
|
||||
VariablePicker={WorkflowVariablePicker}
|
||||
readonly={readonly}
|
||||
/>
|
||||
)
|
||||
) : (
|
||||
<FormTextFieldInput
|
||||
defaultValue={stepFilter.value}
|
||||
onChange={onChange}
|
||||
VariablePicker={WorkflowVariablePicker}
|
||||
readonly={readonly}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
+48
-38
@@ -3,17 +3,13 @@ import { configurableViewFilterOperands } from '@/object-record/object-filter-dr
|
||||
import { FormFieldInput } from '@/object-record/record-field/components/FormFieldInput';
|
||||
import { FormTextFieldInput } from '@/object-record/record-field/form-types/components/FormTextFieldInput';
|
||||
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
||||
import { useWorkflowStepContextOrThrow } from '@/workflow/states/context/WorkflowStepContext';
|
||||
import { stepsOutputSchemaFamilySelector } from '@/workflow/states/selectors/stepsOutputSchemaFamilySelector';
|
||||
import { WorkflowStepFilterValueCompositeInput } from '@/workflow/workflow-steps/workflow-actions/filter-action/components/WorkflowStepFilterValueCompositeInput';
|
||||
import { useUpsertStepFilterSettings } from '@/workflow/workflow-steps/workflow-actions/filter-action/hooks/useUpsertStepFilterSettings';
|
||||
import { WorkflowStepFilterContext } from '@/workflow/workflow-steps/workflow-actions/filter-action/states/context/WorkflowStepFilterContext';
|
||||
import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components/WorkflowVariablePicker';
|
||||
import { extractRawVariableNamePart } from '@/workflow/workflow-variables/utils/extractRawVariableNamePart';
|
||||
import { searchVariableThroughOutputSchema } from '@/workflow/workflow-variables/utils/searchVariableThroughOutputSchema';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { isObject, isString } from '@sniptt/guards';
|
||||
import { useContext } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { FieldMetadataType, StepFilter } from 'twenty-shared/src/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { JsonValue } from 'type-fest';
|
||||
@@ -22,6 +18,14 @@ type WorkflowStepFilterValueInputProps = {
|
||||
stepFilter: StepFilter;
|
||||
};
|
||||
|
||||
const COMPOSITE_FIELD_METADATA_TYPES = [
|
||||
FieldMetadataType.ADDRESS,
|
||||
FieldMetadataType.PHONES,
|
||||
FieldMetadataType.EMAILS,
|
||||
FieldMetadataType.LINKS,
|
||||
FieldMetadataType.CURRENCY,
|
||||
];
|
||||
|
||||
const isFilterableFieldMetadataType = (
|
||||
type: string,
|
||||
): type is FieldMetadataType => {
|
||||
@@ -37,6 +41,8 @@ const isFilterableFieldMetadataType = (
|
||||
FieldMetadataType.RAW_JSON,
|
||||
FieldMetadataType.RICH_TEXT_V2,
|
||||
FieldMetadataType.ARRAY,
|
||||
FieldMetadataType.UUID,
|
||||
...COMPOSITE_FIELD_METADATA_TYPES,
|
||||
].includes(type as FieldMetadataType);
|
||||
};
|
||||
|
||||
@@ -47,24 +53,6 @@ export const WorkflowStepFilterValueInput = ({
|
||||
const { readonly } = useContext(WorkflowStepFilterContext);
|
||||
|
||||
const { upsertStepFilterSettings } = useUpsertStepFilterSettings();
|
||||
const { workflowVersionId } = useWorkflowStepContextOrThrow();
|
||||
|
||||
const stepId = extractRawVariableNamePart({
|
||||
rawVariableName: stepFilter.stepOutputKey,
|
||||
part: 'stepId',
|
||||
});
|
||||
|
||||
const stepsOutputSchema = useRecoilValue(
|
||||
stepsOutputSchemaFamilySelector({
|
||||
workflowVersionId,
|
||||
stepIds: [stepId],
|
||||
}),
|
||||
);
|
||||
const { variableType, fieldMetadataId } = searchVariableThroughOutputSchema({
|
||||
stepOutputSchema: stepsOutputSchema?.[0],
|
||||
rawVariableName: stepFilter.stepOutputKey,
|
||||
isFullRecord: false,
|
||||
});
|
||||
|
||||
const handleValueChange = (value: JsonValue) => {
|
||||
const valueToUpsert = isString(value)
|
||||
@@ -92,23 +80,23 @@ export const WorkflowStepFilterValueInput = ({
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isDefined(variableType) && isFilterableFieldMetadataType(variableType)) {
|
||||
const selectedFieldMetadataItem = isDefined(fieldMetadataId)
|
||||
? getFieldMetadataItemById(fieldMetadataId)
|
||||
: undefined;
|
||||
const {
|
||||
fieldMetadataId,
|
||||
type: variableType,
|
||||
compositeFieldSubFieldName,
|
||||
} = stepFilter;
|
||||
|
||||
const field = {
|
||||
type: variableType as FieldMetadataType,
|
||||
label: '',
|
||||
metadata: {
|
||||
fieldName: selectedFieldMetadataItem?.name ?? '',
|
||||
options: selectedFieldMetadataItem?.options ?? [],
|
||||
} as FieldMetadata,
|
||||
};
|
||||
const selectedFieldMetadataItem = isDefined(fieldMetadataId)
|
||||
? getFieldMetadataItemById(fieldMetadataId)
|
||||
: undefined;
|
||||
|
||||
if (
|
||||
!isDefined(variableType) ||
|
||||
!isFilterableFieldMetadataType(variableType) ||
|
||||
!isDefined(selectedFieldMetadataItem)
|
||||
) {
|
||||
return (
|
||||
<FormFieldInput
|
||||
field={field}
|
||||
<FormTextFieldInput
|
||||
defaultValue={stepFilter.value}
|
||||
onChange={handleValueChange}
|
||||
readonly={readonly}
|
||||
@@ -118,8 +106,30 @@ export const WorkflowStepFilterValueInput = ({
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
isDefined(compositeFieldSubFieldName) &&
|
||||
COMPOSITE_FIELD_METADATA_TYPES.includes(variableType as FieldMetadataType)
|
||||
) {
|
||||
return (
|
||||
<WorkflowStepFilterValueCompositeInput
|
||||
stepFilter={stepFilter}
|
||||
onChange={handleValueChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const field = {
|
||||
type: variableType as FieldMetadataType,
|
||||
label: '',
|
||||
metadata: {
|
||||
fieldName: selectedFieldMetadataItem?.name ?? '',
|
||||
options: selectedFieldMetadataItem?.options ?? [],
|
||||
} as FieldMetadata,
|
||||
};
|
||||
|
||||
return (
|
||||
<FormTextFieldInput
|
||||
<FormFieldInput
|
||||
field={field}
|
||||
defaultValue={stepFilter.value}
|
||||
onChange={handleValueChange}
|
||||
readonly={readonly}
|
||||
|
||||
Reference in New Issue
Block a user