Variables not coming from a Record step should be available in Record Picker (#12708)

We want code and webhook variables available in Record Picker since
those can contains uuid.

This PR:
- update `WorkflowVariablesDropdownObjectItems.tsx` so it manages fields
properly
- factorise both dropdown into a commun hook
- update filterOutputSchema.ts so it does not filter fields that are not
FieldMetadata types
- set relation fields as record object in variable schema so those can
be selected as full record

Before


https://github.com/user-attachments/assets/f4f85402-c056-4fd8-8474-d86bef9d4bc3

After


https://github.com/user-attachments/assets/c6589e18-7dfa-4fc8-a525-3a580e265896
This commit is contained in:
Thomas Trompette
2025-06-19 11:33:21 +02:00
committed by GitHub
parent c16b625752
commit 07cf1ed71d
16 changed files with 229 additions and 159 deletions

View File

@ -2,32 +2,19 @@ import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenu
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 {
BaseOutputSchema,
LinkOutputSchema,
StepOutputSchema,
} from '@/workflow/workflow-variables/types/StepOutputSchema';
import { isBaseOutputSchema } from '@/workflow/workflow-variables/utils/isBaseOutputSchema';
import { isRecordOutputSchema } from '@/workflow/workflow-variables/utils/isRecordOutputSchema';
import { StepOutputSchema } from '@/workflow/workflow-variables/types/StepOutputSchema';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent';
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
import { workflowDiagramTriggerNodeSelectionComponentState } from '@/workflow/workflow-diagram/states/workflowDiagramTriggerNodeSelectionComponentState';
import { workflowSelectedNodeComponentState } from '@/workflow/workflow-diagram/states/workflowSelectedNodeComponentState';
import { getCurrentSubStepFromPath } from '@/workflow/workflow-variables/utils/getCurrentSubStepFromPath';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { getStepHeaderLabel } from '@/workflow/workflow-variables/utils/getStepHeaderLabel';
import { isLinkOutputSchema } from '@/workflow/workflow-variables/utils/isLinkOutputSchema';
import { useState } from 'react';
import { isDefined } from 'twenty-shared/utils';
import {
IconChevronLeft,
OverflowingTextWithTooltip,
useIcons,
} from 'twenty-ui/display';
import { MenuItemSelect } from 'twenty-ui/navigation';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { useVariableDropdown } from '../hooks/useVariableDropdown';
type WorkflowVariablesDropdownFieldItemsProps = {
step: StepOutputSchema;
@ -40,83 +27,19 @@ export const WorkflowVariablesDropdownFieldItems = ({
onSelect,
onBack,
}: WorkflowVariablesDropdownFieldItemsProps) => {
const [currentPath, setCurrentPath] = useState<string[]>([]);
const [searchInputValue, setSearchInputValue] = useState('');
const { getIcon } = useIcons();
const setWorkflowSelectedNode = useSetRecoilComponentStateV2(
workflowSelectedNodeComponentState,
);
const setActiveTabId = useSetRecoilComponentStateV2(
activeTabIdComponentState,
'workflow-serverless-function-tab-list-component-id',
);
const setWorkflowDiagramTriggerNodeSelection = useSetRecoilComponentStateV2(
workflowDiagramTriggerNodeSelectionComponentState,
);
const getDisplayedSubStepFields = () => {
const currentSubStep = getCurrentSubStepFromPath(step, currentPath);
if (isLinkOutputSchema(currentSubStep)) {
return { link: currentSubStep.link };
} else if (isRecordOutputSchema(currentSubStep)) {
return currentSubStep.fields;
} else if (isBaseOutputSchema(currentSubStep)) {
return currentSubStep;
}
};
const handleSelectField = (key: string) => {
const currentSubStep = getCurrentSubStepFromPath(step, currentPath);
const handleSelectBaseOutputSchema = (
baseOutputSchema: BaseOutputSchema,
) => {
if (!baseOutputSchema[key]?.isLeaf) {
setCurrentPath([...currentPath, key]);
setSearchInputValue('');
} else {
onSelect(`{{${step.id}.${[...currentPath, key].join('.')}}}`);
}
};
const handleSelectLinkOutputSchema = (
linkOutputSchema: LinkOutputSchema,
) => {
setWorkflowSelectedNode(step.id);
setWorkflowDiagramTriggerNodeSelection(step.id);
if (isDefined(linkOutputSchema.link.tab)) {
setActiveTabId(linkOutputSchema.link.tab);
}
};
if (isLinkOutputSchema(currentSubStep)) {
handleSelectLinkOutputSchema(currentSubStep);
} else if (isRecordOutputSchema(currentSubStep)) {
handleSelectBaseOutputSchema(currentSubStep.fields);
} else if (isBaseOutputSchema(currentSubStep)) {
handleSelectBaseOutputSchema(currentSubStep);
}
};
const goBack = () => {
if (currentPath.length === 0) {
onBack();
} else {
setCurrentPath(currentPath.slice(0, -1));
}
};
const displayedObject = getDisplayedSubStepFields();
const options = displayedObject ? Object.entries(displayedObject) : [];
const filteredOptions = searchInputValue
? options.filter(
([_, value]) =>
value.label &&
value.label.toLowerCase().includes(searchInputValue.toLowerCase()),
)
: options;
const {
searchInputValue,
setSearchInputValue,
handleSelectField,
goBack,
filteredOptions,
currentPath,
} = useVariableDropdown({
step,
onSelect,
onBack,
});
return (
<DropdownContent widthInPixels={GenericDropdownContentWidth.ExtraLarge}>

View File

@ -5,19 +5,19 @@ import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownM
import { StepOutputSchema } from '@/workflow/workflow-variables/types/StepOutputSchema';
import { getCurrentSubStepFromPath } from '@/workflow/workflow-variables/utils/getCurrentSubStepFromPath';
import { getStepHeaderLabel } from '@/workflow/workflow-variables/utils/getStepHeaderLabel';
import { isBaseOutputSchema } from '@/workflow/workflow-variables/utils/isBaseOutputSchema';
import { isRecordOutputSchema } from '@/workflow/workflow-variables/utils/isRecordOutputSchema';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent';
import { useState } from 'react';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { t } from '@lingui/core/macro';
import {
IconChevronLeft,
OverflowingTextWithTooltip,
useIcons,
} from 'twenty-ui/display';
import { MenuItemSelect } from 'twenty-ui/navigation';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { useVariableDropdown } from '../hooks/useVariableDropdown';
type WorkflowVariablesDropdownObjectItemsProps = {
step: StepOutputSchema;
@ -30,19 +30,19 @@ export const WorkflowVariablesDropdownObjectItems = ({
onSelect,
onBack,
}: WorkflowVariablesDropdownObjectItemsProps) => {
const [currentPath, setCurrentPath] = useState<string[]>([]);
const [searchInputValue, setSearchInputValue] = useState('');
const { getIcon } = useIcons();
const getDisplayedSubStepFields = () => {
const currentSubStep = getCurrentSubStepFromPath(step, currentPath);
if (isRecordOutputSchema(currentSubStep)) {
return currentSubStep.fields;
} else if (isBaseOutputSchema(currentSubStep)) {
return currentSubStep;
}
};
const {
currentPath,
filteredOptions,
searchInputValue,
setSearchInputValue,
handleSelectField,
goBack,
} = useVariableDropdown({
step,
onSelect,
onBack,
});
const getDisplayedSubStepObject = () => {
const currentSubStep = getCurrentSubStepFromPath(step, currentPath);
@ -66,19 +66,6 @@ export const WorkflowVariablesDropdownObjectItems = ({
);
};
const handleSelectField = (key: string) => {
setCurrentPath([...currentPath, key]);
setSearchInputValue('');
};
const goBack = () => {
if (currentPath.length === 0) {
onBack();
} else {
setCurrentPath(currentPath.slice(0, -1));
}
};
const displayedSubStepObject = getDisplayedSubStepObject();
const shouldDisplaySubStepObject = searchInputValue
@ -88,16 +75,9 @@ export const WorkflowVariablesDropdownObjectItems = ({
.includes(searchInputValue.toLowerCase())
: true;
const displayedFields = getDisplayedSubStepFields();
const options = displayedFields ? Object.entries(displayedFields) : [];
const filteredOptions = searchInputValue
? options.filter(
([_, value]) =>
value.label &&
value.label.toLowerCase().includes(searchInputValue.toLowerCase()),
)
: options;
const shouldDisplayObject =
shouldDisplaySubStepObject && displayedSubStepObject?.label;
const nameSingular = displayedSubStepObject?.nameSingular;
return (
<DropdownContent widthInPixels={GenericDropdownContentWidth.ExtraLarge}>
@ -120,29 +100,36 @@ export const WorkflowVariablesDropdownObjectItems = ({
/>
<DropdownMenuSeparator />
<DropdownMenuItemsContainer hasMaxHeight>
{shouldDisplaySubStepObject && displayedSubStepObject?.label && (
{shouldDisplayObject && (
<MenuItemSelect
selected={false}
focused={false}
onClick={handleSelectObject}
text={displayedSubStepObject.label}
text={displayedSubStepObject?.label || ''}
hasSubMenu={false}
LeftIcon={
displayedSubStepObject.icon
? getIcon(displayedSubStepObject.icon)
: undefined
}
contextualText={t`Pick a ${nameSingular} record`}
/>
)}
{filteredOptions.map(([key, value]) => (
{filteredOptions.length > 0 && shouldDisplayObject && (
<DropdownMenuSeparator />
)}
{filteredOptions.map(([key, option]) => (
<MenuItemSelect
key={key}
selected={false}
focused={false}
onClick={() => handleSelectField(key)}
text={value.label || key}
hasSubMenu={!value.isLeaf}
LeftIcon={value.icon ? getIcon(value.icon) : undefined}
text={option.label || key}
hasSubMenu={!option.isLeaf}
LeftIcon={option.icon ? getIcon(option.icon) : undefined}
contextualText={
option.isLeaf ? option?.value?.toString() : undefined
}
/>
))}
</DropdownMenuItemsContainer>

View File

@ -0,0 +1,123 @@
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
import { workflowDiagramTriggerNodeSelectionComponentState } from '@/workflow/workflow-diagram/states/workflowDiagramTriggerNodeSelectionComponentState';
import { workflowSelectedNodeComponentState } from '@/workflow/workflow-diagram/states/workflowSelectedNodeComponentState';
import { useState } from 'react';
import { isDefined } from 'twenty-shared/utils';
import {
BaseOutputSchema,
LinkOutputSchema,
StepOutputSchema,
} from '../types/StepOutputSchema';
import { getCurrentSubStepFromPath } from '../utils/getCurrentSubStepFromPath';
import { isBaseOutputSchema } from '../utils/isBaseOutputSchema';
import { isLinkOutputSchema } from '../utils/isLinkOutputSchema';
import { isRecordOutputSchema } from '../utils/isRecordOutputSchema';
type UseVariableDropdownProps = {
step: StepOutputSchema;
onSelect: (value: string) => void;
onBack: () => void;
};
type UseVariableDropdownReturn = {
currentPath: string[];
searchInputValue: string;
setSearchInputValue: (value: string) => void;
handleSelectField: (key: string) => void;
goBack: () => void;
filteredOptions: [string, any][];
};
export const useVariableDropdown = ({
step,
onSelect,
onBack,
}: UseVariableDropdownProps): UseVariableDropdownReturn => {
const [currentPath, setCurrentPath] = useState<string[]>([]);
const [searchInputValue, setSearchInputValue] = useState('');
const setWorkflowSelectedNode = useSetRecoilComponentStateV2(
workflowSelectedNodeComponentState,
);
const setActiveTabId = useSetRecoilComponentStateV2(
activeTabIdComponentState,
'workflow-serverless-function-tab-list-component-id',
);
const setWorkflowDiagramTriggerNodeSelection = useSetRecoilComponentStateV2(
workflowDiagramTriggerNodeSelectionComponentState,
);
const getDisplayedSubStepFields = () => {
const currentSubStep = getCurrentSubStepFromPath(step, currentPath);
if (isLinkOutputSchema(currentSubStep)) {
return { link: currentSubStep.link };
} else if (isRecordOutputSchema(currentSubStep)) {
return currentSubStep.fields;
} else if (isBaseOutputSchema(currentSubStep)) {
return currentSubStep;
}
};
const handleSelectField = (key: string) => {
const currentSubStep = getCurrentSubStepFromPath(step, currentPath);
const handleSelectBaseOutputSchema = (
baseOutputSchema: BaseOutputSchema,
) => {
if (!baseOutputSchema[key]?.isLeaf) {
setCurrentPath([...currentPath, key]);
setSearchInputValue('');
} else {
onSelect(`{{${step.id}.${[...currentPath, key].join('.')}}}`);
}
};
const handleSelectLinkOutputSchema = (
linkOutputSchema: LinkOutputSchema,
) => {
setWorkflowSelectedNode(step.id);
setWorkflowDiagramTriggerNodeSelection(step.id);
if (isDefined(linkOutputSchema.link.tab)) {
setActiveTabId(linkOutputSchema.link.tab);
}
};
if (isLinkOutputSchema(currentSubStep)) {
handleSelectLinkOutputSchema(currentSubStep);
} else if (isRecordOutputSchema(currentSubStep)) {
handleSelectBaseOutputSchema(currentSubStep.fields);
} else if (isBaseOutputSchema(currentSubStep)) {
handleSelectBaseOutputSchema(currentSubStep);
}
};
const goBack = () => {
if (currentPath.length === 0) {
onBack();
} else {
setCurrentPath(currentPath.slice(0, -1));
}
};
const displayedFields = getDisplayedSubStepFields();
const options = displayedFields ? Object.entries(displayedFields) : [];
const filteredOptions = searchInputValue
? options.filter(
([_, value]) =>
value.label &&
value.label.toLowerCase().includes(searchInputValue.toLowerCase()),
)
: options;
return {
currentPath,
searchInputValue,
setSearchInputValue,
handleSelectField,
goBack,
filteredOptions,
};
};

View File

@ -10,6 +10,7 @@ type Leaf = {
type Node = {
isLeaf: false;
type?: InputSchemaPropertyType;
icon?: string;
label?: string;
value: OutputSchema;

View File

@ -1,4 +1,5 @@
import { OutputSchema } from '@/workflow/workflow-variables/types/StepOutputSchema';
import { FieldMetadataType } from 'twenty-shared/types';
import { filterOutputSchema } from '../filterOutputSchema';
describe('filterOutputSchema', () => {
@ -85,9 +86,10 @@ describe('filterOutputSchema', () => {
expect(filterOutputSchema(inputSchema, 'person')).toEqual(expectedSchema);
});
it('should ignore leaf fields', () => {
it('should ignore leaf fields that are field metadata types', () => {
const inputSchema = createRecordSchema('company', {
name: { isLeaf: true, value: 'string' },
id: { isLeaf: true, type: FieldMetadataType.UUID },
employee: {
isLeaf: false,
value: createRecordSchema('person'),
@ -97,6 +99,7 @@ describe('filterOutputSchema', () => {
const expectedSchema = {
_outputSchemaType: 'RECORD',
fields: {
name: { isLeaf: true, value: 'string' },
employee: {
isLeaf: false,
value: createRecordSchema('person'),
@ -117,6 +120,7 @@ describe('filterOutputSchema', () => {
const inputSchema = createBaseSchema({
field1: {
isLeaf: true,
type: FieldMetadataType.TEXT,
value: 'string',
},
});

View File

@ -4,6 +4,7 @@ import {
RecordOutputSchema,
} from '@/workflow/workflow-variables/types/StepOutputSchema';
import { isBaseOutputSchema } from '@/workflow/workflow-variables/utils/isBaseOutputSchema';
import { isFieldTypeCompatibleWithRecordId } from '@/workflow/workflow-variables/utils/isFieldTypeCompatibleWithRecordId';
import { isLinkOutputSchema } from '@/workflow/workflow-variables/utils/isLinkOutputSchema';
import { isRecordOutputSchema } from '@/workflow/workflow-variables/utils/isRecordOutputSchema';
import { isDefined } from 'twenty-shared/utils';
@ -33,6 +34,10 @@ const filterRecordOutputSchema = (
const field = outputSchema.fields[key];
if (field.isLeaf) {
if (isFieldTypeCompatibleWithRecordId(field.type)) {
filteredFields[key] = field;
hasValidFields = true;
}
continue;
}
@ -75,6 +80,10 @@ const filterBaseOutputSchema = (
const field = outputSchema[key];
if (field.isLeaf) {
if (isFieldTypeCompatibleWithRecordId(field.type)) {
filteredSchema[key] = field;
hasValidFields = true;
}
continue;
}

View File

@ -0,0 +1,7 @@
import { InputSchemaPropertyType } from '@/workflow/types/InputSchema';
export const isFieldTypeCompatibleWithRecordId = (
type?: InputSchemaPropertyType,
): boolean => {
return !type || type === 'string' || type === 'unknown';
};

View File

@ -94,12 +94,13 @@ const searchCurrentStepOutputSchema = ({
}
return {
variableLabel: isFullRecord
? getDisplayedSubStepObjectLabel(currentSubStep)
: getDisplayedSubStepFieldLabel(
isSelectedFieldInNextKey ? nextKey : selectedField,
currentSubStep,
),
variableLabel:
isFullRecord && isRecordOutputSchema(currentSubStep)
? getDisplayedSubStepObjectLabel(currentSubStep)
: getDisplayedSubStepFieldLabel(
isSelectedFieldInNextKey ? nextKey : selectedField,
currentSubStep,
),
variablePathLabel,
};
};

View File

@ -11,6 +11,7 @@ export type Leaf = {
export type Node = {
isLeaf: false;
type?: InputSchemaPropertyType;
icon?: string;
label?: string;
value: OutputSchema;

View File

@ -128,6 +128,7 @@ describe('generateFakeField', () => {
isLeaf: false,
icon: undefined,
label: 'Links Field',
type: FieldMetadataType.LINKS,
value: {
label: {
isLeaf: true,
@ -166,6 +167,7 @@ describe('generateFakeField', () => {
isLeaf: false,
icon: 'IconCurrency',
label: 'Currency Field',
type: FieldMetadataType.CURRENCY,
value: {
amount: {
isLeaf: true,

View File

@ -1,6 +1,6 @@
import { mockObjectMetadataItemsWithFieldMaps } from 'src/engine/core-modules/__mocks__/mockObjectMetadataItemsWithFieldMaps';
import { generateFakeObjectRecord } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-object-record';
import { generateObjectRecordFields } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-object-record-fields';
import { mockObjectMetadataItemsWithFieldMaps } from 'src/engine/core-modules/__mocks__/mockObjectMetadataItemsWithFieldMaps';
jest.mock(
'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-object-record-fields',
@ -33,7 +33,7 @@ const objectMetadataInfo = {
describe('generateFakeObjectRecord', () => {
it('should generate a record with correct object metadata', () => {
const result = generateFakeObjectRecord(objectMetadataInfo);
const result = generateFakeObjectRecord({ objectMetadataInfo });
expect(result).toEqual({
object: {
@ -53,10 +53,11 @@ describe('generateFakeObjectRecord', () => {
});
it('should call generateObjectRecordFields with the object metadata', () => {
generateFakeObjectRecord(objectMetadataInfo);
generateFakeObjectRecord({ objectMetadataInfo });
expect(generateObjectRecordFields).toHaveBeenCalledWith({
objectMetadataInfo,
depth: 0,
});
});
});

View File

@ -22,6 +22,7 @@ export const generateFakeField = ({
if (compositeType) {
return {
isLeaf: false,
type: type,
icon: icon,
label: label,
value: compositeType.properties.reduce((acc, property) => {

View File

@ -1,5 +1,7 @@
import { isDefined } from 'twenty-shared/utils';
import { ObjectMetadataMaps } from 'src/engine/metadata-modules/types/object-metadata-maps';
import { getObjectMetadataMapItemByNameSingular } from 'src/engine/metadata-modules/utils/get-object-metadata-map-item-by-name-singular.util';
import {
Leaf,
Node,
@ -7,8 +9,6 @@ import {
import { generateFakeField } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-field';
import { generateFakeObjectRecord } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-object-record';
import { FormFieldMetadata } from 'src/modules/workflow/workflow-executor/workflow-actions/form/types/workflow-form-action-settings.type';
import { ObjectMetadataMaps } from 'src/engine/metadata-modules/types/object-metadata-maps';
import { getObjectMetadataMapItemByNameSingular } from 'src/engine/metadata-modules/utils/get-object-metadata-map-item-by-name-singular.util';
export const generateFakeFormResponse = async ({
formMetadata,
@ -40,8 +40,10 @@ export const generateFakeFormResponse = async ({
isLeaf: false,
label: formFieldMetadata.label,
value: generateFakeObjectRecord({
objectMetadataMaps,
objectMetadataItemWithFieldsMaps,
objectMetadataInfo: {
objectMetadataItemWithFieldsMaps,
objectMetadataMaps,
},
}),
},
};

View File

@ -1,10 +1,14 @@
import { ObjectMetadataInfo } from 'src/modules/workflow/common/workspace-services/workflow-common.workspace-service';
import { RecordOutputSchema } from 'src/modules/workflow/workflow-builder/workflow-schema/types/output-schema.type';
import { generateObjectRecordFields } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-object-record-fields';
import { ObjectMetadataInfo } from 'src/modules/workflow/common/workspace-services/workflow-common.workspace-service';
export const generateFakeObjectRecord = (
objectMetadataInfo: ObjectMetadataInfo,
): RecordOutputSchema => {
export const generateFakeObjectRecord = ({
objectMetadataInfo,
depth = 0,
}: {
objectMetadataInfo: ObjectMetadataInfo;
depth?: number;
}): RecordOutputSchema => {
return {
object: {
isLeaf: true,
@ -15,7 +19,10 @@ export const generateFakeObjectRecord = (
objectMetadataInfo.objectMetadataItemWithFieldsMaps.nameSingular,
fieldIdName: 'id',
},
fields: generateObjectRecordFields({ objectMetadataInfo }),
fields: generateObjectRecordFields({
objectMetadataInfo,
depth,
}),
_outputSchemaType: 'RECORD',
};
};

View File

@ -1,10 +1,11 @@
import { FieldMetadataType } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { ObjectMetadataInfo } from 'src/modules/workflow/common/workspace-services/workflow-common.workspace-service';
import { BaseOutputSchema } from 'src/modules/workflow/workflow-builder/workflow-schema/types/output-schema.type';
import { generateFakeField } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-field';
import { generateFakeObjectRecord } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-object-record';
import { shouldGenerateFieldFakeValue } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/should-generate-field-fake-value';
import { ObjectMetadataInfo } from 'src/modules/workflow/common/workspace-services/workflow-common.workspace-service';
const MAXIMUM_DEPTH = 1;
@ -45,7 +46,7 @@ export const generateObjectRecordFields = ({
isLeaf: false,
icon: field.icon,
label: field.label,
value: generateObjectRecordFields({
value: generateFakeObjectRecord({
objectMetadataInfo: {
objectMetadataItemWithFieldsMaps: relationTargetObjectMetadata,
objectMetadataMaps: objectMetadataInfo.objectMetadataMaps,

View File

@ -3,6 +3,7 @@ import { Injectable } from '@nestjs/common';
import { DatabaseEventAction } from 'src/engine/api/graphql/graphql-query-runner/enums/database-event-action';
import { checkStringIsDatabaseEventAction } from 'src/engine/api/graphql/graphql-query-runner/utils/check-string-is-database-event-action';
import { generateFakeValue } from 'src/engine/utils/generate-fake-value';
import { WorkflowCommonWorkspaceService } from 'src/modules/workflow/common/workspace-services/workflow-common.workspace-service';
import { OutputSchema } from 'src/modules/workflow/workflow-builder/workflow-schema/types/output-schema.type';
import { generateFakeFormResponse } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-form-response';
import { generateFakeObjectRecord } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-object-record';
@ -16,7 +17,6 @@ import {
WorkflowTrigger,
WorkflowTriggerType,
} from 'src/modules/workflow/workflow-trigger/types/workflow-trigger.type';
import { WorkflowCommonWorkspaceService } from 'src/modules/workflow/common/workspace-services/workflow-common.workspace-service';
@Injectable()
export class WorkflowSchemaWorkspaceService {
@ -148,7 +148,7 @@ export class WorkflowSchemaWorkspaceService {
workspaceId,
);
return generateFakeObjectRecord(objectMetadataInfo);
return generateFakeObjectRecord({ objectMetadataInfo });
}
private computeSendEmailActionOutputSchema(): OutputSchema {