fix(drag-and-drop): add data transfer for source and alias during drag events

fix(i18n): update view mode labels in Chinese localization
fix(auth-files): set fork to true in empty mapping entry and improve error handling in save/delete operations
This commit is contained in:
LTbinglingfeng
2026-02-05 00:02:05 +08:00
parent db487dc49d
commit 759e369d42
4 changed files with 59 additions and 13 deletions

View File

@@ -274,6 +274,7 @@ export const ModelMappingDiagram = forwardRef<ModelMappingDiagramRef, ModelMappi
// 1. Source -> Alias
const handleDragStart = (e: DragEvent, source: SourceNode) => {
setDraggedSource(source);
e.dataTransfer.setData('text/plain', source.id);
e.dataTransfer.effectAllowed = 'link';
};
@@ -300,6 +301,7 @@ export const ModelMappingDiagram = forwardRef<ModelMappingDiagramRef, ModelMappi
// 2. Alias -> Source
const handleDragStartAlias = (e: DragEvent, alias: string) => {
setDraggedAlias(alias);
e.dataTransfer.setData('text/plain', alias);
e.dataTransfer.effectAllowed = 'link';
};
@@ -429,7 +431,7 @@ export const ModelMappingDiagram = forwardRef<ModelMappingDiagramRef, ModelMappi
return (
<div
className={`${styles.container} ${className}`}
className={[styles.container, className].filter(Boolean).join(' ')}
ref={containerRef}
onContextMenu={(e) => {
e.preventDefault();

View File

@@ -578,8 +578,8 @@
"diagram_settings_source_title": "源模型设置",
"diagram_settings_empty": "该别名暂无映射。",
"view_mode": "视图模式",
"view_mode_diagram": "Diagram",
"view_mode_list": "List",
"view_mode_diagram": "概览",
"view_mode_list": "管理",
"provider_required": "请先填写提供商名称",
"upgrade_required": "当前 CPA 版本不支持模型别名功能,请升级 CPA 版本",
"upgrade_required_title": "需要升级 CPA 版本",

View File

@@ -40,7 +40,7 @@ const buildEmptyMappingEntry = (): OAuthModelMappingFormEntry => ({
id: generateId(),
name: '',
alias: '',
fork: false,
fork: true,
});
const normalizeMappingEntries = (

View File

@@ -271,6 +271,8 @@ export function AuthFilesPage() {
}, [files, modelAlias]);
useEffect(() => {
if (viewMode !== 'diagram') return;
let cancelled = false;
const loadAllModels = async () => {
@@ -307,7 +309,7 @@ export function AuthFilesPage() {
return () => {
cancelled = true;
};
}, [providerList]);
}, [providerList, viewMode]);
@@ -1200,8 +1202,11 @@ export function AuthFilesPage() {
if (providersToUpdate.length === 0) return;
let hadFailure = false;
let failureMessage = '';
try {
await Promise.all(
const results = await Promise.allSettled(
providersToUpdate.map(([provider, mappings]) => {
const nextMappings = mappings.map((m) =>
(m.alias ?? '').trim().toLowerCase() === oldKey ? { ...m, alias: newTrim } : m
@@ -1209,11 +1214,29 @@ export function AuthFilesPage() {
return authFilesApi.saveOauthModelAlias(provider, nextMappings);
})
);
const failures = results.filter(
(result): result is PromiseRejectedResult => result.status === 'rejected'
);
if (failures.length > 0) {
hadFailure = true;
const reason = failures[0].reason;
failureMessage = reason instanceof Error ? reason.message : String(reason ?? '');
}
} finally {
await loadModelAlias();
}
if (hadFailure) {
showNotification(
failureMessage
? `${t('oauth_model_alias.save_failed')}: ${failureMessage}`
: t('oauth_model_alias.save_failed'),
'error'
);
} else {
showNotification(t('oauth_model_alias.save_success'), 'success');
} catch (err: unknown) {
const errorMessage = err instanceof Error ? err.message : '';
showNotification(`${t('oauth_model_alias.save_failed')}: ${errorMessage}`, 'error');
}
};
@@ -1239,8 +1262,11 @@ export function AuthFilesPage() {
variant: 'danger',
confirmText: t('common.confirm'),
onConfirm: async () => {
let hadFailure = false;
let failureMessage = '';
try {
await Promise.all(
const results = await Promise.allSettled(
providersToUpdate.map(([provider, mappings]) => {
const nextMappings = mappings.filter(
(m) => (m.alias ?? '').trim().toLowerCase() !== aliasKey
@@ -1251,11 +1277,29 @@ export function AuthFilesPage() {
return authFilesApi.saveOauthModelAlias(provider, nextMappings);
})
);
const failures = results.filter(
(result): result is PromiseRejectedResult => result.status === 'rejected'
);
if (failures.length > 0) {
hadFailure = true;
const reason = failures[0].reason;
failureMessage = reason instanceof Error ? reason.message : String(reason ?? '');
}
} finally {
await loadModelAlias();
}
if (hadFailure) {
showNotification(
failureMessage
? `${t('oauth_model_alias.delete_failed')}: ${failureMessage}`
: t('oauth_model_alias.delete_failed'),
'error'
);
} else {
showNotification(t('oauth_model_alias.delete_success'), 'success');
} catch (err: unknown) {
const errorMessage = err instanceof Error ? err.message : '';
showNotification(`${t('oauth_model_alias.delete_failed')}: ${errorMessage}`, 'error');
}
},
});