From 16dd53e7982245e9fd713eb23f3f66f1ce965fac Mon Sep 17 00:00:00 2001 From: Marius Hein Date: Tue, 24 Sep 2013 17:42:37 +0200 Subject: [PATCH] Implement container load mask refs #4400 --- public/css/main.css | 22 +++++ public/js/icinga/components/container.js | 93 ++++++++++++++++--- public/js/icinga/components/mainDetailGrid.js | 8 +- 3 files changed, 109 insertions(+), 14 deletions(-) diff --git a/public/css/main.css b/public/css/main.css index 5e3ea3a5d..fdf3e8261 100644 --- a/public/css/main.css +++ b/public/css/main.css @@ -1 +1,23 @@ body { padding-top: 70px; } + +.load-indicator .mask { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background-color: #666; + opacity: 0.3; + z-index: 998; +} + +.load-indicator .label { + position: absolute; + top: 0; + left: 0; + color: #000; + background-color: #fff; + font-weight: normal; + z-index: 999; + border: none; +} diff --git a/public/js/icinga/components/container.js b/public/js/icinga/components/container.js index 683582904..2c3e47bb9 100644 --- a/public/js/icinga/components/container.js +++ b/public/js/icinga/components/container.js @@ -117,6 +117,11 @@ define(['jquery', 'logging', 'icinga/componentLoader', 'URIjs/URI', 'URIjs/URITe this.containerType = CONTAINER_TYPES.GENERIC; } this.containerDom.attr('data-icinga-href', this.getContainerHref()); + + if (this.containerDom.data('loadIndicator') !== true) { + this.installDefaultLoadIndicator(); + this.containerDom.data('loadIndicator', true); + } }; /** @@ -208,9 +213,9 @@ define(['jquery', 'logging', 'icinga/componentLoader', 'URIjs/URI', 'URIjs/URITe /** * Return a complete Href string representing the current detail href and the provided main Url * - * @param {URI} url The detail Url to use as an URI.js object + * @param {URI} url The detail Url to use as an URI.js object * - * @returns {URI} The modified URI.js containing the new detail and the current main link + * @returns {URI} The modified URI.js containing the new detail and the current main link */ var setDetailContainerHref = function(url, baseUrl) { var location = new URI(baseUrl); @@ -221,6 +226,33 @@ define(['jquery', 'logging', 'icinga/componentLoader', 'URIjs/URI', 'URIjs/URITe return location; }; + /** + * Create default load mask + * + * @private + */ + var createDefaultLoadIndicator = function() { + + this.showDetail(); + + if (this.containerDom.find('div.load-indicator').length === 0) { + var content = '
' + + '
' + + '
Loading
' + + '
'; + $(this.containerDom).append(content); + } + }; + + /** + * Remove default load mask + * + * @private + */ + var destroyDefaultLoadIndicator = function() { + $(this.containerDom).remove('div.load-indicator'); + }; + /** * Update the Url of this container and let the Url reflect the new changes, if required * @@ -262,7 +294,6 @@ define(['jquery', 'logging', 'icinga/componentLoader', 'URIjs/URI', 'URIjs/URITe return windowUrl.href(); }; - /** * Load the provided url, stop all pending requests for this container and call replaceDom for the returned html * @@ -271,6 +302,7 @@ define(['jquery', 'logging', 'icinga/componentLoader', 'URIjs/URI', 'URIjs/URITe * @param {String, URI} url The Url to load or and URI.js object encapsulating it */ this.replaceDomFromUrl = function(url) { + this.containerDom.trigger('showLoadIndicator'); Icinga.replaceBodyFromUrl(this.updateContainerHref(url)); }; @@ -289,8 +321,10 @@ define(['jquery', 'logging', 'icinga/componentLoader', 'URIjs/URI', 'URIjs/URITe * @see registerOnUpdate */ this.replaceDom = function(domNodes, keepLayout) { + this.containerDom.trigger('showLoadIndicator'); this.containerDom.empty().append(domNodes); this.containerDom.trigger('updated', [domNodes]); + this.containerDom.trigger('hideLoadIndicator'); componentLoader.load(); if (!keepLayout) { if (this.containerType === CONTAINER_TYPES.DETAIL) { @@ -299,8 +333,6 @@ define(['jquery', 'logging', 'icinga/componentLoader', 'URIjs/URI', 'URIjs/URITe } }; - - /** * Register a method to be called when this container is updated * @@ -310,6 +342,41 @@ define(['jquery', 'logging', 'icinga/componentLoader', 'URIjs/URI', 'URIjs/URITe this.containerDom.on('updated', fn); }; + /** + * Register a method to show a load indicator + * + * @param {function} fn The function to register + */ + this.registerOnShowLoadIndicator = function(fn) { + this.containerDom.on('showLoadIndicator', fn); + + }; + + /** + * Register a method when load indicator should be removed + * + * @param {function} fn The function to register + */ + this.registerOnHideLoadIndicator = function(fn) { + this.containerDom.on('hideLoadIndicator', fn); + }; + + /** + * Install default load indicator + */ + this.installDefaultLoadIndicator = function() { + this.registerOnShowLoadIndicator($.proxy(createDefaultLoadIndicator, this)); + this.registerOnHideLoadIndicator($.proxy(destroyDefaultLoadIndicator, this)); + }; + + /** + * Remove default load indicator + */ + this.disableDefaultLoadIndicator = function() { + this.containerDom.off('showLoadIndicator'); + this.containerDom.off('hideLoadIndicator'); + }; + this.construct(target); }; @@ -363,16 +430,16 @@ define(['jquery', 'logging', 'icinga/componentLoader', 'URIjs/URI', 'URIjs/URITe var mainDom = Container.getMainContainer().containerDom, detailDom = Container.getDetailContainer().containerDom; + if (detailDom.find('*').length === 0) { + var mainHeight = $(window).height(); + detailDom.append('
'); + } + mainDom.removeClass(); detailDom.removeClass(); - mainDom.addClass('hidden-md'); - detailDom.addClass('col-md-12'); - mainDom.addClass('col-lg-7'); - detailDom.addClass('col-lg-5'); - mainDom.addClass('hidden-xs'); - detailDom.addClass('col-xs-12'); - mainDom.addClass('hidden-sm'); - detailDom.addClass('col-sm-12'); + + mainDom.addClass('col-xs-pull-12 col-sm-pull-12 col-md-pull-12 col-lg-7'); + detailDom.addClass('col-xs-push-12 col-sm-push-12 col-md-push-12 col-lg-5'); }; /** diff --git a/public/js/icinga/components/mainDetailGrid.js b/public/js/icinga/components/mainDetailGrid.js index 7c14d2dcd..76d25a5bd 100644 --- a/public/js/icinga/components/mainDetailGrid.js +++ b/public/js/icinga/components/mainDetailGrid.js @@ -161,7 +161,7 @@ function(Container, $, logger, URI) { }); $('.pagination li a', contentNode.parent()).on('click', function(ev) { var container = (new Container(this)); - Icinga.replaceBodyFromUrl( + container.replaceDomFromUrl( container.updateContainerHref($(this).attr('href')) ); ev.preventDefault(); @@ -190,16 +190,22 @@ function(Container, $, logger, URI) { Container.getDetailContainer().registerOnUpdate(this.syncSelectionWithDetail.bind(this)); }; + this.registerLoadIndicator = function() { + // console.log(this.container); + }; + /** * Create this component, setup listeners and behaviour */ this.construct = function(target) { this.container = new Container(target); + this.container.disableDefaultLoadIndicator(); controlForms = determineControlForms(); contentNode = determineContentTable(); this.registerControls(); this.registerTableLinks(); this.registerHistoryChanges(); + this.registerLoadIndicator(); }; this.construct(gridDomNode);