// Copyright (c) Jupyter Development Team. // Distributed under the terms of the Modified BSD License. import * as React from 'react'; import { IIterator, toArray } from '@phosphor/algorithm'; import { ISignal, Signal } from '@phosphor/signaling'; import { ReactWidget, UseSignal } from '@jupyterlab/apputils'; import { Dialog, showDialog, ToolbarButtonComponent } from '@jupyterlab/apputils'; import { PathExt } from '@jupyterlab/coreutils'; import { ServiceManager, Session, TerminalSession } from '@jupyterlab/services'; import '../style/index.css'; /** * The class name added to a running widget. */ const RUNNING_CLASS = 'jp-RunningSessions'; /** * The class name added to a running widget header. */ const HEADER_CLASS = 'jp-RunningSessions-header'; /** * The class name added to the running terminal sessions section. */ const SECTION_CLASS = 'jp-RunningSessions-section'; /** * The class name added to the running sessions section header. */ const SECTION_HEADER_CLASS = 'jp-RunningSessions-sectionHeader'; /** * The class name added to a section container. */ const CONTAINER_CLASS = 'jp-RunningSessions-sectionContainer'; /** * The class name added to the running kernel sessions section list. */ const LIST_CLASS = 'jp-RunningSessions-sectionList'; /** * The class name added to the running sessions items. */ const ITEM_CLASS = 'jp-RunningSessions-item'; /** * The class name added to a running session item icon. */ const ITEM_ICON_CLASS = 'jp-RunningSessions-itemIcon'; /** * The class name added to a running session item label. */ const ITEM_LABEL_CLASS = 'jp-RunningSessions-itemLabel'; /** * The class name added to a running session item shutdown button. */ const SHUTDOWN_BUTTON_CLASS = 'jp-RunningSessions-itemShutdown'; /** * The class name added to a notebook icon. */ const NOTEBOOK_ICON_CLASS = 'jp-mod-notebook'; /** * The class name added to a console icon. */ const CONSOLE_ICON_CLASS = 'jp-mod-console'; /** * The class name added to a file icon. */ const FILE_ICON_CLASS = 'jp-mod-file'; /** * The class name added to a terminal icon. */ const TERMINAL_ICON_CLASS = 'jp-mod-terminal'; /** * Properties for a session list displaying items of generic type `M`. */ type SessionProps = { /** * A signal that tracks when the `open` is clicked on a session item. */ openRequested: Signal; /** * The session manager. */ manager: { /** * The function called when the shutdown all button is pressed. */ shutdownAll(): void; /** * A signal that should emit a new list of items whenever they are changed. */ runningChanged: ISignal; /** * Returns a list the running models. */ running(): IIterator; }; /** * The function called when the shutdown button is pressed on an item. */ shutdown: (model: M) => void; /** * The filter that is applied to the items from `runningChanged`. */ filterRunning?: (model: M) => boolean; /** * The name displayed to the user. */ name: string; /** * Returns the icon class for an item. */ iconClass: (model: M) => string; /** * Returns the label for an item. */ label: (model: M) => string; /** * Called to determine the `title` attribute for each item, which is revealed * on hover. */ labelTitle?: (model: M) => string; /** * Flag that sets whether it sessions should be displayed. */ available: boolean; }; function Item(props: SessionProps & { model: M }) { const { model } = props; return (
  • props.openRequested.emit(model)} > {props.label(model)}
  • ); } function ListView(props: { models: M[] } & SessionProps) { const { models, ...rest } = props; return (
      {models.map((m, i) => ( ))}
    ); } function List(props: SessionProps) { const initialModels = toArray(props.manager.running()); const filterRunning = props.filterRunning || (_ => true); function render(models: Array) { return ; } if (!props.available) { return render(initialModels); } return ( {(sender: any, args: Array) => render(args)} ); } /** * The Section component contains the shared look and feel for an interactive * list of kernels and sessions. * * It is specialized for each based on it's props. */ function Section(props: SessionProps) { function onShutdown() { void showDialog({ title: `Shut Down All ${props.name} Sessions?`, buttons: [ Dialog.cancelButton(), Dialog.warnButton({ label: 'SHUT DOWN ALL' }) ] }).then(result => { if (result.button.accept) { props.manager.shutdownAll(); } }); } return (
    {props.available && ( <>

    {props.name} Sessions

    )}
    ); } interface IRunningSessionsProps { manager: ServiceManager.IManager; sessionOpenRequested: Signal; terminalOpenRequested: Signal; } function RunningSessionsComponent({ manager, sessionOpenRequested, terminalOpenRequested }: IRunningSessionsProps) { const terminalsAvailable = manager.terminals.isAvailable(); return ( <>
    { if (terminalsAvailable) { void manager.terminals.refreshRunning(); } void manager.sessions.refreshRunning(); }} />
    `${ITEM_ICON_CLASS} ${TERMINAL_ICON_CLASS}`} label={m => `terminals/${m.name}`} available={terminalsAvailable} shutdown={m => manager.terminals.shutdown(m.name)} />
    !!((m.name || PathExt.basename(m.path)).indexOf('.') !== -1 || m.name) } name="Kernel" iconClass={m => { if ((m.name || PathExt.basename(m.path)).indexOf('.ipynb') !== -1) { return NOTEBOOK_ICON_CLASS; } else if (m.type.toLowerCase() === 'console') { return CONSOLE_ICON_CLASS; } return FILE_ICON_CLASS; }} label={m => m.name || PathExt.basename(m.path)} available={true} labelTitle={m => { let kernelName = m.kernel.name; if (manager.specs) { const spec = manager.specs.kernelspecs[kernelName]; kernelName = spec ? spec.display_name : 'unknown'; } return `Path: ${m.path}\nKernel: ${kernelName}`; }} shutdown={m => manager.sessions.shutdown(m.id)} /> ); } /** * A class that exposes the running terminal and kernel sessions. */ export class RunningSessions extends ReactWidget { /** * Construct a new running widget. */ constructor(options: RunningSessions.IOptions) { super(); this.options = options; // this can't be in the react element, because then it would be too nested this.addClass(RUNNING_CLASS); } protected render() { return ( ); } /** * A signal emitted when a kernel session open is requested. */ get sessionOpenRequested(): ISignal { return this._sessionOpenRequested; } /** * A signal emitted when a terminal session open is requested. */ get terminalOpenRequested(): ISignal { return this._terminalOpenRequested; } private _sessionOpenRequested = new Signal(this); private _terminalOpenRequested = new Signal( this ); private options: RunningSessions.IOptions; } /** * The namespace for the `RunningSessions` class statics. */ export namespace RunningSessions { /** * An options object for creating a running sessions widget. */ export interface IOptions { /** * A service manager instance. */ manager: ServiceManager.IManager; } }