mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-06-16 13:34:04 +08:00
Various functional updates and improvements across provider dialogs, MCP panel, skills page, and internationalization. Provider Dialogs: - AddProviderDialog * Simplified form state management * Improved preset selection workflow * Better validation error messages * Enhanced template variable handling - EditProviderDialog * Streamlined edit flow with better state synchronization * Improved handling of live config backfilling * Better error recovery for failed updates * Enhanced integration with parent components MCP & Skills: - UnifiedMcpPanel * Reduced complexity from 140+ to ~95 lines * Improved multi-app server management * Better server type detection (stdio/http) * Enhanced server status indicators * Cleaner integration with MCP form modal - SkillsPage * Simplified navigation and state management * Better integration with RepoManagerPanel * Improved error handling for repository operations * Enhanced loading states - SkillCard * Minor layout adjustments * Better action button placement Environment & Configuration: - EnvWarningBanner * Improved conflict detection messages * Better visual hierarchy for warnings * Enhanced dismissal behavior - tauri.conf.json * Updated build configuration * Added new window management options Internationalization: - en.json & zh.json * Added 17 new translation keys for new features * Updated existing keys for better clarity * Added translations for new settings page * Improved consistency across UI text Code Cleanup: - mutations.ts * Removed 14 lines of unused mutation definitions * Cleaned up deprecated query invalidation logic * Better type safety for mutation parameters Overall Impact: - Reduced total lines by 51 (-10% in affected files) - Improved component integration and data flow - Better error handling and user feedback - Enhanced i18n coverage for new features These changes improve the overall polish and integration of various components while removing technical debt and unused code.
182 lines
5.0 KiB
TypeScript
182 lines
5.0 KiB
TypeScript
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
|
import { useTranslation } from "react-i18next";
|
|
import { toast } from "sonner";
|
|
import { providersApi, settingsApi, type AppId } from "@/lib/api";
|
|
import type { Provider, Settings } from "@/types";
|
|
import { extractErrorMessage } from "@/utils/errorUtils";
|
|
|
|
export const useAddProviderMutation = (appId: AppId) => {
|
|
const queryClient = useQueryClient();
|
|
const { t } = useTranslation();
|
|
|
|
return useMutation({
|
|
mutationFn: async (providerInput: Omit<Provider, "id">) => {
|
|
const newProvider: Provider = {
|
|
...providerInput,
|
|
id: crypto.randomUUID(),
|
|
createdAt: Date.now(),
|
|
};
|
|
await providersApi.add(newProvider, appId);
|
|
return newProvider;
|
|
},
|
|
onSuccess: async () => {
|
|
await queryClient.invalidateQueries({ queryKey: ["providers", appId] });
|
|
|
|
// 更新托盘菜单(失败不影响主操作)
|
|
try {
|
|
await providersApi.updateTrayMenu();
|
|
} catch (trayError) {
|
|
console.error(
|
|
"Failed to update tray menu after adding provider",
|
|
trayError,
|
|
);
|
|
}
|
|
|
|
toast.success(
|
|
t("notifications.providerAdded", {
|
|
defaultValue: "供应商已添加",
|
|
}),
|
|
);
|
|
},
|
|
onError: (error: Error) => {
|
|
toast.error(
|
|
t("notifications.addFailed", {
|
|
defaultValue: "添加供应商失败: {{error}}",
|
|
error: error.message,
|
|
}),
|
|
);
|
|
},
|
|
});
|
|
};
|
|
|
|
export const useUpdateProviderMutation = (appId: AppId) => {
|
|
const queryClient = useQueryClient();
|
|
const { t } = useTranslation();
|
|
|
|
return useMutation({
|
|
mutationFn: async (provider: Provider) => {
|
|
await providersApi.update(provider, appId);
|
|
return provider;
|
|
},
|
|
onSuccess: async () => {
|
|
await queryClient.invalidateQueries({ queryKey: ["providers", appId] });
|
|
toast.success(
|
|
t("notifications.updateSuccess", {
|
|
defaultValue: "供应商更新成功",
|
|
}),
|
|
);
|
|
},
|
|
onError: (error: Error) => {
|
|
toast.error(
|
|
t("notifications.updateFailed", {
|
|
defaultValue: "更新供应商失败: {{error}}",
|
|
error: error.message,
|
|
}),
|
|
);
|
|
},
|
|
});
|
|
};
|
|
|
|
export const useDeleteProviderMutation = (appId: AppId) => {
|
|
const queryClient = useQueryClient();
|
|
const { t } = useTranslation();
|
|
|
|
return useMutation({
|
|
mutationFn: async (providerId: string) => {
|
|
await providersApi.delete(providerId, appId);
|
|
},
|
|
onSuccess: async () => {
|
|
await queryClient.invalidateQueries({ queryKey: ["providers", appId] });
|
|
|
|
// 更新托盘菜单(失败不影响主操作)
|
|
try {
|
|
await providersApi.updateTrayMenu();
|
|
} catch (trayError) {
|
|
console.error(
|
|
"Failed to update tray menu after deleting provider",
|
|
trayError,
|
|
);
|
|
}
|
|
|
|
toast.success(
|
|
t("notifications.deleteSuccess", {
|
|
defaultValue: "供应商已删除",
|
|
}),
|
|
);
|
|
},
|
|
onError: (error: Error) => {
|
|
toast.error(
|
|
t("notifications.deleteFailed", {
|
|
defaultValue: "删除供应商失败: {{error}}",
|
|
error: error.message,
|
|
}),
|
|
);
|
|
},
|
|
});
|
|
};
|
|
|
|
export const useSwitchProviderMutation = (appId: AppId) => {
|
|
const queryClient = useQueryClient();
|
|
const { t } = useTranslation();
|
|
|
|
return useMutation({
|
|
mutationFn: async (providerId: string) => {
|
|
return await providersApi.switch(providerId, appId);
|
|
},
|
|
onSuccess: async () => {
|
|
await queryClient.invalidateQueries({ queryKey: ["providers", appId] });
|
|
|
|
// 更新托盘菜单(失败不影响主操作)
|
|
try {
|
|
await providersApi.updateTrayMenu();
|
|
} catch (trayError) {
|
|
console.error(
|
|
"Failed to update tray menu after switching provider",
|
|
trayError,
|
|
);
|
|
}
|
|
|
|
toast.success(
|
|
t("notifications.switchSuccess", {
|
|
defaultValue: "切换供应商成功",
|
|
appName: t(`apps.${appId}`, { defaultValue: appId }),
|
|
}),
|
|
);
|
|
},
|
|
onError: (error: Error) => {
|
|
const detail = extractErrorMessage(error) || t("common.unknown");
|
|
|
|
// 标题与详情分离,便于扫描 + 一键复制
|
|
toast.error(
|
|
t("notifications.switchFailedTitle", { defaultValue: "切换失败" }),
|
|
{
|
|
description: t("notifications.switchFailed", {
|
|
defaultValue: "切换失败:{{error}}",
|
|
error: detail,
|
|
}),
|
|
duration: 6000,
|
|
action: {
|
|
label: t("common.copy", { defaultValue: "复制" }),
|
|
onClick: () => {
|
|
navigator.clipboard?.writeText(detail).catch(() => undefined);
|
|
},
|
|
},
|
|
},
|
|
);
|
|
},
|
|
});
|
|
};
|
|
|
|
export const useSaveSettingsMutation = () => {
|
|
const queryClient = useQueryClient();
|
|
|
|
return useMutation({
|
|
mutationFn: async (settings: Settings) => {
|
|
await settingsApi.save(settings);
|
|
},
|
|
onSuccess: async () => {
|
|
await queryClient.invalidateQueries({ queryKey: ["settings"] });
|
|
},
|
|
});
|
|
};
|