Skip to content

Commit 77f87de

Browse files
jtpiogithub-actions[bot]andrii-i
authored
Close the browser tab when clicking on "Close and Shut Down Notebook" (#6937)
* Close the browser tab when clicking on "Close and Shut Down Notebook" * Move menu entry to match classic * Fix menu entries * Add comment about the rank * Use default `isEnabled` * Update Playwright Snapshots * Update Playwright Snapshots * Add UI test * Rename to "Close and Shut Down Notebook" Co-Authored-By: Andrii Ieroshenko <[email protected]> * Update Playwright Snapshots * Update Playwright Snapshots --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Andrii Ieroshenko <[email protected]>
1 parent 9b9ab51 commit 77f87de

File tree

5 files changed

+66
-1
lines changed

5 files changed

+66
-1
lines changed

packages/application-extension/schema/menus.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@
1414
"command": "notebook:trust",
1515
"rank": 20
1616
},
17+
{
18+
"type": "separator",
19+
"rank": 30
20+
},
21+
{
22+
"command": "filemenu:close-and-cleanup",
23+
"rank": 40
24+
},
1725
{
1826
"command": "application:close",
1927
"disabled": true

packages/notebook-extension/src/index.ts

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import { Text, Time } from '@jupyterlab/coreutils';
1818

1919
import { IDocumentManager } from '@jupyterlab/docmanager';
2020

21+
import { IMainMenu } from '@jupyterlab/mainmenu';
22+
2123
import {
2224
NotebookPanel,
2325
INotebookTracker,
@@ -26,7 +28,7 @@ import {
2628

2729
import { ISettingRegistry } from '@jupyterlab/settingregistry';
2830

29-
import { ITranslator } from '@jupyterlab/translation';
31+
import { ITranslator, nullTranslator } from '@jupyterlab/translation';
3032

3133
import { INotebookShell } from '@jupyter-notebook/application';
3234

@@ -126,6 +128,40 @@ const checkpoints: JupyterFrontEndPlugin<void> = {
126128
},
127129
};
128130

131+
/**
132+
* Add a command to close the browser tab when clicking on "Close and Shut Down"
133+
*/
134+
const closeTab: JupyterFrontEndPlugin<void> = {
135+
id: '@jupyter-notebook/notebook-extension:close-tab',
136+
autoStart: true,
137+
requires: [IMainMenu],
138+
optional: [ITranslator],
139+
activate: (
140+
app: JupyterFrontEnd,
141+
menu: IMainMenu,
142+
translator: ITranslator | null
143+
) => {
144+
const { commands } = app;
145+
translator = translator ?? nullTranslator;
146+
const trans = translator.load('notebook');
147+
148+
const id = 'notebook:close-and-halt';
149+
commands.addCommand(id, {
150+
label: trans.__('Close and Shut Down Notebook'),
151+
execute: async () => {
152+
await commands.execute('notebook:close-and-shutdown');
153+
window.close();
154+
},
155+
});
156+
menu.fileMenu.closeAndCleaners.add({
157+
id,
158+
// use a small rank to it takes precedence over the default
159+
// shut down action for the notebook
160+
rank: 0,
161+
});
162+
},
163+
};
164+
129165
/**
130166
* The kernel logo plugin.
131167
*/
@@ -402,6 +438,7 @@ const trusted: JupyterFrontEndPlugin<void> = {
402438
*/
403439
const plugins: JupyterFrontEndPlugin<any>[] = [
404440
checkpoints,
441+
closeTab,
405442
kernelLogo,
406443
kernelStatus,
407444
scrollOutput,
-20.8 KB
Loading
-19.9 KB
Loading

ui-tests/test/notebook.spec.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,4 +155,24 @@ test.describe('Notebook', () => {
155155
const imageName = 'notebooktools-right-panel.png';
156156
expect(await panel.screenshot()).toMatchSnapshot(imageName);
157157
});
158+
159+
test('Clicking on "Close and Shut Down Notebook" should close the browser tab', async ({
160+
page,
161+
tmpPath,
162+
}) => {
163+
const notebook = 'simple.ipynb';
164+
await page.contents.uploadFile(
165+
path.resolve(__dirname, `./notebooks/${notebook}`),
166+
`${tmpPath}/${notebook}`
167+
);
168+
await page.goto(`notebooks/${tmpPath}/${notebook}`);
169+
170+
const menuPath = 'File>Close and Halt';
171+
await page.menu.clickMenuItem(menuPath);
172+
173+
// Press Enter to confirm the dialog
174+
await page.keyboard.press('Enter');
175+
176+
expect(page.isClosed());
177+
});
158178
});

0 commit comments

Comments
 (0)