more polish on workflows
Some checks failed
CI / Rustfmt (push) Failing after 25s
CI / Clippy (push) Failing after 2m3s
CI / Cargo Audit & Deny (push) Successful in 33s
CI / Web Blocking Checks (push) Failing after 26s
CI / Security Blocking Checks (push) Successful in 8s
CI / Security Advisory Checks (push) Has been cancelled
CI / Web Advisory Checks (push) Has been cancelled
CI / Tests (push) Has been cancelled

This commit is contained in:
2026-03-11 11:21:28 -05:00
parent a7ed135af2
commit b5d6bb2243
25 changed files with 366 additions and 322 deletions

View File

@@ -63,7 +63,9 @@ const ARROW_LENGTH = 12;
const ARROW_HALF_WIDTH = 5;
const ARROW_DIRECTION_LOOKBACK_PX = 10;
const ARROW_DIRECTION_SAMPLES = 48;
const ARROW_SHAFT_OVERLAP_PX = 2;
// Keep a small amount of shaft under the arrowhead so sample-based trimming
// does not leave a visible gap on simple bezier edges without waypoints.
const ARROW_SHAFT_OVERLAP_PX = 4;
/** Color for each edge type (alias for shared constant) */
const EDGE_COLORS = EDGE_TYPE_COLORS;

View File

@@ -1,11 +1,29 @@
import { useState } from "react";
import { Pencil, Plus, X, LogIn, LogOut } from "lucide-react";
import {
Pencil,
Plus,
X,
LogIn,
LogOut,
SlidersHorizontal,
} from "lucide-react";
import SchemaBuilder from "@/components/common/SchemaBuilder";
import type { ParamDefinition } from "@/types/workflow";
import type { CancellationPolicy, ParamDefinition } from "@/types/workflow";
import { CANCELLATION_POLICY_LABELS } from "@/types/workflow";
interface WorkflowInputsPanelProps {
label: string;
version: string;
description: string;
tags: string[];
cancellationPolicy: CancellationPolicy;
parameters: Record<string, ParamDefinition>;
output: Record<string, ParamDefinition>;
onLabelChange: (label: string) => void;
onVersionChange: (version: string) => void;
onDescriptionChange: (description: string) => void;
onTagsChange: (tags: string[]) => void;
onCancellationPolicyChange: (policy: CancellationPolicy) => void;
onParametersChange: (parameters: Record<string, ParamDefinition>) => void;
onOutputChange: (output: Record<string, ParamDefinition>) => void;
}
@@ -82,8 +100,18 @@ function ParamSummaryList({
}
export default function WorkflowInputsPanel({
label,
version,
description,
tags,
cancellationPolicy,
parameters,
output,
onLabelChange,
onVersionChange,
onDescriptionChange,
onTagsChange,
onCancellationPolicyChange,
onParametersChange,
onOutputChange,
}: WorkflowInputsPanelProps) {
@@ -123,8 +151,103 @@ export default function WorkflowInputsPanel({
<>
<div className="flex flex-col h-full overflow-hidden">
<div className="flex-1 overflow-y-auto p-3 space-y-4">
{/* Input Parameters */}
<div>
<div className="flex items-center gap-1.5 mb-2">
<SlidersHorizontal className="w-3.5 h-3.5 text-blue-500" />
<h4 className="text-xs font-semibold text-gray-600 uppercase tracking-wider">
Workflow
</h4>
</div>
<div className="space-y-2.5 rounded-lg border border-gray-200 bg-white p-3">
<div>
<label className="block text-[11px] font-medium text-gray-600 mb-1">
Label
</label>
<input
type="text"
value={label}
onChange={(e) => onLabelChange(e.target.value)}
className="w-full px-2.5 py-2 border border-gray-300 rounded-md text-sm focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
placeholder="Workflow Label"
/>
</div>
<div>
<label className="block text-[11px] font-medium text-gray-600 mb-1">
Description
</label>
<input
type="text"
value={description}
onChange={(e) => onDescriptionChange(e.target.value)}
className="w-full px-2.5 py-2 border border-gray-300 rounded-md text-sm focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
placeholder="Workflow description"
/>
</div>
<div className="grid grid-cols-1 gap-2">
<div>
<label className="block text-[11px] font-medium text-gray-600 mb-1">
Version
</label>
<input
type="text"
value={version}
onChange={(e) => onVersionChange(e.target.value)}
className="w-full px-2.5 py-2 border border-gray-300 rounded-md text-sm font-mono focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
placeholder="1.0.0"
/>
</div>
<div>
<label className="block text-[11px] font-medium text-gray-600 mb-1">
Tags
</label>
<input
type="text"
value={tags.join(", ")}
onChange={(e) =>
onTagsChange(
e.target.value
.split(",")
.map((tag) => tag.trim())
.filter(Boolean),
)
}
className="w-full px-2.5 py-2 border border-gray-300 rounded-md text-sm focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
placeholder="tag-one, tag-two"
/>
</div>
</div>
<div>
<label className="block text-[11px] font-medium text-gray-600 mb-1">
Cancellation Policy
</label>
<select
value={cancellationPolicy}
onChange={(e) =>
onCancellationPolicyChange(
e.target.value as CancellationPolicy,
)
}
className="w-full px-2.5 py-2 border border-gray-300 rounded-md text-sm text-gray-700 focus:ring-2 focus:ring-blue-500 focus:border-blue-500 bg-white"
title="Controls how running tasks behave when the workflow is cancelled"
>
{Object.entries(CANCELLATION_POLICY_LABELS).map(
([value, optionLabel]) => (
<option key={value} value={value}>
{optionLabel}
</option>
),
)}
</select>
</div>
</div>
</div>
{/* Input Parameters */}
<div className="border-t border-gray-200 pt-3">
<div className="flex items-center justify-between mb-1.5">
<div className="flex items-center gap-1.5">
<LogIn className="w-3.5 h-3.5 text-green-500" />