Merge branch 'improve-property-tooltip' into loginPage

This commit is contained in:
choizhang
2025-03-15 00:11:50 +08:00
57 changed files with 1822 additions and 606 deletions

View File

@@ -1,6 +1,7 @@
import { create } from 'zustand'
import { createSelectors } from '@/lib/utils'
import { DirectedGraph } from 'graphology'
import { getGraphLabels } from '@/api/lightrag'
export type RawNodeType = {
id: string
@@ -65,9 +66,17 @@ interface GraphState {
rawGraph: RawGraph | null
sigmaGraph: DirectedGraph | null
allDatabaseLabels: string[]
moveToSelectedNode: boolean
isFetching: boolean
shouldRender: boolean
// Global flags to track data fetching attempts
graphDataFetchAttempted: boolean
labelsFetchAttempted: boolean
refreshLayout: () => void
setSelectedNode: (nodeId: string | null, moveToSelectedNode?: boolean) => void
setFocusedNode: (nodeId: string | null) => void
setSelectedEdge: (edgeId: string | null) => void
@@ -79,19 +88,47 @@ interface GraphState {
setRawGraph: (rawGraph: RawGraph | null) => void
setSigmaGraph: (sigmaGraph: DirectedGraph | null) => void
setAllDatabaseLabels: (labels: string[]) => void
fetchAllDatabaseLabels: () => Promise<void>
setIsFetching: (isFetching: boolean) => void
setShouldRender: (shouldRender: boolean) => void
// Methods to set global flags
setGraphDataFetchAttempted: (attempted: boolean) => void
setLabelsFetchAttempted: (attempted: boolean) => void
}
const useGraphStoreBase = create<GraphState>()((set) => ({
const useGraphStoreBase = create<GraphState>()((set, get) => ({
selectedNode: null,
focusedNode: null,
selectedEdge: null,
focusedEdge: null,
moveToSelectedNode: false,
isFetching: false,
shouldRender: false,
// Initialize global flags
graphDataFetchAttempted: false,
labelsFetchAttempted: false,
rawGraph: null,
sigmaGraph: null,
allDatabaseLabels: ['*'],
refreshLayout: () => {
const currentGraph = get().sigmaGraph;
if (currentGraph) {
get().clearSelection();
get().setSigmaGraph(null);
setTimeout(() => {
get().setSigmaGraph(currentGraph);
}, 10);
}
},
setIsFetching: (isFetching: boolean) => set({ isFetching }),
setShouldRender: (shouldRender: boolean) => set({ shouldRender }),
setSelectedNode: (nodeId: string | null, moveToSelectedNode?: boolean) =>
set({ selectedNode: nodeId, moveToSelectedNode }),
setFocusedNode: (nodeId: string | null) => set({ focusedNode: nodeId }),
@@ -104,25 +141,58 @@ const useGraphStoreBase = create<GraphState>()((set) => ({
selectedEdge: null,
focusedEdge: null
}),
reset: () =>
reset: () => {
// Get the existing graph
const existingGraph = get().sigmaGraph;
// If we have an existing graph, clear it by removing all nodes
if (existingGraph) {
const nodes = Array.from(existingGraph.nodes());
nodes.forEach(node => existingGraph.dropNode(node));
}
set({
selectedNode: null,
focusedNode: null,
selectedEdge: null,
focusedEdge: null,
rawGraph: null,
sigmaGraph: null,
moveToSelectedNode: false
}),
// Keep the existing graph instance but with cleared data
moveToSelectedNode: false,
shouldRender: false
});
},
setRawGraph: (rawGraph: RawGraph | null) =>
set({
rawGraph
}),
setSigmaGraph: (sigmaGraph: DirectedGraph | null) => set({ sigmaGraph }),
setSigmaGraph: (sigmaGraph: DirectedGraph | null) => {
// Replace graph instance, no need to keep WebGL context
set({ sigmaGraph });
},
setMoveToSelectedNode: (moveToSelectedNode?: boolean) => set({ moveToSelectedNode })
setAllDatabaseLabels: (labels: string[]) => set({ allDatabaseLabels: labels }),
fetchAllDatabaseLabels: async () => {
try {
console.log('Fetching all database labels...');
const labels = await getGraphLabels();
set({ allDatabaseLabels: ['*', ...labels] });
return;
} catch (error) {
console.error('Failed to fetch all database labels:', error);
set({ allDatabaseLabels: ['*'] });
throw error;
}
},
setMoveToSelectedNode: (moveToSelectedNode?: boolean) => set({ moveToSelectedNode }),
// Methods to set global flags
setGraphDataFetchAttempted: (attempted: boolean) => set({ graphDataFetchAttempted: attempted }),
setLabelsFetchAttempted: (attempted: boolean) => set({ labelsFetchAttempted: attempted })
}))
const useGraphStore = createSelectors(useGraphStoreBase)

View File

@@ -5,6 +5,7 @@ import { defaultQueryLabel } from '@/lib/constants'
import { Message, QueryRequest } from '@/api/lightrag'
type Theme = 'dark' | 'light' | 'system'
type Language = 'en' | 'zh'
type Tab = 'documents' | 'knowledge-graph' | 'retrieval' | 'api'
type Language = 'en' | 'zh'
@@ -48,7 +49,7 @@ interface SettingsState {
setTheme: (theme: Theme) => void
language: Language
setLanguage: (language: Language) => void
setLanguage: (lang: Language) => void
enableHealthCheck: boolean
setEnableHealthCheck: (enable: boolean) => void
@@ -62,7 +63,6 @@ const useSettingsStoreBase = create<SettingsState>()(
(set) => ({
theme: 'system',
language: 'en',
showPropertyPanel: true,
showNodeSearchBar: true,
@@ -75,7 +75,7 @@ const useSettingsStoreBase = create<SettingsState>()(
graphQueryMaxDepth: 3,
graphMinDegree: 0,
graphLayoutMaxIterations: 10,
graphLayoutMaxIterations: 15,
queryLabel: defaultQueryLabel,
@@ -104,7 +104,15 @@ const useSettingsStoreBase = create<SettingsState>()(
setTheme: (theme: Theme) => set({ theme }),
setLanguage: (language: Language) => set({ language }),
setLanguage: (language: Language) => {
set({ language })
// Update i18n after state is updated
import('i18next').then(({ default: i18n }) => {
if (i18n.language !== language) {
i18n.changeLanguage(language)
}
})
},
setGraphLayoutMaxIterations: (iterations: number) =>
set({
@@ -136,7 +144,7 @@ const useSettingsStoreBase = create<SettingsState>()(
{
name: 'settings-storage',
storage: createJSONStorage(() => localStorage),
version: 7,
version: 8,
migrate: (state: any, version: number) => {
if (version < 2) {
state.showEdgeLabel = false
@@ -173,7 +181,11 @@ const useSettingsStoreBase = create<SettingsState>()(
}
if (version < 7) {
state.graphQueryMaxDepth = 3
state.graphLayoutMaxIterations = 10
state.graphLayoutMaxIterations = 15
}
if (version < 8) {
state.graphMinDegree = 0
state.language = 'en'
}
return state
}