@jupyterlab/filebrowser 4.6.0-alpha.1 → 4.6.0-alpha.3
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 +12 -5
- package/lib/browser.js +17 -0
- package/lib/browser.js.map +1 -1
- package/lib/crumbs.d.ts +25 -3
- package/lib/crumbs.js +187 -5
- package/lib/crumbs.js.map +1 -1
- package/lib/listing.d.ts +13 -6
- package/lib/listing.js +36 -12
- package/lib/listing.js.map +1 -1
- package/lib/model.d.ts +8 -8
- package/lib/model.js.map +1 -1
- package/lib/opendialog.d.ts +4 -4
- package/lib/opendialog.js.map +1 -1
- package/lib/upload.d.ts +4 -4
- package/lib/upload.js.map +1 -1
- package/lib/uploadstatus.d.ts +3 -3
- package/lib/uploadstatus.js.map +1 -1
- package/package.json +14 -14
- package/src/browser.ts +28 -7
- package/src/crumbs.ts +231 -13
- package/src/listing.ts +54 -33
- package/src/model.ts +18 -17
- package/src/opendialog.ts +15 -14
- package/src/upload.ts +6 -8
- package/src/uploadstatus.tsx +5 -8
package/src/listing.ts
CHANGED
|
@@ -8,19 +8,13 @@ import {
|
|
|
8
8
|
showErrorMessage
|
|
9
9
|
} from '@jupyterlab/apputils';
|
|
10
10
|
import { PageConfig, PathExt, Time } from '@jupyterlab/coreutils';
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
isValidFileName,
|
|
14
|
-
renameFile
|
|
15
|
-
} from '@jupyterlab/docmanager';
|
|
11
|
+
import type { IDocumentManager } from '@jupyterlab/docmanager';
|
|
12
|
+
import { isValidFileName, renameFile } from '@jupyterlab/docmanager';
|
|
16
13
|
import { DocumentRegistry } from '@jupyterlab/docregistry';
|
|
17
|
-
import { Contents } from '@jupyterlab/services';
|
|
18
|
-
import { IStateDB } from '@jupyterlab/statedb';
|
|
19
|
-
import {
|
|
20
|
-
|
|
21
|
-
nullTranslator,
|
|
22
|
-
TranslationBundle
|
|
23
|
-
} from '@jupyterlab/translation';
|
|
14
|
+
import type { Contents } from '@jupyterlab/services';
|
|
15
|
+
import type { IStateDB } from '@jupyterlab/statedb';
|
|
16
|
+
import type { ITranslator, TranslationBundle } from '@jupyterlab/translation';
|
|
17
|
+
import { nullTranslator } from '@jupyterlab/translation';
|
|
24
18
|
import {
|
|
25
19
|
caretDownIcon,
|
|
26
20
|
caretUpIcon,
|
|
@@ -28,19 +22,19 @@ import {
|
|
|
28
22
|
LabIcon
|
|
29
23
|
} from '@jupyterlab/ui-components';
|
|
30
24
|
import { ArrayExt, filter, StringExt } from '@lumino/algorithm';
|
|
31
|
-
import {
|
|
32
|
-
|
|
33
|
-
PromiseDelegate,
|
|
34
|
-
ReadonlyJSONObject
|
|
35
|
-
} from '@lumino/coreutils';
|
|
25
|
+
import type { ReadonlyJSONObject } from '@lumino/coreutils';
|
|
26
|
+
import { MimeData, PromiseDelegate } from '@lumino/coreutils';
|
|
36
27
|
import { ElementExt } from '@lumino/domutils';
|
|
37
|
-
import {
|
|
28
|
+
import type { IDisposable } from '@lumino/disposable';
|
|
29
|
+
import { DisposableDelegate } from '@lumino/disposable';
|
|
38
30
|
import { Drag } from '@lumino/dragdrop';
|
|
39
|
-
import { Message
|
|
40
|
-
import {
|
|
31
|
+
import type { Message } from '@lumino/messaging';
|
|
32
|
+
import { MessageLoop } from '@lumino/messaging';
|
|
33
|
+
import type { ISignal } from '@lumino/signaling';
|
|
34
|
+
import { Signal } from '@lumino/signaling';
|
|
41
35
|
import { h, VirtualDOM } from '@lumino/virtualdom';
|
|
42
36
|
import { Widget } from '@lumino/widgets';
|
|
43
|
-
import { FilterFileBrowserModel } from './model';
|
|
37
|
+
import type { FilterFileBrowserModel } from './model';
|
|
44
38
|
|
|
45
39
|
/**
|
|
46
40
|
* The class name added to DirListing widget.
|
|
@@ -356,6 +350,7 @@ export class DirListing extends Widget {
|
|
|
356
350
|
this.model.items(),
|
|
357
351
|
state,
|
|
358
352
|
this._sortNotebooksFirst,
|
|
353
|
+
this._sortFileNamesNaturally,
|
|
359
354
|
this.translator
|
|
360
355
|
);
|
|
361
356
|
this._sortState = state;
|
|
@@ -962,8 +957,8 @@ export class DirListing extends Widget {
|
|
|
962
957
|
this._modifiedWidth < 100
|
|
963
958
|
? 'narrow'
|
|
964
959
|
: this._modifiedWidth > 120
|
|
965
|
-
|
|
966
|
-
|
|
960
|
+
? 'long'
|
|
961
|
+
: 'short';
|
|
967
962
|
}
|
|
968
963
|
|
|
969
964
|
/**
|
|
@@ -1361,6 +1356,19 @@ export class DirListing extends Widget {
|
|
|
1361
1356
|
}
|
|
1362
1357
|
}
|
|
1363
1358
|
|
|
1359
|
+
/**
|
|
1360
|
+
* Update the setting to sort file names naturally
|
|
1361
|
+
* vs lexicographically. Default is true (natural).
|
|
1362
|
+
* This sorts the items again if the internal value is modified.
|
|
1363
|
+
*/
|
|
1364
|
+
setSortFileNamesNaturally(natural: boolean): void {
|
|
1365
|
+
const previousValue = this._sortFileNamesNaturally;
|
|
1366
|
+
this._sortFileNamesNaturally = natural;
|
|
1367
|
+
if (this._sortFileNamesNaturally !== previousValue) {
|
|
1368
|
+
this.sort(this._sortState);
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
|
|
1364
1372
|
/**
|
|
1365
1373
|
* Update the setting to allow single click navigation.
|
|
1366
1374
|
* This enables opening files/directories with a single click.
|
|
@@ -2121,7 +2129,7 @@ export class DirListing extends Widget {
|
|
|
2121
2129
|
} as DirListing.IContentsThunk);
|
|
2122
2130
|
}
|
|
2123
2131
|
|
|
2124
|
-
if (item
|
|
2132
|
+
if (item.type !== 'directory') {
|
|
2125
2133
|
const otherPaths = selectedPaths.slice(1).reverse();
|
|
2126
2134
|
this._drag.mimeData.setData(FACTORY_MIME, () => {
|
|
2127
2135
|
if (!item) {
|
|
@@ -2541,6 +2549,9 @@ export class DirListing extends Widget {
|
|
|
2541
2549
|
* Handle a `pathChanged` signal from the model.
|
|
2542
2550
|
*/
|
|
2543
2551
|
private _onPathChanged(): void {
|
|
2552
|
+
// Check if the directory listing (or any of its children) has focus.
|
|
2553
|
+
const hasFocus = this.node.contains(document.activeElement);
|
|
2554
|
+
|
|
2544
2555
|
// Reset the selection.
|
|
2545
2556
|
this.clearSelectedItems();
|
|
2546
2557
|
// Update the sorted items.
|
|
@@ -2548,7 +2559,16 @@ export class DirListing extends Widget {
|
|
|
2548
2559
|
// Reset focus. But wait until the DOM has been updated (hence
|
|
2549
2560
|
// `requestAnimationFrame`).
|
|
2550
2561
|
requestAnimationFrame(() => {
|
|
2551
|
-
this.
|
|
2562
|
+
if (this.isDisposed) {
|
|
2563
|
+
return;
|
|
2564
|
+
}
|
|
2565
|
+
// Only focus the first item if the listing (or a child) previously had focus.
|
|
2566
|
+
if (hasFocus) {
|
|
2567
|
+
this._focusItem(0);
|
|
2568
|
+
} else {
|
|
2569
|
+
// Otherwise, just reset the internal focus index without moving DOM focus.
|
|
2570
|
+
this._focusIndex = 0;
|
|
2571
|
+
}
|
|
2552
2572
|
});
|
|
2553
2573
|
}
|
|
2554
2574
|
|
|
@@ -2645,6 +2665,7 @@ export class DirListing extends Widget {
|
|
|
2645
2665
|
last_modified: null
|
|
2646
2666
|
};
|
|
2647
2667
|
private _sortNotebooksFirst = false;
|
|
2668
|
+
private _sortFileNamesNaturally = true;
|
|
2648
2669
|
private _allowSingleClick = false;
|
|
2649
2670
|
private _allowDragDropUpload = true;
|
|
2650
2671
|
// _focusIndex should never be set outside the range [0, this._items.length - 1]
|
|
@@ -3679,6 +3700,7 @@ namespace Private {
|
|
|
3679
3700
|
items: Iterable<Contents.IModel>,
|
|
3680
3701
|
state: DirListing.ISortState,
|
|
3681
3702
|
sortNotebooksFirst: boolean = false,
|
|
3703
|
+
sortFileNamesNaturally: boolean = true,
|
|
3682
3704
|
translator: ITranslator
|
|
3683
3705
|
): Contents.IModel[] {
|
|
3684
3706
|
const copy = Array.from(items);
|
|
@@ -3710,6 +3732,7 @@ namespace Private {
|
|
|
3710
3732
|
|
|
3711
3733
|
/**
|
|
3712
3734
|
* Compare two items by their name using `translator.languageCode`, with fallback to `navigator.language`.
|
|
3735
|
+
* When sortFileNamesNaturally is true, uses natural order.
|
|
3713
3736
|
*/
|
|
3714
3737
|
function compareByName(a: Contents.IModel, b: Contents.IModel) {
|
|
3715
3738
|
// Wokaround for Chromium invalid language code on CI, see
|
|
@@ -3718,19 +3741,17 @@ namespace Private {
|
|
|
3718
3741
|
const languageCode = (
|
|
3719
3742
|
translator.languageCode ?? navigatorLanguage
|
|
3720
3743
|
).replace('_', '-');
|
|
3744
|
+
const localeOptions: Intl.CollatorOptions = {
|
|
3745
|
+
numeric: sortFileNamesNaturally,
|
|
3746
|
+
sensitivity: 'base'
|
|
3747
|
+
};
|
|
3721
3748
|
try {
|
|
3722
|
-
return a.name.localeCompare(b.name, languageCode,
|
|
3723
|
-
numeric: true,
|
|
3724
|
-
sensitivity: 'base'
|
|
3725
|
-
});
|
|
3749
|
+
return a.name.localeCompare(b.name, languageCode, localeOptions);
|
|
3726
3750
|
} catch (e) {
|
|
3727
3751
|
console.warn(
|
|
3728
3752
|
`localeCompare failed to compare ${a.name} and ${b.name} under languageCode: ${languageCode}`
|
|
3729
3753
|
);
|
|
3730
|
-
return a.name.localeCompare(b.name, navigatorLanguage,
|
|
3731
|
-
numeric: true,
|
|
3732
|
-
sensitivity: 'base'
|
|
3733
|
-
});
|
|
3754
|
+
return a.name.localeCompare(b.name, navigatorLanguage, localeOptions);
|
|
3734
3755
|
}
|
|
3735
3756
|
}
|
|
3736
3757
|
|
package/src/model.ts
CHANGED
|
@@ -2,21 +2,22 @@
|
|
|
2
2
|
// Distributed under the terms of the Modified BSD License.
|
|
3
3
|
|
|
4
4
|
import { Dialog, showDialog } from '@jupyterlab/apputils';
|
|
5
|
-
import { IChangedArgs
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
} from '@jupyterlab/
|
|
14
|
-
import { IFilterBoxProps, IScore } from '@jupyterlab/ui-components';
|
|
5
|
+
import type { IChangedArgs } from '@jupyterlab/coreutils';
|
|
6
|
+
import { PageConfig, PathExt } from '@jupyterlab/coreutils';
|
|
7
|
+
import type { IDocumentManager } from '@jupyterlab/docmanager';
|
|
8
|
+
import { shouldOverwrite } from '@jupyterlab/docmanager';
|
|
9
|
+
import type { Contents, KernelSpec, Session } from '@jupyterlab/services';
|
|
10
|
+
import type { IStateDB } from '@jupyterlab/statedb';
|
|
11
|
+
import type { ITranslator, TranslationBundle } from '@jupyterlab/translation';
|
|
12
|
+
import { nullTranslator } from '@jupyterlab/translation';
|
|
13
|
+
import type { IFilterBoxProps, IScore } from '@jupyterlab/ui-components';
|
|
15
14
|
import { ArrayExt, filter } from '@lumino/algorithm';
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
15
|
+
import type { ReadonlyJSONObject } from '@lumino/coreutils';
|
|
16
|
+
import { PromiseDelegate } from '@lumino/coreutils';
|
|
17
|
+
import type { IDisposable } from '@lumino/disposable';
|
|
18
18
|
import { Poll } from '@lumino/polling';
|
|
19
|
-
import { ISignal
|
|
19
|
+
import type { ISignal } from '@lumino/signaling';
|
|
20
|
+
import { Signal } from '@lumino/signaling';
|
|
20
21
|
|
|
21
22
|
/**
|
|
22
23
|
* The default duration of the auto-refresh in ms
|
|
@@ -633,10 +634,10 @@ export class FileBrowserModel implements IDisposable {
|
|
|
633
634
|
prefix + PathExt.dirname(oldValue.path) === path
|
|
634
635
|
? oldValue
|
|
635
636
|
: newValue &&
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
637
|
+
newValue.path &&
|
|
638
|
+
prefix + PathExt.dirname(newValue.path) === path
|
|
639
|
+
? newValue
|
|
640
|
+
: undefined;
|
|
640
641
|
|
|
641
642
|
// If either the old value or the new value is in the current path, update.
|
|
642
643
|
if (value) {
|
package/src/opendialog.ts
CHANGED
|
@@ -3,14 +3,16 @@
|
|
|
3
3
|
|
|
4
4
|
import { Dialog, setToolbar, ToolbarButton } from '@jupyterlab/apputils';
|
|
5
5
|
import { PathExt } from '@jupyterlab/coreutils';
|
|
6
|
-
import { IDocumentManager } from '@jupyterlab/docmanager';
|
|
7
|
-
import { Contents } from '@jupyterlab/services';
|
|
8
|
-
import { ITranslator
|
|
9
|
-
import {
|
|
6
|
+
import type { IDocumentManager } from '@jupyterlab/docmanager';
|
|
7
|
+
import type { Contents } from '@jupyterlab/services';
|
|
8
|
+
import type { ITranslator } from '@jupyterlab/translation';
|
|
9
|
+
import { nullTranslator } from '@jupyterlab/translation';
|
|
10
|
+
import type { IScore } from '@jupyterlab/ui-components';
|
|
11
|
+
import { newFolderIcon, refreshIcon } from '@jupyterlab/ui-components';
|
|
10
12
|
import { PanelLayout, Widget } from '@lumino/widgets';
|
|
11
13
|
import { FileBrowser } from './browser';
|
|
12
14
|
import { FilterFileBrowserModel } from './model';
|
|
13
|
-
import { IFileBrowserFactory } from './tokens';
|
|
15
|
+
import type { IFileBrowserFactory } from './tokens';
|
|
14
16
|
import { PromiseDelegate } from '@lumino/coreutils';
|
|
15
17
|
|
|
16
18
|
/**
|
|
@@ -30,16 +32,15 @@ export namespace FileDialog {
|
|
|
30
32
|
/**
|
|
31
33
|
* Options for the open directory dialog
|
|
32
34
|
*/
|
|
33
|
-
export interface IDirectoryOptions
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
'body' | 'buttons' | 'defaultButton'
|
|
40
|
-
>
|
|
35
|
+
export interface IDirectoryOptions extends Partial<
|
|
36
|
+
Pick<
|
|
37
|
+
Dialog.IOptions<Promise<Contents.IModel[]>>,
|
|
38
|
+
Exclude<
|
|
39
|
+
keyof Dialog.IOptions<Promise<Contents.IModel[]>>,
|
|
40
|
+
'body' | 'buttons' | 'defaultButton'
|
|
41
41
|
>
|
|
42
|
-
>
|
|
42
|
+
>
|
|
43
|
+
> {
|
|
43
44
|
/**
|
|
44
45
|
* Document manager
|
|
45
46
|
*/
|
package/src/upload.ts
CHANGED
|
@@ -2,15 +2,13 @@
|
|
|
2
2
|
// Distributed under the terms of the Modified BSD License.
|
|
3
3
|
|
|
4
4
|
import { showErrorMessage } from '@jupyterlab/apputils';
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
nullTranslator,
|
|
8
|
-
TranslationBundle
|
|
9
|
-
} from '@jupyterlab/translation';
|
|
5
|
+
import type { ITranslator, TranslationBundle } from '@jupyterlab/translation';
|
|
6
|
+
import { nullTranslator } from '@jupyterlab/translation';
|
|
10
7
|
import { fileUploadIcon, ToolbarButton } from '@jupyterlab/ui-components';
|
|
11
|
-
import { FileBrowserModel } from './model';
|
|
12
|
-
import { Contents } from '@jupyterlab/services';
|
|
13
|
-
import { ISignal
|
|
8
|
+
import type { FileBrowserModel } from './model';
|
|
9
|
+
import type { Contents } from '@jupyterlab/services';
|
|
10
|
+
import type { ISignal } from '@lumino/signaling';
|
|
11
|
+
import { Signal } from '@lumino/signaling';
|
|
14
12
|
|
|
15
13
|
/**
|
|
16
14
|
* A widget which provides an upload button.
|
package/src/uploadstatus.tsx
CHANGED
|
@@ -2,18 +2,15 @@
|
|
|
2
2
|
// Distributed under the terms of the Modified BSD License.
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { WidgetTracker } from '@jupyterlab/apputils';
|
|
6
|
-
import { IChangedArgs } from '@jupyterlab/coreutils';
|
|
5
|
+
import type { WidgetTracker } from '@jupyterlab/apputils';
|
|
6
|
+
import type { IChangedArgs } from '@jupyterlab/coreutils';
|
|
7
7
|
import { GroupItem, ProgressBar, TextItem } from '@jupyterlab/statusbar';
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
nullTranslator,
|
|
11
|
-
TranslationBundle
|
|
12
|
-
} from '@jupyterlab/translation';
|
|
8
|
+
import type { ITranslator, TranslationBundle } from '@jupyterlab/translation';
|
|
9
|
+
import { nullTranslator } from '@jupyterlab/translation';
|
|
13
10
|
import { VDomModel, VDomRenderer } from '@jupyterlab/ui-components';
|
|
14
11
|
import { ArrayExt } from '@lumino/algorithm';
|
|
15
12
|
import React from 'react';
|
|
16
|
-
import { FileBrowser, FileBrowserModel, IUploadModel } from '.';
|
|
13
|
+
import type { FileBrowser, FileBrowserModel, IUploadModel } from '.';
|
|
17
14
|
|
|
18
15
|
/**
|
|
19
16
|
* Half-spacing between items in the overall status item.
|