fix(desktop): unarchive from Settings into the session's own sidebar slice
The Settings unarchive prepended the row into $sessions regardless of source, so a messaging or cron session showed under SESSIONS until the next refresh. Route it through restoreListedSession, which picks the slice from the row's source.
This commit is contained in:
60
apps/desktop/src/app/settings/sessions-settings.test.tsx
Normal file
60
apps/desktop/src/app/settings/sessions-settings.test.tsx
Normal file
@@ -0,0 +1,60 @@
|
||||
// @vitest-environment jsdom
|
||||
import { act, cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import { listAllProfileSessions, setSessionArchived } from '@/hermes'
|
||||
import { en } from '@/i18n/en'
|
||||
import { $messagingSessions, $sessions, setMessagingSessions, setSessions } from '@/store/session'
|
||||
import type { SessionInfo } from '@/types/hermes'
|
||||
|
||||
import { SessionsSettings } from './sessions-settings'
|
||||
|
||||
vi.mock('@/i18n', () => ({ useI18n: () => ({ t: en }) }))
|
||||
|
||||
vi.mock('@/hermes', async importOriginal => ({
|
||||
...(await importOriginal<Record<string, unknown>>()),
|
||||
getHermesConfigRecord: vi.fn().mockResolvedValue({ config: {} }),
|
||||
listAllProfileSessions: vi.fn(),
|
||||
setSessionArchived: vi.fn().mockResolvedValue(undefined)
|
||||
}))
|
||||
|
||||
const archivedMatrixSession = {
|
||||
archived: true,
|
||||
ended_at: null,
|
||||
id: 'matrix-1',
|
||||
input_tokens: 0,
|
||||
is_active: false,
|
||||
last_active: 1,
|
||||
message_count: 2,
|
||||
model: null,
|
||||
output_tokens: 0,
|
||||
preview: null,
|
||||
source: 'matrix',
|
||||
started_at: 1,
|
||||
title: 'archived room',
|
||||
tool_call_count: 0
|
||||
} as SessionInfo
|
||||
|
||||
beforeEach(() => {
|
||||
setSessions([])
|
||||
setMessagingSessions([])
|
||||
vi.mocked(listAllProfileSessions).mockResolvedValue({ sessions: [archivedMatrixSession], total: 1 } as never)
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
cleanup()
|
||||
})
|
||||
|
||||
describe('SessionsSettings unarchive', () => {
|
||||
it('restores a messaging-source session into $messagingSessions, not $sessions', async () => {
|
||||
render(<SessionsSettings />)
|
||||
const button = await screen.findByRole('button', { name: en.settings.sessions.unarchive })
|
||||
|
||||
await act(async () => fireEvent.click(button))
|
||||
|
||||
await waitFor(() => expect(setSessionArchived).toHaveBeenCalledWith('matrix-1', false, undefined))
|
||||
expect($messagingSessions.get().map(session => session.id)).toEqual(['matrix-1'])
|
||||
expect($messagingSessions.get()[0]?.archived).toBe(false)
|
||||
expect($sessions.get()).toEqual([])
|
||||
})
|
||||
})
|
||||
@@ -1,5 +1,6 @@
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
|
||||
import { restoreListedSession } from '@/app/session/hooks/use-session-actions/utils'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Tip } from '@/components/ui/tooltip'
|
||||
@@ -17,7 +18,7 @@ import { triggerHaptic } from '@/lib/haptics'
|
||||
import { Archive, ArchiveOff, FolderOpen, Loader2, Trash2 } from '@/lib/icons'
|
||||
import { confirm } from '@/store/confirm'
|
||||
import { notify, notifyError } from '@/store/notifications'
|
||||
import { applyConfiguredDefaultProjectDir, ensureDefaultWorkspaceCwd, setSessions } from '@/store/session'
|
||||
import { applyConfiguredDefaultProjectDir, ensureDefaultWorkspaceCwd } from '@/store/session'
|
||||
import { untombstoneSessions } from '@/store/session-removal'
|
||||
import { forgetSessionUnread } from '@/store/session-unread'
|
||||
import type { HermesConfigRecord, SessionInfo } from '@/types/hermes'
|
||||
@@ -63,7 +64,7 @@ export function SessionsSettings() {
|
||||
// Surface it again in the sidebar without waiting for a full refresh, and
|
||||
// lift any optimistic eviction so the grouped tree shows it again too.
|
||||
untombstoneSessions([session.id, session._lineage_root_id])
|
||||
setSessions(prev => [{ ...session, archived: false }, ...prev.filter(s => s.id !== session.id)])
|
||||
restoreListedSession({ ...session, archived: false })
|
||||
triggerHaptic('selection')
|
||||
notify({ durationMs: 2_000, kind: 'success', message: s.restored })
|
||||
} catch (err) {
|
||||
|
||||
Reference in New Issue
Block a user