From 181f3e01261d255af62aae1af8613a30555e867b Mon Sep 17 00:00:00 2001 From: Jiawei Zhao Date: Mon, 31 Aug 2026 22:03:32 +0800 Subject: [PATCH 1/3] fix(desktop): simplify archived task actions Archived task rows mixed a text action with a one-item overflow menu. Direct icon actions make both choices visible without redundant chrome. CLOSES #4370 Signed-off-by: Jiawei Zhao --- .../e2e/parent-session-deletion.spec.ts | 12 ++++++ .../renderer/locales/settings-tasks-copy.ts | 18 ++++----- .../renderer/settings/tasks-settings-page.tsx | 26 +++++++------ packages/ui/src/__tests__/icons.test.tsx | 39 +++++++++++++++++++ packages/ui/src/icons.tsx | 22 ++++++++++- packages/ui/src/session-history-list.tsx | 6 +-- 6 files changed, 97 insertions(+), 26 deletions(-) create mode 100644 packages/ui/src/__tests__/icons.test.tsx diff --git a/apps/desktop/e2e/parent-session-deletion.spec.ts b/apps/desktop/e2e/parent-session-deletion.spec.ts index c42e4c88ff..6dcb21a218 100644 --- a/apps/desktop/e2e/parent-session-deletion.spec.ts +++ b/apps/desktop/e2e/parent-session-deletion.spec.ts @@ -75,4 +75,16 @@ test('deleting a parent task archives its linked subagent task', async ({ await expect(archivedTasks.getByText(PARENT_REMOVAL_CHILD_NAME, { exact: true })).toBeVisible(); await expect(archivedTasks.getByText(/原父任务已删除/)).toBeVisible(); await expect(archivedTasks.getByText(PARENT_REMOVAL_PARENT_NAME, { exact: true })).toHaveCount(0); + + const unarchive = archivedTasks.getByRole('button', { + name: `取消归档「${PARENT_REMOVAL_CHILD_NAME}」`, + }); + const remove = archivedTasks.getByRole('button', { + name: `彻底删除「${PARENT_REMOVAL_CHILD_NAME}」`, + }); + await expect(unarchive).toBeVisible(); + await expect(remove).toBeVisible(); + await expect(unarchive.locator('svg[aria-hidden="true"]')).toHaveCount(1); + await expect(remove.locator('svg[aria-hidden="true"]')).toHaveCount(1); + await expect(archivedTasks.getByRole('button', { name: /更多操作/ })).toHaveCount(0); }); diff --git a/apps/desktop/src/renderer/locales/settings-tasks-copy.ts b/apps/desktop/src/renderer/locales/settings-tasks-copy.ts index 4bd7d41e33..77442ce65f 100644 --- a/apps/desktop/src/renderer/locales/settings-tasks-copy.ts +++ b/apps/desktop/src/renderer/locales/settings-tasks-copy.ts @@ -51,10 +51,10 @@ export type SettingsTasksCopy = { purgeUnverified: string; noMatchTitle: string; noMatchBody: string; - moreActions(name: string): string; - restore: string; - restoreTask(name: string): string; + unarchive: string; + unarchiveTask(name: string): string; delete: string; + deleteTask(name: string): string; emptyTitle: string; emptyBody: string; }; @@ -80,10 +80,10 @@ const SETTINGS_TASKS_COPY_BY_LOCALE = { purgeUnverified: '任务已删除,但无法读取列表确认结果。请重新打开本页查看。', noMatchTitle: '没有匹配的任务', noMatchBody: '换个关键词试试。', - moreActions: (name: string) => `「${name}」的更多操作`, - restore: '恢复', - restoreTask: (name: string) => `恢复「${name}」`, + unarchive: '取消归档', + unarchiveTask: (name: string) => `取消归档「${name}」`, delete: '彻底删除', + deleteTask: (name: string) => `彻底删除「${name}」`, emptyTitle: '没有已归档的任务', emptyBody: '在侧栏里归档一个任务后,可以在这里恢复或彻底删除它。', }, @@ -115,10 +115,10 @@ const SETTINGS_TASKS_COPY_BY_LOCALE = { purgeUnverified: 'The tasks were deleted, but the list could not be read back to confirm. Reopen this page to check.', noMatchTitle: 'No matching tasks', noMatchBody: 'Try a different search.', - moreActions: (name: string) => `More actions for ${name}`, - restore: 'Restore', - restoreTask: (name: string) => `Restore ${name}`, + unarchive: 'Unarchive', + unarchiveTask: (name: string) => `Unarchive ${name}`, delete: 'Delete', + deleteTask: (name: string) => `Delete ${name}`, emptyTitle: 'Nothing archived', emptyBody: 'Archive a task from the rail to restore or permanently delete it here.', }, diff --git a/apps/desktop/src/renderer/settings/tasks-settings-page.tsx b/apps/desktop/src/renderer/settings/tasks-settings-page.tsx index 2b36e16ee2..42c0eae8be 100644 --- a/apps/desktop/src/renderer/settings/tasks-settings-page.tsx +++ b/apps/desktop/src/renderer/settings/tasks-settings-page.tsx @@ -21,8 +21,8 @@ import { useCallback, useMemo, useState } from 'react'; import type { ProjectRecord } from '@maka/core/project'; import { formatCompactTimestamp } from '@maka/core/relative-time'; import { runtimeHostProfileUsesHostWorkspace } from '@maka/runtime-host/profile-kind'; -import { Button, EmptyState, MoreMenu, useMountedRef, useToast, useUiLocale } from '@maka/ui'; -import { Archive, ICON_SIZE, Search } from '@maka/ui/icons'; +import { Button, EmptyState, IconButton, useMountedRef, useToast, useUiLocale } from '@maka/ui'; +import { Archive, ICON_SIZE, Search, Trash2, Unarchive } from '@maka/ui/icons'; import { HStack, StackItem } from '@astryxdesign/core'; import { List, ListItem } from '@astryxdesign/core/List'; import { TextInput } from '@astryxdesign/core/TextInput'; @@ -236,25 +236,27 @@ export function TasksSettingsPage(props: ArchivedTasksBridge) { startContent={