@@ -2,15 +2,40 @@ import {
22 JupyterFrontEnd ,
33 JupyterFrontEndPlugin ,
44 ILayoutRestorer ,
5+ ILabShell ,
56} from "@jupyterlab/application" ;
7+ import { ReadonlyPartialJSONObject } from "@lumino/coreutils" ;
68import { ILauncher } from "@jupyterlab/launcher" ;
79import { PageConfig } from "@jupyterlab/coreutils" ;
810import { IFrame , MainAreaWidget , WidgetTracker } from "@jupyterlab/apputils" ;
911
12+ /** An interface for the arguments to the open command. */
13+ export interface IOpenArgs extends ReadonlyPartialJSONObject {
14+ id : string ;
15+ title : string ;
16+ url : string ;
17+ newBrowserTab : boolean ;
18+ }
19+
20+ /** The JSON schema for the open command arguments.
21+ *
22+ * https://lumino.readthedocs.io/en/latest/api/interfaces/commands.CommandRegistry.ICommandOptions.html
23+ */
24+ export const argSchema = {
25+ type : "object" ,
26+ properties : {
27+ id : { type : "string" } ,
28+ title : { type : "string" } ,
29+ url : { type : "string" , format : "uri" } ,
30+ newBrowserTab : { type : "boolean" } ,
31+ } ,
32+ } ;
33+
34+ /** Create a new iframe widget. */
1035function newServerProxyWidget (
1136 id : string ,
1237 url : string ,
13- text : string ,
38+ text : string
1439) : MainAreaWidget < IFrame > {
1540 const content = new IFrame ( {
1641 sandbox : [
@@ -40,27 +65,27 @@ function newServerProxyWidget(
4065 */
4166async function activate (
4267 app : JupyterFrontEnd ,
43- launcher : ILauncher ,
44- restorer : ILayoutRestorer ,
68+ labShell : ILabShell | null ,
69+ launcher : ILauncher | null ,
70+ restorer : ILayoutRestorer | null
4571) : Promise < void > {
72+ const baseUrl = PageConfig . getBaseUrl ( ) ;
4673 // Fetch configured server processes from {base_url}/server-proxy/servers-info
47- const response = await fetch (
48- PageConfig . getBaseUrl ( ) + "server-proxy/servers-info" ,
49- ) ;
74+ const response = await fetch ( `${ baseUrl } server-proxy/servers-info` ) ;
75+
5076 if ( ! response . ok ) {
51- console . log (
52- "Could not fetch metadata about registered servers. Make sure jupyter-server-proxy is installed." ,
77+ console . warn (
78+ "Could not fetch metadata about registered servers. Make sure jupyter-server-proxy is installed."
5379 ) ;
54- console . log ( response ) ;
80+ console . warn ( response ) ;
5581 return ;
5682 }
83+
5784 const data = await response . json ( ) ;
5885
5986 const namespace = "server-proxy" ;
60- const tracker = new WidgetTracker < MainAreaWidget < IFrame > > ( {
61- namespace,
62- } ) ;
63- const command = namespace + ":" + "open" ;
87+ const tracker = new WidgetTracker < MainAreaWidget < IFrame > > ( { namespace } ) ;
88+ const command = `${ namespace } :open` ;
6489
6590 if ( restorer ) {
6691 void restorer . restore ( tracker , {
@@ -76,20 +101,19 @@ async function activate(
76101 }
77102
78103 const { commands, shell } = app ;
104+
79105 commands . addCommand ( command , {
80- label : ( args ) => args [ "title" ] as string ,
106+ label : ( args ) => ( args as IOpenArgs ) . title ,
107+ describedBy : async ( ) => {
108+ return { args : argSchema } ;
109+ } ,
81110 execute : ( args ) => {
82- const id = args [ "id" ] as string ;
83- const title = args [ "title" ] as string ;
84- const url = args [ "url" ] as string ;
85- const newBrowserTab = args [ "newBrowserTab" ] as boolean ;
111+ const { id, title, url, newBrowserTab } = args as IOpenArgs ;
86112 if ( newBrowserTab ) {
87113 window . open ( url , "_blank" ) ;
88114 return ;
89115 }
90- let widget = tracker . find ( ( widget ) => {
91- return widget . content . id == id ;
92- } ) ;
116+ let widget = tracker . find ( ( widget ) => widget . content . id === id ) ;
93117 if ( ! widget ) {
94118 widget = newServerProxyWidget ( id , url , title ) ;
95119 }
@@ -98,38 +122,38 @@ async function activate(
98122 }
99123 if ( ! widget . isAttached ) {
100124 shell . add ( widget ) ;
101- return widget ;
102125 } else {
103126 shell . activateById ( widget . id ) ;
104127 }
128+ return widget ;
105129 } ,
106130 } ) ;
107131
108- for ( let server_process of data . server_processes ) {
109- if ( ! server_process . launcher_entry . enabled ) {
110- continue ;
111- }
132+ if ( launcher ) {
133+ const baseUrl = PageConfig . getBaseUrl ( ) ;
134+ for ( let server_process of data . server_processes ) {
135+ const { new_browser_tab , launcher_entry , name } = server_process ;
112136
113- const url =
114- PageConfig . getBaseUrl ( ) + server_process . launcher_entry . path_info ;
115- const title = server_process . launcher_entry . title ;
116- const newBrowserTab = server_process . new_browser_tab ;
117- const id = namespace + ":" + server_process . name ;
118- const launcher_item : ILauncher . IItemOptions = {
119- command : command ,
120- args : {
121- url : url ,
122- title : title + ( newBrowserTab ? " [↗]" : "" ) ,
123- newBrowserTab : newBrowserTab ,
124- id : id ,
125- } ,
126- category : "Notebook" ,
127- } ;
128-
129- if ( server_process . launcher_entry . icon_url ) {
130- launcher_item . kernelIconUrl = server_process . launcher_entry . icon_url ;
137+ if ( ! launcher_entry . enabled ) {
138+ continue ;
139+ }
140+
141+ launcher . add ( {
142+ command : command ,
143+ args : {
144+ url : `${ baseUrl } ${ launcher_entry . path_info } ` ,
145+ title : launcher_entry . title + ( new_browser_tab ? " [↗]" : "" ) ,
146+ newBrowserTab : new_browser_tab ,
147+ id : `${ namespace } :${ name } ` ,
148+ } ,
149+ category : "Notebook" ,
150+ kernelIconUrl : launcher_entry . icon_url || void 0 ,
151+ } ) ;
131152 }
132- launcher . add ( launcher_item ) ;
153+ }
154+
155+ if ( ! labShell ) {
156+ console . warn ( "TODO: handle notebook 7" ) ;
133157 }
134158}
135159
@@ -142,7 +166,7 @@ async function activate(
142166const extension : JupyterFrontEndPlugin < void > = {
143167 id : "@jupyterhub/jupyter-server-proxy:add-launcher-entries" ,
144168 autoStart : true ,
145- requires : [ ILauncher , ILayoutRestorer ] ,
169+ optional : [ ILabShell , ILauncher , ILayoutRestorer ] ,
146170 activate : activate ,
147171} ;
148172
0 commit comments