@jupyterlab/filebrowser 4.3.0-alpha.1 → 4.3.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/browser.ts CHANGED
@@ -5,9 +5,16 @@ import { showErrorMessage } from '@jupyterlab/apputils';
5
5
  import { PathExt } from '@jupyterlab/coreutils';
6
6
  import { IDocumentManager } from '@jupyterlab/docmanager';
7
7
  import { Contents, ServerConnection } from '@jupyterlab/services';
8
+ import { IStateDB } from '@jupyterlab/statedb';
8
9
  import { ITranslator, nullTranslator } from '@jupyterlab/translation';
9
- import { SidePanel } from '@jupyterlab/ui-components';
10
+ import {
11
+ FilenameSearcher,
12
+ IScore,
13
+ SidePanel,
14
+ Toolbar
15
+ } from '@jupyterlab/ui-components';
10
16
  import { Panel } from '@lumino/widgets';
17
+ import { createRef } from 'react';
11
18
  import { BreadCrumbs } from './crumbs';
12
19
  import { DirListing } from './listing';
13
20
  import { FilterFileBrowserModel } from './model';
@@ -32,11 +39,21 @@ const CRUMBS_CLASS = 'jp-FileBrowser-crumbs';
32
39
  */
33
40
  const TOOLBAR_CLASS = 'jp-FileBrowser-toolbar';
34
41
 
42
+ /**
43
+ * The class name added to the filebrowser filter toolbar node.
44
+ */
45
+ const FILTER_TOOLBAR_CLASS = 'jp-FileBrowser-filterToolbar';
46
+
35
47
  /**
36
48
  * The class name added to the filebrowser listing node.
37
49
  */
38
50
  const LISTING_CLASS = 'jp-FileBrowser-listing';
39
51
 
52
+ /**
53
+ * The class name added to the filebrowser filterbox node.
54
+ */
55
+ const FILTERBOX_CLASS = 'jp-FileBrowser-filterBox';
56
+
40
57
  /**
41
58
  * A widget which hosts a file browser.
42
59
  *
@@ -76,14 +93,39 @@ export class FileBrowser extends SidePanel {
76
93
  this.crumbs = new BreadCrumbs({ model, translator });
77
94
  this.crumbs.addClass(CRUMBS_CLASS);
78
95
 
96
+ // The filter toolbar appears immediately below the breadcrumbs and above the directory listing.
97
+ const searcher = FilenameSearcher({
98
+ updateFilter: (
99
+ filterFn: (item: string) => Partial<IScore> | null,
100
+ query?: string
101
+ ) => {
102
+ this.model.setFilter(value => {
103
+ return filterFn(value.name.toLowerCase());
104
+ });
105
+ },
106
+ useFuzzyFilter: true,
107
+ placeholder: this._trans.__('Filter files by name'),
108
+ forceRefresh: false,
109
+ showIcon: false,
110
+ inputRef: this._fileFilterRef
111
+ });
112
+ searcher.addClass(FILTERBOX_CLASS);
113
+
114
+ this.filterToolbar = new Toolbar();
115
+ this.filterToolbar.addClass(FILTER_TOOLBAR_CLASS);
116
+ this.filterToolbar.addItem('fileNameSearcher', searcher);
117
+ this.filterToolbar.setHidden(!this.showFileFilter);
118
+
79
119
  this.listing = this.createDirListing({
80
120
  model,
81
121
  renderer,
82
- translator
122
+ translator,
123
+ state: options.state
83
124
  });
84
125
  this.listing.addClass(LISTING_CLASS);
85
126
 
86
127
  this.mainPanel.addWidget(this.crumbs);
128
+ this.mainPanel.addWidget(this.filterToolbar);
87
129
  this.mainPanel.addWidget(this.listing);
88
130
 
89
131
  this.addWidget(this.mainPanel);
@@ -91,6 +133,8 @@ export class FileBrowser extends SidePanel {
91
133
  if (options.restore !== false) {
92
134
  void model.restore(this.id);
93
135
  }
136
+ // restore listing regardless of the restore option
137
+ void this.listing.restore(this.id);
94
138
  }
95
139
 
96
140
  /**
@@ -180,6 +224,37 @@ export class FileBrowser extends SidePanel {
180
224
  }
181
225
  }
182
226
 
227
+ /**
228
+ * Whether to show a text box to filter files by name.
229
+ */
230
+ get showFileFilter(): boolean {
231
+ return this._showFileFilter;
232
+ }
233
+
234
+ set showFileFilter(value: boolean) {
235
+ // If the old value was true and the new value is false, clear the filter
236
+ const oldValue = this.showFileFilter;
237
+ if (oldValue && !value) {
238
+ // Clear the search box input
239
+ if (this._fileFilterRef.current) {
240
+ this._fileFilterRef.current.value = '';
241
+ }
242
+
243
+ // Set a filter that doesn't exclude anything.
244
+ this.model.setFilter(value => {
245
+ return {};
246
+ });
247
+ this.model.refresh().catch(console.warn);
248
+ }
249
+ this._showFileFilter = value;
250
+
251
+ // Update widget visibility
252
+ this.filterToolbar.setHidden(!this.showFileFilter);
253
+ if (this.showFileFilter) {
254
+ this._fileFilterRef.current?.focus();
255
+ }
256
+ }
257
+
183
258
  /**
184
259
  * Whether to sort notebooks above other files
185
260
  */
@@ -196,6 +271,22 @@ export class FileBrowser extends SidePanel {
196
271
  }
197
272
  }
198
273
 
274
+ /**
275
+ * Whether to allow single click files and directories
276
+ */
277
+ get singleClickNavigation(): boolean {
278
+ return this._allowSingleClick;
279
+ }
280
+
281
+ set singleClickNavigation(value: boolean) {
282
+ if (this.listing.setAllowSingleClickNavigation) {
283
+ this.listing.setAllowSingleClickNavigation(value);
284
+ this._allowSingleClick = value;
285
+ } else {
286
+ console.warn('Listing does not support single click navigation');
287
+ }
288
+ }
289
+
199
290
  /**
200
291
  * Create an iterator over the listing's selected items.
201
292
  *
@@ -426,18 +517,22 @@ export class FileBrowser extends SidePanel {
426
517
  }
427
518
  }
428
519
 
520
+ protected filterToolbar: Toolbar;
429
521
  protected listing: DirListing;
430
522
  protected crumbs: BreadCrumbs;
431
523
  protected mainPanel: Panel;
432
524
 
433
- private _manager: IDocumentManager;
434
525
  private _directoryPending: Promise<Contents.IModel> | null = null;
435
526
  private _filePending: Promise<Contents.IModel> | null = null;
527
+ private _fileFilterRef = createRef<HTMLInputElement>();
528
+ private _manager: IDocumentManager;
436
529
  private _navigateToCurrentDirectory: boolean;
437
- private _showLastModifiedColumn: boolean = true;
530
+ private _allowSingleClick: boolean = false;
531
+ private _showFileCheckboxes: boolean = false;
532
+ private _showFileFilter: boolean = false;
438
533
  private _showFileSizeColumn: boolean = false;
439
534
  private _showHiddenFiles: boolean = false;
440
- private _showFileCheckboxes: boolean = false;
535
+ private _showLastModifiedColumn: boolean = true;
441
536
  private _sortNotebooksFirst: boolean = false;
442
537
  }
443
538
 
@@ -480,6 +575,12 @@ export namespace FileBrowser {
480
575
  * The application language translator.
481
576
  */
482
577
  translator?: ITranslator;
578
+
579
+ /**
580
+ * An optional state database. If provided, the widget will restore
581
+ * the columns sizes
582
+ */
583
+ state?: IStateDB;
483
584
  }
484
585
 
485
586
  /**