mirror of
https://github.com/soconnor0919/hristudio.git
synced 2026-02-05 07:56:30 -05:00
Pre-conf work 2025
This commit is contained in:
@@ -1,8 +1,15 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
Activity, Bot, CheckCircle,
|
||||
Circle, Clock, GitBranch, Play, Target, Users
|
||||
Activity,
|
||||
Bot,
|
||||
CheckCircle,
|
||||
Circle,
|
||||
Clock,
|
||||
GitBranch,
|
||||
Play,
|
||||
Target,
|
||||
Users,
|
||||
} from "lucide-react";
|
||||
import { Badge } from "~/components/ui/badge";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
|
||||
@@ -13,10 +20,14 @@ interface TrialProgressProps {
|
||||
steps: Array<{
|
||||
id: string;
|
||||
name: string;
|
||||
type: "wizard_action" | "robot_action" | "parallel_steps" | "conditional_branch";
|
||||
type:
|
||||
| "wizard_action"
|
||||
| "robot_action"
|
||||
| "parallel_steps"
|
||||
| "conditional_branch";
|
||||
description?: string;
|
||||
duration?: number;
|
||||
parameters?: any;
|
||||
parameters?: Record<string, unknown>;
|
||||
}>;
|
||||
currentStepIndex: number;
|
||||
trialStatus: "scheduled" | "in_progress" | "completed" | "aborted" | "failed";
|
||||
@@ -29,7 +40,7 @@ const stepTypeConfig = {
|
||||
color: "blue",
|
||||
bgColor: "bg-blue-100",
|
||||
textColor: "text-blue-600",
|
||||
borderColor: "border-blue-300"
|
||||
borderColor: "border-blue-300",
|
||||
},
|
||||
robot_action: {
|
||||
label: "Robot",
|
||||
@@ -37,7 +48,7 @@ const stepTypeConfig = {
|
||||
color: "green",
|
||||
bgColor: "bg-green-100",
|
||||
textColor: "text-green-600",
|
||||
borderColor: "border-green-300"
|
||||
borderColor: "border-green-300",
|
||||
},
|
||||
parallel_steps: {
|
||||
label: "Parallel",
|
||||
@@ -45,7 +56,7 @@ const stepTypeConfig = {
|
||||
color: "purple",
|
||||
bgColor: "bg-purple-100",
|
||||
textColor: "text-purple-600",
|
||||
borderColor: "border-purple-300"
|
||||
borderColor: "border-purple-300",
|
||||
},
|
||||
conditional_branch: {
|
||||
label: "Branch",
|
||||
@@ -53,17 +64,21 @@ const stepTypeConfig = {
|
||||
color: "orange",
|
||||
bgColor: "bg-orange-100",
|
||||
textColor: "text-orange-600",
|
||||
borderColor: "border-orange-300"
|
||||
}
|
||||
borderColor: "border-orange-300",
|
||||
},
|
||||
};
|
||||
|
||||
export function TrialProgress({ steps, currentStepIndex, trialStatus }: TrialProgressProps) {
|
||||
export function TrialProgress({
|
||||
steps,
|
||||
currentStepIndex,
|
||||
trialStatus,
|
||||
}: TrialProgressProps) {
|
||||
if (!steps || steps.length === 0) {
|
||||
return (
|
||||
<Card>
|
||||
<CardContent className="p-6 text-center">
|
||||
<div className="text-slate-500">
|
||||
<Target className="h-8 w-8 mx-auto mb-2 opacity-50" />
|
||||
<Target className="mx-auto mb-2 h-8 w-8 opacity-50" />
|
||||
<p className="text-sm">No experiment steps defined</p>
|
||||
</div>
|
||||
</CardContent>
|
||||
@@ -71,19 +86,28 @@ export function TrialProgress({ steps, currentStepIndex, trialStatus }: TrialPro
|
||||
);
|
||||
}
|
||||
|
||||
const progress = trialStatus === "completed" ? 100 :
|
||||
trialStatus === "aborted" ? 0 :
|
||||
((currentStepIndex + 1) / steps.length) * 100;
|
||||
const progress =
|
||||
trialStatus === "completed"
|
||||
? 100
|
||||
: trialStatus === "aborted"
|
||||
? 0
|
||||
: ((currentStepIndex + 1) / steps.length) * 100;
|
||||
|
||||
const completedSteps = trialStatus === "completed" ? steps.length :
|
||||
trialStatus === "aborted" || trialStatus === "failed" ? 0 :
|
||||
currentStepIndex;
|
||||
const completedSteps =
|
||||
trialStatus === "completed"
|
||||
? steps.length
|
||||
: trialStatus === "aborted" || trialStatus === "failed"
|
||||
? 0
|
||||
: currentStepIndex;
|
||||
|
||||
const getStepStatus = (index: number) => {
|
||||
if (trialStatus === "aborted" || trialStatus === "failed") return "aborted";
|
||||
if (trialStatus === "completed" || index < currentStepIndex) return "completed";
|
||||
if (index === currentStepIndex && trialStatus === "in_progress") return "active";
|
||||
if (index === currentStepIndex && trialStatus === "scheduled") return "pending";
|
||||
if (trialStatus === "completed" || index < currentStepIndex)
|
||||
return "completed";
|
||||
if (index === currentStepIndex && trialStatus === "in_progress")
|
||||
return "active";
|
||||
if (index === currentStepIndex && trialStatus === "scheduled")
|
||||
return "pending";
|
||||
return "upcoming";
|
||||
};
|
||||
|
||||
@@ -95,7 +119,7 @@ export function TrialProgress({ steps, currentStepIndex, trialStatus }: TrialPro
|
||||
iconColor: "text-green-600",
|
||||
bgColor: "bg-green-100",
|
||||
borderColor: "border-green-300",
|
||||
textColor: "text-green-800"
|
||||
textColor: "text-green-800",
|
||||
};
|
||||
case "active":
|
||||
return {
|
||||
@@ -103,7 +127,7 @@ export function TrialProgress({ steps, currentStepIndex, trialStatus }: TrialPro
|
||||
iconColor: "text-blue-600",
|
||||
bgColor: "bg-blue-100",
|
||||
borderColor: "border-blue-300",
|
||||
textColor: "text-blue-800"
|
||||
textColor: "text-blue-800",
|
||||
};
|
||||
case "pending":
|
||||
return {
|
||||
@@ -111,7 +135,7 @@ export function TrialProgress({ steps, currentStepIndex, trialStatus }: TrialPro
|
||||
iconColor: "text-amber-600",
|
||||
bgColor: "bg-amber-100",
|
||||
borderColor: "border-amber-300",
|
||||
textColor: "text-amber-800"
|
||||
textColor: "text-amber-800",
|
||||
};
|
||||
case "aborted":
|
||||
return {
|
||||
@@ -119,7 +143,7 @@ export function TrialProgress({ steps, currentStepIndex, trialStatus }: TrialPro
|
||||
iconColor: "text-red-600",
|
||||
bgColor: "bg-red-100",
|
||||
borderColor: "border-red-300",
|
||||
textColor: "text-red-800"
|
||||
textColor: "text-red-800",
|
||||
};
|
||||
default: // upcoming
|
||||
return {
|
||||
@@ -127,12 +151,15 @@ export function TrialProgress({ steps, currentStepIndex, trialStatus }: TrialPro
|
||||
iconColor: "text-slate-400",
|
||||
bgColor: "bg-slate-100",
|
||||
borderColor: "border-slate-300",
|
||||
textColor: "text-slate-600"
|
||||
textColor: "text-slate-600",
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const totalDuration = steps.reduce((sum, step) => sum + (step.duration || 0), 0);
|
||||
const totalDuration = steps.reduce(
|
||||
(sum, step) => sum + (step.duration ?? 0),
|
||||
0,
|
||||
);
|
||||
|
||||
return (
|
||||
<Card>
|
||||
@@ -165,19 +192,25 @@ export function TrialProgress({ steps, currentStepIndex, trialStatus }: TrialPro
|
||||
<Progress
|
||||
value={progress}
|
||||
className={`h-2 ${
|
||||
trialStatus === "completed" ? "bg-green-100" :
|
||||
trialStatus === "aborted" || trialStatus === "failed" ? "bg-red-100" :
|
||||
"bg-blue-100"
|
||||
trialStatus === "completed"
|
||||
? "bg-green-100"
|
||||
: trialStatus === "aborted" || trialStatus === "failed"
|
||||
? "bg-red-100"
|
||||
: "bg-blue-100"
|
||||
}`}
|
||||
/>
|
||||
<div className="flex justify-between text-xs text-slate-500">
|
||||
<span>Start</span>
|
||||
<span>
|
||||
{trialStatus === "completed" ? "Completed" :
|
||||
trialStatus === "aborted" ? "Aborted" :
|
||||
trialStatus === "failed" ? "Failed" :
|
||||
trialStatus === "in_progress" ? "In Progress" :
|
||||
"Not Started"}
|
||||
{trialStatus === "completed"
|
||||
? "Completed"
|
||||
: trialStatus === "aborted"
|
||||
? "Aborted"
|
||||
: trialStatus === "failed"
|
||||
? "Failed"
|
||||
: trialStatus === "in_progress"
|
||||
? "In Progress"
|
||||
: "Not Started"}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -186,7 +219,9 @@ export function TrialProgress({ steps, currentStepIndex, trialStatus }: TrialPro
|
||||
|
||||
{/* Steps Timeline */}
|
||||
<div className="space-y-4">
|
||||
<h4 className="font-medium text-slate-900 text-sm">Experiment Steps</h4>
|
||||
<h4 className="text-sm font-medium text-slate-900">
|
||||
Experiment Steps
|
||||
</h4>
|
||||
|
||||
<div className="space-y-3">
|
||||
{steps.map((step, index) => {
|
||||
@@ -201,9 +236,10 @@ export function TrialProgress({ steps, currentStepIndex, trialStatus }: TrialPro
|
||||
{/* Connection Line */}
|
||||
{index < steps.length - 1 && (
|
||||
<div
|
||||
className={`absolute left-6 top-12 w-0.5 h-6 ${
|
||||
className={`absolute top-12 left-6 h-6 w-0.5 ${
|
||||
getStepStatus(index + 1) === "completed" ||
|
||||
(getStepStatus(index + 1) === "active" && status === "completed")
|
||||
(getStepStatus(index + 1) === "active" &&
|
||||
status === "completed")
|
||||
? "bg-green-300"
|
||||
: "bg-slate-300"
|
||||
}`}
|
||||
@@ -211,57 +247,76 @@ export function TrialProgress({ steps, currentStepIndex, trialStatus }: TrialPro
|
||||
)}
|
||||
|
||||
{/* Step Card */}
|
||||
<div className={`flex items-start space-x-3 p-3 rounded-lg border transition-all ${
|
||||
status === "active"
|
||||
? `${statusConfig.bgColor} ${statusConfig.borderColor} shadow-md ring-2 ring-blue-200`
|
||||
: status === "completed"
|
||||
? `${statusConfig.bgColor} ${statusConfig.borderColor}`
|
||||
: status === "aborted"
|
||||
? `${statusConfig.bgColor} ${statusConfig.borderColor}`
|
||||
: "bg-slate-50 border-slate-200"
|
||||
}`}>
|
||||
<div
|
||||
className={`flex items-start space-x-3 rounded-lg border p-3 transition-all ${
|
||||
status === "active"
|
||||
? `${statusConfig.bgColor} ${statusConfig.borderColor} shadow-md ring-2 ring-blue-200`
|
||||
: status === "completed"
|
||||
? `${statusConfig.bgColor} ${statusConfig.borderColor}`
|
||||
: status === "aborted"
|
||||
? `${statusConfig.bgColor} ${statusConfig.borderColor}`
|
||||
: "border-slate-200 bg-slate-50"
|
||||
}`}
|
||||
>
|
||||
{/* Step Number & Status */}
|
||||
<div className="flex-shrink-0 space-y-1">
|
||||
<div className={`w-12 h-8 rounded-lg flex items-center justify-center ${
|
||||
status === "active" ? statusConfig.bgColor :
|
||||
status === "completed" ? "bg-green-100" :
|
||||
status === "aborted" ? "bg-red-100" :
|
||||
"bg-slate-100"
|
||||
}`}>
|
||||
<span className={`text-sm font-medium ${
|
||||
status === "active" ? statusConfig.textColor :
|
||||
status === "completed" ? "text-green-700" :
|
||||
status === "aborted" ? "text-red-700" :
|
||||
"text-slate-600"
|
||||
}`}>
|
||||
<div
|
||||
className={`flex h-8 w-12 items-center justify-center rounded-lg ${
|
||||
status === "active"
|
||||
? statusConfig.bgColor
|
||||
: status === "completed"
|
||||
? "bg-green-100"
|
||||
: status === "aborted"
|
||||
? "bg-red-100"
|
||||
: "bg-slate-100"
|
||||
}`}
|
||||
>
|
||||
<span
|
||||
className={`text-sm font-medium ${
|
||||
status === "active"
|
||||
? statusConfig.textColor
|
||||
: status === "completed"
|
||||
? "text-green-700"
|
||||
: status === "aborted"
|
||||
? "text-red-700"
|
||||
: "text-slate-600"
|
||||
}`}
|
||||
>
|
||||
{index + 1}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex justify-center">
|
||||
<StatusIcon className={`h-4 w-4 ${statusConfig.iconColor}`} />
|
||||
<StatusIcon
|
||||
className={`h-4 w-4 ${statusConfig.iconColor}`}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Step Content */}
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="min-w-0 flex-1">
|
||||
<div className="flex items-start justify-between">
|
||||
<div className="min-w-0 flex-1">
|
||||
<h5 className={`font-medium truncate ${
|
||||
status === "active" ? "text-slate-900" :
|
||||
status === "completed" ? "text-green-900" :
|
||||
status === "aborted" ? "text-red-900" :
|
||||
"text-slate-700"
|
||||
}`}>
|
||||
<h5
|
||||
className={`truncate font-medium ${
|
||||
status === "active"
|
||||
? "text-slate-900"
|
||||
: status === "completed"
|
||||
? "text-green-900"
|
||||
: status === "aborted"
|
||||
? "text-red-900"
|
||||
: "text-slate-700"
|
||||
}`}
|
||||
>
|
||||
{step.name}
|
||||
</h5>
|
||||
{step.description && (
|
||||
<p className="text-sm text-slate-600 mt-1 line-clamp-2">
|
||||
<p className="mt-1 line-clamp-2 text-sm text-slate-600">
|
||||
{step.description}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex-shrink-0 ml-3 space-y-1">
|
||||
<div className="ml-3 flex-shrink-0 space-y-1">
|
||||
<Badge
|
||||
variant="outline"
|
||||
className={`text-xs ${stepConfig.textColor} ${stepConfig.borderColor}`}
|
||||
@@ -280,19 +335,19 @@ export function TrialProgress({ steps, currentStepIndex, trialStatus }: TrialPro
|
||||
|
||||
{/* Step Status Message */}
|
||||
{status === "active" && trialStatus === "in_progress" && (
|
||||
<div className="flex items-center space-x-1 mt-2 text-sm text-blue-600">
|
||||
<div className="mt-2 flex items-center space-x-1 text-sm text-blue-600">
|
||||
<Activity className="h-3 w-3 animate-pulse" />
|
||||
<span>Currently executing...</span>
|
||||
</div>
|
||||
)}
|
||||
{status === "active" && trialStatus === "scheduled" && (
|
||||
<div className="flex items-center space-x-1 mt-2 text-sm text-amber-600">
|
||||
<div className="mt-2 flex items-center space-x-1 text-sm text-amber-600">
|
||||
<Clock className="h-3 w-3" />
|
||||
<span>Ready to start</span>
|
||||
</div>
|
||||
)}
|
||||
{status === "completed" && (
|
||||
<div className="flex items-center space-x-1 mt-2 text-sm text-green-600">
|
||||
<div className="mt-2 flex items-center space-x-1 text-sm text-green-600">
|
||||
<CheckCircle className="h-3 w-3" />
|
||||
<span>Completed</span>
|
||||
</div>
|
||||
@@ -309,7 +364,9 @@ export function TrialProgress({ steps, currentStepIndex, trialStatus }: TrialPro
|
||||
<Separator />
|
||||
<div className="grid grid-cols-3 gap-4 text-center">
|
||||
<div>
|
||||
<div className="text-2xl font-bold text-green-600">{completedSteps}</div>
|
||||
<div className="text-2xl font-bold text-green-600">
|
||||
{completedSteps}
|
||||
</div>
|
||||
<div className="text-xs text-slate-600">Completed</div>
|
||||
</div>
|
||||
<div>
|
||||
@@ -320,7 +377,9 @@ export function TrialProgress({ steps, currentStepIndex, trialStatus }: TrialPro
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-2xl font-bold text-slate-600">
|
||||
{steps.length - completedSteps - (trialStatus === "in_progress" ? 1 : 0)}
|
||||
{steps.length -
|
||||
completedSteps -
|
||||
(trialStatus === "in_progress" ? 1 : 0)}
|
||||
</div>
|
||||
<div className="text-xs text-slate-600">Remaining</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user