This commit is contained in:
Ian Gulliver
2026-10-15 22:21:20 -07:00
parent 84de97cec9
commit a1a4b83f39
22 changed files with 171 additions and 204 deletions
+70 -4
View File
@@ -4,11 +4,13 @@ import { h, replace } from "./dom.js";
import { mountFiles } from "./files.js";
import { mountInbox } from "./inbox.js";
import { mountLead } from "./lead.js";
import { openSwitcher } from "./navbar.js";
import { findTask, focusedProject, focusTab, on, onEach, state, tabs } from "./state.js";
import { mountPreview } from "./preview.js";
import { mountProject } from "./project.js";
import { isReviewEvent, latestFindingCount, mountReviews } from "./reviews.js";
import { mountSettings } from "./settings.js";
import { mountStatus } from "./status.js";
import { openSwitcher } from "./switcher.js";
import { mountTranscript } from "./task.js";
import { mountTerminal } from "./terminal.js";
@@ -23,10 +25,74 @@ const views: Record<TaskTab, { label: string; mount: (root: HTMLElement) => () =
project: { label: "Project", mount: mountProject },
};
type LeftTab = "lead" | "status" | "settings";
const leftViews: Record<Exclude<LeftTab, "lead">, { label: string; mount: (root: HTMLElement) => () => void }> = {
status: { label: "Status", mount: mountStatus },
settings: { label: "Settings", mount: mountSettings },
};
let showLeft: (tab: LeftTab) => void = () => {};
export function focusLead(): void {
showLeft("lead");
document.querySelector<HTMLTextAreaElement>(".view-lead .composer textarea")?.focus();
}
export function leadPane(): HTMLElement {
const root = h("div", { class: "view view-lead" });
mountLead(root);
return h("section", { class: "pane" }, h("nav", { class: "pane-tabs" }, h("button", { class: "active" }, "Lead")), h("div", { class: "pane-body" }, root));
const lead = h("div", { class: "view view-lead" });
mountLead(lead);
let other = h("div", { class: "view", hidden: true });
const buttons: Record<LeftTab, HTMLButtonElement> = {
lead: h("button", {}, "Lead"),
status: h("button", {}, leftViews.status.label),
settings: h("button", {}, leftViews.settings.label),
};
let shown: LeftTab | undefined;
let dispose: () => void = () => {};
showLeft = (tab) => {
if (tab === shown) {
return;
}
dispose();
dispose = () => {};
shown = tab;
for (const [t, button] of Object.entries(buttons)) {
button.classList.toggle("active", t === tab);
}
lead.hidden = tab !== "lead";
const root = h("div", { class: tab === "lead" ? "view" : `view view-${tab}`, hidden: tab === "lead" });
other.replaceWith(root);
other = root;
if (tab === "lead") {
return;
}
dispose = leftViews[tab].mount(root);
};
for (const [t, button] of Object.entries(buttons)) {
button.onclick = () => showLeft(t as LeftTab);
}
const conn = h("span", { class: "connection down", title: "connecting" });
const connLabel = h("span", { class: "connection-label" }, "reconnecting…");
const me = h("span", { class: "me" });
const renderConn = () => {
conn.className = state.connected ? "connection up" : "connection down";
conn.title = state.connected ? "live" : "reconnecting";
connLabel.hidden = state.connected;
replace(me, state.me?.display_name ?? "");
};
onEach(["me", "connection"], renderConn);
renderConn();
showLeft("lead");
return h(
"section",
{ class: "pane" },
h("nav", { class: "pane-tabs" }, buttons.lead, buttons.status, buttons.settings, h("span", { class: "pane-status" }, connLabel, conn, me)),
h("div", { class: "pane-body" }, lead, other),
);
}
export function taskPane(): HTMLElement {