Skip to content

Commit f614f7c

Browse files
authored
Move handling of the file browser settings to a separate plugin, enable file browser single click navigation (jupyter#7481)
* Move handling of the file browser settings to a separate plugin * fix typo * optional settingregistry * remove upstream filebrowser plugin * fix file actions buttons * hold ctrl * update changelog * wording * remove console.log * fix comments
1 parent 2a8e579 commit f614f7c

File tree

4 files changed

+61
-21
lines changed

4 files changed

+61
-21
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,13 @@ The file browser now:
4040

4141
- supports resizing the columns and remembers the column sizes after reloading JupyterLab
4242
- supports uploading folders by drag-and-drop
43-
- supports navigation with a single click (opt-in)
43+
- supports navigation with a single click
4444
- adds a file filter collapsed by default (funnel icon)
4545

4646
![a screenshot showing that it's now possible to resize the file browser columns](https://github.com/user-attachments/assets/b0d9cd0a-2828-43f7-a922-e8b271e5f7fc)
4747

48+
In Jupyter Notebook, the single click navigation is enabled by default. If you would like to disable it to get the same experience as in JupyterLab, go to `Settings → File Browser` and make sure "Navigate files and directories with single click" is unchecked.
49+
4850
### Improved kernel and server interactions
4951

5052
The previous release enabled connecting to external kernels, such as those spawned by a third-party application like Blender. In this release the kernel selector dialog was improved to also show the external kernels.

app/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,6 @@
310310
"@jupyterlab/filebrowser-extension:file-upload-status",
311311
"@jupyterlab/filebrowser-extension:open-with",
312312
"@jupyterlab/filebrowser-extension:search",
313-
"@jupyterlab/filebrowser-extension:settings",
314313
"@jupyterlab/filebrowser-extension:share-file"
315314
],
316315
"@jupyter-notebook/tree-extension": true,

packages/tree-extension/src/index.ts

Lines changed: 56 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,9 @@ const fileActions: JupyterFrontEndPlugin<void> = {
170170
selectionChanged.emit(void 0);
171171
};
172172
});
173+
browser.model.pathChanged.connect(() => {
174+
selectionChanged.emit(void 0);
175+
});
173176

174177
// Create a toolbar item that adds buttons to the file browser toolbar
175178
// to perform actions on the files
@@ -186,6 +189,58 @@ const fileActions: JupyterFrontEndPlugin<void> = {
186189
},
187190
};
188191

192+
/**
193+
* A plugin to set the default file browser settings.
194+
*/
195+
const fileBrowserSettings: JupyterFrontEndPlugin<void> = {
196+
id: '@jupyter-notebook/tree-extension:settings',
197+
description: 'Set up the default file browser settings',
198+
requires: [IDefaultFileBrowser],
199+
optional: [ISettingRegistry],
200+
autoStart: true,
201+
activate: (
202+
app: JupyterFrontEnd,
203+
browser: IDefaultFileBrowser,
204+
settingRegistry: ISettingRegistry | null
205+
) => {
206+
// Default config for notebook.
207+
// This is a different set of defaults than JupyterLab.
208+
const defaultFileBrowserConfig = {
209+
navigateToCurrentDirectory: false,
210+
singleClickNavigation: true,
211+
showLastModifiedColumn: true,
212+
showFileSizeColumn: true,
213+
showHiddenFiles: false,
214+
showFileCheckboxes: true,
215+
sortNotebooksFirst: true,
216+
showFullPath: false,
217+
};
218+
219+
// Apply defaults on plugin activation
220+
let key: keyof typeof defaultFileBrowserConfig;
221+
for (key in defaultFileBrowserConfig) {
222+
browser[key] = defaultFileBrowserConfig[key];
223+
}
224+
225+
if (settingRegistry) {
226+
void settingRegistry.load(FILE_BROWSER_PLUGIN_ID).then((settings) => {
227+
function onSettingsChanged(settings: ISettingRegistry.ISettings): void {
228+
let key: keyof typeof defaultFileBrowserConfig;
229+
for (key in defaultFileBrowserConfig) {
230+
const value = settings.get(key).user as boolean;
231+
// only set the setting if it is defined by the user
232+
if (value !== undefined) {
233+
browser[key] = value;
234+
}
235+
}
236+
}
237+
settings.changed.connect(onSettingsChanged);
238+
onSettingsChanged(settings);
239+
});
240+
}
241+
},
242+
};
243+
189244
/**
190245
* A plugin to add the file filter toggle command to the palette
191246
*/
@@ -360,25 +415,6 @@ const notebookTreeWidget: JupyterFrontEndPlugin<INotebookTree> = {
360415
nbTreeWidget.tabBar.addTab(running.title);
361416
}
362417

363-
const settings = settingRegistry.load(FILE_BROWSER_PLUGIN_ID);
364-
Promise.all([settings, app.restored])
365-
.then(([settings]) => {
366-
// Set Notebook 7 defaults if there is no user setting override
367-
[
368-
'showFileCheckboxes',
369-
'showFileSizeColumn',
370-
'sortNotebooksFirst',
371-
'showFullPath',
372-
].forEach((setting) => {
373-
if (settings.user[setting] === undefined) {
374-
void settings.set(setting, true);
375-
}
376-
});
377-
})
378-
.catch((reason: Error) => {
379-
console.error(reason.message);
380-
});
381-
382418
app.shell.add(nbTreeWidget, 'main', { rank: 100 });
383419

384420
// add a separate tab for each setting editor
@@ -419,6 +455,7 @@ const notebookTreeWidget: JupyterFrontEndPlugin<INotebookTree> = {
419455
const plugins: JupyterFrontEndPlugin<any>[] = [
420456
createNew,
421457
fileActions,
458+
fileBrowserSettings,
422459
fileFilterCommand,
423460
loadPlugins,
424461
openFileBrowser,

ui-tests/test/filebrowser.spec.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ test.describe('File Browser', () => {
2020
test('Select one folder', async ({ page, tmpPath }) => {
2121
await page.filebrowser.refresh();
2222

23+
await page.keyboard.down('Control');
2324
await page.getByText('folder1').last().click();
2425

2526
const toolbar = page.getByRole('toolbar');
@@ -31,6 +32,7 @@ test.describe('File Browser', () => {
3132
test('Select one file', async ({ page, tmpPath }) => {
3233
await page.filebrowser.refresh();
3334

35+
await page.keyboard.down('Control');
3436
await page.getByText('empty.ipynb').last().click();
3537

3638
const toolbar = page.getByRole('toolbar');

0 commit comments

Comments
 (0)