mirror of
https://github.com/router-for-me/Cli-Proxy-API-Management-Center.git
synced 2026-08-30 17:56:18 +08:00
fix: adjust ESLint rule for async data loading and refactor sorting logic in ProvidersWorkbenchPage
This commit is contained in:
@@ -19,6 +19,9 @@ export default tseslint.config(
|
||||
},
|
||||
rules: {
|
||||
...reactHooks.configs.recommended.rules,
|
||||
// Pages in this app intentionally start async data loads from effects. Those loaders
|
||||
// synchronously expose their loading state before awaiting the Management API.
|
||||
'react-hooks/set-state-in-effect': 'off',
|
||||
'react-refresh/only-export-components': [
|
||||
'warn',
|
||||
{ allowConstantExport: true },
|
||||
|
||||
@@ -45,7 +45,6 @@ export function AuthFilesStatusFilterCard({
|
||||
if (prevActiveRef.current !== isActive) {
|
||||
// Trigger a one-off flip animation when the active state crosses the
|
||||
// threshold, mirroring the original EffortCard behavior.
|
||||
// eslint-disable-next-line react-hooks/set-state-in-effect
|
||||
setIsAnimating(true);
|
||||
if (timerRef.current) {
|
||||
clearTimeout(timerRef.current);
|
||||
|
||||
@@ -215,19 +215,14 @@ export function ProvidersWorkbenchPage({ fixedBrand }: ProvidersWorkbenchPagePro
|
||||
}
|
||||
|
||||
const sorted = [...arr].sort((a, b) => {
|
||||
let diff = 0;
|
||||
if (providerSortBy === 'name') {
|
||||
diff = getResourceSortName(a).localeCompare(getResourceSortName(b));
|
||||
} else if (providerSortBy === 'priority') {
|
||||
diff = a.priority - b.priority;
|
||||
} else {
|
||||
diff =
|
||||
getResourceRecentSuccess(a, usageByProvider) -
|
||||
getResourceRecentSuccess(b, usageByProvider);
|
||||
}
|
||||
if (diff === 0) {
|
||||
diff = a.originalIndex - b.originalIndex;
|
||||
}
|
||||
const sortDiff =
|
||||
providerSortBy === 'name'
|
||||
? getResourceSortName(a).localeCompare(getResourceSortName(b))
|
||||
: providerSortBy === 'priority'
|
||||
? a.priority - b.priority
|
||||
: getResourceRecentSuccess(a, usageByProvider) -
|
||||
getResourceRecentSuccess(b, usageByProvider);
|
||||
const diff = sortDiff || a.originalIndex - b.originalIndex;
|
||||
return providerSortDir === 'asc' ? diff : -diff;
|
||||
});
|
||||
|
||||
|
||||
+8
-13
@@ -180,7 +180,6 @@ export function LogsPage() {
|
||||
const [requestLogDownloading, setRequestLogDownloading] = useState(false);
|
||||
const [fullscreenLogs, setFullscreenLogs] = useState(false);
|
||||
|
||||
const logScrollerRef = useRef<ReturnType<typeof useLogScroller> | null>(null);
|
||||
const requestLogHomeIpByIdRef = useRef<Record<string, string>>({});
|
||||
const errorLogViewRequestRef = useRef(0);
|
||||
const longPressRef = useRef<{
|
||||
@@ -221,7 +220,7 @@ export function LogsPage() {
|
||||
const autoRefreshDisabled = disableControls || showFileLoggingRequired;
|
||||
const clearDisabled = disableControls || showFileLoggingRequired || isHomeRuntime;
|
||||
|
||||
const loadLogs = async (incremental = false) => {
|
||||
async function loadLogs(incremental = false) {
|
||||
if (connectionStatus !== 'connected') {
|
||||
setLoading(false);
|
||||
return;
|
||||
@@ -254,11 +253,9 @@ export function LogsPage() {
|
||||
setError('');
|
||||
|
||||
try {
|
||||
const scrollerInstance = logScrollerRef.current;
|
||||
const stickToBottom =
|
||||
!incremental || isNearBottom(scrollerInstance?.logViewerRef.current ?? null);
|
||||
const stickToBottom = !incremental || isNearBottom(logViewerRef.current);
|
||||
if (stickToBottom) {
|
||||
scrollerInstance?.requestScrollToBottom();
|
||||
requestScrollToBottom();
|
||||
}
|
||||
|
||||
const params = buildLogsQuery(incremental, logPositionRef.current);
|
||||
@@ -328,7 +325,7 @@ export function LogsPage() {
|
||||
void loadLogs(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
useHeaderRefresh(() => loadLogs(false));
|
||||
|
||||
@@ -579,7 +576,7 @@ export function LogsPage() {
|
||||
|
||||
const rawVisibleText = useMemo(() => filteredLines.join('\n'), [filteredLines]);
|
||||
|
||||
const scroller = useLogScroller({
|
||||
const { canLoadMore, handleLogScroll, logViewerRef, requestScrollToBottom } = useLogScroller({
|
||||
logState,
|
||||
setLogState,
|
||||
loading,
|
||||
@@ -589,8 +586,6 @@ export function LogsPage() {
|
||||
showRawLogs,
|
||||
});
|
||||
|
||||
logScrollerRef.current = scroller;
|
||||
|
||||
const copyLogLine = async (raw: string) => {
|
||||
const ok = await copyToClipboard(raw);
|
||||
if (ok) {
|
||||
@@ -987,13 +982,13 @@ export function LogsPage() {
|
||||
<div className="hint">{t('logs.loading')}</div>
|
||||
) : logState.buffer.length > 0 && filteredLines.length > 0 ? (
|
||||
<div
|
||||
ref={scroller.logViewerRef}
|
||||
ref={logViewerRef}
|
||||
className={[styles.logPanel, fullscreenLogs ? styles.logPanelFullscreen : '']
|
||||
.filter(Boolean)
|
||||
.join(' ')}
|
||||
onScroll={scroller.handleLogScroll}
|
||||
onScroll={handleLogScroll}
|
||||
>
|
||||
{scroller.canLoadMore && (
|
||||
{canLoadMore && (
|
||||
<div className={styles.loadMoreBanner}>
|
||||
<span>{t('logs.load_more_hint')}</span>
|
||||
<div className={styles.loadMoreStats}>
|
||||
|
||||
@@ -84,7 +84,7 @@ class ObfuscatedStorageService {
|
||||
return;
|
||||
}
|
||||
|
||||
let parsed: unknown = raw;
|
||||
let parsed: unknown;
|
||||
try {
|
||||
parsed = JSON.parse(raw);
|
||||
} catch {
|
||||
|
||||
Reference in New Issue
Block a user