summaryrefslogtreecommitdiffhomepage
path: root/src/features/workspaces/ui/WorkspacesHome.svelte
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-09-20 16:55:12 +0900
committerAdam Malczewski <[email protected]>2026-09-20 16:55:12 +0900
commitcaf7060ec571039102acd7b4fd73008fdecbe8a9 (patch)
tree7eac6c55556d20021de4a6e19f63d8efaa21ce84 /src/features/workspaces/ui/WorkspacesHome.svelte
parent72663945ef0a0053fbfd83b168e90f12169a5c3a (diff)
downloaddispatch-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.svelte22
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}