Skip to content

Commit

Permalink
Add statusbar (#5508)
Browse files Browse the repository at this point in the history
* quick fix

* middle Area + fileUpload refactor

* fixedCSS

* changes

* Add context switching on app shell changes

Also support signaling from the status item to the status bar for
context switches. Also set tsconfig for compilation in strict mode.

* Add strict null checks and context switching to tab/space item

* Add strict null checks and context switching to notebook trust item

* Add strict null checks and context switching to line/col item

* Refactor and add context switching to file upload item

* Add strict null checking and contexts switching to command/edit and kernel status

* Cleanup and add context switching to file path item

* added groups for icon and text

* group items

* editied running session

* text

* minor style changes

* Refactor file path item

* Refactor models of most default items

* Refactor model and remove hover behavior of notebook trust item

* Convert all react imports to default style

* Implement editor syntax item

* Fix malformed import

* Add optional title prop to text component

* Add hover text to default items

* titlecase changes

* Convert file upload item to use defaults manager

Also fill plugin settings with all default item ids

* Rename DefaultStatusesManager to DefaultsManager

* Remove default enabled management from status bar class

* Update plugin settings default listing and fix editor syntax display

* Remove defaults management from status bar internals

* Reimplement default settings connection using isActive and stateChanged

* Add null check to stateChange emit lookup

* Implement complete message for file upload

* initial interaction

* Update kernel & terminal icons

* Move and cleanup component styles

Extracte style variables to single global definition. Also, rename files from ts to tsx and moved status bar styles to typestyle.

* Finish moving status bar to typestyle

* Cleanup components, relative to styles

* final interaction details

* eliminate console log

* Make running sessions spacing group icon and number

* Change non-interactive items to not have hover or pointer change

* Rename TextFunctions to TextExt

* Move item spacing style into common class

Remove distinction of nonInteractive items, interactive style is now opt-in

* Move interactive class addition to top of status item structure

* Maintain clicked background color during popup duration

* Fix issue with console kernel status on reload

Also, disabled changing kernels while in console context.

* Remove top status bar border

* Extend file path item to all widgets with title

* Add tab spacing display to console context

* hoverBoxCSS

* hoverBoxCSSe

* alterHeights

* Update icons

* Swap ordering of kernel and terminal in running session item

* Add signal disconnects to most default items

* Dispose of items on status bar disposal

Also add signal disconnects for the line/col item.

* Remove pointer style from interactive items

* Update jupyterlab deps

* Fix line/col form css

* Convert hover box to align on right side of anchor element

* Redo CSS of line/col popup form

Temporarily disabled functionality

* Remove unused icons

* Add icon for display in settings registry

* Changed alt text from inner div groups to outer to account for hovers when cursor on outer padding

* Update settings icon w/ bounding box

* Add bounding boxes to remaining icons

* Expose icon item offset options

* Update height to match multiple of 4 rule

* Add rounded border to progress bar

* Allow event propagation through to popup body

* initial changes

* Scope popup event listeners to current body

Also add key listener for escape to exit popup

* Fix issue with incorrect current editor on reload

* changed alt text names to reflect interaction, added kernel name to active sessions alt text

* added left and right option to hover to align with status bar compponent, added suntax highlighting menu and made editor syntax interactive

* got rid of extraneous console message

* Add CombinedSignal extension

* Rename var to match parent flows to child semantics

* altered filePath to take docManager to check contexts instead of relying on instanceOf behavior

* eliminated instance trackers and checked current trackers for active editor

* eliminated instance trackers and checked current trackers for active editor for tabSpace component

* eliminated instance trackers and checked current trackers for active editor for kernelStatus

* Convert sender to be default manager

* Add connector to watch changes in single settings value

* Update kernel icon

* Change defaults manager to use setting connector

* Convert most default items to check value difference before emitting state change

* Remove unneeded listeners on tracker current changed

* Remove unneed listeners from kernel status item

* Remove console logging

* Switch tab size item to read values from settings

* Update trusted icon

* Allow settings connector to update watched item

* fixed resizing and placement issues for status bar hovers, moved text down slightly

* removed extraneous console logs, comments

* Update package.json

* Update README.md to include video use gif

* Updated GIFs

* updated gif descriptons

* Change all ids to match new package name format

* Bump version

* Update installation instructions

* Make popup creation fallible

* Extract settings data into common type definition

* Flatten setting connectors container

* Convert settings connector to use JSONValue as input requirement

* Implement changing tab/space size for all contexts

* Add indicator for adding tab characters vs space characters

* Bump minor version

* Implement resource usage item

This item will be disabled if the nbresuse package is not installed on the jupyter server

* Formatting and make running sessions/kernel status item explicitly ordered

* Use existing context machinery to hide nbresuse item

* ensured only one popup present at one time

* Updated READ.me with Nbresuse information

* Added formatting changes

* 0.3.0

* 0.3.1

* 0.3.0

* Ignore .DS_Store files in git and npm package creation

* Have memory item cease refreshing if any failures occur

* Fix error in line/col during console prompt changes

* Upgrade jupyterlab packages

* Add null check to tab/space and unrestricted typing for timer ids

* Added documentation for statusbar using typedocs

* further documentation

* bumped version changes

* implemented saving items for default status bar

* fixed extraneous changes

* Added extraneous changes

* Convert undefined check to null check

* removing all file upload failure code

* fixed error with reading model from possible null value

* changed status bar colors to align with Jupyterlab design

* Added null checks

* preventing multiple windows from rnedering, fized resize

* made interactions dark mode compatible

* remove curse word

* updated kernel image and look

* version bump 0.3.1

* public version bump

* fixed fileupload error bug

* fixed line/col font color in dark mode

* removed extraneous line

* removed extraneous line

* final

* Added documentation for all defaults

* updated status bar core docs

* Update jupyterlab packages

* Bump version for jupyterlab release

* Add check coming to/from null in tabspace model

* Patch bump fixing tabspace item

* Add tabspace menu close actions

* Add nbresuse instructions

* Bump patch version

* Bump jupyterlab packages

* added mem indicator to mem item

* fixed tab hover issue

* changed editor synatx tax

* Update @jupyterlab packages

* 0.4.3

* Update for jlab 0.35 prerelease.

From the update-dependency script in @jupyterlab/buildutils:

update-dependency --minimal --regex '^@jupyterlab/' ^next

Then I edited the version of @types/react in package.json. Then I cleaned up the yarn.lock:

git clean -dfx
yarn install
yarn check
yarn-tools fix-duplicates yarn.lock > a
mv a yarn.lock
git clean -dfx
yarn install

* jlpm run create:package updates

* Ran integrity

* Update tsconfig to same format

* Include nested files in tsconfig

* Run `yarn lint`

* remove statusbar docs

* make statusbar package.json more similar

* Run lint

* remove outdated statusbar readme

* Remove some redundant files.

* More integrity.
  • Loading branch information
saulshanabrook authored and blink1073 committed Oct 18, 2018
1 parent cd265a4 commit d158501
Show file tree
Hide file tree
Showing 51 changed files with 4,625 additions and 0 deletions.
3 changes: 3 additions & 0 deletions dev_mode/package.json
Expand Up @@ -66,6 +66,7 @@
"@jupyterlab/settingeditor": "^0.8.1",
"@jupyterlab/settingeditor-extension": "^0.14.1",
"@jupyterlab/shortcuts-extension": "^0.19.3",
"@jupyterlab/statusbar-extension": "^0.5.0",
"@jupyterlab/tabmanager-extension": "^0.19.1",
"@jupyterlab/terminal": "^0.19.1",
"@jupyterlab/terminal-extension": "^0.19.1",
Expand Down Expand Up @@ -152,6 +153,7 @@
"@jupyterlab/running-extension": "",
"@jupyterlab/settingeditor-extension": "",
"@jupyterlab/shortcuts-extension": "",
"@jupyterlab/statusbar-extension": "",
"@jupyterlab/tabmanager-extension": "",
"@jupyterlab/terminal-extension": "",
"@jupyterlab/theme-dark-extension": "",
Expand Down Expand Up @@ -275,6 +277,7 @@
"@jupyterlab/settingeditor": "../packages/settingeditor",
"@jupyterlab/settingeditor-extension": "../packages/settingeditor-extension",
"@jupyterlab/shortcuts-extension": "../packages/shortcuts-extension",
"@jupyterlab/statusbar-extension": "../packages/statusbar-extension",
"@jupyterlab/tabmanager-extension": "../packages/tabmanager-extension",
"@jupyterlab/terminal": "../packages/terminal",
"@jupyterlab/terminal-extension": "../packages/terminal-extension",
Expand Down
1 change: 1 addition & 0 deletions packages/metapackage/package.json
Expand Up @@ -84,6 +84,7 @@
"@jupyterlab/settingeditor": "^0.8.1",
"@jupyterlab/settingeditor-extension": "^0.14.1",
"@jupyterlab/shortcuts-extension": "^0.19.3",
"@jupyterlab/statusbar-extension": "^0.5.0",
"@jupyterlab/tabmanager-extension": "^0.19.1",
"@jupyterlab/terminal": "^0.19.1",
"@jupyterlab/terminal-extension": "^0.19.1",
Expand Down
1 change: 1 addition & 0 deletions packages/metapackage/src/index.ts
Expand Up @@ -55,6 +55,7 @@ import '@jupyterlab/services';
import '@jupyterlab/settingeditor';
import '@jupyterlab/settingeditor-extension';
import '@jupyterlab/shortcuts-extension';
import '@jupyterlab/statusbar-extension';
import '@jupyterlab/tabmanager-extension';
import '@jupyterlab/terminal';
import '@jupyterlab/terminal-extension';
Expand Down
3 changes: 3 additions & 0 deletions packages/metapackage/tsconfig.json
Expand Up @@ -168,6 +168,9 @@
{
"path": "../shortcuts-extension"
},
{
"path": "../statusbar-extension"
},
{
"path": "../tabmanager-extension"
},
Expand Down
23 changes: 23 additions & 0 deletions packages/statusbar-extension/README.md
@@ -0,0 +1,23 @@
# JupyterLab Status Bar

This extension creates a generic statusbar to showcase the various states of JupyterLab. Different components will render depending on the active context: notebook, console, file editor, and terminal. This extension can be used by other
extensions to add custom elements into the statusbar.

Changing Contexts
![Context Changes](http://g.recordit.co/OndGalRjws.gif)

Component Interactions
![Component Previews](http://g.recordit.co/jT0NA6D9c9.gif)

## Dependencies

- JupyterLab

## Optional Dependencies

- [nbresuse](https://github.com/yuvipanda/nbresuse)

```bash
pip install nbresuse
jupyter serverextension enable --py nbresuse
```
75 changes: 75 additions & 0 deletions packages/statusbar-extension/package.json
@@ -0,0 +1,75 @@
{
"name": "@jupyterlab/statusbar-extension",
"version": "0.5.0",
"description": "JupyterLab - Statusbar Extension",
"homepage": "https://github.com/jupyterlab/jupyterlab",
"bugs": {
"url": "https://github.com/jupyterlab/jupyterlab/issues"
},
"license": "BSD-3-Clause",
"author": "Project Jupyter, Richa Gadgil, Takahiro Shimokobe, Declan Kelly",
"files": [
"lib/**/*.d.ts",
"lib/**/*.js.map",
"lib/**/*.js",
"style/*.css",
"style/images/*.svg",
"schema/*.json"
],
"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/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",
"@phosphor/commands": "^1.6.1",
"@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": {
"@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"
},
"publishConfig": {
"access": "public"
},
"jupyterlab": {
"extension": true,
"schemaDir": "schema"
}
}
28 changes: 28 additions & 0 deletions packages/statusbar-extension/schema/plugin.json
@@ -0,0 +1,28 @@
{
"jupyter.lab.setting-icon-class": "status-bar-icon",
"jupyter.lab.setting-icon-label": "Status Bar",
"title": "Status Bar",
"description": "Status Bar settings.",
"properties": {
"enabledDefaultItems": {
"type": "array",
"title": "Default Status Items",
"description": "Which default items should appear in the status bar",
"default": [
"command-edit-item",
"editor-syntax-item",
"file-path-item",
"file-upload-item",
"kernel-status-item",
"line-col-item",
"notebook-trust-item",
"running-sessions-item",
"tab-space-item",
"memory-usage-item",
"saving-status-item"
]
}
},
"additionalProperties": false,
"type": "object"
}
37 changes: 37 additions & 0 deletions packages/statusbar-extension/src/component/group.tsx
@@ -0,0 +1,37 @@
/**
* @ignore
*/
import * as React from 'react';
import { style, classes } from 'typestyle/lib';
import { centeredFlex, leftToRight } from '../style/layout';

const groupItemLayout = style(centeredFlex, leftToRight);

// tslint:disable-next-line:variable-name
export const GroupItem = (
props: GroupItem.IProps & React.HTMLAttributes<HTMLDivElement>
): React.ReactElement<GroupItem.IProps> => {
const { spacing, children, className, ...rest } = props;
const numChildren = React.Children.count(children);

return (
<div className={classes(groupItemLayout, className)} {...rest}>
{React.Children.map(children, (child, i) => {
if (i === 0) {
return <div style={{ marginRight: spacing }}>{child}</div>;
} else if (i === numChildren - 1) {
return <div style={{ marginLeft: spacing }}>{child}</div>;
} else {
return <div style={{ margin: `0px ${spacing}` }}>{child}</div>;
}
})}
</div>
);
};

export namespace GroupItem {
export interface IProps {
spacing: string;
children: JSX.Element[];
}
}
138 changes: 138 additions & 0 deletions packages/statusbar-extension/src/component/hover.tsx
@@ -0,0 +1,138 @@
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';

export function showPopup(options: Popup.IOptions): Popup | null {
let dialog = new Popup(options);
dialog.launch();
return dialog;
}

export class Popup extends Widget {
constructor(options: Popup.IOptions) {
super();
this._body = options.body;
this._body.addClass(hoverItem);
this._anchor = options.anchor;
this._align = options.align;
let layout = (this.layout = new PanelLayout());
layout.addWidget(options.body);
this._body.node.addEventListener('resize', () => {
this.update();
});
}

launch() {
this.setGeometry();
Widget.attach(this, document.body);
this.update();
this._anchor.addClass(clickedItem);
this._anchor.removeClass(interactiveItem);
}

setGeometry() {
let aligned = 0;
const anchorRect = this._anchor.node.getBoundingClientRect();
const bodyRect = this._body.node.getBoundingClientRect();
if (this._align === 'right') {
aligned = -(bodyRect.width - anchorRect.width);
}
const style = window.getComputedStyle(this._body.node);
HoverBox.setGeometry({
anchor: anchorRect,
host: document.body,
maxHeight: 500,
minHeight: 20,
node: this._body.node,
offset: {
horizontal: aligned
},
privilege: 'forceAbove',
style
});
}

protected onUpdateRequest(msg: Message): void {
this.setGeometry();
this.setGeometry();
super.onUpdateRequest(msg);
}

protected onAfterAttach(msg: Message): void {
document.addEventListener('click', this, false);
this.node.addEventListener('keypress', this, false);
window.addEventListener('resize', this, false);
}

protected onAfterDetach(msg: Message): void {
document.removeEventListener('click', this, false);
this.node.removeEventListener('keypress', this, false);
window.removeEventListener('resize', this, false);
}

protected _evtClick(event: MouseEvent): void {
if (
!!event.target &&
!(
this._body.node.contains(event.target as HTMLElement) ||
this._anchor.node.contains(event.target as HTMLElement)
)
) {
this.dispose();
}
}

protected onResize(): void {
this.update();
}

dispose() {
super.dispose();
this._anchor.removeClass(clickedItem);
this._anchor.addClass(interactiveItem);
}

protected _evtKeydown(event: KeyboardEvent): void {
// Check for escape key
switch (event.keyCode) {
case 27: // Escape.
event.stopPropagation();
event.preventDefault();
this.dispose();
break;
default:
break;
}
}

handleEvent(event: Event): void {
switch (event.type) {
case 'keydown':
this._evtKeydown(event as KeyboardEvent);
break;
case 'click':
this._evtClick(event as MouseEvent);
break;
case 'resize':
this.onResize();
break;
default:
break;
}
}

private _body: Widget;
private _anchor: Widget;
private _align: 'left' | 'right' | undefined;
}

export namespace Popup {
export interface IOptions {
body: Widget;
anchor: Widget;
align?: 'left' | 'right';
}
}
26 changes: 26 additions & 0 deletions packages/statusbar-extension/src/component/icon.tsx
@@ -0,0 +1,26 @@
import * as React from 'react';

import icon from '../style/icon';
import { classes, style } from 'typestyle/lib';

export namespace IconItem {
export interface IProps {
source: string;
}
}

// tslint:disable-next-line:variable-name
export const IconItem = (
props: IconItem.IProps &
React.HTMLAttributes<HTMLDivElement> & {
offset: { x: number; y: number };
}
): React.ReactElement<IconItem.IProps> => {
const { source, className, offset, ...rest } = props;
return (
<div
className={classes(className, source, style(icon(offset)))}
{...rest}
/>
);
};
5 changes: 5 additions & 0 deletions packages/statusbar-extension/src/component/index.ts
@@ -0,0 +1,5 @@
export * from './icon';
export * from './progressBar';
export * from './text';
export * from './group';
export * from './hover';

0 comments on commit d158501

Please sign in to comment.