Skip to content

Commit

Permalink
Add starred section
Browse files Browse the repository at this point in the history
  • Loading branch information
krassowski committed May 6, 2024
1 parent 9a9fcda commit 65a3a01
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 9 deletions.
6 changes: 6 additions & 0 deletions schema/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"type": "object",
"properties": {
"hiddenColumns": {
"title": "Hidden columns",
"type": "object",
"default": {
"conda_env_path": "hidden",
Expand All @@ -18,10 +19,15 @@
}
},
"columnOrder": {
"title": "Column order",
"type": "array",
"items": {
"type": "string"
}
},
"starredSection": {
"type": "boolean",
"title": "Show starred section"
}
},
"additionalProperties": false
Expand Down
8 changes: 8 additions & 0 deletions src/database.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { IStateDB } from '@jupyterlab/statedb';
import { ReadonlyPartialJSONValue, PromiseDelegate } from '@lumino/coreutils';
import { Signal } from '@lumino/signaling';
import { ILauncher } from '@jupyterlab/launcher';
import {
ILastUsedDatabase,
Expand Down Expand Up @@ -94,7 +95,14 @@ export class FavoritesDatabase

async set(item: ILauncher.IItemOptions, isFavourite: boolean) {
this._set(item, isFavourite);
this._changed.emit();
}

get changed() {
return this._changed;
}

private _changed = new Signal<FavoritesDatabase, void>(this);
}

/**
Expand Down
68 changes: 63 additions & 5 deletions src/launcher.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Nebari Development Team.
// Distributed under the terms of the Modified BSD License.
import type { CommandRegistry } from '@lumino/commands';
import type { ISignal } from '@lumino/signaling';
import { ISettingRegistry } from '@jupyterlab/settingregistry';
import { ILauncher, Launcher } from '@jupyterlab/launcher';
import { TranslationBundle } from '@jupyterlab/translation';
Expand All @@ -14,9 +15,10 @@ import {
IItem,
IKernelItem,
ILastUsedDatabase,
IFavoritesDatabase
IFavoritesDatabase,
ISettingsLayout
} from './types';
import { fileIcon } from './icons';
import { fileIcon, starIcon } from './icons';
import { Item } from './item';
import { KernelTable } from './components/table';
import { CollapsibleSection } from './components/section';
Expand All @@ -31,9 +33,44 @@ function LauncherBody(props: {
otherItems: IItem[];
commands: CommandRegistry;
settings: ISettingRegistry.ISettings;
favouritesChanged?: ISignal<IFavoritesDatabase, void>;
}): React.ReactElement {
const { trans, cwd, typeItems, otherItems } = props;
const { trans, cwd, typeItems, otherItems, favouritesChanged } = props;
const [query, updateQuery] = React.useState<string>('');
const [, forceUpdate] = React.useReducer(x => x + 1, 0);
const [showStarred, updateShowStarred] = React.useState<
ISettingsLayout['starredSection']
>(
props.settings.composite.starredSection as ISettingsLayout['starredSection']
);

const syncSettings = () => {
updateShowStarred(
props.settings.composite
.starredSection as ISettingsLayout['starredSection']
);
};

React.useEffect(() => {
props.settings.changed.connect(syncSettings);
return () => {
props.settings.changed.disconnect(syncSettings);
};
});

if (favouritesChanged) {
const updateIfNeeded = () => {
if (showStarred) {
forceUpdate();
}
};
React.useEffect(() => {
favouritesChanged.connect(updateIfNeeded);
return () => {
favouritesChanged.disconnect(updateIfNeeded);
};
});
}

const metadataAvailable = new Set<string>();
for (const item of props.notebookItems) {
Expand Down Expand Up @@ -86,8 +123,28 @@ function LauncherBody(props: {
<TypeCard item={item} trans={trans} />
))}
</CollapsibleSection>
{showStarred ? (
<CollapsibleSection
className="jp-Launcher-openByKernel"
title={trans.__('Starred')}
icon={starIcon}
open={true} // TODO: store this in layout/state higher up
>
<KernelTable
items={[...props.notebookItems, ...props.consoleItems].filter(
item => item.starred
)}
commands={props.commands}
showSearchBox={false}
query={query}
settings={props.settings}
trans={trans}
onClick={item => item.execute()}
/>
</CollapsibleSection>
) : null}
<CollapsibleSection
className="jp-Launcher-openByKernel"
className="jp-Launcher-openByKernel jp-Launcher-launchNotebook"
title={trans.__('Launch Notebook')}
icon={notebookIcon}
open={true} // TODO: store this in layout/state higher up
Expand All @@ -103,7 +160,7 @@ function LauncherBody(props: {
/>
</CollapsibleSection>
<CollapsibleSection
className="jp-Launcher-openByKernel"
className="jp-Launcher-openByKernel jp-Launcher-launchConsole"
title={trans.__('Launch Console')}
icon={consoleIcon}
open={false}
Expand Down Expand Up @@ -229,6 +286,7 @@ export class NewLauncher extends Launcher {
consoleItems={consoleItems}
otherItems={otherItems}
settings={this._settings}
favouritesChanged={this._favoritesDatabase.changed}
/>
);
}
Expand Down
2 changes: 2 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export namespace CommandIDs {
export interface ISettingsLayout {
hiddenColumns: Record<string, 'visible' | 'hidden'>;
columnOrder: string[];
starredSection: boolean;
}

export interface IItem extends ILauncher.IItemOptions {
Expand Down Expand Up @@ -47,6 +48,7 @@ export interface IFavoritesDatabase {
ready: Promise<void>;
get(item: ILauncher.IItemOptions): boolean | null;
set(item: ILauncher.IItemOptions, isFavourite: boolean): Promise<void>;
changed: ISignal<IFavoritesDatabase, void>;
}

/**
Expand Down
38 changes: 34 additions & 4 deletions ui-tests/tests/jupyterlab_new_launcher.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,36 @@
import { expect, test } from '@jupyterlab/galata';
import { expect, test, galata } from '@jupyterlab/galata';

test('should render new launcher', async ({ page }) => {
const launcher = page.locator('.jp-LauncherBody');
expect(await launcher.screenshot()).toMatchSnapshot('launcher.png');
const SETTINGS_ID = 'jupyterlab-new-launcher:plugin';

describe('Default settings', () => {
test('should render new launcher', async ({ page }) => {
const launcher = page.locator('.jp-LauncherBody');
expect(await launcher.screenshot()).toMatchSnapshot('launcher.png');
});
});

describe('With starred section', () => {
test.use({
mockSettings: {
...galata.DEFAULT_SETTINGS,
[SETTINGS_ID]: {
...galata.DEFAULT_SETTINGS[SETTINGS_ID],
starredSection: true
}
}
});

test('should render new launcher with starred section', async ({ page }) => {
const launcher = page.locator('.jp-LauncherBody');
// expand the console section
await page.locator('.jp-Launcher-launchConsole summary').click();
// star some items
await page
.locator('.jp-Launcher-launchNotebook .jp-starIconButton')
.click();
await page.locator('.jp-Launcher-launchConsole .jp-starIconButton').click();
expect(await launcher.screenshot()).toMatchSnapshot(
'launcher-with-starred.png'
);
});
});

0 comments on commit 65a3a01

Please sign in to comment.