From b58e64b55536964b978784ebf90f2c22a9939c28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E7=94=B5=E8=8A=BD=E8=A1=A3?= Date: Thu, 16 Apr 2026 23:00:48 -0400 Subject: [PATCH] refactor(ConsoleView): hoist Select options into useMemo, name shutdown sentinels, localise close label (P2-25, P2-26, P3-51) Replace options IIFE with memoised runSelectOptions; extract magic-string run-summary filters to SHUTDOWN_SUMMARY/WORKER_CRASH_SUMMARY constants; localise Close console aria-label via console.close key. --- src/renderer/i18n/en.ts | 1 + src/renderer/i18n/zh.ts | 1 + src/renderer/views/ConsoleView.tsx | 22 +++++++++++++++------- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/renderer/i18n/en.ts b/src/renderer/i18n/en.ts index 898333ae..1cb865ca 100644 --- a/src/renderer/i18n/en.ts +++ b/src/renderer/i18n/en.ts @@ -275,6 +275,7 @@ export const en: Record = { // ── Console panel ── "console.title": "Console", "console.noRuns": "No runs", + "console.close": "Close console", // ── Entity labels (command palette sections) ── "entity.sections": "Sections", diff --git a/src/renderer/i18n/zh.ts b/src/renderer/i18n/zh.ts index b7b3db67..72d96bb1 100644 --- a/src/renderer/i18n/zh.ts +++ b/src/renderer/i18n/zh.ts @@ -275,6 +275,7 @@ export const zh: Record = { // ── 控制台面板 ── "console.title": "控制台", "console.noRuns": "暂无运行", + "console.close": "关闭控制台", // ── 实体标签(命令面板分类) ── "entity.sections": "版块", diff --git a/src/renderer/views/ConsoleView.tsx b/src/renderer/views/ConsoleView.tsx index b39eeb1e..4e883b5b 100644 --- a/src/renderer/views/ConsoleView.tsx +++ b/src/renderer/views/ConsoleView.tsx @@ -6,6 +6,11 @@ import { ActionButton, Select, StatusPill } from "../components/ui"; import { formatMoney, formatTime } from "../lib/formatters"; import { useAppStore } from "../state/store"; +// Run summaries that indicate the run is no longer active; these entries +// should not appear in the console run selector. +const SHUTDOWN_SUMMARY = "Application shut down."; +const WORKER_CRASH_SUMMARY = "Worker process crashed."; + interface ConsoleViewProps { consoleOpen: boolean; setConsoleOpen: (value: boolean) => void; @@ -37,6 +42,14 @@ export function ConsoleView({ // the ref contents on re-render. [selectedRun, logRevision, logBufferRef], ); + const runSelectOptions = useMemo(() => { + const activeRuns = runs.filter( + (run) => run.summary !== SHUTDOWN_SUMMARY && run.summary !== WORKER_CRASH_SUMMARY, + ); + return activeRuns.length > 0 + ? activeRuns.map((run) => ({ value: run.id, label: run.summary || `Run ${run.id.slice(0, 8)}` })) + : [{ value: "", label: t("console.noRuns") }]; + }, [runs, t]); return ( {consoleOpen ? ( @@ -57,18 +70,13 @@ export function ConsoleView({ compact value={selectedRun?.id ?? ""} onChange={setSelectedRunId} - options={(() => { - const activeRuns = runs.filter((r) => r.summary !== "Application shut down." && r.summary !== "Worker process crashed."); - return activeRuns.length > 0 - ? activeRuns.map((run) => ({ value: run.id, label: run.summary || `Run ${run.id.slice(0, 8)}` })) - : [{ value: "", label: t("console.noRuns") }]; - })()} + options={runSelectOptions} />