diff options
Diffstat (limited to 'catalog-ui/src/app/directives/loader/loader-directive.ts')
-rw-r--r-- | catalog-ui/src/app/directives/loader/loader-directive.ts | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/catalog-ui/src/app/directives/loader/loader-directive.ts b/catalog-ui/src/app/directives/loader/loader-directive.ts new file mode 100644 index 0000000000..aa9c4b09c4 --- /dev/null +++ b/catalog-ui/src/app/directives/loader/loader-directive.ts @@ -0,0 +1,155 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ +'use strict'; +import {EVENTS} from "app/utils"; +import {EventListenerService} from "app/services"; + +export interface ILoaderScope extends ng.IScope { + display:boolean; // Toggle show || hide scroll + size:string; // small || medium || large + elementSelector:string; // Jquery selector to hide and scroll inside + relative:boolean; // Will use the parent of <loader> element and hide it and scroll inside + loaderType:string; +} + +export class LoaderDirective implements ng.IDirective { + + constructor(private EventListenerService:EventListenerService) { + } + + /* + * relative is used when inserting the HTML loader inside some div <loader data-display="isLoading" relative="true"></loader> + * elementSelector when we want to pass the Jquery selector of the loader. + */ + scope = { + display: '=', + size: '@?', + elementSelector: '@?', + relative: '=?', + loaderType: '@?' + }; + + public replace = false; + public restrict = 'E'; + template = ():string => { + return require('./loader-directive.html'); + } + + link = (scope:ILoaderScope, element:any) => { + + let interval; + + this.EventListenerService.registerObserverCallback(EVENTS.SHOW_LOADER_EVENT, (loaderType)=> { + if (scope.loaderType !== loaderType) { + return; + } + scope.display = true; + }); + this.EventListenerService.registerObserverCallback(EVENTS.HIDE_LOADER_EVENT, (loaderType)=> { + if (scope.loaderType !== loaderType) { + return; + } + scope.display = false; + }); + + let calculateSizesForFixPosition = (positionStyle:string):void => { + // This is problematic, I do not want to change the parent position. + // set the loader on all the screen + let parentPosition = element.parent().position(); + let parentWidth = element.parent().width(); + let parentHeight = element.parent().height(); + element.css('position', positionStyle); + element.css('top', parentPosition.top); + element.css('left', parentPosition.left); + element.css('width', parentWidth); + element.css('height', parentHeight); + }; + + let setStyle = (positionStyle:string):void => { + + switch (positionStyle) { + case 'absolute': + case 'fixed': + // The parent size is not set yet, still loading, so need to use interval to update the size. + interval = window.setInterval(()=> { + calculateSizesForFixPosition(positionStyle); + }, 2000); + break; + default: + // Can change the parent position to relative without causing style issues. + element.parent().css('position', 'relative'); + break; + } + }; + + // This should be executed after the dom loaded + window.setTimeout(():void => { + + element.css('display', 'none'); + + if (scope.elementSelector) { + let elemParent = angular.element(scope.elementSelector); + let positionStyle:string = elemParent.css('position'); + setStyle(positionStyle); + } + + if (scope.relative === true) { + let positionStyle:string = element.parent().css('position'); + setStyle(positionStyle); + } + + if (!scope.size) { + scope.size = 'large'; + } + + }, 0); + + if (scope.elementSelector) { + + } + + function cleanUp() { + clearInterval(interval); + } + + scope.$watch("display", (newVal, oldVal) => { + element.css('display', 'none'); + if (newVal === true) { + window.setTimeout(():void => { + element.css('display', 'block'); + }, 500); + } else { + window.setTimeout(():void => { + element.css('display', 'none'); + }, 0); + } + }); + + scope.$on('$destroy', cleanUp); + + }; + + public static factory = (EventListenerService:EventListenerService)=> { + return new LoaderDirective( EventListenerService); + }; + +} + +LoaderDirective.factory.$inject = ['EventListenerService']; |