mirror of
https://github.com/OFFIS-ESC/constellation-analyzer
synced 2026-01-26 23:43:40 +00:00
feat: implement global settings system with localStorage persistence
Creates a new extendable settings store for application-wide preferences that persist across browser sessions using Zustand's persist middleware. Architecture: - New settingsStore.ts using Zustand persist middleware - Automatic localStorage synchronization - Versioned schema (v1) for future migrations - Clean, typed interface for easy extensibility Changes: - Created settingsStore for persistent global settings - Migrated autoZoomEnabled from searchStore to settingsStore - Updated GraphEditor to use settings store for auto-zoom - Updated LeftPanel to use settings store for toggle control - searchStore now focuses on ephemeral filter/search state Settings Persistence: - Storage key: 'constellation-settings' - Automatically saves on any setting change - Restores settings on page reload - Same proven pattern as panelStore Future Extensibility: The settings store is designed to easily accommodate new settings: - Theme preferences (light/dark mode) - Default view options - User interface preferences - Any application-wide persistent settings Benefits: - User preferences persist across sessions - Clean separation between ephemeral and persistent state - Type-safe settings management - Easy to extend for future features 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
58e04650c0
commit
084a3bb486
4 changed files with 48 additions and 12 deletions
|
|
@ -25,6 +25,7 @@ import { useGraphWithHistory } from "../../hooks/useGraphWithHistory";
|
|||
import { useDocumentHistory } from "../../hooks/useDocumentHistory";
|
||||
import { useEditorStore } from "../../stores/editorStore";
|
||||
import { useSearchStore } from "../../stores/searchStore";
|
||||
import { useSettingsStore } from "../../stores/settingsStore";
|
||||
import { useActiveDocument } from "../../stores/workspace/useActiveDocument";
|
||||
import { useWorkspaceStore } from "../../stores/workspaceStore";
|
||||
import { useCreateDocument } from "../../hooks/useCreateDocument";
|
||||
|
|
@ -108,9 +109,11 @@ const GraphEditor = ({ onNodeSelect, onEdgeSelect, onAddNodeRequest, onExportReq
|
|||
searchText,
|
||||
visibleActorTypes,
|
||||
visibleRelationTypes,
|
||||
autoZoomEnabled,
|
||||
} = useSearchStore();
|
||||
|
||||
// Settings for auto-zoom
|
||||
const { autoZoomEnabled } = useSettingsStore();
|
||||
|
||||
// Track previous document ID to save viewport before switching
|
||||
const prevDocumentIdRef = useRef<string | null>(null);
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import { usePanelStore } from '../../stores/panelStore';
|
|||
import { useGraphWithHistory } from '../../hooks/useGraphWithHistory';
|
||||
import { useEditorStore } from '../../stores/editorStore';
|
||||
import { useSearchStore } from '../../stores/searchStore';
|
||||
import { useSettingsStore } from '../../stores/settingsStore';
|
||||
import { createNode } from '../../utils/nodeUtils';
|
||||
import { getIconComponent } from '../../utils/iconUtils';
|
||||
import { getContrastColor } from '../../utils/colorUtils';
|
||||
|
|
@ -87,12 +88,13 @@ const LeftPanel = forwardRef<LeftPanelRef, LeftPanelProps>(({ onDeselectAll, onA
|
|||
setActorTypeVisible,
|
||||
visibleRelationTypes,
|
||||
setRelationTypeVisible,
|
||||
autoZoomEnabled,
|
||||
setAutoZoomEnabled,
|
||||
clearFilters,
|
||||
hasActiveFilters,
|
||||
} = useSearchStore();
|
||||
|
||||
// Settings
|
||||
const { autoZoomEnabled, setAutoZoomEnabled } = useSettingsStore();
|
||||
|
||||
// Initialize filter state when node/edge types change
|
||||
useEffect(() => {
|
||||
nodeTypes.forEach((nodeType) => {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import { create } from 'zustand';
|
|||
* - Search text for filtering both actors (by label, description, or type) and relations (by label or type)
|
||||
* - Filter by actor types (show/hide specific node types)
|
||||
* - Filter by relation types (show/hide specific edge types)
|
||||
* - Auto-zoom to filtered results (optional, enabled by default)
|
||||
* - Results tracking
|
||||
*/
|
||||
|
||||
|
|
@ -28,10 +27,6 @@ interface SearchStore {
|
|||
toggleRelationType: (typeId: string) => void;
|
||||
setAllRelationTypesVisible: (visible: boolean) => void;
|
||||
|
||||
// Auto-zoom to filtered results
|
||||
autoZoomEnabled: boolean;
|
||||
setAutoZoomEnabled: (enabled: boolean) => void;
|
||||
|
||||
// Clear all filters
|
||||
clearFilters: () => void;
|
||||
|
||||
|
|
@ -43,7 +38,6 @@ export const useSearchStore = create<SearchStore>((set, get) => ({
|
|||
searchText: '',
|
||||
visibleActorTypes: {},
|
||||
visibleRelationTypes: {},
|
||||
autoZoomEnabled: true,
|
||||
|
||||
setSearchText: (text: string) =>
|
||||
set({ searchText: text }),
|
||||
|
|
@ -98,9 +92,6 @@ export const useSearchStore = create<SearchStore>((set, get) => ({
|
|||
return { visibleRelationTypes: updated };
|
||||
}),
|
||||
|
||||
setAutoZoomEnabled: (enabled: boolean) =>
|
||||
set({ autoZoomEnabled: enabled }),
|
||||
|
||||
clearFilters: () =>
|
||||
set((state) => {
|
||||
// Reset all actor types to visible
|
||||
|
|
|
|||
40
src/stores/settingsStore.ts
Normal file
40
src/stores/settingsStore.ts
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
import { create } from 'zustand';
|
||||
import { persist } from 'zustand/middleware';
|
||||
|
||||
/**
|
||||
* Settings Store - Global application settings with localStorage persistence
|
||||
*
|
||||
* Features:
|
||||
* - Search and filter preferences
|
||||
* - UI behavior settings
|
||||
* - Auto-save to localStorage
|
||||
* - Extendable for future settings
|
||||
*/
|
||||
|
||||
interface SettingsState {
|
||||
// Search & Filter Settings
|
||||
autoZoomEnabled: boolean;
|
||||
setAutoZoomEnabled: (enabled: boolean) => void;
|
||||
|
||||
// Future settings can be added here
|
||||
// Example:
|
||||
// theme: 'light' | 'dark';
|
||||
// setTheme: (theme: 'light' | 'dark') => void;
|
||||
}
|
||||
|
||||
export const useSettingsStore = create<SettingsState>()(
|
||||
persist(
|
||||
(set) => ({
|
||||
// Search & Filter Settings
|
||||
autoZoomEnabled: true,
|
||||
setAutoZoomEnabled: (enabled: boolean) =>
|
||||
set({ autoZoomEnabled: enabled }),
|
||||
|
||||
// Future settings implementations go here
|
||||
}),
|
||||
{
|
||||
name: 'constellation-settings', // localStorage key
|
||||
version: 1, // For future migrations if needed
|
||||
}
|
||||
)
|
||||
);
|
||||
Loading…
Reference in a new issue