Archiv-Wiki im Panel: vier Tabs, FTS5-Suche, strukturierbares Archiv
- Archiv-Home pro Projekt (archiveHome in ai-control.json); archive_panel mit Ordner, Beschreibung und Schlagwörtern (Frontmatter + Zeitstempel-Stem) - Archiv-Index (archive_index.rs): Scan mit Frontmatter, Wikilinks, Backlinks; Wiki-Seiten als strukturierte Daten (Übersicht/Tag-Seiten) - FTS5-Suche (archive_search.rs, rusqlite bundled): in-memory-Index pro Anfrage; MCP search_archive und Panel-Suchfeld (search_run) teilen die Engine - Panel: vier Puffer/Ansichten (Dokument, Befehle, Suche, Wiki) mit Tabs im Fenster-Header; gemeinsame Verdrahtung panel-wiring.ts, Kachel-CSS, Wiki-View mit Tag-Chips, Ordner-Sektionen und Backlinks - Archivieren speichert offene Bearbeitung (flush); Tab-Wechsel speichert statt zu blockieren; Fehler sichtbar als Panel-Toast - Abgelöstes Fenster: rahmenlos (Linux), eigene Kopfleiste mit Tabs und Fensterknöpfen, Theme-Kopplung über gemeinsames themes.ts - MCP-Tools show_commands, show_archive; Befehls-History mit Kachel-Löschen
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
/// Gemeinsame Panel-Verdrahtung für das angedockte Panel (terminal.ts) und
|
||||
/// das abgelöste Fenster (panel.ts): Entwurfs-Ansicht, Befehls- und
|
||||
/// Such-Kacheln, Modus-Umschalter, Wikilink-Klick und die drei Update-Events.
|
||||
/// Die Element-IDs sind in beiden HTML-Dateien identisch; die Draft-Controls
|
||||
/// trägt das Markup als `.draft-only`.
|
||||
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { listen } from "@tauri-apps/api/event";
|
||||
import { initPanelView, type PanelView } from "./panel-view";
|
||||
import {
|
||||
initCommandsView,
|
||||
initPanelMode,
|
||||
panelToast,
|
||||
type CommandsView,
|
||||
type PanelMode,
|
||||
} from "./commands-view";
|
||||
import { initSearchView } from "./search-view";
|
||||
import { initWikiView } from "./wiki-view";
|
||||
import "./panel-tiles.css";
|
||||
|
||||
export interface PanelWiring {
|
||||
view: PanelView;
|
||||
cmdView: CommandsView;
|
||||
mode: { to(m: PanelMode): void; current(): PanelMode };
|
||||
/// Entwurfstext beim Start (für die Anfangs-Modus-Entscheidung).
|
||||
draft: string;
|
||||
}
|
||||
|
||||
export async function wirePanel(
|
||||
project: string,
|
||||
onIncoming?: () => void,
|
||||
): Promise<PanelWiring> {
|
||||
const titleEl = document.querySelector(".panel-title") as HTMLElement;
|
||||
const [defaultLang, draft, cmds, search, wiki] = await Promise.all([
|
||||
invoke<string>("spellcheck_lang"),
|
||||
invoke<string>("panel_read", { project }),
|
||||
invoke<string>("commands_read", { project }),
|
||||
invoke<string>("search_read", { project }),
|
||||
invoke<string>("wiki_read", { project }),
|
||||
]);
|
||||
|
||||
// Jeder Wiki-Sprung (Wikilink, Chip, Suchtreffer) geht als ein Invoke an den
|
||||
// Kern; das Ergebnis kommt über den Wiki-Puffer und `wiki-update` zurück.
|
||||
const openWiki = (name: string) => invoke("wiki_open", { project, name });
|
||||
|
||||
const view = initPanelView({
|
||||
content: document.getElementById("panel-content")!,
|
||||
copyBtn: document.getElementById("panel-copy")!,
|
||||
modeBtn: document.getElementById("panel-mode")!,
|
||||
titleEl,
|
||||
editBtn: document.getElementById("panel-title-edit")!,
|
||||
editContentBtn: document.getElementById("panel-content-edit")!,
|
||||
langSelect: document.getElementById("panel-lang") as HTMLSelectElement,
|
||||
defaultLang,
|
||||
onCommit: (text) => invoke("panel_set", { project, text }),
|
||||
onWikiLink: openWiki,
|
||||
});
|
||||
const cmdView = initCommandsView(document.getElementById("commands-content")!, (line, entry) =>
|
||||
invoke("commands_delete", { project, line, entry }),
|
||||
);
|
||||
const searchView = initSearchView(
|
||||
document.getElementById("search-content")!,
|
||||
(relpath) => openWiki(relpath.split("/").pop()!.replace(/\.md$/, "")),
|
||||
(query) =>
|
||||
void invoke("search_run", { project, query }).catch((e) =>
|
||||
panelToast(`Suche fehlgeschlagen: ${e}`),
|
||||
),
|
||||
);
|
||||
const wikiView = initWikiView(document.getElementById("wiki-content")!, openWiki);
|
||||
const mode = initPanelMode({
|
||||
tabsEl: document.getElementById("panel-tabs")!,
|
||||
draftEls: [
|
||||
document.getElementById("panel-content")!,
|
||||
...document.querySelectorAll<HTMLElement>(".draft-only"),
|
||||
],
|
||||
commandsContent: document.getElementById("commands-content")!,
|
||||
searchContent: document.getElementById("search-content")!,
|
||||
wikiContent: document.getElementById("wiki-content")!,
|
||||
titleEl,
|
||||
flush: () => void view.flush(),
|
||||
});
|
||||
|
||||
view.set(draft);
|
||||
cmdView.set(cmds);
|
||||
searchView.set(search);
|
||||
wikiView.set(wiki);
|
||||
|
||||
// Wiki-Tab bei leerem Puffer (Session-Start): Übersicht direkt laden.
|
||||
document
|
||||
.querySelector<HTMLElement>('#panel-tabs [data-mode="wiki"]')!
|
||||
.addEventListener("click", () => {
|
||||
if (wikiView.empty()) void openWiki("tag:");
|
||||
});
|
||||
|
||||
await listen<string>("panel-update", (e) => {
|
||||
view.set(e.payload);
|
||||
mode.to("draft");
|
||||
onIncoming?.();
|
||||
});
|
||||
await listen<string>("commands-update", (e) => {
|
||||
cmdView.set(e.payload);
|
||||
mode.to("commands");
|
||||
onIncoming?.();
|
||||
});
|
||||
await listen<string>("search-update", (e) => {
|
||||
searchView.set(e.payload);
|
||||
mode.to("search");
|
||||
onIncoming?.();
|
||||
});
|
||||
await listen<string>("wiki-update", (e) => {
|
||||
wikiView.set(e.payload);
|
||||
mode.to("wiki");
|
||||
onIncoming?.();
|
||||
});
|
||||
|
||||
return { view, cmdView, mode, draft };
|
||||
}
|
||||
Reference in New Issue
Block a user