/** * UI Store Module * * Zustand store for managing UI state and operations. * Handles: * - Global loading state * - Global error messages * - Left panel width with localStorage persistence * * @module stores/uiStore */ import { create } from 'zustand'; import type { UIStoreState } from '../types/store'; import { getItem, setItem } from '../utils/storage'; /** * LocalStorage key for persisting left panel width */ const LEFT_PANEL_WIDTH_KEY = 'ax-leftPanelWidth'; /** * Default left panel width percentage */ const DEFAULT_LEFT_PANEL_WIDTH = 40; /** * Load left panel width from localStorage * * @returns Persisted width or default value */ const loadLeftPanelWidth = (): number => { const saved = getItem(LEFT_PANEL_WIDTH_KEY); return saved ?? DEFAULT_LEFT_PANEL_WIDTH; }; /** * UI store * * Manages global UI state including loading indicators, error messages, * panel width preferences, and document preview state. * * The left panel width is automatically persisted to localStorage * when updated via setLeftPanelWidth action. * * @example * ```typescript * // Set global loading state * useUIStore.getState().setLoading(true); * * // Set global error message * useUIStore.getState().setError('Failed to load document'); * * // Clear error * useUIStore.getState().setError(null); * * // Update left panel width (persists to localStorage) * useUIStore.getState().setLeftPanelWidth(35); * * // Open document preview * useUIStore.getState().openDocumentPreview('doc-abc123'); * * // Close document preview and return to chat * useUIStore.getState().closeDocumentPreview(); * ``` */ export const useUIStore = create((set) => ({ // ============ State ============ loading: false, error: null, leftPanelWidth: loadLeftPanelWidth(), // Note: previewMode is deprecated. Right panel now shows EditorPanel by default. // Kept for backward compatibility. previewMode: false, previewDocumentId: null, previewDocumentName: null, // ============ Actions ============ /** * Set global loading state * * Controls the global loading indicator. * Used for app-wide loading states like initial app load. * * @param loading - True to show loading, false to hide */ setLoading: (loading: boolean) => { set({ loading }); }, /** * Set global error message * * Sets a global error message to display to the user. * Pass null to clear the error. * * @param error - Error message string or null to clear */ setError: (error: string | null) => { set({ error }); }, /** * Set left panel width and persist to localStorage * * Updates the left panel width and saves it to localStorage * for persistence across sessions. * * @param width - Width percentage (0-100) */ setLeftPanelWidth: (width: number) => { // Update store state set({ leftPanelWidth: width }); // Persist to localStorage setItem(LEFT_PANEL_WIDTH_KEY, width); }, /** * Open document preview mode * * Opens the document in the right panel EditorPanel for preview and editing. * Used when user clicks on an export record link in the chat. * * @param documentId - ID of the document to preview * @param documentName - Optional name of the document to display in the editor toolbar */ openDocumentPreview: (documentId: string, documentName?: string) => { set({ previewDocumentId: documentId, previewDocumentName: documentName || null, }); }, /** * Close document preview mode * * Closes the document in the right panel EditorPanel. */ closeDocumentPreview: () => { set({ previewDocumentId: null, previewDocumentName: null, }); }, })); export default useUIStore;