From e078b0029f10814f46221c2be0e782f6099379c0 Mon Sep 17 00:00:00 2001 From: Froidefond Julien Date: Fri, 27 Mar 2026 09:13:38 +0100 Subject: [PATCH] =?UTF-8?q?fix:=20SSR=20pour=20les=20providers=20cach?= =?UTF-8?q?=C3=A9s=20dans=20MetadataSearchModal?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Les metadata providers sont récupérés côté serveur et les providers sans API key sont passés en prop initialHiddenProviders, supprimant le fetch client useEffect qui causait un layout shift. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../libraries/[id]/series/[name]/page.tsx | 7 ++++++- .../app/components/MetadataSearchModal.tsx | 18 +++--------------- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/apps/backoffice/app/(app)/libraries/[id]/series/[name]/page.tsx b/apps/backoffice/app/(app)/libraries/[id]/series/[name]/page.tsx index aab9c71..2151e9e 100644 --- a/apps/backoffice/app/(app)/libraries/[id]/series/[name]/page.tsx +++ b/apps/backoffice/app/(app)/libraries/[id]/series/[name]/page.tsx @@ -41,7 +41,7 @@ export default async function SeriesDetailPage({ const seriesName = decodeURIComponent(name); - const [library, booksPage, seriesMeta, metadataLinks, readingStatusLink, prowlarrConfigured, qbConfigured] = await Promise.all([ + const [library, booksPage, seriesMeta, metadataLinks, readingStatusLink, prowlarrConfigured, qbConfigured, metadataProviders] = await Promise.all([ fetchLibraries().then((libs) => libs.find((l) => l.id === id)), fetchBooks(id, seriesName, page, limit).catch(() => ({ items: [] as BookDto[], @@ -58,8 +58,12 @@ export default async function SeriesDetailPage({ apiFetch<{ url?: string; username?: string }>("/settings/qbittorrent") .then(d => !!(d?.url?.trim() && d?.username?.trim())) .catch(() => false), + apiFetch<{ comicvine?: { api_key?: string } }>("/settings/metadata_providers").catch(() => null), ]); + const hiddenProviders: string[] = []; + if (!metadataProviders?.comicvine?.api_key) hiddenProviders.push("comicvine"); + const existingLink = metadataLinks.find((l) => l.status === "approved") ?? metadataLinks[0] ?? null; let missingData: MissingBooksDto | null = null; if (existingLink && existingLink.status === "approved") { @@ -249,6 +253,7 @@ export default async function SeriesDetailPage({ seriesName={seriesName} existingLink={existingLink} initialMissing={missingData} + initialHiddenProviders={hiddenProviders} /> >(new Set()); - - // Fetch metadata provider settings to hide providers without required API keys - useEffect(() => { - fetch("/api/settings/metadata_providers") - .then((r) => r.ok ? r.json() : null) - .then((data) => { - if (!data) return; - const hidden = new Set(); - // ComicVine requires an API key - if (!data.comicvine?.api_key) hidden.add("comicvine"); - setHiddenProviders(hidden); - }) - .catch(() => {}); - }, []); + const [hiddenProviders] = useState>(new Set(initialHiddenProviders ?? [])); const visibleProviders = PROVIDERS.filter((p) => !hiddenProviders.has(p.value));