fix(clients): keep the client list live with a background poll (#5262)

The paged client list is sorted/paginated server-side but fetched with staleTime: Infinity, so the WS client_stats patch only refreshed traffic on already-visible rows — newly connected clients never appeared and the sort order went stale until a manual refresh.

Add a 5s refetchInterval so the current page tracks reality, and drive the table overlay off isPlaceholderData so the background poll does not flash it.
This commit is contained in:
MHSanaei
2026-06-13 10:42:14 +02:00
parent 8f556fe2db
commit 355262e632
2 changed files with 10 additions and 3 deletions
+7
View File
@@ -183,6 +183,9 @@ export function useClients() {
queryKey: keys.clients.list(query),
queryFn: () => fetchClientPage(query),
staleTime: Infinity,
// List is sorted/paged server-side, so the WS patch can't add new or
// re-sort rows; poll the current page to keep it live (pauses when hidden).
refetchInterval: 5000,
placeholderData: keepPreviousData,
});
@@ -216,6 +219,9 @@ export function useClients() {
const fetched = listQuery.data !== undefined || listQuery.isError;
const fetchError = listQuery.error ? (listQuery.error as Error).message : '';
const loading = listQuery.isFetching;
// Showing kept-previous data for a new key (filter/sort/page) — drives the
// table overlay so the 5s background poll doesn't flash it.
const transitioning = listQuery.isPlaceholderData;
const inbounds = inboundOptionsQuery.data ?? [];
const onlines = useMemo(() => onlinesQuery.data ?? [], [onlinesQuery.data]);
@@ -528,6 +534,7 @@ export function useClients() {
inbounds,
onlines,
loading,
transitioning,
fetched,
fetchError,
subSettings,
+3 -3
View File
@@ -197,7 +197,7 @@ export default function ClientsPage() {
summary: serverSummary,
allGroups,
setQuery,
inbounds, onlines, loading, fetched, fetchError, subSettings,
inbounds, onlines, loading, transitioning, fetched, fetchError, subSettings,
tgBotEnable, expireDiff, trafficDiff, pageSize,
create, update, remove, bulkDelete, bulkAdjust, bulkAddToGroup, bulkRemoveFromGroup, attach, bulkAttach, detach, bulkDetach,
resetTraffic, resetAllTraffics, delDepleted, setEnable,
@@ -1100,7 +1100,7 @@ export default function ClientsPage() {
<Table<ClientRecord>
columns={columns}
dataSource={sortedClients}
loading={loading}
loading={transitioning}
rowKey="email"
rowSelection={rowSelection}
pagination={tablePagination}
@@ -1117,7 +1117,7 @@ export default function ClientsPage() {
}}
/>
) : (
<Spin spinning={loading}>
<Spin spinning={transitioning}>
<div className="client-cards">
{filteredClients.length > 0 && (
<div className="card-bulk-bar">