From 59dbd9d2aa8b9f63ac2b85b6937b09b16119ed6e Mon Sep 17 00:00:00 2001 From: kongb Date: Fri, 9 Oct 2026 10:54:24 +0800 Subject: [PATCH 1/2] Refine repository card actions and history labels for issue 440 --- .../GlobalChatHistorySheet.test.tsx | 1 + src/components/GlobalChatHistorySheet.tsx | 1 + src/components/RepositoryCard.test.tsx | 13 +++--- src/components/RepositoryCard.tsx | 43 +++++-------------- src/components/RepositoryHealthPanel.test.tsx | 4 +- src/components/SearchBar.tsx | 36 ---------------- src/locales/de/app.json | 2 +- src/locales/de/repositories.json | 2 +- src/locales/en/app.json | 2 +- src/locales/en/repositories.json | 2 +- src/locales/es/app.json | 2 +- src/locales/es/repositories.json | 2 +- src/locales/fr/app.json | 2 +- src/locales/fr/repositories.json | 2 +- src/locales/ja/app.json | 2 +- src/locales/ja/repositories.json | 2 +- src/locales/ko/app.json | 2 +- src/locales/ko/repositories.json | 2 +- src/locales/pt-BR/app.json | 2 +- src/locales/pt-BR/repositories.json | 2 +- src/locales/ru/app.json | 2 +- src/locales/ru/repositories.json | 2 +- src/locales/zh-TW/app.json | 2 +- src/locales/zh-TW/repositories.json | 2 +- src/locales/zh/app.json | 2 +- src/locales/zh/repositories.json | 2 +- 26 files changed, 42 insertions(+), 96 deletions(-) diff --git a/src/components/GlobalChatHistorySheet.test.tsx b/src/components/GlobalChatHistorySheet.test.tsx index 5189cbd18..33bc98d64 100644 --- a/src/components/GlobalChatHistorySheet.test.tsx +++ b/src/components/GlobalChatHistorySheet.test.tsx @@ -41,6 +41,7 @@ describe('GlobalChatHistorySheet', () => { render( {}} onSelectSession={() => {}} />); const items = await screen.findAllByTitle(/进入 owner\//); + expect(screen.getByRole('heading', { name: '问答历史 (2)' })).toBeInTheDocument(); expect(items.map((item) => item.textContent)).toEqual([ expect.stringContaining('title-newer'), expect.stringContaining('title-older'), diff --git a/src/components/GlobalChatHistorySheet.tsx b/src/components/GlobalChatHistorySheet.tsx index a590b5114..3e114fb58 100644 --- a/src/components/GlobalChatHistorySheet.tsx +++ b/src/components/GlobalChatHistorySheet.tsx @@ -115,6 +115,7 @@ export const GlobalChatHistorySheet: React.FC = ({ {t('globalChatHistorySheet.conversations-across-repositories-select-one-to')} diff --git a/src/components/RepositoryCard.test.tsx b/src/components/RepositoryCard.test.tsx index 1bc551504..b5f0b907a 100644 --- a/src/components/RepositoryCard.test.tsx +++ b/src/components/RepositoryCard.test.tsx @@ -210,7 +210,7 @@ describe('RepositoryCard view modes', () => { actionMocks.actions.vectorSearchAvailable = false; renderRepositoryCard('list'); - expect(screen.queryByRole('button', { name: '更多仓库操作' })).not.toBeInTheDocument(); + expect(screen.getByRole('button', { name: '更多仓库操作' })).toBeInTheDocument(); expect(screen.queryByRole('menuitem', { name: '查找同类仓库' })).not.toBeInTheDocument(); expect(screen.queryByText('查找同类')).not.toBeInTheDocument(); } finally { @@ -280,12 +280,15 @@ describe('RepositoryCard view modes', () => { expect(screen.getByTestId('repository-edit-modal')).toBeInTheDocument(); }); - it('delegates grid quick actions to the domain Hook without changing their presentation', async () => { + it('keeps Unstar at the bottom of the grid menu and delegates it to the domain Hook', async () => { const user = userEvent.setup(); renderRepositoryCard('grid'); await user.click(screen.getByTitle('AI分析此仓库')); - await user.click(screen.getByTitle('取消 Star')); + expect(screen.queryByTitle('取消 Star')).not.toBeInTheDocument(); + await user.click(screen.getByRole('button', { name: '更多仓库操作' })); + expect(screen.getAllByRole('menuitem').at(-1)).toHaveTextContent('取消 Star'); + await user.click(screen.getByRole('menuitem', { name: '取消 Star' })); expect(actionMocks.actions.analyze).toHaveBeenCalledOnce(); expect(actionMocks.actions.unstar).toHaveBeenCalledOnce(); @@ -360,10 +363,10 @@ describe('RepositoryCard view modes', () => { expect(screen.queryByTestId('readme-modal')).not.toBeInTheDocument(); }); - it('retains the existing quick action row in grid mode', () => { + it('retains the other quick actions in grid mode', () => { renderRepositoryCard('grid', { onAskRepository: vi.fn() }); - expect(screen.queryByRole('button', { name: '更多仓库操作' })).not.toBeInTheDocument(); + expect(screen.getByRole('button', { name: '更多仓库操作' })).toBeInTheDocument(); expect(screen.getByTitle('AI分析此仓库')).toBeInTheDocument(); expect(screen.getByTitle('问答此仓库')).toBeInTheDocument(); expect(screen.getByTitle('取消订阅发布')).toBeInTheDocument(); diff --git a/src/components/RepositoryCard.tsx b/src/components/RepositoryCard.tsx index eca16a726..9fb529fd0 100644 --- a/src/components/RepositoryCard.tsx +++ b/src/components/RepositoryCard.tsx @@ -198,21 +198,17 @@ const MAX_CACHE_SIZE = 500; const ACTION_SLOT_WIDTH = 32; const ACTION_SLOT_GAP = 6; const ACTION_SLOT_STRIDE = ACTION_SLOT_WIDTH + ACTION_SLOT_GAP; -const BASE_OVERFLOW_ACTION_COUNT = 7; +const BASE_OVERFLOW_ACTION_COUNT = 6; const highlightCache = new Map(); const countVisibleOverflowActions = ( width: number, primaryActionCount: number, - hasPersistentMenu: boolean, ): number => { if (width === 0) return primaryActionCount; const capacity = Math.max(1, Math.floor((width + ACTION_SLOT_GAP) / ACTION_SLOT_STRIDE)); - if (hasPersistentMenu) { - return Math.max(0, Math.min(primaryActionCount, capacity - 1)); - } - return capacity >= primaryActionCount ? primaryActionCount : Math.max(0, capacity - 1); + return Math.max(0, Math.min(primaryActionCount, capacity - 1)); }; const mutedIconButtonClass = @@ -295,9 +291,7 @@ const OverflowActionRow: React.FC = ({ const showReleases = visibleActionCount >= 4 + askSlot; const showDocs = visibleActionCount >= 5 + askSlot; const showGithub = visibleActionCount >= 6 + askSlot; - const showUnstar = visibleActionCount >= 7 + askSlot; const showFindSimilarInMenu = Boolean(vectorSearchAvailable && onFindSimilar && (persistFindSimilarInMenu || visibleActionCount < primaryActionCount)); - const showOverflowMenu = visibleActionCount < primaryActionCount || pluginActions.length > 0 || showFindSimilarInMenu; const menuOpenProps = onActionsMenuOpenChange ? { open: isActionsMenuOpen, onOpenChange: onActionsMenuOpenChange } : {}; @@ -387,19 +381,7 @@ const OverflowActionRow: React.FC = ({ ) : null} - {showUnstar ? ( - - - - ) : null} - {showOverflowMenu ? ( - +