@jupyterlab/filebrowser 4.5.0-alpha.1 → 4.5.0-alpha.2

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/lib/upload.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"upload.js","sourceRoot":"","sources":["../src/upload.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"upload.js","sourceRoot":"","sources":["../src/upload.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jupyterlab/filebrowser",
3
- "version": "4.5.0-alpha.1",
3
+ "version": "4.5.0-alpha.2",
4
4
  "description": "JupyterLab - FileBrowser Widget",
5
5
  "homepage": "https://github.com/jupyterlab/jupyterlab",
6
6
  "bugs": {
@@ -41,15 +41,15 @@
41
41
  "watch": "tsc -b --watch"
42
42
  },
43
43
  "dependencies": {
44
- "@jupyterlab/apputils": "^4.6.0-alpha.1",
45
- "@jupyterlab/coreutils": "^6.5.0-alpha.1",
46
- "@jupyterlab/docmanager": "^4.5.0-alpha.1",
47
- "@jupyterlab/docregistry": "^4.5.0-alpha.1",
48
- "@jupyterlab/services": "^7.5.0-alpha.1",
49
- "@jupyterlab/statedb": "^4.5.0-alpha.1",
50
- "@jupyterlab/statusbar": "^4.5.0-alpha.1",
51
- "@jupyterlab/translation": "^4.5.0-alpha.1",
52
- "@jupyterlab/ui-components": "^4.5.0-alpha.1",
44
+ "@jupyterlab/apputils": "^4.6.0-alpha.2",
45
+ "@jupyterlab/coreutils": "^6.5.0-alpha.2",
46
+ "@jupyterlab/docmanager": "^4.5.0-alpha.2",
47
+ "@jupyterlab/docregistry": "^4.5.0-alpha.2",
48
+ "@jupyterlab/services": "^7.5.0-alpha.2",
49
+ "@jupyterlab/statedb": "^4.5.0-alpha.2",
50
+ "@jupyterlab/statusbar": "^4.5.0-alpha.2",
51
+ "@jupyterlab/translation": "^4.5.0-alpha.2",
52
+ "@jupyterlab/ui-components": "^4.5.0-alpha.2",
53
53
  "@lumino/algorithm": "^2.0.3",
54
54
  "@lumino/coreutils": "^2.2.1",
55
55
  "@lumino/disposable": "^2.1.4",
@@ -60,10 +60,11 @@
60
60
  "@lumino/signaling": "^2.1.4",
61
61
  "@lumino/virtualdom": "^2.0.3",
62
62
  "@lumino/widgets": "^2.7.1",
63
+ "jest-environment-jsdom": "^29.3.0",
63
64
  "react": "^18.2.0"
64
65
  },
65
66
  "devDependencies": {
66
- "@jupyterlab/testing": "^4.5.0-alpha.1",
67
+ "@jupyterlab/testing": "^4.5.0-alpha.2",
67
68
  "@types/jest": "^29.2.0",
68
69
  "jest": "^29.2.0",
69
70
  "rimraf": "~5.0.5",
package/src/browser.ts CHANGED
@@ -296,6 +296,23 @@ export class FileBrowser extends SidePanel {
296
296
  }
297
297
  }
298
298
 
299
+ /**
300
+ * Whether to allow upload of files.
301
+ */
302
+ get allowFileUploads(): boolean {
303
+ return this._allowFileUploads;
304
+ }
305
+
306
+ set allowFileUploads(value: boolean) {
307
+ this.model.allowFileUploads = value;
308
+ if (this.listing.setAllowDragDropUpload) {
309
+ this.listing.setAllowDragDropUpload(value);
310
+ this._allowFileUploads = value;
311
+ } else {
312
+ console.warn('Listing does not support setting upload');
313
+ }
314
+ }
315
+
299
316
  /**
300
317
  * Create an iterator over the listing's selected items.
301
318
  *
@@ -433,6 +450,13 @@ export class FileBrowser extends SidePanel {
433
450
  return this.listing.duplicate();
434
451
  }
435
452
 
453
+ /**
454
+ * Select all listing items.
455
+ */
456
+ selectAll(): Promise<void> {
457
+ return this.listing.selectAll();
458
+ }
459
+
436
460
  /**
437
461
  * Download the currently selected item(s).
438
462
  */
@@ -550,6 +574,7 @@ export class FileBrowser extends SidePanel {
550
574
  private _showHiddenFiles: boolean = false;
551
575
  private _showLastModifiedColumn: boolean = true;
552
576
  private _sortNotebooksFirst: boolean = false;
577
+ private _allowFileUploads: boolean = true;
553
578
  private _selectionChanged = new Signal<this, void>(this);
554
579
  }
555
580
 
@@ -0,0 +1,21 @@
1
+ /*
2
+ * Copyright (c) Jupyter Development Team.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+
6
+ // From: https://github.com/jsdom/jsdom/issues/1724#issuecomment-1446858041
7
+ // Mostly the same as in @jupyterlab/testing, but using jsdom version of `File`
8
+ // so that it is compatible with `FileReader` from jsdom.
9
+
10
+ import JSDOMEnvironment from 'jest-environment-jsdom';
11
+
12
+ export default class FixJSDOMEnvironment extends JSDOMEnvironment {
13
+ constructor(...args: ConstructorParameters<typeof JSDOMEnvironment>) {
14
+ super(...args);
15
+
16
+ this.global.fetch = fetch;
17
+ this.global.Headers = Headers;
18
+ this.global.Request = Request;
19
+ this.global.Response = Response;
20
+ }
21
+ }
package/src/listing.ts CHANGED
@@ -238,6 +238,7 @@ export class DirListing extends Widget {
238
238
  this._manager = this._model.manager;
239
239
  this._renderer = options.renderer || DirListing.defaultRenderer;
240
240
  this._state = options.state || null;
241
+ this._allowDragDropUpload = options.allowDragDropUpload ?? true;
241
242
 
242
243
  // Get the width of the "modified" column
243
244
  this._updateModifiedSize(this.node);
@@ -521,6 +522,22 @@ export class DirListing extends Widget {
521
522
  });
522
523
  }
523
524
 
525
+ /**
526
+ * Select all listing items in the current directory.
527
+ */
528
+ async selectAll(): Promise<void> {
529
+ const items = this._model.items();
530
+ const newSelection: { [key: string]: boolean } = {};
531
+
532
+ for (const item of items) {
533
+ newSelection[item.path] = true;
534
+ }
535
+
536
+ this.selection = newSelection;
537
+ this._selectionChanged.emit();
538
+ this.update();
539
+ }
540
+
524
541
  /**
525
542
  * Download the currently selected item(s).
526
543
  */
@@ -715,9 +732,11 @@ export class DirListing extends Widget {
715
732
  /**
716
733
  * Clear the selected items.
717
734
  */
718
- clearSelectedItems(): void {
735
+ clearSelectedItems(emit = true): void {
719
736
  this.selection = Object.create(null);
720
- this._selectionChanged.emit();
737
+ if (emit) {
738
+ this._selectionChanged.emit();
739
+ }
721
740
  }
722
741
 
723
742
  /**
@@ -798,7 +817,10 @@ export class DirListing extends Widget {
798
817
  break;
799
818
  case 'dragenter':
800
819
  case 'dragover':
801
- this.addClass('jp-mod-native-drop');
820
+ // Only show visual feedback if drag and drop upload is enabled
821
+ if (this._allowDragDropUpload) {
822
+ this.addClass('jp-mod-native-drop');
823
+ }
802
824
  event.preventDefault();
803
825
  break;
804
826
  case 'dragleave':
@@ -852,6 +874,7 @@ export class DirListing extends Widget {
852
874
  content.addEventListener('lm-dragleave', this);
853
875
  content.addEventListener('lm-dragover', this);
854
876
  content.addEventListener('lm-drop', this);
877
+ this._updateColumnSizes();
855
878
  }
856
879
 
857
880
  /**
@@ -1065,6 +1088,8 @@ export class DirListing extends Widget {
1065
1088
  // Fetch common variables.
1066
1089
  const items = this._sortedItems;
1067
1090
  const nodes = this._items;
1091
+ // If we didn't get any item yet, we'll need to resize once items are added
1092
+ const needsResize = nodes.length === 0;
1068
1093
  const content = DOMUtils.findElement(this.node, CONTENT_CLASS);
1069
1094
  const renderer = this._renderer;
1070
1095
 
@@ -1099,12 +1124,18 @@ export class DirListing extends Widget {
1099
1124
  checkbox.checked = false;
1100
1125
  }
1101
1126
 
1102
- // Handle `tabIndex`
1127
+ // Handle `tabIndex` & `role`
1103
1128
  const nameNode = renderer.getNameNode(node);
1104
1129
  if (nameNode) {
1105
1130
  // Must check if the name node is there because it gets replaced by the
1106
1131
  // edit node when editing the name of the file or directory.
1107
- nameNode.tabIndex = i === this._focusIndex ? 0 : -1;
1132
+ if (i === this._focusIndex) {
1133
+ nameNode.setAttribute('tabIndex', '0');
1134
+ nameNode.setAttribute('role', 'button');
1135
+ } else {
1136
+ nameNode.setAttribute('tabIndex', '-1');
1137
+ nameNode.removeAttribute('role');
1138
+ }
1108
1139
  }
1109
1140
  });
1110
1141
 
@@ -1134,6 +1165,11 @@ export class DirListing extends Widget {
1134
1165
 
1135
1166
  this.updateNodes(items, nodes);
1136
1167
 
1168
+ if (needsResize) {
1169
+ this._width = this._computeContentWidth();
1170
+ this._updateColumnSizes();
1171
+ }
1172
+
1137
1173
  this._prevPath = this._model.path;
1138
1174
  }
1139
1175
 
@@ -1328,6 +1364,14 @@ export class DirListing extends Widget {
1328
1364
  this._allowSingleClick = isEnabled;
1329
1365
  }
1330
1366
 
1367
+ /**
1368
+ * Update the setting to allow drag and drop upload.
1369
+ * This enables uploading files via drag and drop.
1370
+ */
1371
+ setAllowDragDropUpload(isEnabled: boolean) {
1372
+ this._allowDragDropUpload = isEnabled;
1373
+ }
1374
+
1331
1375
  /**
1332
1376
  * Would this click (or other event type) hit the checkbox by default?
1333
1377
  */
@@ -1834,6 +1878,11 @@ export class DirListing extends Widget {
1834
1878
  // Prevent navigation
1835
1879
  event.preventDefault();
1836
1880
 
1881
+ // Check if drag and drop upload is disabled
1882
+ if (!this._allowDragDropUpload) {
1883
+ return;
1884
+ }
1885
+
1837
1886
  const items = event.dataTransfer?.items;
1838
1887
  if (!items) {
1839
1888
  // Fallback to simple upload of files (if any)
@@ -2468,7 +2517,7 @@ export class DirListing extends Widget {
2468
2517
  private _onModelRefreshed(): void {
2469
2518
  // Update the selection.
2470
2519
  const existing = Object.keys(this.selection);
2471
- this.clearSelectedItems();
2520
+ this.clearSelectedItems(false);
2472
2521
  for (const item of this._model.items()) {
2473
2522
  const path = item.path;
2474
2523
  if (existing.indexOf(path) !== -1) {
@@ -2591,6 +2640,7 @@ export class DirListing extends Widget {
2591
2640
  };
2592
2641
  private _sortNotebooksFirst = false;
2593
2642
  private _allowSingleClick = false;
2643
+ private _allowDragDropUpload = true;
2594
2644
  // _focusIndex should never be set outside the range [0, this._items.length - 1]
2595
2645
  private _focusIndex = 0;
2596
2646
  // Width of the "last modified" column for an individual file
@@ -2638,6 +2688,12 @@ export namespace DirListing {
2638
2688
  * the columns sizes
2639
2689
  */
2640
2690
  state?: IStateDB;
2691
+
2692
+ /**
2693
+ * Whether to allow drag and drop upload of files.
2694
+ * The default is `true`.
2695
+ */
2696
+ allowDragDropUpload?: boolean;
2641
2697
  }
2642
2698
 
2643
2699
  /**
package/src/model.ts CHANGED
@@ -60,6 +60,7 @@ export class FileBrowserModel implements IDisposable {
60
60
  this.translator = options.translator || nullTranslator;
61
61
  this._trans = this.translator.load('jupyterlab');
62
62
  this._driveName = options.driveName || '';
63
+ this._allowFileUploads = options.allowFileUploads ?? true;
63
64
  this._model = {
64
65
  path: this.rootPath,
65
66
  name: PathExt.basename(this.rootPath),
@@ -379,6 +380,17 @@ export class FileBrowserModel implements IDisposable {
379
380
  this._restored.resolve(undefined);
380
381
  }
381
382
 
383
+ /**
384
+ * Whether uploads are allowed.
385
+ */
386
+ get allowFileUploads(): boolean {
387
+ return this._allowFileUploads;
388
+ }
389
+
390
+ set allowFileUploads(value: boolean) {
391
+ this._allowFileUploads = value;
392
+ }
393
+
382
394
  /**
383
395
  * Upload a `File` object.
384
396
  *
@@ -394,6 +406,11 @@ export class FileBrowserModel implements IDisposable {
394
406
  * chunks.
395
407
  */
396
408
  async upload(file: File, path?: string): Promise<Contents.IModel> {
409
+ // Check if upload is allowed
410
+ if (!this._allowFileUploads) {
411
+ throw new Error(this._trans.__('File uploads are disabled'));
412
+ }
413
+
397
414
  // We do not support Jupyter Notebook version less than 4, and Jupyter
398
415
  // Server advertises itself as version 1 and supports chunked
399
416
  // uploading. We assume any version less than 4.0.0 to be Jupyter Server
@@ -657,6 +674,7 @@ export class FileBrowserModel implements IDisposable {
657
674
  private _sessions: Session.IModel[] = [];
658
675
  private _state: IStateDB | null = null;
659
676
  private _driveName: string;
677
+ private _allowFileUploads: boolean;
660
678
  private _isDisposed = false;
661
679
  private _restored = new PromiseDelegate<void>();
662
680
  private _uploads: IUploadModel[] = [];
@@ -713,6 +731,11 @@ export namespace FileBrowserModel {
713
731
  * The application language translator.
714
732
  */
715
733
  translator?: ITranslator;
734
+
735
+ /**
736
+ * Whether to allow file uploads. Defaults to `true`.
737
+ */
738
+ allowFileUploads?: boolean;
716
739
  }
717
740
  }
718
741
 
package/src/tokens.ts CHANGED
@@ -115,6 +115,11 @@ export namespace IFileBrowserFactory {
115
115
  * database will be automatically passed in and used for state restoration.
116
116
  */
117
117
  state?: IStateDB | null;
118
+
119
+ /**
120
+ * Whether to allow file uploads. Defaults to `true`.
121
+ */
122
+ allowFileUploads?: boolean;
118
123
  }
119
124
  }
120
125
 
package/src/upload.ts CHANGED
@@ -26,7 +26,8 @@ export class Uploader extends ToolbarButton {
26
26
  onClick: () => {
27
27
  this._input.click();
28
28
  },
29
- tooltip: Private.translateToolTip(options.translator)
29
+ tooltip: Private.translateToolTip(options.translator),
30
+ enabled: options.model.allowFileUploads
30
31
  });
31
32
  this.fileBrowserModel = options.model;
32
33
  this.translator = options.translator || nullTranslator;