Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace launcher plugin #61

Merged
merged 3 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"@jupyterlab/apputils": "^4.2.0",
"@jupyterlab/coreutils": "^6.2.0",
"@jupyterlab/filebrowser": "^4.2.0",
"@jupyterlab/launcher": "^4.3.3",
"@jupyterlab/services": "^7.2.0",
"@jupyterlab/settingregistry": "^4.2.0",
"@jupyterlab/translation": "^4.2.0",
Expand Down Expand Up @@ -113,7 +114,10 @@
},
"extension": true,
"outputDir": "jupyter_drives/labextension",
"schemaDir": "schema"
"schemaDir": "schema",
"disabledExtensions": [
"@jupyterlab/launcher-extension:plugin"
]
},
"eslintIgnore": [
"node_modules",
Expand Down Expand Up @@ -175,7 +179,8 @@
"all"
],
"eqeqeq": "error",
"prefer-arrow-callback": "error"
"prefer-arrow-callback": "error",
"prefer-const": "off"
}
},
"prettier": {
Expand Down
6 changes: 4 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { DriveIcon, driveBrowserIcon } from './icons';
import { Drive } from './contents';
import { getDrivesList, setListingLimit } from './requests';
import { IDriveInfo, IDrivesList } from './token';
import { launcherPlugin } from './launcher';

/**
* The command IDs used by the driveBrowser plugin.
Expand Down Expand Up @@ -230,7 +231,7 @@ const driveFileBrowser: JupyterFrontEndPlugin<void> = {
driveBrowser.node.setAttribute('aria-label', 'Drive Browser Section');
driveBrowser.title.icon = driveBrowserIcon;
driveBrowser.title.caption = 'Drive File Browser';
driveBrowser.id = 'Drive-File-Browser';
driveBrowser.id = 'drive-file-browser';

void Private.restoreBrowser(driveBrowser, commands, router, tree, labShell);

Expand Down Expand Up @@ -313,7 +314,8 @@ const driveFileBrowser: JupyterFrontEndPlugin<void> = {
const plugins: JupyterFrontEndPlugin<any>[] = [
driveFileBrowser,
drivesListProvider,
openDriveDialogPlugin
openDriveDialogPlugin,
launcherPlugin
];
export default plugins;

Expand Down
156 changes: 156 additions & 0 deletions src/launcher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import {
ILabShell,
JupyterFrontEnd,
JupyterFrontEndPlugin
} from '@jupyterlab/application';
import { ICommandPalette, MainAreaWidget } from '@jupyterlab/apputils';
import { FileBrowserModel, IFileBrowserFactory } from '@jupyterlab/filebrowser';
import { ILauncher, Launcher, LauncherModel } from '@jupyterlab/launcher';
import { ITranslator } from '@jupyterlab/translation';
import { addIcon, launcherIcon } from '@jupyterlab/ui-components';
import { find } from '@lumino/algorithm';
import { ReadonlyPartialJSONObject } from '@lumino/coreutils';
import { DockPanel, TabBar, Widget } from '@lumino/widgets';

/**
* The command IDs used by the launcher plugin.
*/
namespace CommandIDs {
export const launcher = 'launcher:create';
}

/**
* A service providing an interface to the the launcher.
*/
export const launcherPlugin: JupyterFrontEndPlugin<ILauncher> = {
activate,
id: 'jupyter-drives:launcher-extension-plugin',
description: 'Provides the launcher tab service for the file browsers.',
requires: [ITranslator],
optional: [ILabShell, ICommandPalette, IFileBrowserFactory],
provides: ILauncher,
autoStart: true
};

/**
* Activate the launcher.
*/
function activate(
app: JupyterFrontEnd,
translator: ITranslator,
labShell: ILabShell | null,
palette: ICommandPalette | null,
factory: IFileBrowserFactory | null
): ILauncher {
const { commands, shell } = app;
const trans = translator.load('jupyter-drives');
const model = new LauncherModel();

commands.addCommand(CommandIDs.launcher, {
label: trans.__('New Launcher'),
icon: args => (args.toolbar ? addIcon : undefined),
execute: (args: ReadonlyPartialJSONObject) => {
// get current file browser used
const currentBrowser = factory?.tracker.currentWidget;
const cwd = (args['cwd'] as string) ?? currentBrowser?.model.path ?? '';
const id = `launcher-${Private.id++}`;
const callback = (item: Widget) => {
// If widget is attached to the main area replace the launcher
if (find(shell.widgets('main'), w => w === item)) {
shell.add(item, 'main', { ref: id });
launcher.dispose();
}
};
const launcher = new Launcher({
model,
cwd,
callback,
commands,
translator
});

launcher.model = model;
launcher.title.icon = launcherIcon;
launcher.title.label = trans.__('Launcher');

const main = new MainAreaWidget({ content: launcher });

// If there are any other widgets open, remove the launcher close icon.
main.title.closable = !!Array.from(shell.widgets('main')).length;
main.id = id;

shell.add(main, 'main', {
activate: args['activate'] as boolean,
ref: args['ref'] as string
});

if (labShell) {
labShell.layoutModified.connect(() => {
// If there is only a launcher open, remove the close icon.
main.title.closable = Array.from(labShell.widgets('main')).length > 1;
}, main);
}

if (currentBrowser) {
const onPathChanged = (model: FileBrowserModel) => {
launcher.cwd = model.path;
};
currentBrowser.model.pathChanged.connect(onPathChanged);
launcher.disposed.connect(() => {
currentBrowser.model.pathChanged.disconnect(onPathChanged);
});
}

return main;
}
});

if (labShell) {
const currentBrowser = factory?.tracker.currentWidget;
void Promise.all([app.restored, currentBrowser?.model.restored]).then(
() => {
function maybeCreate() {
// Create a launcher if there are no open items.
if (labShell!.isEmpty('main')) {
void commands.execute(CommandIDs.launcher);
}
}
// When layout is modified, create a launcher if there are no open items.
labShell.layoutModified.connect(() => {
maybeCreate();
});
}
);
}

if (palette) {
palette.addItem({
command: CommandIDs.launcher,
category: trans.__('Launcher')
});
}

if (labShell) {
labShell.addButtonEnabled = true;
labShell.addRequested.connect((sender: DockPanel, arg: TabBar<Widget>) => {
// Get the ref for the current tab of the tabbar which the add button was clicked
const ref =
arg.currentTitle?.owner.id ||
arg.titles[arg.titles.length - 1].owner.id;

return commands.execute(CommandIDs.launcher, { ref });
});
}

return model;
}

/**
* The namespace for module private data.
*/
namespace Private {
/**
* The incrementing id used for launcher widgets.
*/
export let id = 0;
}
19 changes: 19 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2357,6 +2357,24 @@ __metadata:
languageName: node
linkType: hard

"@jupyterlab/launcher@npm:^4.3.3":
version: 4.3.3
resolution: "@jupyterlab/launcher@npm:4.3.3"
dependencies:
"@jupyterlab/apputils": ^4.4.3
"@jupyterlab/translation": ^4.3.3
"@jupyterlab/ui-components": ^4.3.3
"@lumino/algorithm": ^2.0.2
"@lumino/commands": ^2.3.1
"@lumino/coreutils": ^2.2.0
"@lumino/disposable": ^2.1.3
"@lumino/properties": ^2.0.2
"@lumino/widgets": ^2.5.0
react: ^18.2.0
checksum: d91ab6375b23b6cad8498d855008f9299353f8bc411793ed8242ab7a37f5e0ab9f6b4799d5931368a30d27bf612d88b4fc37a4b0cab44f2231754ea38d732787
languageName: node
linkType: hard

"@jupyterlab/lsp@npm:^4.3.3":
version: 4.3.3
resolution: "@jupyterlab/lsp@npm:4.3.3"
Expand Down Expand Up @@ -7207,6 +7225,7 @@ __metadata:
"@jupyterlab/builder": ^4.2.0
"@jupyterlab/coreutils": ^6.2.0
"@jupyterlab/filebrowser": ^4.2.0
"@jupyterlab/launcher": ^4.3.3
"@jupyterlab/services": ^7.2.0
"@jupyterlab/settingregistry": ^4.2.0
"@jupyterlab/testutils": ^4.2.0
Expand Down
Loading