@@ -4,32 +4,23 @@ import {
44 ILayoutRestorer ,
55 ILabShell ,
66} from "@jupyterlab/application" ;
7- import { ReadonlyPartialJSONObject } from "@lumino/coreutils" ;
7+ import { IToolbarWidgetRegistry } from "@jupyterlab/apputils" ;
8+
89import { ILauncher } from "@jupyterlab/launcher" ;
910import { PageConfig } from "@jupyterlab/coreutils" ;
1011import { IFrame , MainAreaWidget , WidgetTracker } from "@jupyterlab/apputils" ;
12+ import { IDefaultFileBrowser } from "@jupyterlab/filebrowser" ;
1113
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- }
14+ import {
15+ CommandIDs ,
16+ IOpenArgs ,
17+ IServerProcess ,
18+ IServersInfo ,
19+ NS ,
20+ argSchema ,
21+ } from "./tokens" ;
1922
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- } ;
23+ import type { Widget , Menu } from "@lumino/widgets" ;
3324
3425/** Create a new iframe widget. */
3526function newServerProxyWidget (
@@ -68,8 +59,15 @@ async function activate(
6859 labShell : ILabShell | null ,
6960 launcher : ILauncher | null ,
7061 restorer : ILayoutRestorer | null ,
62+ toolbarRegistry : IToolbarWidgetRegistry | null ,
63+ fileBrowser : IDefaultFileBrowser | null ,
7164) : Promise < void > {
7265 const baseUrl = PageConfig . getBaseUrl ( ) ;
66+ // determine whether we are in the Notebook 7 tree
67+ const notebookPage = PageConfig . getOption ( "notebookPage" ) ;
68+ const isNotebook7 = ! ! notebookPage ;
69+ const isTree = isNotebook7 && notebookPage === "tree" ;
70+
7371 // Fetch configured server processes from {base_url}/server-proxy/servers-info
7472 const response = await fetch ( `${ baseUrl } server-proxy/servers-info` ) ;
7573
@@ -81,15 +79,26 @@ async function activate(
8179 return ;
8280 }
8381
84- const data = await response . json ( ) ;
82+ function argsForServer ( server_process : IServerProcess ) : IOpenArgs {
83+ const { new_browser_tab, launcher_entry, name } = server_process ;
8584
86- const namespace = "server-proxy" ;
87- const tracker = new WidgetTracker < MainAreaWidget < IFrame > > ( { namespace } ) ;
88- const command = `${ namespace } :open` ;
85+ const suffix = new_browser_tab && ! isNotebook7 ? " [↗]" : "" ;
86+
87+ return {
88+ url : `${ baseUrl } ${ launcher_entry . path_info } ` ,
89+ title : `${ launcher_entry . title } ${ suffix } ` ,
90+ newBrowserTab : new_browser_tab ,
91+ id : `${ NS } :${ name } ` ,
92+ } ;
93+ }
94+
95+ const data : IServersInfo = await response . json ( ) ;
96+
97+ const tracker = new WidgetTracker < MainAreaWidget < IFrame > > ( { namespace : NS } ) ;
8998
9099 if ( restorer ) {
91100 void restorer . restore ( tracker , {
92- command : command ,
101+ command : CommandIDs . open ,
93102 args : ( widget ) => ( {
94103 url : widget . content . url ,
95104 title : widget . content . title . label ,
@@ -102,7 +111,7 @@ async function activate(
102111
103112 const { commands, shell } = app ;
104113
105- commands . addCommand ( command , {
114+ commands . addCommand ( CommandIDs . open , {
106115 label : ( args ) => ( args as IOpenArgs ) . title ,
107116 describedBy : async ( ) => {
108117 return { args : argSchema } ;
@@ -130,30 +139,42 @@ async function activate(
130139 } ) ;
131140
132141 if ( launcher ) {
133- const baseUrl = PageConfig . getBaseUrl ( ) ;
134142 for ( let server_process of data . server_processes ) {
135- const { new_browser_tab , launcher_entry, name } = server_process ;
143+ const { launcher_entry } = server_process ;
136144
137145 if ( ! launcher_entry . enabled ) {
138146 continue ;
139147 }
140148
141149 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- } ,
150+ command : CommandIDs . open ,
151+ args : argsForServer ( server_process ) ,
149152 category : "Notebook" ,
150153 kernelIconUrl : launcher_entry . icon_url || void 0 ,
151154 } ) ;
152155 }
153156 }
154157
155- if ( ! labShell ) {
156- console . warn ( "TODO: handle notebook 7" ) ;
158+ if ( isTree && ! labShell && toolbarRegistry && fileBrowser ) {
159+ const { toolbar } = fileBrowser ;
160+ const widgets = ( ( toolbar . layout || { } ) as any ) . widgets as Widget [ ] ;
161+ if ( widgets && widgets . length ) {
162+ for ( const widget of widgets ) {
163+ if ( widget && ( widget as any ) . menus ) {
164+ const menu : Menu = ( widget as any ) . menus [ 0 ] ;
165+ console . warn ( menu ) ;
166+ menu . addItem ( { type : "separator" } ) ;
167+ for ( const server_process of data . server_processes ) {
168+ // create args, overriding all to launch in new heavyweight browser tabs
169+ let args = {
170+ ...argsForServer ( server_process ) ,
171+ newBrowserTab : true ,
172+ } ;
173+ menu . addItem ( { command : CommandIDs . open , args } ) ;
174+ }
175+ }
176+ }
177+ }
157178 }
158179}
159180
@@ -166,8 +187,14 @@ async function activate(
166187const extension : JupyterFrontEndPlugin < void > = {
167188 id : "@jupyterhub/jupyter-server-proxy:add-launcher-entries" ,
168189 autoStart : true ,
169- optional : [ ILabShell , ILauncher , ILayoutRestorer ] ,
170- activate : activate ,
190+ optional : [
191+ ILabShell ,
192+ ILauncher ,
193+ ILayoutRestorer ,
194+ IToolbarWidgetRegistry ,
195+ IDefaultFileBrowser ,
196+ ] ,
197+ activate,
171198} ;
172199
173200export default extension ;
0 commit comments