yangdx commited on
Commit
2e179f3
·
1 Parent(s): 9bf536e

Fix linting

Browse files
lightrag/api/webui/assets/{index-DbL6qA5M.js → index-CKDgttI2.js} RENAMED
Binary files a/lightrag/api/webui/assets/index-DbL6qA5M.js and b/lightrag/api/webui/assets/index-CKDgttI2.js differ
 
lightrag/api/webui/assets/index-CRQxBxm4.css DELETED
Binary file (48.3 kB)
 
lightrag/api/webui/assets/index-ban2VJxS.css ADDED
Binary file (48.4 kB). View file
 
lightrag/api/webui/index.html CHANGED
Binary files a/lightrag/api/webui/index.html and b/lightrag/api/webui/index.html differ
 
lightrag_webui/src/components/graph/GraphLabels.tsx CHANGED
@@ -11,23 +11,23 @@ const GraphLabels = () => {
11
  const label = useSettingsStore.use.queryLabel()
12
  const allDatabaseLabels = useGraphStore.use.allDatabaseLabels()
13
  const labelsLoadedRef = useRef(false)
14
-
15
  // Track if a fetch is in progress to prevent multiple simultaneous fetches
16
  const fetchInProgressRef = useRef(false)
17
-
18
  // Fetch labels once on component mount, using global flag to prevent duplicates
19
  useEffect(() => {
20
  // Check if we've already attempted to fetch labels in this session
21
  const labelsFetchAttempted = useGraphStore.getState().labelsFetchAttempted
22
-
23
  // Only fetch if we haven't attempted in this session and no fetch is in progress
24
  if (!labelsFetchAttempted && !fetchInProgressRef.current) {
25
  fetchInProgressRef.current = true
26
  // Set global flag to indicate we've attempted to fetch in this session
27
  useGraphStore.getState().setLabelsFetchAttempted(true)
28
-
29
  console.log('Fetching graph labels (once per session)...')
30
-
31
  useGraphStore.getState().fetchAllDatabaseLabels()
32
  .then(() => {
33
  labelsLoadedRef.current = true
@@ -103,22 +103,22 @@ const GraphLabels = () => {
103
  if (newLabel === '...') {
104
  newLabel = '*'
105
  }
106
-
107
  // Reset the fetch attempted flag to force a new data fetch
108
  useGraphStore.getState().setGraphDataFetchAttempted(false)
109
-
110
  // Clear current graph data to ensure complete reload when label changes
111
  if (newLabel !== currentLabel) {
112
  const graphStore = useGraphStore.getState();
113
  graphStore.clearSelection();
114
-
115
  // Reset the graph state but preserve the instance
116
  if (graphStore.sigmaGraph) {
117
  const nodes = Array.from(graphStore.sigmaGraph.nodes());
118
  nodes.forEach(node => graphStore.sigmaGraph?.dropNode(node));
119
  }
120
  }
121
-
122
  if (newLabel === currentLabel && newLabel !== '*') {
123
  // 选择相同标签时切换到'*'
124
  useSettingsStore.getState().setQueryLabel('*')
 
11
  const label = useSettingsStore.use.queryLabel()
12
  const allDatabaseLabels = useGraphStore.use.allDatabaseLabels()
13
  const labelsLoadedRef = useRef(false)
14
+
15
  // Track if a fetch is in progress to prevent multiple simultaneous fetches
16
  const fetchInProgressRef = useRef(false)
17
+
18
  // Fetch labels once on component mount, using global flag to prevent duplicates
19
  useEffect(() => {
20
  // Check if we've already attempted to fetch labels in this session
21
  const labelsFetchAttempted = useGraphStore.getState().labelsFetchAttempted
22
+
23
  // Only fetch if we haven't attempted in this session and no fetch is in progress
24
  if (!labelsFetchAttempted && !fetchInProgressRef.current) {
25
  fetchInProgressRef.current = true
26
  // Set global flag to indicate we've attempted to fetch in this session
27
  useGraphStore.getState().setLabelsFetchAttempted(true)
28
+
29
  console.log('Fetching graph labels (once per session)...')
30
+
31
  useGraphStore.getState().fetchAllDatabaseLabels()
32
  .then(() => {
33
  labelsLoadedRef.current = true
 
103
  if (newLabel === '...') {
104
  newLabel = '*'
105
  }
106
+
107
  // Reset the fetch attempted flag to force a new data fetch
108
  useGraphStore.getState().setGraphDataFetchAttempted(false)
109
+
110
  // Clear current graph data to ensure complete reload when label changes
111
  if (newLabel !== currentLabel) {
112
  const graphStore = useGraphStore.getState();
113
  graphStore.clearSelection();
114
+
115
  // Reset the graph state but preserve the instance
116
  if (graphStore.sigmaGraph) {
117
  const nodes = Array.from(graphStore.sigmaGraph.nodes());
118
  nodes.forEach(node => graphStore.sigmaGraph?.dropNode(node));
119
  }
120
  }
121
+
122
  if (newLabel === currentLabel && newLabel !== '*') {
123
  // 选择相同标签时切换到'*'
124
  useSettingsStore.getState().setQueryLabel('*')
lightrag_webui/src/components/ui/TabContent.tsx CHANGED
@@ -18,7 +18,7 @@ const TabContent: React.FC<TabContentProps> = ({ tabId, children, className = ''
18
  // Register this tab with the context when mounted
19
  useEffect(() => {
20
  setTabVisibility(tabId, true);
21
-
22
  // Cleanup when unmounted
23
  return () => {
24
  setTabVisibility(tabId, false);
 
18
  // Register this tab with the context when mounted
19
  useEffect(() => {
20
  setTabVisibility(tabId, true);
21
+
22
  // Cleanup when unmounted
23
  return () => {
24
  setTabVisibility(tabId, false);
lightrag_webui/src/contexts/TabVisibilityProvider.tsx CHANGED
@@ -14,7 +14,7 @@ interface TabVisibilityProviderProps {
14
  export const TabVisibilityProvider: React.FC<TabVisibilityProviderProps> = ({ children }) => {
15
  // Get current tab from settings store
16
  const currentTab = useSettingsStore.use.currentTab();
17
-
18
  // Initialize visibility state with current tab as visible
19
  const [visibleTabs, setVisibleTabs] = useState<Record<string, boolean>>(() => ({
20
  [currentTab]: true
 
14
  export const TabVisibilityProvider: React.FC<TabVisibilityProviderProps> = ({ children }) => {
15
  // Get current tab from settings store
16
  const currentTab = useSettingsStore.use.currentTab();
17
+
18
  // Initialize visibility state with current tab as visible
19
  const [visibleTabs, setVisibleTabs] = useState<Record<string, boolean>>(() => ({
20
  [currentTab]: true
lightrag_webui/src/contexts/useTabVisibility.ts CHANGED
@@ -8,10 +8,10 @@ import { TabVisibilityContextType } from './types';
8
  */
9
  export const useTabVisibility = (): TabVisibilityContextType => {
10
  const context = useContext(TabVisibilityContext);
11
-
12
  if (!context) {
13
  throw new Error('useTabVisibility must be used within a TabVisibilityProvider');
14
  }
15
-
16
  return context;
17
  };
 
8
  */
9
  export const useTabVisibility = (): TabVisibilityContextType => {
10
  const context = useContext(TabVisibilityContext);
11
+
12
  if (!context) {
13
  throw new Error('useTabVisibility must be used within a TabVisibilityProvider');
14
  }
15
+
16
  return context;
17
  };
lightrag_webui/src/features/ApiSite.tsx CHANGED
@@ -8,20 +8,20 @@ export default function ApiSite() {
8
  const { isTabVisible } = useTabVisibility()
9
  const isApiTabVisible = isTabVisible('api')
10
  const [iframeLoaded, setIframeLoaded] = useState(false)
11
-
12
  // Load the iframe once on component mount
13
  useEffect(() => {
14
  if (!iframeLoaded) {
15
  setIframeLoaded(true)
16
  }
17
  }, [iframeLoaded])
18
-
19
  // Use CSS to hide content when tab is not visible
20
  return (
21
  <div className={`size-full ${isApiTabVisible ? '' : 'hidden'}`}>
22
  {iframeLoaded ? (
23
- <iframe
24
- src={backendBaseUrl + '/docs'}
25
  className="size-full w-full h-full"
26
  style={{ width: '100%', height: '100%', border: 'none' }}
27
  // Use key to ensure iframe doesn't reload
 
8
  const { isTabVisible } = useTabVisibility()
9
  const isApiTabVisible = isTabVisible('api')
10
  const [iframeLoaded, setIframeLoaded] = useState(false)
11
+
12
  // Load the iframe once on component mount
13
  useEffect(() => {
14
  if (!iframeLoaded) {
15
  setIframeLoaded(true)
16
  }
17
  }, [iframeLoaded])
18
+
19
  // Use CSS to hide content when tab is not visible
20
  return (
21
  <div className={`size-full ${isApiTabVisible ? '' : 'hidden'}`}>
22
  {iframeLoaded ? (
23
+ <iframe
24
+ src={backendBaseUrl + '/docs'}
25
  className="size-full w-full h-full"
26
  style={{ width: '100%', height: '100%', border: 'none' }}
27
  // Use key to ensure iframe doesn't reload
lightrag_webui/src/features/DocumentManager.tsx CHANGED
@@ -76,7 +76,7 @@ export default function DocumentManager() {
76
  if (!isDocumentsTabVisible || !health) {
77
  return
78
  }
79
-
80
  const interval = setInterval(async () => {
81
  try {
82
  await fetchDocuments()
@@ -84,7 +84,7 @@ export default function DocumentManager() {
84
  toast.error(t('documentPanel.documentManager.errors.scanProgressFailed', { error: errorMessage(err) }))
85
  }
86
  }, 5000)
87
-
88
  return () => clearInterval(interval)
89
  }, [health, fetchDocuments, t, isDocumentsTabVisible])
90
 
 
76
  if (!isDocumentsTabVisible || !health) {
77
  return
78
  }
79
+
80
  const interval = setInterval(async () => {
81
  try {
82
  await fetchDocuments()
 
84
  toast.error(t('documentPanel.documentManager.errors.scanProgressFailed', { error: errorMessage(err) }))
85
  }
86
  }, 5000)
87
+
88
  return () => clearInterval(interval)
89
  }, [health, fetchDocuments, t, isDocumentsTabVisible])
90
 
lightrag_webui/src/features/GraphViewer.tsx CHANGED
@@ -115,7 +115,7 @@ const GraphViewer = () => {
115
  const moveToSelectedNode = useGraphStore.use.moveToSelectedNode()
116
  const isFetching = useGraphStore.use.isFetching()
117
  const shouldRender = useGraphStore.use.shouldRender() // Rendering control state
118
-
119
  // Get tab visibility
120
  const { isTabVisible } = useTabVisibility()
121
  const isGraphTabVisible = isTabVisible('knowledge-graph')
@@ -137,7 +137,7 @@ const GraphViewer = () => {
137
  initAttemptedRef.current = true
138
  console.log('Graph viewer initialized')
139
  }
140
-
141
  // Cleanup function when component unmounts
142
  return () => {
143
  // Only log cleanup, don't actually clean up the WebGL context
 
115
  const moveToSelectedNode = useGraphStore.use.moveToSelectedNode()
116
  const isFetching = useGraphStore.use.isFetching()
117
  const shouldRender = useGraphStore.use.shouldRender() // Rendering control state
118
+
119
  // Get tab visibility
120
  const { isTabVisible } = useTabVisibility()
121
  const isGraphTabVisible = isTabVisible('knowledge-graph')
 
137
  initAttemptedRef.current = true
138
  console.log('Graph viewer initialized')
139
  }
140
+
141
  // Cleanup function when component unmounts
142
  return () => {
143
  // Only log cleanup, don't actually clean up the WebGL context
lightrag_webui/src/hooks/useLightragGraph.tsx CHANGED
@@ -148,7 +148,7 @@ const createSigmaGraph = (rawGraph: RawGraph | null) => {
148
  seedrandom(rawNode.id + Date.now().toString(), { global: true })
149
  const x = Math.random()
150
  const y = Math.random()
151
-
152
  graph.addNode(rawNode.id, {
153
  label: rawNode.labels.join(', '),
154
  color: rawNode.color,
@@ -178,20 +178,20 @@ const useLightrangeGraph = () => {
178
  const maxQueryDepth = useSettingsStore.use.graphQueryMaxDepth()
179
  const minDegree = useSettingsStore.use.graphMinDegree()
180
  const isFetching = useGraphStore.use.isFetching()
181
-
182
  // Get tab visibility
183
  const { isTabVisible } = useTabVisibility()
184
  const isGraphTabVisible = isTabVisible('knowledge-graph')
185
-
186
  // Track previous parameters to detect actual changes
187
  const prevParamsRef = useRef({ queryLabel, maxQueryDepth, minDegree })
188
-
189
  // Use ref to track if data has been loaded and initial load
190
  const dataLoadedRef = useRef(false)
191
  const initialLoadRef = useRef(false)
192
-
193
  // Check if parameters have changed
194
- const paramsChanged =
195
  prevParamsRef.current.queryLabel !== queryLabel ||
196
  prevParamsRef.current.maxQueryDepth !== maxQueryDepth ||
197
  prevParamsRef.current.minDegree !== minDegree
@@ -212,14 +212,14 @@ const useLightrangeGraph = () => {
212
 
213
  // Track if a fetch is in progress to prevent multiple simultaneous fetches
214
  const fetchInProgressRef = useRef(false)
215
-
216
  // Data fetching logic - simplified but preserving TAB visibility check
217
  useEffect(() => {
218
  // Skip if fetch is already in progress
219
  if (fetchInProgressRef.current) {
220
  return
221
  }
222
-
223
  // If there's no query label, reset the graph
224
  if (!queryLabel) {
225
  if (rawGraph !== null || sigmaGraph !== null) {
@@ -233,25 +233,25 @@ const useLightrangeGraph = () => {
233
  initialLoadRef.current = false
234
  return
235
  }
236
-
237
  // Check if parameters have changed
238
- if (!isFetching && !fetchInProgressRef.current &&
239
  (paramsChanged || !useGraphStore.getState().graphDataFetchAttempted)) {
240
-
241
  // Only fetch data if the Graph tab is visible
242
  if (!isGraphTabVisible) {
243
  console.log('Graph tab not visible, skipping data fetch');
244
  return;
245
  }
246
-
247
  // Set flags
248
  fetchInProgressRef.current = true
249
  useGraphStore.getState().setGraphDataFetchAttempted(true)
250
-
251
  const state = useGraphStore.getState()
252
  state.setIsFetching(true)
253
  state.setShouldRender(false) // Disable rendering during data loading
254
-
255
  // Clear selection and highlighted nodes before fetching new graph
256
  state.clearSelection()
257
  if (state.sigmaGraph) {
@@ -259,32 +259,32 @@ const useLightrangeGraph = () => {
259
  state.sigmaGraph?.setNodeAttribute(node, 'highlighted', false)
260
  })
261
  }
262
-
263
  // Update parameter reference
264
  prevParamsRef.current = { queryLabel, maxQueryDepth, minDegree }
265
-
266
  console.log('Fetching graph data...')
267
-
268
  // Use a local copy of the parameters
269
  const currentQueryLabel = queryLabel
270
  const currentMaxQueryDepth = maxQueryDepth
271
  const currentMinDegree = minDegree
272
-
273
  // Fetch graph data
274
  fetchGraph(currentQueryLabel, currentMaxQueryDepth, currentMinDegree).then((data) => {
275
  const state = useGraphStore.getState()
276
-
277
  // Reset state
278
  state.reset()
279
-
280
  // Create and set new graph directly
281
  const newSigmaGraph = createSigmaGraph(data)
282
  data?.buildDynamicMap()
283
-
284
  // Set new graph data
285
  state.setSigmaGraph(newSigmaGraph)
286
  state.setRawGraph(data)
287
-
288
  // Extract labels from current graph data
289
  if (data) {
290
  const labelSet = new Set<string>()
@@ -303,21 +303,21 @@ const useLightrangeGraph = () => {
303
  } else {
304
  state.setGraphLabels(['*'])
305
  }
306
-
307
  // Update flags
308
  dataLoadedRef.current = true
309
  initialLoadRef.current = true
310
  fetchInProgressRef.current = false
311
-
312
  // Reset camera view
313
  state.setMoveToSelectedNode(true)
314
-
315
  // Enable rendering if the tab is visible
316
  state.setShouldRender(isGraphTabVisible)
317
  state.setIsFetching(false)
318
  }).catch((error) => {
319
  console.error('Error fetching graph data:', error)
320
-
321
  // Reset state on error
322
  const state = useGraphStore.getState()
323
  state.setIsFetching(false)
@@ -328,7 +328,7 @@ const useLightrangeGraph = () => {
328
  })
329
  }
330
  }, [queryLabel, maxQueryDepth, minDegree, isFetching, paramsChanged, isGraphTabVisible, rawGraph, sigmaGraph])
331
-
332
  // Update rendering state and handle tab visibility changes
333
  useEffect(() => {
334
  // When tab becomes visible
@@ -337,7 +337,7 @@ const useLightrangeGraph = () => {
337
  if (rawGraph) {
338
  useGraphStore.getState().setShouldRender(true)
339
  }
340
-
341
  // We no longer reset the fetch attempted flag here to prevent continuous API calls
342
  } else {
343
  // When tab becomes invisible, disable rendering
@@ -350,7 +350,7 @@ const useLightrangeGraph = () => {
350
  if (sigmaGraph) {
351
  return sigmaGraph as Graph<NodeType, EdgeType>
352
  }
353
-
354
  // If no graph exists yet, create a new one and store it
355
  console.log('Creating new Sigma graph instance')
356
  const graph = new DirectedGraph()
 
148
  seedrandom(rawNode.id + Date.now().toString(), { global: true })
149
  const x = Math.random()
150
  const y = Math.random()
151
+
152
  graph.addNode(rawNode.id, {
153
  label: rawNode.labels.join(', '),
154
  color: rawNode.color,
 
178
  const maxQueryDepth = useSettingsStore.use.graphQueryMaxDepth()
179
  const minDegree = useSettingsStore.use.graphMinDegree()
180
  const isFetching = useGraphStore.use.isFetching()
181
+
182
  // Get tab visibility
183
  const { isTabVisible } = useTabVisibility()
184
  const isGraphTabVisible = isTabVisible('knowledge-graph')
185
+
186
  // Track previous parameters to detect actual changes
187
  const prevParamsRef = useRef({ queryLabel, maxQueryDepth, minDegree })
188
+
189
  // Use ref to track if data has been loaded and initial load
190
  const dataLoadedRef = useRef(false)
191
  const initialLoadRef = useRef(false)
192
+
193
  // Check if parameters have changed
194
+ const paramsChanged =
195
  prevParamsRef.current.queryLabel !== queryLabel ||
196
  prevParamsRef.current.maxQueryDepth !== maxQueryDepth ||
197
  prevParamsRef.current.minDegree !== minDegree
 
212
 
213
  // Track if a fetch is in progress to prevent multiple simultaneous fetches
214
  const fetchInProgressRef = useRef(false)
215
+
216
  // Data fetching logic - simplified but preserving TAB visibility check
217
  useEffect(() => {
218
  // Skip if fetch is already in progress
219
  if (fetchInProgressRef.current) {
220
  return
221
  }
222
+
223
  // If there's no query label, reset the graph
224
  if (!queryLabel) {
225
  if (rawGraph !== null || sigmaGraph !== null) {
 
233
  initialLoadRef.current = false
234
  return
235
  }
236
+
237
  // Check if parameters have changed
238
+ if (!isFetching && !fetchInProgressRef.current &&
239
  (paramsChanged || !useGraphStore.getState().graphDataFetchAttempted)) {
240
+
241
  // Only fetch data if the Graph tab is visible
242
  if (!isGraphTabVisible) {
243
  console.log('Graph tab not visible, skipping data fetch');
244
  return;
245
  }
246
+
247
  // Set flags
248
  fetchInProgressRef.current = true
249
  useGraphStore.getState().setGraphDataFetchAttempted(true)
250
+
251
  const state = useGraphStore.getState()
252
  state.setIsFetching(true)
253
  state.setShouldRender(false) // Disable rendering during data loading
254
+
255
  // Clear selection and highlighted nodes before fetching new graph
256
  state.clearSelection()
257
  if (state.sigmaGraph) {
 
259
  state.sigmaGraph?.setNodeAttribute(node, 'highlighted', false)
260
  })
261
  }
262
+
263
  // Update parameter reference
264
  prevParamsRef.current = { queryLabel, maxQueryDepth, minDegree }
265
+
266
  console.log('Fetching graph data...')
267
+
268
  // Use a local copy of the parameters
269
  const currentQueryLabel = queryLabel
270
  const currentMaxQueryDepth = maxQueryDepth
271
  const currentMinDegree = minDegree
272
+
273
  // Fetch graph data
274
  fetchGraph(currentQueryLabel, currentMaxQueryDepth, currentMinDegree).then((data) => {
275
  const state = useGraphStore.getState()
276
+
277
  // Reset state
278
  state.reset()
279
+
280
  // Create and set new graph directly
281
  const newSigmaGraph = createSigmaGraph(data)
282
  data?.buildDynamicMap()
283
+
284
  // Set new graph data
285
  state.setSigmaGraph(newSigmaGraph)
286
  state.setRawGraph(data)
287
+
288
  // Extract labels from current graph data
289
  if (data) {
290
  const labelSet = new Set<string>()
 
303
  } else {
304
  state.setGraphLabels(['*'])
305
  }
306
+
307
  // Update flags
308
  dataLoadedRef.current = true
309
  initialLoadRef.current = true
310
  fetchInProgressRef.current = false
311
+
312
  // Reset camera view
313
  state.setMoveToSelectedNode(true)
314
+
315
  // Enable rendering if the tab is visible
316
  state.setShouldRender(isGraphTabVisible)
317
  state.setIsFetching(false)
318
  }).catch((error) => {
319
  console.error('Error fetching graph data:', error)
320
+
321
  // Reset state on error
322
  const state = useGraphStore.getState()
323
  state.setIsFetching(false)
 
328
  })
329
  }
330
  }, [queryLabel, maxQueryDepth, minDegree, isFetching, paramsChanged, isGraphTabVisible, rawGraph, sigmaGraph])
331
+
332
  // Update rendering state and handle tab visibility changes
333
  useEffect(() => {
334
  // When tab becomes visible
 
337
  if (rawGraph) {
338
  useGraphStore.getState().setShouldRender(true)
339
  }
340
+
341
  // We no longer reset the fetch attempted flag here to prevent continuous API calls
342
  } else {
343
  // When tab becomes invisible, disable rendering
 
350
  if (sigmaGraph) {
351
  return sigmaGraph as Graph<NodeType, EdgeType>
352
  }
353
+
354
  // If no graph exists yet, create a new one and store it
355
  console.log('Creating new Sigma graph instance')
356
  const graph = new DirectedGraph()
lightrag_webui/src/stores/graph.ts CHANGED
@@ -72,7 +72,7 @@ interface GraphState {
72
  moveToSelectedNode: boolean
73
  isFetching: boolean
74
  shouldRender: boolean
75
-
76
  // Global flags to track data fetching attempts
77
  graphDataFetchAttempted: boolean
78
  labelsFetchAttempted: boolean
@@ -94,7 +94,7 @@ interface GraphState {
94
  fetchAllDatabaseLabels: () => Promise<void>
95
  setIsFetching: (isFetching: boolean) => void
96
  setShouldRender: (shouldRender: boolean) => void
97
-
98
  // Methods to set global flags
99
  setGraphDataFetchAttempted: (attempted: boolean) => void
100
  setLabelsFetchAttempted: (attempted: boolean) => void
@@ -109,7 +109,7 @@ const useGraphStoreBase = create<GraphState>()((set, get) => ({
109
  moveToSelectedNode: false,
110
  isFetching: false,
111
  shouldRender: false,
112
-
113
  // Initialize global flags
114
  graphDataFetchAttempted: false,
115
  labelsFetchAttempted: false,
@@ -147,13 +147,13 @@ const useGraphStoreBase = create<GraphState>()((set, get) => ({
147
  reset: () => {
148
  // Get the existing graph
149
  const existingGraph = get().sigmaGraph;
150
-
151
  // If we have an existing graph, clear it by removing all nodes
152
  if (existingGraph) {
153
  const nodes = Array.from(existingGraph.nodes());
154
  nodes.forEach(node => existingGraph.dropNode(node));
155
  }
156
-
157
  set({
158
  selectedNode: null,
159
  focusedNode: null,
@@ -195,7 +195,7 @@ const useGraphStoreBase = create<GraphState>()((set, get) => ({
195
  },
196
 
197
  setMoveToSelectedNode: (moveToSelectedNode?: boolean) => set({ moveToSelectedNode }),
198
-
199
  // Methods to set global flags
200
  setGraphDataFetchAttempted: (attempted: boolean) => set({ graphDataFetchAttempted: attempted }),
201
  setLabelsFetchAttempted: (attempted: boolean) => set({ labelsFetchAttempted: attempted })
 
72
  moveToSelectedNode: boolean
73
  isFetching: boolean
74
  shouldRender: boolean
75
+
76
  // Global flags to track data fetching attempts
77
  graphDataFetchAttempted: boolean
78
  labelsFetchAttempted: boolean
 
94
  fetchAllDatabaseLabels: () => Promise<void>
95
  setIsFetching: (isFetching: boolean) => void
96
  setShouldRender: (shouldRender: boolean) => void
97
+
98
  // Methods to set global flags
99
  setGraphDataFetchAttempted: (attempted: boolean) => void
100
  setLabelsFetchAttempted: (attempted: boolean) => void
 
109
  moveToSelectedNode: false,
110
  isFetching: false,
111
  shouldRender: false,
112
+
113
  // Initialize global flags
114
  graphDataFetchAttempted: false,
115
  labelsFetchAttempted: false,
 
147
  reset: () => {
148
  // Get the existing graph
149
  const existingGraph = get().sigmaGraph;
150
+
151
  // If we have an existing graph, clear it by removing all nodes
152
  if (existingGraph) {
153
  const nodes = Array.from(existingGraph.nodes());
154
  nodes.forEach(node => existingGraph.dropNode(node));
155
  }
156
+
157
  set({
158
  selectedNode: null,
159
  focusedNode: null,
 
195
  },
196
 
197
  setMoveToSelectedNode: (moveToSelectedNode?: boolean) => set({ moveToSelectedNode }),
198
+
199
  // Methods to set global flags
200
  setGraphDataFetchAttempted: (attempted: boolean) => set({ graphDataFetchAttempted: attempted }),
201
  setLabelsFetchAttempted: (attempted: boolean) => set({ labelsFetchAttempted: attempted })