11import {
2+ ILayoutRestorer ,
23 JupyterFrontEnd ,
34 JupyterFrontEndPlugin
45} from '@jupyterlab/application' ;
5- import { ICommandPalette } from '@jupyterlab/apputils' ;
6+ import {
7+ ICommandPalette ,
8+ WidgetTracker
9+ } from '@jupyterlab/apputils' ;
610import { ILauncher } from '@jupyterlab/launcher' ;
711import { imageIcon } from '@jupyterlab/ui-components' ;
812
@@ -17,12 +21,14 @@ const plugin: JupyterFrontEndPlugin<void> = {
1721 description : 'A JupyterLab extension that displays a random image and caption.' ,
1822 autoStart : true ,
1923 requires : [ ICommandPalette , ILauncher ] , // dependencies of our extension
24+ optional : [ ILayoutRestorer ] ,
2025 activate : (
2126 app : JupyterFrontEnd ,
2227 // The activation method receives dependencies in the order they are specified in
2328 // the "requires" parameter above:
2429 palette : ICommandPalette ,
25- launcher : ILauncher
30+ launcher : ILauncher ,
31+ restorer : ILayoutRestorer | null
2632 ) => {
2733 console . log ( 'JupyterLab extension jupytercon2025-extension-workshop is activated!' ) ;
2834
@@ -36,13 +42,31 @@ const plugin: JupyterFrontEndPlugin<void> = {
3642 ) ;
3743 } ) ;
3844
45+ // Track widget state
46+ const tracker_namespace = 'jupytercon2025-extension-workshop' ;
47+ const tracker = new WidgetTracker < ImageCaptionMainAreaWidget > ( {
48+ namespace : tracker_namespace
49+ } ) ;
50+
3951 //Register a new command:
4052 const command_id = 'image-caption:open' ;
4153 app . commands . addCommand ( command_id , {
42- execute : ( ) => {
54+ execute : ( args ?: { id ?: string } ) => {
4355 // When the command is executed, create a new instance of our widget
4456 const widget = new ImageCaptionMainAreaWidget ( ) ;
4557
58+ // Use provided ID or generate a new one
59+ // During restoration, the args will contain the saved widget ID
60+ if ( args && args . id ) {
61+ widget . id = args . id ;
62+ } else {
63+ widget . id = `image-caption-${ crypto . randomUUID ( ) } ` ;
64+ }
65+
66+ if ( ! tracker . has ( widget ) ) {
67+ tracker . add ( widget ) ;
68+ }
69+
4670 // Then add it to the main area:
4771 app . shell . add ( widget , 'main' ) ;
4872 return widget ;
@@ -53,6 +77,15 @@ const plugin: JupyterFrontEndPlugin<void> = {
5377
5478 palette . addItem ( { command : command_id , category : 'Tutorial' } ) ;
5579 launcher . add ( { command : command_id } ) ;
80+
81+ // Restore widget state
82+ if ( restorer ) {
83+ restorer . restore ( tracker , {
84+ command : command_id ,
85+ name : widget => widget . id ,
86+ args : widget => ( { id : widget . id } )
87+ } ) ;
88+ }
5689 }
5790} ;
5891
0 commit comments