Skip to content

Commit ebd89cf

Browse files
authored
Fix filebrowser model path with mouse event (#16)
* Fix filebrowser model path with mouse event * Trigger test for all PRs * Clean code Correct CI * Fix manifest * Forget include in MANIFEST * No tests were added
1 parent cd7a495 commit ebd89cf

File tree

5 files changed

+62
-64
lines changed

5 files changed

+62
-64
lines changed

.github/workflows/build.yml

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,15 @@ on:
66
- master
77
pull_request:
88
branches:
9-
- master
9+
- '*'
1010

1111
defaults:
1212
run:
1313
shell: bash -l {0}
1414

1515
jobs:
1616
run:
17-
runs-on: ${{ matrix.os }}
18-
19-
strategy:
20-
fail-fast: false
21-
matrix:
22-
os: [ubuntu-latest]
23-
python-version: [3.8]
17+
runs-on: ubuntu-latest
2418

2519
steps:
2620
- name: Checkout
@@ -29,15 +23,19 @@ jobs:
2923
- name: Install Mamba
3024
uses: mamba-org/provision-with-micromamba@main
3125

32-
- name: Install jupyterlab-unfold
33-
run: pip install .
26+
- name: Build the extension
27+
run: |
28+
set -eux
29+
yarn
30+
yarn run eslint:check
31+
python -m pip install .
3432
35-
- name: Check installation files
33+
- name: Check installation
3634
run: |
3735
test -d $CONDA_PREFIX/share/jupyter/labextensions/jupyterlab-unfold
3836
test -f $CONDA_PREFIX/share/jupyter/labextensions/jupyterlab-unfold/package.json
37+
38+
jupyter labextension list 2>&1 | grep -ie "jupyterlab-unfold.*OK"
39+
python -m jupyterlab.browser_check
3940
40-
- name: Lint check
41-
run: |
42-
yarn install
43-
yarn eslint:check
41+
check-manifest -v

MANIFEST.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,15 @@ include install.json
88
include ts*.json
99
include yarn.lock
1010

11+
include images/screenshot.png
12+
include environment.yml
13+
1114
graft jupyterlab-unfold/labextension
1215

1316
# Javascript files
1417
graft src
1518
graft style
19+
include schema/jupyterlab-unfold-settings.json
1620
prune **/node_modules
1721
prune lib
1822
prune binder

environment.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ name: jupyterlab-unfold
22
channels:
33
- conda-forge
44
dependencies:
5+
- check-manifest
56
- jupyterlab >=3.1,<4
67
- yarn
78
- jupyter-packaging

src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ const extension: JupyterFrontEndPlugin<IFileBrowserFactory> = {
5656
manager: docManager,
5757
driveName: options.driveName || '',
5858
refreshInterval: options.refreshInterval,
59-
app,
6059
state:
6160
options.state === null
6261
? undefined

src/unfold.ts

Lines changed: 44 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { DOMUtils, showErrorMessage } from '@jupyterlab/apputils';
1212

1313
import { JupyterFrontEnd } from '@jupyterlab/application';
1414

15-
import { Contents, ContentsManager } from '@jupyterlab/services';
15+
import { Contents } from '@jupyterlab/services';
1616

1717
import { DocumentRegistry } from '@jupyterlab/docregistry';
1818

@@ -85,21 +85,6 @@ export namespace DirTreeListing {
8585
}
8686
}
8787

88-
/**
89-
* The namespace for the `FilterFileTreeBrowserModel` class statics.
90-
*/
91-
export namespace FilterFileTreeBrowserModel {
92-
/**
93-
* An options object for initializing a file tree listing widget.
94-
*/
95-
export interface IOptions extends FilterFileBrowserModel.IOptions {
96-
/**
97-
* The JupyterFrontEnd app.
98-
*/
99-
app: JupyterFrontEnd;
100-
}
101-
}
102-
10388
/**
10489
* The namespace for the `FileTreeBrowser` class statics.
10590
*/
@@ -161,7 +146,7 @@ export class FileTreeRenderer extends DirListing.Renderer {
161146
): void {
162147
super.updateItemNode(node, model, fileType, translator, hiddenColumns);
163148

164-
if (model.type === 'directory' && this.model.isOpen(model)) {
149+
if (model.type === 'directory' && this.model.isOpen(model.path)) {
165150
const iconContainer = DOMUtils.findElement(
166151
node,
167152
'jp-DirListing-itemIcon'
@@ -222,26 +207,6 @@ export class DirTreeListing extends DirListing {
222207
return this._model;
223208
}
224209

225-
protected async handleFileSelect(event: MouseEvent): Promise<void> {
226-
super.handleFileSelect(event);
227-
const entry = this.modelForClick(event);
228-
229-
if (entry) {
230-
if (entry.type === 'directory') {
231-
this.model.path = '/' + entry.path;
232-
233-
if (
234-
this._singleClickToUnfold &&
235-
Object.keys(this.selection).length === 1
236-
) {
237-
this.model.toggle(entry.path);
238-
}
239-
} else {
240-
this.model.path = '/' + PathExt.dirname(entry.path);
241-
}
242-
}
243-
}
244-
245210
private async _eventDblClick(event: MouseEvent): Promise<void> {
246211
const entry = this.modelForClick(event);
247212

@@ -389,24 +354,56 @@ export class DirTreeListing extends DirListing {
389354
case 'lm-drop':
390355
this._eventDrop(event as IDragEvent);
391356
break;
357+
case 'mousedown':
358+
super.handleEvent(event);
359+
this._changeModelPath(event as MouseEvent);
360+
break;
392361
default:
393362
super.handleEvent(event);
394363
break;
395364
}
396365
}
397366

367+
/**
368+
* Change the model path on each 'mousedown' event
369+
*
370+
* Note: This allow to change the path to the root when the user
371+
* is clicking on an empty space.
372+
*/
373+
private _changeModelPath(event: MouseEvent): void {
374+
const entry = this.modelForClick(event);
375+
376+
if (entry) {
377+
if (entry.type === 'directory') {
378+
this.model.path = '/' + entry.path;
379+
380+
if (
381+
this._singleClickToUnfold &&
382+
(event.button === 0 || // State toggled on main button
383+
(event.button === 2 && !this.model.isOpen(entry.path)) || // State toggled on right click if folder is closed
384+
event.type === 'click') // State toggled on click and double click
385+
) {
386+
this.model.toggle(entry.path);
387+
}
388+
} else {
389+
this.model.path = '/' + PathExt.dirname(entry.path);
390+
}
391+
} else {
392+
this.model.path = this.model.rootPath;
393+
}
394+
}
395+
398396
private _singleClickToUnfold = true;
399397
}
400398

401399
/**
402400
* Filetree browser model with optional filter on element.
403401
*/
404402
export class FilterFileTreeBrowserModel extends FilterFileBrowserModel {
405-
constructor(options: FilterFileTreeBrowserModel.IOptions) {
403+
constructor(options: FilterFileBrowserModel.IOptions) {
406404
super(options);
407405

408-
this.app = options.app;
409-
this.contentManager = this.app.serviceManager.contents;
406+
this.contentManager = this.manager.services.contents;
410407
this.basePath = '.';
411408

412409
this._savedState = options.state || null;
@@ -523,15 +520,15 @@ export class FilterFileTreeBrowserModel extends FilterFileBrowserModel {
523520
}
524521

525522
/**
526-
* Check whether a directory entry is open or not.
523+
* Check whether a directory path is opened or not.
527524
*
528-
* @param model - The given entry.
525+
* @param path - The given path
529526
*
530-
* @returns Whether the directory is open or not.
527+
* @returns Whether the directory is opened or not.
531528
*
532529
*/
533-
isOpen(model: Contents.IModel): boolean {
534-
return !!this.openState[model.path];
530+
isOpen(path: string): boolean {
531+
return !!this.openState[path];
535532
}
536533

537534
private async fetchContent(
@@ -555,7 +552,7 @@ export class FilterFileTreeBrowserModel extends FilterFileBrowserModel {
555552

556553
const isOpen =
557554
(pathToUpdate && pathToUpdate.startsWith('/' + entry.path)) ||
558-
this.isOpen(entry);
555+
this.isOpen(entry.path);
559556

560557
if (isOpen) {
561558
const subEntryContent = await this.fetchContent(
@@ -602,8 +599,7 @@ export class FilterFileTreeBrowserModel extends FilterFileBrowserModel {
602599
private _stateKey: string | null = null;
603600
private _path = '.';
604601
private basePath: string;
605-
private contentManager: ContentsManager;
606-
private app: JupyterFrontEnd;
602+
private contentManager: Contents.IManager;
607603
private openState: { [path: string]: boolean } = {};
608604
}
609605

0 commit comments

Comments
 (0)