Morph many to one picker (#14155)
This PR follows the multiSelect PR merged previously. It will enable morph relation Many to One to be handled from the table, using a singleSelect picker Main point : I decided to change the singleSelect API to take an array of **objectMetadataName** instead of only one to deal with both our usecases. --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@@ -1 +1 @@
|
||||
export const TRIGGER_STEP_ID = 'trigger';
|
||||
export const TRIGGER_STEP_ID = 'trigger';
|
||||
|
||||
@@ -4,7 +4,9 @@ export const baseTriggerSchema = z.object({
|
||||
name: z
|
||||
.string()
|
||||
.optional()
|
||||
.describe('Human-readable name for the trigger. Optional but recommended for clarity.'),
|
||||
.describe(
|
||||
'Human-readable name for the trigger. Optional but recommended for clarity.',
|
||||
),
|
||||
type: z
|
||||
.enum(['DATABASE_EVENT', 'MANUAL', 'CRON', 'WEBHOOK'])
|
||||
.describe(
|
||||
@@ -14,10 +16,14 @@ export const baseTriggerSchema = z.object({
|
||||
.object({ x: z.number(), y: z.number() })
|
||||
.optional()
|
||||
.nullable()
|
||||
.describe('Position coordinates for the trigger in the workflow diagram. Use (0, 0) for the trigger step.'),
|
||||
.describe(
|
||||
'Position coordinates for the trigger in the workflow diagram. Use (0, 0) for the trigger step.',
|
||||
),
|
||||
nextStepIds: z
|
||||
.array(z.string())
|
||||
.optional()
|
||||
.nullable()
|
||||
.describe('Array of step IDs that the trigger connects to. These are the first steps in the workflow.'),
|
||||
.describe(
|
||||
'Array of step IDs that the trigger connects to. These are the first steps in the workflow.',
|
||||
),
|
||||
});
|
||||
|
||||
@@ -3,18 +3,26 @@ import { z } from 'zod';
|
||||
export const baseWorkflowActionSchema = z.object({
|
||||
id: z
|
||||
.string()
|
||||
.describe('Unique identifier for the workflow step. Must be unique within the workflow.'),
|
||||
.describe(
|
||||
'Unique identifier for the workflow step. Must be unique within the workflow.',
|
||||
),
|
||||
name: z
|
||||
.string()
|
||||
.describe('Human-readable name for the workflow step. Should clearly describe what the step does.'),
|
||||
.describe(
|
||||
'Human-readable name for the workflow step. Should clearly describe what the step does.',
|
||||
),
|
||||
valid: z
|
||||
.boolean()
|
||||
.describe('Whether the step configuration is valid. Set to true when all required fields are properly configured.'),
|
||||
.describe(
|
||||
'Whether the step configuration is valid. Set to true when all required fields are properly configured.',
|
||||
),
|
||||
nextStepIds: z
|
||||
.array(z.string())
|
||||
.optional()
|
||||
.nullable()
|
||||
.describe('Array of step IDs that this step connects to. Leave empty or null for the final step.'),
|
||||
.describe(
|
||||
'Array of step IDs that this step connects to. Leave empty or null for the final step.',
|
||||
),
|
||||
position: z
|
||||
.object({ x: z.number(), y: z.number() })
|
||||
.optional()
|
||||
|
||||
@@ -16,7 +16,9 @@ export const baseWorkflowActionSettingsSchema = z.object({
|
||||
value: z.boolean().describe('Whether to retry the action if it fails.'),
|
||||
}),
|
||||
continueOnFailure: z.object({
|
||||
value: z.boolean().describe('Whether to continue to the next step if this action fails.'),
|
||||
value: z
|
||||
.boolean()
|
||||
.describe('Whether to continue to the next step if this action fails.'),
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -2,7 +2,9 @@ import { z } from 'zod';
|
||||
import { baseWorkflowActionSchema } from './base-workflow-action-schema';
|
||||
import { workflowCreateRecordActionSettingsSchema } from './create-record-action-settings-schema';
|
||||
|
||||
export const workflowCreateRecordActionSchema = baseWorkflowActionSchema.extend({
|
||||
type: z.literal('CREATE_RECORD'),
|
||||
settings: workflowCreateRecordActionSettingsSchema,
|
||||
});
|
||||
export const workflowCreateRecordActionSchema = baseWorkflowActionSchema.extend(
|
||||
{
|
||||
type: z.literal('CREATE_RECORD'),
|
||||
settings: workflowCreateRecordActionSettingsSchema,
|
||||
},
|
||||
);
|
||||
|
||||
@@ -10,9 +10,6 @@ export const workflowCreateRecordActionSettingsSchema =
|
||||
.describe(
|
||||
'The name of the object to create a record in. Must be lowercase (e.g., "person", "company", "task").',
|
||||
),
|
||||
objectRecord: objectRecordSchema
|
||||
.describe(
|
||||
'The record data to create.',
|
||||
)
|
||||
objectRecord: objectRecordSchema.describe('The record data to create.'),
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -2,7 +2,9 @@ import { z } from 'zod';
|
||||
import { baseWorkflowActionSchema } from './base-workflow-action-schema';
|
||||
import { workflowDeleteRecordActionSettingsSchema } from './delete-record-action-settings-schema';
|
||||
|
||||
export const workflowDeleteRecordActionSchema = baseWorkflowActionSchema.extend({
|
||||
type: z.literal('DELETE_RECORD'),
|
||||
settings: workflowDeleteRecordActionSettingsSchema,
|
||||
});
|
||||
export const workflowDeleteRecordActionSchema = baseWorkflowActionSchema.extend(
|
||||
{
|
||||
type: z.literal('DELETE_RECORD'),
|
||||
settings: workflowDeleteRecordActionSettingsSchema,
|
||||
},
|
||||
);
|
||||
|
||||
@@ -20,7 +20,9 @@ export const workflowFilterActionSettingsSchema =
|
||||
id: z.string(),
|
||||
type: z.string(),
|
||||
stepOutputKey: z.string(),
|
||||
operand: z.enum(ViewFilterOperand).or(z.enum(ViewFilterOperandDeprecated)),
|
||||
operand: z
|
||||
.enum(ViewFilterOperand)
|
||||
.or(z.enum(ViewFilterOperandDeprecated)),
|
||||
value: z.string(),
|
||||
stepFilterGroupId: z.string(),
|
||||
positionInStepFilterGroup: z.number().optional(),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { z } from 'zod';
|
||||
import { baseTriggerSchema } from './base-trigger-schema';
|
||||
|
||||
export const workflowManualTriggerSchema = baseTriggerSchema
|
||||
export const workflowManualTriggerSchema = baseTriggerSchema
|
||||
.extend({
|
||||
type: z.literal('MANUAL'),
|
||||
settings: z.object({
|
||||
@@ -34,4 +34,4 @@ import { baseTriggerSchema } from './base-trigger-schema';
|
||||
})
|
||||
.describe(
|
||||
'Manual trigger that can be launched by the user. If a record is selected when launched, it is accessible via {{trigger.record.fieldName}}. If no record is selected, no data context is available.',
|
||||
);
|
||||
);
|
||||
|
||||
@@ -4,7 +4,7 @@ export const objectRecordSchema = z
|
||||
.record(z.string(), z.any())
|
||||
.describe(
|
||||
'Record data object. Use nested objects for relationships (e.g., "company": {"id": "{{reference}}"}). Common patterns:\n' +
|
||||
'- Person: {"name": {"firstName": "John", "lastName": "Doe"}, "emails": {"primaryEmail": "john@example.com"}, "company": {"id": "{{trigger.object.id}}"}}\n' +
|
||||
'- Company: {"name": "Acme Corp", "domainName": {"primaryLinkUrl": "https://acme.com"}}\n' +
|
||||
'- Task: {"title": "Follow up", "status": "TODO", "assignee": {"id": "{{user.id}}"}}',
|
||||
'- Person: {"name": {"firstName": "John", "lastName": "Doe"}, "emails": {"primaryEmail": "john@example.com"}, "company": {"id": "{{trigger.object.id}}"}}\n' +
|
||||
'- Company: {"name": "Acme Corp", "domainName": {"primaryLinkUrl": "https://acme.com"}}\n' +
|
||||
'- Task: {"title": "Follow up", "status": "TODO", "assignee": {"id": "{{user.id}}"}}',
|
||||
);
|
||||
|
||||
@@ -2,7 +2,9 @@ import { z } from 'zod';
|
||||
import { baseWorkflowActionSchema } from './base-workflow-action-schema';
|
||||
import { workflowUpdateRecordActionSettingsSchema } from './update-record-action-settings-schema';
|
||||
|
||||
export const workflowUpdateRecordActionSchema = baseWorkflowActionSchema.extend({
|
||||
type: z.literal('UPDATE_RECORD'),
|
||||
settings: workflowUpdateRecordActionSettingsSchema,
|
||||
});
|
||||
export const workflowUpdateRecordActionSchema = baseWorkflowActionSchema.extend(
|
||||
{
|
||||
type: z.literal('UPDATE_RECORD'),
|
||||
settings: workflowUpdateRecordActionSettingsSchema,
|
||||
},
|
||||
);
|
||||
|
||||
@@ -6,12 +6,14 @@ export const workflowRunStateStepInfoSchema = z.object({
|
||||
error: z.string().optional(),
|
||||
status: workflowRunStepStatusSchema,
|
||||
get history() {
|
||||
return z.array(
|
||||
workflowRunStateStepInfoSchema.pick({
|
||||
result: true,
|
||||
status: true,
|
||||
error: true,
|
||||
})
|
||||
).optional();
|
||||
}
|
||||
return z
|
||||
.array(
|
||||
workflowRunStateStepInfoSchema.pick({
|
||||
result: true,
|
||||
status: true,
|
||||
error: true,
|
||||
}),
|
||||
)
|
||||
.optional();
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { type workflowRunStateStepInfoSchema } from "@/workflow/schemas/workflow-run-state-step-info-schema";
|
||||
import { type workflowRunStateStepInfosSchema } from "@/workflow/schemas/workflow-run-state-step-infos-schema";
|
||||
import type z from "zod";
|
||||
import { type workflowRunStateStepInfoSchema } from '@/workflow/schemas/workflow-run-state-step-info-schema';
|
||||
import { type workflowRunStateStepInfosSchema } from '@/workflow/schemas/workflow-run-state-step-infos-schema';
|
||||
import type z from 'zod';
|
||||
|
||||
export enum StepStatus {
|
||||
NOT_STARTED = 'NOT_STARTED',
|
||||
@@ -11,6 +11,10 @@ export enum StepStatus {
|
||||
PENDING = 'PENDING',
|
||||
}
|
||||
|
||||
export type WorkflowRunStepInfo = z.infer<typeof workflowRunStateStepInfoSchema>
|
||||
export type WorkflowRunStepInfo = z.infer<
|
||||
typeof workflowRunStateStepInfoSchema
|
||||
>;
|
||||
|
||||
export type WorkflowRunStepInfos = z.infer<typeof workflowRunStateStepInfosSchema>;
|
||||
export type WorkflowRunStepInfos = z.infer<
|
||||
typeof workflowRunStateStepInfosSchema
|
||||
>;
|
||||
|
||||
@@ -12,7 +12,8 @@ export const canObjectBeManagedByWorkflow = ({
|
||||
'dashboard',
|
||||
];
|
||||
|
||||
return !excludedNonSystemObjectMetadataItemNames.includes(
|
||||
nameSingular,
|
||||
) && !isSystem;
|
||||
return (
|
||||
!excludedNonSystemObjectMetadataItemNames.includes(nameSingular) &&
|
||||
!isSystem
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user