Skip to content

Commit 4cc2336

Browse files
committed
add first solution to refreshing variables system
1 parent c1e38a5 commit 4cc2336

File tree

8 files changed

+301
-125
lines changed

8 files changed

+301
-125
lines changed

src/components/searchBar.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ export const SearchBar: React.FC = () => {
1414
type="text"
1515
value={searchTerm}
1616
onChange={handleChange}
17-
placeholder="Search Package..."
18-
className='search-bar-input'
17+
placeholder="Search Variable..."
18+
className='mljar-search-bar-input'
1919
/>
2020
</div>
2121
);

src/components/variableInspectorSidebar.tsx

Lines changed: 55 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,72 @@
1-
import React from 'react';
2-
import { ReactWidget } from '@jupyterlab/ui-components';
3-
import { pluginIcon } from '../icons/pluginIcon';
1+
// src/components/variableInspectorSidebarWidget.tsx
2+
import React from 'react'
3+
import { ReactWidget } from '@jupyterlab/ui-components'
4+
import { Message } from '@lumino/messaging'
5+
import { pluginIcon } from '../icons/pluginIcon'
46
import { NotebookWatcher } from '../watchers/notebookWatcher'
5-
import { NotebookPanelContextProvider } from '../context/notebookPanelContext';
6-
import { CommandRegistry } from '@lumino/commands';
7-
import { VariableListComponent } from './variableListComponent';
8-
import { NotebookKernelContextProvider } from '../context/notebookKernelContext';
9-
import { VariableContextProvider } from '../context/notebookVariableContext';
7+
import { CommandRegistry } from '@lumino/commands'
8+
import { NotebookPanelContextProvider } from '../context/notebookPanelContext'
9+
import { NotebookKernelContextProvider } from '../context/notebookKernelContext'
10+
import { VariableContextProvider } from '../context/notebookVariableContext'
11+
import { VariableListComponent } from './variableListComponent'
12+
import { PluginVisibilityContextValue, PluginVisibilityContext } from '../context/pluginVisibilityContext'
13+
import { KernelIdleWatcherContextProvider } from '../context/kernelStatusContext'
1014

15+
export class VariableInspectorSidebarWidget extends ReactWidget {
16+
private notebookWatcher: NotebookWatcher
17+
private commands: CommandRegistry
18+
private isOpen = false
1119

12-
class VariableInspectorSidebarWidget extends ReactWidget {
13-
private notebookWatcher: NotebookWatcher;
14-
private commands: CommandRegistry;
15-
constructor(notebookWatcher:NotebookWatcher, commands: CommandRegistry) {
16-
super();
17-
this.notebookWatcher = notebookWatcher;
18-
this.commands = commands;
19-
this.id = 'my-plugin::empty-sidebar';
20-
this.title.icon = pluginIcon;
21-
this.title.caption ='My Plugin';
22-
this.addClass('my-plugin-sidebar-widget');
20+
constructor(notebookWatcher: NotebookWatcher, commands: CommandRegistry) {
21+
super()
22+
this.notebookWatcher = notebookWatcher
23+
this.commands = commands
24+
this.id = 'my-plugin::empty-sidebar'
25+
this.title.icon = pluginIcon
26+
this.title.caption = 'My Plugin'
27+
this.addClass('mljar-plugin-sidebar-widget')
28+
}
29+
30+
protected onAfterShow(msg: Message): void {
31+
super.onAfterShow(msg)
32+
this.isOpen = true
33+
this.update()
34+
}
35+
36+
protected onAfterHide(msg: Message): void {
37+
super.onAfterHide(msg)
38+
this.isOpen = false
39+
this.update()
2340
}
2441

2542
render(): JSX.Element {
43+
const contextValue: PluginVisibilityContextValue = {
44+
isPluginOpen: this.isOpen,
45+
setPluginOpen: open => {
46+
this.isOpen = open
47+
this.update()
48+
}
49+
}
2650
return (
27-
<div
28-
className='mljar-sidebar-container'
29-
>
30-
51+
<PluginVisibilityContext.Provider value={contextValue}>
3152
<NotebookPanelContextProvider notebookWatcher={this.notebookWatcher}>
3253
<NotebookKernelContextProvider notebookWatcher={this.notebookWatcher}>
33-
<VariableContextProvider>
34-
<VariableListComponent/>
35-
<button
36-
onClick={() => this.commands.execute('custom:open-variable-inspector')}
37-
>
38-
Hello
39-
</button>
54+
<VariableContextProvider>
55+
<KernelIdleWatcherContextProvider>
56+
<VariableListComponent />
57+
58+
<button onClick={() => this.commands.execute('custom:open-variable-inspector')}>
59+
Hello
60+
</button>
61+
</KernelIdleWatcherContextProvider>
4062
</VariableContextProvider>
4163
</NotebookKernelContextProvider>
4264
</NotebookPanelContextProvider>
43-
</div>
44-
);
65+
</PluginVisibilityContext.Provider>
66+
)
4567
}
4668
}
4769

4870
export function createVariableInspectorSidebar(notebookWatcher: NotebookWatcher, commands: CommandRegistry): VariableInspectorSidebarWidget {
49-
return new VariableInspectorSidebarWidget(notebookWatcher, commands);
71+
return new VariableInspectorSidebarWidget(notebookWatcher, commands)
5072
}
51-
52-

src/components/variableItem.tsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,21 @@ interface VariableItemProps {
1111
}
1212

1313
export const VariableItem: React.FC<VariableItemProps> = ({ vrb }) => {
14-
const handleButtonClick = () => {
15-
console.log(`Variable clicked: ${vrb.name}`);
16-
};
1714

1815
return (
1916
<li className='mljar-variable-item'>
2017
<span className='mljar-variable-name'>{vrb.name}</span>
21-
<span className='mljar-variable-version'>{vrb.type}</span>
18+
<span className='mljar-variable-type'>{vrb.type}</span>
2219
<span className='mljar-variable-shape'>{vrb.shape}</span>
23-
<button
20+
{
21+
/* <button
2422
className='mljar-show-variable-button'
2523
onClick={handleButtonClick}
2624
aria-label={`Show details for ${vrb.name}`}
2725
>
2826
Show
29-
</button>
27+
</button> */
28+
}
3029
</li>
3130
);
3231
};

src/components/variableListComponent.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ export const VariableListComponent: React.FC = () => {
1010
<div className="mljar-variable-container">
1111
<div className="mljar-variable-header-container">
1212
<h3 className="mljar-variable-header">Variable Inspector</h3>
13-
<SearchBar />
14-
<VariableList/>
1513
</div>
14+
<div>
15+
<SearchBar />
16+
<VariableList/>
17+
</div>
1618
</div>
1719
);
1820
};
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import React, { createContext, useContext, useEffect, useRef, useState } from 'react'
2+
import { Kernel } from '@jupyterlab/services'
3+
import { useNotebookPanelContext } from './notebookPanelContext'
4+
import { useVariableContext } from './notebookVariableContext'
5+
6+
const KernelIdleWatcherContext = createContext({})
7+
8+
export const KernelIdleWatcherContextProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
9+
const notebookPanel = useNotebookPanelContext()
10+
const [kernelStatus, setKernelStatus] = useState<Kernel.Status>('unknown')
11+
const timerRef = useRef<number | null>(null)
12+
const [hasRefreshed, setHasRefreshed] = useState(false)
13+
const { refreshVariables, isRefreshing } = useVariableContext()
14+
15+
16+
17+
18+
useEffect(() => {
19+
if (!notebookPanel || !notebookPanel.sessionContext) return
20+
const kernel = notebookPanel.sessionContext?.session?.kernel
21+
if (!kernel) return
22+
const onKernelStatusChange = () => {
23+
setKernelStatus(kernel.status)
24+
}
25+
kernel.statusChanged.connect(onKernelStatusChange)
26+
return () => {
27+
kernel.statusChanged.disconnect(onKernelStatusChange)
28+
}
29+
}, [notebookPanel?.sessionContext?.session?.kernel])
30+
31+
32+
33+
// first idea to solve the problem, code might be unstable
34+
useEffect(() => {
35+
//clearing timeout
36+
if (isRefreshing) {
37+
if (timerRef.current) {
38+
clearTimeout(timerRef.current)
39+
timerRef.current = null
40+
}
41+
return
42+
}
43+
if (kernelStatus === 'idle') {
44+
if (!hasRefreshed) {
45+
timerRef.current = window.setTimeout(() => {
46+
if (
47+
notebookPanel &&
48+
notebookPanel.sessionContext?.session?.kernel?.status === 'idle' &&
49+
!isRefreshing
50+
) {
51+
refreshVariables()
52+
setHasRefreshed(true)
53+
}
54+
}, 2000)
55+
}
56+
} else {
57+
if (timerRef.current) {
58+
clearTimeout(timerRef.current)
59+
timerRef.current = null
60+
}
61+
if(!isRefreshing && notebookPanel){
62+
setHasRefreshed(false)
63+
}
64+
}
65+
//clearing timeout
66+
return () => {
67+
if (timerRef.current) {
68+
clearTimeout(timerRef.current)
69+
timerRef.current = null
70+
}
71+
}
72+
}, [kernelStatus,notebookPanel,refreshVariables, hasRefreshed])
73+
74+
return (
75+
<KernelIdleWatcherContext.Provider value={{ kernelStatus }}>
76+
{children}
77+
</KernelIdleWatcherContext.Provider>
78+
)
79+
}
80+
81+
export const useKernelIdleWatcherContext = () => useContext(KernelIdleWatcherContext)

0 commit comments

Comments
 (0)