mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-16 13:03:31 +08:00
fix(desktop): keep dismissed task progress hidden
Dismissed completed task lists are a user visibility choice for that completed cycle, so polling the same persisted tasks during the next chat turn should not resurrect the bar. The store now keeps the dismissed completion key while the remote reset is in flight, and the markdown renderer gives default lists enough inset so bullets stay inside message cards. Constraint: Preserve future task cycles when new TodoWrite or task updates arrive. Rejected: Clear only the visible task array | polling can rehydrate the same completed list before remote reset finishes Confidence: high Scope-risk: narrow Tested: cd desktop && bun run test -- run src/stores/cliTaskStore.test.ts src/components/markdown/MarkdownRenderer.test.tsx Tested: bun run check:desktop Tested: git diff --check Not-tested: Live Tauri chat session task creation and dismissal
This commit is contained in:
parent
3b1b96022f
commit
ef818f8d8c
@ -57,6 +57,19 @@ describe('MarkdownRenderer', () => {
|
||||
expect(screen.getByText('Body copy.')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('gives default markdown lists enough inset to keep bullets inside message cards', () => {
|
||||
const { container } = render(
|
||||
<MarkdownRenderer content={'- First item\n- Second item'} />,
|
||||
)
|
||||
|
||||
const root = container.firstChild as HTMLDivElement
|
||||
expect(root.className).toContain('prose-ul:pl-5')
|
||||
expect(root.className).toContain('prose-ol:pl-5')
|
||||
expect(root.className).toContain('prose-ul:list-outside')
|
||||
expect(root.className).toContain('prose-ol:list-outside')
|
||||
expect(screen.getByText('First item')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('applies compact prose classes for dense surfaces', () => {
|
||||
const { container } = render(
|
||||
<MarkdownRenderer
|
||||
|
||||
@ -414,7 +414,7 @@ const BASE_PROSE_CLASSES = `markdown-prose prose prose-sm min-w-0 max-w-none bre
|
||||
prose-pre:!bg-transparent prose-pre:!p-0 prose-pre:!shadow-none
|
||||
prose-a:text-[var(--color-text-accent)] prose-a:no-underline prose-a:[overflow-wrap:anywhere] hover:prose-a:underline
|
||||
prose-strong:text-[var(--color-text-primary)]
|
||||
prose-ul:my-2 prose-ol:my-2
|
||||
prose-ul:my-2 prose-ol:my-2 prose-ul:pl-5 prose-ol:pl-5 prose-ul:list-outside prose-ol:list-outside
|
||||
prose-li:my-0.5
|
||||
prose-table:my-0 prose-table:w-full prose-table:table-auto prose-table:text-sm
|
||||
prose-th:bg-[var(--color-surface-info)] prose-th:px-3 prose-th:py-2 prose-th:text-left prose-th:whitespace-normal prose-th:break-words prose-th:align-top prose-th:border-b prose-th:border-[var(--color-border)]
|
||||
|
||||
@ -95,8 +95,8 @@ describe('cliTaskStore', () => {
|
||||
expect(useCLITaskStore.getState()).toMatchObject({
|
||||
tasks: [],
|
||||
resetting: true,
|
||||
completedAndDismissed: false,
|
||||
dismissedCompletionKey: null,
|
||||
completedAndDismissed: true,
|
||||
dismissedCompletionKey: 'session-1::1::Keep current session isolated::completed::::|session-1::2::Second completed task::completed::::',
|
||||
expanded: false,
|
||||
})
|
||||
|
||||
@ -107,6 +107,34 @@ describe('cliTaskStore', () => {
|
||||
expect(useCLITaskStore.getState().resetting).toBe(false)
|
||||
})
|
||||
|
||||
it('keeps a dismissed completed list hidden if polling returns it again', async () => {
|
||||
const completedTasks = [
|
||||
makeTask('session-1', 'completed'),
|
||||
{ ...makeTask('session-1', 'completed'), id: '2', subject: 'Second completed task' },
|
||||
]
|
||||
|
||||
vi.mocked(cliTasksApi.resetTaskList).mockResolvedValue({ ok: true })
|
||||
vi.mocked(cliTasksApi.getTasksForList).mockResolvedValue({ tasks: completedTasks })
|
||||
|
||||
useCLITaskStore.setState({
|
||||
sessionId: 'session-1',
|
||||
tasks: completedTasks,
|
||||
expanded: true,
|
||||
completedAndDismissed: false,
|
||||
dismissedCompletionKey: null,
|
||||
})
|
||||
|
||||
await useCLITaskStore.getState().resetCompletedTasks()
|
||||
await useCLITaskStore.getState().fetchSessionTasks('session-1')
|
||||
|
||||
expect(useCLITaskStore.getState()).toMatchObject({
|
||||
tasks: completedTasks,
|
||||
completedAndDismissed: true,
|
||||
dismissedCompletionKey: 'session-1::1::Keep current session isolated::completed::::|session-1::2::Second completed task::completed::::',
|
||||
expanded: false,
|
||||
})
|
||||
})
|
||||
|
||||
it('refreshes tasks for the currently tracked session by default', async () => {
|
||||
vi.mocked(cliTasksApi.getTasksForList).mockResolvedValue({
|
||||
tasks: [makeTask('session-1', 'in_progress')],
|
||||
|
||||
@ -165,8 +165,8 @@ export const useCLITaskStore = create<CLITaskStore>((set, get) => ({
|
||||
set({
|
||||
tasks: [],
|
||||
resetting: true,
|
||||
completedAndDismissed: false,
|
||||
dismissedCompletionKey: null,
|
||||
completedAndDismissed: true,
|
||||
dismissedCompletionKey: completionKey,
|
||||
expanded: false,
|
||||
})
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user