|
@@ -136,33 +136,271 @@ namespace CommandIDs {
|
|
|
export const search = 'filebrowser:search';
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * The file browser namespace token.
|
|
|
+ */
|
|
|
+const namespace = 'filebrowser';
|
|
|
+
|
|
|
/**
|
|
|
* The default file browser extension.
|
|
|
*/
|
|
|
const browser: JupyterFrontEndPlugin<void> = {
|
|
|
- activate: activateBrowser,
|
|
|
id: '@jupyterlab/filebrowser-extension:browser',
|
|
|
- requires: [
|
|
|
- IFileBrowserFactory,
|
|
|
- IDocumentManager,
|
|
|
- ILabShell,
|
|
|
+ requires: [IFileBrowserFactory, ITranslator],
|
|
|
+ optional: [
|
|
|
ILayoutRestorer,
|
|
|
ISettingRegistry,
|
|
|
- ITranslator
|
|
|
+ ITreePathUpdater,
|
|
|
+ ICommandPalette,
|
|
|
+ IMainMenu
|
|
|
],
|
|
|
- optional: [ITreePathUpdater, ICommandPalette, IMainMenu],
|
|
|
- autoStart: true
|
|
|
+ autoStart: true,
|
|
|
+ activate: (
|
|
|
+ app: JupyterFrontEnd,
|
|
|
+ factory: IFileBrowserFactory,
|
|
|
+ translator: ITranslator,
|
|
|
+ restorer: ILayoutRestorer | null,
|
|
|
+ settingRegistry: ISettingRegistry | null,
|
|
|
+ treePathUpdater: ITreePathUpdater | null,
|
|
|
+ commandPalette: ICommandPalette | null,
|
|
|
+ mainMenu: IMainMenu | null
|
|
|
+ ): void => {
|
|
|
+ const trans = translator.load('jupyterlab');
|
|
|
+ const browser = factory.defaultBrowser;
|
|
|
+
|
|
|
+ // Let the application restorer track the primary file browser (that is
|
|
|
+ // automatically created) for restoration of application state (e.g. setting
|
|
|
+ // the file browser as the current side bar widget).
|
|
|
+ //
|
|
|
+ // All other file browsers created by using the factory function are
|
|
|
+ // responsible for their own restoration behavior, if any.
|
|
|
+ if (restorer) {
|
|
|
+ restorer.add(browser, namespace);
|
|
|
+ }
|
|
|
+
|
|
|
+ addCommands(
|
|
|
+ app,
|
|
|
+ factory,
|
|
|
+ translator,
|
|
|
+ settingRegistry,
|
|
|
+ commandPalette,
|
|
|
+ mainMenu
|
|
|
+ );
|
|
|
+
|
|
|
+ browser.title.icon = folderIcon;
|
|
|
+ // Show the current file browser shortcut in its title.
|
|
|
+ const updateBrowserTitle = () => {
|
|
|
+ const binding = find(
|
|
|
+ app.commands.keyBindings,
|
|
|
+ b => b.command === CommandIDs.toggleBrowser
|
|
|
+ );
|
|
|
+ if (binding) {
|
|
|
+ const ks = CommandRegistry.formatKeystroke(binding.keys.join(' '));
|
|
|
+ browser.title.caption = trans.__('File Browser (%1)', ks);
|
|
|
+ } else {
|
|
|
+ browser.title.caption = trans.__('File Browser');
|
|
|
+ }
|
|
|
+ };
|
|
|
+ updateBrowserTitle();
|
|
|
+ app.commands.keyBindingChanged.connect(() => {
|
|
|
+ updateBrowserTitle();
|
|
|
+ });
|
|
|
+
|
|
|
+ void Promise.all([app.restored, browser.model.restored]).then(() => {
|
|
|
+ if (treePathUpdater) {
|
|
|
+ browser.model.pathChanged.connect((sender, args) => {
|
|
|
+ treePathUpdater(args.newValue);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ let navigateToCurrentDirectory: boolean = false;
|
|
|
+ let useFuzzyFilter: boolean = true;
|
|
|
+
|
|
|
+ if (settingRegistry) {
|
|
|
+ void settingRegistry
|
|
|
+ .load('@jupyterlab/filebrowser-extension:browser')
|
|
|
+ .then(settings => {
|
|
|
+ settings.changed.connect(settings => {
|
|
|
+ navigateToCurrentDirectory = settings.get(
|
|
|
+ 'navigateToCurrentDirectory'
|
|
|
+ ).composite as boolean;
|
|
|
+ browser.navigateToCurrentDirectory = navigateToCurrentDirectory;
|
|
|
+ });
|
|
|
+ navigateToCurrentDirectory = settings.get(
|
|
|
+ 'navigateToCurrentDirectory'
|
|
|
+ ).composite as boolean;
|
|
|
+ browser.navigateToCurrentDirectory = navigateToCurrentDirectory;
|
|
|
+ settings.changed.connect(settings => {
|
|
|
+ useFuzzyFilter = settings.get('useFuzzyFilter')
|
|
|
+ .composite as boolean;
|
|
|
+ browser.useFuzzyFilter = useFuzzyFilter;
|
|
|
+ });
|
|
|
+ useFuzzyFilter = settings.get('useFuzzyFilter')
|
|
|
+ .composite as boolean;
|
|
|
+ browser.useFuzzyFilter = useFuzzyFilter;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* The default file browser factory provider.
|
|
|
*/
|
|
|
const factory: JupyterFrontEndPlugin<IFileBrowserFactory> = {
|
|
|
- activate: activateFactory,
|
|
|
id: '@jupyterlab/filebrowser-extension:factory',
|
|
|
provides: IFileBrowserFactory,
|
|
|
requires: [IDocumentManager, ITranslator],
|
|
|
- optional: [IStateDB, IRouter, JupyterFrontEnd.ITreeResolver]
|
|
|
+ optional: [IStateDB, IRouter, JupyterFrontEnd.ITreeResolver],
|
|
|
+ activate: async (
|
|
|
+ app: JupyterFrontEnd,
|
|
|
+ docManager: IDocumentManager,
|
|
|
+ translator: ITranslator,
|
|
|
+ state: IStateDB | null,
|
|
|
+ router: IRouter | null,
|
|
|
+ tree: JupyterFrontEnd.ITreeResolver | null
|
|
|
+ ): Promise<IFileBrowserFactory> => {
|
|
|
+ const { commands } = app;
|
|
|
+ const tracker = new WidgetTracker<FileBrowser>({ namespace });
|
|
|
+ const createFileBrowser = (
|
|
|
+ id: string,
|
|
|
+ options: IFileBrowserFactory.IOptions = {}
|
|
|
+ ) => {
|
|
|
+ const model = new FilterFileBrowserModel({
|
|
|
+ translator: translator,
|
|
|
+ auto: options.auto ?? true,
|
|
|
+ manager: docManager,
|
|
|
+ driveName: options.driveName || '',
|
|
|
+ refreshInterval: options.refreshInterval,
|
|
|
+ state:
|
|
|
+ options.state === null
|
|
|
+ ? undefined
|
|
|
+ : options.state || state || undefined
|
|
|
+ });
|
|
|
+ const restore = options.restore;
|
|
|
+ const widget = new FileBrowser({ id, model, restore, translator });
|
|
|
+
|
|
|
+ // Track the newly created file browser.
|
|
|
+ void tracker.add(widget);
|
|
|
+
|
|
|
+ return widget;
|
|
|
+ };
|
|
|
+
|
|
|
+ // Manually restore and load the default file browser.
|
|
|
+ const defaultBrowser = createFileBrowser('filebrowser', {
|
|
|
+ auto: false,
|
|
|
+ restore: false
|
|
|
+ });
|
|
|
+ void Private.restoreBrowser(defaultBrowser, commands, router, tree);
|
|
|
+
|
|
|
+ return { createFileBrowser, defaultBrowser, tracker };
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ * A plugin to add the file browser widget to an ILabShell
|
|
|
+ */
|
|
|
+const browserWidget: JupyterFrontEndPlugin<void> = {
|
|
|
+ id: '@jupyterlab/filebrowser-extension:widget',
|
|
|
+ requires: [IDocumentManager, IFileBrowserFactory, ITranslator, ILabShell],
|
|
|
+ autoStart: true,
|
|
|
+ activate: (
|
|
|
+ app: JupyterFrontEnd,
|
|
|
+ docManager: IDocumentManager,
|
|
|
+ factory: IFileBrowserFactory,
|
|
|
+ translator: ITranslator,
|
|
|
+ labShell: ILabShell
|
|
|
+ ): void => {
|
|
|
+ const { commands } = app;
|
|
|
+ const { defaultBrowser: browser, tracker } = factory;
|
|
|
+ labShell.add(browser, 'left', { rank: 100 });
|
|
|
+
|
|
|
+ commands.addCommand(CommandIDs.showBrowser, {
|
|
|
+ execute: args => {
|
|
|
+ const path = (args.path as string) || '';
|
|
|
+ const browserForPath = Private.getBrowserForPath(path, factory);
|
|
|
+
|
|
|
+ // Check for browser not found
|
|
|
+ if (!browserForPath) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // Shortcut if we are using the main file browser
|
|
|
+ if (browser === browserForPath) {
|
|
|
+ labShell.activateById(browser.id);
|
|
|
+ return;
|
|
|
+ } else {
|
|
|
+ const areas: ILabShell.Area[] = ['left', 'right'];
|
|
|
+ for (const area of areas) {
|
|
|
+ const it = labShell.widgets(area);
|
|
|
+ let widget = it.next();
|
|
|
+ while (widget) {
|
|
|
+ if (widget.contains(browserForPath)) {
|
|
|
+ labShell.activateById(widget.id);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ widget = it.next();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ commands.addCommand(CommandIDs.hideBrowser, {
|
|
|
+ execute: () => {
|
|
|
+ const widget = tracker.currentWidget;
|
|
|
+ if (widget && !widget.isHidden) {
|
|
|
+ labShell.collapseLeft();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // If the layout is a fresh session without saved data and not in single document
|
|
|
+ // mode, open file browser.
|
|
|
+ void labShell.restored.then(layout => {
|
|
|
+ if (layout.fresh && labShell.mode !== 'single-document') {
|
|
|
+ void commands.execute(CommandIDs.showBrowser, void 0);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ void Promise.all([app.restored, browser.model.restored]).then(() => {
|
|
|
+ function maybeCreate() {
|
|
|
+ // Create a launcher if there are no open items.
|
|
|
+ if (
|
|
|
+ labShell.isEmpty('main') &&
|
|
|
+ commands.hasCommand('launcher:create')
|
|
|
+ ) {
|
|
|
+ void Private.createLauncher(commands, browser);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // When layout is modified, create a launcher if there are no open items.
|
|
|
+ labShell.layoutModified.connect(() => {
|
|
|
+ maybeCreate();
|
|
|
+ });
|
|
|
+
|
|
|
+ // Whether to automatically navigate to a document's current directory
|
|
|
+ labShell.currentChanged.connect(async (_, change) => {
|
|
|
+ if (browser.navigateToCurrentDirectory && change.newValue) {
|
|
|
+ const { newValue } = change;
|
|
|
+ const context = docManager.contextForWidget(newValue);
|
|
|
+ if (context) {
|
|
|
+ const { path } = context;
|
|
|
+ try {
|
|
|
+ await Private.navigateToPath(path, factory, translator);
|
|
|
+ labShell.currentWidget?.activate();
|
|
|
+ } catch (reason) {
|
|
|
+ console.warn(
|
|
|
+ `${CommandIDs.goToPath} failed to open: ${path}`,
|
|
|
+ reason
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ maybeCreate();
|
|
|
+ });
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
/**
|
|
@@ -177,10 +415,44 @@ const factory: JupyterFrontEndPlugin<IFileBrowserFactory> = {
|
|
|
* with another implementation.
|
|
|
*/
|
|
|
const shareFile: JupyterFrontEndPlugin<void> = {
|
|
|
- activate: activateShareFile,
|
|
|
id: '@jupyterlab/filebrowser-extension:share-file',
|
|
|
requires: [IFileBrowserFactory, ITranslator],
|
|
|
- autoStart: true
|
|
|
+ autoStart: true,
|
|
|
+ activate: (
|
|
|
+ app: JupyterFrontEnd,
|
|
|
+ factory: IFileBrowserFactory,
|
|
|
+ translator: ITranslator
|
|
|
+ ): void => {
|
|
|
+ const trans = translator.load('jupyterlab');
|
|
|
+ const { commands } = app;
|
|
|
+ const { tracker } = factory;
|
|
|
+
|
|
|
+ commands.addCommand(CommandIDs.share, {
|
|
|
+ execute: () => {
|
|
|
+ const widget = tracker.currentWidget;
|
|
|
+ const model = widget?.selectedItems().next();
|
|
|
+ if (!model) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const path = encodeURI(model.path);
|
|
|
+
|
|
|
+ Clipboard.copyToSystem(
|
|
|
+ URLExt.normalize(
|
|
|
+ PageConfig.getUrl({
|
|
|
+ mode: 'single-document',
|
|
|
+ workspace: PageConfig.defaultWorkspace,
|
|
|
+ treePath: path
|
|
|
+ })
|
|
|
+ )
|
|
|
+ );
|
|
|
+ },
|
|
|
+ isVisible: () =>
|
|
|
+ !!tracker.currentWidget &&
|
|
|
+ toArray(tracker.currentWidget.selectedItems()).length === 1,
|
|
|
+ icon: linkIcon.bindprops({ stylesheet: 'menuItem' }),
|
|
|
+ label: trans.__('Copy Shareable Link')
|
|
|
+ });
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
/**
|
|
@@ -221,247 +493,35 @@ export const fileUploadStatus: JupyterFrontEndPlugin<void> = {
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
- * The file browser namespace token.
|
|
|
- */
|
|
|
-const namespace = 'filebrowser';
|
|
|
-
|
|
|
-/**
|
|
|
- * Export the plugins as default.
|
|
|
- */
|
|
|
-const plugins: JupyterFrontEndPlugin<any>[] = [
|
|
|
- factory,
|
|
|
- browser,
|
|
|
- shareFile,
|
|
|
- fileUploadStatus
|
|
|
-];
|
|
|
-export default plugins;
|
|
|
-
|
|
|
-/**
|
|
|
- * Activate the file browser factory provider.
|
|
|
+ * A plugin to add a launcher button to the file browser toolbar
|
|
|
*/
|
|
|
-async function activateFactory(
|
|
|
- app: JupyterFrontEnd,
|
|
|
- docManager: IDocumentManager,
|
|
|
- translator: ITranslator,
|
|
|
- state: IStateDB | null,
|
|
|
- router: IRouter | null,
|
|
|
- tree: JupyterFrontEnd.ITreeResolver | null
|
|
|
-): Promise<IFileBrowserFactory> {
|
|
|
- const trans = translator.load('jupyterlab');
|
|
|
- const { commands } = app;
|
|
|
- const tracker = new WidgetTracker<FileBrowser>({ namespace });
|
|
|
- const createFileBrowser = (
|
|
|
- id: string,
|
|
|
- options: IFileBrowserFactory.IOptions = {}
|
|
|
+export const launcherToolbarButton: JupyterFrontEndPlugin<void> = {
|
|
|
+ id: '@jupyterlab/filebrowser-extension:launcher-toolbar-button',
|
|
|
+ autoStart: true,
|
|
|
+ requires: [IFileBrowserFactory, ITranslator],
|
|
|
+ activate: (
|
|
|
+ app: JupyterFrontEnd,
|
|
|
+ factory: IFileBrowserFactory,
|
|
|
+ translator: ITranslator
|
|
|
) => {
|
|
|
- const model = new FilterFileBrowserModel({
|
|
|
- translator: translator,
|
|
|
- auto: options.auto ?? true,
|
|
|
- manager: docManager,
|
|
|
- driveName: options.driveName || '',
|
|
|
- refreshInterval: options.refreshInterval,
|
|
|
- state:
|
|
|
- options.state === null ? undefined : options.state || state || undefined
|
|
|
- });
|
|
|
- const restore = options.restore;
|
|
|
- const widget = new FileBrowser({ id, model, restore, translator });
|
|
|
+ const { commands } = app;
|
|
|
+ const trans = translator.load('jupyterlab');
|
|
|
+ const { defaultBrowser: browser } = factory;
|
|
|
|
|
|
// Add a launcher toolbar item.
|
|
|
const launcher = new ToolbarButton({
|
|
|
icon: addIcon,
|
|
|
onClick: () => {
|
|
|
if (commands.hasCommand('launcher:create')) {
|
|
|
- return Private.createLauncher(commands, widget);
|
|
|
+ return Private.createLauncher(commands, browser);
|
|
|
}
|
|
|
},
|
|
|
tooltip: trans.__('New Launcher'),
|
|
|
actualOnClick: true
|
|
|
});
|
|
|
- widget.toolbar.insertItem(0, 'launch', launcher);
|
|
|
-
|
|
|
- // Track the newly created file browser.
|
|
|
- void tracker.add(widget);
|
|
|
-
|
|
|
- return widget;
|
|
|
- };
|
|
|
-
|
|
|
- // Manually restore and load the default file browser.
|
|
|
- const defaultBrowser = createFileBrowser('filebrowser', {
|
|
|
- auto: false,
|
|
|
- restore: false
|
|
|
- });
|
|
|
- void Private.restoreBrowser(defaultBrowser, commands, router, tree);
|
|
|
-
|
|
|
- return { createFileBrowser, defaultBrowser, tracker };
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * Activate the default file browser in the sidebar.
|
|
|
- */
|
|
|
-function activateBrowser(
|
|
|
- app: JupyterFrontEnd,
|
|
|
- factory: IFileBrowserFactory,
|
|
|
- docManager: IDocumentManager,
|
|
|
- labShell: ILabShell,
|
|
|
- restorer: ILayoutRestorer,
|
|
|
- settingRegistry: ISettingRegistry,
|
|
|
- translator: ITranslator,
|
|
|
- treePathUpdater: ITreePathUpdater | null,
|
|
|
- commandPalette: ICommandPalette | null,
|
|
|
- mainMenu: IMainMenu | null
|
|
|
-): void {
|
|
|
- const trans = translator.load('jupyterlab');
|
|
|
- const browser = factory.defaultBrowser;
|
|
|
- const { commands } = app;
|
|
|
-
|
|
|
- // Let the application restorer track the primary file browser (that is
|
|
|
- // automatically created) for restoration of application state (e.g. setting
|
|
|
- // the file browser as the current side bar widget).
|
|
|
- //
|
|
|
- // All other file browsers created by using the factory function are
|
|
|
- // responsible for their own restoration behavior, if any.
|
|
|
- restorer.add(browser, namespace);
|
|
|
-
|
|
|
- addCommands(
|
|
|
- app,
|
|
|
- factory,
|
|
|
- labShell,
|
|
|
- docManager,
|
|
|
- settingRegistry,
|
|
|
- translator,
|
|
|
- commandPalette,
|
|
|
- mainMenu
|
|
|
- );
|
|
|
-
|
|
|
- browser.title.icon = folderIcon;
|
|
|
- // Show the current file browser shortcut in its title.
|
|
|
- const updateBrowserTitle = () => {
|
|
|
- const binding = find(
|
|
|
- app.commands.keyBindings,
|
|
|
- b => b.command === CommandIDs.toggleBrowser
|
|
|
- );
|
|
|
- if (binding) {
|
|
|
- const ks = CommandRegistry.formatKeystroke(binding.keys.join(' '));
|
|
|
- browser.title.caption = trans.__('File Browser (%1)', ks);
|
|
|
- } else {
|
|
|
- browser.title.caption = trans.__('File Browser');
|
|
|
- }
|
|
|
- };
|
|
|
- updateBrowserTitle();
|
|
|
- app.commands.keyBindingChanged.connect(() => {
|
|
|
- updateBrowserTitle();
|
|
|
- });
|
|
|
- labShell.add(browser, 'left', { rank: 100 });
|
|
|
-
|
|
|
- // If the layout is a fresh session without saved data and not in single document
|
|
|
- // mode, open file browser.
|
|
|
- void labShell.restored.then(layout => {
|
|
|
- if (layout.fresh && labShell.mode !== 'single-document') {
|
|
|
- void commands.execute(CommandIDs.showBrowser, void 0);
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- void Promise.all([app.restored, browser.model.restored]).then(() => {
|
|
|
- function maybeCreate() {
|
|
|
- // Create a launcher if there are no open items.
|
|
|
- if (labShell.isEmpty('main') && commands.hasCommand('launcher:create')) {
|
|
|
- void Private.createLauncher(commands, browser);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // When layout is modified, create a launcher if there are no open items.
|
|
|
- labShell.layoutModified.connect(() => {
|
|
|
- maybeCreate();
|
|
|
- });
|
|
|
-
|
|
|
- let navigateToCurrentDirectory: boolean = false;
|
|
|
- let useFuzzyFilter: boolean = true;
|
|
|
-
|
|
|
- void settingRegistry
|
|
|
- .load('@jupyterlab/filebrowser-extension:browser')
|
|
|
- .then(settings => {
|
|
|
- settings.changed.connect(settings => {
|
|
|
- navigateToCurrentDirectory = settings.get(
|
|
|
- 'navigateToCurrentDirectory'
|
|
|
- ).composite as boolean;
|
|
|
- browser.navigateToCurrentDirectory = navigateToCurrentDirectory;
|
|
|
- });
|
|
|
- navigateToCurrentDirectory = settings.get('navigateToCurrentDirectory')
|
|
|
- .composite as boolean;
|
|
|
- browser.navigateToCurrentDirectory = navigateToCurrentDirectory;
|
|
|
- settings.changed.connect(settings => {
|
|
|
- useFuzzyFilter = settings.get('useFuzzyFilter').composite as boolean;
|
|
|
- browser.useFuzzyFilter = useFuzzyFilter;
|
|
|
- });
|
|
|
- useFuzzyFilter = settings.get('useFuzzyFilter').composite as boolean;
|
|
|
- browser.useFuzzyFilter = useFuzzyFilter;
|
|
|
- });
|
|
|
-
|
|
|
- // Whether to automatically navigate to a document's current directory
|
|
|
- labShell.currentChanged.connect(async (_, change) => {
|
|
|
- if (navigateToCurrentDirectory && change.newValue) {
|
|
|
- const { newValue } = change;
|
|
|
- const context = docManager.contextForWidget(newValue);
|
|
|
- if (context) {
|
|
|
- const { path } = context;
|
|
|
- try {
|
|
|
- await Private.navigateToPath(path, factory, translator);
|
|
|
- labShell.currentWidget?.activate();
|
|
|
- } catch (reason) {
|
|
|
- console.warn(
|
|
|
- `${CommandIDs.goToPath} failed to open: ${path}`,
|
|
|
- reason
|
|
|
- );
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- if (treePathUpdater) {
|
|
|
- browser.model.pathChanged.connect((sender, args) => {
|
|
|
- treePathUpdater(args.newValue);
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- maybeCreate();
|
|
|
- });
|
|
|
-}
|
|
|
-
|
|
|
-function activateShareFile(
|
|
|
- app: JupyterFrontEnd,
|
|
|
- factory: IFileBrowserFactory,
|
|
|
- translator: ITranslator
|
|
|
-): void {
|
|
|
- const trans = translator.load('jupyterlab');
|
|
|
- const { commands } = app;
|
|
|
- const { tracker } = factory;
|
|
|
-
|
|
|
- commands.addCommand(CommandIDs.share, {
|
|
|
- execute: () => {
|
|
|
- const widget = tracker.currentWidget;
|
|
|
- const model = widget?.selectedItems().next();
|
|
|
- if (!model) {
|
|
|
- return;
|
|
|
- }
|
|
|
- const path = encodeURI(model.path);
|
|
|
-
|
|
|
- Clipboard.copyToSystem(
|
|
|
- URLExt.normalize(
|
|
|
- PageConfig.getUrl({
|
|
|
- mode: 'single-document',
|
|
|
- workspace: PageConfig.defaultWorkspace,
|
|
|
- treePath: path
|
|
|
- })
|
|
|
- )
|
|
|
- );
|
|
|
- },
|
|
|
- isVisible: () =>
|
|
|
- !!tracker.currentWidget &&
|
|
|
- toArray(tracker.currentWidget.selectedItems()).length === 1,
|
|
|
- icon: linkIcon.bindprops({ stylesheet: 'menuItem' }),
|
|
|
- label: trans.__('Copy Shareable Link')
|
|
|
- });
|
|
|
-}
|
|
|
+ browser.toolbar.insertItem(0, 'launch', launcher);
|
|
|
+ }
|
|
|
+};
|
|
|
|
|
|
/**
|
|
|
* Add the main file browser commands to the application's command registry.
|
|
@@ -469,10 +529,8 @@ function activateShareFile(
|
|
|
function addCommands(
|
|
|
app: JupyterFrontEnd,
|
|
|
factory: IFileBrowserFactory,
|
|
|
- labShell: ILabShell,
|
|
|
- docManager: IDocumentManager,
|
|
|
- settingRegistry: ISettingRegistry,
|
|
|
translator: ITranslator,
|
|
|
+ settingRegistry: ISettingRegistry | null,
|
|
|
commandPalette: ICommandPalette | null,
|
|
|
mainMenu: IMainMenu | null
|
|
|
): void {
|
|
@@ -542,15 +600,6 @@ function addCommands(
|
|
|
label: trans.__('Duplicate')
|
|
|
});
|
|
|
|
|
|
- commands.addCommand(CommandIDs.hideBrowser, {
|
|
|
- execute: () => {
|
|
|
- const widget = tracker.currentWidget;
|
|
|
- if (widget && !widget.isHidden) {
|
|
|
- labShell.collapseLeft();
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
commands.addCommand(CommandIDs.goToPath, {
|
|
|
execute: async args => {
|
|
|
const path = (args.path as string) || '';
|
|
@@ -811,36 +860,6 @@ function addCommands(
|
|
|
label: trans.__('Copy Path')
|
|
|
});
|
|
|
|
|
|
- commands.addCommand(CommandIDs.showBrowser, {
|
|
|
- execute: args => {
|
|
|
- const path = (args.path as string) || '';
|
|
|
- const browserForPath = Private.getBrowserForPath(path, factory);
|
|
|
-
|
|
|
- // Check for browser not found
|
|
|
- if (!browserForPath) {
|
|
|
- return;
|
|
|
- }
|
|
|
- // Shortcut if we are using the main file browser
|
|
|
- if (browser === browserForPath) {
|
|
|
- labShell.activateById(browser.id);
|
|
|
- return;
|
|
|
- } else {
|
|
|
- const areas: ILabShell.Area[] = ['left', 'right'];
|
|
|
- for (const area of areas) {
|
|
|
- const it = labShell.widgets(area);
|
|
|
- let widget = it.next();
|
|
|
- while (widget) {
|
|
|
- if (widget.contains(browserForPath)) {
|
|
|
- labShell.activateById(widget.id);
|
|
|
- return;
|
|
|
- }
|
|
|
- widget = it.next();
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
commands.addCommand(CommandIDs.shutdown, {
|
|
|
execute: () => {
|
|
|
const widget = tracker.currentWidget;
|
|
@@ -868,19 +887,21 @@ function addCommands(
|
|
|
execute: () => Private.createLauncher(commands, browser)
|
|
|
});
|
|
|
|
|
|
- commands.addCommand(CommandIDs.toggleNavigateToCurrentDirectory, {
|
|
|
- label: trans.__('Show Active File in File Browser'),
|
|
|
- isToggled: () => browser.navigateToCurrentDirectory,
|
|
|
- execute: () => {
|
|
|
- const value = !browser.navigateToCurrentDirectory;
|
|
|
- const key = 'navigateToCurrentDirectory';
|
|
|
- return settingRegistry
|
|
|
- .set('@jupyterlab/filebrowser-extension:browser', key, value)
|
|
|
- .catch((reason: Error) => {
|
|
|
- console.error(`Failed to set navigateToCurrentDirectory setting`);
|
|
|
- });
|
|
|
- }
|
|
|
- });
|
|
|
+ if (settingRegistry) {
|
|
|
+ commands.addCommand(CommandIDs.toggleNavigateToCurrentDirectory, {
|
|
|
+ label: trans.__('Show Active File in File Browser'),
|
|
|
+ isToggled: () => browser.navigateToCurrentDirectory,
|
|
|
+ execute: () => {
|
|
|
+ const value = !browser.navigateToCurrentDirectory;
|
|
|
+ const key = 'navigateToCurrentDirectory';
|
|
|
+ return settingRegistry
|
|
|
+ .set('@jupyterlab/filebrowser-extension:browser', key, value)
|
|
|
+ .catch((reason: Error) => {
|
|
|
+ console.error(`Failed to set navigateToCurrentDirectory setting`);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
|
|
|
commands.addCommand(CommandIDs.toggleLastModified, {
|
|
|
label: trans.__('Toggle Last Modified Column'),
|
|
@@ -1239,3 +1260,16 @@ namespace Private {
|
|
|
router.routed.connect(listener);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Export the plugins as default.
|
|
|
+ */
|
|
|
+const plugins: JupyterFrontEndPlugin<any>[] = [
|
|
|
+ factory,
|
|
|
+ browser,
|
|
|
+ shareFile,
|
|
|
+ fileUploadStatus,
|
|
|
+ browserWidget,
|
|
|
+ launcherToolbarButton
|
|
|
+];
|
|
|
+export default plugins;
|