From 45dc892a54ee67b6096679ff85b4a56d8b61ee90 Mon Sep 17 00:00:00 2001 From: Gykes <24581046+Gykes@users.noreply.github.com> Date: Sun, 4 Jan 2026 22:04:28 -0800 Subject: [PATCH] FR: Hide Already Installed Plugins or Scrapers (#6443) --- .../src/components/Settings/PluginPackageManager.tsx | 11 ++++++++++- .../src/components/Settings/ScraperPackageManager.tsx | 11 ++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/ui/v2.5/src/components/Settings/PluginPackageManager.tsx b/ui/v2.5/src/components/Settings/PluginPackageManager.tsx index ed3160139..d71bea5ee 100644 --- a/ui/v2.5/src/components/Settings/PluginPackageManager.tsx +++ b/ui/v2.5/src/components/Settings/PluginPackageManager.tsx @@ -100,6 +100,12 @@ export const AvailablePluginPackages: React.FC = () => { const [jobID, setJobID] = useState(); const { job } = useMonitorJob(jobID, () => onPackageChanges()); + // Get installed packages to filter them out from available list + const { data: installedData } = useInstalledPluginPackages(false); + const installedPackageIds = new Set( + installedData?.installedPackages?.map((p) => p.package_id) ?? [] + ); + async function onInstallPackages(packages: GQL.PackageSpecInput[]) { const r = await mutateInstallPluginPackages(packages); @@ -114,7 +120,10 @@ export const AvailablePluginPackages: React.FC = () => { async function loadSource(source: string): Promise { const { data } = await queryAvailablePluginPackages(source); - return data.availablePackages; + // Filter out already installed packages + return data.availablePackages.filter( + (pkg) => !installedPackageIds.has(pkg.package_id) + ); } function addSource(source: GQL.PackageSource) { diff --git a/ui/v2.5/src/components/Settings/ScraperPackageManager.tsx b/ui/v2.5/src/components/Settings/ScraperPackageManager.tsx index cb6858610..5c93bc2a3 100644 --- a/ui/v2.5/src/components/Settings/ScraperPackageManager.tsx +++ b/ui/v2.5/src/components/Settings/ScraperPackageManager.tsx @@ -100,6 +100,12 @@ export const AvailableScraperPackages: React.FC = () => { const [jobID, setJobID] = useState(); const { job } = useMonitorJob(jobID, () => onPackageChanges()); + // Get installed packages to filter them out from available list + const { data: installedData } = useInstalledScraperPackages(false); + const installedPackageIds = new Set( + installedData?.installedPackages?.map((p) => p.package_id) ?? [] + ); + async function onInstallPackages(packages: GQL.PackageSpecInput[]) { const r = await mutateInstallScraperPackages(packages); @@ -114,7 +120,10 @@ export const AvailableScraperPackages: React.FC = () => { async function loadSource(source: string): Promise { const { data } = await queryAvailableScraperPackages(source); - return data.availablePackages; + // Filter out already installed packages + return data.availablePackages.filter( + (pkg) => !installedPackageIds.has(pkg.package_id) + ); } function addSource(source: GQL.PackageSource) {