Fix email node not saved correctly (#832)
This commit is contained in:
@@ -1,6 +1,10 @@
|
|||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import { useWorkflowQuery } from "../hooks/useWorkflowQuery";
|
import { useWorkflowQuery } from "../hooks/useWorkflowQuery";
|
||||||
import { convertEchoParameters, getElements } from "./workflowEditorUtils";
|
import {
|
||||||
|
convertEchoParameters,
|
||||||
|
getAdditionalParametersForEmailBlock,
|
||||||
|
getElements,
|
||||||
|
} from "./workflowEditorUtils";
|
||||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||||
import {
|
import {
|
||||||
BlockYAML,
|
BlockYAML,
|
||||||
@@ -143,8 +147,21 @@ function WorkflowEditor() {
|
|||||||
|
|
||||||
const echoParameters = convertEchoParameters(filteredParameters);
|
const echoParameters = convertEchoParameters(filteredParameters);
|
||||||
|
|
||||||
|
const overallParameters = [
|
||||||
|
...parameters,
|
||||||
|
...echoParameters,
|
||||||
|
] as Array<ParameterYAML>;
|
||||||
|
|
||||||
|
// if there is an email node, we need to add the email aws secret parameters
|
||||||
|
const emailAwsSecretParameters =
|
||||||
|
getAdditionalParametersForEmailBlock(blocks, overallParameters);
|
||||||
|
|
||||||
saveWorkflowMutation.mutate({
|
saveWorkflowMutation.mutate({
|
||||||
parameters: [...echoParameters, ...parameters],
|
parameters: [
|
||||||
|
...echoParameters,
|
||||||
|
...parameters,
|
||||||
|
...emailAwsSecretParameters,
|
||||||
|
],
|
||||||
blocks,
|
blocks,
|
||||||
title,
|
title,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,2 +1,16 @@
|
|||||||
// nodes have 1000 Z index and we want edges above
|
// nodes have 1000 Z index and we want edges above
|
||||||
export const REACT_FLOW_EDGE_Z_INDEX = 1001;
|
export const REACT_FLOW_EDGE_Z_INDEX = 1001;
|
||||||
|
|
||||||
|
export const SKYVERN_DOWNLOAD_DIRECTORY = "SKYVERN_DOWNLOAD_DIRECTORY";
|
||||||
|
|
||||||
|
export const SMTP_HOST_PARAMETER_KEY = "smtp_host";
|
||||||
|
export const SMTP_PORT_PARAMETER_KEY = "smtp_port";
|
||||||
|
export const SMTP_USERNAME_PARAMETER_KEY = "smtp_username";
|
||||||
|
export const SMTP_PASSWORD_PARAMETER_KEY = "smtp_password";
|
||||||
|
|
||||||
|
export const SMTP_HOST_AWS_KEY = "SKYVERN_SMTP_HOST_AWS_SES";
|
||||||
|
export const SMTP_PORT_AWS_KEY = "SKYVERN_SMTP_PORT_AWS_SES";
|
||||||
|
export const SMTP_USERNAME_AWS_KEY = "SKYVERN_SMTP_USERNAME_AWS_SES";
|
||||||
|
export const SMTP_PASSWORD_AWS_KEY = "SKYVERN_SMTP_PASSWORD_AWS_SES";
|
||||||
|
|
||||||
|
export const EMAIL_BLOCK_SENDER = "hello@skyvern.com";
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import type { Node } from "@xyflow/react";
|
import type { Node } from "@xyflow/react";
|
||||||
|
import { SKYVERN_DOWNLOAD_DIRECTORY } from "../../constants";
|
||||||
|
|
||||||
export type DownloadNodeData = {
|
export type DownloadNodeData = {
|
||||||
url: string;
|
url: string;
|
||||||
@@ -11,5 +12,5 @@ export type DownloadNode = Node<DownloadNodeData, "download">;
|
|||||||
export const downloadNodeDefaultData: DownloadNodeData = {
|
export const downloadNodeDefaultData: DownloadNodeData = {
|
||||||
editable: true,
|
editable: true,
|
||||||
label: "",
|
label: "",
|
||||||
url: "SKYVERN_DOWNLOAD_DIRECTORY",
|
url: SKYVERN_DOWNLOAD_DIRECTORY,
|
||||||
} as const;
|
} as const;
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ function SendEmailNode({ id, data }: NodeProps<SendEmailNode>) {
|
|||||||
const deleteNodeCallback = useDeleteNodeCallback();
|
const deleteNodeCallback = useDeleteNodeCallback();
|
||||||
const [label, setLabel] = useState(data.label);
|
const [label, setLabel] = useState(data.label);
|
||||||
const [inputs, setInputs] = useState({
|
const [inputs, setInputs] = useState({
|
||||||
sender: data.sender,
|
|
||||||
recipients: data.recipients,
|
recipients: data.recipients,
|
||||||
subject: data.subject,
|
subject: data.subject,
|
||||||
body: data.body,
|
body: data.body,
|
||||||
@@ -83,20 +82,6 @@ function SendEmailNode({ id, data }: NodeProps<SendEmailNode>) {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-1">
|
|
||||||
<Label className="text-xs text-slate-300">Sender</Label>
|
|
||||||
<Input
|
|
||||||
onChange={(event) => {
|
|
||||||
if (!data.editable) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
handleChange("sender", event.target.value);
|
|
||||||
}}
|
|
||||||
value={inputs.sender}
|
|
||||||
placeholder="example@gmail.com"
|
|
||||||
className="nopan"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
<Label className="text-xs text-slate-300">Recipients</Label>
|
<Label className="text-xs text-slate-300">Recipients</Label>
|
||||||
<Input
|
<Input
|
||||||
@@ -151,6 +136,7 @@ function SendEmailNode({ id, data }: NodeProps<SendEmailNode>) {
|
|||||||
}
|
}
|
||||||
handleChange("fileAttachments", event.target.value);
|
handleChange("fileAttachments", event.target.value);
|
||||||
}}
|
}}
|
||||||
|
disabled
|
||||||
className="nopan"
|
className="nopan"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,12 @@
|
|||||||
import type { Node } from "@xyflow/react";
|
import type { Node } from "@xyflow/react";
|
||||||
|
import {
|
||||||
|
EMAIL_BLOCK_SENDER,
|
||||||
|
SKYVERN_DOWNLOAD_DIRECTORY,
|
||||||
|
SMTP_HOST_PARAMETER_KEY,
|
||||||
|
SMTP_PASSWORD_PARAMETER_KEY,
|
||||||
|
SMTP_PORT_PARAMETER_KEY,
|
||||||
|
SMTP_USERNAME_PARAMETER_KEY,
|
||||||
|
} from "../../constants";
|
||||||
|
|
||||||
export type SendEmailNodeData = {
|
export type SendEmailNodeData = {
|
||||||
recipients: string;
|
recipients: string;
|
||||||
@@ -20,8 +28,12 @@ export const sendEmailNodeDefaultData: SendEmailNodeData = {
|
|||||||
recipients: "",
|
recipients: "",
|
||||||
subject: "",
|
subject: "",
|
||||||
body: "",
|
body: "",
|
||||||
fileAttachments: "",
|
fileAttachments: SKYVERN_DOWNLOAD_DIRECTORY,
|
||||||
editable: true,
|
editable: true,
|
||||||
label: "",
|
label: "",
|
||||||
sender: "",
|
sender: EMAIL_BLOCK_SENDER,
|
||||||
|
smtpHostSecretParameterKey: SMTP_HOST_PARAMETER_KEY,
|
||||||
|
smtpPortSecretParameterKey: SMTP_PORT_PARAMETER_KEY,
|
||||||
|
smtpUsernameSecretParameterKey: SMTP_USERNAME_PARAMETER_KEY,
|
||||||
|
smtpPasswordSecretParameterKey: SMTP_PASSWORD_PARAMETER_KEY,
|
||||||
} as const;
|
} as const;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import type { Node } from "@xyflow/react";
|
import type { Node } from "@xyflow/react";
|
||||||
|
import { SKYVERN_DOWNLOAD_DIRECTORY } from "../../constants";
|
||||||
|
|
||||||
export type UploadNodeData = {
|
export type UploadNodeData = {
|
||||||
path: string;
|
path: string;
|
||||||
@@ -11,5 +12,5 @@ export type UploadNode = Node<UploadNodeData, "upload">;
|
|||||||
export const uploadNodeDefaultData: UploadNodeData = {
|
export const uploadNodeDefaultData: UploadNodeData = {
|
||||||
editable: true,
|
editable: true,
|
||||||
label: "",
|
label: "",
|
||||||
path: "SKYVERN_DOWNLOAD_DIRECTORY",
|
path: SKYVERN_DOWNLOAD_DIRECTORY,
|
||||||
} as const;
|
} as const;
|
||||||
|
|||||||
@@ -3,7 +3,18 @@ import { Edge } from "@xyflow/react";
|
|||||||
import { nanoid } from "nanoid";
|
import { nanoid } from "nanoid";
|
||||||
import type { WorkflowBlock } from "../types/workflowTypes";
|
import type { WorkflowBlock } from "../types/workflowTypes";
|
||||||
import { BlockYAML, ParameterYAML } from "../types/workflowYamlTypes";
|
import { BlockYAML, ParameterYAML } from "../types/workflowYamlTypes";
|
||||||
import { REACT_FLOW_EDGE_Z_INDEX } from "./constants";
|
import {
|
||||||
|
EMAIL_BLOCK_SENDER,
|
||||||
|
REACT_FLOW_EDGE_Z_INDEX,
|
||||||
|
SMTP_HOST_AWS_KEY,
|
||||||
|
SMTP_HOST_PARAMETER_KEY,
|
||||||
|
SMTP_PASSWORD_AWS_KEY,
|
||||||
|
SMTP_PASSWORD_PARAMETER_KEY,
|
||||||
|
SMTP_PORT_AWS_KEY,
|
||||||
|
SMTP_PORT_PARAMETER_KEY,
|
||||||
|
SMTP_USERNAME_AWS_KEY,
|
||||||
|
SMTP_USERNAME_PARAMETER_KEY,
|
||||||
|
} from "./constants";
|
||||||
import { AppNode, nodeTypes } from "./nodes";
|
import { AppNode, nodeTypes } from "./nodes";
|
||||||
import { codeBlockNodeDefaultData } from "./nodes/CodeBlockNode/types";
|
import { codeBlockNodeDefaultData } from "./nodes/CodeBlockNode/types";
|
||||||
import { downloadNodeDefaultData } from "./nodes/DownloadNode/types";
|
import { downloadNodeDefaultData } from "./nodes/DownloadNode/types";
|
||||||
@@ -471,7 +482,7 @@ function getWorkflowBlock(
|
|||||||
file_attachments: node.data.fileAttachments.split(","),
|
file_attachments: node.data.fileAttachments.split(","),
|
||||||
recipients: node.data.recipients.split(","),
|
recipients: node.data.recipients.split(","),
|
||||||
subject: node.data.subject,
|
subject: node.data.subject,
|
||||||
sender: node.data.sender,
|
sender: node.data.sender === "" ? EMAIL_BLOCK_SENDER : node.data.sender,
|
||||||
smtp_host_secret_parameter_key: node.data.smtpHostSecretParameterKey,
|
smtp_host_secret_parameter_key: node.data.smtpHostSecretParameterKey,
|
||||||
smtp_port_secret_parameter_key: node.data.smtpPortSecretParameterKey,
|
smtp_port_secret_parameter_key: node.data.smtpPortSecretParameterKey,
|
||||||
smtp_username_secret_parameter_key:
|
smtp_username_secret_parameter_key:
|
||||||
@@ -657,6 +668,52 @@ function getUpdatedNodesAfterLabelUpdateForParameterKeys(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const sendEmailExpectedParameters = [
|
||||||
|
{
|
||||||
|
key: SMTP_HOST_PARAMETER_KEY,
|
||||||
|
aws_key: SMTP_HOST_AWS_KEY,
|
||||||
|
parameter_type: "aws_secret",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: SMTP_PORT_PARAMETER_KEY,
|
||||||
|
aws_key: SMTP_PORT_AWS_KEY,
|
||||||
|
parameter_type: "aws_secret",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: SMTP_USERNAME_PARAMETER_KEY,
|
||||||
|
aws_key: SMTP_USERNAME_AWS_KEY,
|
||||||
|
parameter_type: "aws_secret",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: SMTP_PASSWORD_PARAMETER_KEY,
|
||||||
|
aws_key: SMTP_PASSWORD_AWS_KEY,
|
||||||
|
parameter_type: "aws_secret",
|
||||||
|
},
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
function getAdditionalParametersForEmailBlock(
|
||||||
|
blocks: Array<BlockYAML>,
|
||||||
|
parameters: Array<ParameterYAML>,
|
||||||
|
): Array<ParameterYAML> {
|
||||||
|
const emailBlocks = blocks.filter(
|
||||||
|
(block) => block.block_type === "send_email",
|
||||||
|
);
|
||||||
|
if (emailBlocks.length === 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const sendEmailParameters = sendEmailExpectedParameters.flatMap(
|
||||||
|
(parameter) => {
|
||||||
|
const existingParameter = parameters.find((p) => p.key === parameter.key);
|
||||||
|
if (existingParameter) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return [parameter];
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return sendEmailParameters;
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
createNode,
|
createNode,
|
||||||
generateNodeData,
|
generateNodeData,
|
||||||
@@ -667,4 +724,5 @@ export {
|
|||||||
convertEchoParameters,
|
convertEchoParameters,
|
||||||
getOutputParameterKey,
|
getOutputParameterKey,
|
||||||
getUpdatedNodesAfterLabelUpdateForParameterKeys,
|
getUpdatedNodesAfterLabelUpdateForParameterKeys,
|
||||||
|
getAdditionalParametersForEmailBlock,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user