From 0702ec72af1e7a09d7f6ade4f90b641fbb61710d Mon Sep 17 00:00:00 2001 From: "alexei.dolgolyov" Date: Mon, 23 Mar 2026 21:30:25 +0300 Subject: [PATCH] fix: dashboard provider card shows filtered count, fix provider update 400 - Dashboard providers card now shows count of providers matching the global provider type filter instead of special name/type display - Fix provider update sending empty config when only name/icon changed, causing 400 validation error (api_key required) --- frontend/src/routes/+page.svelte | 20 ++++++++------------ frontend/src/routes/providers/+page.svelte | 9 ++++++++- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/frontend/src/routes/+page.svelte b/frontend/src/routes/+page.svelte index 9c130e3..ac6b05d 100644 --- a/frontend/src/routes/+page.svelte +++ b/frontend/src/routes/+page.svelte @@ -177,12 +177,12 @@ let displayCommandTrackers = $state(0); - const filteredProvider = $derived(globalProviderFilter.id ? providers.find(p => p.id === globalProviderFilter.id) : null); + const filteredProviderCount = $derived(globalProviderFilter.providerType + ? providers.filter(p => p.type === globalProviderFilter.providerType).length + : displayProviders); const statCards = $derived(status ? [ - filteredProvider - ? { icon: providerDefaultIcon(filteredProvider), label: filteredProvider.name, value: filteredProvider.type, color: '#0d9488', isProvider: true } - : { icon: 'mdiServer', label: 'dashboard.providers', value: displayProviders, color: '#0d9488' }, + { icon: 'mdiServer', label: 'dashboard.providers', value: filteredProviderCount, color: '#0d9488' }, { icon: 'mdiRadar', label: 'dashboard.activeTrackers', value: displayActive, suffix: ` / ${displayTotal}`, color: '#6366f1' }, { icon: 'mdiTarget', label: 'dashboard.targets', value: displayTargets, color: '#f59e0b' }, ...(status.command_trackers !== undefined ? [{ icon: 'mdiConsoleLine', label: 'nav.commandTrackers', value: displayCommandTrackers, color: '#8b5cf6' }] : []), @@ -238,14 +238,10 @@
-

{card.isProvider ? card.label : t(card.label)}

- {#if card.isProvider} -

{card.value}

- {:else} -

- {card.value}{#if card.suffix}{card.suffix}{/if} -

- {/if} +

{t(card.label)}

+

+ {card.value}{#if card.suffix}{card.suffix}{/if} +

diff --git a/frontend/src/routes/providers/+page.svelte b/frontend/src/routes/providers/+page.svelte index c72b189..31f7d2f 100644 --- a/frontend/src/routes/providers/+page.svelte +++ b/frontend/src/routes/providers/+page.svelte @@ -106,7 +106,14 @@ } } if (editing) { - await api(`/providers/${editing}`, { method: 'PUT', body: JSON.stringify({ name: form.name, icon: form.icon, config }) }); + // Only send config if user changed a config field (secrets are blank on edit) + const hasConfigChange = form.url !== (providers.find(p => p.id === editing)?.config?.url || '') || + (form.type === 'immich' && (form.api_key || form.external_domain !== (providers.find(p => p.id === editing)?.config?.external_domain || ''))) || + (form.type === 'gitea' && (form.api_token || form.webhook_secret)) || + (form.type === 'planka' && (form.api_key || form.webhook_secret)); + const body: any = { name: form.name, icon: form.icon }; + if (hasConfigChange) body.config = config; + await api(`/providers/${editing}`, { method: 'PUT', body: JSON.stringify(body) }); } else { await api('/providers', { method: 'POST', body: JSON.stringify({ type: form.type, name: form.name, icon: form.icon, config }) }); }