Add a per-user lead agent and make the right pane task-focused

This commit is contained in:
Ian Gulliver
2026-10-15 09:40:30 -07:00
parent d212590cdc
commit bdd1ae48f0
68 changed files with 3332 additions and 1364 deletions
+31 -54
View File
@@ -1,71 +1,48 @@
import { mountAdmin } from "./admin.js";
import { mountChanges } from "./changes.js";
import { h, replace } from "./dom.js";
import { mountFiles } from "./files.js";
import { mountInbox } from "./inbox.js";
import { mountSettings } from "./settings.js";
import { mountLead } from "./lead.js";
import { focusTab, on, state, tabs } from "./state.js";
import { mountTranscript } from "./task.js";
import { mountTasks } from "./tasks.js";
import { mountTodo } from "./todo.js";
const views = {
transcript: { label: "Transcript", mount: mountTranscript },
changes: { label: "Changes", mount: (root) => mountChanges(root) },
files: { label: "Files", mount: mountFiles },
tasks: { label: "Tasks", mount: mountTasks },
todo: { label: "Todo", mount: mountTodo },
inbox: { label: "Inbox", mount: mountInbox },
admin: { label: "Admin", mount: mountAdmin },
settings: { label: "Settings", mount: mountSettings },
todo: { label: "Todo", mount: mountTodo },
};
const order = ["transcript", "changes", "files", "tasks", "todo", "inbox", "admin", "settings"];
const panes = [];
export function openTranscript() {
if (panes.some((p) => p.current() === "transcript")) {
return;
}
(panes.find((p) => p.current() !== "tasks") ?? panes[0])?.show("transcript");
export function leadPane() {
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));
}
export function openChanges(from) {
if (panes.some((p) => p.current() === "changes")) {
return;
}
(panes.find((p) => !p.el.contains(from)) ?? panes[0])?.show("changes");
}
export class Pane {
key;
el;
tabs;
body;
view;
dispose = () => { };
constructor(key, fallback) {
this.key = key;
this.tabs = h("nav", { class: "pane-tabs" });
this.body = h("div", { class: "pane-body" });
this.el = h("section", { class: "pane" }, this.tabs, this.body);
const saved = localStorage.getItem(this.storageKey());
this.view = saved && saved in views ? saved : fallback;
this.show(this.view);
panes.push(this);
}
current() {
return this.view;
}
show(view) {
this.dispose();
this.view = view;
localStorage.setItem(this.storageKey(), view);
replace(this.tabs, ...order.map((v) => {
const b = h("button", { class: v === view ? "active" : "" }, views[v].label);
b.onclick = () => this.show(v);
export function taskPane() {
const strip = h("nav", { class: "pane-tabs" });
const body = h("div", { class: "pane-body" });
let shown;
let dispose = () => { };
const render = () => {
const first = state.focus.tabs.filter((t, i, all) => tabs.includes(t) && all.indexOf(t) === i);
const order = [...first, ...tabs.filter((t) => !first.includes(t))];
const tab = state.focus.tab;
replace(strip, ...order.map((t) => {
const b = h("button", { class: t === tab ? "active" : "" }, views[t].label);
b.onclick = () => focusTab(t);
return b;
}));
const root = h("div", { class: `view view-${view}` });
replace(this.body, root);
this.dispose = views[view].mount(root);
}
storageKey() {
return `byre.pane.${this.key}`;
}
if (tab === shown) {
return;
}
dispose();
shown = tab;
const root = h("div", { class: `view view-${tab}` });
replace(body, root);
dispose = views[tab].mount(root);
};
on("focus", render);
render();
return h("section", { class: "pane" }, strip, body);
}
//# sourceMappingURL=panes.js.map