4adafa1936
Add P7 Cytoscape relationship graph with setting CRUD, P9 cockpit analytics driven by writing_sessions, chapter POV selection, and full test coverage. Co-authored-by: Cursor <cursoragent@cursor.com>
35 lines
978 B
TypeScript
35 lines
978 B
TypeScript
import { create } from 'zustand'
|
|
import type { CharacterGraphData } from '@shared/types'
|
|
import { ipcCall } from '@renderer/lib/ipc-client'
|
|
|
|
interface GraphState {
|
|
open: boolean
|
|
data: CharacterGraphData | null
|
|
loading: boolean
|
|
filter: 'all' | 'connected'
|
|
openModal: () => void
|
|
close: () => void
|
|
load: (bookId: string, filter?: 'all' | 'connected') => Promise<void>
|
|
setFilter: (filter: 'all' | 'connected') => void
|
|
}
|
|
|
|
export const useGraphStore = create<GraphState>((set, get) => ({
|
|
open: false,
|
|
data: null,
|
|
loading: false,
|
|
filter: 'all',
|
|
openModal: () => set({ open: true }),
|
|
close: () => set({ open: false, data: null }),
|
|
setFilter: (filter) => set({ filter }),
|
|
load: async (bookId, filter) => {
|
|
const f = filter ?? get().filter
|
|
set({ loading: true })
|
|
try {
|
|
const data = await ipcCall(() => window.electronAPI.graph.getData(bookId, f))
|
|
set({ data, filter: f })
|
|
} finally {
|
|
set({ loading: false })
|
|
}
|
|
}
|
|
}))
|