agent-ecosystem/src/renderer/store/slices/configSlice.ts
matt 9915cf5a03 feat(settings): enhance Claude root management and UI updates
- Implemented functionality to select and manage the local Claude root folder, allowing users to specify a custom path.
- Added UI components for displaying and interacting with Claude root settings, including error handling for missing directories.
- Enhanced the settings view to support dynamic updates based on user selections and improved state management for pending settings.
- Refactored related components to integrate the new Claude root features seamlessly, including updates to the general settings section and connection handling.
2026-02-16 20:06:09 +09:00

101 lines
2.9 KiB
TypeScript

/**
* Config slice - manages app configuration state and actions.
*/
import { api } from '@renderer/api';
import { createLogger } from '@shared/utils/logger';
import type { AppState } from '../types';
import type { AppConfig } from '@renderer/types/data';
import type { StateCreator } from 'zustand';
const logger = createLogger('Store:config');
// =============================================================================
// Slice Interface
// =============================================================================
export interface ConfigSlice {
// State
appConfig: AppConfig | null;
configLoading: boolean;
configError: string | null;
pendingSettingsSection: string | null;
// Actions
fetchConfig: () => Promise<void>;
updateConfig: (section: string, data: Record<string, unknown>) => Promise<void>;
openSettingsTab: (section?: string) => void;
clearPendingSettingsSection: () => void;
}
// =============================================================================
// Slice Creator
// =============================================================================
export const createConfigSlice: StateCreator<AppState, [], [], ConfigSlice> = (set, get) => ({
// Initial state
appConfig: null,
configLoading: false,
configError: null,
pendingSettingsSection: null,
// Fetch app configuration from main process
fetchConfig: async () => {
set({ configLoading: true, configError: null });
try {
const config = await api.config.get();
set({
appConfig: config,
configLoading: false,
});
} catch (error) {
set({
configError: error instanceof Error ? error.message : 'Failed to fetch config',
configLoading: false,
});
}
},
// Update a section of the app configuration
updateConfig: async (section: string, data: Record<string, unknown>) => {
try {
await api.config.update(section, data);
// Refresh config after update
const config = await api.config.get();
set({ appConfig: config });
} catch (error) {
logger.error('Failed to update config:', error);
set({
configError: error instanceof Error ? error.message : 'Failed to update config',
});
}
},
// Open or focus the settings tab (per-pane singleton)
openSettingsTab: (section?: string) => {
const state = get();
if (section) {
set({ pendingSettingsSection: section });
}
// Check if settings tab exists in focused pane
const focusedPane = state.paneLayout.panes.find((p) => p.id === state.paneLayout.focusedPaneId);
const settingsTab = focusedPane?.tabs.find((t) => t.type === 'settings');
if (settingsTab) {
state.setActiveTab(settingsTab.id);
return;
}
// Create new settings tab via openTab (which adds to focused pane)
state.openTab({
type: 'settings',
label: 'Settings',
});
},
clearPendingSettingsSection: () => {
set({ pendingSettingsSection: null });
},
});