mirror of
https://github.com/router-for-me/Cli-Proxy-API-Management-Center.git
synced 2026-02-03 19:30:51 +08:00
fix(layout): wire header refresh to page loaders and quota config refresh
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
import { useEffect, useMemo, useRef, useState, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useInterval } from '@/hooks/useInterval';
|
||||
import { Card } from '@/components/ui/Card';
|
||||
import { Button } from '@/components/ui/Button';
|
||||
import { useEffect, useMemo, useRef, useState, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useInterval } from '@/hooks/useInterval';
|
||||
import { useHeaderRefresh } from '@/hooks/useHeaderRefresh';
|
||||
import { Card } from '@/components/ui/Card';
|
||||
import { Button } from '@/components/ui/Button';
|
||||
import { LoadingSpinner } from '@/components/ui/LoadingSpinner';
|
||||
import { Input } from '@/components/ui/Input';
|
||||
import { Modal } from '@/components/ui/Modal';
|
||||
@@ -270,6 +271,12 @@ export function AuthFilesPage() {
|
||||
}
|
||||
}, [showNotification, t]);
|
||||
|
||||
const handleHeaderRefresh = useCallback(async () => {
|
||||
await Promise.all([loadFiles(), loadKeyStats(), loadExcluded()]);
|
||||
}, [loadFiles, loadKeyStats, loadExcluded]);
|
||||
|
||||
useHeaderRefresh(handleHeaderRefresh);
|
||||
|
||||
useEffect(() => {
|
||||
loadFiles();
|
||||
loadKeyStats();
|
||||
@@ -824,11 +831,16 @@ export function AuthFilesPage() {
|
||||
|
||||
<Card
|
||||
title={t('auth_files.title_section')}
|
||||
extra={
|
||||
<div className={styles.headerActions}>
|
||||
<Button variant="secondary" size="sm" onClick={() => { loadFiles(); loadKeyStats(); }} disabled={loading}>
|
||||
{t('common.refresh')}
|
||||
</Button>
|
||||
extra={
|
||||
<div className={styles.headerActions}>
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
onClick={handleHeaderRefresh}
|
||||
disabled={loading}
|
||||
>
|
||||
{t('common.refresh')}
|
||||
</Button>
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
IconTrash2,
|
||||
IconX,
|
||||
} from '@/components/ui/icons';
|
||||
import { useHeaderRefresh } from '@/hooks/useHeaderRefresh';
|
||||
import { useAuthStore, useConfigStore, useNotificationStore } from '@/stores';
|
||||
import { logsApi } from '@/services/api/logs';
|
||||
import { MANAGEMENT_API_PREFIX } from '@/utils/constants';
|
||||
@@ -474,6 +475,8 @@ export function LogsPage() {
|
||||
}
|
||||
};
|
||||
|
||||
useHeaderRefresh(() => loadLogs(false));
|
||||
|
||||
const clearLogs = async () => {
|
||||
if (!window.confirm(t('logs.clear_confirm'))) return;
|
||||
try {
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button } from '@/components/ui/Button';
|
||||
import { useHeaderRefresh } from '@/hooks/useHeaderRefresh';
|
||||
import { useAuthStore } from '@/stores';
|
||||
import { authFilesApi } from '@/services/api';
|
||||
import { authFilesApi, configFileApi } from '@/services/api';
|
||||
import {
|
||||
QuotaSection,
|
||||
ANTIGRAVITY_CONFIG,
|
||||
@@ -26,6 +26,15 @@ export function QuotaPage() {
|
||||
|
||||
const disableControls = connectionStatus !== 'connected';
|
||||
|
||||
const loadConfig = useCallback(async () => {
|
||||
try {
|
||||
await configFileApi.fetchConfigYaml();
|
||||
} catch (err: unknown) {
|
||||
const errorMessage = err instanceof Error ? err.message : t('notification.refresh_failed');
|
||||
setError((prev) => prev || errorMessage);
|
||||
}
|
||||
}, [t]);
|
||||
|
||||
const loadFiles = useCallback(async () => {
|
||||
setLoading(true);
|
||||
setError('');
|
||||
@@ -40,20 +49,22 @@ export function QuotaPage() {
|
||||
}
|
||||
}, [t]);
|
||||
|
||||
const handleHeaderRefresh = useCallback(async () => {
|
||||
await Promise.all([loadConfig(), loadFiles()]);
|
||||
}, [loadConfig, loadFiles]);
|
||||
|
||||
useHeaderRefresh(handleHeaderRefresh);
|
||||
|
||||
useEffect(() => {
|
||||
loadFiles();
|
||||
}, [loadFiles]);
|
||||
loadConfig();
|
||||
}, [loadFiles, loadConfig]);
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.pageHeader}>
|
||||
<h1 className={styles.pageTitle}>{t('quota_management.title')}</h1>
|
||||
<p className={styles.description}>{t('quota_management.description')}</p>
|
||||
<div className={styles.headerActions}>
|
||||
<Button variant="secondary" size="sm" onClick={loadFiles} disabled={loading}>
|
||||
{t('quota_management.refresh_files')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{error && <div className={styles.errorBox}>{error}</div>}
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
import { Button } from '@/components/ui/Button';
|
||||
import { LoadingSpinner } from '@/components/ui/LoadingSpinner';
|
||||
import { useMediaQuery } from '@/hooks/useMediaQuery';
|
||||
import { useHeaderRefresh } from '@/hooks/useHeaderRefresh';
|
||||
import { useThemeStore } from '@/stores';
|
||||
import {
|
||||
StatCards,
|
||||
@@ -63,6 +64,8 @@ export function UsagePage() {
|
||||
importing
|
||||
} = useUsageData();
|
||||
|
||||
useHeaderRefresh(loadUsage);
|
||||
|
||||
// Chart lines state
|
||||
const [chartLines, setChartLines] = useState<string[]>(['all']);
|
||||
const MAX_CHART_LINES = 9;
|
||||
|
||||
Reference in New Issue
Block a user