- Introduced an HTTP server to facilitate communication with the application. - Added route handlers for managing application configuration, including getting and updating settings. - Implemented notification operations with routes for retrieving, marking, and deleting notifications. - Created project and session management routes to list projects, sessions, and their details. - Developed SSH connection management routes for connecting, disconnecting, and retrieving SSH state and configuration. - Enhanced the application architecture to support real-time event streaming via Server-Sent Events (SSE). This commit significantly expands the application's capabilities by integrating an HTTP server and various management routes, improving user interaction and functionality.
90 lines
2.6 KiB
TypeScript
90 lines
2.6 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;
|
|
|
|
// Actions
|
|
fetchConfig: () => Promise<void>;
|
|
updateConfig: (section: string, data: Record<string, unknown>) => Promise<void>;
|
|
openSettingsTab: () => void;
|
|
}
|
|
|
|
// =============================================================================
|
|
// Slice Creator
|
|
// =============================================================================
|
|
|
|
export const createConfigSlice: StateCreator<AppState, [], [], ConfigSlice> = (set, get) => ({
|
|
// Initial state
|
|
appConfig: null,
|
|
configLoading: false,
|
|
configError: 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: () => {
|
|
const state = get();
|
|
|
|
// 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',
|
|
});
|
|
},
|
|
});
|