refactor(electrobun): centralize all shared state into global stores

New stores:
- ui-store.svelte.ts: settingsOpen, paletteOpen, searchOpen, notifDrawerOpen,
  showWizard, settingsCategory, projectToDelete, showAddGroup, newGroupName
- project-tabs-store.svelte.ts: per-project activeTab + activatedTabs via Map

Wired:
- App.svelte: 8 inline $state removed, reads/writes via ui-store
- ProjectCard: activeTab/activatedTabs from project-tabs-store
- SettingsDrawer: activeCategory from ui-store
- CommandPalette: 4 commands call ui-store directly (no CustomEvent dispatch)

Components are now pure view layers reading from stores.
This commit is contained in:
Hibryda 2026-03-23 20:26:07 +01:00
parent c88577a34a
commit 2b1194c809
6 changed files with 230 additions and 60 deletions

View file

@ -13,8 +13,10 @@
loadLastSession,
type AgentStatus, type AgentMessage,
} from './agent-store.svelte.ts';
type ProjectTab = 'model' | 'docs' | 'context' | 'files' | 'ssh' | 'memory' | 'comms' | 'tasks';
import {
getActiveTab, setActiveTab, isTabActivated,
ALL_TABS, type ProjectTab,
} from './project-tabs-store.svelte.ts';
interface Props {
id: string;
@ -117,11 +119,8 @@
showCloneDialog = false;
}
let activeTab = $state<ProjectTab>('model');
// Track which project tabs have been activated (PERSISTED-LAZY pattern)
let activatedTabs = $state<Set<ProjectTab>>(new Set(['model']));
const ALL_TABS: ProjectTab[] = ['model', 'docs', 'context', 'files', 'ssh', 'memory', 'comms', 'tasks'];
// Derived from project-tabs-store for reactive reads
let activeTab = $derived(getActiveTab(id));
// ── Load last session on mount ──────────────────────────────────────
$effect(() => {
@ -129,8 +128,7 @@
});
function setTab(tab: ProjectTab) {
activeTab = tab;
activatedTabs = new Set([...activatedTabs, tab]);
setActiveTab(id, tab);
}
function handleSend(text: string) {