feat(web): add Agent Studio workspace UI
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
import { Activity, MessageSquare, PanelsTopLeft } from "lucide-react";
|
||||
import { useEffect, useState, type ReactNode } from "react";
|
||||
import { TopBar, type TopBarProps } from "../topbar/TopBar.js";
|
||||
|
||||
type WorkspaceTab = "chat" | "skills" | "events";
|
||||
|
||||
export function AppShell({ topBar, skills, chat, timeline }: { topBar: TopBarProps; skills: ReactNode; chat: ReactNode; timeline: ReactNode }) {
|
||||
const [activeTab, setActiveTab] = useState<WorkspaceTab>("chat");
|
||||
const [mobile, setMobile] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window.matchMedia !== "function") return undefined;
|
||||
const media = window.matchMedia("(max-width: 720px)");
|
||||
const update = () => setMobile(media.matches);
|
||||
update();
|
||||
media.addEventListener("change", update);
|
||||
return () => media.removeEventListener("change", update);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="app-shell">
|
||||
<TopBar {...topBar} />
|
||||
<nav className="mobile-tabs" aria-label="工作区导航" role="tablist">
|
||||
<TabButton id="chat" active={activeTab === "chat"} onSelect={setActiveTab}><MessageSquare size={17} />Chat</TabButton>
|
||||
<TabButton id="skills" active={activeTab === "skills"} onSelect={setActiveTab}><PanelsTopLeft size={17} />Skills</TabButton>
|
||||
<TabButton id="events" active={activeTab === "events"} onSelect={setActiveTab}><Activity size={17} />Events</TabButton>
|
||||
</nav>
|
||||
<div className="workspace-grid">
|
||||
<div id="skills-panel" role={mobile ? "tabpanel" : undefined} hidden={mobile && activeTab !== "skills"}>{skills}</div>
|
||||
<div id="chat-panel" role={mobile ? "tabpanel" : undefined} hidden={mobile && activeTab !== "chat"}>{chat}</div>
|
||||
<div id="events-panel" role={mobile ? "tabpanel" : undefined} hidden={mobile && activeTab !== "events"}>{timeline}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function TabButton({ id, active, onSelect, children }: { id: WorkspaceTab; active: boolean; onSelect: (tab: WorkspaceTab) => void; children: ReactNode }) {
|
||||
return (
|
||||
<button type="button" role="tab" aria-selected={active} aria-controls={`${id}-panel`} tabIndex={active ? 0 : -1} onClick={() => onSelect(id)}>
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user