Allow to select full object and object id in filters (#14083)
Today WorkflowVariablesDropdownAllItems is used for variable picker in all workflow steps, and for step field picker in filters. Using that component in filters prevent us from knowing if a full record or only the id has been selected. This PR: - creates a new component WorkflowDropdownStepOutputItems, mostly copying the logic of WorkflowVariablesDropdownAllItems - call it WorkflowStepFilterFieldSelect, removing the display logic from that parent component - store isFullRecord in filter. So we now know if we should display a record picker or a uuid picker Before - selecting id makes picker behaves like when we select an object https://github.com/user-attachments/assets/bde34dc5-8011-4983-8d0f-d8cb0cb3c045 After - selecting object and id are two different things https://github.com/user-attachments/assets/49289990-3e6d-4ad7-abc1-e3ade2a821bb
This commit is contained in:
+238
@@ -0,0 +1,238 @@
|
||||
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader/DropdownMenuHeader';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
|
||||
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
||||
import { type StepOutputSchema } from '@/workflow/workflow-variables/types/StepOutputSchema';
|
||||
|
||||
import { useGetFieldMetadataItemByIdOrThrow } from '@/object-metadata/hooks/useGetFieldMetadataItemById';
|
||||
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
||||
import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent';
|
||||
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
|
||||
import { useWorkflowVersionIdOrThrow } from '@/workflow/hooks/useWorkflowVersionIdOrThrow';
|
||||
import { stepsOutputSchemaFamilySelector } from '@/workflow/states/selectors/stepsOutputSchemaFamilySelector';
|
||||
import { useUpsertStepFilterSettings } from '@/workflow/workflow-steps/workflow-actions/filter-action/hooks/useUpsertStepFilterSettings';
|
||||
import { getStepFilterOperands } from '@/workflow/workflow-steps/workflow-actions/filter-action/utils/getStepFilterOperands';
|
||||
import { useVariableDropdown } from '@/workflow/workflow-variables/hooks/useVariableDropdown';
|
||||
import { extractRawVariableNamePart } from '@/workflow/workflow-variables/utils/extractRawVariableNamePart';
|
||||
import { getCurrentSubStepFromPath } from '@/workflow/workflow-variables/utils/getCurrentSubStepFromPath';
|
||||
import { getStepHeaderLabel } from '@/workflow/workflow-variables/utils/getStepHeaderLabel';
|
||||
import { getVariableTemplateFromPath } from '@/workflow/workflow-variables/utils/getVariableTemplateFromPath';
|
||||
import { isRecordOutputSchema } from '@/workflow/workflow-variables/utils/isRecordOutputSchema';
|
||||
import { searchVariableThroughOutputSchema } from '@/workflow/workflow-variables/utils/searchVariableThroughOutputSchema';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { type StepFilter } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import {
|
||||
IconChevronLeft,
|
||||
OverflowingTextWithTooltip,
|
||||
useIcons,
|
||||
} from 'twenty-ui/display';
|
||||
import { MenuItemSelect } from 'twenty-ui/navigation';
|
||||
|
||||
type WorkflowDropdownStepOutputItemsProps = {
|
||||
stepFilter: StepFilter;
|
||||
step: StepOutputSchema;
|
||||
onSelect: () => void;
|
||||
onBack: () => void;
|
||||
};
|
||||
|
||||
export const WorkflowDropdownStepOutputItems = ({
|
||||
stepFilter,
|
||||
step,
|
||||
onSelect,
|
||||
onBack,
|
||||
}: WorkflowDropdownStepOutputItemsProps) => {
|
||||
const { t } = useLingui();
|
||||
const { getIcon } = useIcons();
|
||||
|
||||
const { upsertStepFilterSettings } = useUpsertStepFilterSettings();
|
||||
const { getFieldMetadataItemByIdOrThrow } =
|
||||
useGetFieldMetadataItemByIdOrThrow();
|
||||
|
||||
const workflowVersionId = useWorkflowVersionIdOrThrow();
|
||||
|
||||
const updateStepFilter = useRecoilCallback(
|
||||
({ snapshot }) =>
|
||||
({
|
||||
rawVariableName,
|
||||
isFullRecord,
|
||||
}: {
|
||||
rawVariableName: string;
|
||||
isFullRecord: boolean;
|
||||
}) => {
|
||||
const stepId = extractRawVariableNamePart({
|
||||
rawVariableName,
|
||||
part: 'stepId',
|
||||
});
|
||||
const [currentStepOutputSchema] = snapshot
|
||||
.getLoadable(
|
||||
stepsOutputSchemaFamilySelector({
|
||||
workflowVersionId,
|
||||
stepIds: [stepId],
|
||||
}),
|
||||
)
|
||||
.getValue();
|
||||
|
||||
const { variableType, fieldMetadataId, compositeFieldSubFieldName } =
|
||||
searchVariableThroughOutputSchema({
|
||||
stepOutputSchema: currentStepOutputSchema,
|
||||
rawVariableName,
|
||||
isFullRecord: false,
|
||||
});
|
||||
|
||||
const { fieldMetadataItem: filterFieldMetadataItem } = isDefined(
|
||||
fieldMetadataId,
|
||||
)
|
||||
? getFieldMetadataItemByIdOrThrow(fieldMetadataId)
|
||||
: { fieldMetadataItem: undefined };
|
||||
|
||||
const filterType = isDefined(fieldMetadataId)
|
||||
? (filterFieldMetadataItem?.type ?? 'unknown')
|
||||
: variableType;
|
||||
|
||||
const availableOperandsForFilter = getStepFilterOperands({
|
||||
filterType,
|
||||
subFieldName: compositeFieldSubFieldName,
|
||||
});
|
||||
const defaultOperand = availableOperandsForFilter[0];
|
||||
|
||||
upsertStepFilterSettings({
|
||||
stepFilterToUpsert: {
|
||||
...stepFilter,
|
||||
stepOutputKey: rawVariableName,
|
||||
isFullRecord,
|
||||
type: filterType ?? 'unknown',
|
||||
value: '',
|
||||
fieldMetadataId,
|
||||
compositeFieldSubFieldName,
|
||||
operand: defaultOperand,
|
||||
},
|
||||
});
|
||||
},
|
||||
[
|
||||
workflowVersionId,
|
||||
getFieldMetadataItemByIdOrThrow,
|
||||
upsertStepFilterSettings,
|
||||
stepFilter,
|
||||
],
|
||||
);
|
||||
|
||||
const handleStepFilterFieldSelect = (key: string) => {
|
||||
updateStepFilter({
|
||||
rawVariableName: key,
|
||||
isFullRecord: false,
|
||||
});
|
||||
onSelect();
|
||||
};
|
||||
|
||||
const {
|
||||
searchInputValue,
|
||||
setSearchInputValue,
|
||||
handleSelectField,
|
||||
goBack,
|
||||
filteredOptions,
|
||||
currentPath,
|
||||
} = useVariableDropdown({
|
||||
step,
|
||||
onSelect: handleStepFilterFieldSelect,
|
||||
onBack,
|
||||
});
|
||||
|
||||
const getDisplayedSubStepObject = () => {
|
||||
const currentSubStep = getCurrentSubStepFromPath(step, currentPath);
|
||||
|
||||
if (!isRecordOutputSchema(currentSubStep)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return currentSubStep.object;
|
||||
};
|
||||
|
||||
const handleSelectObject = () => {
|
||||
const currentSubStep = getCurrentSubStepFromPath(step, currentPath);
|
||||
|
||||
if (!isRecordOutputSchema(currentSubStep)) {
|
||||
return;
|
||||
}
|
||||
|
||||
updateStepFilter({
|
||||
rawVariableName: getVariableTemplateFromPath({
|
||||
stepId: step.id,
|
||||
path: [...currentPath, currentSubStep.object.fieldIdName],
|
||||
}),
|
||||
isFullRecord: true,
|
||||
});
|
||||
onSelect();
|
||||
};
|
||||
|
||||
const displayedSubStepObject = getDisplayedSubStepObject();
|
||||
|
||||
const shouldDisplaySubStepObject = searchInputValue
|
||||
? displayedSubStepObject?.label &&
|
||||
displayedSubStepObject.label
|
||||
.toLowerCase()
|
||||
.includes(searchInputValue.toLowerCase())
|
||||
: true;
|
||||
|
||||
const shouldDisplayObject =
|
||||
shouldDisplaySubStepObject && displayedSubStepObject?.label;
|
||||
const nameSingular = displayedSubStepObject?.nameSingular;
|
||||
|
||||
return (
|
||||
<DropdownContent widthInPixels={GenericDropdownContentWidth.ExtraLarge}>
|
||||
<DropdownMenuHeader
|
||||
StartComponent={
|
||||
<DropdownMenuHeaderLeftComponent
|
||||
onClick={goBack}
|
||||
Icon={IconChevronLeft}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<OverflowingTextWithTooltip
|
||||
text={getStepHeaderLabel(step, currentPath)}
|
||||
/>
|
||||
</DropdownMenuHeader>
|
||||
<DropdownMenuSearchInput
|
||||
autoFocus
|
||||
value={searchInputValue}
|
||||
onChange={(event) => setSearchInputValue(event.target.value)}
|
||||
/>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItemsContainer hasMaxHeight>
|
||||
{shouldDisplayObject && (
|
||||
<MenuItemSelect
|
||||
selected={false}
|
||||
focused={false}
|
||||
onClick={handleSelectObject}
|
||||
text={displayedSubStepObject?.label || ''}
|
||||
hasSubMenu={false}
|
||||
LeftIcon={
|
||||
displayedSubStepObject.icon
|
||||
? getIcon(displayedSubStepObject.icon)
|
||||
: undefined
|
||||
}
|
||||
contextualText={t`Pick a ${nameSingular} record`}
|
||||
/>
|
||||
)}
|
||||
{filteredOptions.length > 0 && shouldDisplayObject && (
|
||||
<DropdownMenuSeparator />
|
||||
)}
|
||||
{filteredOptions.map(([key, subStep]) => (
|
||||
<MenuItemSelect
|
||||
key={key}
|
||||
selected={false}
|
||||
focused={false}
|
||||
onClick={() => handleSelectField(key)}
|
||||
text={subStep.label || key}
|
||||
hasSubMenu={!subStep.isLeaf}
|
||||
LeftIcon={subStep.icon ? getIcon(subStep.icon) : undefined}
|
||||
contextualText={
|
||||
subStep.isLeaf ? subStep?.value?.toString() : undefined
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</DropdownMenuItemsContainer>
|
||||
</DropdownContent>
|
||||
);
|
||||
};
|
||||
-1
@@ -137,7 +137,6 @@ export const WorkflowStepFilterAddFilterRuleSelect = ({
|
||||
</DropdownMenuItemsContainer>
|
||||
</DropdownContent>
|
||||
}
|
||||
dropdownOffset={{ y: 8, x: 0 }}
|
||||
dropdownPlacement="bottom-start"
|
||||
/>
|
||||
);
|
||||
|
||||
+85
-152
@@ -1,19 +1,18 @@
|
||||
import { useFieldMetadataItemById } from '@/object-metadata/hooks/useFieldMetadataItemById';
|
||||
import { useGetFieldMetadataItemByIdOrThrow } from '@/object-metadata/hooks/useGetFieldMetadataItemById';
|
||||
import { SelectControl } from '@/ui/input/components/SelectControl';
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { useWorkflowVersionIdOrThrow } from '@/workflow/hooks/useWorkflowVersionIdOrThrow';
|
||||
import { stepsOutputSchemaFamilySelector } from '@/workflow/states/selectors/stepsOutputSchemaFamilySelector';
|
||||
import { useUpsertStepFilterSettings } from '@/workflow/workflow-steps/workflow-actions/filter-action/hooks/useUpsertStepFilterSettings';
|
||||
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||
import { WorkflowDropdownStepOutputItems } from '@/workflow/workflow-steps/workflow-actions/filter-action/components/WorkflowDropdownStepOutputItems';
|
||||
import { WorkflowStepFilterContext } from '@/workflow/workflow-steps/workflow-actions/filter-action/states/context/WorkflowStepFilterContext';
|
||||
import { getViewFilterOperands } from '@/workflow/workflow-steps/workflow-actions/filter-action/utils/getStepFilterOperands';
|
||||
import { WorkflowVariablesDropdown } from '@/workflow/workflow-variables/components/WorkflowVariablesDropdown';
|
||||
import { WorkflowVariablesDropdownWorkflowStepItems } from '@/workflow/workflow-variables/components/WorkflowVariablesDropdownWorkflowStepItems';
|
||||
import { useAvailableVariablesInWorkflowStep } from '@/workflow/workflow-variables/hooks/useAvailableVariablesInWorkflowStep';
|
||||
import { useSearchVariable } from '@/workflow/workflow-variables/hooks/useSearchVariable';
|
||||
|
||||
import { type StepOutputSchema } from '@/workflow/workflow-variables/types/StepOutputSchema';
|
||||
import { extractRawVariableNamePart } from '@/workflow/workflow-variables/utils/extractRawVariableNamePart';
|
||||
import { searchVariableThroughOutputSchema } from '@/workflow/workflow-variables/utils/searchVariableThroughOutputSchema';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useContext } from 'react';
|
||||
import { useRecoilCallback, useRecoilValue } from 'recoil';
|
||||
import { useContext, useState } from 'react';
|
||||
import { type StepFilter } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
@@ -34,139 +33,76 @@ export const WorkflowStepFilterFieldSelect = ({
|
||||
stepFilter,
|
||||
}: WorkflowStepFilterFieldSelectProps) => {
|
||||
const { readonly } = useContext(WorkflowStepFilterContext);
|
||||
const shouldDisplayRecordFields = true;
|
||||
const shouldDisplayRecordObjects = true;
|
||||
|
||||
const { upsertStepFilterSettings } = useUpsertStepFilterSettings();
|
||||
|
||||
const { t } = useLingui();
|
||||
const workflowVersionId = useWorkflowVersionIdOrThrow();
|
||||
const theme = useTheme();
|
||||
const { closeDropdown } = useCloseDropdown();
|
||||
const { getIcon } = useIcons();
|
||||
|
||||
const availableVariablesInWorkflowStep = useAvailableVariablesInWorkflowStep({
|
||||
shouldDisplayRecordFields: true,
|
||||
shouldDisplayRecordObjects: true,
|
||||
fieldTypesToExclude: NON_SELECTABLE_FIELD_TYPES,
|
||||
});
|
||||
const noAvailableVariables = availableVariablesInWorkflowStep.length === 0;
|
||||
|
||||
const initialStep =
|
||||
availableVariablesInWorkflowStep.length === 1
|
||||
? availableVariablesInWorkflowStep[0]
|
||||
: undefined;
|
||||
|
||||
const [selectedStep, setSelectedStep] = useState<
|
||||
StepOutputSchema | undefined
|
||||
>(initialStep);
|
||||
|
||||
const stepId = extractRawVariableNamePart({
|
||||
rawVariableName: stepFilter.stepOutputKey,
|
||||
part: 'stepId',
|
||||
});
|
||||
|
||||
const stepsOutputSchema = useRecoilValue(
|
||||
stepsOutputSchemaFamilySelector({
|
||||
workflowVersionId,
|
||||
stepIds: [stepId],
|
||||
}),
|
||||
);
|
||||
|
||||
const { getIcon } = useIcons();
|
||||
const { variableLabel } = useSearchVariable({
|
||||
stepId,
|
||||
rawVariableName: stepFilter.stepOutputKey,
|
||||
isFullRecord: stepFilter.isFullRecord ?? false,
|
||||
});
|
||||
|
||||
const {
|
||||
fieldMetadataItem: filterFieldMetadataItem,
|
||||
objectMetadataItem: filterObjectMetadataItem,
|
||||
} = useFieldMetadataItemById(stepFilter.fieldMetadataId ?? '');
|
||||
|
||||
const { getFieldMetadataItemByIdOrThrow } =
|
||||
useGetFieldMetadataItemByIdOrThrow();
|
||||
const dropdownId = `step-filter-field-${stepFilter.id}`;
|
||||
|
||||
const availableVariablesInWorkflowStep = useAvailableVariablesInWorkflowStep({
|
||||
shouldDisplayRecordFields,
|
||||
shouldDisplayRecordObjects,
|
||||
});
|
||||
const handleStepSelect = (stepId: string) => {
|
||||
setSelectedStep(
|
||||
availableVariablesInWorkflowStep.find((step) => step.id === stepId),
|
||||
);
|
||||
};
|
||||
|
||||
const noAvailableVariables = availableVariablesInWorkflowStep.length === 0;
|
||||
const handleSubItemSelect = () => {
|
||||
setSelectedStep(initialStep);
|
||||
closeDropdown(dropdownId);
|
||||
};
|
||||
|
||||
const handleChange = useRecoilCallback(
|
||||
({ snapshot }) =>
|
||||
(variableName: string) => {
|
||||
const stepId = extractRawVariableNamePart({
|
||||
rawVariableName: variableName,
|
||||
part: 'stepId',
|
||||
});
|
||||
const [currentStepOutputSchema] = snapshot
|
||||
.getLoadable(
|
||||
stepsOutputSchemaFamilySelector({
|
||||
workflowVersionId,
|
||||
stepIds: [stepId],
|
||||
}),
|
||||
)
|
||||
.getValue();
|
||||
|
||||
const {
|
||||
variableLabel,
|
||||
variableType,
|
||||
fieldMetadataId,
|
||||
compositeFieldSubFieldName,
|
||||
} = searchVariableThroughOutputSchema({
|
||||
stepOutputSchema: currentStepOutputSchema,
|
||||
rawVariableName: variableName,
|
||||
isFullRecord: false,
|
||||
});
|
||||
|
||||
const {
|
||||
fieldMetadataItem: filterFieldMetadataItem,
|
||||
objectMetadataItem: filterObjectMetadataItem,
|
||||
} = isDefined(fieldMetadataId)
|
||||
? getFieldMetadataItemByIdOrThrow(fieldMetadataId)
|
||||
: { fieldMetadataItem: undefined, objectMetadataItem: undefined };
|
||||
|
||||
const filterType = isDefined(fieldMetadataId)
|
||||
? (filterFieldMetadataItem?.type ?? 'unknown')
|
||||
: variableType;
|
||||
|
||||
const isFullRecord =
|
||||
filterFieldMetadataItem?.name === 'id' &&
|
||||
isDefined(filterObjectMetadataItem?.labelSingular);
|
||||
|
||||
upsertStepFilterSettings({
|
||||
stepFilterToUpsert: {
|
||||
...stepFilter,
|
||||
stepOutputKey: variableName,
|
||||
displayValue: isFullRecord
|
||||
? filterObjectMetadataItem.labelSingular
|
||||
: (variableLabel ?? ''),
|
||||
type: filterType ?? 'unknown',
|
||||
value: '',
|
||||
fieldMetadataId,
|
||||
compositeFieldSubFieldName,
|
||||
operand: getViewFilterOperands({
|
||||
filterType,
|
||||
subFieldName: compositeFieldSubFieldName,
|
||||
})?.[0],
|
||||
},
|
||||
});
|
||||
},
|
||||
[
|
||||
workflowVersionId,
|
||||
getFieldMetadataItemByIdOrThrow,
|
||||
upsertStepFilterSettings,
|
||||
stepFilter,
|
||||
],
|
||||
);
|
||||
|
||||
if (!isDefined(stepId)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const isFullRecord =
|
||||
filterFieldMetadataItem?.name === 'id' &&
|
||||
isDefined(filterObjectMetadataItem?.labelSingular);
|
||||
|
||||
const { variableLabel } = searchVariableThroughOutputSchema({
|
||||
stepOutputSchema: stepsOutputSchema?.[0],
|
||||
rawVariableName: stepFilter.stepOutputKey,
|
||||
isFullRecord,
|
||||
});
|
||||
const handleBack = () => {
|
||||
setSelectedStep(undefined);
|
||||
};
|
||||
|
||||
const isSelectedFieldNotFound = !isDefined(variableLabel);
|
||||
const label = isSelectedFieldNotFound
|
||||
? t`Select a field from a previous step`
|
||||
: variableLabel;
|
||||
|
||||
const icon = isFullRecord
|
||||
const icon = stepFilter.isFullRecord
|
||||
? getIcon(filterObjectMetadataItem?.icon)
|
||||
: filterFieldMetadataItem?.icon
|
||||
? getIcon(filterFieldMetadataItem.icon)
|
||||
: undefined;
|
||||
|
||||
const dropdownId = `step-filter-field-${stepFilter.id}`;
|
||||
if (readonly || noAvailableVariables) {
|
||||
const disabledLabel = noAvailableVariables
|
||||
? t`No available fields to select`
|
||||
: label;
|
||||
|
||||
if (noAvailableVariables) {
|
||||
return (
|
||||
<Dropdown
|
||||
dropdownId={dropdownId}
|
||||
@@ -174,25 +110,7 @@ export const WorkflowStepFilterFieldSelect = ({
|
||||
<SelectControl
|
||||
selectedOption={{
|
||||
value: stepFilter.stepOutputKey,
|
||||
label: t`No available fields to select`,
|
||||
}}
|
||||
isDisabled={true}
|
||||
/>
|
||||
}
|
||||
dropdownComponents={[]}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (readonly === true) {
|
||||
return (
|
||||
<Dropdown
|
||||
dropdownId={dropdownId}
|
||||
clickableComponent={
|
||||
<SelectControl
|
||||
selectedOption={{
|
||||
value: stepFilter.stepOutputKey,
|
||||
label,
|
||||
label: disabledLabel,
|
||||
Icon: icon,
|
||||
}}
|
||||
isDisabled={true}
|
||||
@@ -204,25 +122,40 @@ export const WorkflowStepFilterFieldSelect = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<WorkflowVariablesDropdown
|
||||
instanceId={dropdownId}
|
||||
onVariableSelect={handleChange}
|
||||
clickableComponent={
|
||||
<SelectControl
|
||||
selectedOption={{
|
||||
label,
|
||||
value: stepFilter.stepOutputKey,
|
||||
Icon: icon,
|
||||
}}
|
||||
textAccent={isSelectedFieldNotFound ? 'placeholder' : 'default'}
|
||||
<Dropdown
|
||||
dropdownId={dropdownId}
|
||||
clickableComponent={
|
||||
<SelectControl
|
||||
selectedOption={{
|
||||
label,
|
||||
value: stepFilter.stepOutputKey,
|
||||
Icon: icon,
|
||||
}}
|
||||
textAccent={isSelectedFieldNotFound ? 'placeholder' : 'default'}
|
||||
isDisabled={readonly}
|
||||
/>
|
||||
}
|
||||
dropdownComponents={
|
||||
!isDefined(selectedStep) ? (
|
||||
<WorkflowVariablesDropdownWorkflowStepItems
|
||||
dropdownId={dropdownId}
|
||||
steps={availableVariablesInWorkflowStep}
|
||||
onSelect={handleStepSelect}
|
||||
/>
|
||||
}
|
||||
shouldDisplayRecordFields={shouldDisplayRecordFields}
|
||||
shouldDisplayRecordObjects={shouldDisplayRecordObjects}
|
||||
shouldEnableSelectRelationObject={true}
|
||||
fieldTypesToExclude={NON_SELECTABLE_FIELD_TYPES}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<WorkflowDropdownStepOutputItems
|
||||
stepFilter={stepFilter}
|
||||
step={selectedStep}
|
||||
onSelect={handleSubItemSelect}
|
||||
onBack={handleBack}
|
||||
/>
|
||||
)
|
||||
}
|
||||
dropdownPlacement="bottom-end"
|
||||
dropdownOffset={{
|
||||
x: parseInt(theme.spacing(0.5), 10),
|
||||
y: parseInt(theme.spacing(1), 10),
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
+2
-2
@@ -4,7 +4,7 @@ import { Select } from '@/ui/input/components/Select';
|
||||
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
|
||||
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 { getViewFilterOperands } from '@/workflow/workflow-steps/workflow-actions/filter-action/utils/getStepFilterOperands';
|
||||
import { getStepFilterOperands } from '@/workflow/workflow-steps/workflow-actions/filter-action/utils/getStepFilterOperands';
|
||||
import { useContext } from 'react';
|
||||
import { type StepFilter, type ViewFilterOperand } from 'twenty-shared/types';
|
||||
|
||||
@@ -18,7 +18,7 @@ export const WorkflowStepFilterOperandSelect = ({
|
||||
const { readonly } = useContext(WorkflowStepFilterContext);
|
||||
|
||||
const { upsertStepFilterSettings } = useUpsertStepFilterSettings();
|
||||
const operands = getViewFilterOperands({
|
||||
const operands = getStepFilterOperands({
|
||||
filterType: stepFilter.type,
|
||||
subFieldName: stepFilter.compositeFieldSubFieldName,
|
||||
});
|
||||
|
||||
+2
-1
@@ -102,7 +102,8 @@ export const WorkflowStepFilterValueInput = ({
|
||||
variableType === FieldMetadataType.SELECT;
|
||||
|
||||
const isFullRecord =
|
||||
selectedFieldMetadataItem?.name === 'id' &&
|
||||
isDefined(stepFilter.isFullRecord) &&
|
||||
stepFilter.isFullRecord &&
|
||||
isDefined(objectMetadataItem?.nameSingular);
|
||||
|
||||
const isDateField =
|
||||
|
||||
-2
@@ -24,9 +24,7 @@ const TEXT_STEP_FILTER: StepFilter = {
|
||||
id: 'filter-1',
|
||||
stepFilterGroupId: 'filter-group-1',
|
||||
stepOutputKey: 'company.name',
|
||||
displayValue: 'Company Name',
|
||||
type: 'text',
|
||||
label: 'Company Name',
|
||||
value: 'Acme',
|
||||
operand: ViewFilterOperand.Contains,
|
||||
};
|
||||
|
||||
-2
@@ -13,9 +13,7 @@ const DEFAULT_STEP_FILTER: StepFilter = {
|
||||
id: 'filter-1',
|
||||
stepFilterGroupId: 'filter-group-1',
|
||||
stepOutputKey: '',
|
||||
displayValue: '',
|
||||
type: 'text',
|
||||
label: 'New Filter',
|
||||
operand: ViewFilterOperand.Is,
|
||||
value: '',
|
||||
positionInStepFilterGroup: 0,
|
||||
|
||||
-4
@@ -14,9 +14,7 @@ const DEFAULT_STEP_FILTER: StepFilter = {
|
||||
id: 'filter-1',
|
||||
stepFilterGroupId: 'filter-group-1',
|
||||
stepOutputKey: 'company.name',
|
||||
displayValue: 'Company Name',
|
||||
type: 'text',
|
||||
label: 'Company Name',
|
||||
operand: ViewFilterOperand.Contains,
|
||||
value: '',
|
||||
positionInStepFilterGroup: 0,
|
||||
@@ -26,9 +24,7 @@ const GREATER_THAN_FILTER: StepFilter = {
|
||||
id: 'filter-1',
|
||||
stepFilterGroupId: 'filter-group-1',
|
||||
stepOutputKey: 'company.employees',
|
||||
displayValue: 'Employee Count',
|
||||
type: 'number',
|
||||
label: 'Employee Count',
|
||||
operand: ViewFilterOperand.GreaterThanOrEqual,
|
||||
value: '100',
|
||||
positionInStepFilterGroup: 0,
|
||||
|
||||
-4
@@ -14,9 +14,7 @@ const TEXT_FILTER: StepFilter = {
|
||||
id: 'filter-1',
|
||||
stepFilterGroupId: 'filter-group-1',
|
||||
stepOutputKey: 'company.name',
|
||||
displayValue: 'Company Name',
|
||||
type: 'text',
|
||||
label: 'Company Name',
|
||||
operand: ViewFilterOperand.Contains,
|
||||
value: 'Acme',
|
||||
positionInStepFilterGroup: 0,
|
||||
@@ -26,9 +24,7 @@ const NUMBER_FILTER: StepFilter = {
|
||||
id: 'filter-2',
|
||||
stepFilterGroupId: 'filter-group-1',
|
||||
stepOutputKey: 'company.employees',
|
||||
displayValue: 'Employee Count',
|
||||
type: 'number',
|
||||
label: 'Employee Count',
|
||||
operand: ViewFilterOperand.GreaterThanOrEqual,
|
||||
value: '100',
|
||||
positionInStepFilterGroup: 0,
|
||||
|
||||
-2
@@ -49,10 +49,8 @@ export const useAddRootStepFilter = () => {
|
||||
const newStepFilter: StepFilter = {
|
||||
id: v4(),
|
||||
type: 'unknown',
|
||||
label: 'New Filter',
|
||||
value: '',
|
||||
operand: ViewFilterOperand.Is,
|
||||
displayValue: '',
|
||||
stepFilterGroupId: newStepFilterGroup.id,
|
||||
stepOutputKey: '',
|
||||
positionInStepFilterGroup: 0,
|
||||
|
||||
+1
-1
@@ -85,7 +85,7 @@ export const COMPOSITE_FIELD_FILTER_OPERANDS_MAP = {
|
||||
},
|
||||
};
|
||||
|
||||
export const getViewFilterOperands = ({
|
||||
export const getStepFilterOperands = ({
|
||||
filterType,
|
||||
subFieldName,
|
||||
}: {
|
||||
|
||||
-3
@@ -39,7 +39,6 @@ export const WorkflowVariablesDropdown = ({
|
||||
shouldDisplayRecordFields,
|
||||
shouldDisplayRecordObjects,
|
||||
fieldTypesToExclude,
|
||||
shouldEnableSelectRelationObject,
|
||||
multiline,
|
||||
clickableComponent,
|
||||
}: {
|
||||
@@ -48,7 +47,6 @@ export const WorkflowVariablesDropdown = ({
|
||||
shouldDisplayRecordFields: boolean;
|
||||
shouldDisplayRecordObjects: boolean;
|
||||
fieldTypesToExclude?: InputSchemaPropertyType[];
|
||||
shouldEnableSelectRelationObject?: boolean;
|
||||
disabled?: boolean;
|
||||
multiline?: boolean;
|
||||
clickableComponent?: React.ReactNode;
|
||||
@@ -134,7 +132,6 @@ export const WorkflowVariablesDropdown = ({
|
||||
step={selectedStep}
|
||||
onSelect={handleSubItemSelect}
|
||||
onBack={handleBack}
|
||||
shouldEnableSelectRelationObject={shouldEnableSelectRelationObject}
|
||||
/>
|
||||
) : (
|
||||
<WorkflowVariablesDropdownFieldItems
|
||||
|
||||
+6
-21
@@ -24,14 +24,12 @@ type WorkflowVariablesDropdownAllItemsProps = {
|
||||
step: StepOutputSchema;
|
||||
onSelect: (value: string) => void;
|
||||
onBack: () => void;
|
||||
shouldEnableSelectRelationObject?: boolean;
|
||||
};
|
||||
|
||||
export const WorkflowVariablesDropdownAllItems = ({
|
||||
step,
|
||||
onSelect,
|
||||
onBack,
|
||||
shouldEnableSelectRelationObject,
|
||||
}: WorkflowVariablesDropdownAllItemsProps) => {
|
||||
const { t } = useLingui();
|
||||
const { getIcon } = useIcons();
|
||||
@@ -65,25 +63,12 @@ export const WorkflowVariablesDropdownAllItems = ({
|
||||
return;
|
||||
}
|
||||
|
||||
const isRelationField = currentSubStep.object.isRelationField ?? false;
|
||||
const isRelationObjectSelectable =
|
||||
shouldEnableSelectRelationObject ?? false;
|
||||
|
||||
if (isRelationField && isRelationObjectSelectable) {
|
||||
onSelect(
|
||||
getVariableTemplateFromPath({
|
||||
stepId: step.id,
|
||||
path: currentPath,
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
onSelect(
|
||||
getVariableTemplateFromPath({
|
||||
stepId: step.id,
|
||||
path: [...currentPath, currentSubStep.object.fieldIdName],
|
||||
}),
|
||||
);
|
||||
}
|
||||
onSelect(
|
||||
getVariableTemplateFromPath({
|
||||
stepId: step.id,
|
||||
path: [...currentPath, currentSubStep.object.fieldIdName],
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
const displayedSubStepObject = getDisplayedSubStepObject();
|
||||
|
||||
-2
@@ -37,10 +37,8 @@ export type FieldOutputSchema =
|
||||
|
||||
export type RecordOutputSchema = {
|
||||
object: {
|
||||
nameSingular: string;
|
||||
fieldIdName: string;
|
||||
objectMetadataId: string;
|
||||
isRelationField?: boolean;
|
||||
} & Leaf;
|
||||
fields: Record<string, FieldOutputSchema>;
|
||||
_outputSchemaType: 'RECORD';
|
||||
|
||||
-1
@@ -116,7 +116,6 @@ describe('generateFakeFormResponse', () => {
|
||||
icon: 'test-company-icon',
|
||||
isLeaf: true,
|
||||
label: 'Company',
|
||||
nameSingular: 'company',
|
||||
objectMetadataId: '20202020-c03c-45d6-a4b0-04afe1357c5c',
|
||||
value: 'A company',
|
||||
},
|
||||
|
||||
-4
@@ -61,7 +61,6 @@ describe('generateFakeObjectRecordEvent', () => {
|
||||
icon: 'test-company-icon',
|
||||
label: 'Company',
|
||||
value: 'A company',
|
||||
nameSingular: 'company',
|
||||
fieldIdName: 'properties.after.id',
|
||||
objectMetadataId: '20202020-c03c-45d6-a4b0-04afe1357c5c',
|
||||
},
|
||||
@@ -93,7 +92,6 @@ describe('generateFakeObjectRecordEvent', () => {
|
||||
icon: 'test-company-icon',
|
||||
label: 'Company',
|
||||
value: 'A company',
|
||||
nameSingular: 'company',
|
||||
fieldIdName: 'properties.after.id',
|
||||
objectMetadataId: '20202020-c03c-45d6-a4b0-04afe1357c5c',
|
||||
},
|
||||
@@ -125,7 +123,6 @@ describe('generateFakeObjectRecordEvent', () => {
|
||||
icon: 'test-company-icon',
|
||||
label: 'Company',
|
||||
value: 'A company',
|
||||
nameSingular: 'company',
|
||||
fieldIdName: 'properties.before.id',
|
||||
objectMetadataId: '20202020-c03c-45d6-a4b0-04afe1357c5c',
|
||||
},
|
||||
@@ -157,7 +154,6 @@ describe('generateFakeObjectRecordEvent', () => {
|
||||
icon: 'test-company-icon',
|
||||
label: 'Company',
|
||||
value: 'A company',
|
||||
nameSingular: 'company',
|
||||
fieldIdName: 'properties.before.id',
|
||||
objectMetadataId: '20202020-c03c-45d6-a4b0-04afe1357c5c',
|
||||
},
|
||||
|
||||
-1
@@ -41,7 +41,6 @@ describe('generateFakeObjectRecord', () => {
|
||||
icon: 'test-company-icon',
|
||||
label: 'Company',
|
||||
value: 'A company',
|
||||
nameSingular: 'company',
|
||||
fieldIdName: 'id',
|
||||
objectMetadataId: '20202020-c03c-45d6-a4b0-04afe1357c5c',
|
||||
},
|
||||
|
||||
-2
@@ -30,8 +30,6 @@ const generateFakeObjectRecordEventWithPrefix = ({
|
||||
objectMetadataInfo.objectMetadataItemWithFieldsMaps.icon ?? undefined,
|
||||
label: objectMetadataInfo.objectMetadataItemWithFieldsMaps.labelSingular,
|
||||
value: objectMetadataInfo.objectMetadataItemWithFieldsMaps.description,
|
||||
nameSingular:
|
||||
objectMetadataInfo.objectMetadataItemWithFieldsMaps.nameSingular,
|
||||
fieldIdName: `${prefix}.id`,
|
||||
objectMetadataId: objectMetadataInfo.objectMetadataItemWithFieldsMaps.id,
|
||||
},
|
||||
|
||||
-5
@@ -5,11 +5,9 @@ import { generateObjectRecordFields } from 'src/modules/workflow/workflow-builde
|
||||
export const generateFakeObjectRecord = ({
|
||||
objectMetadataInfo,
|
||||
depth = 0,
|
||||
isRelationField,
|
||||
}: {
|
||||
objectMetadataInfo: ObjectMetadataInfo;
|
||||
depth?: number;
|
||||
isRelationField?: boolean;
|
||||
}): RecordOutputSchema => {
|
||||
return {
|
||||
object: {
|
||||
@@ -18,11 +16,8 @@ export const generateFakeObjectRecord = ({
|
||||
objectMetadataInfo.objectMetadataItemWithFieldsMaps.icon ?? undefined,
|
||||
label: objectMetadataInfo.objectMetadataItemWithFieldsMaps.labelSingular,
|
||||
value: objectMetadataInfo.objectMetadataItemWithFieldsMaps.description,
|
||||
nameSingular:
|
||||
objectMetadataInfo.objectMetadataItemWithFieldsMaps.nameSingular,
|
||||
fieldIdName: 'id',
|
||||
objectMetadataId: objectMetadataInfo.objectMetadataItemWithFieldsMaps.id,
|
||||
isRelationField,
|
||||
},
|
||||
fields: generateObjectRecordFields({
|
||||
objectMetadataInfo,
|
||||
|
||||
-1
@@ -60,7 +60,6 @@ export const generateObjectRecordFields = ({
|
||||
objectMetadataMaps: objectMetadataInfo.objectMetadataMaps,
|
||||
},
|
||||
depth: depth + 1,
|
||||
isRelationField: true,
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
-42
@@ -21,10 +21,8 @@ describe('evaluateFilterConditions', () => {
|
||||
): ResolvedFilter => ({
|
||||
id: 'filter1',
|
||||
type: type,
|
||||
label: 'Test Filter',
|
||||
rightOperand,
|
||||
operand,
|
||||
displayValue: String(rightOperand),
|
||||
stepFilterGroupId: 'group1',
|
||||
leftOperand,
|
||||
});
|
||||
@@ -784,10 +782,8 @@ describe('evaluateFilterConditions', () => {
|
||||
const filter: ResolvedFilter = {
|
||||
id: 'filter1',
|
||||
type: 'CURRENCY',
|
||||
label: 'Currency Filter',
|
||||
rightOperand: 'USD',
|
||||
operand: ViewFilterOperand.Is,
|
||||
displayValue: 'USD',
|
||||
stepFilterGroupId: 'group1',
|
||||
leftOperand: 'USD',
|
||||
compositeFieldSubFieldName: 'currencyCode',
|
||||
@@ -800,10 +796,8 @@ describe('evaluateFilterConditions', () => {
|
||||
const filter: ResolvedFilter = {
|
||||
id: 'filter1',
|
||||
type: 'CURRENCY',
|
||||
label: 'Currency Filter',
|
||||
rightOperand: 100,
|
||||
operand: ViewFilterOperand.GreaterThanOrEqual,
|
||||
displayValue: '100',
|
||||
stepFilterGroupId: 'group1',
|
||||
leftOperand: 150,
|
||||
compositeFieldSubFieldName: 'amountMicros',
|
||||
@@ -1215,20 +1209,16 @@ describe('evaluateFilterConditions', () => {
|
||||
{
|
||||
id: 'filter1',
|
||||
type: 'RELATION',
|
||||
label: 'Name Filter',
|
||||
rightOperand: 'John',
|
||||
operand: ViewFilterOperand.Is,
|
||||
displayValue: 'John',
|
||||
stepFilterGroupId: 'group1',
|
||||
leftOperand: 'John',
|
||||
},
|
||||
{
|
||||
id: 'filter2',
|
||||
type: 'NUMBER',
|
||||
label: 'Age Filter',
|
||||
rightOperand: 25,
|
||||
operand: ViewFilterOperand.GreaterThanOrEqual,
|
||||
displayValue: '25',
|
||||
stepFilterGroupId: 'group1',
|
||||
leftOperand: 30,
|
||||
},
|
||||
@@ -1244,20 +1234,16 @@ describe('evaluateFilterConditions', () => {
|
||||
{
|
||||
id: 'filter1',
|
||||
type: 'RELATION',
|
||||
label: 'Name Filter',
|
||||
rightOperand: 'John',
|
||||
operand: ViewFilterOperand.Is,
|
||||
displayValue: 'John',
|
||||
stepFilterGroupId: 'group1',
|
||||
leftOperand: 'John',
|
||||
},
|
||||
{
|
||||
id: 'filter2',
|
||||
type: 'NUMBER',
|
||||
label: 'Age Filter',
|
||||
rightOperand: 25,
|
||||
operand: ViewFilterOperand.GreaterThanOrEqual,
|
||||
displayValue: '25',
|
||||
stepFilterGroupId: 'group1',
|
||||
leftOperand: 20, // This will fail
|
||||
},
|
||||
@@ -1283,20 +1269,16 @@ describe('evaluateFilterConditions', () => {
|
||||
{
|
||||
id: 'filter1',
|
||||
type: 'RELATION',
|
||||
label: 'Name Filter',
|
||||
rightOperand: 'John',
|
||||
operand: ViewFilterOperand.Is,
|
||||
displayValue: 'John',
|
||||
stepFilterGroupId: 'group1',
|
||||
leftOperand: 'John',
|
||||
},
|
||||
{
|
||||
id: 'filter2',
|
||||
type: 'NUMBER',
|
||||
label: 'Age Filter',
|
||||
rightOperand: 25,
|
||||
operand: ViewFilterOperand.GreaterThanOrEqual,
|
||||
displayValue: '25',
|
||||
stepFilterGroupId: 'group1',
|
||||
leftOperand: 30,
|
||||
},
|
||||
@@ -1319,20 +1301,16 @@ describe('evaluateFilterConditions', () => {
|
||||
{
|
||||
id: 'filter1',
|
||||
type: 'RELATION',
|
||||
label: 'Name Filter',
|
||||
rightOperand: 'John',
|
||||
operand: ViewFilterOperand.Is,
|
||||
displayValue: 'John',
|
||||
stepFilterGroupId: 'group1',
|
||||
leftOperand: 'Jane', // This will fail
|
||||
},
|
||||
{
|
||||
id: 'filter2',
|
||||
type: 'NUMBER',
|
||||
label: 'Age Filter',
|
||||
rightOperand: 25,
|
||||
operand: ViewFilterOperand.GreaterThanOrEqual,
|
||||
displayValue: '25',
|
||||
stepFilterGroupId: 'group1',
|
||||
leftOperand: 30,
|
||||
},
|
||||
@@ -1357,20 +1335,16 @@ describe('evaluateFilterConditions', () => {
|
||||
{
|
||||
id: 'filter1',
|
||||
type: 'RELATION',
|
||||
label: 'Name Filter',
|
||||
rightOperand: 'John',
|
||||
operand: ViewFilterOperand.Is,
|
||||
displayValue: 'John',
|
||||
stepFilterGroupId: 'group1',
|
||||
leftOperand: 'Jane', // This will fail
|
||||
},
|
||||
{
|
||||
id: 'filter2',
|
||||
type: 'NUMBER',
|
||||
label: 'Age Filter',
|
||||
rightOperand: 25,
|
||||
operand: ViewFilterOperand.GreaterThanOrEqual,
|
||||
displayValue: '25',
|
||||
stepFilterGroupId: 'group1',
|
||||
leftOperand: 30, // This will pass
|
||||
},
|
||||
@@ -1393,20 +1367,16 @@ describe('evaluateFilterConditions', () => {
|
||||
{
|
||||
id: 'filter1',
|
||||
type: 'RELATION',
|
||||
label: 'Name Filter',
|
||||
rightOperand: 'John',
|
||||
operand: ViewFilterOperand.Is,
|
||||
displayValue: 'John',
|
||||
stepFilterGroupId: 'group1',
|
||||
leftOperand: 'Jane', // This will fail
|
||||
},
|
||||
{
|
||||
id: 'filter2',
|
||||
type: 'NUMBER',
|
||||
label: 'Age Filter',
|
||||
rightOperand: 25,
|
||||
operand: ViewFilterOperand.GreaterThanOrEqual,
|
||||
displayValue: '25',
|
||||
stepFilterGroupId: 'group1',
|
||||
leftOperand: 20, // This will fail
|
||||
},
|
||||
@@ -1435,20 +1405,16 @@ describe('evaluateFilterConditions', () => {
|
||||
{
|
||||
id: 'filter1',
|
||||
type: 'RELATION',
|
||||
label: 'Name Filter',
|
||||
rightOperand: 'John',
|
||||
operand: ViewFilterOperand.Is,
|
||||
displayValue: 'John',
|
||||
stepFilterGroupId: 'group1',
|
||||
leftOperand: 'John',
|
||||
},
|
||||
{
|
||||
id: 'filter2',
|
||||
type: 'NUMBER',
|
||||
label: 'Age Filter',
|
||||
rightOperand: 25,
|
||||
operand: ViewFilterOperand.GreaterThanOrEqual,
|
||||
displayValue: '25',
|
||||
stepFilterGroupId: 'group2',
|
||||
leftOperand: 30,
|
||||
},
|
||||
@@ -1485,30 +1451,24 @@ describe('evaluateFilterConditions', () => {
|
||||
{
|
||||
id: 'filter1',
|
||||
type: 'RELATION',
|
||||
label: 'Filter 1',
|
||||
rightOperand: 'John',
|
||||
operand: ViewFilterOperand.Is,
|
||||
displayValue: 'John',
|
||||
stepFilterGroupId: 'child1',
|
||||
leftOperand: 'Jane', // This will fail
|
||||
},
|
||||
{
|
||||
id: 'filter2',
|
||||
type: 'RELATION',
|
||||
label: 'Filter 2',
|
||||
rightOperand: 'Smith',
|
||||
operand: ViewFilterOperand.Is,
|
||||
displayValue: 'Smith',
|
||||
stepFilterGroupId: 'child1',
|
||||
leftOperand: 'Smith', // This will pass (OR group passes)
|
||||
},
|
||||
{
|
||||
id: 'filter3',
|
||||
type: 'NUMBER',
|
||||
label: 'Filter 3',
|
||||
rightOperand: 25,
|
||||
operand: ViewFilterOperand.GreaterThanOrEqual,
|
||||
displayValue: '25',
|
||||
stepFilterGroupId: 'child2',
|
||||
leftOperand: 30, // This will pass (AND group passes)
|
||||
},
|
||||
@@ -1548,10 +1508,8 @@ describe('evaluateFilterConditions', () => {
|
||||
{
|
||||
id: 'filter1',
|
||||
type: 'RELATION',
|
||||
label: 'Name Filter',
|
||||
rightOperand: 'John',
|
||||
operand: ViewFilterOperand.Is,
|
||||
displayValue: 'John',
|
||||
stepFilterGroupId: 'nonexistent',
|
||||
leftOperand: 'John',
|
||||
},
|
||||
|
||||
-1
@@ -49,7 +49,6 @@ const settings: WorkflowFormActionSettings = {
|
||||
value: 'A company',
|
||||
isLeaf: true,
|
||||
fieldIdName: 'id',
|
||||
nameSingular: 'company',
|
||||
objectMetadataId: '123e4567-e89b-12d3-a456-426614174000',
|
||||
},
|
||||
_outputSchemaType: 'RECORD',
|
||||
|
||||
@@ -15,13 +15,12 @@ export type StepFilterGroup = {
|
||||
export type StepFilter = {
|
||||
id: string;
|
||||
type: string;
|
||||
label: string;
|
||||
stepOutputKey: string;
|
||||
operand: ViewFilterOperand;
|
||||
value: string;
|
||||
displayValue: string;
|
||||
stepFilterGroupId: string;
|
||||
positionInStepFilterGroup?: number;
|
||||
fieldMetadataId?: string;
|
||||
compositeFieldSubFieldName?: string;
|
||||
isFullRecord?: boolean;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user