diff --git a/client/src/components/Admin/AdminPluginsPanel.tsx b/client/src/components/Admin/AdminPluginsPanel.tsx index ac0810d60..c66841ef2 100644 --- a/client/src/components/Admin/AdminPluginsPanel.tsx +++ b/client/src/components/Admin/AdminPluginsPanel.tsx @@ -2,7 +2,7 @@ import { useEffect, useMemo, useState } from 'react' import { Blocks, AlertTriangle, PackageOpen, RefreshCw, Trash2, Download, Bug, X, ShieldCheck, ArrowUpCircle, Github, ExternalLink, ChevronDown, Check, Lock, Search, - SlidersHorizontal, MoreHorizontal, RotateCw, ArrowRight, Database, Users, LayoutDashboard, + SlidersHorizontal, ArrowUpDown, CircleDot, MoreHorizontal, RotateCw, ArrowRight, Database, Users, LayoutDashboard, Radio, Luggage, Plane, Globe, Image, CalendarDays, Map, Bell, Cloud, Camera, Compass, BookOpen, Wallet, Puzzle, } from 'lucide-react' @@ -267,7 +267,7 @@ export default function AdminPluginsPanel() { {/* Click-away layer for any open dropdown (filters or a row's ⋯ menu). */} {menu &&
setMenu(null)} />} {/* Header */} -
+

{t('admin.plugins.title')}

@@ -283,7 +283,7 @@ export default function AdminPluginsPanel() { {/* Runtime-disabled notice */} {!runtimeOn && !loading && !error && ( -
+

{t('admin.plugins.disabledTitle')}

@@ -292,15 +292,23 @@ export default function AdminPluginsPanel() {
)} - {/* Toolbar */} + {/* Toolbar — on mobile: tabs+rescan, then full-width search, then a + right-aligned filter row. On sm+ the wrappers collapse (sm:contents) + so everything sits in one wrapping row. */} {runtimeOn && !loading && !error && ( -
-
- setView('installed')} label={t('admin.plugins.installed')} count={plugins.length} /> - +
+
+
+ setView('installed')} label={t('admin.plugins.installed')} count={plugins.length} /> + +
+
-
+
setQ(e.target.value)} type="search" @@ -309,33 +317,35 @@ export default function AdminPluginsPanel() { />
- } - options={[ - ['all', t('admin.plugins.allTypes')], ['widget', t('admin.plugins.type.widget')], - ['integration', t('admin.plugins.type.integration')], ['page', t('admin.plugins.type.page')], - ]} - valueLabel={typeFilter === 'all' ? t('admin.plugins.allTypes') : t(`admin.plugins.type.${typeFilter}` as never)} - onPick={v => setTypeFilter(v as TypeFilter)} /> - - {view === 'installed' && ( - + } options={[ - ['all', t('admin.plugins.allStatuses')], ['on', t('admin.plugins.status.active')], ['off', t('admin.plugins.stateOff')], - ['update', t('admin.plugins.filterUpdate')], ['err', t('admin.plugins.status.error')], + ['all', t('admin.plugins.allTypes')], ['widget', t('admin.plugins.type.widget')], + ['integration', t('admin.plugins.type.integration')], ['page', t('admin.plugins.type.page')], ]} - valueLabel={statusLabel(statusFilter, t)} - onPick={v => setStatusFilter(v as StatusFilter)} /> - )} + valueLabel={typeFilter === 'all' ? t('admin.plugins.allTypes') : t(`admin.plugins.type.${typeFilter}` as never)} + onPick={v => setTypeFilter(v as TypeFilter)} /> - setSort(v as SortKey)} /> + {view === 'installed' && ( + } + options={[ + ['all', t('admin.plugins.allStatuses')], ['on', t('admin.plugins.status.active')], ['off', t('admin.plugins.stateOff')], + ['update', t('admin.plugins.filterUpdate')], ['err', t('admin.plugins.status.error')], + ]} + valueLabel={statusLabel(statusFilter, t)} + onPick={v => setStatusFilter(v as StatusFilter)} /> + )} - + } + options={[['name', t('admin.plugins.sortName')], ['recent', t('admin.plugins.sortRecent')], ['updates', t('admin.plugins.sortUpdates')]]} + valueLabel={sortLabel(sort, t)} + onPick={v => setSort(v as SortKey)} /> + + +
)} @@ -351,9 +361,9 @@ export default function AdminPluginsPanel() { ) : plugins.length === 0 ? ( ) : ( -
+
{updatable.length > 0 && statusFilter !== 'err' && ( -
+
{t('admin.plugins.updatesAvailable', { count: updatable.length })} {open && ( -
+
{options.map(([v, lbl]) => ( )} @@ -618,7 +628,7 @@ function RegistryGrid({ items, onInstall, onOpenDetail, busy, t, installedIds, f
) return ( -
+
{items.map(item => { const installed = installedIds.has(item.id) return ( @@ -694,7 +704,7 @@ function PluginDetailModal({ item, installed, busy, onInstall, onClose, t, local
-
+
@@ -706,12 +716,12 @@ function PluginDetailModal({ item, installed, busy, onInstall, onClose, t, local

{item.author}{item.latest ? ` · v${item.latest}` : ''}

-
+

{item.description}

{failed &&

{t('admin.plugins.detailError')}

} @@ -774,7 +784,7 @@ function PluginDetailModal({ item, installed, busy, onInstall, onClose, t, local
-