Refactoring: merge WorkflowParameterEditPanel and WorkflowParameterAddPanel (#3750)

This commit is contained in:
Stanislav Novosad
2025-10-23 11:02:41 -06:00
committed by GitHub
parent a2cef7985d
commit 117b2469e4
4 changed files with 69 additions and 669 deletions

View File

@@ -1,615 +0,0 @@
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { ScrollArea, ScrollAreaViewport } from "@/components/ui/scroll-area";
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { toast } from "@/components/ui/use-toast";
import CloudContext from "@/store/CloudContext";
import { Cross2Icon } from "@radix-ui/react-icons";
import { useContext, useState } from "react";
import { CredentialParameterSourceSelector } from "../../components/CredentialParameterSourceSelector";
import { SourceParameterKeySelector } from "../../components/SourceParameterKeySelector";
import {
WorkflowEditorParameterType,
WorkflowParameterValueType,
} from "../../types/workflowTypes";
import { WorkflowParameterInput } from "../../WorkflowParameterInput";
import { ParametersState } from "../types";
import { getDefaultValueForParameterType } from "../workflowEditorUtils";
import { validateBitwardenLoginCredential } from "./util";
import { HelpTooltip } from "@/components/HelpTooltip";
type Props = {
type: WorkflowEditorParameterType;
onClose: () => void;
onSave: (value: ParametersState[number]) => void;
};
const workflowParameterTypeOptions = [
{ label: "string", value: WorkflowParameterValueType.String },
{ label: "float", value: WorkflowParameterValueType.Float },
{ label: "integer", value: WorkflowParameterValueType.Integer },
{ label: "boolean", value: WorkflowParameterValueType.Boolean },
{ label: "file", value: WorkflowParameterValueType.FileURL },
{ label: "JSON", value: WorkflowParameterValueType.JSON },
];
function header(type: WorkflowEditorParameterType) {
if (type === "workflow") {
return "Add Input Parameter";
}
if (type === "credential") {
return "Add Credential Parameter";
}
if (type === "secret") {
return "Add Secret Parameter";
}
if (type === "creditCardData") {
return "Add Credit Card Parameter";
}
return "Add Context Parameter";
}
function WorkflowParameterAddPanel({ type, onClose, onSave }: Props) {
const reservedKeys = ["current_item", "current_value", "current_index"];
const isCloud = useContext(CloudContext);
const [key, setKey] = useState("");
const hasWhitespace = /\s/.test(key);
const [urlParameterKey, setUrlParameterKey] = useState("");
const [description, setDescription] = useState("");
const [bitwardenCollectionId, setBitwardenCollectionId] = useState("");
const [bitwardenLoginCredentialItemId, setBitwardenLoginCredentialItemId] =
useState("");
const [parameterType, setParameterType] =
useState<WorkflowParameterValueType>("string");
const [defaultValueState, setDefaultValueState] = useState<{
hasDefaultValue: boolean;
defaultValue: unknown;
}>({
hasDefaultValue: false,
defaultValue: null,
});
const [sourceParameterKey, setSourceParameterKey] = useState<
string | undefined
>(undefined);
const [credentialType, setCredentialType] = useState<
"bitwarden" | "skyvern" | "onepassword" | "azurevault"
>("skyvern");
const [vaultId, setVaultId] = useState("");
const [itemId, setItemId] = useState("");
const [identityKey, setIdentityKey] = useState("");
const [identityFields, setIdentityFields] = useState("");
const [sensitiveInformationItemId, setSensitiveInformationItemId] =
useState("");
const [credentialId, setCredentialId] = useState("");
const [azureVaultName, setAzureVaultName] = useState("");
const [azureUsernameKey, setAzureUsernameKey] = useState("");
const [azurePasswordKey, setAzurePasswordKey] = useState("");
const [azureTotpSecretKey, setAzureTotpKey] = useState("");
return (
<ScrollArea>
<ScrollAreaViewport className="max-h-[500px]">
<div className="space-y-4 p-1 px-4">
<header className="flex items-center justify-between">
<span>{header(type)}</span>
<Cross2Icon className="h-6 w-6 cursor-pointer" onClick={onClose} />
</header>
<div className="space-y-1">
<Label className="text-xs text-slate-300">Key</Label>
<Input value={key} onChange={(e) => setKey(e.target.value)} />
{hasWhitespace && (
<p className="text-xs text-destructive">
Spaces are not allowed, consider using _
</p>
)}
</div>
<div className="space-y-1">
<Label className="text-xs text-slate-300">Description</Label>
<Input
value={description}
onChange={(e) => setDescription(e.target.value)}
/>
</div>
{type === "workflow" && (
<>
<div className="space-y-1">
<Label className="text-xs">Value Type</Label>
<Select
value={parameterType}
onValueChange={(value) => {
setParameterType(value as WorkflowParameterValueType);
setDefaultValueState((state) => {
return {
...state,
defaultValue: getDefaultValueForParameterType(
value as WorkflowParameterValueType,
),
};
});
}}
>
<SelectTrigger className="w-full">
<SelectValue placeholder="Select a type" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
{workflowParameterTypeOptions.map((option) => (
<SelectItem key={option.value} value={option.value}>
{option.label}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
</div>
<div className="space-y-4">
<div className="flex items-center gap-2">
<Checkbox
checked={defaultValueState.hasDefaultValue}
onCheckedChange={(checked) => {
if (!checked) {
setDefaultValueState({
hasDefaultValue: false,
defaultValue: null,
});
return;
}
setDefaultValueState({
hasDefaultValue: true,
defaultValue:
getDefaultValueForParameterType(parameterType),
});
}}
/>
<Label className="text-xs text-slate-300">
Use Default Value
</Label>
</div>
{defaultValueState.hasDefaultValue && (
<WorkflowParameterInput
onChange={(value) => {
if (
parameterType === "file_url" &&
typeof value === "object" &&
value &&
"s3uri" in value
) {
setDefaultValueState((state) => {
return {
...state,
defaultValue: value.s3uri,
};
});
return;
}
setDefaultValueState((state) => {
return {
...state,
defaultValue: value,
};
});
}}
type={parameterType}
value={defaultValueState.defaultValue}
/>
)}
</div>
</>
)}
{type === "credential" && (
<>
<div className="space-y-1">
<Label className="text-xs text-slate-300">
Credential Type
</Label>
<Select
value={credentialType}
onValueChange={(value) => {
setCredentialType(
value as
| "bitwarden"
| "skyvern"
| "onepassword"
| "azurevault",
);
}}
>
<SelectTrigger className="w-full">
<SelectValue placeholder="Select a type" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectItem value="skyvern">Skyvern</SelectItem>
<SelectItem value="bitwarden">Bitwarden</SelectItem>
<SelectItem value="onepassword">1Password</SelectItem>
<SelectItem value="azurevault">Azure Vault</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</div>
</>
)}
{type === "credential" && credentialType === "bitwarden" && (
<>
<div className="space-y-1">
<Label className="text-xs text-slate-300">
URL Parameter Key
</Label>
<Input
value={urlParameterKey}
onChange={(e) => setUrlParameterKey(e.target.value)}
/>
</div>
<div className="space-y-1">
<Label className="text-xs text-slate-300">Collection ID</Label>
<Input
value={bitwardenCollectionId}
onChange={(e) => setBitwardenCollectionId(e.target.value)}
/>
</div>
<div className="space-y-1">
<Label className="text-xs text-slate-300">Item ID</Label>
<Input
value={bitwardenLoginCredentialItemId}
onChange={(e) =>
setBitwardenLoginCredentialItemId(e.target.value)
}
/>
</div>
</>
)}
{type === "credential" && credentialType === "onepassword" && (
<>
<div className="space-y-1">
<div className="flex gap-2">
<Label className="text-xs text-slate-300">Vault ID</Label>
<HelpTooltip content="You can find the Vault ID and Item ID in the URL when viewing the item in 1Password on the web." />
</div>
<Input
value={vaultId}
onChange={(e) => setVaultId(e.target.value)}
/>
</div>
<div className="space-y-1">
<div className="flex gap-2">
<Label className="text-xs text-slate-300">Item ID</Label>
<HelpTooltip content="Supports all 1Password item types: Logins, Passwords, Credit Cards, Secure Notes, and more." />
</div>
<Input
value={itemId}
onChange={(e) => setItemId(e.target.value)}
/>
</div>
<div className="rounded-md bg-slate-800 p-2">
<div className="space-y-1 text-xs text-slate-400">
* Credit Cards: Due to a 1Password limitation, add the
expiration date as a separate text field named "Expire Date"
in the format MM/YYYY (e.g. 09/2027).
</div>
</div>
</>
)}
{type === "credential" && credentialType === "azurevault" && (
<>
<div className="space-y-1">
<Label className="text-xs text-slate-300">Vault Name</Label>
<Input
value={azureVaultName}
onChange={(e) => setAzureVaultName(e.target.value)}
/>
</div>
<div className="space-y-1">
<Label className="text-xs text-slate-300">Username Key</Label>
<Input
autoComplete="off"
value={azureUsernameKey}
onChange={(e) => setAzureUsernameKey(e.target.value)}
/>
</div>
<div className="space-y-1">
<Label className="text-xs text-slate-300">Password Key</Label>
<Input
value={azurePasswordKey}
onChange={(e) => setAzurePasswordKey(e.target.value)}
/>
</div>
<div className="space-y-1">
<Label className="text-xs text-slate-300">
TOTP Secret Key
</Label>
<Input
value={azureTotpSecretKey}
onChange={(e) => setAzureTotpKey(e.target.value)}
/>
</div>
</>
)}
{type === "context" && (
<div className="space-y-1">
<Label className="text-xs text-slate-300">Source Parameter</Label>
<SourceParameterKeySelector
value={sourceParameterKey}
onChange={setSourceParameterKey}
/>
</div>
)}
{type === "secret" && (
<>
<div className="space-y-1">
<Label className="text-xs text-slate-300">Identity Key</Label>
<Input
value={identityKey}
onChange={(e) => setIdentityKey(e.target.value)}
/>
</div>
<div className="space-y-1">
<Label className="text-xs text-slate-300">
Identity Fields
</Label>
<Input
value={identityFields}
onChange={(e) => setIdentityFields(e.target.value)}
/>
</div>
<div className="space-y-1">
<Label className="text-xs text-slate-300">Collection ID</Label>
<Input
value={bitwardenCollectionId}
onChange={(e) => setBitwardenCollectionId(e.target.value)}
/>
</div>
</>
)}
{type === "creditCardData" && (
<>
<div className="space-y-1">
<Label className="text-xs text-slate-300">Collection ID</Label>
<Input
value={bitwardenCollectionId}
onChange={(e) => setBitwardenCollectionId(e.target.value)}
/>
</div>
<div className="space-y-1">
<Label className="text-xs text-slate-300">Item ID</Label>
<Input
value={sensitiveInformationItemId}
onChange={(e) =>
setSensitiveInformationItemId(e.target.value)
}
/>
</div>
</>
)}
{
// temporarily cloud only
type === "credential" &&
credentialType === "skyvern" &&
isCloud && (
<div className="space-y-1">
<Label className="text-xs text-slate-300">Credential</Label>
<CredentialParameterSourceSelector
value={credentialId}
onChange={(value) => setCredentialId(value)}
/>
</div>
)
}
<div className="flex justify-end">
<Button
onClick={() => {
if (!key) {
toast({
variant: "destructive",
title: "Failed to add parameter",
description: "Key is required",
});
return;
}
if (hasWhitespace) {
toast({
variant: "destructive",
title: "Failed to add parameter",
description: "Key cannot contain whitespaces",
});
return;
}
if (reservedKeys.includes(key)) {
toast({
variant: "destructive",
title: "Failed to add parameter",
description: `${key} is reserved, please use another key`,
});
return;
}
if (type === "workflow") {
if (
parameterType === "json" &&
typeof defaultValueState.defaultValue === "string"
) {
try {
JSON.parse(defaultValueState.defaultValue);
} catch (e) {
toast({
variant: "destructive",
title: "Failed to add parameter",
description: "Invalid JSON for default value",
});
return;
}
}
const defaultValue =
parameterType === "json" &&
typeof defaultValueState.defaultValue === "string"
? JSON.parse(defaultValueState.defaultValue)
: defaultValueState.defaultValue;
onSave({
key,
parameterType: "workflow",
dataType: parameterType,
description,
defaultValue: defaultValueState.hasDefaultValue
? defaultValue
: null,
});
}
if (type === "credential" && credentialType === "bitwarden") {
const errorMessage = validateBitwardenLoginCredential(
bitwardenCollectionId,
bitwardenLoginCredentialItemId,
urlParameterKey,
);
if (errorMessage) {
toast({
variant: "destructive",
title: "Failed to save parameter",
description: errorMessage,
});
return;
}
onSave({
key,
parameterType: "credential",
collectionId:
bitwardenCollectionId === ""
? null
: bitwardenCollectionId,
itemId:
bitwardenLoginCredentialItemId === ""
? null
: bitwardenLoginCredentialItemId,
urlParameterKey:
urlParameterKey === "" ? null : urlParameterKey,
description,
});
}
if (type === "credential" && credentialType === "onepassword") {
if (vaultId.trim() === "" || itemId.trim() === "") {
toast({
variant: "destructive",
title: "Failed to add parameter",
description: "Vault ID and Item ID are required",
});
return;
}
onSave({
key,
parameterType: "onepassword",
vaultId,
itemId,
description,
});
}
if (type === "credential" && credentialType === "azurevault") {
if (
azureVaultName.trim() === "" ||
azureUsernameKey.trim() === "" ||
azurePasswordKey.trim() === ""
) {
toast({
variant: "destructive",
title: "Failed to add parameter",
description:
"Azure Vault Name, Username Key and Password Key are required",
});
return;
}
onSave({
key,
parameterType: "credential",
vaultName: azureVaultName,
usernameKey: azureUsernameKey,
passwordKey: azurePasswordKey,
totpSecretKey:
azureTotpSecretKey === "" ? null : azureTotpSecretKey,
description: description,
});
}
if (type === "secret" || type === "creditCardData") {
if (!bitwardenCollectionId) {
toast({
variant: "destructive",
title: "Failed to save parameter",
description: "Collection ID is required",
});
return;
}
}
if (type === "secret") {
onSave({
key,
parameterType: "secret",
collectionId: bitwardenCollectionId,
identityFields: identityFields
.split(",")
.filter((s) => s.length > 0)
.map((field) => field.trim()),
identityKey,
description,
});
}
if (type === "creditCardData") {
onSave({
key,
parameterType: "creditCardData",
collectionId: bitwardenCollectionId,
itemId: sensitiveInformationItemId,
description,
});
}
if (type === "context") {
if (!sourceParameterKey) {
toast({
variant: "destructive",
title: "Failed to add parameter",
description: "Source parameter key is required",
});
return;
}
onSave({
key,
parameterType: "context",
sourceParameterKey,
description,
});
}
if (type === "credential" && credentialType === "skyvern") {
if (!credentialId) {
toast({
variant: "destructive",
title: "Failed to add parameter",
description: "Credential is required",
});
return;
}
onSave({
key,
parameterType: "credential",
credentialId,
description,
});
}
}}
>
Save
</Button>
</div>
</div>
</ScrollAreaViewport>
</ScrollArea>
);
}
export { WorkflowParameterAddPanel };

View File

@@ -37,7 +37,7 @@ type Props = {
type: WorkflowEditorParameterType;
onClose: () => void;
onSave: (value: ParametersState[number]) => void;
initialValues: ParametersState[number];
initialValues?: ParametersState[number];
};
const workflowParameterTypeOptions = [
@@ -50,20 +50,21 @@ const workflowParameterTypeOptions = [
{ label: "JSON", value: WorkflowParameterValueType.JSON },
];
function header(type: WorkflowEditorParameterType) {
function header(type: WorkflowEditorParameterType, isEdit: boolean) {
const prefix = isEdit ? "Edit" : "Add";
if (type === "workflow") {
return "Edit Input Parameter";
return `${prefix} Input Parameter`;
}
if (type === "credential") {
return "Edit Credential Parameter";
return `${prefix} Credential Parameter`;
}
if (type === "secret") {
return "Edit Secret Parameter";
return `${prefix} Secret Parameter`;
}
if (type === "creditCardData") {
return "Edit Credit Card Parameter";
return `${prefix} Credit Card Parameter`;
}
return "Edit Context Parameter";
return `${prefix} Context Parameter`;
}
function WorkflowParameterEditPanel({
@@ -72,20 +73,22 @@ function WorkflowParameterEditPanel({
onSave,
initialValues,
}: Props) {
const reservedKeys = ["current_item", "current_value", "current_index"];
const isCloud = useContext(CloudContext);
const [key, setKey] = useState(initialValues.key);
const isEditMode = !!initialValues;
const [key, setKey] = useState(initialValues?.key ?? "");
const hasWhitespace = /\s/.test(key);
const isBitwardenCredential =
initialValues.parameterType === "credential" &&
initialValues?.parameterType === "credential" &&
parameterIsBitwardenCredential(initialValues);
const isSkyvernCredential =
initialValues.parameterType === "credential" &&
initialValues?.parameterType === "credential" &&
parameterIsSkyvernCredential(initialValues);
const isOnePasswordCredential =
initialValues.parameterType === "onepassword" &&
initialValues?.parameterType === "onepassword" &&
parameterIsOnePasswordCredential(initialValues);
const isAzureVaultCredential =
initialValues.parameterType === "credential" &&
initialValues?.parameterType === "credential" &&
parameterIsAzureVaultCredential(initialValues);
const [credentialType, setCredentialType] = useState<
"bitwarden" | "skyvern" | "onepassword" | "azurevault"
@@ -99,21 +102,21 @@ function WorkflowParameterEditPanel({
: "skyvern",
);
const [urlParameterKey, setUrlParameterKey] = useState(
isBitwardenCredential ? initialValues.urlParameterKey ?? "" : "",
isBitwardenCredential ? initialValues?.urlParameterKey ?? "" : "",
);
const [description, setDescription] = useState(
initialValues.description ?? "",
initialValues?.description ?? "",
);
const [collectionId, setCollectionId] = useState(
const [bitwardenCollectionId, setBitwardenCollectionId] = useState(
isBitwardenCredential ||
initialValues.parameterType === "secret" ||
initialValues.parameterType === "creditCardData"
? initialValues.collectionId ?? ""
initialValues?.parameterType === "secret" ||
initialValues?.parameterType === "creditCardData"
? initialValues?.collectionId ?? ""
: "",
);
const [parameterType, setParameterType] =
useState<WorkflowParameterValueType>(
initialValues.parameterType === "workflow"
initialValues?.parameterType === "workflow"
? initialValues.dataType
: "string",
);
@@ -122,7 +125,7 @@ function WorkflowParameterEditPanel({
hasDefaultValue: boolean;
defaultValue: unknown;
}>(
initialValues.parameterType === "workflow"
initialValues?.parameterType === "workflow"
? {
hasDefaultValue: initialValues.defaultValue !== null,
defaultValue: initialValues.defaultValue ?? null,
@@ -136,23 +139,23 @@ function WorkflowParameterEditPanel({
const [sourceParameterKey, setSourceParameterKey] = useState<
string | undefined
>(
initialValues.parameterType === "context"
initialValues?.parameterType === "context"
? initialValues.sourceParameterKey
: undefined,
);
const [identityKey, setIdentityKey] = useState(
initialValues.parameterType === "secret" ? initialValues.identityKey : "",
initialValues?.parameterType === "secret" ? initialValues.identityKey : "",
);
const [identityFields, setIdentityFields] = useState(
initialValues.parameterType === "secret"
initialValues?.parameterType === "secret"
? initialValues.identityFields.join(", ")
: "",
);
const [itemId, setItemId] = useState(
initialValues.parameterType === "creditCardData"
const [sensitiveInformationItemId, setSensitiveInformationItemId] = useState(
initialValues?.parameterType === "creditCardData"
? initialValues.itemId
: "",
);
@@ -160,7 +163,7 @@ function WorkflowParameterEditPanel({
const [credentialId, setCredentialId] = useState(
isSkyvernCredential ? initialValues.credentialId : "",
);
const [vaultId, setVaultId] = useState(
const [opVaultId, setOpVaultId] = useState(
isOnePasswordCredential ? initialValues.vaultId : "",
);
const [opItemId, setOpItemId] = useState(
@@ -168,7 +171,7 @@ function WorkflowParameterEditPanel({
);
const [bitwardenLoginCredentialItemId, setBitwardenLoginCredentialItemId] =
useState(isBitwardenCredential ? initialValues.itemId ?? "" : "");
useState(isBitwardenCredential ? initialValues?.itemId ?? "" : "");
const [azureVaultName, setAzureVaultName] = useState(
isAzureVaultCredential ? initialValues.vaultName : "",
@@ -188,7 +191,7 @@ function WorkflowParameterEditPanel({
<ScrollAreaViewport className="max-h-[500px]">
<div className="space-y-4 p-1 px-4">
<header className="flex items-center justify-between">
<span>{header(type)}</span>
<span>{header(type, isEditMode)}</span>
<Cross2Icon className="h-6 w-6 cursor-pointer" onClick={onClose} />
</header>
<div className="space-y-1">
@@ -274,7 +277,7 @@ function WorkflowParameterEditPanel({
setDefaultValueState((state) => {
return {
...state,
defaultValue: value,
defaultValue: value.s3uri,
};
});
return;
@@ -340,8 +343,8 @@ function WorkflowParameterEditPanel({
<div className="space-y-1">
<Label className="text-xs text-slate-300">Collection ID</Label>
<Input
value={collectionId}
onChange={(e) => setCollectionId(e.target.value)}
value={bitwardenCollectionId}
onChange={(e) => setBitwardenCollectionId(e.target.value)}
/>
</div>
<div className="space-y-1">
@@ -363,8 +366,8 @@ function WorkflowParameterEditPanel({
<HelpTooltip content="You can find the Vault ID and Item ID in the URL when viewing the item in 1Password on the web." />
</div>
<Input
value={vaultId}
onChange={(e) => setVaultId(e.target.value)}
value={opVaultId}
onChange={(e) => setOpVaultId(e.target.value)}
/>
</div>
<div className="space-y-1">
@@ -451,8 +454,8 @@ function WorkflowParameterEditPanel({
<div className="space-y-1">
<Label className="text-xs text-slate-300">Collection ID</Label>
<Input
value={collectionId}
onChange={(e) => setCollectionId(e.target.value)}
value={bitwardenCollectionId}
onChange={(e) => setBitwardenCollectionId(e.target.value)}
/>
</div>
</>
@@ -462,15 +465,17 @@ function WorkflowParameterEditPanel({
<div className="space-y-1">
<Label className="text-xs text-slate-300">Collection ID</Label>
<Input
value={collectionId}
onChange={(e) => setCollectionId(e.target.value)}
value={bitwardenCollectionId}
onChange={(e) => setBitwardenCollectionId(e.target.value)}
/>
</div>
<div className="space-y-1">
<Label className="text-xs text-slate-300">Item ID</Label>
<Input
value={itemId}
onChange={(e) => setItemId(e.target.value)}
value={sensitiveInformationItemId}
onChange={(e) =>
setSensitiveInformationItemId(e.target.value)
}
/>
</div>
</>
@@ -509,6 +514,14 @@ function WorkflowParameterEditPanel({
});
return;
}
if (!isEditMode && reservedKeys.includes(key)) {
toast({
variant: "destructive",
title: "Failed to add parameter",
description: `${key} is reserved, please use another key`,
});
return;
}
if (type === "workflow") {
if (
parameterType === "json" &&
@@ -542,7 +555,7 @@ function WorkflowParameterEditPanel({
}
if (type === "credential" && credentialType === "bitwarden") {
const errorMessage = validateBitwardenLoginCredential(
collectionId,
bitwardenCollectionId,
bitwardenLoginCredentialItemId,
urlParameterKey,
);
@@ -563,12 +576,15 @@ function WorkflowParameterEditPanel({
: bitwardenLoginCredentialItemId,
urlParameterKey:
urlParameterKey === "" ? null : urlParameterKey,
collectionId: collectionId === "" ? null : collectionId,
collectionId:
bitwardenCollectionId === ""
? null
: bitwardenCollectionId,
description,
});
}
if (type === "credential" && credentialType === "onepassword") {
if (vaultId.trim() === "" || opItemId.trim() === "") {
if (opVaultId.trim() === "" || opItemId.trim() === "") {
toast({
variant: "destructive",
title: "Failed to save parameter",
@@ -579,7 +595,7 @@ function WorkflowParameterEditPanel({
onSave({
key,
parameterType: "onepassword",
vaultId,
vaultId: opVaultId,
itemId: opItemId,
description,
});
@@ -610,7 +626,7 @@ function WorkflowParameterEditPanel({
});
}
if (type === "secret" || type === "creditCardData") {
if (!collectionId) {
if (!bitwardenCollectionId) {
toast({
variant: "destructive",
title: "Failed to save parameter",
@@ -623,7 +639,7 @@ function WorkflowParameterEditPanel({
onSave({
key,
parameterType: "secret",
collectionId,
collectionId: bitwardenCollectionId,
identityFields: identityFields
.split(",")
.filter((s) => s.length > 0)
@@ -636,8 +652,8 @@ function WorkflowParameterEditPanel({
onSave({
key,
parameterType: "creditCardData",
collectionId,
itemId,
collectionId: bitwardenCollectionId,
itemId: sensitiveInformationItemId,
description,
});
}

View File

@@ -1,5 +1,4 @@
import { useState } from "react";
import { WorkflowParameterAddPanel } from "./WorkflowParameterAddPanel";
import { ParametersState } from "../types";
import { WorkflowParameterEditPanel } from "./WorkflowParameterEditPanel";
import { MixerVerticalIcon, PlusIcon } from "@radix-ui/react-icons";
@@ -242,7 +241,7 @@ function WorkflowParametersPanel({ onMouseDownCapture }: Props) {
>
{operationPanelState.operation === "add" && (
<div className="w-80 rounded-xl border border-slate-700 bg-slate-950 p-5 px-2 shadow-xl">
<WorkflowParameterAddPanel
<WorkflowParameterEditPanel
type={operationPanelState.type}
onSave={(parameter) => {
setWorkflowParameters([...workflowParameters, parameter]);

View File

@@ -1,6 +1,6 @@
import { defineConfig } from 'vitest/config'
import react from '@vitejs/plugin-react-swc'
import path from 'path'
import { defineConfig } from "vitest/config";
import react from "@vitejs/plugin-react-swc";
import path from "path";
export default defineConfig({
plugins: [react()],
@@ -9,7 +9,7 @@ export default defineConfig({
},
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
"@": path.resolve(__dirname, "./src"),
},
},
})
});