From 562fbb3ff76a0b9466ca942770ccbf812ff6397e Mon Sep 17 00:00:00 2001 From: defi-failure <159208748+defi-failure@users.noreply.github.com> Date: Fri, 31 Oct 2025 22:28:25 +0800 Subject: [PATCH] fix: minor ui tweak of plugin installation interface (#11085) * fix: use dropdown instead of chip filter * fix: add padding to avoid scroll bar overlap * fix: set max card grid col to 2 * fix: minor ui tweak for plugin card * fix: remove redundant args * fix(i18n): Auto update translations for PR #11085 * fix: cleanup comments --------- Co-authored-by: GitHub Action --- src/renderer/src/i18n/translate/pt-pt.json | 24 ++-- src/renderer/src/i18n/translate/ru-ru.json | 6 +- .../settings/AgentSettings/PluginSettings.tsx | 4 +- .../components/CategoryFilter.tsx | 53 -------- .../components/PluginBrowser.tsx | 127 +++++++++++++----- .../AgentSettings/components/PluginCard.tsx | 15 ++- .../AgentSettings/components/index.ts | 2 - 7 files changed, 121 insertions(+), 110 deletions(-) delete mode 100644 src/renderer/src/pages/settings/AgentSettings/components/CategoryFilter.tsx diff --git a/src/renderer/src/i18n/translate/pt-pt.json b/src/renderer/src/i18n/translate/pt-pt.json index 75c4db55e9..aa185cb07d 100644 --- a/src/renderer/src/i18n/translate/pt-pt.json +++ b/src/renderer/src/i18n/translate/pt-pt.json @@ -3052,10 +3052,10 @@ "connection_failed": "Falha na conexão", "content": "Certifique-se de que o computador e o telefone estejam na mesma rede para usar a transferência via LAN. Abra o aplicativo Cherry Studio e escaneie este código QR.", "error": { - "init_failed": "[to be translated]:Initialization failed", + "init_failed": "Falha na inicialização", "no_file": "Nenhum arquivo selecionado", - "no_ip": "[to be translated]:Unable to get IP address", - "send_failed": "[to be translated]:Failed to send file" + "no_ip": "Incapaz de obter endereço IP", + "send_failed": "Falha ao enviar arquivo" }, "force_close": "Forçar Fechamento", "generating_qr": "Gerando código QR...", @@ -3064,15 +3064,15 @@ "selectZip": "Selecionar arquivo compactado", "sendZip": "Iniciar recuperação de dados", "status": { - "completed": "[to be translated]:Transfer completed", - "connected": "[to be translated]:Connected", - "connecting": "[to be translated]:Connecting...", - "disconnected": "[to be translated]:Disconnected", - "error": "[to be translated]:Connection error", - "initializing": "[to be translated]:Initializing connection...", - "preparing": "[to be translated]:Preparing transfer...", - "sending": "[to be translated]:Transferring {{progress}}%", - "waiting_qr_scan": "[to be translated]:Please scan QR code to connect" + "completed": "Transferência concluída", + "connected": "Conectado", + "connecting": "Conectando...", + "disconnected": "Desconectado", + "error": "Erro de conexão", + "initializing": "Inicializando conexão...", + "preparing": "Preparando transferência...", + "sending": "Transferindo {{progress}}%", + "waiting_qr_scan": "Por favor, escaneie o código QR para conectar" }, "title": "transmissão de rede local", "transfer_progress": "Progresso da transferência" diff --git a/src/renderer/src/i18n/translate/ru-ru.json b/src/renderer/src/i18n/translate/ru-ru.json index f86e16ff2f..8df5ef6630 100644 --- a/src/renderer/src/i18n/translate/ru-ru.json +++ b/src/renderer/src/i18n/translate/ru-ru.json @@ -1047,7 +1047,7 @@ "clear": "Очистить", "close": "Закрыть", "collapse": "Свернуть", - "completed": "[to be translated]:Completed", + "completed": "Завершено", "confirm": "Подтверждение", "copied": "Скопировано", "copy": "Копировать", @@ -3043,7 +3043,7 @@ "confirm": { "button": "Выберите файл резервной копии" }, - "content": "[to be translated]:导出部分数据,包括聊天记录、设置。请注意,备份过程可能需要一些时间,感谢您的耐心等待。", + "content": "Экспорт части данных, включая чат и настройки. Пожалуйста, обратите внимание, что процесс резервного копирования может занять некоторое время. Благодарим за ваше терпение.", "lan": { "auto_close_tip": "Автоматическое закрытие через {{seconds}} секунд...", "confirm_close_message": "Передача файла в процессе. Закрытие прервет передачу. Вы уверены, что хотите принудительно закрыть?", @@ -3077,7 +3077,7 @@ "title": "Передача по локальной сети", "transfer_progress": "Прогресс передачи" }, - "title": "[to be translated]:导出至手机" + "title": "Экспорт на телефон" }, "hour_interval_one": "{{count}} час", "hour_interval_other": "{{count}} часов", diff --git a/src/renderer/src/pages/settings/AgentSettings/PluginSettings.tsx b/src/renderer/src/pages/settings/AgentSettings/PluginSettings.tsx index aa7bb93ea4..fec28b13a0 100644 --- a/src/renderer/src/pages/settings/AgentSettings/PluginSettings.tsx +++ b/src/renderer/src/pages/settings/AgentSettings/PluginSettings.tsx @@ -63,7 +63,7 @@ const PluginSettings: FC = ({ agentBase }) => { panel: 'w-full flex-1 overflow-hidden' }}> -
+
{errorAvailable ? ( @@ -88,7 +88,7 @@ const PluginSettings: FC = ({ agentBase }) => { -
+
{errorInstalled ? ( diff --git a/src/renderer/src/pages/settings/AgentSettings/components/CategoryFilter.tsx b/src/renderer/src/pages/settings/AgentSettings/components/CategoryFilter.tsx deleted file mode 100644 index c9ecee2814..0000000000 --- a/src/renderer/src/pages/settings/AgentSettings/components/CategoryFilter.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import { Chip } from '@heroui/react' -import { FC } from 'react' -import { useTranslation } from 'react-i18next' - -export interface CategoryFilterProps { - categories: string[] - selectedCategories: string[] - onChange: (categories: string[]) => void -} - -export const CategoryFilter: FC = ({ categories, selectedCategories, onChange }) => { - const { t } = useTranslation() - - const isAllSelected = selectedCategories.length === 0 - - const handleCategoryClick = (category: string) => { - if (selectedCategories.includes(category)) { - onChange(selectedCategories.filter((c) => c !== category)) - } else { - onChange([...selectedCategories, category]) - } - } - - const handleAllClick = () => { - onChange([]) - } - - return ( -
- - {t('plugins.all_categories')} - - - {categories.map((category) => { - const isSelected = selectedCategories.includes(category) - return ( - handleCategoryClick(category)} - className="cursor-pointer"> - {category} - - ) - })} -
- ) -} diff --git a/src/renderer/src/pages/settings/AgentSettings/components/PluginBrowser.tsx b/src/renderer/src/pages/settings/AgentSettings/components/PluginBrowser.tsx index 3f034e5ec4..af9f5d357c 100644 --- a/src/renderer/src/pages/settings/AgentSettings/components/PluginBrowser.tsx +++ b/src/renderer/src/pages/settings/AgentSettings/components/PluginBrowser.tsx @@ -1,10 +1,19 @@ -import { Input, Pagination, Tab, Tabs } from '@heroui/react' +import { + Button, + Dropdown, + DropdownItem, + DropdownMenu, + DropdownTrigger, + Input, + Pagination, + Tab, + Tabs +} from '@heroui/react' import { InstalledPlugin, PluginMetadata } from '@renderer/types/plugin' -import { Search } from 'lucide-react' +import { Filter, Search } from 'lucide-react' import { FC, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' -import { CategoryFilter } from './CategoryFilter' import { PluginCard } from './PluginCard' import { PluginDetailModal } from './PluginDetailModal' @@ -122,8 +131,13 @@ export const PluginBrowser: FC = ({ setCurrentPage(1) } - const handleCategoryChange = (categories: string[]) => { - setSelectedCategories(categories) + const handleCategoryChange = (keys: Set) => { + // Reset if "all" selected, otherwise filter categories + if (keys.has('all') || keys.size === 0) { + setSelectedCategories([]) + } else { + setSelectedCategories(Array.from(keys).filter((key) => key !== 'all')) + } setCurrentPage(1) } @@ -144,25 +158,71 @@ export const PluginBrowser: FC = ({ return (
- {/* Search Input */} - } - isClearable - classNames={{ - input: 'text-small', - inputWrapper: 'h-10' - }} - /> + {/* Search and Filter */} +
+ } + isClearable + classNames={{ + input: 'text-small', + inputWrapper: 'h-10' + }} + className="flex-1" + /> - {/* Category Filter */} - + + + + + ({ key: category, label: category })) + ]}> + {(item) => { + const isSelected = + item.key === 'all' ? selectedCategories.length === 0 : selectedCategories.includes(item.key) + + return ( + { + if (item.key === 'all') { + handleCategoryChange(new Set(['all'])) + } else { + const newKeys = selectedCategories.includes(item.key) + ? new Set(selectedCategories.filter((c) => c !== item.key)) + : new Set([...selectedCategories, item.key]) + handleCategoryChange(newKeys) + } + }} + className={isSelected ? 'bg-primary-50' : ''}> + {item.label} + {isSelected && } + + ) + }} + + +
{/* Type Tabs */} @@ -184,21 +244,22 @@ export const PluginBrowser: FC = ({

{t('plugins.try_different_search')}

) : ( -
+
{paginatedPlugins.map((plugin) => { const installed = isPluginInstalled(plugin) const isActioning = actioningPlugin === plugin.sourcePath return ( - handleInstall(plugin)} - onUninstall={() => handleUninstall(plugin)} - loading={loading || isActioning} - onClick={() => handlePluginClick(plugin)} - /> +
+ handleInstall(plugin)} + onUninstall={() => handleUninstall(plugin)} + loading={loading || isActioning} + onClick={() => handlePluginClick(plugin)} + /> +
) })}
diff --git a/src/renderer/src/pages/settings/AgentSettings/components/PluginCard.tsx b/src/renderer/src/pages/settings/AgentSettings/components/PluginCard.tsx index ddf89adad7..a82a9e7726 100644 --- a/src/renderer/src/pages/settings/AgentSettings/components/PluginCard.tsx +++ b/src/renderer/src/pages/settings/AgentSettings/components/PluginCard.tsx @@ -17,14 +17,19 @@ export const PluginCard: FC = ({ plugin, installed, onInstall, const { t } = useTranslation() return ( - + -
-

{plugin.name}

+
+

{plugin.name}

+ color={plugin.type === 'agent' ? 'primary' : plugin.type === 'skill' ? 'success' : 'secondary'} + className="h-4 min-w-0 flex-shrink-0 px-0.5" + style={{ fontSize: '10px' }}> {plugin.type}
@@ -33,7 +38,7 @@ export const PluginCard: FC = ({ plugin, installed, onInstall, - +

{plugin.description || t('plugins.no_description')}

{plugin.tags && plugin.tags.length > 0 && ( diff --git a/src/renderer/src/pages/settings/AgentSettings/components/index.ts b/src/renderer/src/pages/settings/AgentSettings/components/index.ts index 9cdb704545..6c6873f7ed 100644 --- a/src/renderer/src/pages/settings/AgentSettings/components/index.ts +++ b/src/renderer/src/pages/settings/AgentSettings/components/index.ts @@ -1,5 +1,3 @@ -export type { CategoryFilterProps } from './CategoryFilter' -export { CategoryFilter } from './CategoryFilter' export type { InstalledPluginsListProps } from './InstalledPluginsList' export { InstalledPluginsList } from './InstalledPluginsList' export type { PluginBrowserProps } from './PluginBrowser'