Skip to content

Commit

Permalink
Add public API for adding sections
Browse files Browse the repository at this point in the history
  • Loading branch information
krassowski committed May 27, 2024
1 parent e5c8e9f commit 2779524
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 81 deletions.
14 changes: 10 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,21 @@ import {
} from '@jupyterlab/application';
import { ICommandPalette, MainAreaWidget } from '@jupyterlab/apputils';
import { FileBrowserModel, IDefaultFileBrowser } from '@jupyterlab/filebrowser';
import { ILauncher, LauncherModel } from '@jupyterlab/launcher';
import { ILauncher } from '@jupyterlab/launcher';
import { ISettingRegistry } from '@jupyterlab/settingregistry';
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';
import { NewLauncher as Launcher } from './launcher';
import { CommandIDs, ILauncherDatabase, MAIN_PLUGIN_ID } from './types';
import { NewModel as Model } from './model';

Check failure on line 18 in src/index.ts

View workflow job for this annotation

GitHub Actions / check_release

Cannot find module './model' or its corresponding type declarations.
import {
CommandIDs,
ILauncherDatabase,
INewLauncher,
MAIN_PLUGIN_ID
} from './types';
import { addCommands } from './commands';
import { sessionDialogsPlugin } from './dialogs';
import { databasePlugin } from './database';
Expand Down Expand Up @@ -54,10 +60,10 @@ function activate(
labShell: ILabShell | null,
palette: ICommandPalette | null,
defaultBrowser: IDefaultFileBrowser | null
): ILauncher {
): INewLauncher {
const { commands, shell } = app;
const trans = translator.load('jupyterlab-new-launcher');
const model = new LauncherModel();
const model = new Model();

if (
navigator.userAgent.indexOf('AppleWebKit') !== -1 &&
Expand Down
182 changes: 105 additions & 77 deletions src/launcher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ import {
consoleIcon
} from '@jupyterlab/ui-components';
import * as React from 'react';
import { NewModel } from './model';

Check failure on line 14 in src/launcher.tsx

View workflow job for this annotation

GitHub Actions / check_release

Cannot find module './model' or its corresponding type declarations.
import {
IItem,
IKernelItem,
ILastUsedDatabase,
IFavoritesDatabase,
ISettingsLayout
ISettingsLayout,
ISectionOptions
} from './types';
import { fileIcon, starIcon } from './icons';
import { Item } from './item';
Expand All @@ -35,6 +37,7 @@ function LauncherBody(props: {
settings: ISettingRegistry.ISettings;
favouritesChanged: ISignal<IFavoritesDatabase, void>;
lastUsedChanged: ISignal<ILastUsedDatabase, void>;
sections: ISectionOptions[];
}): React.ReactElement {
const { trans, cwd, typeItems, otherItems, favouritesChanged } = props;
const [query, updateQuery] = React.useState<string>('');
Expand Down Expand Up @@ -104,79 +107,29 @@ function LauncherBody(props: {
const startCollapsed = props.settings.composite
.collapsedSections as ISettingsLayout['collapsedSections'];

return (
<div className="jp-LauncherBody">
<div className="jp-NewLauncher-TopBar">
<div className="jp-Launcher-cwd">
<h3>
{trans.__('Current folder:')} <code>{cwd ? cwd : '/'}</code>
</h3>
</div>
<div className="jp-NewLauncher-OtherItems">
{otherItems.map(item => (
<TypeCard item={item} trans={trans} />
))}
</div>
</div>
{searchAll ? (
<div className="jp-Launcher-searchBox">
<FilterBox
placeholder={trans.__('Filter')}
updateFilter={(_, query) => {
updateQuery(query ?? '');
}}
initialQuery={''}
useFuzzyFilter={false}
/>
</div>
) : null}
<CollapsibleSection
className="jp-Launcher-openByType"
title={trans.__('Create Empty')}
icon={fileIcon}
open={startCollapsed['create-empty'] !== 'collapsed'}
>
{typeItems
const builtinSections: ISectionOptions[] = [
{
className: 'jp-Launcher-openByType',
title: trans.__('Create Empty'),
icon: fileIcon,
id: 'create-empty',
rank: 1,
render: () =>
typeItems
.filter(
item =>
!query ||
item.label.toLowerCase().indexOf(query.toLowerCase()) !== -1
)
.map(item => (
<TypeCard item={item} trans={trans} />
))}
</CollapsibleSection>
{showStarred ? (
<CollapsibleSection
className="jp-Launcher-openByKernel"
title={trans.__('Starred')}
icon={starIcon}
open={startCollapsed['starred'] !== 'collapsed'}
>
{starred.length > 0 ? (
<KernelTable
items={starred}
commands={props.commands}
showSearchBox={!searchAll}
showWidgetType={true}
query={query}
settings={props.settings}
trans={trans}
onClick={item => item.execute()}
favouritesChanged={props.favouritesChanged}
lastUsedChanged={props.lastUsedChanged}
/>
) : (
'No starred items'
)}
</CollapsibleSection>
) : null}
<CollapsibleSection
className="jp-Launcher-openByKernel jp-Launcher-launchNotebook"
title={trans.__('Launch New Notebook')}
icon={notebookIcon}
open={startCollapsed['launch-notebook'] !== 'collapsed'}
>
.map(item => <TypeCard item={item} trans={trans} />)
},
{
className: 'jp-Launcher-openByKernel jp-Launcher-launchNotebook',
title: trans.__('Launch New Notebook'),
icon: notebookIcon,
id: 'launch-notebook',
rank: 3,
render: () => (
<KernelTable
items={props.notebookItems}
commands={props.commands}
Expand All @@ -188,13 +141,15 @@ function LauncherBody(props: {
favouritesChanged={props.favouritesChanged}
lastUsedChanged={props.lastUsedChanged}
/>
</CollapsibleSection>
<CollapsibleSection
className="jp-Launcher-openByKernel jp-Launcher-launchConsole"
title={trans.__('Launch New Console')}
icon={consoleIcon}
open={startCollapsed['launch-console'] !== 'collapsed'}
>
)
},
{
className: 'jp-Launcher-openByKernel jp-Launcher-launchConsole',
title: trans.__('Launch New Console'),
icon: consoleIcon,
id: 'launch-console',
rank: 5,
render: () => (
<KernelTable
items={props.consoleItems}
commands={props.commands}
Expand All @@ -206,7 +161,75 @@ function LauncherBody(props: {
favouritesChanged={props.favouritesChanged}
lastUsedChanged={props.lastUsedChanged}
/>
</CollapsibleSection>
)
}
];
if (showStarred) {
builtinSections.push({
className: 'jp-Launcher-openByKernel',
title: trans.__('Starred'),
icon: starIcon,
id: 'starred',
rank: 2,
render: () =>
starred.length > 0 ? (
<KernelTable
items={starred}
commands={props.commands}
showSearchBox={!searchAll}
showWidgetType={true}
query={query}
settings={props.settings}
trans={trans}
onClick={item => item.execute()}
favouritesChanged={props.favouritesChanged}
lastUsedChanged={props.lastUsedChanged}
/>
) : (
'No starred items'
)
});
}
const allSections = [...builtinSections, ...props.sections];

return (
<div className="jp-LauncherBody">
<div className="jp-NewLauncher-TopBar">
<div className="jp-Launcher-cwd">
<h3>
{trans.__('Current folder:')} <code>{cwd ? cwd : '/'}</code>
</h3>
</div>
<div className="jp-NewLauncher-OtherItems">
{otherItems.map(item => (
<TypeCard item={item} trans={trans} />
))}
</div>
</div>
{searchAll ? (
<div className="jp-Launcher-searchBox">
<FilterBox
placeholder={trans.__('Filter')}
updateFilter={(_, query) => {
updateQuery(query ?? '');
}}
initialQuery={''}
useFuzzyFilter={false}
/>
</div>
) : null}
{allSections
.sort((a, b) => a.rank - b.rank)
.map(section => (
<CollapsibleSection
className={section.className}
title={section.title}
icon={section.icon}
open={startCollapsed[section.id] !== 'collapsed'}
>
{section.render()}
</CollapsibleSection>
))}
</div>
);
}
Expand All @@ -216,6 +239,7 @@ export namespace NewLauncher {
lastUsedDatabase: ILastUsedDatabase;
favoritesDatabase: IFavoritesDatabase;
settings: ISettingRegistry.ISettings;
model: NewModel;
}
}

Expand All @@ -229,9 +253,12 @@ export class NewLauncher extends Launcher {
this._lastUsedDatabase = options.lastUsedDatabase;
this._favoritesDatabase = options.favoritesDatabase;
this._settings = options.settings;
this._newModel = options.model;
}
private _lastUsedDatabase: ILastUsedDatabase;
private _favoritesDatabase: IFavoritesDatabase;
private _newModel: NewModel;

trans: TranslationBundle;

renderCommand = (item: ILauncher.IItemOptions): IItem => {
Expand Down Expand Up @@ -334,6 +361,7 @@ export class NewLauncher extends Launcher {
settings={this._settings}
favouritesChanged={this._favoritesDatabase.changed}
lastUsedChanged={this._lastUsedDatabase.changed}
sections={this._newModel.sections}
/>
);
}
Expand Down
14 changes: 14 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,23 @@ import type { ILauncher } from '@jupyterlab/launcher';
import type { VirtualElement } from '@lumino/virtualdom';
import type { ISignal } from '@lumino/signaling';
import { Token } from '@lumino/coreutils';
import type { LabIcon } from '@jupyterlab/ui-components';

export const MAIN_PLUGIN_ID = 'jupyterlab-new-launcher:plugin';

export interface INewLauncher extends ILauncher {
addSection(options: ISectionOptions): void;
}

export interface ISectionOptions {
id: string;
title: string;
className: string;
icon: LabIcon;
render: () => React.ReactNode;
rank: number;
}

/**
* The command IDs used by the launcher plugin.
*/
Expand Down

0 comments on commit 2779524

Please sign in to comment.