Files
automaker/apps/ui/src/hooks/mutations/use-settings-mutations.ts
Shirone 845674128e feat(ui): add React Query mutation hooks
- Add feature mutations (create, update, delete with optimistic updates)
- Add auto-mode mutations (start, stop, approve plan)
- Add worktree mutations (create, delete, checkout, switch branch)
- Add settings mutations (update global/project, validate API keys)
- Add GitHub mutations (create PR, validate PR)
- Add cursor permissions mutations (apply profile, copy config)
- Add spec mutations (generate, update, save)
- Add pipeline mutations (toggle, update config)
- Add session mutations with cache invalidation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-15 16:20:38 +01:00

145 lines
4.2 KiB
TypeScript

/**
* Settings Mutations
*
* React Query mutations for updating global and project settings.
*/
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { getElectronAPI } from '@/lib/electron';
import { queryKeys } from '@/lib/query-keys';
import { toast } from 'sonner';
interface UpdateGlobalSettingsOptions {
/** Show success toast (default: true) */
showSuccessToast?: boolean;
}
/**
* Update global settings
*
* @param options - Configuration options
* @returns Mutation for updating global settings
*
* @example
* ```tsx
* const mutation = useUpdateGlobalSettings();
* mutation.mutate({ enableSkills: true });
*
* // With custom success handling (no default toast)
* const mutation = useUpdateGlobalSettings({ showSuccessToast: false });
* mutation.mutate({ enableSkills: true }, {
* onSuccess: () => toast.success('Skills enabled'),
* });
* ```
*/
export function useUpdateGlobalSettings(options: UpdateGlobalSettingsOptions = {}) {
const { showSuccessToast = true } = options;
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (settings: Record<string, unknown>) => {
const api = getElectronAPI();
// Use updateGlobal for partial updates
const result = await api.settings.updateGlobal(settings);
if (!result.success) {
throw new Error(result.error || 'Failed to update settings');
}
return result;
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: queryKeys.settings.global() });
if (showSuccessToast) {
toast.success('Settings saved');
}
},
onError: (error: Error) => {
toast.error('Failed to save settings', {
description: error.message,
});
},
});
}
/**
* Update project settings
*
* @param projectPath - Optional path to the project (can also pass via mutation variables)
* @returns Mutation for updating project settings
*/
export function useUpdateProjectSettings(projectPath?: string) {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (
variables:
| Record<string, unknown>
| { projectPath: string; settings: Record<string, unknown> }
) => {
// Support both call patterns:
// 1. useUpdateProjectSettings(projectPath) then mutate(settings)
// 2. useUpdateProjectSettings() then mutate({ projectPath, settings })
let path: string;
let settings: Record<string, unknown>;
if ('projectPath' in variables && 'settings' in variables) {
path = variables.projectPath;
settings = variables.settings;
} else if (projectPath) {
path = projectPath;
settings = variables;
} else {
throw new Error('Project path is required');
}
const api = getElectronAPI();
const result = await api.settings.setProject(path, settings);
if (!result.success) {
throw new Error(result.error || 'Failed to update project settings');
}
return { ...result, projectPath: path };
},
onSuccess: (data) => {
const path = data.projectPath || projectPath;
if (path) {
queryClient.invalidateQueries({ queryKey: queryKeys.settings.project(path) });
}
toast.success('Project settings saved');
},
onError: (error: Error) => {
toast.error('Failed to save project settings', {
description: error.message,
});
},
});
}
/**
* Save credentials (API keys)
*
* @returns Mutation for saving credentials
*/
export function useSaveCredentials() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (credentials: Record<string, string>) => {
const api = getElectronAPI();
const result = await api.settings.setCredentials(credentials);
if (!result.success) {
throw new Error(result.error || 'Failed to save credentials');
}
return result;
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: queryKeys.settings.credentials() });
queryClient.invalidateQueries({ queryKey: queryKeys.cli.apiKeys() });
toast.success('Credentials saved');
},
onError: (error: Error) => {
toast.error('Failed to save credentials', {
description: error.message,
});
},
});
}