Show progress bar for fetchData()

This will allow to show users that data loading is still
in progress for slow connections.

Partial-Bug: #1549744

Change-Id: Ic1fc8e5da324c4ece3bac63045eb32b37b163c7a
This commit is contained in:
Vitaly Kramskikh 2016-03-25 20:16:52 +03:00 committed by Kate Pimenova
parent 10c845b1bd
commit cadf1c78ee
4 changed files with 75 additions and 2 deletions

View File

@ -21,6 +21,7 @@ import Backbone from 'backbone';
import React from 'react';
import ReactDOM from 'react-dom';
import models from 'models';
import dispatcher from 'dispatcher';
import {NailgunUnavailabilityDialog} from 'views/dialogs';
import KeystoneClient from 'keystone_client';
import RootComponent from 'views/root';
@ -217,11 +218,13 @@ class App {
}
loadPage(Page, options = []) {
dispatcher.trigger('pageLoadStarted');
return (Page.fetchData ? Page.fetchData(...options) : $.Deferred().resolve())
.done((pageOptions) => {
if (!this.rootComponent) this.renderLayout();
this.setPage(Page, pageOptions);
});
})
.always(() => dispatcher.trigger('pageLoadFinished'));
}
setPage(Page, options) {

View File

@ -905,6 +905,25 @@ input[type=range] {
}
}
.page-load-progress {
position: absolute;
height: 5px;
top: 0;
left: 0;
z-index: 40;
opacity: 1;
transition: opacity 0.2s linear 0.2s;
.page-load-progress-bar {
position: fixed;
top: 0;
left: 0;
height: 2px;
background: @navbar-color-hover;
box-shadow: 0 0 8px @navbar-color-hover;
transition: width 0.35s ease;
}
}
// BREADCRUMBS
.breadcrumb {

View File

@ -373,6 +373,54 @@ export var Footer = React.createClass({
}
});
export var PageLoadProgressBar = React.createClass({
mixins: [
dispatcherMixin('pageLoadStarted', 'showProgressBar'),
dispatcherMixin('pageLoadFinished', 'hideProgressBar')
],
getDefaultProps() {
return {
initialProgress: 10,
maxProgress: 94,
progressStep: 2,
stepDelay: 300
};
},
getInitialState() {
return {
visible: false,
progress: this.props.initialProgress
};
},
showProgressBar() {
this.setState({progress: this.props.initialProgress, visible: true});
this.activeInterval = setInterval(() => {
if (this.state.progress < this.props.maxProgress) {
this.setState({progress: this.state.progress + this.props.progressStep});
}
}, this.props.stepDelay);
},
hideProgressBar() {
clearInterval(this.activeInterval);
this.setState({progress: 100, visible: false}, () => {
setTimeout(() => this.setState({progress: this.props.initialProgress}), 400);
});
},
componentWillUnmount() {
clearInterval(this.activeInterval);
},
render() {
return (
<div className='page-load-progress' style={{opacity: this.state.visible ? 1 : 0}}>
<div
className='page-load-progress-bar'
style={{width: this.state.progress + '%'}}
/>
</div>
);
}
});
export var Breadcrumbs = React.createClass({
mixins: [
dispatcherMixin('updatePageLayout', 'refresh')

View File

@ -20,7 +20,9 @@ import React from 'react';
import dispatcher from 'dispatcher';
import utils from 'utils';
import {dispatcherMixin} from 'component_mixins';
import {Navbar, Breadcrumbs, DefaultPasswordWarning, BootstrapError, Footer} from 'views/layout';
import {
Navbar, Breadcrumbs, PageLoadProgressBar, DefaultPasswordWarning, BootstrapError, Footer
} from 'views/layout';
import {DragDropContext} from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
@ -68,6 +70,7 @@ var RootComponent = React.createClass({
<div id='content-wrapper'>
<div className={utils.classNames(layoutClasses)}>
{!Page.hiddenLayout && [
<PageLoadProgressBar key='page-load-progress' />,
<Navbar
key='navbar'
ref='navbar'