Browse Source

Add Shutdown All handling (#3497)

* Add shtudownall handling

* Combine shutdown commands

* Add dialogs for shutdown all

* Add ellipsis
Steven Silvester 7 năm trước cách đây
mục cha
commit
3e2f8cb04d

+ 1 - 0
packages/mainmenu-extension/package.json

@@ -29,6 +29,7 @@
   },
   "dependencies": {
     "@jupyterlab/application": "^0.14.1",
+    "@jupyterlab/apputils": "^0.14.1",
     "@jupyterlab/mainmenu": "^0.3.1",
     "@phosphor/algorithm": "^1.1.2",
     "@phosphor/widgets": "^1.5.0"

+ 40 - 6
packages/mainmenu-extension/src/index.ts

@@ -1,10 +1,6 @@
 // Copyright (c) Jupyter Development Team.
 // Distributed under the terms of the Modified BSD License.
 
-import {
-  JupyterLab, JupyterLabPlugin
-} from '@jupyterlab/application';
-
 import {
   each
 } from '@phosphor/algorithm';
@@ -13,6 +9,14 @@ import {
   Menu, Widget
 } from '@phosphor/widgets';
 
+import {
+  JupyterLab, JupyterLabPlugin
+} from '@jupyterlab/application';
+
+import {
+  ICommandPalette, showDialog, Dialog
+} from '@jupyterlab/apputils';
+
 import {
   IMainMenu, IMenuExtender, EditMenu, FileMenu, KernelMenu,
   MainMenu, RunMenu, SettingsMenu, ViewMenu, TabsMenu
@@ -63,6 +67,9 @@ namespace CommandIDs {
   export
   const shutdownKernel = 'kernelmenu:shutdown';
 
+  export
+  const shutdownAllKernels = 'kernelmenu:shutdownAll';
+
   export
   const wordWrap = 'viewmenu:word-wrap';
 
@@ -93,8 +100,9 @@ namespace CommandIDs {
  */
 const menuPlugin: JupyterLabPlugin<IMainMenu> = {
   id: '@jupyterlab/mainmenu-extension:plugin',
+  requires: [ICommandPalette],
   provides: IMainMenu,
-  activate: (app: JupyterLab): IMainMenu => {
+  activate: (app: JupyterLab, palette: ICommandPalette): IMainMenu => {
     let menu = new MainMenu(app.commands);
     menu.id = 'jp-MainMenu';
 
@@ -112,6 +120,11 @@ const menuPlugin: JupyterLabPlugin<IMainMenu> = {
     createViewMenu(app, menu.viewMenu);
     createTabsMenu(app, menu.tabsMenu);
 
+    palette.addItem({
+      command: CommandIDs.shutdownAllKernels,
+      category: 'Kernel Operations'
+    });
+
     app.shell.addToTopArea(logo);
     app.shell.addToTopArea(menu);
 
@@ -309,6 +322,26 @@ function createKernelMenu(app: JupyterLab, menu: KernelMenu): void {
     execute: Private.delegateExecute(app, menu.kernelUsers, 'shutdownKernel')
   });
 
+  commands.addCommand(CommandIDs.shutdownAllKernels, {
+    label: 'Shutdown All Kernels...',
+    isEnabled: () => {
+      return app.serviceManager.sessions.running().next() !== undefined;
+    },
+    execute: () => {
+      showDialog({
+        title: 'Shutdown All?',
+        body: 'Shut down all kernels?',
+        buttons: [
+          Dialog.cancelButton(), Dialog.warnButton({ label: 'SHUTDOWN' })
+        ]
+      }).then(result => {
+        if (result.button.accept) {
+          return app.serviceManager.sessions.shutdownAll();
+        }
+      });
+    }
+  });
+
   const restartGroup = [
     CommandIDs.restartKernel,
     CommandIDs.restartKernelAndClear,
@@ -317,7 +350,8 @@ function createKernelMenu(app: JupyterLab, menu: KernelMenu): void {
 
   menu.addGroup([{ command: CommandIDs.interruptKernel }], 0);
   menu.addGroup(restartGroup, 1);
-  menu.addGroup([{ command: CommandIDs.shutdownKernel }], 2);
+  menu.addGroup([{ command: CommandIDs.shutdownKernel },
+                 { command: CommandIDs.shutdownAllKernels }], 2);
   menu.addGroup([{ command: CommandIDs.changeKernel }], 3);
 }
 

+ 28 - 1
packages/running/src/index.ts

@@ -18,7 +18,7 @@ import {
 } from '@phosphor/widgets';
 
 import {
-  DOMUtils
+ Dialog, DOMUtils, showDialog
 } from '@jupyterlab/apputils';
 
 import {
@@ -46,6 +46,11 @@ const HEADER_CLASS = 'jp-RunningSessions-header';
  */
 const REFRESH_CLASS = 'jp-RunningSessions-headerRefresh';
 
+/**
+ * The class name added to a shutdown all button.
+ */
+const SHUTDOWN_CLASS = 'jp-RunningSessions-headerShutdownAll';
+
 /**
  * The class name added to the running terminal sessions section.
  */
@@ -294,15 +299,33 @@ class RunningSessions extends Widget {
     let sessionSection = DOMUtils.findElement(this.node, SESSIONS_CLASS);
     let sessionList = DOMUtils.findElement(sessionSection, LIST_CLASS);
     let refresh = DOMUtils.findElement(this.node, REFRESH_CLASS);
+    let shutdown = DOMUtils.findElement(this.node, SHUTDOWN_CLASS);
     let renderer = this._renderer;
     let clientX = event.clientX;
     let clientY = event.clientY;
 
     // Check for a refresh.
     if (ElementExt.hitTest(refresh, clientX, clientY)) {
+      this.refresh();
       return;
     }
 
+    // Check for a shutdown.
+    if (ElementExt.hitTest(shutdown, clientX, clientY)) {
+      showDialog({
+        title: 'Shutdown All?',
+        body: 'Shut down all kernels and terminals?',
+        buttons: [
+          Dialog.cancelButton(), Dialog.warnButton({ label: 'SHUTDOWN' })
+        ]
+      }).then(result => {
+        if (result.button.accept) {
+          this._manager.sessions.shutdownAll();
+          this._manager.terminals.shutdownAll();
+        }
+      });
+    }
+
     // Create a dummy div if terminals are not available.
     termList = termList || document.createElement('div');
 
@@ -514,6 +537,10 @@ namespace RunningSessions {
       refresh.className = REFRESH_CLASS;
       header.appendChild(refresh);
 
+      let shutdown = document.createElement('button');
+      shutdown.className = SHUTDOWN_CLASS;
+      header.appendChild(shutdown);
+
       node.appendChild(header);
       node.appendChild(terminals);
       node.appendChild(sessions);

+ 24 - 2
packages/running/style/index.css

@@ -52,6 +52,26 @@
 }
 
 
+.jp-RunningSessions-headerShutdownAll {
+  flex: 1 1 auto;
+  height: var(--jp-private-running-button-height);
+  width: var(--jp-private-running-button-width);
+  max-width: 100px;
+  min-width: 16px;
+  min-height: 16px;
+  padding: 4px 6px;
+  background: var(--jp-layout-color1);
+  border: none;
+  outline: 0;
+  background-image: var(--jp-icon-close);
+  background-size: 16px;
+  display: block;
+  vertical-align: middle;
+  background-repeat: no-repeat;
+  background-position: center;
+}
+
+
 .jp-RunningSessions-section {
   display: flex;
   flex: 0 1 auto;
@@ -59,7 +79,8 @@
 }
 
 
-.jp-RunningSessions-headerRefresh:hover {
+.jp-RunningSessions-headerRefresh:hover,
+.jp-RunningSessions-headerShutdownAll:hover {
   background-color: var(--jp-layout-color0);
   box-shadow: var(--jp-toolbar-box-shadow);
   border: 1px solid var(--jp-toolbar-border-color);
@@ -67,7 +88,8 @@
 }
 
 
-.jp-RunningSessions-headerRefresh:active {
+.jp-RunningSessions-headerRefresh:active,
+.jp-RunningSessions-headerShutdownAll:active  {
   border: 1px solid var(--jp-toolbar-border-color);
   background-color: var(--jp-toolbar-active-background);
   box-shadow: var(--jp-toolbar-box-shadow);