From 16f39e264ebdfc324302f69b397715effda54f81 Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Tue, 14 Apr 2026 09:15:37 -0700 Subject: [PATCH] =?UTF-8?q?feat:=20responsive=20dashboard=20=E2=80=94=20dy?= =?UTF-8?q?namic=20reflow,=20wider=20cap,=20half-width=20panels?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Use Ink's useWindowSize() hook for reactive terminal reflow (PR #18) - Raise width cap from 104 to 160 columns for wide screens - Move Activity panel from full-width to half-width row with Model panel - Pair Tool + Bash panels, MCP goes full-width at bottom - Addresses issue #23 (UI responsiveness) --- src/dashboard.tsx | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/dashboard.tsx b/src/dashboard.tsx index 4efe0b0..9e17550 100644 --- a/src/dashboard.tsx +++ b/src/dashboard.tsx @@ -1,5 +1,5 @@ import React, { useState, useCallback, useEffect } from 'react' -import { render, Box, Text, useInput, useApp } from 'ink' +import { render, Box, Text, useInput, useApp, useWindowSize } from 'ink' import { CATEGORY_LABELS, type ProjectSummary, type TaskCategory } from './types.js' import { formatCost, formatTokens } from './format.js' import { parseAllSessions } from './parser.js' @@ -83,9 +83,9 @@ function getDateRange(period: Period): { start: Date; end: Date } { type Layout = { dashWidth: number; wide: boolean; halfWidth: number; barWidth: number } -function getLayout(): Layout { - const termWidth = process.stdout.columns || parseInt(process.env['COLUMNS'] ?? '') || 80 - const dashWidth = Math.min(104, termWidth) +function getLayout(columns?: number): Layout { + const termWidth = columns || parseInt(process.env['COLUMNS'] ?? '') || 80 + const dashWidth = Math.min(160, termWidth) const wide = dashWidth >= MIN_WIDE const halfWidth = wide ? Math.floor(dashWidth / 2) : dashWidth const inner = halfWidth - 4 @@ -429,8 +429,8 @@ function Row({ wide, width, children }: { wide: boolean; width: number; children return <>{children} } -function DashboardContent({ projects, period }: { projects: ProjectSummary[]; period: Period }) { - const { dashWidth, wide, halfWidth, barWidth } = getLayout() +function DashboardContent({ projects, period, columns }: { projects: ProjectSummary[]; period: Period; columns?: number }) { + const { dashWidth, wide, halfWidth, barWidth } = getLayout(columns) if (projects.length === 0) { return ( @@ -451,17 +451,17 @@ function DashboardContent({ projects, period }: { projects: ProjectSummary[]; pe - - + - + - + + ) } @@ -477,7 +477,8 @@ function InteractiveDashboard({ initialProjects, initialPeriod, initialProvider const [loading, setLoading] = useState(false) const [activeProvider, setActiveProvider] = useState(initialProvider) const [detectedProviders, setDetectedProviders] = useState([]) - const { dashWidth } = getLayout() + const { columns } = useWindowSize() + const { dashWidth } = getLayout(columns) const multipleProviders = detectedProviders.length > 1 useEffect(() => { @@ -555,18 +556,19 @@ function InteractiveDashboard({ initialProjects, initialPeriod, initialProvider return ( - + ) } function StaticDashboard({ projects, period }: { projects: ProjectSummary[]; period: Period }) { - const { dashWidth } = getLayout() + const { columns } = useWindowSize() + const { dashWidth } = getLayout(columns) return ( - + ) }