mirror of
https://github.com/router-for-me/Cli-Proxy-API-Management-Center.git
synced 2026-06-16 21:03:58 +08:00
feat(auth-files): add problem filter functionality and enhance deletion confirmation messages
This commit is contained in:
@@ -18,6 +18,7 @@ import { formatFileSize } from '@/utils/format';
|
||||
import {
|
||||
QUOTA_PROVIDER_TYPES,
|
||||
formatModified,
|
||||
getAuthFileStatusMessage,
|
||||
getTypeColor,
|
||||
getTypeLabel,
|
||||
isRuntimeOnlyAuthFile,
|
||||
@@ -105,7 +106,7 @@ export function AuthFileCard(props: AuthFileCardProps) {
|
||||
const authIndexKey = normalizeAuthIndex(rawAuthIndex);
|
||||
const statusData =
|
||||
(authIndexKey && statusBarCache.get(authIndexKey)) || calculateStatusBarData([]);
|
||||
const rawStatusMessage = String(file['status_message'] ?? file.statusMessage ?? '').trim();
|
||||
const rawStatusMessage = getAuthFileStatusMessage(file);
|
||||
const hasStatusWarning =
|
||||
Boolean(rawStatusMessage) && !HEALTHY_STATUS_MESSAGES.has(rawStatusMessage.toLowerCase());
|
||||
|
||||
|
||||
@@ -93,6 +93,16 @@ export const resolveQuotaErrorMessage = (
|
||||
|
||||
export const normalizeProviderKey = (value: string) => value.trim().toLowerCase();
|
||||
|
||||
export const getAuthFileStatusMessage = (file: AuthFileItem): string => {
|
||||
const raw = file['status_message'] ?? file.statusMessage;
|
||||
if (typeof raw === 'string') return raw.trim();
|
||||
if (raw == null) return '';
|
||||
return String(raw).trim();
|
||||
};
|
||||
|
||||
export const hasAuthFileStatusMessage = (file: AuthFileItem): boolean =>
|
||||
getAuthFileStatusMessage(file).length > 0;
|
||||
|
||||
export const getTypeLabel = (t: TFunction, type: string): string => {
|
||||
const key = `auth_files.filter_${type}`;
|
||||
const translated = t(key);
|
||||
|
||||
@@ -7,11 +7,17 @@ import type { AuthFileItem } from '@/types';
|
||||
import { formatFileSize } from '@/utils/format';
|
||||
import { MAX_AUTH_FILE_SIZE } from '@/utils/constants';
|
||||
import { downloadBlob } from '@/utils/download';
|
||||
import { getTypeLabel, isRuntimeOnlyAuthFile } from '@/features/authFiles/constants';
|
||||
import {
|
||||
getTypeLabel,
|
||||
hasAuthFileStatusMessage,
|
||||
isRuntimeOnlyAuthFile,
|
||||
} from '@/features/authFiles/constants';
|
||||
|
||||
type DeleteAllOptions = {
|
||||
filter: string;
|
||||
problemOnly: boolean;
|
||||
onResetFilterToAll: () => void;
|
||||
onResetProblemOnly: () => void;
|
||||
};
|
||||
|
||||
export type UseAuthFilesDataResult = {
|
||||
@@ -233,12 +239,17 @@ export function useAuthFilesData(options: UseAuthFilesDataOptions): UseAuthFiles
|
||||
|
||||
const handleDeleteAll = useCallback(
|
||||
(deleteAllOptions: DeleteAllOptions) => {
|
||||
const { filter, onResetFilterToAll } = deleteAllOptions;
|
||||
const { filter, problemOnly, onResetFilterToAll, onResetProblemOnly } = deleteAllOptions;
|
||||
const isFiltered = filter !== 'all';
|
||||
const isProblemOnly = problemOnly === true;
|
||||
const typeLabel = isFiltered ? getTypeLabel(t, filter) : t('auth_files.filter_all');
|
||||
const confirmMessage = isFiltered
|
||||
? t('auth_files.delete_filtered_confirm', { type: typeLabel })
|
||||
: t('auth_files.delete_all_confirm');
|
||||
const confirmMessage = isProblemOnly
|
||||
? isFiltered
|
||||
? t('auth_files.delete_problem_filtered_confirm', { type: typeLabel })
|
||||
: t('auth_files.delete_problem_confirm')
|
||||
: isFiltered
|
||||
? t('auth_files.delete_filtered_confirm', { type: typeLabel })
|
||||
: t('auth_files.delete_all_confirm');
|
||||
|
||||
showConfirmation({
|
||||
title: t('auth_files.delete_all_title', { defaultValue: 'Delete All Files' }),
|
||||
@@ -248,18 +259,26 @@ export function useAuthFilesData(options: UseAuthFilesDataOptions): UseAuthFiles
|
||||
onConfirm: async () => {
|
||||
setDeletingAll(true);
|
||||
try {
|
||||
if (!isFiltered) {
|
||||
if (!isFiltered && !isProblemOnly) {
|
||||
await authFilesApi.deleteAll();
|
||||
showNotification(t('auth_files.delete_all_success'), 'success');
|
||||
setFiles((prev) => prev.filter((file) => isRuntimeOnlyAuthFile(file)));
|
||||
deselectAll();
|
||||
} else {
|
||||
const filesToDelete = files.filter(
|
||||
(f) => f.type === filter && !isRuntimeOnlyAuthFile(f)
|
||||
);
|
||||
const filesToDelete = files.filter((file) => {
|
||||
if (isRuntimeOnlyAuthFile(file)) return false;
|
||||
if (isFiltered && file.type !== filter) return false;
|
||||
if (isProblemOnly && !hasAuthFileStatusMessage(file)) return false;
|
||||
return true;
|
||||
});
|
||||
|
||||
if (filesToDelete.length === 0) {
|
||||
showNotification(t('auth_files.delete_filtered_none', { type: typeLabel }), 'info');
|
||||
const emptyMessage = isProblemOnly
|
||||
? isFiltered
|
||||
? t('auth_files.delete_problem_filtered_none', { type: typeLabel })
|
||||
: t('auth_files.delete_problem_none')
|
||||
: t('auth_files.delete_filtered_none', { type: typeLabel });
|
||||
showNotification(emptyMessage, 'info');
|
||||
setDeletingAll(false);
|
||||
return;
|
||||
}
|
||||
@@ -294,18 +313,45 @@ export function useAuthFilesData(options: UseAuthFilesDataOptions): UseAuthFiles
|
||||
return changed ? next : prev;
|
||||
});
|
||||
|
||||
if (failed === 0) {
|
||||
if (failed === 0 && isProblemOnly) {
|
||||
showNotification(
|
||||
isFiltered
|
||||
? t('auth_files.delete_problem_filtered_success', {
|
||||
count: success,
|
||||
type: typeLabel,
|
||||
})
|
||||
: t('auth_files.delete_problem_success', { count: success }),
|
||||
'success'
|
||||
);
|
||||
} else if (failed === 0) {
|
||||
showNotification(
|
||||
t('auth_files.delete_filtered_success', { count: success, type: typeLabel }),
|
||||
'success'
|
||||
);
|
||||
} else if (isProblemOnly) {
|
||||
showNotification(
|
||||
isFiltered
|
||||
? t('auth_files.delete_problem_filtered_partial', {
|
||||
success,
|
||||
failed,
|
||||
type: typeLabel,
|
||||
})
|
||||
: t('auth_files.delete_problem_partial', { success, failed }),
|
||||
'warning'
|
||||
);
|
||||
} else {
|
||||
showNotification(
|
||||
t('auth_files.delete_filtered_partial', { success, failed, type: typeLabel }),
|
||||
'warning'
|
||||
);
|
||||
}
|
||||
onResetFilterToAll();
|
||||
|
||||
if (isFiltered) {
|
||||
onResetFilterToAll();
|
||||
}
|
||||
if (isProblemOnly) {
|
||||
onResetProblemOnly();
|
||||
}
|
||||
}
|
||||
} catch (err: unknown) {
|
||||
const errorMessage = err instanceof Error ? err.message : '';
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
export type AuthFilesUiState = {
|
||||
filter?: string;
|
||||
problemOnly?: boolean;
|
||||
search?: string;
|
||||
page?: number;
|
||||
pageSize?: number;
|
||||
@@ -27,4 +28,3 @@ export const writeAuthFilesUiState = (state: AuthFilesUiState) => {
|
||||
// ignore
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user