refactor(types): rename AppType to AppId for semantic clarity

Rename `AppType` to `AppId` across the entire frontend codebase to better
reflect its purpose as an application identifier rather than a type category.
This aligns frontend naming with backend command parameter conventions.

Changes:
- Rename type `AppType` to `AppId` in src/lib/api/types.ts
- Remove `AppType` export from src/lib/api/index.ts
- Update all component props from `appType` to `appId` (43 files)
- Update all variable names from `appType` to `appId`
- Synchronize documentation (CHANGELOG, refactoring plans)
- Update test files and MSW mocks

BREAKING CHANGE: `AppType` type is no longer exported. Use `AppId` instead.
All component props have been renamed from `appType` to `appId`.
This commit is contained in:
Jason
2025-10-30 14:59:15 +08:00
parent 80dd6e9381
commit 8e4a0a1bbb
43 changed files with 327 additions and 347 deletions

View File

@@ -2,7 +2,7 @@ import { useCallback, useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
import { homeDir, join } from "@tauri-apps/api/path";
import { settingsApi, type AppType } from "@/lib/api";
import { settingsApi, type AppId } from "@/lib/api";
import type { SettingsFormState } from "./useSettingsForm";
type DirectoryKey = "appConfig" | "claude" | "codex";
@@ -33,7 +33,7 @@ const computeDefaultAppConfigDir = async (): Promise<string | undefined> => {
};
const computeDefaultConfigDir = async (
app: AppType,
app: AppId,
): Promise<string | undefined> => {
try {
const home = await homeDir();
@@ -58,11 +58,11 @@ export interface UseDirectorySettingsResult {
resolvedDirs: ResolvedDirectories;
isLoading: boolean;
initialAppConfigDir?: string;
updateDirectory: (app: AppType, value?: string) => void;
updateDirectory: (app: AppId, value?: string) => void;
updateAppConfigDir: (value?: string) => void;
browseDirectory: (app: AppType) => Promise<void>;
browseDirectory: (app: AppId) => Promise<void>;
browseAppConfigDir: () => Promise<void>;
resetDirectory: (app: AppType) => Promise<void>;
resetDirectory: (app: AppId) => Promise<void>;
resetAppConfigDir: () => Promise<void>;
resetAllDirectories: (claudeDir?: string, codexDir?: string) => void;
}
@@ -187,14 +187,14 @@ export function useDirectorySettings({
);
const updateDirectory = useCallback(
(app: AppType, value?: string) => {
(app: AppId, value?: string) => {
updateDirectoryState(app === "claude" ? "claude" : "codex", value);
},
[updateDirectoryState],
);
const browseDirectory = useCallback(
async (app: AppType) => {
async (app: AppId) => {
const key: DirectoryKey = app === "claude" ? "claude" : "codex";
const currentValue =
key === "claude"
@@ -239,7 +239,7 @@ export function useDirectorySettings({
}, [appConfigDir, resolvedDirs.appConfig, t, updateDirectoryState]);
const resetDirectory = useCallback(
async (app: AppType) => {
async (app: AppId) => {
const key: DirectoryKey = app === "claude" ? "claude" : "codex";
if (!defaultsRef.current[key]) {
const fallback = await computeDefaultConfigDir(app);

View File

@@ -11,11 +11,11 @@ import { useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { useTranslation } from "react-i18next";
import type { Provider } from "@/types";
import { providersApi, type AppType } from "@/lib/api";
import { providersApi, type AppId } from "@/lib/api";
export function useDragSort(
providers: Record<string, Provider>,
appType: AppType,
appId: AppId,
) {
const queryClient = useQueryClient();
const { t, i18n } = useTranslation();
@@ -73,9 +73,9 @@ export function useDragSort(
}));
try {
await providersApi.updateSortOrder(updates, appType);
await providersApi.updateSortOrder(updates, appId);
await queryClient.invalidateQueries({
queryKey: ["providers", appType],
queryKey: ["providers", appId],
});
toast.success(
t("provider.sortUpdated", {
@@ -91,7 +91,7 @@ export function useDragSort(
);
}
},
[sortedProviders, appType, queryClient, t],
[sortedProviders, appId, queryClient, t],
);
return {

View File

@@ -1,7 +1,7 @@
import { useCallback, useState } from "react";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
import { mcpApi, type AppType } from "@/lib/api";
import { mcpApi, type AppId } from "@/lib/api";
import type { McpServer } from "@/types";
import {
extractErrorMessage,
@@ -30,7 +30,7 @@ export interface UseMcpActionsResult {
* - Delete server
* - Error handling and toast notifications
*/
export function useMcpActions(appType: AppType): UseMcpActionsResult {
export function useMcpActions(appId: AppId): UseMcpActionsResult {
const { t } = useTranslation();
const [servers, setServers] = useState<Record<string, McpServer>>({});
const [loading, setLoading] = useState(false);
@@ -38,7 +38,7 @@ export function useMcpActions(appType: AppType): UseMcpActionsResult {
const reload = useCallback(async () => {
setLoading(true);
try {
const cfg = await mcpApi.getConfig(appType);
const cfg = await mcpApi.getConfig(appId);
setServers(cfg.servers || {});
} catch (error) {
console.error("[useMcpActions] Failed to load MCP config", error);
@@ -50,7 +50,7 @@ export function useMcpActions(appType: AppType): UseMcpActionsResult {
} finally {
setLoading(false);
}
}, [appType, t]);
}, [appId, t]);
const toggleEnabled = useCallback(
async (id: string, enabled: boolean) => {
@@ -65,7 +65,7 @@ export function useMcpActions(appType: AppType): UseMcpActionsResult {
}));
try {
await mcpApi.setEnabled(appType, id, enabled);
await mcpApi.setEnabled(appId, id, enabled);
toast.success(enabled ? t("mcp.msg.enabled") : t("mcp.msg.disabled"), {
duration: 1500,
});
@@ -79,7 +79,7 @@ export function useMcpActions(appType: AppType): UseMcpActionsResult {
});
}
},
[appType, servers, t],
[appId, servers, t],
);
const saveServer = useCallback(
@@ -90,7 +90,7 @@ export function useMcpActions(appType: AppType): UseMcpActionsResult {
) => {
try {
const payload: McpServer = { ...server, id };
await mcpApi.upsertServerInConfig(appType, id, payload, {
await mcpApi.upsertServerInConfig(appId, id, payload, {
syncOtherSide: options?.syncOtherSide,
});
await reload();
@@ -104,13 +104,13 @@ export function useMcpActions(appType: AppType): UseMcpActionsResult {
throw error;
}
},
[appType, reload, t],
[appId, reload, t],
);
const deleteServer = useCallback(
async (id: string) => {
try {
await mcpApi.deleteServerInConfig(appType, id);
await mcpApi.deleteServerInConfig(appId, id);
await reload();
toast.success(t("mcp.msg.deleted"), { duration: 1500 });
} catch (error) {
@@ -122,7 +122,7 @@ export function useMcpActions(appType: AppType): UseMcpActionsResult {
throw error;
}
},
[appType, reload, t],
[appId, reload, t],
);
return {

View File

@@ -2,7 +2,7 @@ import { useCallback } from "react";
import { useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { useTranslation } from "react-i18next";
import { providersApi, settingsApi, type AppType } from "@/lib/api";
import { providersApi, settingsApi, type AppId } from "@/lib/api";
import type { Provider, UsageScript } from "@/types";
import {
useAddProviderMutation,
@@ -16,7 +16,7 @@ import { extractErrorMessage } from "@/utils/errorUtils";
* Hook for managing provider actions (add, update, delete, switch)
* Extracts business logic from App.tsx
*/
export function useProviderActions(activeApp: AppType) {
export function useProviderActions(activeApp: AppId) {
const { t } = useTranslation();
const queryClient = useQueryClient();

View File

@@ -1,7 +1,7 @@
import { useCallback, useMemo } from "react";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
import { settingsApi, type AppType } from "@/lib/api";
import { settingsApi, type AppId } from "@/lib/api";
import { useSettingsQuery, useSaveSettingsMutation } from "@/lib/query";
import type { Settings } from "@/types";
import { useSettingsForm, type SettingsFormState } from "./useSettingsForm";
@@ -26,11 +26,11 @@ export interface UseSettingsResult {
resolvedDirs: ResolvedDirectories;
requiresRestart: boolean;
updateSettings: (updates: Partial<SettingsFormState>) => void;
updateDirectory: (app: AppType, value?: string) => void;
updateDirectory: (app: AppId, value?: string) => void;
updateAppConfigDir: (value?: string) => void;
browseDirectory: (app: AppType) => Promise<void>;
browseDirectory: (app: AppId) => Promise<void>;
browseAppConfigDir: () => Promise<void>;
resetDirectory: (app: AppType) => Promise<void>;
resetDirectory: (app: AppId) => Promise<void>;
resetAppConfigDir: () => Promise<void>;
saveSettings: () => Promise<SaveResult | null>;
resetSettings: () => void;