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

Add settings and menu items to toggle display of each section #71

Merged
17 changes: 16 additions & 1 deletion schema/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,24 @@
"type": "string"
}
},
"createEmptySection": {
"type": "boolean",
"title": "Show \"Create Empty\" section",
"default": true
},
"starredSection": {
"type": "boolean",
"title": "Show starred section"
"title": "Show \"Starred\" section"
},
"launchNotebookSection": {
"type": "boolean",
"title": "Show \"Launch New Notebook\" section",
"default": true
},
"launchConsoleSection": {
"type": "boolean",
"title": "Show \"Launch New Console\" section",
"default": true
},
"searchAllSections": {
"type": "boolean",
Expand Down
41 changes: 40 additions & 1 deletion src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,19 +76,58 @@ export function addCommands(
await settings.set('columnOrder', order);
}
});
app.commands.addCommand(CommandIDs.showCreateEmpty, {
isToggleable: true,
isToggled: () => {
return settings.composite
.createEmptySection as ISettingsLayout['createEmptySection'];
},
label: trans.__('Show "Create Empty" Section'),
execute: async () => {
const createEmptySection = settings.composite
.createEmptySection as ISettingsLayout['createEmptySection'];
await settings.set('createEmptySection', !createEmptySection);
}
});
app.commands.addCommand(CommandIDs.showStarred, {
isToggleable: true,
isToggled: () => {
return settings.composite
.starredSection as ISettingsLayout['starredSection'];
},
label: trans.__('Show Starred Section'),
label: trans.__('Show "Starred" Section'),
execute: async () => {
const starredSection = settings.composite
.starredSection as ISettingsLayout['starredSection'];
await settings.set('starredSection', !starredSection);
}
});
app.commands.addCommand(CommandIDs.showNotebookLauncher, {
isToggleable: true,
isToggled: () => {
return settings.composite
.launchNotebookSection as ISettingsLayout['launchNotebookSection'];
},
label: trans.__('Show "Launch New Notebook" section'),
execute: async () => {
const launchNotebookSection = settings.composite
.launchNotebookSection as ISettingsLayout['launchNotebookSection'];
await settings.set('launchNotebookSection', !launchNotebookSection);
}
});
app.commands.addCommand(CommandIDs.showConsoleLauncher, {
isToggleable: true,
isToggled: () => {
return settings.composite
.launchConsoleSection as ISettingsLayout['launchConsoleSection'];
},
label: trans.__('Show "Launch New Console" Section'),
execute: async () => {
const launchConsoleSection = settings.composite
.launchConsoleSection as ISettingsLayout['launchConsoleSection'];
await settings.set('launchConsoleSection', !launchConsoleSection);
}
});
app.commands.addCommand(CommandIDs.searchAllSections, {
isToggleable: true,
isToggled: () => {
Expand Down
3 changes: 3 additions & 0 deletions src/components/quick-settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ export function QuickSettings(props: {
const { commands } = props;

const menu = new MenuSvg({ commands: commands });
menu.addItem({ command: CommandIDs.showCreateEmpty });
menu.addItem({ command: CommandIDs.showStarred });
menu.addItem({ command: CommandIDs.showNotebookLauncher });
menu.addItem({ command: CommandIDs.showConsoleLauncher });
menu.addItem({ command: CommandIDs.searchAllSections });
menu.addItem({ command: CommandIDs.openSettings });

Expand Down
112 changes: 80 additions & 32 deletions src/launcher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,29 @@ function LauncherBody(props: {
props;
const [query, updateQuery] = React.useState<string>('');
const [, forceUpdate] = React.useReducer(x => x + 1, 0);
const [showCreateEmpty, updateCreateEmpty] = React.useState<
ISettingsLayout['createEmptySection']
>(
props.settings.composite
.createEmptySection as ISettingsLayout['createEmptySection']
);
const [showStarred, updateShowStarred] = React.useState<
ISettingsLayout['starredSection']
>(
props.settings.composite.starredSection as ISettingsLayout['starredSection']
);
const [showNotebookLauncher, updateShowNotebookLauncher] = React.useState<
ISettingsLayout['launchNotebookSection']
>(
props.settings.composite
.launchNotebookSection as ISettingsLayout['launchNotebookSection']
);
const [showConsole, updateShowConsole] = React.useState<
ISettingsLayout['launchConsoleSection']
>(
props.settings.composite
.launchConsoleSection as ISettingsLayout['launchConsoleSection']
);

const [searchAll, updateSearchAll] = React.useState<
ISettingsLayout['searchAllSections']
Expand All @@ -59,11 +77,27 @@ function LauncherBody(props: {
);

const syncSettings = () => {
const newShowCreateEmpty = props.settings.composite
.createEmptySection as ISettingsLayout['createEmptySection'];
if (showCreateEmpty !== newShowCreateEmpty) {
updateCreateEmpty(newShowCreateEmpty);
}
const newStarred = props.settings.composite
.starredSection as ISettingsLayout['starredSection'];
if (showStarred !== newStarred) {
updateShowStarred(newStarred);
}
const newShowConsole = props.settings.composite
.launchConsoleSection as ISettingsLayout['launchConsoleSection'];
if (showConsole !== newShowConsole) {
updateShowConsole(newShowConsole);
}
const newShowNotebook = props.settings.composite
.launchNotebookSection as ISettingsLayout['launchNotebookSection'];
if (showNotebookLauncher !== newShowNotebook) {
updateShowNotebookLauncher(newShowNotebook);
}

const newSearchAll = props.settings.composite
.searchAllSections as ISettingsLayout['searchAllSections'];
if (searchAll !== newSearchAll) {
Expand All @@ -80,9 +114,18 @@ function LauncherBody(props: {

if (favouritesChanged) {
const updateIfNeeded = () => {
if (showCreateEmpty) {
forceUpdate();
}
if (showStarred) {
forceUpdate();
}
if (showNotebookLauncher) {
forceUpdate();
}
if (showConsole) {
forceUpdate();
}
};
React.useEffect(() => {
favouritesChanged.connect(updateIfNeeded);
Expand Down Expand Up @@ -110,8 +153,9 @@ function LauncherBody(props: {
const startCollapsed = props.settings.composite
.collapsedSections as ISettingsLayout['collapsedSections'];

const builtinSections: ISectionOptions[] = [
{
const builtinSections: ISectionOptions[] = [];
if (showCreateEmpty) {
builtinSections.push({
className: 'jp-Launcher-openByType',
title: trans.__('Create Empty'),
icon: fileIcon,
Expand All @@ -125,8 +169,36 @@ function LauncherBody(props: {
item.label.toLowerCase().indexOf(query.toLowerCase()) !== -1
)
.map(item => <TypeCard item={item} trans={trans} />)
},
{
});
}
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}
/>
) : (
trans.__('No starred items')
)
});
}
if (showNotebookLauncher) {
builtinSections.push({
className: 'jp-Launcher-openByKernel jp-Launcher-launchNotebook',
title: trans.__('Launch New Notebook'),
icon: notebookIcon,
Expand All @@ -145,8 +217,10 @@ function LauncherBody(props: {
lastUsedChanged={props.lastUsedChanged}
/>
)
},
{
});
}
if (showConsole) {
builtinSections.push({
className: 'jp-Launcher-openByKernel jp-Launcher-launchConsole',
title: trans.__('Launch New Console'),
icon: consoleIcon,
Expand All @@ -165,32 +239,6 @@ function LauncherBody(props: {
lastUsedChanged={props.lastUsedChanged}
/>
)
}
];
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];
Expand Down
6 changes: 6 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,21 @@ export namespace CommandIDs {
export const create = 'launcher:create';
export const moveColumn = 'launchpad:table-move-column';
export const toggleColumn = 'launchpad:table-toggle-column';
export const showCreateEmpty = 'launchpad:show-create-empty';
export const showStarred = 'launchpad:show-starred';
export const showNotebookLauncher = 'launchpad:show-notebook-launcher';
export const showConsoleLauncher = 'launchpad:show-console-launcher';
export const searchAllSections = 'launchpad:search-all-sections';
export const openSettings = 'launchpad:open-settings';
}

export interface ISettingsLayout {
hiddenColumns: Record<string, 'visible' | 'hidden'>;
columnOrder: string[];
createEmptySection: boolean;
starredSection: boolean;
launchNotebookSection: boolean;
launchConsoleSection: boolean;
collapsedSections: Record<string, 'collapsed' | 'expanded'>;
searchAllSections: boolean;
utilityCommands: string[];
Expand Down
14 changes: 13 additions & 1 deletion ui-tests/tests/jupyterlab_new_launcher.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,23 @@ test.describe('Quick Settings', () => {
const launcher = page.locator('.jp-LauncherBody');
await page.locator('.jp-Launcher-QuickSettings').click();
await page
.locator('.lm-Menu-itemLabel:text("Show Starred Section")')
.locator('.lm-Menu-itemLabel:text(\'Show "Starred" Section\')')
.click();
const starredSection = page.locator(
'.jp-CollapsibleSection-Title:has-text("starred")'
);
await expect(starredSection).toBeVisible();
});

test('hide console from quick settings', async ({ page }) => {
const launcher = page.locator('.jp-LauncherBody');
await page.locator('.jp-Launcher-QuickSettings').click();
await page
.locator('.lm-Menu-itemLabel:text(\'Show "Launch New Console" Section\')')
.click();
const starredSection = page.locator(
'.jp-CollapsibleSection-Title:has-text("Launch New Console")'
);
await expect(starredSection).toHaveCount(0);
});
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading