@jupyterlab/filebrowser 4.2.0-beta.1 → 4.2.0-beta.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 +2 -2
- package/lib/browser.js +2 -2
- package/lib/crumbs.d.ts +1 -1
- package/lib/crumbs.js +1 -1
- package/lib/listing.d.ts +31 -3
- package/lib/listing.js +100 -48
- package/lib/listing.js.map +1 -1
- package/lib/model.d.ts +2 -2
- package/lib/model.js +13 -15
- package/lib/model.js.map +1 -1
- package/lib/uploadstatus.js +1 -1
- package/package.json +11 -13
- package/src/browser.ts +2 -2
- package/src/crumbs.ts +1 -1
- package/src/listing.ts +161 -64
- package/src/model.ts +13 -20
- package/src/uploadstatus.tsx +1 -1
- package/style/base.css +8 -4
package/lib/browser.d.ts
CHANGED
|
@@ -161,8 +161,8 @@ export declare class FileBrowser extends SidePanel {
|
|
|
161
161
|
* Given a drive name and a local path, return the full
|
|
162
162
|
* drive path which includes the drive name and the local path.
|
|
163
163
|
*
|
|
164
|
-
* @param driveName
|
|
165
|
-
* @param localPath
|
|
164
|
+
* @param driveName the name of the drive
|
|
165
|
+
* @param localPath the local path on the drive.
|
|
166
166
|
*
|
|
167
167
|
* @returns the full drive path
|
|
168
168
|
*/
|
package/lib/browser.js
CHANGED
|
@@ -353,8 +353,8 @@ export class FileBrowser extends SidePanel {
|
|
|
353
353
|
* Given a drive name and a local path, return the full
|
|
354
354
|
* drive path which includes the drive name and the local path.
|
|
355
355
|
*
|
|
356
|
-
* @param driveName
|
|
357
|
-
* @param localPath
|
|
356
|
+
* @param driveName the name of the drive
|
|
357
|
+
* @param localPath the local path on the drive.
|
|
358
358
|
*
|
|
359
359
|
* @returns the full drive path
|
|
360
360
|
*/
|
package/lib/crumbs.d.ts
CHANGED
package/lib/crumbs.js
CHANGED
package/lib/listing.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Time } from '@jupyterlab/coreutils';
|
|
1
2
|
import { DocumentRegistry } from '@jupyterlab/docregistry';
|
|
2
3
|
import { Contents } from '@jupyterlab/services';
|
|
3
4
|
import { ITranslator, TranslationBundle } from '@jupyterlab/translation';
|
|
@@ -13,7 +14,7 @@ export declare class DirListing extends Widget {
|
|
|
13
14
|
/**
|
|
14
15
|
* Construct a new file browser directory listing widget.
|
|
15
16
|
*
|
|
16
|
-
* @param
|
|
17
|
+
* @param options The constructor options
|
|
17
18
|
*/
|
|
18
19
|
constructor(options: DirListing.IOptions);
|
|
19
20
|
/**
|
|
@@ -190,6 +191,9 @@ export declare class DirListing extends Widget {
|
|
|
190
191
|
* A message handler invoked on an `'after-show'` message.
|
|
191
192
|
*/
|
|
192
193
|
protected onAfterShow(msg: Message): void;
|
|
194
|
+
private _updateModifiedSize;
|
|
195
|
+
protected updateModified(items: Contents.IModel[], nodes: HTMLElement[]): void;
|
|
196
|
+
protected updateNodes(items: Contents.IModel[], nodes: HTMLElement[]): void;
|
|
193
197
|
/**
|
|
194
198
|
* A handler invoked on an `'update-request'` message.
|
|
195
199
|
*/
|
|
@@ -369,6 +373,8 @@ export declare class DirListing extends Widget {
|
|
|
369
373
|
private _hiddenColumns;
|
|
370
374
|
private _sortNotebooksFirst;
|
|
371
375
|
private _focusIndex;
|
|
376
|
+
private _modifiedWidth;
|
|
377
|
+
private _modifiedStyle;
|
|
372
378
|
}
|
|
373
379
|
/**
|
|
374
380
|
* The namespace for the `DirListing` class statics.
|
|
@@ -457,6 +463,16 @@ export declare namespace DirListing {
|
|
|
457
463
|
* @returns A new DOM node to use as a content item.
|
|
458
464
|
*/
|
|
459
465
|
createItemNode(hiddenColumns?: Set<DirListing.ToggleableColumn>): HTMLElement;
|
|
466
|
+
/**
|
|
467
|
+
* Update an item's last modified date.
|
|
468
|
+
*
|
|
469
|
+
* @param modified - Element containing the file's last modified date.
|
|
470
|
+
*
|
|
471
|
+
* @param modifiedDate - String representation of the last modified date.
|
|
472
|
+
*
|
|
473
|
+
* @param modifiedStyle - The date style for the modified column: narrow, short, or long
|
|
474
|
+
*/
|
|
475
|
+
updateItemModified?(modified: HTMLElement, modifiedDate: string, modifiedStyle: Time.HumanStyle): void;
|
|
460
476
|
/**
|
|
461
477
|
* Update an item node to reflect the current state of a model.
|
|
462
478
|
*
|
|
@@ -464,9 +480,11 @@ export declare namespace DirListing {
|
|
|
464
480
|
*
|
|
465
481
|
* @param model - The model object to use for the item state.
|
|
466
482
|
*
|
|
483
|
+
* @param modifiedStyle - The date style for the modified column: narrow, short, or long
|
|
484
|
+
*
|
|
467
485
|
* @param fileType - The file type of the item, if applicable.
|
|
468
486
|
*/
|
|
469
|
-
updateItemNode(node: HTMLElement, model: Contents.IModel, fileType?: DocumentRegistry.IFileType, translator?: ITranslator, hiddenColumns?: Set<DirListing.ToggleableColumn>, selected?: boolean): void;
|
|
487
|
+
updateItemNode(node: HTMLElement, model: Contents.IModel, fileType?: DocumentRegistry.IFileType, translator?: ITranslator, hiddenColumns?: Set<DirListing.ToggleableColumn>, selected?: boolean, modifiedStyle?: Time.HumanStyle): void;
|
|
470
488
|
/**
|
|
471
489
|
* Get the node containing the file name.
|
|
472
490
|
*
|
|
@@ -549,6 +567,16 @@ export declare namespace DirListing {
|
|
|
549
567
|
alwaysVisible: boolean;
|
|
550
568
|
headerNode?: boolean;
|
|
551
569
|
}): HTMLElement;
|
|
570
|
+
/**
|
|
571
|
+
* Update an item's last modified date.
|
|
572
|
+
*
|
|
573
|
+
* @param modified - Element containing the file's last modified date.
|
|
574
|
+
*
|
|
575
|
+
* @param modifiedDate - String representation of the last modified date.
|
|
576
|
+
*
|
|
577
|
+
* @param modifiedStyle - The date style for the modified column: narrow, short, or long
|
|
578
|
+
*/
|
|
579
|
+
updateItemModified(modified: HTMLElement, modifiedDate: string, modifiedStyle: Time.HumanStyle): void;
|
|
552
580
|
/**
|
|
553
581
|
* Update an item node to reflect the current state of a model.
|
|
554
582
|
*
|
|
@@ -559,7 +587,7 @@ export declare namespace DirListing {
|
|
|
559
587
|
* @param fileType - The file type of the item, if applicable.
|
|
560
588
|
*
|
|
561
589
|
*/
|
|
562
|
-
updateItemNode(node: HTMLElement, model: Contents.IModel, fileType?: DocumentRegistry.IFileType, translator?: ITranslator, hiddenColumns?: Set<DirListing.ToggleableColumn>, selected?: boolean): void;
|
|
590
|
+
updateItemNode(node: HTMLElement, model: Contents.IModel, fileType?: DocumentRegistry.IFileType, translator?: ITranslator, hiddenColumns?: Set<DirListing.ToggleableColumn>, selected?: boolean, modifiedStyle?: Time.HumanStyle): void;
|
|
563
591
|
/**
|
|
564
592
|
* Get the node containing the file name.
|
|
565
593
|
*
|
package/lib/listing.js
CHANGED
|
@@ -154,7 +154,7 @@ export class DirListing extends Widget {
|
|
|
154
154
|
/**
|
|
155
155
|
* Construct a new file browser directory listing widget.
|
|
156
156
|
*
|
|
157
|
-
* @param
|
|
157
|
+
* @param options The constructor options
|
|
158
158
|
*/
|
|
159
159
|
constructor(options) {
|
|
160
160
|
super({
|
|
@@ -194,6 +194,8 @@ export class DirListing extends Widget {
|
|
|
194
194
|
this._editNode.className = EDITOR_CLASS;
|
|
195
195
|
this._manager = this._model.manager;
|
|
196
196
|
this._renderer = options.renderer || DirListing.defaultRenderer;
|
|
197
|
+
// Get the width of the "modified" column
|
|
198
|
+
this._updateModifiedSize(this.node);
|
|
197
199
|
const headerNode = DOMUtils.findElement(this.node, HEADER_CLASS);
|
|
198
200
|
// hide the file size column by default
|
|
199
201
|
this._hiddenColumns.add('file_size');
|
|
@@ -697,11 +699,78 @@ export class DirListing extends Widget {
|
|
|
697
699
|
this.update();
|
|
698
700
|
}
|
|
699
701
|
}
|
|
702
|
+
// Update the modified column's size
|
|
703
|
+
_updateModifiedSize(node) {
|
|
704
|
+
var _a;
|
|
705
|
+
const modified = DOMUtils.findElement(node, ITEM_MODIFIED_CLASS);
|
|
706
|
+
this._modifiedWidth = (_a = modified === null || modified === void 0 ? void 0 : modified.getBoundingClientRect().width) !== null && _a !== void 0 ? _a : 83;
|
|
707
|
+
this._modifiedStyle =
|
|
708
|
+
this._modifiedWidth < 90
|
|
709
|
+
? 'narrow'
|
|
710
|
+
: this._modifiedWidth > 110
|
|
711
|
+
? 'long'
|
|
712
|
+
: 'short';
|
|
713
|
+
}
|
|
714
|
+
// Update only the modified dates.
|
|
715
|
+
updateModified(items, nodes) {
|
|
716
|
+
items.forEach((item, i) => {
|
|
717
|
+
const node = nodes[i];
|
|
718
|
+
if (item.last_modified) {
|
|
719
|
+
const modified = DOMUtils.findElement(node, ITEM_MODIFIED_CLASS);
|
|
720
|
+
if (this.renderer.updateItemModified !== undefined) {
|
|
721
|
+
this.renderer.updateItemModified(modified, item.last_modified, this._modifiedStyle);
|
|
722
|
+
}
|
|
723
|
+
else {
|
|
724
|
+
DirListing.defaultRenderer.updateItemModified(modified, item.last_modified, this._modifiedStyle);
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
});
|
|
728
|
+
}
|
|
729
|
+
// Update item nodes based on widget state.
|
|
730
|
+
updateNodes(items, nodes) {
|
|
731
|
+
var _a;
|
|
732
|
+
items.forEach((item, i) => {
|
|
733
|
+
const node = nodes[i];
|
|
734
|
+
const ft = this._manager.registry.getFileTypeForModel(item);
|
|
735
|
+
this.renderer.updateItemNode(node, item, ft, this.translator, this._hiddenColumns, this.selection[item.path], this._modifiedStyle);
|
|
736
|
+
if (this.selection[item.path] &&
|
|
737
|
+
this._isCut &&
|
|
738
|
+
this._model.path === this._prevPath) {
|
|
739
|
+
node.classList.add(CUT_CLASS);
|
|
740
|
+
}
|
|
741
|
+
// add metadata to the node
|
|
742
|
+
node.setAttribute('data-isdir', item.type === 'directory' ? 'true' : 'false');
|
|
743
|
+
});
|
|
744
|
+
// Handle the selectors on the widget node.
|
|
745
|
+
const selected = Object.keys(this.selection).length;
|
|
746
|
+
if (selected) {
|
|
747
|
+
this.addClass(SELECTED_CLASS);
|
|
748
|
+
if (selected > 1) {
|
|
749
|
+
this.addClass(MULTI_SELECTED_CLASS);
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
// Handle file session statuses.
|
|
753
|
+
const paths = items.map(item => item.path);
|
|
754
|
+
for (const session of this._model.sessions()) {
|
|
755
|
+
const index = ArrayExt.firstIndexOf(paths, session.path);
|
|
756
|
+
const node = nodes[index];
|
|
757
|
+
// Node may have been filtered out.
|
|
758
|
+
if (node) {
|
|
759
|
+
let name = (_a = session.kernel) === null || _a === void 0 ? void 0 : _a.name;
|
|
760
|
+
const specs = this._model.specs;
|
|
761
|
+
node.classList.add(RUNNING_CLASS);
|
|
762
|
+
if (specs && name) {
|
|
763
|
+
const spec = specs.kernelspecs[name];
|
|
764
|
+
name = spec ? spec.display_name : this._trans.__('unknown');
|
|
765
|
+
}
|
|
766
|
+
node.title = this._trans.__('%1\nKernel: %2', node.title, name);
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
}
|
|
700
770
|
/**
|
|
701
771
|
* A handler invoked on an `'update-request'` message.
|
|
702
772
|
*/
|
|
703
773
|
onUpdateRequest(msg) {
|
|
704
|
-
var _a;
|
|
705
774
|
this._isDirty = false;
|
|
706
775
|
// Fetch common variables.
|
|
707
776
|
const items = this._sortedItems;
|
|
@@ -758,49 +827,18 @@ export class DirListing extends Widget {
|
|
|
758
827
|
? trans.__('Deselect all files and directories')
|
|
759
828
|
: trans.__('Select all files and directories'));
|
|
760
829
|
}
|
|
761
|
-
|
|
762
|
-
items.forEach((item, i) => {
|
|
763
|
-
const node = nodes[i];
|
|
764
|
-
const ft = this._manager.registry.getFileTypeForModel(item);
|
|
765
|
-
renderer.updateItemNode(node, item, ft, this.translator, this._hiddenColumns, this.selection[item.path]);
|
|
766
|
-
if (this.selection[item.path] &&
|
|
767
|
-
this._isCut &&
|
|
768
|
-
this._model.path === this._prevPath) {
|
|
769
|
-
node.classList.add(CUT_CLASS);
|
|
770
|
-
}
|
|
771
|
-
// add metadata to the node
|
|
772
|
-
node.setAttribute('data-isdir', item.type === 'directory' ? 'true' : 'false');
|
|
773
|
-
});
|
|
774
|
-
// Handle the selectors on the widget node.
|
|
775
|
-
const selected = Object.keys(this.selection).length;
|
|
776
|
-
if (selected) {
|
|
777
|
-
this.addClass(SELECTED_CLASS);
|
|
778
|
-
if (selected > 1) {
|
|
779
|
-
this.addClass(MULTI_SELECTED_CLASS);
|
|
780
|
-
}
|
|
781
|
-
}
|
|
782
|
-
// Handle file session statuses.
|
|
783
|
-
const paths = items.map(item => item.path);
|
|
784
|
-
for (const session of this._model.sessions()) {
|
|
785
|
-
const index = ArrayExt.firstIndexOf(paths, session.path);
|
|
786
|
-
const node = nodes[index];
|
|
787
|
-
// Node may have been filtered out.
|
|
788
|
-
if (node) {
|
|
789
|
-
let name = (_a = session.kernel) === null || _a === void 0 ? void 0 : _a.name;
|
|
790
|
-
const specs = this._model.specs;
|
|
791
|
-
node.classList.add(RUNNING_CLASS);
|
|
792
|
-
if (specs && name) {
|
|
793
|
-
const spec = specs.kernelspecs[name];
|
|
794
|
-
name = spec ? spec.display_name : this._trans.__('unknown');
|
|
795
|
-
}
|
|
796
|
-
node.title = this._trans.__('%1\nKernel: %2', node.title, name);
|
|
797
|
-
}
|
|
798
|
-
}
|
|
830
|
+
this.updateNodes(items, nodes);
|
|
799
831
|
this._prevPath = this._model.path;
|
|
800
832
|
}
|
|
801
833
|
onResize(msg) {
|
|
802
834
|
const { width } = msg.width === -1 ? this.node.getBoundingClientRect() : msg;
|
|
803
835
|
this.toggleClass('jp-DirListing-narrow', width < 250);
|
|
836
|
+
// Rerender item nodes' modified dates, if the modified style has changed.
|
|
837
|
+
const oldModifiedStyle = this._modifiedStyle;
|
|
838
|
+
this._updateModifiedSize(this.node);
|
|
839
|
+
if (oldModifiedStyle !== this._modifiedStyle) {
|
|
840
|
+
this.updateModified(this._sortedItems, this._items);
|
|
841
|
+
}
|
|
804
842
|
}
|
|
805
843
|
setColumnVisibility(name, visible) {
|
|
806
844
|
if (visible) {
|
|
@@ -1792,7 +1830,7 @@ export class DirListing extends Widget {
|
|
|
1792
1830
|
const trans = translator.load('jupyterlab');
|
|
1793
1831
|
const name = this.createHeaderItemNode(trans.__('Name'));
|
|
1794
1832
|
const narrow = document.createElement('div');
|
|
1795
|
-
const modified = this.createHeaderItemNode(trans.__('
|
|
1833
|
+
const modified = this.createHeaderItemNode(trans.__('Modified'));
|
|
1796
1834
|
const fileSize = this.createHeaderItemNode(trans.__('File Size'));
|
|
1797
1835
|
name.classList.add(NAME_ID_CLASS);
|
|
1798
1836
|
name.classList.add(SELECTED_CLASS);
|
|
@@ -2000,6 +2038,25 @@ export class DirListing extends Widget {
|
|
|
2000
2038
|
labelWrapper.appendChild(checkbox);
|
|
2001
2039
|
return labelWrapper;
|
|
2002
2040
|
}
|
|
2041
|
+
/**
|
|
2042
|
+
* Update an item's last modified date.
|
|
2043
|
+
*
|
|
2044
|
+
* @param modified - Element containing the file's last modified date.
|
|
2045
|
+
*
|
|
2046
|
+
* @param modifiedDate - String representation of the last modified date.
|
|
2047
|
+
*
|
|
2048
|
+
* @param modifiedStyle - The date style for the modified column: narrow, short, or long
|
|
2049
|
+
*/
|
|
2050
|
+
updateItemModified(modified, modifiedDate, modifiedStyle) {
|
|
2051
|
+
let modText = '';
|
|
2052
|
+
let modTitle = '';
|
|
2053
|
+
const parsedDate = new Date(modifiedDate);
|
|
2054
|
+
// Render the date in one of multiple formats, depending on the container's size
|
|
2055
|
+
modText = Time.formatHuman(parsedDate, modifiedStyle);
|
|
2056
|
+
modTitle = Time.format(parsedDate);
|
|
2057
|
+
modified.textContent = modText;
|
|
2058
|
+
modified.title = modTitle;
|
|
2059
|
+
}
|
|
2003
2060
|
/**
|
|
2004
2061
|
* Update an item node to reflect the current state of a model.
|
|
2005
2062
|
*
|
|
@@ -2010,7 +2067,7 @@ export class DirListing extends Widget {
|
|
|
2010
2067
|
* @param fileType - The file type of the item, if applicable.
|
|
2011
2068
|
*
|
|
2012
2069
|
*/
|
|
2013
|
-
updateItemNode(node, model, fileType, translator, hiddenColumns, selected) {
|
|
2070
|
+
updateItemNode(node, model, fileType, translator, hiddenColumns, selected, modifiedStyle) {
|
|
2014
2071
|
if (selected) {
|
|
2015
2072
|
node.classList.add(SELECTED_CLASS);
|
|
2016
2073
|
}
|
|
@@ -2109,14 +2166,9 @@ export class DirListing extends Widget {
|
|
|
2109
2166
|
checkbox.setAttribute('aria-label', ariaLabel);
|
|
2110
2167
|
checkbox.checked = selected !== null && selected !== void 0 ? selected : false;
|
|
2111
2168
|
}
|
|
2112
|
-
let modText = '';
|
|
2113
|
-
let modTitle = '';
|
|
2114
2169
|
if (model.last_modified) {
|
|
2115
|
-
|
|
2116
|
-
modTitle = Time.format(new Date(model.last_modified));
|
|
2170
|
+
this.updateItemModified(modified, model.last_modified, modifiedStyle !== null && modifiedStyle !== void 0 ? modifiedStyle : 'short');
|
|
2117
2171
|
}
|
|
2118
|
-
modified.textContent = modText;
|
|
2119
|
-
modified.title = modTitle;
|
|
2120
2172
|
}
|
|
2121
2173
|
/**
|
|
2122
2174
|
* Get the node containing the file name.
|