refactor(openclaw): migrate config panels to TanStack Query hooks

Centralize query keys and extract reusable hooks (useOpenClaw.ts),
replacing manual useState/useEffect load/save patterns in Env, Tools,
and AgentsDefaults panels for consistency with MCP/Skills modules.
This commit is contained in:
Jason
2026-02-08 15:35:09 +08:00
parent bc87f9d9eb
commit 00b424628f
8 changed files with 228 additions and 120 deletions
+128
View File
@@ -0,0 +1,128 @@
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { openclawApi } from "@/lib/api/openclaw";
import { providersApi } from "@/lib/api/providers";
import type {
OpenClawEnvConfig,
OpenClawToolsConfig,
OpenClawAgentsDefaults,
} from "@/types";
/**
* Centralized query keys for all OpenClaw-related queries.
* Import this from any file that needs to invalidate OpenClaw caches.
*/
export const openclawKeys = {
all: ["openclaw"] as const,
liveProviderIds: ["openclaw", "liveProviderIds"] as const,
defaultModel: ["openclaw", "defaultModel"] as const,
env: ["openclaw", "env"] as const,
tools: ["openclaw", "tools"] as const,
agentsDefaults: ["openclaw", "agentsDefaults"] as const,
};
// ============================================================
// Query hooks
// ============================================================
/**
* Query live provider IDs from openclaw.json config.
* Used by ProviderList to show "In Config" badge.
*/
export function useOpenClawLiveProviderIds(enabled: boolean) {
return useQuery({
queryKey: openclawKeys.liveProviderIds,
queryFn: () => providersApi.getOpenClawLiveProviderIds(),
enabled,
});
}
/**
* Query the default model from agents.defaults.model.
* Used by ProviderList to show which provider is the default.
*/
export function useOpenClawDefaultModel(enabled: boolean) {
return useQuery({
queryKey: openclawKeys.defaultModel,
queryFn: () => openclawApi.getDefaultModel(),
enabled,
});
}
/**
* Query env section of openclaw.json.
*/
export function useOpenClawEnv() {
return useQuery({
queryKey: openclawKeys.env,
queryFn: () => openclawApi.getEnv(),
});
}
/**
* Query tools section of openclaw.json.
*/
export function useOpenClawTools() {
return useQuery({
queryKey: openclawKeys.tools,
queryFn: () => openclawApi.getTools(),
});
}
/**
* Query agents.defaults section of openclaw.json.
*/
export function useOpenClawAgentsDefaults() {
return useQuery({
queryKey: openclawKeys.agentsDefaults,
queryFn: () => openclawApi.getAgentsDefaults(),
});
}
// ============================================================
// Mutation hooks
// ============================================================
/**
* Save env config. Invalidates env query on success.
* Toast notifications are handled by the component.
*/
export function useSaveOpenClawEnv() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (env: OpenClawEnvConfig) => openclawApi.setEnv(env),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: openclawKeys.env });
},
});
}
/**
* Save tools config. Invalidates tools query on success.
* Toast notifications are handled by the component.
*/
export function useSaveOpenClawTools() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (tools: OpenClawToolsConfig) => openclawApi.setTools(tools),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: openclawKeys.tools });
},
});
}
/**
* Save agents.defaults config. Invalidates both agentsDefaults and defaultModel
* queries on success (since changing agents.defaults may affect the default model).
* Toast notifications are handled by the component.
*/
export function useSaveOpenClawAgentsDefaults() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (defaults: OpenClawAgentsDefaults) =>
openclawApi.setAgentsDefaults(defaults),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: openclawKeys.agentsDefaults });
queryClient.invalidateQueries({ queryKey: openclawKeys.defaultModel });
},
});
}
+2 -1
View File
@@ -17,6 +17,7 @@ import {
useSwitchProviderMutation,
} from "@/lib/query";
import { extractErrorMessage } from "@/utils/errorUtils";
import { openclawKeys } from "@/hooks/useOpenClaw";
/**
* Hook for managing provider actions (add, update, delete, switch)
@@ -244,7 +245,7 @@ export function useProviderActions(activeApp: AppId) {
try {
await openclawApi.setDefaultModel(model);
await queryClient.invalidateQueries({
queryKey: ["openclawDefaultModel"],
queryKey: openclawKeys.defaultModel,
});
toast.success(
t("notifications.openclawDefaultModelSet", {