diff --git a/packages/cli/src/ui/components/messages/Todo.test.tsx b/packages/cli/src/ui/components/messages/Todo.test.tsx index 14ace3b3b7..bae8f694fe 100644 --- a/packages/cli/src/ui/components/messages/Todo.test.tsx +++ b/packages/cli/src/ui/components/messages/Todo.test.tsx @@ -30,36 +30,30 @@ const createTodoHistoryItem = (todos: Todo[]): HistoryItem => ], }) as unknown as HistoryItem; -describe('', () => { - const renderWithUiState = (uiState: Partial) => - render( - - - , - ); +describe.each([true, false])( + ' (showFullTodos: %s)', + (showFullTodos: boolean) => { + const renderWithUiState = (uiState: Partial) => + render( + + + , + ); - it.each([true, false])( - 'renders null when no todos are in the history', - (showFullTodos) => { + it('renders null when no todos are in the history', () => { const { lastFrame } = renderWithUiState({ history: [], showFullTodos }); expect(lastFrame()).toMatchSnapshot(); - }, - ); + }); - it.each([true, false])( - 'renders null when todo list is empty', - (showFullTodos) => { + it('renders null when todo list is empty', () => { const { lastFrame } = renderWithUiState({ history: [createTodoHistoryItem([])], showFullTodos, }); expect(lastFrame()).toMatchSnapshot(); - }, - ); + }); - it.each([true, false])( - 'renders when todos exist but none are in progress', - (showFullTodos) => { + it('renders when todos exist but none are in progress', () => { const { lastFrame } = renderWithUiState({ history: [ createTodoHistoryItem([ @@ -71,12 +65,9 @@ describe('', () => { showFullTodos, }); expect(lastFrame()).toMatchSnapshot(); - }, - ); + }); - it.each([true, false])( - 'renders when todos exist and one is in progress', - (showFullTodos) => { + it('renders when todos exist and one is in progress', () => { const { lastFrame } = renderWithUiState({ history: [ createTodoHistoryItem([ @@ -89,12 +80,9 @@ describe('', () => { showFullTodos, }); expect(lastFrame()).toMatchSnapshot(); - }, - ); + }); - it.each([true, false])( - 'renders a todo list with long descriptions that wrap when full view is on', - (showFullTodos) => { + it('renders a todo list with long descriptions that wrap when full view is on', () => { const { lastFrame } = render( ', () => { , ); expect(lastFrame()).toMatchSnapshot(); - }, - ); - - it('renders the most recent todo list when multiple write_todos calls are in history', () => { - const { lastFrame } = renderWithUiState({ - history: [ - createTodoHistoryItem([ - { description: 'Older Task 1', status: 'completed' }, - { description: 'Older Task 2', status: 'pending' }, - ]), - createTodoHistoryItem([ - { description: 'Newer Task 1', status: 'pending' }, - { description: 'Newer Task 2', status: 'in_progress' }, - ]), - ], - showFullTodos: true, }); - expect(lastFrame()).toMatchSnapshot(); - }); -}); + + it('renders the most recent todo list when multiple write_todos calls are in history', () => { + const { lastFrame } = renderWithUiState({ + history: [ + createTodoHistoryItem([ + { description: 'Older Task 1', status: 'completed' }, + { description: 'Older Task 2', status: 'pending' }, + ]), + createTodoHistoryItem([ + { description: 'Newer Task 1', status: 'pending' }, + { description: 'Newer Task 2', status: 'in_progress' }, + ]), + ], + showFullTodos, + }); + expect(lastFrame()).toMatchSnapshot(); + }); + + it('renders full list when all todos are inactive', () => { + const { lastFrame } = renderWithUiState({ + history: [ + createTodoHistoryItem([ + { description: 'Task 1', status: 'completed' }, + { description: 'Task 2', status: 'cancelled' }, + ]), + ], + showFullTodos, + }); + expect(lastFrame()).toMatchSnapshot(); + }); + }, +); diff --git a/packages/cli/src/ui/components/messages/Todo.tsx b/packages/cli/src/ui/components/messages/Todo.tsx index 73ba528972..c558e0a43a 100644 --- a/packages/cli/src/ui/components/messages/Todo.tsx +++ b/packages/cli/src/ui/components/messages/Todo.tsx @@ -117,7 +117,19 @@ export const TodoTray: React.FC = () => { return todos.todos.find((todo) => todo.status === 'in_progress') || null; }, [todos]); - if (todos === null || !todos.todos || todos.todos.length === 0) { + const hasActiveTodos = useMemo(() => { + if (!todos || !todos.todos) return false; + return todos.todos.some( + (todo) => todo.status === 'pending' || todo.status === 'in_progress', + ); + }, [todos]); + + if ( + todos === null || + !todos.todos || + todos.todos.length === 0 || + (!uiState.showFullTodos && !hasActiveTodos) + ) { return null; } @@ -134,7 +146,7 @@ export const TodoTray: React.FC = () => { {uiState.showFullTodos ? ( - + ) : ( @@ -143,7 +155,7 @@ export const TodoTray: React.FC = () => { {inProgress && ( - + )} diff --git a/packages/cli/src/ui/components/messages/__snapshots__/Todo.test.tsx.snap b/packages/cli/src/ui/components/messages/__snapshots__/Todo.test.tsx.snap index 873bf4d57b..47c202b81b 100644 --- a/packages/cli/src/ui/components/messages/__snapshots__/Todo.test.tsx.snap +++ b/packages/cli/src/ui/components/messages/__snapshots__/Todo.test.tsx.snap @@ -1,6 +1,32 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[` > renders a todo list with long descriptions that wrap when full view is on 1`] = ` +exports[` (showFullTodos: false) > renders a todo list with long descriptions that wrap when full view is on 1`] = ` +"────────────────────────────────────────────────── + Todo 1/2 (ctrl+t to toggle) » This is a very l…" +`; + +exports[` (showFullTodos: false) > renders full list when all todos are inactive 1`] = `""`; + +exports[` (showFullTodos: false) > renders null when no todos are in the history 1`] = `""`; + +exports[` (showFullTodos: false) > renders null when todo list is empty 1`] = `""`; + +exports[` (showFullTodos: false) > renders the most recent todo list when multiple write_todos calls are in history 1`] = ` +"──────────────────────────────────────────────────────────────────────────────────────────────────── + Todo 0/2 (ctrl+t to toggle) » Newer Task 2" +`; + +exports[` (showFullTodos: false) > renders when todos exist and one is in progress 1`] = ` +"──────────────────────────────────────────────────────────────────────────────────────────────────── + Todo 1/3 (ctrl+t to toggle) » Task 2" +`; + +exports[` (showFullTodos: false) > renders when todos exist but none are in progress 1`] = ` +"──────────────────────────────────────────────────────────────────────────────────────────────────── + Todo 1/2 (ctrl+t to toggle)" +`; + +exports[` (showFullTodos: true) > renders a todo list with long descriptions that wrap when full view is on 1`] = ` "────────────────────────────────────────────────── Todo 1/2 (ctrl+t to toggle) @@ -11,20 +37,19 @@ exports[` > renders a todo list with long descriptions that wrap whe description to test wrapping behavior." `; -exports[` > renders a todo list with long descriptions that wrap when full view is on 2`] = ` -"────────────────────────────────────────────────── - Todo 1/2 (ctrl+t to toggle) » This is a very l…" +exports[` (showFullTodos: true) > renders full list when all todos are inactive 1`] = ` +"──────────────────────────────────────────────────────────────────────────────────────────────────── + Todo 1/1 (ctrl+t to toggle) + + ✓ Task 1 + ✗ Task 2" `; -exports[` > renders null when no todos are in the history 1`] = `""`; +exports[` (showFullTodos: true) > renders null when no todos are in the history 1`] = `""`; -exports[` > renders null when no todos are in the history 2`] = `""`; +exports[` (showFullTodos: true) > renders null when todo list is empty 1`] = `""`; -exports[` > renders null when todo list is empty 1`] = `""`; - -exports[` > renders null when todo list is empty 2`] = `""`; - -exports[` > renders the most recent todo list when multiple write_todos calls are in history 1`] = ` +exports[` (showFullTodos: true) > renders the most recent todo list when multiple write_todos calls are in history 1`] = ` "──────────────────────────────────────────────────────────────────────────────────────────────────── Todo 0/2 (ctrl+t to toggle) @@ -32,7 +57,7 @@ exports[` > renders the most recent todo list when multiple write_to » Newer Task 2" `; -exports[` > renders when todos exist and one is in progress 1`] = ` +exports[` (showFullTodos: true) > renders when todos exist and one is in progress 1`] = ` "──────────────────────────────────────────────────────────────────────────────────────────────────── Todo 1/3 (ctrl+t to toggle) @@ -42,12 +67,7 @@ exports[` > renders when todos exist and one is in progress 1`] = ` ✓ Completed Task" `; -exports[` > renders when todos exist and one is in progress 2`] = ` -"──────────────────────────────────────────────────────────────────────────────────────────────────── - Todo 1/3 (ctrl+t to toggle) » Task 2" -`; - -exports[` > renders when todos exist but none are in progress 1`] = ` +exports[` (showFullTodos: true) > renders when todos exist but none are in progress 1`] = ` "──────────────────────────────────────────────────────────────────────────────────────────────────── Todo 1/2 (ctrl+t to toggle) @@ -55,8 +75,3 @@ exports[` > renders when todos exist but none are in progress 1`] = ✗ In Progress Task ✓ Completed Task" `; - -exports[` > renders when todos exist but none are in progress 2`] = ` -"──────────────────────────────────────────────────────────────────────────────────────────────────── - Todo 1/2 (ctrl+t to toggle)" -`;