From caf7060ec571039102acd7b4fd73008fdecbe8a9 Mon Sep 17 00:00:00 2001 From: Adam Malczewski Date: Sun, 20 Sep 2026 16:55:12 +0900 Subject: feat(workspaces): archive option + archived-workspaces view MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Consume the backend's archive contract (feature/archive-workspaces): - adapter/http: archive(id)/unarchive(id) (PUT/DELETE /workspaces/:id/archive); list(archived?) passes the ?archived= query - logic/view-model: pure applyArchived(list, id, archived) - store.svelte: setArchived(id, archived) (optimistic + revert-on-error + reconciling refresh); archivedList + refreshArchived() for the archived view - ui/TileActionBar: new Archive action (the right-click→select action bar) - ui/HomeHeader: new Archived button opens the archived view - ui/ArchivedWorkspaces (new): modal listing archived workspaces with Unarchive + View (navigates to /) - ui/WorkspacesHome: wire the Archive action + the Archived modal - .dispatch/wire.reference.md + backend-handoff.md: record the contract delta --- src/features/workspaces/ui/WorkspacesHome.svelte | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'src/features/workspaces/ui/WorkspacesHome.svelte') diff --git a/src/features/workspaces/ui/WorkspacesHome.svelte b/src/features/workspaces/ui/WorkspacesHome.svelte index 798d1bb..b330e1d 100644 --- a/src/features/workspaces/ui/WorkspacesHome.svelte +++ b/src/features/workspaces/ui/WorkspacesHome.svelte @@ -22,6 +22,7 @@ import TileActionBar from "./TileActionBar.svelte"; import ResizePicker from "./ResizePicker.svelte"; import WorkspaceDetails from "./WorkspaceDetails.svelte"; + import ArchivedWorkspaces from "./ArchivedWorkspaces.svelte"; let { store, @@ -178,6 +179,9 @@ // loads/unloads code (strict layering). let managerOpen = $state(false); + // ── Archived workspaces modal ────────────────────────────────────────────── + let archivedOpen = $state(false); + // ── Actions (the action bar) ─────────────────────────────────────────────── function openWorkspace(id: string): void { deselect(); @@ -203,6 +207,14 @@ await store.setStarred(selected.id, !selected.starred); } + async function archiveSelected(): Promise { + if (!selected) return; + const ws = selected; + // Reversible without a confirm dialog — the workspace is hidden, not deleted. + const result = await store.setArchived(ws.id, true); + if (result.ok) deselect(); + } + // ── Create (header popover): create on the backend — do NOT navigate — // place the new tile in the first empty slot, and go straight into rename. async function createWorkspace( @@ -245,6 +257,7 @@ onCreate={createWorkspace} onOpenPlugins={() => (managerOpen = true)} onSort={() => void sortByRecent()} + onOpenArchived={() => (archivedOpen = true)} />
@@ -294,6 +307,7 @@ onToggleStar={() => void toggleStar()} onDetails={() => (detailsForId = selected.id)} onPlugins={() => (pluginsModalId = selected.id)} + onArchive={() => void archiveSelected()} onDelete={() => void deleteSelected()} onClose={deselect} /> @@ -328,3 +342,11 @@ {#if managerOpen && plugins} (managerOpen = false)} /> {/if} + +{#if archivedOpen} + openWorkspace(id)} + onClose={() => (archivedOpen = false)} + /> +{/if} -- cgit v1.2.3