From 42f1699245b86eacbf0ae956eb6e5c2db9012646 Mon Sep 17 00:00:00 2001 From: Diego Rodrigues de Sa e Souza Date: Wed, 15 Jul 2026 11:19:48 -0300 Subject: [PATCH] fix(dashboard): extract reorder-by-availability into its own hook (file-size ratchet) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The reorder-by-availability feature pushed useProviderConnections.ts to 974 lines, past its frozen file-size cap (954). Extract the handler + its state into a dedicated useReorderByAvailability hook, following the same pattern already used for useModelVisibilityHandlers/useModelImportHandlers — no behavior change, same tests still cover the sort logic in connectionRowHelpers.ts. --- .../[id]/hooks/useProviderConnections.ts | 47 +++------- .../[id]/hooks/useReorderByAvailability.ts | 86 +++++++++++++++++++ 2 files changed, 96 insertions(+), 37 deletions(-) create mode 100644 src/app/(dashboard)/dashboard/providers/[id]/hooks/useReorderByAvailability.ts diff --git a/src/app/(dashboard)/dashboard/providers/[id]/hooks/useProviderConnections.ts b/src/app/(dashboard)/dashboard/providers/[id]/hooks/useProviderConnections.ts index 2e56896b9e..ca31016194 100644 --- a/src/app/(dashboard)/dashboard/providers/[id]/hooks/useProviderConnections.ts +++ b/src/app/(dashboard)/dashboard/providers/[id]/hooks/useProviderConnections.ts @@ -27,7 +27,7 @@ import { useNotificationStore } from "@/store/notificationStore"; import { isClaudeCodeCompatibleProvider } from "@/shared/constants/providers"; import type { ConnectionRowConnection } from "../components/ConnectionRow"; import { normalizeCodexLimitPolicy } from "../providerPageHelpers"; -import { sortConnectionsByAvailability } from "../components/connectionRowHelpers"; +import { useReorderByAvailability } from "./useReorderByAvailability"; // Max connection ids accepted per bulk request — mirrors API-side cap. const MAX_BULK_IDS = 100; @@ -163,9 +163,6 @@ export function useProviderConnections( // ── token refresh state ───────────────────────────────────────────────── const [refreshingId, setRefreshingId] = useState(null); - // ── reorder-by-availability state ─────────────────────────────────────── - const [reorderingByAvailability, setReorderingByAvailability] = useState(false); - // ──────────────────────────────────────────────────────────────────────── // Fetch helpers // ──────────────────────────────────────────────────────────────────────── @@ -613,39 +610,15 @@ export function useProviderConnections( } }; - /** - * Reorder every connection for this provider by availability: connections - * whose effective status is active/success move to the top, the rest move - * to the bottom, each group keeping its existing relative order (stable - * sort — see `sortConnectionsByAvailability`). Persists the new order as - * sequential `priority` values via the same PUT endpoint `handleSwapPriority` - * already uses, then re-fetches from the server so the UI never runs ahead - * of persisted state on a partial failure (#2558 upstream: fzrilsh). - */ - const handleReorderByAvailability = async () => { - if (reorderingByAvailability || (connections as any[]).length < 2) return; - setReorderingByAvailability(true); - const sorted = sortConnectionsByAvailability(connections as any[]); - setConnections(sorted as ConnectionRowConnection[]); - try { - await Promise.all( - sorted.map((conn: any, idx: number) => - fetch(`/api/providers/${conn.id}`, { - method: "PUT", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ priority: idx }), - }) - ) - ); - await fetchConnections(); - } catch (error) { - console.log("Error reordering connections by availability:", error); - notify.error(t("reorderByAvailabilityError")); - await fetchConnections(); - } finally { - setReorderingByAvailability(false); - } - }; + // Reorder-by-availability toolbar action — extracted to its own hook + // (see useReorderByAvailability.ts) to keep this file under the file-size cap. + const { reorderingByAvailability, handleReorderByAvailability } = useReorderByAvailability({ + connections, + setConnections, + fetchConnections, + notify, + t, + }); // ──────────────────────────────────────────────────────────────────────── // Selection handlers diff --git a/src/app/(dashboard)/dashboard/providers/[id]/hooks/useReorderByAvailability.ts b/src/app/(dashboard)/dashboard/providers/[id]/hooks/useReorderByAvailability.ts new file mode 100644 index 0000000000..5613421837 --- /dev/null +++ b/src/app/(dashboard)/dashboard/providers/[id]/hooks/useReorderByAvailability.ts @@ -0,0 +1,86 @@ +"use client"; + +/** + * useReorderByAvailability — extracted from useProviderConnections (file-size + * ratchet: useProviderConnections.ts is frozen at 954 lines; this feature + * pushed it to 974) to keep the god-file from growing. + * + * Owns the "Reorder by availability" toolbar action: sorts a provider's + * connections so available ones float to the top and unavailable ones sink + * to the bottom (stable sort — see `sortConnectionsByAvailability`), then + * persists the new order via the same per-connection priority PUT endpoint + * `handleSwapPriority` already uses in useProviderConnections. + * + * Cycle-safe: imports only from leaf modules. No import from + * ProviderDetailPageClient or useProviderConnections. + */ + +import { useState } from "react"; +import { sortConnectionsByAvailability } from "../components/connectionRowHelpers"; +import type { ConnectionRowConnection } from "../components/ConnectionRow"; +import { useNotificationStore } from "@/store/notificationStore"; + +type NotifyStore = ReturnType; + +export interface UseReorderByAvailabilityParams { + connections: ConnectionRowConnection[]; + setConnections: ( + updater: + | ConnectionRowConnection[] + | ((prev: ConnectionRowConnection[]) => ConnectionRowConnection[]) + ) => void; + fetchConnections: () => Promise; + notify: NotifyStore; + t: (key: string, params?: Record) => string; +} + +export interface UseReorderByAvailabilityReturn { + reorderingByAvailability: boolean; + handleReorderByAvailability: () => Promise; +} + +export function useReorderByAvailability({ + connections, + setConnections, + fetchConnections, + notify, + t, +}: UseReorderByAvailabilityParams): UseReorderByAvailabilityReturn { + const [reorderingByAvailability, setReorderingByAvailability] = useState(false); + + /** + * Reorder every connection for this provider by availability: connections + * whose effective status is active/success move to the top, the rest move + * to the bottom, each group keeping its existing relative order (stable + * sort — see `sortConnectionsByAvailability`). Persists the new order as + * sequential `priority` values via the same PUT endpoint `handleSwapPriority` + * already uses, then re-fetches from the server so the UI never runs ahead + * of persisted state on a partial failure (#2558 upstream: fzrilsh). + */ + const handleReorderByAvailability = async () => { + if (reorderingByAvailability || (connections as any[]).length < 2) return; + setReorderingByAvailability(true); + const sorted = sortConnectionsByAvailability(connections as any[]); + setConnections(sorted as ConnectionRowConnection[]); + try { + await Promise.all( + sorted.map((conn: any, idx: number) => + fetch(`/api/providers/${conn.id}`, { + method: "PUT", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ priority: idx }), + }) + ) + ); + await fetchConnections(); + } catch (error) { + console.log("Error reordering connections by availability:", error); + notify.error(t("reorderByAvailabilityError")); + await fetchConnections(); + } finally { + setReorderingByAvailability(false); + } + }; + + return { reorderingByAvailability, handleReorderByAvailability }; +}