diff --git a/src/client/src/appActions.test.ts b/src/client/src/appActions.test.ts index 089efe7..53caf64 100644 --- a/src/client/src/appActions.test.ts +++ b/src/client/src/appActions.test.ts @@ -1,6 +1,7 @@ import { describe, expect, it, vi } from "vitest"; import { createAppActions } from "./appActions"; import { initialAppState, type AppState } from "./appState"; +import type { SessionInfo } from "./api"; function createContext(statePatch: Partial = {}) { const calls: string[] = []; @@ -13,6 +14,7 @@ function createContext(statePatch: Partial = {}) { refreshFiles: vi.fn(() => { calls.push("refreshFiles"); }), refreshGit: vi.fn(() => { calls.push("refreshGit"); }), startSession: vi.fn(() => { calls.push("startSession"); }), + archiveSession: vi.fn(() => { calls.push("archiveSession"); }), stopActiveWork: vi.fn(() => { calls.push("stopActiveWork"); }), }; return { context, calls }; @@ -25,6 +27,7 @@ describe("createAppActions", () => { expect(actions.find((action) => action.id === "view.files")?.enabled).toBe(false); expect(actions.find((action) => action.id === "session.start")?.enabled).toBe(false); + expect(actions.find((action) => action.id === "session.archive")?.enabled).toBe(false); expect(actions.find((action) => action.id === "session.stop")?.enabled).toBe(false); expect(actions.find((action) => action.id === "actions.show")?.enabled).toBeUndefined(); }); @@ -49,6 +52,24 @@ describe("createAppActions", () => { expect(calls).toEqual(["refreshGit"]); }); + it("enables archive for the selected active session", () => { + const selectedSession = testSession(); + const active = createAppActions(createContext({ selectedSession }).context); + const archived = createAppActions(createContext({ selectedSession: { ...selectedSession, archived: true } }).context); + + expect(active.find((action) => action.id === "session.archive")?.enabled).toBe(true); + expect(archived.find((action) => action.id === "session.archive")?.enabled).toBe(false); + }); + + it("runs archive on the selected session", () => { + const { context, calls } = createContext({ selectedSession: testSession() }); + const action = createAppActions(context).find((candidate) => candidate.id === "session.archive"); + + if (action !== undefined) void action.run(); + + expect(calls).toEqual(["archiveSession"]); + }); + it("only enables stop while a session is actively working", () => { const selectedSession = testSession(); const inactive = createAppActions(createContext({ selectedSession }).context); @@ -63,7 +84,7 @@ function testWorkspace(): AppState["selectedWorkspace"] { return { id: "w1", projectId: "p1", path: "/tmp/project", label: "main", isMain: true, isGitWorktree: false }; } -function testSession(): AppState["selectedSession"] { +function testSession(): SessionInfo { return { id: "s1", path: "/tmp/project/.pi/sessions/s1", cwd: "/tmp/project", created: "now", modified: "now", messageCount: 0, firstMessage: "" }; } diff --git a/src/client/src/appActions.ts b/src/client/src/appActions.ts index 6870c7e..56aadd0 100644 --- a/src/client/src/appActions.ts +++ b/src/client/src/appActions.ts @@ -10,12 +10,14 @@ export interface AppActionContext { refreshFiles: () => void | Promise; refreshGit: () => void | Promise; startSession: () => void | Promise; + archiveSession: () => void | Promise; stopActiveWork: () => void | Promise; } export function createAppActions(context: AppActionContext): AppAction[] { const hasWorkspace = context.state.selectedWorkspace !== undefined; const hasSession = context.state.selectedSession !== undefined; + const canArchiveSession = hasSession && context.state.selectedSession?.archived !== true; const isBusy = isActive(context.state.status); return [ { @@ -95,6 +97,14 @@ export function createAppActions(context: AppActionContext): AppAction[] { enabled: hasWorkspace, run: context.startSession, }, + { + id: "session.archive", + title: "Archive Session", + description: "Archive the selected session", + group: "Session", + enabled: canArchiveSession, + run: context.archiveSession, + }, { id: "session.stop", title: "Stop Active Work", diff --git a/src/client/src/components/PiWebApp.ts b/src/client/src/components/PiWebApp.ts index fa8bdbe..f6d1b58 100644 --- a/src/client/src/components/PiWebApp.ts +++ b/src/client/src/components/PiWebApp.ts @@ -187,6 +187,7 @@ export class PiWebApp extends LitElement { refreshFiles: () => this.files.refreshFiles(), refreshGit: () => this.git.refreshGit(), startSession: () => this.withChatScrollTransition(() => this.sessions.startSession()), + archiveSession: () => this.sessions.archiveSession(), stopActiveWork: () => this.sessions.stopActiveWork(), }); }