From a59a90e6a1d12126dfed6af0bbbd50bfb2735c74 Mon Sep 17 00:00:00 2001 From: diegosouzapw Date: Sat, 30 May 2026 12:31:08 -0300 Subject: [PATCH] fix(dashboard): v3.8.8 screen quick wins (Phase 1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - search-tools: export modal no longer opens by default / stuck — guard on exportOpen and drop the invalid isOpen prop the modal never read. - logs: remove duplicate proxy/console tabs + SegmentedControl (dedicated /dashboard/logs/proxy and /console pages already exist in the menu). - memory: order tabs Memories -> Engine -> Playground. - ui(Select): render children and suppress the placeholder/options branch when children are provided — fixes the "empty" memory type/strategy dropdowns (children were being shadowed by the component's own option list). - test: source-level regression guards for all four. --- src/app/(dashboard)/dashboard/logs/page.tsx | 45 +++---------------- src/app/(dashboard)/dashboard/memory/page.tsx | 2 +- .../components/SearchToolsTopBar.tsx | 8 +--- src/shared/components/Select.tsx | 19 +++++--- tests/unit/v388-phase1-screen-fixes.test.ts | 35 +++++++++++++++ 5 files changed, 57 insertions(+), 52 deletions(-) create mode 100644 tests/unit/v388-phase1-screen-fixes.test.ts diff --git a/src/app/(dashboard)/dashboard/logs/page.tsx b/src/app/(dashboard)/dashboard/logs/page.tsx index 5ef549d357..40b1271958 100644 --- a/src/app/(dashboard)/dashboard/logs/page.tsx +++ b/src/app/(dashboard)/dashboard/logs/page.tsx @@ -1,9 +1,7 @@ "use client"; import { useState, useRef, useEffect } from "react"; -import { useSearchParams } from "next/navigation"; -import { ConfirmModal, RequestLoggerV2, ProxyLogger, SegmentedControl } from "@/shared/components"; -import ConsoleLogViewer from "@/shared/components/ConsoleLogViewer"; +import { ConfirmModal, RequestLoggerV2 } from "@/shared/components"; import EmailPrivacyToggle from "@/shared/components/EmailPrivacyToggle"; import ActiveRequestsPanel from "@/shared/components/ActiveRequestsPanel"; import { useTranslations } from "next-intl"; @@ -15,18 +13,7 @@ const TIME_RANGES = [ { label: "24h", hours: 24 }, ]; -const TAB_TO_LOG_TYPE: Record = { - "request-logs": "request-logs", - "proxy-logs": "proxy-logs", - console: "call-logs", -}; - export default function LogsPage() { - const searchParams = useSearchParams(); - const requestedTab = searchParams.get("tab"); - const [activeTab, setActiveTab] = useState( - requestedTab && TAB_TO_LOG_TYPE[requestedTab] ? requestedTab : "request-logs" - ); const [showExport, setShowExport] = useState(false); const [exporting, setExporting] = useState(false); const [showCleanHistory, setShowCleanHistory] = useState(false); @@ -36,12 +23,6 @@ export default function LogsPage() { const dropdownRef = useRef(null); const t = useTranslations("logs"); - useEffect(() => { - if (requestedTab && TAB_TO_LOG_TYPE[requestedTab] && requestedTab !== activeTab) { - setActiveTab(requestedTab); - } - }, [activeTab, requestedTab]); - useEffect(() => { function handleClickOutside(e: MouseEvent) { if (dropdownRef.current && !dropdownRef.current.contains(e.target as Node)) { @@ -56,7 +37,7 @@ export default function LogsPage() { setExporting(true); setShowExport(false); try { - const logType = TAB_TO_LOG_TYPE[activeTab] || "call-logs"; + const logType = "request-logs"; const res = await fetch(`/api/logs/export?hours=${hours}&type=${logType}`); if (!res.ok) throw new Error(t("exportFailed")); const blob = await res.blob(); @@ -108,15 +89,7 @@ export default function LogsPage() { return (
- +

{t("requestLogs")}

@@ -211,14 +184,10 @@ export default function LogsPage() {
)} - {activeTab === "request-logs" && ( -
- - -
- )} - {activeTab === "proxy-logs" && } - {activeTab === "console" && } +
+ + +
- {exportState && ( - setExportOpen(false)} - state={exportState} - /> + {exportOpen && exportState != null && ( + setExportOpen(false)} state={exportState} /> )} ); diff --git a/src/shared/components/Select.tsx b/src/shared/components/Select.tsx index 5284aecdee..8abcfd7755 100644 --- a/src/shared/components/Select.tsx +++ b/src/shared/components/Select.tsx @@ -30,6 +30,7 @@ export default function Select({ className, selectClassName, id: externalId, + children, ...props }: SelectProps) { const generatedId = useId(); @@ -71,14 +72,18 @@ export default function Select({ )} {...props} > - - {options.map((option) => ( - - ))} + )} + {!children && + options.map((option) => ( + + ))} + {children}
readFileSync(join(root, p), "utf8"); + +test("search-tools: export modal mounts on exportOpen (not by default) without invalid isOpen prop", () => { + const src = read("src/app/(dashboard)/dashboard/search-tools/components/SearchToolsTopBar.tsx"); + assert.ok(src.includes("{exportOpen && exportState != null && ("), "modal guarded by exportOpen"); + assert.equal(/]*\bisOpen=/.test(src), false, "no invalid isOpen prop on ExportCodeModal"); +}); + +test("memory: tabs ordered memories -> engine -> playground", () => { + const src = read("src/app/(dashboard)/dashboard/memory/page.tsx"); + assert.ok(src.includes('["memories", "engine", "playground"]'), "TABS order is memories, engine, playground"); +}); + +test("shared Select: renders children and guards placeholder/options when children present", () => { + const src = read("src/shared/components/Select.tsx"); + assert.ok(src.includes("{children}"), "renders children passed by callers"); + assert.ok(src.includes("!children && placeholder"), "placeholder guarded by !children"); + assert.ok(src.includes("!children &&\n options.map") || src.includes("!children &&"), "options guarded by !children"); +}); + +test("logs: proxy/console tabs removed (dedicated menu pages exist)", () => { + const src = read("src/app/(dashboard)/dashboard/logs/page.tsx"); + assert.equal(/value:\s*"proxy-logs"/.test(src), false, "proxy-logs tab removed"); + assert.equal(/value:\s*"console"/.test(src), false, "console tab removed"); + assert.equal(src.includes("