feat: refine agent workflow step timeline
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled

This commit is contained in:
Your Name 2026-03-23 10:15:15 +08:00
parent 467de8ff1e
commit cb4cf50337
2 changed files with 63 additions and 46 deletions

View File

@ -2337,7 +2337,7 @@ export function AgentGenerationWorkspaceDarkV2({
默认载入最新一套,可随时切换
</div>
</div>
<div className="agent-dark-scrollbar grid max-h-[360px] grid-cols-1 gap-3 overflow-y-auto pr-1 xl:grid-cols-2">
<div className="agent-dark-scrollbar grid max-h-[360px] grid-cols-1 gap-3 overflow-y-auto pr-1 md:grid-cols-2 xl:grid-cols-4">
{detailReplacementCandidates.map((candidate) => {
const isSelected = detailReplacementSelectedCandidateId === candidate.id;
const previewUrls = getCandidatePreviewUrls(
@ -2369,14 +2369,14 @@ export function AgentGenerationWorkspaceDarkV2({
type="button"
onClick={() => handleSelectDetailReplacementCandidate(candidate.id)}
className={cn(
"group relative min-w-0 overflow-hidden rounded-2xl border p-2.5 text-left transition-all duration-300",
"group relative min-w-0 overflow-hidden rounded-2xl border p-2 text-left transition-all duration-300",
isSelected
? "border-emerald-400/40 bg-emerald-500/[0.08] shadow-[0_0_24px_rgba(16,185,129,0.14)]"
: "border-white/10 bg-white/[0.03] hover:border-white/20 hover:bg-white/[0.06]"
)}
>
<div className="flex items-stretch gap-3">
<div className="relative w-[88px] min-h-[112px] shrink-0 overflow-hidden rounded-[20px] border border-white/10 bg-black/30">
<div className="relative w-[72px] min-h-[96px] shrink-0 overflow-hidden rounded-[18px] border border-white/10 bg-black/30">
<div className="h-full w-full">
{primaryPreviewUrl ? (
<img
@ -2393,16 +2393,16 @@ export function AgentGenerationWorkspaceDarkV2({
{getCandidateTargetCount(candidate, detailReferenceTarget)}张
</div>
</div>
<div className="flex min-h-[112px] min-w-0 flex-1 flex-col justify-between pr-7">
<div className="line-clamp-2 text-[13px] font-semibold leading-5 text-white">
<div className="flex min-h-[96px] min-w-0 flex-1 flex-col justify-between pr-5">
<div className="line-clamp-2 text-[12px] font-semibold leading-5 text-white">
{candidate.sceneName || candidate.taskNo || candidate.productModel || "候选整套"}
</div>
<div className="mt-2 flex flex-wrap gap-1.5">
<div className="mt-1.5 flex flex-wrap gap-1">
{summaryBadges.map((badge, badgeIndex) => (
<span
key={`${candidate.id}-badge-${badgeIndex}-${badge}`}
className={cn(
"rounded-full border px-2 py-1 text-[9px] leading-none",
"rounded-full border px-1.5 py-0.5 text-[8px] leading-none",
badgeIndex === 0
? "border-emerald-400/25 bg-emerald-500/[0.12] text-emerald-100"
: "border-white/10 bg-white/[0.04] text-white/62"
@ -2412,7 +2412,7 @@ export function AgentGenerationWorkspaceDarkV2({
</span>
))}
</div>
<div className="mt-2 text-[10px] leading-4 text-white/45">
<div className="mt-1.5 text-[9px] leading-4 text-white/45">
<div className="truncate">
场景名称:{candidate.sceneName || candidate.productModel || "未命名整套"}
</div>
@ -2420,13 +2420,13 @@ export function AgentGenerationWorkspaceDarkV2({
任务编号:{candidate.taskNo || "未记录"}
</div>
</div>
<div className="mt-2 flex flex-col gap-1 text-[10px] text-white/50">
<div className="mt-1.5 flex flex-col gap-0.5 text-[9px] text-white/50">
<div className="truncate">店铺:{candidate.shopName || "未记录"}</div>
<div className="truncate">更新时间:{uploadedAtText}</div>
</div>
</div>
{isSelected ? (
<div className="absolute right-4 top-4 h-3 w-3 rounded-full bg-emerald-400 shadow-[0_0_0_4px_rgba(16,185,129,0.18),0_0_18px_rgba(52,211,153,0.45)]" />
<div className="absolute right-3 top-3 h-2.5 w-2.5 rounded-full bg-emerald-400 shadow-[0_0_0_4px_rgba(16,185,129,0.18),0_0_18px_rgba(52,211,153,0.45)]" />
) : null}
</div>
</button>

View File

@ -1,6 +1,6 @@
"use client";
import { useEffect, useMemo, useState, type ReactNode } from "react";
import { Fragment, useEffect, useMemo, useState, type ReactNode } from "react";
import { motion } from "framer-motion";
import { ArrowRight, Check, Copy, Sparkles, ChevronRight } from "lucide-react";
import { toast } from "sonner";
@ -516,7 +516,8 @@ export function AgentWorkflowPanelDarkV2({
animate={{ opacity: 1, y: 0 }}
>
<div className="mb-5 space-y-4">
<div className="flex flex-wrap gap-2">
<div className="agent-dark-scrollbar -mx-1 overflow-x-auto px-1 pb-2">
<div className="flex min-w-max items-start">
{flattenedResolvedSteps.map(({ step }, stepIndex) => {
const completed = isAgentWorkflowStepSelectionComplete({
step,
@ -526,52 +527,68 @@ export function AgentWorkflowPanelDarkV2({
const stepSummary = stepSelectionSummaryMap[step.key] || "";
return (
<button
key={step.key}
type="button"
onClick={() => {
setPendingAutoAdvanceStepKey(null);
setActiveEmbeddedStepKey(step.key);
}}
className={cn(
"flex items-start gap-2 rounded-[18px] border px-3 py-2 text-left transition-colors",
active
? "border-emerald-400/45 bg-emerald-500/[0.12] text-emerald-100"
: completed
? "border-white/14 bg-white/[0.05] text-white/72 hover:border-white/22"
: "border-white/10 bg-black/20 text-white/40 hover:border-white/16 hover:text-white/72"
)}
>
<span
className={cn(
"flex h-5 w-5 items-center justify-center rounded-full text-[10px] font-semibold",
active
? "bg-emerald-300 text-black"
: completed
? "bg-white text-black"
: "bg-white/10 text-white/55"
)}
<Fragment key={step.key}>
<button
type="button"
onClick={() => {
setPendingAutoAdvanceStepKey(null);
setActiveEmbeddedStepKey(step.key);
}}
className="group flex w-[156px] shrink-0 flex-col items-start pr-4 text-left transition-transform duration-200 hover:-translate-y-[1px]"
>
{stepIndex + 1}
</span>
<span className="flex min-w-0 flex-col">
<span>{step.title}</span>
<div className="flex w-full items-center gap-3">
<span
className={cn(
"flex h-8 w-8 shrink-0 items-center justify-center rounded-full border text-[12px] font-semibold transition-colors",
active
? "border-emerald-300 bg-emerald-300 text-black shadow-[0_0_18px_rgba(52,211,153,0.28)]"
: completed
? "border-white/30 bg-white text-black"
: "border-white/12 bg-white/[0.04] text-white/62 group-hover:border-white/24 group-hover:text-white/82"
)}
>
{stepIndex + 1}
</span>
<span
className={cn(
"truncate text-[15px] font-semibold transition-colors",
active
? "text-white"
: completed
? "text-white/82"
: "text-white/52 group-hover:text-white/76"
)}
>
{step.title}
</span>
</div>
<span
className={cn(
"mt-0.5 max-w-[180px] truncate text-[10px]",
"mt-2 pl-11 text-[11px] leading-5",
active
? "text-emerald-100/80"
? "text-emerald-100/78"
: completed
? "text-white/52"
? "text-white/50"
: "text-white/32"
)}
>
{stepSummary || "待选择"}
</span>
</span>
</button>
</button>
{stepIndex < flattenedResolvedSteps.length - 1 ? (
<div
className={cn(
"mr-4 mt-4 h-px min-w-[40px] transition-colors",
stepIndex < activeEmbeddedStepIndex
? "bg-emerald-400/35"
: "bg-white/10"
)}
/>
) : null}
</Fragment>
);
})}
</div>
</div>
<div>