Add ability to add default values to workflow parameters (#865)
This commit is contained in:
@@ -150,7 +150,7 @@ function FileUpload({ value, onChange }: Props) {
|
|||||||
accept=".csv"
|
accept=".csv"
|
||||||
className="hidden"
|
className="hidden"
|
||||||
/>
|
/>
|
||||||
<div className="flex max-w-full gap-2 truncate">
|
<div className="flex max-w-full gap-2 px-2">
|
||||||
{uploadFileMutation.isPending && (
|
{uploadFileMutation.isPending && (
|
||||||
<ReloadIcon className="mr-2 h-4 w-4 animate-spin" />
|
<ReloadIcon className="mr-2 h-4 w-4 animate-spin" />
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import { FileInputValue, FileUpload } from "@/components/FileUpload";
|
|||||||
import { Checkbox } from "@/components/ui/checkbox";
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { CodeEditor } from "./components/CodeEditor";
|
import { CodeEditor } from "./components/CodeEditor";
|
||||||
|
import { AutoResizingTextarea } from "@/components/AutoResizingTextarea/AutoResizingTextarea";
|
||||||
|
import { Label } from "@/components/ui/label";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
type: WorkflowParameterValueType;
|
type: WorkflowParameterValueType;
|
||||||
@@ -26,7 +28,7 @@ function WorkflowParameterInput({ type, value, onChange }: Props) {
|
|||||||
|
|
||||||
if (type === "string") {
|
if (type === "string") {
|
||||||
return (
|
return (
|
||||||
<Input
|
<AutoResizingTextarea
|
||||||
value={value as string}
|
value={value as string}
|
||||||
onChange={(e) => onChange(e.target.value)}
|
onChange={(e) => onChange(e.target.value)}
|
||||||
/>
|
/>
|
||||||
@@ -55,12 +57,16 @@ function WorkflowParameterInput({ type, value, onChange }: Props) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (type === "boolean") {
|
if (type === "boolean") {
|
||||||
|
const checked = typeof value === "boolean" ? value : Boolean(value);
|
||||||
return (
|
return (
|
||||||
<Checkbox
|
<div className="flex items-center gap-2">
|
||||||
checked={value as boolean}
|
<Checkbox
|
||||||
onCheckedChange={(checked) => onChange(checked)}
|
checked={checked}
|
||||||
className="block"
|
onCheckedChange={(checked) => onChange(checked)}
|
||||||
/>
|
className="block"
|
||||||
|
/>
|
||||||
|
<Label>{value ? "True" : "False"}</Label>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,10 +45,6 @@ function WorkflowRunParameters() {
|
|||||||
? location.state.data
|
? location.state.data
|
||||||
: workflowParameters?.reduce(
|
: workflowParameters?.reduce(
|
||||||
(acc, curr) => {
|
(acc, curr) => {
|
||||||
if (curr.workflow_parameter_type === "file_url") {
|
|
||||||
acc[curr.key] = null;
|
|
||||||
return acc;
|
|
||||||
}
|
|
||||||
if (curr.workflow_parameter_type === "json") {
|
if (curr.workflow_parameter_type === "json") {
|
||||||
if (typeof curr.default_value === "string") {
|
if (typeof curr.default_value === "string") {
|
||||||
acc[curr.key] = curr.default_value;
|
acc[curr.key] = curr.default_value;
|
||||||
@@ -59,6 +55,13 @@ function WorkflowRunParameters() {
|
|||||||
return acc;
|
return acc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
curr.default_value &&
|
||||||
|
curr.workflow_parameter_type === "boolean"
|
||||||
|
) {
|
||||||
|
acc[curr.key] = Boolean(curr.default_value);
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
if (curr.default_value) {
|
if (curr.default_value) {
|
||||||
acc[curr.key] = curr.default_value;
|
acc[curr.key] = curr.default_value;
|
||||||
return acc;
|
return acc;
|
||||||
|
|||||||
@@ -73,7 +73,9 @@ function convertToParametersYAML(
|
|||||||
key: parameter.key,
|
key: parameter.key,
|
||||||
description: parameter.description || null,
|
description: parameter.description || null,
|
||||||
workflow_parameter_type: parameter.dataType,
|
workflow_parameter_type: parameter.dataType,
|
||||||
default_value: null,
|
...(parameter.defaultValue === null
|
||||||
|
? {}
|
||||||
|
: { default_value: parameter.defaultValue }),
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
@@ -98,6 +100,7 @@ export type ParametersState = Array<
|
|||||||
parameterType: "workflow";
|
parameterType: "workflow";
|
||||||
dataType: WorkflowParameterValueType;
|
dataType: WorkflowParameterValueType;
|
||||||
description?: string;
|
description?: string;
|
||||||
|
defaultValue: unknown;
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
key: string;
|
key: string;
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ function WorkflowEditor() {
|
|||||||
key: parameter.key,
|
key: parameter.key,
|
||||||
parameterType: "workflow",
|
parameterType: "workflow",
|
||||||
dataType: parameter.workflow_parameter_type,
|
dataType: parameter.workflow_parameter_type,
|
||||||
|
defaultValue: parameter.default_value,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ function WorkflowHeader({
|
|||||||
inputClassName="text-3xl"
|
inputClassName="text-3xl"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex h-full w-1/3 items-center justify-end gap-4">
|
<div className="flex h-full items-center justify-end gap-4">
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
|
|||||||
@@ -13,6 +13,10 @@ import {
|
|||||||
} from "@/components/ui/select";
|
} from "@/components/ui/select";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { ParametersState } from "../FlowRenderer";
|
import { ParametersState } from "../FlowRenderer";
|
||||||
|
import { WorkflowParameterInput } from "../../WorkflowParameterInput";
|
||||||
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
|
import { getDefaultValueForParameterType } from "../workflowEditorUtils";
|
||||||
|
import { toast } from "@/components/ui/use-toast";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
type: "workflow" | "credential";
|
type: "workflow" | "credential";
|
||||||
@@ -35,6 +39,13 @@ function WorkflowParameterAddPanel({ type, onClose, onSave }: Props) {
|
|||||||
const [collectionId, setCollectionId] = useState("");
|
const [collectionId, setCollectionId] = useState("");
|
||||||
const [parameterType, setParameterType] =
|
const [parameterType, setParameterType] =
|
||||||
useState<WorkflowParameterValueType>("string");
|
useState<WorkflowParameterValueType>("string");
|
||||||
|
const [defaultValueState, setDefaultValueState] = useState<{
|
||||||
|
hasDefaultValue: boolean;
|
||||||
|
defaultValue: unknown;
|
||||||
|
}>({
|
||||||
|
hasDefaultValue: false,
|
||||||
|
defaultValue: null,
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
@@ -56,28 +67,90 @@ function WorkflowParameterAddPanel({ type, onClose, onSave }: Props) {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{type === "workflow" && (
|
{type === "workflow" && (
|
||||||
<div className="space-y-1">
|
<>
|
||||||
<Label className="text-xs">Value Type</Label>
|
<div className="space-y-1">
|
||||||
<Select
|
<Label className="text-xs">Value Type</Label>
|
||||||
value={parameterType}
|
<Select
|
||||||
onValueChange={(value) =>
|
value={parameterType}
|
||||||
setParameterType(value as WorkflowParameterValueType)
|
onValueChange={(value) => {
|
||||||
}
|
setParameterType(value as WorkflowParameterValueType);
|
||||||
>
|
setDefaultValueState((state) => {
|
||||||
<SelectTrigger className="w-full">
|
return {
|
||||||
<SelectValue placeholder="Select a type" />
|
...state,
|
||||||
</SelectTrigger>
|
defaultValue: getDefaultValueForParameterType(
|
||||||
<SelectContent>
|
value as WorkflowParameterValueType,
|
||||||
<SelectGroup>
|
),
|
||||||
{workflowParameterTypeOptions.map((option) => (
|
};
|
||||||
<SelectItem key={option.value} value={option.value}>
|
});
|
||||||
{option.label}
|
}}
|
||||||
</SelectItem>
|
>
|
||||||
))}
|
<SelectTrigger className="w-full">
|
||||||
</SelectGroup>
|
<SelectValue placeholder="Select a type" />
|
||||||
</SelectContent>
|
</SelectTrigger>
|
||||||
</Select>
|
<SelectContent>
|
||||||
</div>
|
<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" && (
|
{type === "credential" && (
|
||||||
<>
|
<>
|
||||||
@@ -101,11 +174,32 @@ function WorkflowParameterAddPanel({ type, onClose, onSave }: Props) {
|
|||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (type === "workflow") {
|
if (type === "workflow") {
|
||||||
|
if (
|
||||||
|
parameterType === "json" &&
|
||||||
|
typeof defaultValueState.defaultValue === "string"
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
JSON.parse(defaultValueState.defaultValue);
|
||||||
|
} catch (e) {
|
||||||
|
toast({
|
||||||
|
variant: "destructive",
|
||||||
|
title: "Failed to save parameters",
|
||||||
|
description: "Invalid JSON for default value",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const defaultValue =
|
||||||
|
parameterType === "json" &&
|
||||||
|
typeof defaultValueState.defaultValue === "string"
|
||||||
|
? JSON.parse(defaultValueState.defaultValue)
|
||||||
|
: defaultValueState.defaultValue;
|
||||||
onSave({
|
onSave({
|
||||||
key,
|
key,
|
||||||
parameterType: "workflow",
|
parameterType: "workflow",
|
||||||
dataType: parameterType,
|
dataType: parameterType,
|
||||||
description,
|
description,
|
||||||
|
defaultValue: defaultValue,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (type === "credential") {
|
if (type === "credential") {
|
||||||
|
|||||||
@@ -13,6 +13,10 @@ import {
|
|||||||
} from "@/components/ui/select";
|
} from "@/components/ui/select";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { ParametersState } from "../FlowRenderer";
|
import { ParametersState } from "../FlowRenderer";
|
||||||
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
|
import { getDefaultValueForParameterType } from "../workflowEditorUtils";
|
||||||
|
import { WorkflowParameterInput } from "../../WorkflowParameterInput";
|
||||||
|
import { toast } from "@/components/ui/use-toast";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
type: "workflow" | "credential";
|
type: "workflow" | "credential";
|
||||||
@@ -56,6 +60,21 @@ function WorkflowParameterEditPanel({
|
|||||||
: "string",
|
: "string",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const [defaultValueState, setDefaultValueState] = useState<{
|
||||||
|
hasDefaultValue: boolean;
|
||||||
|
defaultValue: unknown;
|
||||||
|
}>(
|
||||||
|
initialValues.parameterType === "workflow"
|
||||||
|
? {
|
||||||
|
hasDefaultValue: initialValues.defaultValue !== null,
|
||||||
|
defaultValue: initialValues.defaultValue ?? null,
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
hasDefaultValue: false,
|
||||||
|
defaultValue: null,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<header className="flex items-center justify-between">
|
<header className="flex items-center justify-between">
|
||||||
@@ -76,28 +95,90 @@ function WorkflowParameterEditPanel({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{type === "workflow" && (
|
{type === "workflow" && (
|
||||||
<div className="space-y-1">
|
<>
|
||||||
<Label className="text-xs">Value Type</Label>
|
<div className="space-y-1">
|
||||||
<Select
|
<Label className="text-xs">Value Type</Label>
|
||||||
value={parameterType}
|
<Select
|
||||||
onValueChange={(value) =>
|
value={parameterType}
|
||||||
setParameterType(value as WorkflowParameterValueType)
|
onValueChange={(value) => {
|
||||||
}
|
setParameterType(value as WorkflowParameterValueType);
|
||||||
>
|
setDefaultValueState((state) => {
|
||||||
<SelectTrigger className="w-full">
|
return {
|
||||||
<SelectValue placeholder="Select a type" />
|
...state,
|
||||||
</SelectTrigger>
|
defaultValue: getDefaultValueForParameterType(
|
||||||
<SelectContent>
|
value as WorkflowParameterValueType,
|
||||||
<SelectGroup>
|
),
|
||||||
{workflowParameterTypeOptions.map((option) => (
|
};
|
||||||
<SelectItem key={option.value} value={option.value}>
|
});
|
||||||
{option.label}
|
}}
|
||||||
</SelectItem>
|
>
|
||||||
))}
|
<SelectTrigger className="w-full">
|
||||||
</SelectGroup>
|
<SelectValue placeholder="Select a type" />
|
||||||
</SelectContent>
|
</SelectTrigger>
|
||||||
</Select>
|
<SelectContent>
|
||||||
</div>
|
<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,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setDefaultValueState((state) => {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
defaultValue: value,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
type={parameterType}
|
||||||
|
value={defaultValueState.defaultValue}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
{type === "credential" && (
|
{type === "credential" && (
|
||||||
<>
|
<>
|
||||||
@@ -121,11 +202,32 @@ function WorkflowParameterEditPanel({
|
|||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (type === "workflow") {
|
if (type === "workflow") {
|
||||||
|
if (
|
||||||
|
parameterType === "json" &&
|
||||||
|
typeof defaultValueState.defaultValue === "string"
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
JSON.parse(defaultValueState.defaultValue);
|
||||||
|
} catch (e) {
|
||||||
|
toast({
|
||||||
|
variant: "destructive",
|
||||||
|
title: "Failed to save parameters",
|
||||||
|
description: "Invalid JSON for default value",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const defaultValue =
|
||||||
|
parameterType === "json" &&
|
||||||
|
typeof defaultValueState.defaultValue === "string"
|
||||||
|
? JSON.parse(defaultValueState.defaultValue)
|
||||||
|
: defaultValueState.defaultValue;
|
||||||
onSave({
|
onSave({
|
||||||
key,
|
key,
|
||||||
parameterType: "workflow",
|
parameterType: "workflow",
|
||||||
dataType: parameterType,
|
dataType: parameterType,
|
||||||
description,
|
description,
|
||||||
|
defaultValue: defaultValue,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (type === "credential") {
|
if (type === "credential") {
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
import Dagre from "@dagrejs/dagre";
|
import Dagre from "@dagrejs/dagre";
|
||||||
import { Edge } from "@xyflow/react";
|
import { Edge } from "@xyflow/react";
|
||||||
import { nanoid } from "nanoid";
|
import { nanoid } from "nanoid";
|
||||||
import type { WorkflowBlock } from "../types/workflowTypes";
|
import type {
|
||||||
|
WorkflowBlock,
|
||||||
|
WorkflowParameterValueType,
|
||||||
|
} from "../types/workflowTypes";
|
||||||
import { BlockYAML, ParameterYAML } from "../types/workflowYamlTypes";
|
import { BlockYAML, ParameterYAML } from "../types/workflowYamlTypes";
|
||||||
import {
|
import {
|
||||||
EMAIL_BLOCK_SENDER,
|
EMAIL_BLOCK_SENDER,
|
||||||
@@ -764,6 +767,29 @@ function getLabelForExistingNode(label: string, existingLabels: Array<string>) {
|
|||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getDefaultValueForParameterType(
|
||||||
|
parameterType: WorkflowParameterValueType,
|
||||||
|
): unknown {
|
||||||
|
switch (parameterType) {
|
||||||
|
case "json": {
|
||||||
|
return "{}";
|
||||||
|
}
|
||||||
|
case "string": {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
case "boolean": {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
case "float":
|
||||||
|
case "integer": {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
case "file_url": {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
createNode,
|
createNode,
|
||||||
generateNodeData,
|
generateNodeData,
|
||||||
@@ -778,4 +804,5 @@ export {
|
|||||||
getLabelForExistingNode,
|
getLabelForExistingNode,
|
||||||
isOutputParameterKey,
|
isOutputParameterKey,
|
||||||
getBlockNameOfOutputParameterKey,
|
getBlockNameOfOutputParameterKey,
|
||||||
|
getDefaultValueForParameterType,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ export type ParameterYAMLBase = {
|
|||||||
export type WorkflowParameterYAML = ParameterYAMLBase & {
|
export type WorkflowParameterYAML = ParameterYAMLBase & {
|
||||||
parameter_type: "workflow";
|
parameter_type: "workflow";
|
||||||
workflow_parameter_type: string;
|
workflow_parameter_type: string;
|
||||||
default_value: string | null;
|
default_value?: unknown;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type BitwardenLoginCredentialParameterYAML = ParameterYAMLBase & {
|
export type BitwardenLoginCredentialParameterYAML = ParameterYAMLBase & {
|
||||||
|
|||||||
Reference in New Issue
Block a user