feat(dashboard): rearrange agent + task detail panels
- AgentsView: agent metrics bar moves to the top of the scrolling content (was below the agent list); token-usage panel moves into the controls dropdown next to the heartbeat slider, which is now scrollable so the added content fits on short viewports. - AgentsView mobile: 2x2 grid for the metric cards with tighter padding and smaller value/label text so labels don't crowd off the card on narrow phones. - TaskDetailModal: new "Stats" tab at the end of the fixed tab list hosts the token-usage panel, removed from the inline definition body. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -834,6 +834,29 @@
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
/* Stats cards: drop to a 2x2 grid with tighter padding so they
|
||||
don't squeeze the labels off the card on narrow phones. */
|
||||
.agent-metrics-bar {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: var(--space-sm);
|
||||
margin-bottom: var(--space-md);
|
||||
}
|
||||
|
||||
.agent-metric-card {
|
||||
padding: var(--space-sm) var(--space-md);
|
||||
gap: var(--space-sm);
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.agent-metric-value {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.agent-metric-label {
|
||||
font-size: calc(var(--space-sm) + var(--space-xs) * 0.5);
|
||||
}
|
||||
|
||||
.agent-org-chart {
|
||||
padding: var(--space-sm);
|
||||
padding-bottom: calc(var(--space-lg) + var(--space-sm));
|
||||
|
||||
@@ -749,10 +749,11 @@ export function AgentsView({ addToast, projectId }: AgentsViewProps) {
|
||||
<div
|
||||
ref={controlsPanelRef}
|
||||
id={controlsPanelId}
|
||||
className="agent-controls-panel"
|
||||
className="agent-controls-panel agent-controls-panel--scrollable"
|
||||
role="dialog"
|
||||
aria-label="Agent controls"
|
||||
aria-modal="false"
|
||||
style={{ maxHeight: "70vh", overflowY: "auto" }}
|
||||
>
|
||||
<div className="agent-controls">
|
||||
<div className="agent-controls-filters">
|
||||
@@ -846,11 +847,15 @@ export function AgentsView({ addToast, projectId }: AgentsViewProps) {
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<AgentTokenStatsPanel agents={displayAgents} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="agents-view-content">
|
||||
|
||||
<AgentMetricsBar stats={stats} />
|
||||
|
||||
<NewAgentDialog
|
||||
isOpen={isCreating}
|
||||
onClose={() => setIsCreating(false)}
|
||||
@@ -1266,8 +1271,6 @@ export function AgentsView({ addToast, projectId }: AgentsViewProps) {
|
||||
)}
|
||||
|
||||
{/* Secondary sections after the main collection */}
|
||||
<AgentMetricsBar stats={stats} />
|
||||
<AgentTokenStatsPanel agents={displayAgents} />
|
||||
<ActiveAgentsPanel agents={activeAgents} projectId={projectId} onAgentSelect={setSelectedAgentId} />
|
||||
</div>
|
||||
|
||||
|
||||
@@ -157,7 +157,7 @@ function formatBytes(bytes: number): string {
|
||||
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
||||
}
|
||||
|
||||
type TabId = "definition" | "logs" | "changes" | "comments" | "model" | "workflow" | "documents" | `plugin-${string}`;
|
||||
type TabId = "definition" | "logs" | "changes" | "comments" | "model" | "workflow" | "documents" | "stats" | `plugin-${string}`;
|
||||
|
||||
interface TaskDetailModalProps {
|
||||
task: Task | TaskDetail;
|
||||
@@ -1286,6 +1286,12 @@ export function TaskDetailModal({
|
||||
>
|
||||
Workflow
|
||||
</button>
|
||||
<button
|
||||
className={`detail-tab${activeTab === "stats" ? " detail-tab-active" : ""}`}
|
||||
onClick={() => setActiveTab("stats")}
|
||||
>
|
||||
Stats
|
||||
</button>
|
||||
{/* Plugin tabs */}
|
||||
{pluginTabSlots.map((entry, index) => {
|
||||
const pluginTabId = `plugin-${index}` as TabId;
|
||||
@@ -1391,6 +1397,13 @@ export function TaskDetailModal({
|
||||
<div className="detail-section">
|
||||
<PluginSlot slotId="task-detail-tab" projectId={projectId} />
|
||||
</div>
|
||||
) : activeTab === "stats" ? (
|
||||
<div className="detail-section">
|
||||
<TaskTokenStatsPanel
|
||||
tokenUsage={workingTask.tokenUsage}
|
||||
loading={detailLoading}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{/* Summary section - only for done tasks with summary */}
|
||||
@@ -1482,12 +1495,6 @@ export function TaskDetailModal({
|
||||
<div className="step-progress-empty">(no steps defined)</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="detail-section">
|
||||
<TaskTokenStatsPanel
|
||||
tokenUsage={workingTask.tokenUsage}
|
||||
loading={detailLoading}
|
||||
/>
|
||||
</div>
|
||||
<div className="detail-section">
|
||||
{!isEditingSpec && (
|
||||
<div className="detail-spec-edit-trigger">
|
||||
|
||||
Reference in New Issue
Block a user