diff --git a/dev_mode/package.json b/dev_mode/package.json index 22e3fb06a758..81da47bca702 100644 --- a/dev_mode/package.json +++ b/dev_mode/package.json @@ -66,6 +66,7 @@ "@jupyterlab/settingeditor": "^0.8.1", "@jupyterlab/settingeditor-extension": "^0.14.1", "@jupyterlab/shortcuts-extension": "^0.19.3", + "@jupyterlab/statusbar": "^0.7.1", "@jupyterlab/statusbar-extension": "^0.5.0", "@jupyterlab/tabmanager-extension": "^0.19.1", "@jupyterlab/terminal": "^0.19.1", @@ -279,6 +280,7 @@ "@jupyterlab/settingeditor": "../packages/settingeditor", "@jupyterlab/settingeditor-extension": "../packages/settingeditor-extension", "@jupyterlab/shortcuts-extension": "../packages/shortcuts-extension", + "@jupyterlab/statusbar": "../packages/statusbar", "@jupyterlab/statusbar-extension": "../packages/statusbar-extension", "@jupyterlab/tabmanager-extension": "../packages/tabmanager-extension", "@jupyterlab/terminal": "../packages/terminal", diff --git a/packages/codemirror-extension/package.json b/packages/codemirror-extension/package.json index 347bec62efbf..bea53df61afa 100644 --- a/packages/codemirror-extension/package.json +++ b/packages/codemirror-extension/package.json @@ -32,14 +32,20 @@ }, "dependencies": { "@jupyterlab/application": "^0.19.1", + "@jupyterlab/apputils": "^0.19.1", "@jupyterlab/codeeditor": "^0.19.1", "@jupyterlab/codemirror": "^0.19.1", "@jupyterlab/coreutils": "^2.2.1", "@jupyterlab/docregistry": "^0.19.1", "@jupyterlab/fileeditor": "^0.19.1", "@jupyterlab/mainmenu": "^0.8.1", + "@jupyterlab/statusbar": "^0.7.1", + "@phosphor/commands": "^1.6.1", + "@phosphor/coreutils": "^1.3.0", + "@phosphor/signaling": "^1.2.2", "@phosphor/widgets": "^1.6.0", - "codemirror": "~5.39.0" + "codemirror": "~5.39.0", + "react": "~16.4.2" }, "devDependencies": { "rimraf": "~2.6.2", diff --git a/packages/codemirror-extension/src/index.ts b/packages/codemirror-extension/src/index.ts index 6f3e7aab17de..718757c55176 100644 --- a/packages/codemirror-extension/src/index.ts +++ b/packages/codemirror-extension/src/index.ts @@ -19,6 +19,8 @@ import { IDocumentWidget } from '@jupyterlab/docregistry'; import { IEditorTracker, FileEditor } from '@jupyterlab/fileeditor'; +import { editorSyntaxStatus } from './syntaxstatus'; + /** * The command IDs used by the codemirror plugin. */ @@ -58,7 +60,11 @@ const commands: JupyterLabPlugin = { /** * Export the plugins as default. */ -const plugins: JupyterLabPlugin[] = [commands, services]; +const plugins: JupyterLabPlugin[] = [ + commands, + services, + editorSyntaxStatus +]; export default plugins; /** diff --git a/packages/statusbar-extension/src/defaults/editorSyntax.tsx b/packages/codemirror-extension/src/syntaxstatus.tsx similarity index 84% rename from packages/statusbar-extension/src/defaults/editorSyntax.tsx rename to packages/codemirror-extension/src/syntaxstatus.tsx index a59a4e2bf6b5..064aad59bcc2 100644 --- a/packages/statusbar-extension/src/defaults/editorSyntax.tsx +++ b/packages/codemirror-extension/src/syntaxstatus.tsx @@ -1,28 +1,34 @@ -/** - * Default item to change the language syntax highlighting of the file editor. - */ -/** - * Part of Jupyterlab status bar defaults. - */ import React from 'react'; -import { TextItem } from '../component'; -import { ISignal } from '@phosphor/signaling'; -import { Token } from '@phosphor/coreutils'; import { JupyterLabPlugin, JupyterLab } from '@jupyterlab/application'; -import { IDefaultsManager } from './manager'; -import { IEditorTracker, FileEditor } from '@jupyterlab/fileeditor'; -import { IStatusContext } from '../contexts'; + import { VDomRenderer, VDomModel } from '@jupyterlab/apputils'; -import { IDocumentWidget, DocumentRegistry } from '@jupyterlab/docregistry'; + import { CodeEditor } from '@jupyterlab/codeeditor'; -import { Mode } from '@jupyterlab/codemirror'; + import { IChangedArgs } from '@jupyterlab/coreutils'; + +import { IDocumentWidget, DocumentRegistry } from '@jupyterlab/docregistry'; + +import { IEditorTracker, FileEditor } from '@jupyterlab/fileeditor'; + +import { + IStatusBar, + interactiveItem, + Popup, + showPopup, + TextItem +} from '@jupyterlab/statusbar'; + +import { Mode } from '@jupyterlab/codemirror'; + import { CommandRegistry } from '@phosphor/commands'; + import { JSONObject } from '@phosphor/coreutils'; + +import { ISignal } from '@phosphor/signaling'; + import { Menu } from '@phosphor/widgets'; -import { showPopup, Popup } from '../component/hover'; -import { interactiveItem } from '../style/statusBar'; namespace EditorSyntaxComponent { export interface IProps { @@ -38,6 +44,9 @@ const EditorSyntaxComponent = ( return ; }; +/** + * StatusBar item to change the language syntax highlighting of the file editor. + */ class EditorSyntax extends VDomRenderer implements IEditorSyntax { constructor(opts: EditorSyntax.IOptions) { @@ -199,28 +208,23 @@ export namespace IEditorSyntax { } } -// tslint:disable-next-line:variable-name -export const IEditorSyntax = new Token( - '@jupyterlab/statusbar:IEditorSyntax' -); - -export const editorSyntax: JupyterLabPlugin = { - id: '@jupyterlab/statusbar:editor-syntax-item', +export const editorSyntaxStatus: JupyterLabPlugin = { + id: '@jupyterlab/codemirror-extension:editor-syntax-status', autoStart: true, - provides: IEditorSyntax, - requires: [IDefaultsManager, IEditorTracker], + requires: [IStatusBar, IEditorTracker], activate: ( app: JupyterLab, - manager: IDefaultsManager, + statusBar: IStatusBar, tracker: IEditorTracker ) => { let item = new EditorSyntax({ tracker, commands: app.commands }); - manager.addDefaultStatus('editor-syntax-item', item, { + statusBar.registerStatusItem('editor-syntax-item', item, { align: 'left', - priority: 0, - isActive: IStatusContext.delegateActive(app.shell, [{ tracker }]) + rank: 0, + isActive: () => + app.shell.currentWidget && + tracker.currentWidget && + app.shell.currentWidget === tracker.currentWidget }); - - return item; } }; diff --git a/packages/codemirror-extension/tsconfig.json b/packages/codemirror-extension/tsconfig.json index da45e5c9072a..7466ffa8cc04 100644 --- a/packages/codemirror-extension/tsconfig.json +++ b/packages/codemirror-extension/tsconfig.json @@ -9,6 +9,9 @@ { "path": "../application" }, + { + "path": "../apputils" + }, { "path": "../codeeditor" }, @@ -26,6 +29,9 @@ }, { "path": "../mainmenu" + }, + { + "path": "../statusbar" } ] } diff --git a/packages/filebrowser-extension/package.json b/packages/filebrowser-extension/package.json index c8e191dcc766..4d8d4259c0e3 100644 --- a/packages/filebrowser-extension/package.json +++ b/packages/filebrowser-extension/package.json @@ -37,10 +37,14 @@ "@jupyterlab/filebrowser": "^0.19.3", "@jupyterlab/launcher": "^0.19.1", "@jupyterlab/services": "^3.2.1", + "@jupyterlab/statusbar": "^0.7.1", "@phosphor/algorithm": "^1.1.2", "@phosphor/commands": "^1.6.1", + "@phosphor/disposable": "^1.1.2", "@phosphor/messaging": "^1.2.2", - "@phosphor/widgets": "^1.6.0" + "@phosphor/signaling": "^1.2.2", + "@phosphor/widgets": "^1.6.0", + "react": "~16.4.2" }, "devDependencies": { "rimraf": "~2.6.2", diff --git a/packages/filebrowser-extension/src/index.ts b/packages/filebrowser-extension/src/index.ts index c3544e633244..15fee01879ad 100644 --- a/packages/filebrowser-extension/src/index.ts +++ b/packages/filebrowser-extension/src/index.ts @@ -25,6 +25,8 @@ import { IFileBrowserFactory } from '@jupyterlab/filebrowser'; +import { fileUploadStatus } from './uploadstatus'; + import { Launcher } from '@jupyterlab/launcher'; import { Contents } from '@jupyterlab/services'; @@ -131,7 +133,12 @@ const namespace = 'filebrowser'; /** * Export the plugins as default. */ -const plugins: JupyterLabPlugin[] = [factory, browser, shareFile]; +const plugins: JupyterLabPlugin[] = [ + factory, + browser, + shareFile, + fileUploadStatus +]; export default plugins; /** diff --git a/packages/statusbar-extension/src/defaults/fileUpload.tsx b/packages/filebrowser-extension/src/uploadstatus.tsx similarity index 85% rename from packages/statusbar-extension/src/defaults/fileUpload.tsx rename to packages/filebrowser-extension/src/uploadstatus.tsx index c4d238d8f05b..89b431dafe6a 100644 --- a/packages/statusbar-extension/src/defaults/fileUpload.tsx +++ b/packages/filebrowser-extension/src/uploadstatus.tsx @@ -1,11 +1,5 @@ -/** - * Default item to display file upload progress. - */ -/** - * Part of Jupyterlab status bar defaults. - */ import React from 'react'; -import { TextItem } from '../component/text'; +import { TextItem } from '@jupyterlab/statusbar'; import { JupyterLabPlugin, JupyterLab } from '@jupyterlab/application'; @@ -19,21 +13,20 @@ import { import { IChangedArgs } from '@jupyterlab/coreutils'; import { ISignal } from '@phosphor/signaling'; import { IDisposable } from '@phosphor/disposable'; -import { Token } from '@phosphor/coreutils'; -import { ProgressBar } from '../component/progressBar'; +import { ProgressBar } from '@jupyterlab/statusbar'; import { VDomRenderer, InstanceTracker, VDomModel } from '@jupyterlab/apputils'; import { ArrayExt } from '@phosphor/algorithm'; -import { IDefaultsManager } from './manager'; -import { GroupItem } from '../component/group'; -import vars from '../style/variables'; +import { IStatusBar, GroupItem } from '@jupyterlab/statusbar'; + +const HALF_SPACING = 4; // tslint:disable-next-line:variable-name const FileUploadComponent = ( props: FileUploadComponent.IProps ): React.ReactElement => { return ( - + @@ -48,6 +41,9 @@ namespace FileUploadComponent { const UPLOAD_COMPLETE_MESSAGE_MILLIS: number = 2000; +/** + * Status bar item to display file upload progress. + */ class FileUpload extends VDomRenderer implements IFileUpload { constructor(opts: FileUpload.IOptions) { super(); @@ -181,11 +177,6 @@ export interface IFileUpload extends IDisposable { readonly modelChanged: ISignal; } -// tslint:disable-next-line:variable-name -export const IFileUpload = new Token( - '@jupyterlab/statusbar:IFileUpload' -); - export namespace IFileUpload { export interface IModel { readonly items: Array; @@ -199,28 +190,25 @@ export namespace IFileUpload { } } -export const fileUploadItem: JupyterLabPlugin = { - id: '@jupyterlab/statusbar:file-upload-item', +export const fileUploadStatus: JupyterLabPlugin = { + id: '@jupyterlab/filebrowser-extension:file-upload-item', autoStart: true, - provides: IFileUpload, - requires: [IDefaultsManager, IFileBrowserFactory], + requires: [IStatusBar, IFileBrowserFactory], activate: ( app: JupyterLab, - manager: IDefaultsManager, + statusBar: IStatusBar, browser: IFileBrowserFactory ) => { const item = new FileUpload({ tracker: browser.tracker }); - manager.addDefaultStatus('file-upload-item', item, { + statusBar.registerStatusItem('file-upload-item', item, { align: 'middle', isActive: () => { return !!item.model && item.model.items.length > 0; }, stateChanged: item.model!.stateChanged }); - - return item; } }; diff --git a/packages/filebrowser-extension/tsconfig.json b/packages/filebrowser-extension/tsconfig.json index 99ac9523b03e..35681d6681ff 100644 --- a/packages/filebrowser-extension/tsconfig.json +++ b/packages/filebrowser-extension/tsconfig.json @@ -26,6 +26,9 @@ }, { "path": "../services" + }, + { + "path": "../statusbar" } ] } diff --git a/packages/metapackage/package.json b/packages/metapackage/package.json index 5257017447d8..6d0079f7b18c 100644 --- a/packages/metapackage/package.json +++ b/packages/metapackage/package.json @@ -84,6 +84,7 @@ "@jupyterlab/settingeditor": "^0.8.1", "@jupyterlab/settingeditor-extension": "^0.14.1", "@jupyterlab/shortcuts-extension": "^0.19.3", + "@jupyterlab/statusbar": "^0.7.1", "@jupyterlab/statusbar-extension": "^0.5.0", "@jupyterlab/tabmanager-extension": "^0.19.1", "@jupyterlab/terminal": "^0.19.1", diff --git a/packages/metapackage/tsconfig.json b/packages/metapackage/tsconfig.json index d9495f78c9c6..12900cb211f8 100644 --- a/packages/metapackage/tsconfig.json +++ b/packages/metapackage/tsconfig.json @@ -168,6 +168,9 @@ { "path": "../shortcuts-extension" }, + { + "path": "../statusbar" + }, { "path": "../statusbar-extension" }, diff --git a/packages/notebook-extension/package.json b/packages/notebook-extension/package.json index bdd7928fae57..a3e18e3c9915 100644 --- a/packages/notebook-extension/package.json +++ b/packages/notebook-extension/package.json @@ -42,9 +42,14 @@ "@jupyterlab/notebook": "^0.19.2", "@jupyterlab/rendermime": "^0.19.1", "@jupyterlab/services": "^3.2.1", + "@jupyterlab/statusbar": "^0.7.1", + "@phosphor/algorithm": "^1.1.2", "@phosphor/coreutils": "^1.3.0", + "@phosphor/disposable": "^1.1.2", "@phosphor/messaging": "^1.2.2", - "@phosphor/widgets": "^1.6.0" + "@phosphor/signaling": "^1.2.2", + "@phosphor/widgets": "^1.6.0", + "react": "~16.4.2" }, "devDependencies": { "rimraf": "~2.6.2", diff --git a/packages/notebook-extension/src/index.ts b/packages/notebook-extension/src/index.ts index c29b62fd6d0b..2c4984b6b596 100644 --- a/packages/notebook-extension/src/index.ts +++ b/packages/notebook-extension/src/index.ts @@ -63,6 +63,10 @@ import { Message, MessageLoop } from '@phosphor/messaging'; import { Menu } from '@phosphor/widgets'; +import { commandEditItem } from './modestatus'; + +import { notebookTrustItem } from './truststatus'; + /** * The command IDs used by the notebook plugin. */ @@ -284,7 +288,13 @@ const tools: JupyterLabPlugin = { /** * Export the plugins as default. */ -const plugins: JupyterLabPlugin[] = [factory, trackerPlugin, tools]; +const plugins: JupyterLabPlugin[] = [ + factory, + trackerPlugin, + tools, + commandEditItem, + notebookTrustItem +]; export default plugins; /** diff --git a/packages/statusbar-extension/src/defaults/commandEdit.tsx b/packages/notebook-extension/src/modestatus.tsx similarity index 82% rename from packages/statusbar-extension/src/defaults/commandEdit.tsx rename to packages/notebook-extension/src/modestatus.tsx index 2587aa505ab7..a624137d0a1a 100644 --- a/packages/statusbar-extension/src/defaults/commandEdit.tsx +++ b/packages/notebook-extension/src/modestatus.tsx @@ -1,13 +1,9 @@ -/** - * Default item to display which notebook mode user is in. - */ -/** - * Part of Jupyterlab status bar defaults. - */ import * as React from 'react'; import { JupyterLabPlugin, JupyterLab } from '@jupyterlab/application'; +import { VDomRenderer, VDomModel } from '@jupyterlab/apputils'; + import { INotebookTracker, Notebook, @@ -15,17 +11,11 @@ import { NotebookMode } from '@jupyterlab/notebook'; -import { IDefaultsManager } from './manager'; - -import { TextItem } from '../component/text'; +import { IStatusBar, TextItem, TextExt } from '@jupyterlab/statusbar'; -import { VDomRenderer, VDomModel } from '@jupyterlab/apputils'; -// import { CommandRegistry } from '@phosphor/commands'; import { ISignal } from '@phosphor/signaling'; + import { IDisposable } from '@phosphor/disposable'; -import { Token } from '@phosphor/coreutils'; -import { IStatusContext } from '../contexts'; -import { TextExt } from '../util/text'; // tslint:disable-next-line:variable-name const CommandEditComponent = ( @@ -40,6 +30,9 @@ namespace CommandEditComponent { } } +/** + * StatusBar item to display which notebook mode user is in. + */ class CommandEdit extends VDomRenderer implements ICommandEdit { constructor(opts: CommandEdit.IOptions) { @@ -162,31 +155,26 @@ export namespace ICommandEdit { } } -// tslint:disable-next-line:variable-name -export const ICommandEdit = new Token( - '@jupyterlab/statusbar:ICommandEdit' -); - -export const commandEditItem: JupyterLabPlugin = { - id: '@jupyterlab/statusbar:command-edit-item', +export const commandEditItem: JupyterLabPlugin = { + id: '@jupyterlab/notebook-extension:mode-status', autoStart: true, - provides: ICommandEdit, - requires: [IDefaultsManager, INotebookTracker], + requires: [IStatusBar, INotebookTracker], activate: ( app: JupyterLab, - manager: IDefaultsManager, + statusBar: IStatusBar, tracker: INotebookTracker ) => { const item = new CommandEdit({ tracker }); - manager.addDefaultStatus('command-edit-item', item, { + statusBar.registerStatusItem('command-edit-item', item, { align: 'right', - priority: 4, - isActive: IStatusContext.delegateActive(app.shell, [{ tracker }]) + rank: 4, + isActive: () => + app.shell.currentWidget && + tracker.currentWidget && + app.shell.currentWidget === tracker.currentWidget }); - - return item; } }; diff --git a/packages/statusbar-extension/src/defaults/notebookTrust.tsx b/packages/notebook-extension/src/truststatus.tsx similarity index 90% rename from packages/statusbar-extension/src/defaults/notebookTrust.tsx rename to packages/notebook-extension/src/truststatus.tsx index 1019872f9f24..c1317ad9dee9 100644 --- a/packages/statusbar-extension/src/defaults/notebookTrust.tsx +++ b/packages/notebook-extension/src/truststatus.tsx @@ -7,21 +7,25 @@ import React from 'react'; import { JupyterLabPlugin, JupyterLab } from '@jupyterlab/application'; + +import { VDomRenderer, VDomModel } from '@jupyterlab/apputils'; + import { INotebookTracker, NotebookPanel, INotebookModel, Notebook } from '@jupyterlab/notebook'; -import { toArray } from '@phosphor/algorithm'; -import { IDefaultsManager } from './manager'; + import { Cell } from '@jupyterlab/cells'; -import { VDomRenderer, VDomModel } from '@jupyterlab/apputils'; + +import { IconItem, IStatusBar } from '@jupyterlab/statusbar'; + +import { toArray } from '@phosphor/algorithm'; + import { IDisposable } from '@phosphor/disposable'; + import { ISignal } from '@phosphor/signaling'; -import { Token } from '@phosphor/coreutils'; -import { IconItem } from '../component/icon'; -import { IStatusContext } from '../contexts'; export const cellStatus = ( prop: NotebookTrustComponent.IProps | NotebookTrust.Model @@ -267,29 +271,24 @@ export namespace INotebookTrust { } } -// tslint:disable-next-line:variable-name -export const INotebookTrust = new Token( - '@jupyterlab/statusbar:INotebookTrust' -); - -export const notebookTrustItem: JupyterLabPlugin = { - id: '@jupyterlab/statusbar:trusted-notebook-item', +export const notebookTrustItem: JupyterLabPlugin = { + id: '@jupyterlab/notebook-extension:trust-status', autoStart: true, - provides: INotebookTrust, - requires: [IDefaultsManager, INotebookTracker], + requires: [IStatusBar, INotebookTracker], activate: ( app: JupyterLab, - manager: IDefaultsManager, + statusBar: IStatusBar, tracker: INotebookTracker ) => { const item = new NotebookTrust({ tracker }); - manager.addDefaultStatus('notebook-trust-item', item, { + statusBar.registerStatusItem('notebook-trust-item', item, { align: 'right', - priority: 3, - isActive: IStatusContext.delegateActive(app.shell, [{ tracker }]) + rank: 3, + isActive: () => + app.shell.currentWidget && + tracker.currentWidget && + app.shell.currentWidget === tracker.currentWidget }); - - return item; } }; diff --git a/packages/notebook-extension/tsconfig.json b/packages/notebook-extension/tsconfig.json index 794486f3b159..56d36e8af0dd 100644 --- a/packages/notebook-extension/tsconfig.json +++ b/packages/notebook-extension/tsconfig.json @@ -38,6 +38,9 @@ }, { "path": "../services" + }, + { + "path": "../statusbar" } ] } diff --git a/packages/statusbar-extension/package.json b/packages/statusbar-extension/package.json index 73da9d375ab6..5b3ef870b74f 100644 --- a/packages/statusbar-extension/package.json +++ b/packages/statusbar-extension/package.json @@ -37,16 +37,14 @@ "@jupyterlab/apputils": "^0.19.1", "@jupyterlab/cells": "^0.19.1", "@jupyterlab/codeeditor": "^0.19.1", - "@jupyterlab/codemirror": "^0.19.1", "@jupyterlab/console": "^0.19.1", "@jupyterlab/coreutils": "^2.2.1", "@jupyterlab/docmanager": "^0.19.1", "@jupyterlab/docregistry": "^0.19.1", - "@jupyterlab/filebrowser": "^0.19.3", "@jupyterlab/fileeditor": "^0.19.1", "@jupyterlab/notebook": "^0.19.2", "@jupyterlab/services": "^3.2.1", - "@phosphor/algorithm": "^1.1.2", + "@jupyterlab/statusbar": "^0.7.1", "@phosphor/commands": "^1.6.1", "@phosphor/coreutils": "^1.3.0", "@phosphor/disposable": "^1.1.2", @@ -59,9 +57,7 @@ "devDependencies": { "@types/react": "~16.4.13", "@types/react-dom": "~16.0.7", - "prettier": "^1.14.2", "rimraf": "~2.6.2", - "tslint": "~5.10.0", "typedoc": "~0.12.0", "typescript": "~3.1.1" }, diff --git a/packages/statusbar-extension/src/defaults/filePath.tsx b/packages/statusbar-extension/src/defaults/filePath.tsx index bb1a634c011a..a502607950fe 100644 --- a/packages/statusbar-extension/src/defaults/filePath.tsx +++ b/packages/statusbar-extension/src/defaults/filePath.tsx @@ -11,16 +11,22 @@ import { JupyterLab, ApplicationShell } from '@jupyterlab/application'; -import { IDefaultsManager } from './manager'; -import { TextItem } from '../component/text'; -import { DocumentRegistry } from '@jupyterlab/docregistry'; + import { VDomModel, VDomRenderer } from '@jupyterlab/apputils'; + +import { PathExt } from '@jupyterlab/coreutils'; + +import { IDocumentManager } from '@jupyterlab/docmanager'; + +import { DocumentRegistry } from '@jupyterlab/docregistry'; + +import { IStatusBar, TextItem } from '@jupyterlab/statusbar'; + import { IDisposable } from '@phosphor/disposable'; + import { ISignal } from '@phosphor/signaling'; -import { Token } from '@phosphor/coreutils'; -import { PathExt } from '@jupyterlab/coreutils'; + import { Widget, Title } from '@phosphor/widgets'; -import { IDocumentManager } from '@jupyterlab/docmanager'; namespace FilePathComponent { export interface IProps { @@ -193,31 +199,23 @@ export namespace IFilePath { } } -// tslint:disable-next-line:variable-name -export const IFilePath = new Token( - '@jupyterlab/statusbar:IFilePath' -); - -export const filePathItem: JupyterLabPlugin = { - id: '@jupyterlab/statusbar:file-path-item', +export const filePathStatus: JupyterLabPlugin = { + id: '@jupyterlab/statusbar:file-path-status', autoStart: true, - provides: IFilePath, - requires: [IDefaultsManager, IDocumentManager], + requires: [IStatusBar, IDocumentManager], activate: ( app: JupyterLab, - manager: IDefaultsManager, + statusBar: IStatusBar, docManager: IDocumentManager ) => { let item = new FilePath({ shell: app.shell, docManager }); - manager.addDefaultStatus('file-path-item', item, { + statusBar.registerStatusItem('file-path-item', item, { align: 'right', - priority: 0, + rank: 0, isActive: () => { return true; } }); - - return item; } }; diff --git a/packages/statusbar-extension/src/defaults/index.ts b/packages/statusbar-extension/src/defaults/index.ts index e262cd2bcc57..7c6ff590a127 100644 --- a/packages/statusbar-extension/src/defaults/index.ts +++ b/packages/statusbar-extension/src/defaults/index.ts @@ -1,12 +1,7 @@ -export * from './notebookTrust'; -export * from './manager'; export * from './lineCol'; -export * from './fileUpload'; export * from './kernelStatus'; -export * from './commandEdit'; export * from './runningSessions'; export * from './filePath'; export * from './tabSpace'; -export * from './editorSyntax'; export * from './memoryUsage'; export * from './savingStatus'; diff --git a/packages/statusbar-extension/src/defaults/kernelStatus.tsx b/packages/statusbar-extension/src/defaults/kernelStatus.tsx index 30158bf6416f..8d35c8679012 100644 --- a/packages/statusbar-extension/src/defaults/kernelStatus.tsx +++ b/packages/statusbar-extension/src/defaults/kernelStatus.tsx @@ -5,7 +5,6 @@ * Part of Jupyterlab status bar defaults. */ import React from 'react'; -import { TextItem } from '../component/text'; import { JupyterLabPlugin, @@ -13,23 +12,32 @@ import { ApplicationShell } from '@jupyterlab/application'; +import { IClientSession, VDomRenderer, VDomModel } from '@jupyterlab/apputils'; + +import { IConsoleTracker, ConsolePanel } from '@jupyterlab/console'; + import { INotebookTracker, NotebookPanel } from '@jupyterlab/notebook'; -import { IDefaultsManager } from './manager'; +import { Kernel, Session } from '@jupyterlab/services'; + +import { + interactiveItem, + IStatusBar, + TextItem, + TextExt +} from '@jupyterlab/statusbar'; + +import { CommandRegistry } from '@phosphor/commands'; -import { IConsoleTracker, ConsolePanel } from '@jupyterlab/console'; -import { IClientSession, VDomRenderer, VDomModel } from '@jupyterlab/apputils'; -import { ISignal } from '@phosphor/signaling'; -import { Token } from '@phosphor/coreutils'; import { IDisposable } from '@phosphor/disposable'; -import { Kernel, Session } from '@jupyterlab/services'; + +import { Message } from '@phosphor/messaging'; + +import { ISignal, Signal } from '@phosphor/signaling'; + import { Widget } from '@phosphor/widgets'; + import { IStatusContext } from '../contexts'; -import { TextExt } from '../util/text'; -import { CommandRegistry } from '@phosphor/commands'; -import { interactiveItem } from '../style/statusBar'; -import { Message } from '@phosphor/messaging'; -import { IFilePath } from './filePath'; // tslint:disable-next-line:variable-name const KernelStatusComponent = ( @@ -62,22 +70,21 @@ class KernelStatus extends VDomRenderer this._consoleTracker = opts.consoleTracker; this._commands = opts.commands; this._shell = opts.shell; - this._filePath = opts.filePath; - this._shell.currentChanged.connect(this._onMainAreaCurrentChange); - this._filePath.model!.stateChanged.connect(this._onFilePathChange); + this._shell.currentChanged.connect( + this._onCurrentChanged, + this + ); this.model = new KernelStatus.Model( this._getFocusedSession(this._shell.currentWidget) ); - if (this.model!.type === 'notebook') { - this.addClass(interactiveItem); - } - - this._onFilePathChange(); + this.addClass(interactiveItem); } + readonly model: KernelStatus.Model; + render() { if (this.model === null) { return null; @@ -94,40 +101,30 @@ class KernelStatus extends VDomRenderer dispose() { super.dispose(); - - this._shell.currentChanged.disconnect(this._onMainAreaCurrentChange); + Signal.disconnectAll(this); + this._shell.currentChanged.disconnect(this._onCurrentChanged); } protected onUpdateRequest(msg: Message) { - this.model!.session = this._getFocusedSession(this._shell.currentWidget); - - if (this.model!.type === 'notebook') { - this.addClass(interactiveItem); - } else { - this.removeClass(interactiveItem); - } - + this.model.session = this._getFocusedSession(this._shell.currentWidget); super.onUpdateRequest(msg); } private _handleClick = () => { - if (this.model!.type === 'notebook') { - this._commands.execute('notebook:change-kernel'); - } + // The kernel menu flavor of change kernel delegates + // based on the active widget, so use that. + this._commands.execute('kernelmenu:change'); }; - private _onFilePathChange = () => { - if (this.model!.type === 'notebook') { - this.node.title = `Change active kernel for ${ - this._filePath.model!.name - }`; - } else { - this.node.title = `Active kernel type for ${this._filePath.model!.name}`; - } + private _onTitleChanged = () => { + const name = this._shell.currentWidget + ? this._shell.currentWidget.title.label + : 'activity'; + this.node.title = `Change active kernel for ${name}`; }; private _getFocusedSession(val: Widget | null): IClientSession | null { - if (val === null) { + if (!val) { return null; } else { if (this._notebookTracker.has(val)) { @@ -140,25 +137,27 @@ class KernelStatus extends VDomRenderer } } - private _onMainAreaCurrentChange = ( + private _onCurrentChanged( shell: ApplicationShell, change: ApplicationShell.IChangedArgs - ) => { - const { newValue } = change; - const editor = this._getFocusedSession(newValue); - this.model!.session = editor; - if (this.model!.type === 'notebook') { - this.addClass(interactiveItem); - } else { - this.removeClass(interactiveItem); + ): void { + if (this._current) { + this._current.title.changed.disconnect(this._onTitleChanged, this); } - }; + this._current = change.newValue; + this._current.title.changed.connect( + this._onTitleChanged, + this + ); + const session = this._getFocusedSession(this._current); + this.model.session = session; + } + private _current: Widget | undefined; private _notebookTracker: INotebookTracker; private _consoleTracker: IConsoleTracker; private _shell: ApplicationShell; private _commands: CommandRegistry; - private _filePath: IFilePath; } namespace KernelStatus { @@ -255,7 +254,6 @@ namespace KernelStatus { consoleTracker: IConsoleTracker; shell: ApplicationShell; commands: CommandRegistry; - filePath: IFilePath; } } @@ -273,39 +271,30 @@ export namespace IKernelStatus { } } -// tslint:disable-next-line:variable-name -export const IKernelStatus = new Token( - '@jupyterlab/statusbar:IKernelStatus' -); - -export const kernelStatusItem: JupyterLabPlugin = { - id: '@jupyterlab/statusbar:kernel-status-item', +export const kernelStatus: JupyterLabPlugin = { + id: '@jupyterlab/statusbar:kernel-status', autoStart: true, - requires: [IDefaultsManager, INotebookTracker, IConsoleTracker, IFilePath], + requires: [IStatusBar, INotebookTracker, IConsoleTracker], activate: ( app: JupyterLab, - manager: IDefaultsManager, + statusBar: IStatusBar, notebookTracker: INotebookTracker, - consoleTracker: IConsoleTracker, - filePath: IFilePath + consoleTracker: IConsoleTracker ) => { const item = new KernelStatus({ shell: app.shell, notebookTracker, consoleTracker, - commands: app.commands, - filePath + commands: app.commands }); - manager.addDefaultStatus('kernel-status-item', item, { + statusBar.registerStatusItem('kernel-status-item', item, { align: 'left', - priority: 1, + rank: 1, isActive: IStatusContext.delegateActive(app.shell, [ { tracker: notebookTracker }, { tracker: consoleTracker } ]) }); - - return item; } }; diff --git a/packages/statusbar-extension/src/defaults/lineCol.tsx b/packages/statusbar-extension/src/defaults/lineCol.tsx index 76d284a06be7..2ce6e0d02894 100644 --- a/packages/statusbar-extension/src/defaults/lineCol.tsx +++ b/packages/statusbar-extension/src/defaults/lineCol.tsx @@ -4,31 +4,55 @@ /** * Part of Jupyterlab status bar defaults. */ + import React from 'react'; -import { TextItem } from '../component/text'; + import { JupyterLabPlugin, JupyterLab, ApplicationShell } from '@jupyterlab/application'; -import { INotebookTracker, NotebookPanel } from '@jupyterlab/notebook'; + import { VDomRenderer, VDomModel, ReactElementWidget } from '@jupyterlab/apputils'; -import { CodeEditor } from '@jupyterlab/codeeditor'; -import { IEditorTracker, FileEditor } from '@jupyterlab/fileeditor'; -import { ISignal } from '@phosphor/signaling'; + import { Cell, CodeCell } from '@jupyterlab/cells'; + +import { + IConsoleTracker, + ConsolePanel, + CodeConsole +} from '@jupyterlab/console'; + +import { CodeEditor } from '@jupyterlab/codeeditor'; + import { IDocumentWidget } from '@jupyterlab/docregistry'; + +import { IEditorTracker, FileEditor } from '@jupyterlab/fileeditor'; + +import { INotebookTracker, NotebookPanel } from '@jupyterlab/notebook'; + +import { + IStatusBar, + interactiveItem, + showPopup, + Popup, + TextItem +} from '@jupyterlab/statusbar'; + import { IDisposable } from '@phosphor/disposable'; -import { Token } from '@phosphor/coreutils'; + +import { Message } from '@phosphor/messaging'; + +import { ISignal } from '@phosphor/signaling'; + import { Widget } from '@phosphor/widgets'; + import { IStatusContext } from '../contexts'; -import { showPopup, Popup } from '../component/hover'; -import { IDefaultsManager } from './manager'; -import { interactiveItem } from '../style/statusBar'; + import { lineFormWrapper, lineFormInput, @@ -37,13 +61,8 @@ import { lineFormCaption, lineFormButton } from '../style/lineForm'; + import { classes } from 'typestyle/lib'; -import { Message } from '@phosphor/messaging'; -import { - IConsoleTracker, - ConsolePanel, - CodeConsole -} from '@jupyterlab/console'; namespace LineForm { export interface IProps { @@ -383,22 +402,13 @@ export namespace ILineCol { } } -// tslint:disable-next-line:variable-name -export const ILineCol = new Token('@jupyterlab/statusbar:ILineCol'); - -export const lineColItem: JupyterLabPlugin = { +export const lineColItem: JupyterLabPlugin = { id: '@jupyterlab/statusbar:line-col-item', autoStart: true, - provides: ILineCol, - requires: [ - IDefaultsManager, - INotebookTracker, - IEditorTracker, - IConsoleTracker - ], + requires: [IStatusBar, INotebookTracker, IEditorTracker, IConsoleTracker], activate: ( app: JupyterLab, - defaultsManager: IDefaultsManager, + statusBar: IStatusBar, notebookTracker: INotebookTracker, editorTracker: IEditorTracker, consoleTracker: IConsoleTracker @@ -410,16 +420,14 @@ export const lineColItem: JupyterLabPlugin = { consoleTracker }); - defaultsManager.addDefaultStatus('line-col-item', item, { + statusBar.registerStatusItem('line-col-item', item, { align: 'right', - priority: 2, + rank: 2, isActive: IStatusContext.delegateActive(app.shell, [ { tracker: notebookTracker }, { tracker: editorTracker }, { tracker: consoleTracker } ]) }); - - return item; } }; diff --git a/packages/statusbar-extension/src/defaults/manager.ts b/packages/statusbar-extension/src/defaults/manager.ts deleted file mode 100644 index 46ed8b45d04a..000000000000 --- a/packages/statusbar-extension/src/defaults/manager.ts +++ /dev/null @@ -1,168 +0,0 @@ -import { Token } from '@phosphor/coreutils'; -import { ISettingRegistry } from '@jupyterlab/coreutils'; -import { IStatusBar } from '../statusBar'; -import { JupyterLab, JupyterLabPlugin } from '@jupyterlab/application'; -import { STATUSBAR_PLUGIN_ID } from '..'; -import { SetExt } from '../util/set'; -import { Widget } from '@phosphor/widgets'; -import { Signal } from '@phosphor/signaling'; -import { IDisposable } from '@phosphor/disposable'; -import { SignalExt } from '../util/signal'; -import { SettingsConnector } from '../util/settings'; - -export interface IDefaultsManager { - addDefaultStatus( - id: string, - widget: Widget, - opts: IStatusBar.IItemOptions - ): void; -} - -export namespace IDefaultsManager { - export interface IItem { - id: string; - item: Widget; - opts: IStatusBar.IItemOptions; - } -} - -// tslint:disable-next-line:variable-name -export const IDefaultsManager = new Token( - '@jupyterlab/statusbar:IDefaultStatusesManager' -); - -class DefaultsManager implements IDefaultsManager, IDisposable { - constructor(opts: DefaultsManager.IOptions) { - this._statusBar = opts.statusBar; - this._settingsConnector = new SettingsConnector({ - pluginId: STATUSBAR_PLUGIN_ID, - registry: opts.settings, - settingKey: 'enabledDefaultItems' - }); - - this._settingsConnector.changed.connect(this._onSettingsUpdated); - } - - addDefaultStatus( - id: string, - item: Widget, - opts: IStatusBar.IItemOptions - ): void { - // Combine settings and provided isActive function - if (opts.isActive === undefined) { - opts.isActive = () => { - return this._enabledStatusIds.has(id); - }; - } else { - const prevIsActive = opts.isActive; - opts.isActive = () => { - return prevIsActive() && this._enabledStatusIds.has(id); - }; - } - - // Combine stateChanged of settings with provided stateChanged - const stateChanged: SignalExt.CombinedSignal< - this, - void - > = new SignalExt.CombinedSignal(this); - if (opts.stateChanged === undefined) { - opts.stateChanged = stateChanged; - } else { - opts.stateChanged = new SignalExt.CombinedSignal( - this, - opts.stateChanged, - stateChanged - ); - } - - const defaultItem = { - id, - item, - opts, - stateChanged - }; - - this._statusBar.registerStatusItem(id, item, opts); - this._allDefaultStatusItems.set(id, defaultItem); - } - - get isDisposed() { - return this._isDisposed; - } - - dispose() { - if (this.isDisposed) { - return; - } - - Signal.clearData(this); - this._settingsConnector.dispose(); - this._allDefaultStatusItems.forEach(item => { - item.stateChanged.dispose(); - }); - this._isDisposed = true; - } - - private _onSettingsUpdated = ( - connector: SettingsConnector, - change: SettingsConnector.IChangedArgs - ) => { - let rawEnabledItems = change.newValue !== null ? change.newValue : []; - - let newEnabledItems = new Set(rawEnabledItems); - - let idsToRemove = SetExt.difference( - this._enabledStatusIds, - newEnabledItems - ); - - let idsToAdd = SetExt.difference(newEnabledItems, this._enabledStatusIds); - - SetExt.deleteAll(this._enabledStatusIds, [...idsToRemove]); - SetExt.addAll(this._enabledStatusIds, [...idsToAdd]); - - [...idsToAdd, ...idsToRemove].forEach(val => { - const statusItem = this._allDefaultStatusItems.get(val); - if (statusItem !== undefined) { - statusItem.stateChanged.emit(void 0); - } - }); - }; - - private _allDefaultStatusItems: Map< - string, - DefaultsManager.IItem - > = new Map(); - private _enabledStatusIds: Set = new Set(); - private _isDisposed: boolean = false; - private _settingsConnector: SettingsConnector; - private _statusBar: IStatusBar; -} - -namespace DefaultsManager { - export interface IOptions { - settings: ISettingRegistry; - statusBar: IStatusBar; - } - - export interface IItem extends IDefaultsManager.IItem { - stateChanged: SignalExt.CombinedSignal; - } -} - -/** - * Initialization data for the statusbar extension. - */ -export const defaultsManager: JupyterLabPlugin = { - id: '@jupyterlab/statusbar:defaults-manager', - provides: IDefaultsManager, - autoStart: true, - requires: [ISettingRegistry, IStatusBar], - activate: ( - _app: JupyterLab, - settings: ISettingRegistry, - statusBar: IStatusBar - ) => { - return new DefaultsManager({ settings, statusBar }); - } -}; diff --git a/packages/statusbar-extension/src/defaults/memoryUsage.tsx b/packages/statusbar-extension/src/defaults/memoryUsage.tsx index 7f1532c3ef6d..f85390ee541e 100644 --- a/packages/statusbar-extension/src/defaults/memoryUsage.tsx +++ b/packages/statusbar-extension/src/defaults/memoryUsage.tsx @@ -5,15 +5,20 @@ * Part of Jupyterlab status bar defaults. */ import React from 'react'; -import { ISignal } from '@phosphor/signaling'; -import { IDisposable } from '@phosphor/disposable'; -import { Token } from '@phosphor/coreutils'; + import { JupyterLabPlugin, JupyterLab } from '@jupyterlab/application'; -import { IDefaultsManager } from './manager'; + import { VDomModel, VDomRenderer } from '@jupyterlab/apputils'; -import { ServerConnection } from '@jupyterlab/services'; + import { URLExt } from '@jupyterlab/coreutils'; -import { TextItem } from '../component'; + +import { IStatusBar, TextItem } from '@jupyterlab/statusbar'; + +import { ServerConnection } from '@jupyterlab/services'; + +import { IDisposable } from '@phosphor/disposable'; + +import { ISignal } from '@phosphor/signaling'; class MemoryUsage extends VDomRenderer implements IMemoryUsage { @@ -248,26 +253,18 @@ namespace Private { } } -// tslint:disable-next-line:variable-name -export const IMemoryUsage = new Token( - '@jupyterlab/statusbar:IMemoryUsage' -); - -export const memoryUsageItem: JupyterLabPlugin = { +export const memoryUsageItem: JupyterLabPlugin = { id: '@jupyterlab/statusbar:memory-usage-item', autoStart: true, - provides: IMemoryUsage, - requires: [IDefaultsManager], - activate: (app: JupyterLab, defaultsManager: IDefaultsManager) => { + requires: [IStatusBar], + activate: (app: JupyterLab, statusBar: IStatusBar) => { let item = new MemoryUsage(); - defaultsManager.addDefaultStatus('memory-usage-item', item, { + statusBar.registerStatusItem('memory-usage-item', item, { align: 'left', - priority: 2, + rank: 2, isActive: () => item.model!.metricsAvailable, stateChanged: item.model!.stateChanged }); - - return item; } }; diff --git a/packages/statusbar-extension/src/defaults/runningSessions.tsx b/packages/statusbar-extension/src/defaults/runningSessions.tsx index c39000ec1963..255965bb0c4d 100644 --- a/packages/statusbar-extension/src/defaults/runningSessions.tsx +++ b/packages/statusbar-extension/src/defaults/runningSessions.tsx @@ -5,13 +5,15 @@ * Part of Jupyterlab status bar defaults. */ import React from 'react'; -import { IconItem } from '../component/icon'; -import { TextItem } from '../component/text'; + import { JupyterLabPlugin, JupyterLab, ApplicationShell } from '@jupyterlab/application'; + +import { VDomRenderer, VDomModel } from '@jupyterlab/apputils'; + import { ServiceManager, Kernel, @@ -19,26 +21,32 @@ import { TerminalManager, SessionManager } from '@jupyterlab/services'; -import { VDomRenderer, VDomModel } from '@jupyterlab/apputils'; -import { ISignal } from '@phosphor/signaling'; + +import { + GroupItem, + IconItem, + IStatusBar, + interactiveItem, + TextItem +} from '@jupyterlab/statusbar'; + import { IDisposable } from '@phosphor/disposable'; -import { Token } from '@phosphor/coreutils'; -import { IDefaultsManager } from './manager'; -import { GroupItem } from '../component/group'; -import vars from '../style/variables'; -import { interactiveItem } from '../style/statusBar'; + +import { ISignal } from '@phosphor/signaling'; + +const HALF_SPACING = 4; // tslint:disable-next-line:variable-name const RunningSessionsComponent = ( props: RunningSessionsComponent.IProps ): React.ReactElement => { return ( - - + + - + @@ -169,30 +177,22 @@ export namespace IRunningSessions { } } -// tslint:disable-next-line:variable-name -export const IRunningSessions = new Token( - '@jupyterlab/statusbar:IRunningSessions' -); - /* * Initialization data for the statusbar extension. */ -export const runningSessionsItem: JupyterLabPlugin = { +export const runningSessionsItem: JupyterLabPlugin = { id: '@jupyterlab/statusbar:running-sessions-item', autoStart: true, - provides: IRunningSessions, - requires: [IDefaultsManager], - activate: (app: JupyterLab, manager: IDefaultsManager) => { + requires: [IStatusBar], + activate: (app: JupyterLab, statusBar: IStatusBar) => { const item = new RunningSessions({ host: app.shell, serviceManager: app.serviceManager }); - manager.addDefaultStatus('running-sessions-item', item, { + statusBar.registerStatusItem('running-sessions-item', item, { align: 'left', - priority: 0 + rank: 0 }); - - return item; } }; diff --git a/packages/statusbar-extension/src/defaults/savingStatus.tsx b/packages/statusbar-extension/src/defaults/savingStatus.tsx index 757bcb17a760..f289789d737b 100644 --- a/packages/statusbar-extension/src/defaults/savingStatus.tsx +++ b/packages/statusbar-extension/src/defaults/savingStatus.tsx @@ -5,15 +5,20 @@ import { JupyterLab, ApplicationShell } from '@jupyterlab/application'; -import { IDefaultsManager } from './manager'; -import { TextItem } from '../component/text'; -import { DocumentRegistry } from '@jupyterlab/docregistry'; + import { VDomModel, VDomRenderer } from '@jupyterlab/apputils'; + +import { IDocumentManager } from '@jupyterlab/docmanager'; + +import { DocumentRegistry } from '@jupyterlab/docregistry'; + +import { IStatusBar, TextItem } from '@jupyterlab/statusbar'; + import { IDisposable } from '@phosphor/disposable'; + import { ISignal } from '@phosphor/signaling'; -import { Token } from '@phosphor/coreutils'; + import { Widget } from '@phosphor/widgets'; -import { IDocumentManager } from '@jupyterlab/docmanager'; namespace SavingStatusComponent { export interface IProps { @@ -150,31 +155,23 @@ export namespace ISavingStatus { } } -// tslint:disable-next-line:variable-name -export const ISavingStatus = new Token( - '@jupyterlab/statusbar:ISavingStatus' -); - -export const savingStatusItem: JupyterLabPlugin = { +export const savingStatusItem: JupyterLabPlugin = { id: '@jupyterlab/statusbar:saving-status-item', autoStart: true, - provides: ISavingStatus, - requires: [IDefaultsManager, IDocumentManager], + requires: [IStatusBar, IDocumentManager], activate: ( app: JupyterLab, - manager: IDefaultsManager, + statusBar: IStatusBar, docManager: IDocumentManager ) => { let item = new SavingStatus({ shell: app.shell, docManager }); - manager.addDefaultStatus('saving-status-item', item, { + statusBar.registerStatusItem('saving-status-item', item, { align: 'middle', isActive: () => { return true; }, stateChanged: item.model!.stateChanged }); - - return item; } }; diff --git a/packages/statusbar-extension/src/defaults/tabSpace.tsx b/packages/statusbar-extension/src/defaults/tabSpace.tsx index f3becd0a5a84..109b0d44e968 100644 --- a/packages/statusbar-extension/src/defaults/tabSpace.tsx +++ b/packages/statusbar-extension/src/defaults/tabSpace.tsx @@ -5,33 +5,48 @@ * Part of Jupyterlab status bar defaults. */ import React from 'react'; -import { TextItem } from '../component/text'; import { JupyterLabPlugin, JupyterLab, ApplicationShell } from '@jupyterlab/application'; -import { INotebookTracker, NotebookPanel } from '@jupyterlab/notebook'; + import { VDomRenderer, VDomModel } from '@jupyterlab/apputils'; -import { IEditorTracker } from '@jupyterlab/fileeditor'; -import { ISignal } from '@phosphor/signaling'; + import { Cell } from '@jupyterlab/cells'; -import { IDisposable } from '@phosphor/disposable'; -import { Token } from '@phosphor/coreutils'; -import { IDefaultsManager } from './manager'; -import { Widget } from '@phosphor/widgets'; -import { IStatusContext } from '../contexts'; -import { CommandRegistry } from '@phosphor/commands'; -import { Menu } from '@phosphor/widgets'; -import { JSONObject } from '@phosphor/coreutils'; -import { showPopup, Popup } from '../component/hover'; -import { interactiveItem, clickedItem } from '../style/statusBar'; import { IConsoleTracker, ConsolePanel } from '@jupyterlab/console'; + import { ISettingRegistry } from '@jupyterlab/coreutils'; + +import { IEditorTracker } from '@jupyterlab/fileeditor'; + +import { INotebookTracker, NotebookPanel } from '@jupyterlab/notebook'; + +import { + IStatusBar, + interactiveItem, + clickedItem, + Popup, + showPopup, + TextItem, + SettingsConnector +} from '@jupyterlab/statusbar'; + +import { CommandRegistry } from '@phosphor/commands'; + +import { JSONObject } from '@phosphor/coreutils'; + +import { IDisposable } from '@phosphor/disposable'; + import { Message } from '@phosphor/messaging'; -import { SettingsConnector } from '../util/settings'; + +import { ISignal } from '@phosphor/signaling'; + +import { Menu, Widget } from '@phosphor/widgets'; + +import { IStatusContext } from '../contexts'; namespace TabSpaceComponent { export interface IProps { @@ -387,17 +402,11 @@ export namespace ITabSpace { } } -// tslint:disable-next-line:variable-name -export const ITabSpace = new Token( - '@jupyterlab/statusbar:ITabSpace' -); - -export const tabSpaceItem: JupyterLabPlugin = { +export const tabSpaceItem: JupyterLabPlugin = { id: '@jupyterlab/statusbar:tab-space-item', autoStart: true, - provides: ITabSpace, requires: [ - IDefaultsManager, + IStatusBar, INotebookTracker, IEditorTracker, IConsoleTracker, @@ -405,7 +414,7 @@ export const tabSpaceItem: JupyterLabPlugin = { ], activate: ( app: JupyterLab, - defaultsManager: IDefaultsManager, + statusBar: IStatusBar, notebookTracker: INotebookTracker, editorTracker: IEditorTracker, consoleTracker: IConsoleTracker, @@ -502,17 +511,15 @@ export const tabSpaceItem: JupyterLabPlugin = { settingsProviderData }); - defaultsManager.addDefaultStatus('tab-space-item', item, { + statusBar.registerStatusItem('tab-space-item', item, { align: 'right', - priority: 1, + rank: 1, isActive: IStatusContext.delegateActive(app.shell, [ { tracker: notebookTracker }, { tracker: editorTracker }, { tracker: consoleTracker } ]) }); - - return item; } }; diff --git a/packages/statusbar-extension/src/index.ts b/packages/statusbar-extension/src/index.ts index f2a291dd32a2..21e39b75410e 100644 --- a/packages/statusbar-extension/src/index.ts +++ b/packages/statusbar-extension/src/index.ts @@ -3,26 +3,21 @@ import '../style/index.css'; import { JupyterLab, JupyterLabPlugin } from '@jupyterlab/application'; -import { StatusBar, IStatusBar } from './statusBar'; +import { IStatusBar, StatusBar } from '@jupyterlab/statusbar'; // Export default status bar items import { - defaultsManager, - notebookTrustItem, lineColItem, - fileUploadItem, - kernelStatusItem, - commandEditItem, + kernelStatus, runningSessionsItem, - filePathItem, + filePathStatus, tabSpaceItem, - editorSyntax, memoryUsageItem, savingStatusItem } from './defaults'; -export const STATUSBAR_PLUGIN_ID = '@jupyterlab/statusbar:plugin'; +export const STATUSBAR_PLUGIN_ID = '@jupyterlab/statusbar-extension:plugin'; /** * Initialization data for the statusbar extension. @@ -38,20 +33,13 @@ const statusBar: JupyterLabPlugin = { const plugins: JupyterLabPlugin[] = [ statusBar, - defaultsManager, lineColItem, - notebookTrustItem, - fileUploadItem, - kernelStatusItem, - commandEditItem, + kernelStatus, runningSessionsItem, - filePathItem, + filePathStatus, tabSpaceItem, - editorSyntax, memoryUsageItem, savingStatusItem ]; export default plugins; - -export * from './statusBar'; diff --git a/packages/statusbar-extension/tsconfig.json b/packages/statusbar-extension/tsconfig.json index 0150ff32243a..6e056619af2e 100644 --- a/packages/statusbar-extension/tsconfig.json +++ b/packages/statusbar-extension/tsconfig.json @@ -18,9 +18,6 @@ { "path": "../codeeditor" }, - { - "path": "../codemirror" - }, { "path": "../console" }, @@ -33,9 +30,6 @@ { "path": "../docregistry" }, - { - "path": "../filebrowser" - }, { "path": "../fileeditor" }, @@ -44,6 +38,9 @@ }, { "path": "../services" + }, + { + "path": "../statusbar" } ] } diff --git a/packages/statusbar-extension/tslint.json b/packages/statusbar-extension/tslint.json deleted file mode 100644 index e3e455183570..000000000000 --- a/packages/statusbar-extension/tslint.json +++ /dev/null @@ -1,111 +0,0 @@ -{ - "rules": { - "align": [true, "parameters", "statements"], - "ban": [ - true, - ["_", "forEach"], - ["_", "each"], - ["$", "each"], - ["angular", "forEach"] - ], - "class-name": true, - "comment-format": [true, "check-space"], - "curly": true, - "eofline": true, - "forin": false, - "indent": [true, "spaces", 2], - "interface-name": [true, "always-prefix"], - "jsdoc-format": true, - "label-position": true, - "max-line-length": [false], - "member-access": false, - "member-ordering": [false], - "new-parens": true, - "no-angle-bracket-type-assertion": true, - "no-any": false, - "no-arg": true, - "no-bitwise": true, - "no-conditional-assignment": true, - "no-consecutive-blank-lines": false, - "no-console": { - "severity": "warning", - "options": ["debug", "info", "time", "timeEnd", "trace"] - }, - "no-construct": true, - "no-debugger": true, - "no-default-export": false, - "no-duplicate-variable": true, - "no-empty": true, - "no-eval": true, - "no-inferrable-types": false, - "no-internal-module": true, - "no-invalid-this": [true, "check-function-in-method"], - "no-null-keyword": false, - "no-reference": true, - "no-require-imports": false, - "no-shadowed-variable": false, - "no-string-literal": false, - "no-switch-case-fall-through": true, - "no-trailing-whitespace": true, - "no-unused-expression": true, - "no-use-before-declare": false, - "no-var-keyword": true, - "no-var-requires": true, - "object-literal-sort-keys": false, - "one-line": [ - true, - "check-open-brace", - "check-catch", - "check-else", - "check-finally", - "check-whitespace" - ], - "one-variable-per-declaration": [true, "ignore-for-loop"], - "quotemark": [true, "single", "avoid-escape", "jsx-double"], - "radix": true, - "semicolon": [true, "always", "ignore-bound-class-methods"], - "switch-default": true, - "trailing-comma": [ - false, - { - "multiline": "never", - "singleline": "never" - } - ], - "triple-equals": [true, "allow-null-check", "allow-undefined-check"], - "typedef": [false], - "typedef-whitespace": [ - false, - { - "call-signature": "nospace", - "index-signature": "nospace", - "parameter": "nospace", - "property-declaration": "nospace", - "variable-declaration": "nospace" - }, - { - "call-signature": "space", - "index-signature": "space", - "parameter": "space", - "property-declaration": "space", - "variable-declaration": "space" - } - ], - "use-isnan": true, - "use-strict": [false], - "variable-name": [ - true, - "check-format", - "allow-leading-underscore", - "ban-keywords" - ], - "whitespace": [ - true, - "check-branch", - "check-operator", - "check-separator", - "check-type" - ], - "no-implicit-dependencies": true - } -} diff --git a/packages/statusbar/package.json b/packages/statusbar/package.json new file mode 100644 index 000000000000..fcf5ba954973 --- /dev/null +++ b/packages/statusbar/package.json @@ -0,0 +1,51 @@ +{ + "name": "@jupyterlab/statusbar", + "version": "0.7.1", + "description": "JupyterLab statusbar package.", + "homepage": "https://github.com/jupyterlab/jupyterlab", + "bugs": { + "url": "https://github.com/jupyterlab/jupyterlab/issues" + }, + "license": "BSD-3-Clause", + "author": "Project Jupyter", + "files": [ + "lib/**/*.{d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf}", + "style/**/*.{css,eot,gif,html,jpg,json,png,svg,woff2,ttf}" + ], + "main": "lib/index.js", + "types": "lib/index.d.ts", + "directories": { + "lib": "lib/" + }, + "repository": { + "type": "git", + "url": "https://github.com/jupyterlab/jupyterlab.git" + }, + "scripts": { + "build": "tsc -b", + "clean": "rimraf lib", + "docs": "typedoc --options tdoptions.json --theme ../../typedoc-theme src", + "prepublishOnly": "npm run build", + "watch": "tsc -b --watch" + }, + "dependencies": { + "@jupyterlab/application": "^0.19.1", + "@jupyterlab/apputils": "^0.19.1", + "@jupyterlab/coreutils": "^2.2.1", + "@phosphor/algorithm": "^1.1.2", + "@phosphor/coreutils": "^1.3.0", + "@phosphor/disposable": "^1.1.2", + "@phosphor/messaging": "^1.2.2", + "@phosphor/signaling": "^1.2.2", + "@phosphor/widgets": "^1.6.0", + "react": "~16.4.2", + "typestyle": "^2.0.1" + }, + "devDependencies": { + "rimraf": "~2.6.2", + "typescript": "~3.1.1" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/statusbar-extension/src/component/group.tsx b/packages/statusbar/src/components/group.tsx similarity index 77% rename from packages/statusbar-extension/src/component/group.tsx rename to packages/statusbar/src/components/group.tsx index 43fc3ff4e20a..91d496519c17 100644 --- a/packages/statusbar-extension/src/component/group.tsx +++ b/packages/statusbar/src/components/group.tsx @@ -18,11 +18,11 @@ export const GroupItem = (
{React.Children.map(children, (child, i) => { if (i === 0) { - return
{child}
; + return
{child}
; } else if (i === numChildren - 1) { - return
{child}
; + return
{child}
; } else { - return
{child}
; + return
{child}
; } })}
@@ -31,7 +31,7 @@ export const GroupItem = ( export namespace GroupItem { export interface IProps { - spacing: string; + spacing: number; children: JSX.Element[]; } } diff --git a/packages/statusbar-extension/src/component/hover.tsx b/packages/statusbar/src/components/hover.tsx similarity index 94% rename from packages/statusbar-extension/src/component/hover.tsx rename to packages/statusbar/src/components/hover.tsx index 9d658ce9bd7d..8c68658df153 100644 --- a/packages/statusbar-extension/src/component/hover.tsx +++ b/packages/statusbar/src/components/hover.tsx @@ -2,8 +2,13 @@ import { Widget, PanelLayout } from '@phosphor/widgets'; import { HoverBox } from '@jupyterlab/apputils'; import { Message } from '@phosphor/messaging'; -import { hoverItem } from '../style/lineForm'; -import { clickedItem, interactiveItem } from '../style/statusBar'; +import { clickedItem, interactiveItem } from '../style/statusbar'; + +import { style } from 'typestyle/lib'; + +const hoverItem = style({ + boxShadow: '0px 4px 4px rgba(0, 0, 0, 0.25)' +}); export function showPopup(options: Popup.IOptions): Popup | null { let dialog = new Popup(options); diff --git a/packages/statusbar-extension/src/component/icon.tsx b/packages/statusbar/src/components/icon.tsx similarity index 100% rename from packages/statusbar-extension/src/component/icon.tsx rename to packages/statusbar/src/components/icon.tsx diff --git a/packages/statusbar-extension/src/component/index.ts b/packages/statusbar/src/components/index.ts similarity index 100% rename from packages/statusbar-extension/src/component/index.ts rename to packages/statusbar/src/components/index.ts diff --git a/packages/statusbar-extension/src/component/progressBar.tsx b/packages/statusbar/src/components/progressBar.tsx similarity index 100% rename from packages/statusbar-extension/src/component/progressBar.tsx rename to packages/statusbar/src/components/progressBar.tsx diff --git a/packages/statusbar-extension/src/component/text.tsx b/packages/statusbar/src/components/text.tsx similarity index 100% rename from packages/statusbar-extension/src/component/text.tsx rename to packages/statusbar/src/components/text.tsx diff --git a/packages/statusbar/src/index.ts b/packages/statusbar/src/index.ts new file mode 100644 index 000000000000..242d482e5822 --- /dev/null +++ b/packages/statusbar/src/index.ts @@ -0,0 +1,9 @@ +/*----------------------------------------------------------------------------- +| Copyright (c) Jupyter Development Team. +| Distributed under the terms of the Modified BSD License. +|----------------------------------------------------------------------------*/ + +export * from './statusbar'; +export * from './style/statusbar'; +export * from './components'; +export * from './util'; diff --git a/packages/statusbar-extension/src/statusBar.ts b/packages/statusbar/src/statusbar.ts similarity index 72% rename from packages/statusbar-extension/src/statusBar.ts rename to packages/statusbar/src/statusbar.ts index 67488825b645..72a1b28158bc 100644 --- a/packages/statusbar-extension/src/statusBar.ts +++ b/packages/statusbar/src/statusbar.ts @@ -1,42 +1,58 @@ -/** - * Main status bar object which contains all widgets. - */ -/** - * - */ -import { Widget, Panel, PanelLayout } from '@phosphor/widgets'; -import { Token } from '@phosphor/coreutils'; +// Copyright (c) Jupyter Development Team. +// Distributed under the terms of the Modified BSD License. + import { ApplicationShell } from '@jupyterlab/application'; + import { ArrayExt } from '@phosphor/algorithm'; + import { ISignal } from '@phosphor/signaling'; + +import { Token } from '@phosphor/coreutils'; + +import { DisposableDelegate, IDisposable } from '@phosphor/disposable'; + +import { Message } from '@phosphor/messaging'; + +import { Widget, Panel, PanelLayout } from '@phosphor/widgets'; + import { statusBar as barStyle, side as sideStyle, item as itemStyle, leftSide as leftSideStyle, rightSide as rightSideStyle -} from './style/statusBar'; -import { Message } from '@phosphor/messaging'; +} from './style/statusbar'; // tslint:disable-next-line:variable-name export const IStatusBar = new Token( '@jupyterlab/statusbar:IStatusBar' ); +/** + * Main status bar object which contains all widgets. + */ export interface IStatusBar { /** - * Add an item to the status bar. - * @param id Id of the widget to be displayed in the Settings Registry. - * @param widget Widget added to the status bar. - * @param opts + * Register a new status item. + * + * @param id - a unique id for the status item. + * + * @param widget - The item to add to the status bar. + * + * @param options - The options for how to add the status item. + * + * @returns an `IDisposable` that can be disposed to remove the item. */ registerStatusItem( id: string, widget: Widget, - opts: IStatusBar.IItemOptions - ): void; + options: IStatusBar.IItemOptions + ): IDisposable; } +/** + * A namespace for status bar statics. + */ export namespace IStatusBar { export type Alignment = 'right' | 'left' | 'middle'; @@ -47,11 +63,11 @@ export namespace IStatusBar { /** * Which side to place widget. Permanent widgets are intended for the right and left side, with more transient widgets in the middle. */ - align?: IStatusBar.Alignment; + align?: Alignment; /** - * Ordering of Items -- higher priority items are closer to the middle. + * Ordering of Items -- higher rank items are closer to the middle. */ - priority?: number; + rank?: number; /** * Whether the widget is shown or hidden. */ @@ -63,6 +79,9 @@ export namespace IStatusBar { } } +/** + * The DOM id for the status bar. + */ const STATUS_BAR_ID = 'jp-main-status-bar'; /** @@ -106,22 +125,30 @@ export class StatusBar extends Widget implements IStatusBar { }); } + /** + * Register a new status item. + * + * @param id - a unique id for the status item. + * + * @param widget - The item to add to the status bar. + * + * @param options - The options for how to add the status item. + */ registerStatusItem( id: string, widget: Widget, - opts: IStatusBar.IItemOptions = {} - ) { + options: IStatusBar.IItemOptions = {} + ): IDisposable { if (id in this._statusItems) { throw new Error(`Status item ${id} already registered.`); } - let align = opts.align ? opts.align : 'left'; - let priority = opts.priority !== undefined ? opts.priority : 0; - let isActive = opts.isActive !== undefined ? opts.isActive : () => true; - let stateChanged = - opts.stateChanged !== undefined ? opts.stateChanged : null; + let align = options.align || 'left'; + let rank = options.rank || 0; + let isActive = options.isActive || (() => true); + let stateChanged = options.stateChanged || null; let changeCallback = - opts.stateChanged !== undefined + options.stateChanged !== undefined ? () => { this._onIndividualStateChange(id); } @@ -130,7 +157,7 @@ export class StatusBar extends Widget implements IStatusBar { let wrapper = { widget, align, - priority, + rank, isActive, stateChanged, changeCallback @@ -138,7 +165,7 @@ export class StatusBar extends Widget implements IStatusBar { let rankItem = { id, - priority + rank }; widget.addClass(itemStyle); @@ -171,8 +198,18 @@ export class StatusBar extends Widget implements IStatusBar { } else { this._middlePanel.addWidget(widget); } + + return new DisposableDelegate(() => { + delete this._statusItems[id]; + ArrayExt.removeFirstOf(this._statusIds, id); + widget.parent = null; + widget.dispose(); + }); } + /** + * Dispose of the status bar. + */ dispose() { super.dispose(); @@ -188,6 +225,9 @@ export class StatusBar extends Widget implements IStatusBar { }); } + /** + * Handle an 'update-request' message to the status bar. + */ protected onUpdateRequest(msg: Message) { this._statusIds.forEach(statusId => { this._statusItems[statusId].widget.update(); @@ -198,13 +238,10 @@ export class StatusBar extends Widget implements IStatusBar { } private _findInsertIndex( - side: StatusBar.IRankItem[], - newItem: StatusBar.IRankItem + side: Private.IRankItem[], + newItem: Private.IRankItem ): number { - return ArrayExt.findFirstIndex( - side, - item => item.priority > newItem.priority - ); + return ArrayExt.findFirstIndex(side, item => item.rank > newItem.rank); } private _refreshItem({ isActive, widget }: StatusBar.IItem) { @@ -229,8 +266,8 @@ export class StatusBar extends Widget implements IStatusBar { this._refreshItem(this._statusItems[statusId]); }; - private _leftRankItems: StatusBar.IRankItem[] = []; - private _rightRankItems: StatusBar.IRankItem[] = []; + private _leftRankItems: Private.IRankItem[] = []; + private _rightRankItems: Private.IRankItem[] = []; private _statusItems: { [id: string]: StatusBar.IItem } = Object.create(null); private _statusIds: Array = []; @@ -242,11 +279,6 @@ export class StatusBar extends Widget implements IStatusBar { } export namespace StatusBar { - export interface IRankItem { - id: string; - priority: number; - } - /** * Options for creating a new StatusBar instance */ @@ -254,12 +286,28 @@ export namespace StatusBar { host: ApplicationShell; } + /** + * The interface for a status bar item. + */ export interface IItem { align: IStatusBar.Alignment; - priority: number; + rank: number; widget: Widget; isActive: () => boolean; stateChanged: ISignal | null; changeCallback: (() => void) | null; } } + +/** + * A namespace for private functionality. + */ +namespace Private { + /** + * An interface for storing the rank of a status item. + */ + export interface IRankItem { + id: string; + rank: number; + } +} diff --git a/packages/statusbar-extension/src/style/icon.ts b/packages/statusbar/src/style/icon.ts similarity index 100% rename from packages/statusbar-extension/src/style/icon.ts rename to packages/statusbar/src/style/icon.ts diff --git a/packages/statusbar-extension/src/style/layout.ts b/packages/statusbar/src/style/layout.ts similarity index 100% rename from packages/statusbar-extension/src/style/layout.ts rename to packages/statusbar/src/style/layout.ts diff --git a/packages/statusbar-extension/src/style/progressBar.ts b/packages/statusbar/src/style/progressBar.ts similarity index 100% rename from packages/statusbar-extension/src/style/progressBar.ts rename to packages/statusbar/src/style/progressBar.ts diff --git a/packages/statusbar-extension/src/style/statusBar.ts b/packages/statusbar/src/style/statusbar.ts similarity index 100% rename from packages/statusbar-extension/src/style/statusBar.ts rename to packages/statusbar/src/style/statusbar.ts diff --git a/packages/statusbar-extension/src/style/text.ts b/packages/statusbar/src/style/text.ts similarity index 100% rename from packages/statusbar-extension/src/style/text.ts rename to packages/statusbar/src/style/text.ts diff --git a/packages/statusbar-extension/src/style/variables.ts b/packages/statusbar/src/style/variables.ts similarity index 100% rename from packages/statusbar-extension/src/style/variables.ts rename to packages/statusbar/src/style/variables.ts diff --git a/packages/statusbar/src/util/index.ts b/packages/statusbar/src/util/index.ts new file mode 100644 index 000000000000..94e62d1ad7a3 --- /dev/null +++ b/packages/statusbar/src/util/index.ts @@ -0,0 +1,4 @@ +export * from './settings'; +export * from './set'; +export * from './signal'; +export * from './text'; diff --git a/packages/statusbar-extension/src/util/set.ts b/packages/statusbar/src/util/set.ts similarity index 100% rename from packages/statusbar-extension/src/util/set.ts rename to packages/statusbar/src/util/set.ts diff --git a/packages/statusbar-extension/src/util/settings.ts b/packages/statusbar/src/util/settings.ts similarity index 100% rename from packages/statusbar-extension/src/util/settings.ts rename to packages/statusbar/src/util/settings.ts diff --git a/packages/statusbar-extension/src/util/signal.ts b/packages/statusbar/src/util/signal.ts similarity index 100% rename from packages/statusbar-extension/src/util/signal.ts rename to packages/statusbar/src/util/signal.ts diff --git a/packages/statusbar-extension/src/util/text.ts b/packages/statusbar/src/util/text.ts similarity index 100% rename from packages/statusbar-extension/src/util/text.ts rename to packages/statusbar/src/util/text.ts diff --git a/packages/statusbar/tdoptions.json b/packages/statusbar/tdoptions.json new file mode 100644 index 000000000000..dd95ae826fa8 --- /dev/null +++ b/packages/statusbar/tdoptions.json @@ -0,0 +1,20 @@ +{ + "excludeNotExported": true, + "mode": "file", + "target": "es5", + "module": "es5", + "lib": [ + "lib.es2015.d.ts", + "lib.es2015.collection.d.ts", + "lib.es2015.promise.d.ts", + "lib.dom.d.ts" + ], + "out": "../../docs/api/statusbar-extension", + "baseUrl": ".", + "paths": { + "@jupyterlab/*": ["../packages/*"] + }, + "esModuleInterop": true, + "jsx": "react", + "types": [] +} diff --git a/packages/statusbar/tsconfig.json b/packages/statusbar/tsconfig.json new file mode 100644 index 000000000000..76c827c205db --- /dev/null +++ b/packages/statusbar/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "../../tsconfigbase", + "compilerOptions": { + "outDir": "lib", + "rootDir": "src" + }, + "include": ["src/**/*"], + "references": [ + { + "path": "../application" + }, + { + "path": "../apputils" + }, + { + "path": "../coreutils" + } + ] +} diff --git a/yarn.lock b/yarn.lock index dc81fefd32d7..9e9033f23cc7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7800,10 +7800,6 @@ prettier@^1.11.1: version "1.14.2" resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.14.2.tgz#0ac1c6e1a90baa22a62925f41963c841983282f9" -prettier@^1.14.2: - version "1.14.3" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.14.3.tgz#90238dd4c0684b7edce5f83b0fb7328e48bd0895" - pretty-error@^2.0.2: version "2.1.1" resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.1.tgz#5f4f87c8f91e5ae3f3ba87ab4cf5e03b1a17f1a3"