Skip to content

Commit

Permalink
#7267 show Spark progress bar in Foldout (#7362)
Browse files Browse the repository at this point in the history
* #7267 SparkProgress and foldout js part

* #7267 SparkProgress and Foldout java part

* #7267 fix Foldout paddings
  • Loading branch information
Mariusz Jurowicz authored and scottdraves committed May 16, 2018
1 parent 5926a29 commit aa8fb8a
Show file tree
Hide file tree
Showing 12 changed files with 313 additions and 175 deletions.
152 changes: 112 additions & 40 deletions js/notebook/src/Foldout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@

const widgets = require('./widgets');
const DEFAULT_LABEL_TEXT = 'Output';
const DEFAULT_CONTENT_PADDING = 14;
const DEFAULT_CONTENT_MIN_LINE_HEIGHT = 16;
const ANIMATION_DURATION = 500;
const DEFAULT_ADDED_SPACE = 22;
const ANIMATION_DURATION = 300;

class FoldoutModel extends widgets.HTMLModel {
class FoldoutModel extends widgets.BoxModel {
defaults() {
return {
...super.defaults(),
Expand All @@ -34,50 +33,123 @@ class FoldoutModel extends widgets.HTMLModel {
}
}

class FoldoutView extends widgets.HTMLView {
render() {
super.render();
class FoldoutView extends widgets.BoxView {
label: HTMLLabelElement;
content: HTMLElement;
previewContainer: HTMLElement;
previewContent: HTMLElement;
previewContentParent: HTMLElement;
hiddenContainer: HTMLElement;
timeoutId: number;
active: boolean;

let active = false;
let hiddenContainer: HTMLElement = document.createElement('div');
let minHeight = 2 * DEFAULT_CONTENT_PADDING + DEFAULT_CONTENT_MIN_LINE_HEIGHT;
let timeoutId;
addLabel(labelElement?: HTMLLabelElement) {
if (!labelElement) {
this.label = document.createElement('label');
this.label.innerText = DEFAULT_LABEL_TEXT;
} else {
this.label = labelElement;
}

hiddenContainer.innerHTML = this.content.outerHTML;
let original = hiddenContainer.firstChild as HTMLElement;
this.label.classList.add('foldout-label');
this.label.style.display = 'block';
this.el.insertBefore(this.label, this.content);
}

hiddenContainer.style.visibility = 'hidden';
hiddenContainer.style.position = 'fixed';
hiddenContainer.style.zIndex = '-1';
original.style.whiteSpace = 'normal';
original.style.height = 'auto';
addContent() {
this.content = document.createElement('div');
this.content.classList.add('foldout-content');
this.el.appendChild(this.content);
}

this.el.classList.add('foldout-widget');
this.el.appendChild(hiddenContainer);
addPreviewContent() {
this.previewContainer = document.createElement('div');
this.previewContent = document.createElement('div');
this.previewContainer.classList.add('foldout-preview');
this.el.appendChild(this.previewContainer);
}

this.content.style.whiteSpace = 'nowrap';
addHiddenContainer() {
this.hiddenContainer = document.createElement('div');
this.hiddenContainer.classList.add('foldout-content');
this.hiddenContainer.style.visibility = 'hidden';
this.hiddenContainer.style.position = 'fixed';
this.hiddenContainer.style.zIndex = '-1';
this.el.appendChild(this.hiddenContainer);
}

if (!this.label.innerText) {
this.label.innerText = DEFAULT_LABEL_TEXT;
this.label.style.display = 'block'
headerClickCallback() {
clearTimeout(this.timeoutId);
this.active = !this.active;
this.el.classList.toggle('active', this.active);

if (this.active) {
this.hiddenContainer.style.width = `${this.el.clientWidth}px`;
this.previewContainer.style.height = `0px`;
this.timeoutId = setTimeout(
this.activateFoldoutCallback.bind(this),
ANIMATION_DURATION
);
} else {
this.content.style.height = `0px`;
this.timeoutId = setTimeout(
this.deactivateFoldoutCallback.bind(this),
ANIMATION_DURATION
);
}
}

activateFoldoutCallback() {
this.previewContainer.style.display = 'none';
this.content.style.display = 'block';
this.previewContentParent.appendChild(this.previewContent);
this.content.style.height = `${
this.hiddenContainer.clientHeight + DEFAULT_ADDED_SPACE / 2
}px`;
}

deactivateFoldoutCallback() {
this.content.style.display = 'none';
this.previewContainer.style.display = 'block';
this.previewContainer.appendChild(this.previewContent);
this.previewContainer.style.height = `${
this.previewContent.clientHeight + DEFAULT_ADDED_SPACE
}px`;
}

getPreviewContent(): HTMLElement {
return this.content.firstChild as HTMLElement;
}

render() {
super.render();

this.addContent();
this.addPreviewContent();
this.addHiddenContainer();

this.el.classList.add('foldout-widget');

this.children_views.update(this.model.get('children')).then((views) => {
this.content.innerHTML = '';

views.forEach((view) => {
if (view.el.classList.contains('widget-label')) {
this.addLabel(view.el);
} else {
this.content.appendChild(view.el);
}
});

this.label.addEventListener('click', () => {
clearTimeout(timeoutId);
active = !active;
this.el.classList.toggle('active', active);

if (active) {
hiddenContainer.style.width = `${this.el.clientWidth}px`;
this.content.style.whiteSpace = 'normal';
this.content.style.height = `${ original.clientHeight }px`;
} else {
this.content.style.height = `${minHeight}px`;
timeoutId = setTimeout(
() => { this.content.style.whiteSpace = 'nowrap'; },
ANIMATION_DURATION
);
}
!this.label && this.addLabel();
this.content.style.height = '0px';
this.content.style.display = 'none';
this.hiddenContainer.innerHTML = this.content.innerHTML;
this.previewContent = this.getPreviewContent();
this.previewContentParent = this.previewContent.parentNode as HTMLElement;
this.previewContainer.appendChild(this.previewContent);
this.previewContainer.style.height = `${this.previewContent.clientHeight + DEFAULT_ADDED_SPACE}px`;
this.label.addEventListener('click', this.headerClickCallback.bind(this));
});
}
}
Expand Down
44 changes: 44 additions & 0 deletions js/notebook/src/SparkFoldout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright 2018 TWO SIGMA OPEN SOURCE, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import Foldout from "./Foldout";

const widgets = require('./widgets');

class SparkFoldoutModel extends widgets.BoxModel {
defaults() {
return {
...super.defaults(),
_view_name: "SparkFoldoutView",
_model_name: "SparkFoldoutModel",
_model_module: 'beakerx',
_view_module: 'beakerx',
_model_module_version: BEAKERX_MODULE_VERSION,
_view_module_version: BEAKERX_MODULE_VERSION
};
}
}

class SparkFoldoutView extends Foldout.FoldoutView {
getPreviewContent(): HTMLElement {
return this.content.querySelector('.bx-spark-stagePanel');
}
}

export default {
SparkFoldoutModel,
SparkFoldoutView
};
Loading

0 comments on commit aa8fb8a

Please sign in to comment.