@jupyterlab/filebrowser 4.5.0-alpha.0 → 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/browser.d.ts +16 -0
- package/lib/browser.js +34 -0
- package/lib/browser.js.map +1 -1
- package/lib/jest-env.d.ts +4 -0
- package/lib/jest-env.js +18 -0
- package/lib/jest-env.js.map +1 -0
- package/lib/listing.d.ts +25 -1
- package/lib/listing.js +101 -29
- package/lib/listing.js.map +1 -1
- package/lib/model.d.ts +10 -0
- package/lib/model.js +16 -2
- package/lib/model.js.map +1 -1
- package/lib/tokens.d.ts +4 -0
- package/lib/tokens.js.map +1 -1
- package/lib/upload.d.ts +7 -0
- package/lib/upload.js +16 -2
- package/lib/upload.js.map +1 -1
- package/lib/uploadstatus.js +2 -0
- package/lib/uploadstatus.js.map +1 -1
- package/package.json +12 -11
- package/src/browser.ts +37 -0
- package/src/jest-env.ts +21 -0
- package/src/listing.ts +119 -32
- package/src/model.ts +23 -0
- package/src/tokens.ts +5 -0
- package/src/upload.ts +23 -7
- package/src/uploadstatus.tsx +1 -1
package/lib/upload.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { showErrorMessage } from '@jupyterlab/apputils';
|
|
4
4
|
import { nullTranslator } from '@jupyterlab/translation';
|
|
5
5
|
import { fileUploadIcon, ToolbarButton } from '@jupyterlab/ui-components';
|
|
6
|
+
import { Signal } from '@lumino/signaling';
|
|
6
7
|
/**
|
|
7
8
|
* A widget which provides an upload button.
|
|
8
9
|
*/
|
|
@@ -17,7 +18,8 @@ export class Uploader extends ToolbarButton {
|
|
|
17
18
|
onClick: () => {
|
|
18
19
|
this._input.click();
|
|
19
20
|
},
|
|
20
|
-
tooltip: Private.translateToolTip(options.translator)
|
|
21
|
+
tooltip: Private.translateToolTip(options.translator),
|
|
22
|
+
enabled: options.model.allowFileUploads
|
|
21
23
|
});
|
|
22
24
|
/**
|
|
23
25
|
* The 'change' handler for the input field.
|
|
@@ -25,7 +27,12 @@ export class Uploader extends ToolbarButton {
|
|
|
25
27
|
this._onInputChanged = () => {
|
|
26
28
|
const files = Array.prototype.slice.call(this._input.files);
|
|
27
29
|
const pending = files.map(file => this.fileBrowserModel.upload(file));
|
|
28
|
-
void Promise.all(pending)
|
|
30
|
+
void Promise.all(pending)
|
|
31
|
+
.then(models => {
|
|
32
|
+
// emit the batch
|
|
33
|
+
this._filesUploaded.emit(models);
|
|
34
|
+
})
|
|
35
|
+
.catch(error => {
|
|
29
36
|
void showErrorMessage(this._trans._p('showErrorMessage', 'Upload Error'), error);
|
|
30
37
|
});
|
|
31
38
|
};
|
|
@@ -38,6 +45,7 @@ export class Uploader extends ToolbarButton {
|
|
|
38
45
|
this._input.value = '';
|
|
39
46
|
};
|
|
40
47
|
this._input = Private.createUploadInput();
|
|
48
|
+
this._filesUploaded = new Signal(this);
|
|
41
49
|
this.fileBrowserModel = options.model;
|
|
42
50
|
this.translator = options.translator || nullTranslator;
|
|
43
51
|
this._trans = this.translator.load('jupyterlab');
|
|
@@ -45,6 +53,12 @@ export class Uploader extends ToolbarButton {
|
|
|
45
53
|
this._input.onchange = this._onInputChanged;
|
|
46
54
|
this.addClass('jp-id-upload');
|
|
47
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* A signal emitted with file info when a batch of upload completes.
|
|
58
|
+
*/
|
|
59
|
+
get filesUploaded() {
|
|
60
|
+
return this._filesUploaded;
|
|
61
|
+
}
|
|
48
62
|
}
|
|
49
63
|
/**
|
|
50
64
|
* The namespace for module private data.
|
package/lib/upload.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../src/upload.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,2DAA2D;AAE3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAEL,cAAc,EAEf,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAG1E;;GAEG;AACH,MAAM,OAAO,QAAS,SAAQ,aAAa;IACzC;;OAEG;IACH,YAAY,OAA0B;QACpC,KAAK,CAAC;YACJ,IAAI,EAAE,cAAc;YACpB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,OAAO,EAAE,GAAG,EAAE;gBACZ,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YACtB,CAAC;YACD,OAAO,EAAE,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../src/upload.ts"],"names":[],"mappings":"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"}
|
package/lib/uploadstatus.js
CHANGED
|
@@ -116,6 +116,8 @@ export class FileUploadStatus extends VDomRenderer {
|
|
|
116
116
|
else if (uploads.name === 'failure') {
|
|
117
117
|
ArrayExt.removeFirstWhere(this._items, val => val.path === uploads.newValue.path);
|
|
118
118
|
}
|
|
119
|
+
else
|
|
120
|
+
return;
|
|
119
121
|
this.stateChanged.emit(void 0);
|
|
120
122
|
};
|
|
121
123
|
this._items = [];
|
package/lib/uploadstatus.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uploadstatus.js","sourceRoot":"","sources":["../src/uploadstatus.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"uploadstatus.js","sourceRoot":"","sources":["../src/uploadstatus.tsx"],"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.
|
|
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.
|
|
45
|
-
"@jupyterlab/coreutils": "^6.5.0-alpha.
|
|
46
|
-
"@jupyterlab/docmanager": "^4.5.0-alpha.
|
|
47
|
-
"@jupyterlab/docregistry": "^4.5.0-alpha.
|
|
48
|
-
"@jupyterlab/services": "^7.5.0-alpha.
|
|
49
|
-
"@jupyterlab/statedb": "^4.5.0-alpha.
|
|
50
|
-
"@jupyterlab/statusbar": "^4.5.0-alpha.
|
|
51
|
-
"@jupyterlab/translation": "^4.5.0-alpha.
|
|
52
|
-
"@jupyterlab/ui-components": "^4.5.0-alpha.
|
|
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.
|
|
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
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
SidePanel,
|
|
14
14
|
Toolbar
|
|
15
15
|
} from '@jupyterlab/ui-components';
|
|
16
|
+
import { ISignal, Signal } from '@lumino/signaling';
|
|
16
17
|
import { Panel } from '@lumino/widgets';
|
|
17
18
|
import { createRef } from 'react';
|
|
18
19
|
import { BreadCrumbs } from './crumbs';
|
|
@@ -128,6 +129,9 @@ export class FileBrowser extends SidePanel {
|
|
|
128
129
|
state: options.state
|
|
129
130
|
});
|
|
130
131
|
this.listing.addClass(LISTING_CLASS);
|
|
132
|
+
this.listing.selectionChanged.connect(() => {
|
|
133
|
+
this._selectionChanged.emit();
|
|
134
|
+
});
|
|
131
135
|
|
|
132
136
|
this.mainPanel.addWidget(this.crumbs);
|
|
133
137
|
this.mainPanel.addWidget(this.filterToolbar);
|
|
@@ -292,6 +296,23 @@ export class FileBrowser extends SidePanel {
|
|
|
292
296
|
}
|
|
293
297
|
}
|
|
294
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
|
+
|
|
295
316
|
/**
|
|
296
317
|
* Create an iterator over the listing's selected items.
|
|
297
318
|
*
|
|
@@ -301,6 +322,13 @@ export class FileBrowser extends SidePanel {
|
|
|
301
322
|
return this.listing.selectedItems();
|
|
302
323
|
}
|
|
303
324
|
|
|
325
|
+
/**
|
|
326
|
+
* A signal emitted when the selection changes in the file browser.
|
|
327
|
+
*/
|
|
328
|
+
get selectionChanged(): ISignal<this, void> {
|
|
329
|
+
return this._selectionChanged;
|
|
330
|
+
}
|
|
331
|
+
|
|
304
332
|
/**
|
|
305
333
|
* Select an item by name.
|
|
306
334
|
*
|
|
@@ -422,6 +450,13 @@ export class FileBrowser extends SidePanel {
|
|
|
422
450
|
return this.listing.duplicate();
|
|
423
451
|
}
|
|
424
452
|
|
|
453
|
+
/**
|
|
454
|
+
* Select all listing items.
|
|
455
|
+
*/
|
|
456
|
+
selectAll(): Promise<void> {
|
|
457
|
+
return this.listing.selectAll();
|
|
458
|
+
}
|
|
459
|
+
|
|
425
460
|
/**
|
|
426
461
|
* Download the currently selected item(s).
|
|
427
462
|
*/
|
|
@@ -539,6 +574,8 @@ export class FileBrowser extends SidePanel {
|
|
|
539
574
|
private _showHiddenFiles: boolean = false;
|
|
540
575
|
private _showLastModifiedColumn: boolean = true;
|
|
541
576
|
private _sortNotebooksFirst: boolean = false;
|
|
577
|
+
private _allowFileUploads: boolean = true;
|
|
578
|
+
private _selectionChanged = new Signal<this, void>(this);
|
|
542
579
|
}
|
|
543
580
|
|
|
544
581
|
/**
|
package/src/jest-env.ts
ADDED
|
@@ -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);
|
|
@@ -316,6 +317,13 @@ export class DirListing extends Widget {
|
|
|
316
317
|
return this._onItemOpened;
|
|
317
318
|
}
|
|
318
319
|
|
|
320
|
+
/**
|
|
321
|
+
* A signal fired when the selection changes.
|
|
322
|
+
*/
|
|
323
|
+
get selectionChanged(): ISignal<DirListing, void> {
|
|
324
|
+
return this._selectionChanged;
|
|
325
|
+
}
|
|
326
|
+
|
|
319
327
|
/**
|
|
320
328
|
* Create an iterator over the listing's selected items.
|
|
321
329
|
*
|
|
@@ -514,6 +522,22 @@ export class DirListing extends Widget {
|
|
|
514
522
|
});
|
|
515
523
|
}
|
|
516
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
|
+
|
|
517
541
|
/**
|
|
518
542
|
* Download the currently selected item(s).
|
|
519
543
|
*/
|
|
@@ -708,8 +732,11 @@ export class DirListing extends Widget {
|
|
|
708
732
|
/**
|
|
709
733
|
* Clear the selected items.
|
|
710
734
|
*/
|
|
711
|
-
clearSelectedItems(): void {
|
|
735
|
+
clearSelectedItems(emit = true): void {
|
|
712
736
|
this.selection = Object.create(null);
|
|
737
|
+
if (emit) {
|
|
738
|
+
this._selectionChanged.emit();
|
|
739
|
+
}
|
|
713
740
|
}
|
|
714
741
|
|
|
715
742
|
/**
|
|
@@ -790,7 +817,10 @@ export class DirListing extends Widget {
|
|
|
790
817
|
break;
|
|
791
818
|
case 'dragenter':
|
|
792
819
|
case 'dragover':
|
|
793
|
-
|
|
820
|
+
// Only show visual feedback if drag and drop upload is enabled
|
|
821
|
+
if (this._allowDragDropUpload) {
|
|
822
|
+
this.addClass('jp-mod-native-drop');
|
|
823
|
+
}
|
|
794
824
|
event.preventDefault();
|
|
795
825
|
break;
|
|
796
826
|
case 'dragleave':
|
|
@@ -844,6 +874,7 @@ export class DirListing extends Widget {
|
|
|
844
874
|
content.addEventListener('lm-dragleave', this);
|
|
845
875
|
content.addEventListener('lm-dragover', this);
|
|
846
876
|
content.addEventListener('lm-drop', this);
|
|
877
|
+
this._updateColumnSizes();
|
|
847
878
|
}
|
|
848
879
|
|
|
849
880
|
/**
|
|
@@ -1057,6 +1088,8 @@ export class DirListing extends Widget {
|
|
|
1057
1088
|
// Fetch common variables.
|
|
1058
1089
|
const items = this._sortedItems;
|
|
1059
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;
|
|
1060
1093
|
const content = DOMUtils.findElement(this.node, CONTENT_CLASS);
|
|
1061
1094
|
const renderer = this._renderer;
|
|
1062
1095
|
|
|
@@ -1091,12 +1124,18 @@ export class DirListing extends Widget {
|
|
|
1091
1124
|
checkbox.checked = false;
|
|
1092
1125
|
}
|
|
1093
1126
|
|
|
1094
|
-
// Handle `tabIndex`
|
|
1127
|
+
// Handle `tabIndex` & `role`
|
|
1095
1128
|
const nameNode = renderer.getNameNode(node);
|
|
1096
1129
|
if (nameNode) {
|
|
1097
1130
|
// Must check if the name node is there because it gets replaced by the
|
|
1098
1131
|
// edit node when editing the name of the file or directory.
|
|
1099
|
-
|
|
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
|
+
}
|
|
1100
1139
|
}
|
|
1101
1140
|
});
|
|
1102
1141
|
|
|
@@ -1126,6 +1165,11 @@ export class DirListing extends Widget {
|
|
|
1126
1165
|
|
|
1127
1166
|
this.updateNodes(items, nodes);
|
|
1128
1167
|
|
|
1168
|
+
if (needsResize) {
|
|
1169
|
+
this._width = this._computeContentWidth();
|
|
1170
|
+
this._updateColumnSizes();
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1129
1173
|
this._prevPath = this._model.path;
|
|
1130
1174
|
}
|
|
1131
1175
|
|
|
@@ -1320,6 +1364,14 @@ export class DirListing extends Widget {
|
|
|
1320
1364
|
this._allowSingleClick = isEnabled;
|
|
1321
1365
|
}
|
|
1322
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
|
+
|
|
1323
1375
|
/**
|
|
1324
1376
|
* Would this click (or other event type) hit the checkbox by default?
|
|
1325
1377
|
*/
|
|
@@ -1357,6 +1409,7 @@ export class DirListing extends Widget {
|
|
|
1357
1409
|
this._sortedItems.forEach(
|
|
1358
1410
|
(item: Contents.IModel) => (this.selection[item.path] = true)
|
|
1359
1411
|
);
|
|
1412
|
+
this._selectionChanged.emit();
|
|
1360
1413
|
} else {
|
|
1361
1414
|
// Unselect all items
|
|
1362
1415
|
this.clearSelectedItems();
|
|
@@ -1487,6 +1540,7 @@ export class DirListing extends Widget {
|
|
|
1487
1540
|
if (!altered && event.button === 0) {
|
|
1488
1541
|
this.clearSelectedItems();
|
|
1489
1542
|
this.selection[this._softSelection] = true;
|
|
1543
|
+
this._selectionChanged.emit();
|
|
1490
1544
|
this.update();
|
|
1491
1545
|
}
|
|
1492
1546
|
this._softSelection = '';
|
|
@@ -1737,6 +1791,7 @@ export class DirListing extends Widget {
|
|
|
1737
1791
|
} else {
|
|
1738
1792
|
this.selection[path] = true;
|
|
1739
1793
|
}
|
|
1794
|
+
this._selectionChanged.emit();
|
|
1740
1795
|
|
|
1741
1796
|
this.update();
|
|
1742
1797
|
// Key was handled, so return.
|
|
@@ -1823,6 +1878,11 @@ export class DirListing extends Widget {
|
|
|
1823
1878
|
// Prevent navigation
|
|
1824
1879
|
event.preventDefault();
|
|
1825
1880
|
|
|
1881
|
+
// Check if drag and drop upload is disabled
|
|
1882
|
+
if (!this._allowDragDropUpload) {
|
|
1883
|
+
return;
|
|
1884
|
+
}
|
|
1885
|
+
|
|
1826
1886
|
const items = event.dataTransfer?.items;
|
|
1827
1887
|
if (!items) {
|
|
1828
1888
|
// Fallback to simple upload of files (if any)
|
|
@@ -2138,6 +2198,7 @@ export class DirListing extends Widget {
|
|
|
2138
2198
|
} else {
|
|
2139
2199
|
this.selection[path] = true;
|
|
2140
2200
|
}
|
|
2201
|
+
this._selectionChanged.emit();
|
|
2141
2202
|
this._focusItem(index);
|
|
2142
2203
|
// Handle multiple select.
|
|
2143
2204
|
} else if (event.shiftKey) {
|
|
@@ -2217,7 +2278,10 @@ export class DirListing extends Widget {
|
|
|
2217
2278
|
// the focussed item to gain but not lose selected status on shift-click.
|
|
2218
2279
|
// (MacOS is irrelevant here because MacOS Finder has no notion of a
|
|
2219
2280
|
// focused-but-not-selected state.)
|
|
2220
|
-
this.selection[target.path]
|
|
2281
|
+
if (!this.selection[target.path]) {
|
|
2282
|
+
this.selection[target.path] = true;
|
|
2283
|
+
this._selectionChanged.emit();
|
|
2284
|
+
}
|
|
2221
2285
|
return;
|
|
2222
2286
|
}
|
|
2223
2287
|
|
|
@@ -2247,6 +2311,7 @@ export class DirListing extends Widget {
|
|
|
2247
2311
|
(!anteAnchor || !this.selection[anteAnchor.path])
|
|
2248
2312
|
) {
|
|
2249
2313
|
delete this.selection[anchor.path];
|
|
2314
|
+
this._selectionChanged.emit();
|
|
2250
2315
|
}
|
|
2251
2316
|
} else if (this._allSelectedBetween(fromIndex, index)) {
|
|
2252
2317
|
shouldAdd = false;
|
|
@@ -2256,21 +2321,33 @@ export class DirListing extends Widget {
|
|
|
2256
2321
|
// Select (or unselect) the rows between chosen index (target) and the last
|
|
2257
2322
|
// focussed.
|
|
2258
2323
|
const step = fromIndex < index ? 1 : -1;
|
|
2324
|
+
let selectionModified = false;
|
|
2325
|
+
|
|
2259
2326
|
for (let i = fromIndex; i !== index + step; i += step) {
|
|
2260
2327
|
if (shouldAdd) {
|
|
2261
2328
|
if (i === fromIndex) {
|
|
2262
2329
|
// Do not change the selection state of the starting (fromIndex) item.
|
|
2263
2330
|
continue;
|
|
2264
2331
|
}
|
|
2265
|
-
this.selection[items[i].path]
|
|
2332
|
+
if (!this.selection[items[i].path]) {
|
|
2333
|
+
this.selection[items[i].path] = true;
|
|
2334
|
+
selectionModified = true;
|
|
2335
|
+
}
|
|
2266
2336
|
} else {
|
|
2267
2337
|
if (i === index) {
|
|
2268
2338
|
// Do not unselect the target item.
|
|
2269
2339
|
continue;
|
|
2270
2340
|
}
|
|
2271
|
-
|
|
2341
|
+
if (this.selection[items[i].path]) {
|
|
2342
|
+
delete this.selection[items[i].path];
|
|
2343
|
+
selectionModified = true;
|
|
2344
|
+
}
|
|
2272
2345
|
}
|
|
2273
2346
|
}
|
|
2347
|
+
|
|
2348
|
+
if (selectionModified) {
|
|
2349
|
+
this._selectionChanged.emit();
|
|
2350
|
+
}
|
|
2274
2351
|
}
|
|
2275
2352
|
|
|
2276
2353
|
/**
|
|
@@ -2425,10 +2502,12 @@ export class DirListing extends Widget {
|
|
|
2425
2502
|
}
|
|
2426
2503
|
const path = items[index].path;
|
|
2427
2504
|
this.selection[path] = true;
|
|
2505
|
+
this._selectionChanged.emit();
|
|
2428
2506
|
|
|
2429
2507
|
if (focus) {
|
|
2430
2508
|
this._focusItem(index);
|
|
2431
2509
|
}
|
|
2510
|
+
|
|
2432
2511
|
this.update();
|
|
2433
2512
|
}
|
|
2434
2513
|
|
|
@@ -2438,7 +2517,7 @@ export class DirListing extends Widget {
|
|
|
2438
2517
|
private _onModelRefreshed(): void {
|
|
2439
2518
|
// Update the selection.
|
|
2440
2519
|
const existing = Object.keys(this.selection);
|
|
2441
|
-
this.clearSelectedItems();
|
|
2520
|
+
this.clearSelectedItems(false);
|
|
2442
2521
|
for (const item of this._model.items()) {
|
|
2443
2522
|
const path = item.path;
|
|
2444
2523
|
if (existing.indexOf(path) !== -1) {
|
|
@@ -2515,6 +2594,7 @@ export class DirListing extends Widget {
|
|
|
2515
2594
|
key: 'name'
|
|
2516
2595
|
};
|
|
2517
2596
|
private _onItemOpened = new Signal<DirListing, Contents.IModel>(this);
|
|
2597
|
+
private _selectionChanged = new Signal<DirListing, void>(this);
|
|
2518
2598
|
private _drag: Drag | null = null;
|
|
2519
2599
|
private _dragData: {
|
|
2520
2600
|
pressX: number;
|
|
@@ -2560,6 +2640,7 @@ export class DirListing extends Widget {
|
|
|
2560
2640
|
};
|
|
2561
2641
|
private _sortNotebooksFirst = false;
|
|
2562
2642
|
private _allowSingleClick = false;
|
|
2643
|
+
private _allowDragDropUpload = true;
|
|
2563
2644
|
// _focusIndex should never be set outside the range [0, this._items.length - 1]
|
|
2564
2645
|
private _focusIndex = 0;
|
|
2565
2646
|
// Width of the "last modified" column for an individual file
|
|
@@ -2607,6 +2688,12 @@ export namespace DirListing {
|
|
|
2607
2688
|
* the columns sizes
|
|
2608
2689
|
*/
|
|
2609
2690
|
state?: IStateDB;
|
|
2691
|
+
|
|
2692
|
+
/**
|
|
2693
|
+
* Whether to allow drag and drop upload of files.
|
|
2694
|
+
* The default is `true`.
|
|
2695
|
+
*/
|
|
2696
|
+
allowDragDropUpload?: boolean;
|
|
2610
2697
|
}
|
|
2611
2698
|
|
|
2612
2699
|
/**
|
|
@@ -3256,13 +3343,13 @@ export namespace DirListing {
|
|
|
3256
3343
|
|
|
3257
3344
|
// add file size to pop up if its available
|
|
3258
3345
|
if (model.size !== null && model.size !== undefined) {
|
|
3259
|
-
const fileSizeText =
|
|
3346
|
+
const fileSizeText = formatFileSize(model.size, 1, 1024);
|
|
3260
3347
|
if (fileSize) {
|
|
3261
3348
|
fileSize.textContent = fileSizeText;
|
|
3262
3349
|
}
|
|
3263
3350
|
hoverText += trans.__(
|
|
3264
3351
|
'\nSize: %1',
|
|
3265
|
-
|
|
3352
|
+
formatFileSize(model.size, 1, 1024)
|
|
3266
3353
|
);
|
|
3267
3354
|
} else if (fileSize) {
|
|
3268
3355
|
fileSize.textContent = '';
|
|
@@ -3716,28 +3803,6 @@ namespace Private {
|
|
|
3716
3803
|
);
|
|
3717
3804
|
}
|
|
3718
3805
|
|
|
3719
|
-
/**
|
|
3720
|
-
* Format bytes to human readable string.
|
|
3721
|
-
*/
|
|
3722
|
-
export function formatFileSize(
|
|
3723
|
-
bytes: number,
|
|
3724
|
-
decimalPoint: number,
|
|
3725
|
-
k: number
|
|
3726
|
-
): string {
|
|
3727
|
-
// https://www.codexworld.com/how-to/convert-file-size-bytes-kb-mb-gb-javascript/
|
|
3728
|
-
if (bytes === 0) {
|
|
3729
|
-
return '0 B';
|
|
3730
|
-
}
|
|
3731
|
-
const dm = decimalPoint || 2;
|
|
3732
|
-
const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
|
3733
|
-
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
3734
|
-
if (i >= 0 && i < sizes.length) {
|
|
3735
|
-
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
|
|
3736
|
-
} else {
|
|
3737
|
-
return String(bytes);
|
|
3738
|
-
}
|
|
3739
|
-
}
|
|
3740
|
-
|
|
3741
3806
|
/**
|
|
3742
3807
|
* Update an inline svg caret icon in a node.
|
|
3743
3808
|
*/
|
|
@@ -3834,3 +3899,25 @@ namespace Private {
|
|
|
3834
3899
|
return allEntries;
|
|
3835
3900
|
}
|
|
3836
3901
|
}
|
|
3902
|
+
|
|
3903
|
+
/**
|
|
3904
|
+
* Format bytes to human readable string.
|
|
3905
|
+
*/
|
|
3906
|
+
export function formatFileSize(
|
|
3907
|
+
bytes: number,
|
|
3908
|
+
decimalPoint: number,
|
|
3909
|
+
k: number
|
|
3910
|
+
): string {
|
|
3911
|
+
// https://www.codexworld.com/how-to/convert-file-size-bytes-kb-mb-gb-javascript/
|
|
3912
|
+
if (bytes === 0) {
|
|
3913
|
+
return '0 B';
|
|
3914
|
+
}
|
|
3915
|
+
const dm = decimalPoint || 2;
|
|
3916
|
+
const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
|
3917
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
3918
|
+
if (i >= 0 && i < sizes.length) {
|
|
3919
|
+
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
|
|
3920
|
+
} else {
|
|
3921
|
+
return String(bytes);
|
|
3922
|
+
}
|
|
3923
|
+
}
|
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
|
|