feat(11-02): replace 1113 old CSS variable references with Paperclip design tokens
- Replace all bg-[color:var(--old)] with bg-background/bg-card/bg-muted/bg-primary etc. - Replace all text-[color:var(--old)] with text-foreground/text-muted-foreground/text-primary etc. - Replace all border-[color:var(--line)] with border-border - Replace all inline var(--old) with var(--new) equivalents - Replace all rounded-[6px]/rounded-[8px] with rounded-lg - Replace .surface class with bg-card border border-border shadow-sm - Replace .focus-ring class with focus-visible Tailwind utilities - Replace .mono class with font-mono - Replace data-theme attribute with class-based dark mode - 99 files updated, ~1265 lines changed, zero old references remaining
This commit is contained in:
1 parent
2ed5dd3388
commit
06ea4c6aec
99 files changed
+1265
-1265
No files matched your search
@@ -38,7 +38,7 @@ export function TaskInspector({ task, tasks, runs, agents, goals, projects, work
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<ConfirmDialog open={confirmDelete} title={t("exec.deleteTask")} message={`${t("exec.deleteTaskConfirm").replace("{0}", task.title)}`} errorMessage={deleteError} onConfirm={() => void handleDelete()} onCancel={() => { setDeleteError(null); setConfirmDelete(false) }} />
|
||||
{budgetWarning > 0.8 && assignee ? <div className={`flex items-center gap-2 rounded-[8px] border px-4 py-3 text-[13px] font-medium ${budgetWarning > 1 ? "border-[color:var(--danger)] bg-[color:var(--danger-soft)] text-[color:var(--danger)]" : "border-[color:var(--warn)] bg-[color:var(--warn-soft)] text-[color:var(--warn)]"}`}><Warning size={16} weight="fill" />{assignee.name} has used {Math.round(budgetWarning * 100)}% of their monthly budget ({formatMoney(assignee.spentMonthlyUsd)} / {formatMoney(assignee.budgetMonthlyUsd)})</div> : null}
|
||||
{budgetWarning > 0.8 && assignee ? <div className={`flex items-center gap-2 rounded-lg border px-4 py-3 text-[13px] font-medium ${budgetWarning > 1 ? "border-[color:var(--destructive)] bg-red-100 dark:bg-red-900/50 text-destructive" : "border-[color:var(--destructive)] bg-yellow-100 dark:bg-yellow-900/50 text-yellow-600 dark:text-yellow-400"}`}><Warning size={16} weight="fill" />{assignee.name} has used {Math.round(budgetWarning * 100)}% of their monthly budget ({formatMoney(assignee.spentMonthlyUsd)} / {formatMoney(assignee.budgetMonthlyUsd)})</div> : null}
|
||||
{actionError ? <InlineNotice message={actionError} /> : null}
|
||||
{!actionError && actionNotice ? <InlineNotice message={actionNotice} tone="success" /> : null}
|
||||
{editing ? (
|
||||
@@ -56,16 +56,16 @@ export function TaskInspector({ task, tasks, runs, agents, goals, projects, work
|
||||
) : (
|
||||
<>
|
||||
<div className="grid gap-x-6 gap-y-2 text-[13px] md:grid-cols-2">
|
||||
{assignee && <div className="text-[color:var(--muted)]">Assignee: <span className="text-[color:var(--text)]">{assignee.name}</span></div>}
|
||||
{project && <div className="text-[color:var(--muted)]">Project: <span className="text-[color:var(--text)]">{project.name}</span></div>}
|
||||
{goal && <div className="text-[color:var(--muted)]">Goal: <span className="text-[color:var(--text)]">{goal.title}</span></div>}
|
||||
{task.parentId && (() => { const parent = tasks.find((t) => t.id === task.parentId); return parent ? <div className="text-[color:var(--muted)]">Parent: <span className="text-[color:var(--text)]">{parent.title}</span></div> : null })()}
|
||||
{workspace && <div className="text-[color:var(--muted)]">Workspace: <span className="text-[color:var(--text)]">{workspace.name}</span></div>}
|
||||
{task.costUsd > 0 && <div className="text-[color:var(--muted)]">Cost: <span className="mono tabular-nums text-[color:var(--text)]">{formatMoney(task.costUsd)}</span></div>}
|
||||
{assignee && <div className="text-muted-foreground">Assignee: <span className="text-foreground">{assignee.name}</span></div>}
|
||||
{project && <div className="text-muted-foreground">Project: <span className="text-foreground">{project.name}</span></div>}
|
||||
{goal && <div className="text-muted-foreground">Goal: <span className="text-foreground">{goal.title}</span></div>}
|
||||
{task.parentId && (() => { const parent = tasks.find((t) => t.id === task.parentId); return parent ? <div className="text-muted-foreground">Parent: <span className="text-foreground">{parent.title}</span></div> : null })()}
|
||||
{workspace && <div className="text-muted-foreground">Workspace: <span className="text-foreground">{workspace.name}</span></div>}
|
||||
{task.costUsd > 0 && <div className="text-muted-foreground">Cost: <span className="font-mono tabular-nums text-foreground">{formatMoney(task.costUsd)}</span></div>}
|
||||
</div>
|
||||
{task.description ? <div className="text-[13px] leading-relaxed text-[color:var(--muted-strong)] whitespace-pre-wrap">{task.description}</div> : null}
|
||||
{task.status === "in_review" && reviewer ? <div className="rounded-[8px] border border-[color:var(--accent-soft)] bg-[color:var(--accent-soft)] px-4 py-3"><div className="flex items-center gap-2 text-[13px] font-semibold text-[color:var(--accent-text)]"><Robot size={16} weight="fill" />Being reviewed by {reviewer.name}{reviewer.title ? ` (${reviewer.title})` : ""}</div><div className="mt-1 text-[13px] leading-relaxed text-[color:var(--accent-text)]">{assignee?.name} submitted this task for review. {reviewer.name} will approve, request revisions, or escalate.</div></div>
|
||||
: needsGovernance ? <div className="rounded-[8px] border border-[color:var(--warn)] bg-[color:var(--warn-soft)] px-4 py-3"><div className="flex items-center gap-2 text-[13px] font-semibold text-[color:var(--warn)]"><ShieldCheck size={16} weight="fill" />{task.status === "blocked" ? t("exec.governanceRequired") : t("exec.waitingOnReview")}</div><div className="mt-1 text-[13px] leading-relaxed text-[color:var(--muted-strong)]">{task.status === "blocked" ? t("exec.blockedGovernance") : t("exec.reviewGovernance")}</div><div className="mt-3"><ActionButton label={task.status === "blocked" ? t("exec.createUnblockApproval") : t("exec.createReviewApproval")} onClick={() => void handleCreateApproval()} icon={ShieldCheck} loading={creatingApproval} /></div></div> : null}
|
||||
{task.description ? <div className="text-[13px] leading-relaxed text-muted-foreground whitespace-pre-wrap">{task.description}</div> : null}
|
||||
{task.status === "in_review" && reviewer ? <div className="rounded-lg border border-[color:var(--primary)] bg-accent px-4 py-3"><div className="flex items-center gap-2 text-[13px] font-semibold text-primary"><Robot size={16} weight="fill" />Being reviewed by {reviewer.name}{reviewer.title ? ` (${reviewer.title})` : ""}</div><div className="mt-1 text-[13px] leading-relaxed text-primary">{assignee?.name} submitted this task for review. {reviewer.name} will approve, request revisions, or escalate.</div></div>
|
||||
: needsGovernance ? <div className="rounded-lg border border-[color:var(--destructive)] bg-yellow-100 dark:bg-yellow-900/50 px-4 py-3"><div className="flex items-center gap-2 text-[13px] font-semibold text-yellow-600 dark:text-yellow-400"><ShieldCheck size={16} weight="fill" />{task.status === "blocked" ? t("exec.governanceRequired") : t("exec.waitingOnReview")}</div><div className="mt-1 text-[13px] leading-relaxed text-muted-foreground">{task.status === "blocked" ? t("exec.blockedGovernance") : t("exec.reviewGovernance")}</div><div className="mt-3"><ActionButton label={task.status === "blocked" ? t("exec.createUnblockApproval") : t("exec.createReviewApproval")} onClick={() => void handleCreateApproval()} icon={ShieldCheck} loading={creatingApproval} /></div></div> : null}
|
||||
<div className="flex items-center gap-3">
|
||||
{activeRun ? <ActionButton label={t("exec.cancelRun")} onClick={() => void onCancelRun(activeRun.id)} icon={XCircle} tone="danger" /> : <>
|
||||
{["todo","in_progress","blocked"].includes(task.status) && <ActionButton label={t("exec.run")} onClick={() => void onRun(task.id)} icon={Play} tone="accent" />}
|
||||
@@ -80,20 +80,20 @@ export function TaskInspector({ task, tasks, runs, agents, goals, projects, work
|
||||
)}
|
||||
{(() => { const subtasks = tasks.filter((t) => t.parentId === task.id); if (subtasks.length === 0) return null; return (
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center gap-2"><ListChecks size={14} className="text-[color:var(--muted)]" /><span className="text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]">{t("exec.subtasks")} ({subtasks.length})</span><span className="text-[10px] text-[color:var(--success)]">{subtasks.filter((t) => t.status === "done").length}/{subtasks.length} done</span></div>
|
||||
<div className="h-1.5 w-full overflow-hidden rounded-full bg-[color:var(--panel-soft)]"><div className="h-full rounded-full bg-[color:var(--success)] transition-all duration-300" style={{ width: `${subtasks.length > 0 ? (subtasks.filter((t) => t.status === "done").length / subtasks.length) * 100 : 0}%` }} /></div>
|
||||
<div className="flex items-center gap-2"><ListChecks size={14} className="text-muted-foreground" /><span className="text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground">{t("exec.subtasks")} ({subtasks.length})</span><span className="text-[10px] text-green-600 dark:text-green-400">{subtasks.filter((t) => t.status === "done").length}/{subtasks.length} done</span></div>
|
||||
<div className="h-1.5 w-full overflow-hidden rounded-full bg-muted"><div className="h-full rounded-full bg-green-600 dark:bg-green-400 transition-all duration-300" style={{ width: `${subtasks.length > 0 ? (subtasks.filter((t) => t.status === "done").length / subtasks.length) * 100 : 0}%` }} /></div>
|
||||
<div className="space-y-1">{subtasks.map((sub) => { const subAssignee = agentMap.get(sub.assigneeAgentId ?? ""); return (
|
||||
<div key={sub.id} className="flex items-center gap-2 rounded-[6px] px-3 py-2 text-[12px] bg-[color:var(--panel-soft)]">
|
||||
<span className={`h-1.5 w-1.5 shrink-0 rounded-full ${sub.status === "done" ? "bg-[color:var(--success)]" : sub.status === "in_progress" ? "bg-[color:var(--accent)]" : sub.status === "blocked" ? "bg-[color:var(--danger)]" : sub.status === "in_review" ? "bg-[color:var(--warn)]" : "bg-[color:var(--muted)]"}`} />
|
||||
<span className={`flex-1 truncate ${sub.status === "done" ? "line-through text-[color:var(--muted)]" : "text-[color:var(--text)]"}`}>{sub.title}</span>
|
||||
{subAssignee ? <span className="shrink-0 text-[10px] text-[color:var(--muted)]">{subAssignee.name}</span> : null}<StatusPill status={sub.status} />
|
||||
<div key={sub.id} className="flex items-center gap-2 rounded-lg px-3 py-2 text-[12px] bg-muted">
|
||||
<span className={`h-1.5 w-1.5 shrink-0 rounded-full ${sub.status === "done" ? "bg-green-600 dark:bg-green-400" : sub.status === "in_progress" ? "bg-primary" : sub.status === "blocked" ? "bg-destructive" : sub.status === "in_review" ? "bg-yellow-600 dark:bg-yellow-400" : "bg-[color:var(--muted-foreground)]"}`} />
|
||||
<span className={`flex-1 truncate ${sub.status === "done" ? "line-through text-muted-foreground" : "text-foreground"}`}>{sub.title}</span>
|
||||
{subAssignee ? <span className="shrink-0 text-[10px] text-muted-foreground">{subAssignee.name}</span> : null}<StatusPill status={sub.status} />
|
||||
</div>) })}</div></div>) })()}
|
||||
<TaskComments taskId={task.id} companyId={task.companyId} agents={agents} comments={comments} onRefresh={onRefresh} />
|
||||
{runs.length > 0 && <div className="space-y-2"><div className="text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]">{t("exec.runHistory")}</div><div className="space-y-2">{runs.slice(0, 8).map((run) => { const runAgent = agentMap.get(run.agentId); const isActive = run.status === "running" || run.status === "queued"; return (
|
||||
<div key={run.id} className={`rounded-[8px] border px-3 py-2.5 ${isActive ? "border-[color:var(--success)] bg-[color:var(--success-soft)]" : run.status === "failed" || run.status === "timed_out" ? "border-[color:var(--danger)] border-opacity-30 bg-[color:var(--danger-soft)]" : "border-[color:var(--line)] bg-[color:var(--panel-soft)]"}`}>
|
||||
<div className="flex items-center justify-between gap-2"><div className="min-w-0 flex-1"><div className="flex items-center gap-2">{isActive ? <span className="h-2 w-2 animate-pulse rounded-full bg-[color:var(--success)]" /> : null}<span className="truncate text-[13px] font-medium text-[color:var(--text)]">{run.summary || (isActive ? "Running..." : "Completed run")}</span></div><div className="mt-0.5 flex flex-wrap items-center gap-x-3 gap-y-0.5 text-[10px] text-[color:var(--muted)]">{runAgent ? <span>{runAgent.name}</span> : null}<span>{run.connectorId.replace("_local", "")}</span>{run.model ? <span className="mono">{run.model}</span> : null}<span>{formatTime(run.startedAt)}</span>{run.costUsd != null && run.costUsd > 0 ? <span className="mono tabular-nums">{formatMoney(run.costUsd)}</span> : null}</div></div><StatusPill status={run.status} /></div>
|
||||
{run.errorMessage ? <div className="mt-1.5 rounded bg-[color:var(--danger-soft)] px-2 py-1 text-[11px] text-[color:var(--danger)] break-words">{run.errorMessage}</div> : null}
|
||||
</div>) })}{runs.length > 8 && <div className="text-[11px] text-[color:var(--muted)] text-center">+{runs.length - 8} more runs</div>}</div></div>}
|
||||
{runs.length > 0 && <div className="space-y-2"><div className="text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground">{t("exec.runHistory")}</div><div className="space-y-2">{runs.slice(0, 8).map((run) => { const runAgent = agentMap.get(run.agentId); const isActive = run.status === "running" || run.status === "queued"; return (
|
||||
<div key={run.id} className={`rounded-lg border px-3 py-2.5 ${isActive ? "border-[color:var(--primary)] bg-green-100 dark:bg-green-900/50" : run.status === "failed" || run.status === "timed_out" ? "border-[color:var(--destructive)] border-opacity-30 bg-red-100 dark:bg-red-900/50" : "border-border bg-muted"}`}>
|
||||
<div className="flex items-center justify-between gap-2"><div className="min-w-0 flex-1"><div className="flex items-center gap-2">{isActive ? <span className="h-2 w-2 animate-pulse rounded-full bg-green-600 dark:bg-green-400" /> : null}<span className="truncate text-[13px] font-medium text-foreground">{run.summary || (isActive ? "Running..." : "Completed run")}</span></div><div className="mt-0.5 flex flex-wrap items-center gap-x-3 gap-y-0.5 text-[10px] text-muted-foreground">{runAgent ? <span>{runAgent.name}</span> : null}<span>{run.connectorId.replace("_local", "")}</span>{run.model ? <span className="font-mono">{run.model}</span> : null}<span>{formatTime(run.startedAt)}</span>{run.costUsd != null && run.costUsd > 0 ? <span className="font-mono tabular-nums">{formatMoney(run.costUsd)}</span> : null}</div></div><StatusPill status={run.status} /></div>
|
||||
{run.errorMessage ? <div className="mt-1.5 rounded bg-red-100 dark:bg-red-900/50 px-2 py-1 text-[11px] text-destructive break-words">{run.errorMessage}</div> : null}
|
||||
</div>) })}{runs.length > 8 && <div className="text-[11px] text-muted-foreground text-center">+{runs.length - 8} more runs</div>}</div></div>}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in new issue
Block a user