mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-07-25 05:46:18 +00:00
fix(ui): exit infinite spinner with a retry card on failed initial load
List pages wrapped content in <Spin spinning={!fetched}> where 'fetched' only flipped true once data arrived. With staleTime: Infinity + retry: 1, a transient network error on first load left the query in a permanent error state and the spinner stuck forever.
Now 'fetched' also settles on query.isError, and a failed load shows a Result error card with a Refresh button that self-heals when the backend returns, mirroring the existing XrayPage pattern. Applied to clients, inbounds, groups, nodes, and the dashboard.
Fixes #4723
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { Card, Col, ConfigProvider, Layout, Modal, Row, Spin, Statistic, message } from 'antd';
|
||||
import { Button, Card, Col, ConfigProvider, Layout, Modal, Result, Row, Spin, Statistic, message } from 'antd';
|
||||
import {
|
||||
CheckCircleOutlined,
|
||||
CloseCircleOutlined,
|
||||
@@ -29,7 +29,7 @@ export default function NodesPage() {
|
||||
const [messageApi, messageContextHolder] = message.useMessage();
|
||||
useEffect(() => { setMessageInstance(messageApi); }, [messageApi]);
|
||||
|
||||
const { nodes, loading, fetched, totals } = useNodesQuery();
|
||||
const { nodes, loading, fetched, fetchError, refetch, totals } = useNodesQuery();
|
||||
const { create, update, remove, setEnable, testConnection, probe, updatePanels } = useNodeMutations();
|
||||
|
||||
const { data: latestVersion = '' } = useQuery({
|
||||
@@ -159,6 +159,13 @@ export default function NodesPage() {
|
||||
<Spin spinning={!fetched} delay={200} description={t('loading')} size="large">
|
||||
{!fetched ? (
|
||||
<div className="loading-spacer" />
|
||||
) : fetchError ? (
|
||||
<Result
|
||||
status="error"
|
||||
title={t('somethingWentWrong')}
|
||||
subTitle={fetchError}
|
||||
extra={<Button type="primary" loading={loading} onClick={() => refetch()}>{t('refresh')}</Button>}
|
||||
/>
|
||||
) : (
|
||||
<Row gutter={[isMobile ? 8 : 16, isMobile ? 8 : 12]}>
|
||||
<Col span={24}>
|
||||
|
||||
Reference in New Issue
Block a user