diff options
| author | Adam Malczewski <[email protected]> | 2026-09-20 16:55:12 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-09-20 16:55:12 +0900 |
| commit | caf7060ec571039102acd7b4fd73008fdecbe8a9 (patch) | |
| tree | 7eac6c55556d20021de4a6e19f63d8efaa21ce84 /src/features/workspaces/ui/WorkspacesHome.svelte | |
| parent | 72663945ef0a0053fbfd83b168e90f12169a5c3a (diff) | |
| download | dispatch-web-caf7060ec571039102acd7b4fd73008fdecbe8a9.tar.gz dispatch-web-caf7060ec571039102acd7b4fd73008fdecbe8a9.zip | |
feat(workspaces): archive option + archived-workspaces view
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 /<id>)
- ui/WorkspacesHome: wire the Archive action + the Archived modal
- .dispatch/wire.reference.md + backend-handoff.md: record the contract delta
Diffstat (limited to 'src/features/workspaces/ui/WorkspacesHome.svelte')
| -rw-r--r-- | src/features/workspaces/ui/WorkspacesHome.svelte | 22 |
1 files changed, 22 insertions, 0 deletions
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<void> { + 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)} /> <div bind:this={regionEl} class="min-h-0 w-full flex-1"> @@ -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} <PluginManager {plugins} onClose={() => (managerOpen = false)} /> {/if} + +{#if archivedOpen} + <ArchivedWorkspaces + {store} + onOpen={(id) => openWorkspace(id)} + onClose={() => (archivedOpen = false)} + /> +{/if} |
