Skip to content
Snippets Groups Projects
Commit 0bcd8cbb authored by Mathis Neumann's avatar Mathis Neumann
Browse files

implement loading indicator

parent 89824300
No related branches found
No related tags found
No related merge requests found
......@@ -13,5 +13,13 @@ export default Controller.extend({
* @property flashMessage
* @type {FlashMessageService}
*/
flashMessages: inject.service()
flashMessages: inject.service(),
/**
* Injected LoadingState service to handle loading. Set from route
*
* @property loadingState
* @type {LoadingStateService}
*/
loadingState: inject.service()
});
\ No newline at end of file
import Ember from 'ember';
const { Route, inject } = Ember;
export default Route.extend({
/**
* Injected LoadingState service to handle loading. Set from route
*
* @property loadingState
* @type {LoadingStateService}
*/
loadingState: inject.service(),
actions: {
loading(transition) {
this.get('loadingState').loadPromise(transition.promise);
}
}
});
\ No newline at end of file
import Ember from 'ember';
const { Service, computed } = Ember;
/**
* Central service to trigger the loading state for the application.
* Gives the application the possibility to block actions while the application is loading a route.
*
* @class LoadingStateService
* @extends {Ember.Service}
*/
export default Service.extend({
/**
* Computed property which states if the application is loading a route.
* Can be subscribed to.
*
* @type {Boolean}
* @property isLoading
*/
isLoading: computed('_loadingCounter', function() {
return this.get('_loadingCounter') > 0;
}),
/**
* Negation of `isLoading`.
*
* @type {Boolean}
* @property isNotLoading
*/
isNotLoading: computed('isLoading', function() {
return !this.get('isLoading');
}),
/**
* States if the application is loading a route.
* Can be subscribed to.
*
* @type {Number}
* @property _loadingCounter
* @private
*/
_loadingCounter: 0,
/**
* starts the loading process. Increments internal counter.
*
* @method startLoading
*/
startLoading() {
this.incrementProperty('_loadingCounter');
this.debug('starting to load', this.get('_loadingCounter'));
},
/**
* Automagically handle the loading state for promises. Do not call `stopLoading` after that.
* @method loadPromise
* @param {Promise} promise
* @return promise that resolves after the loading was stopped
*/
loadPromise(promise) {
this.startLoading();
return promise.finally(() => {
this.stopLoading();
});
},
/**
* Signals that a loading was stopped. Decreases internal counter.
* @method stopLoading
*/
stopLoading() {
this.set('_loadingCounter', Math.max(0, this.get('_loadingCounter') - 1));
this.debug('stopped loading', this.get('_loadingCounter'));
}
});
\ No newline at end of file
......@@ -19,3 +19,31 @@ $navbar-default-color: $light-orange;
opacity: 0;
}
}
.invisible {
opacity: 0;
pointer-events: none; // invisible elements should not block clicking
}
.loadingIndicator {
opacity: 1;
transition: opacity 500ms ease-in; // .invisible will get toggled FIXME
position: absolute;
top: 10px;
left: 10px;
background-color: #EEE;
padding: 10px;
border-radius: 10px;
z-index: 1000;
}
.rotationAnimation {
transition: transform 1s;
animation: rotate 2s infinite linear;
}
@keyframes rotate {
from {transform: rotate(0deg);}
to {transform: rotate(360deg);}
}
\ No newline at end of file
{{loading-slider isLoading=loading duration=250}}
<div class="loadingIndicator {{if loadingState.isNotLoading 'invisible'}}">
<i class="glyphicon glyphicon-refresh rotationAnimation"></i>
Loading...
</div>
<nav class="navbar">
<div class="container">
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment