@@ -14,11 +14,14 @@ import { ITranslator } from '@jupyterlab/translation';
14
14
import {
15
15
createToolbarFactory ,
16
16
IToolbarWidgetRegistry ,
17
- setToolbar
17
+ setToolbar ,
18
+ showDialog ,
19
+ Dialog
18
20
} from '@jupyterlab/apputils' ;
19
21
import { ISettingRegistry } from '@jupyterlab/settingregistry' ;
20
22
import { FilenameSearcher , IScore } from '@jupyterlab/ui-components' ;
21
23
import { CommandRegistry } from '@lumino/commands' ;
24
+ import { Widget } from '@lumino/widgets' ;
22
25
23
26
import { driveBrowserIcon } from '../icons' ;
24
27
import { Drive } from '../contents' ;
@@ -35,6 +38,16 @@ const FILE_BROWSER_FACTORY = 'DriveBrowser';
35
38
*/
36
39
const FILTERBOX_CLASS = 'jp-drive-browser-search-box' ;
37
40
41
+ /**
42
+ * The class name added to dialogs.
43
+ */
44
+ const FILE_DIALOG_CLASS = 'jp-FileDialog' ;
45
+
46
+ /**
47
+ * The class name added for the new drive label in the creating new drive dialog.
48
+ */
49
+ const CREATE_DRIVE_TITLE_CLASS = 'jp-new-drive-title' ;
50
+
38
51
/**
39
52
* The drives list provider.
40
53
*/
@@ -184,6 +197,9 @@ export const driveFileBrowser: JupyterFrontEndPlugin<void> = {
184
197
185
198
// Listen for your plugin setting changes using Signal
186
199
setting . changed . connect ( loadSetting ) ;
200
+
201
+ // Add commands
202
+ Private . addCommands ( app , drive ) ;
187
203
} )
188
204
. catch ( reason => {
189
205
console . error (
@@ -246,4 +262,101 @@ namespace Private {
246
262
} ;
247
263
router . routed . connect ( listener ) ;
248
264
}
265
+
266
+ /**
267
+ * Create the node for a creating a new drive handler.
268
+ */
269
+ const createNewDriveNode = ( newDriveName : string ) : HTMLElement => {
270
+ const body = document . createElement ( 'div' ) ;
271
+
272
+ const drive = document . createElement ( 'label' ) ;
273
+ drive . textContent = 'Name' ;
274
+ drive . className = CREATE_DRIVE_TITLE_CLASS ;
275
+ const driveName = document . createElement ( 'input' ) ;
276
+
277
+ const region = document . createElement ( 'label' ) ;
278
+ region . textContent = 'Region' ;
279
+ region . className = CREATE_DRIVE_TITLE_CLASS ;
280
+ const regionName = document . createElement ( 'input' ) ;
281
+ regionName . placeholder = 'us-east-1' ;
282
+
283
+ body . appendChild ( drive ) ;
284
+ body . appendChild ( driveName ) ;
285
+ body . appendChild ( region ) ;
286
+ body . appendChild ( regionName ) ;
287
+ return body ;
288
+ } ;
289
+
290
+ /**
291
+ * A widget used to create a new drive.
292
+ */
293
+ export class CreateDriveHandler extends Widget {
294
+ /**
295
+ * Construct a new "create-drive" dialog.
296
+ */
297
+ constructor ( newDriveName : string ) {
298
+ super ( { node : createNewDriveNode ( newDriveName ) } ) ;
299
+ this . onAfterAttach ( ) ;
300
+ }
301
+
302
+ protected onAfterAttach ( ) : void {
303
+ this . addClass ( FILE_DIALOG_CLASS ) ;
304
+ const drive = this . driveInput . value ;
305
+ this . driveInput . setSelectionRange ( 0 , drive . length ) ;
306
+ const region = this . regionInput . value ;
307
+ this . regionInput . setSelectionRange ( 0 , region . length ) ;
308
+ }
309
+
310
+ /**
311
+ * Get the input text node for drive name.
312
+ */
313
+ get driveInput ( ) : HTMLInputElement {
314
+ return this . node . getElementsByTagName ( 'input' ) [ 0 ] as HTMLInputElement ;
315
+ }
316
+
317
+ /**
318
+ * Get the input text node for region.
319
+ */
320
+ get regionInput ( ) : HTMLInputElement {
321
+ return this . node . getElementsByTagName ( 'input' ) [ 1 ] as HTMLInputElement ;
322
+ }
323
+
324
+ /**
325
+ * Get the value of the widget.
326
+ */
327
+ getValue ( ) : string [ ] {
328
+ return [ this . driveInput . value , this . regionInput . value ] ;
329
+ }
330
+ }
331
+
332
+ export function addCommands ( app : JupyterFrontEnd , drive : Drive ) : void {
333
+ app . commands . addCommand ( CommandIDs . createNewDrive , {
334
+ execute : async ( ) => {
335
+ return showDialog ( {
336
+ title : 'New Drive' ,
337
+ body : new Private . CreateDriveHandler ( drive . name ) ,
338
+ focusNodeSelector : 'input' ,
339
+ buttons : [
340
+ Dialog . cancelButton ( ) ,
341
+ Dialog . okButton ( {
342
+ label : 'Create' ,
343
+ ariaLabel : 'Create New Drive'
344
+ } )
345
+ ]
346
+ } ) . then ( result => {
347
+ if ( result . value ) {
348
+ drive . newDrive ( result . value [ 0 ] , result . value [ 1 ] ) ;
349
+ }
350
+ } ) ;
351
+ } ,
352
+ label : 'New Drive' ,
353
+ icon : driveBrowserIcon . bindprops ( { stylesheet : 'menuItem' } )
354
+ } ) ;
355
+
356
+ app . contextMenu . addItem ( {
357
+ command : CommandIDs . createNewDrive ,
358
+ selector : '#drive-file-browser.jp-SidePanel .jp-DirListing-content' ,
359
+ rank : 100
360
+ } ) ;
361
+ }
249
362
}
0 commit comments