From c5dd5e46c3053d50f27943e195e182ef25fd4b5e Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Sun, 15 Jan 2017 19:36:11 -0800 Subject: [PATCH 01/30] added tdFadeInOut animation in common module --- .../animations/fade/fadeInOut.animation.ts | 24 +++++++++++++++++++ src/platform/core/common/common.module.ts | 1 + 2 files changed, 25 insertions(+) create mode 100644 src/platform/core/common/animations/fade/fadeInOut.animation.ts diff --git a/src/platform/core/common/animations/fade/fadeInOut.animation.ts b/src/platform/core/common/animations/fade/fadeInOut.animation.ts new file mode 100644 index 0000000000..ab04693eff --- /dev/null +++ b/src/platform/core/common/animations/fade/fadeInOut.animation.ts @@ -0,0 +1,24 @@ +import { trigger, state, style, transition, animate, AnimationEntryMetadata } from '@angular/core'; + +/** + * Function TdFadeInOutAnimation + * + * params: + * * duration: Duration of animation in miliseconds. Defaults to 150 ms. + * + * Returns an [AnimationEntryMetadata] object with states for a fading animation. + * + * usage: [@tdFadeInOut]="true|false" + */ +export function TdFadeInOutAnimation(duration: number = 150): AnimationEntryMetadata { + return trigger('tdFadeInOut', [ + state('false', style({ + opacity: '0', + })), + state('true', style({ + opacity: '*', + })), + transition('0 => 1', animate(duration + 'ms ease-in')), + transition('1 => 0', animate(duration + 'ms ease-out')), + ]); +} diff --git a/src/platform/core/common/common.module.ts b/src/platform/core/common/common.module.ts index a26c7eda2e..7be857ea75 100644 --- a/src/platform/core/common/common.module.ts +++ b/src/platform/core/common/common.module.ts @@ -18,6 +18,7 @@ const TD_ANIMATIONS: Type[] = [ export { TdToggleDirective, TdFadeDirective }; export { TdCollapseAnimation } from './animations/collapse/collapse.animation'; +export { TdFadeInOutAnimation } from './animations/fade/fadeInOut.animation'; /** * FORMS From a8b787dc8cfc0f44fe00f91d73f94516cabffaf9 Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Sun, 15 Jan 2017 19:46:13 -0800 Subject: [PATCH 02/30] use tdFadeInOut animation in loading component --- .../core/loading/loading.component.html | 5 ++--- .../core/loading/loading.component.ts | 22 ++++++++++++++++--- .../core/loading/services/loading.service.ts | 2 +- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/platform/core/loading/loading.component.html b/src/platform/core/loading/loading.component.html index 6fb99d48e2..3dd9dcf882 100644 --- a/src/platform/core/loading/loading.component.html +++ b/src/platform/core/loading/loading.component.html @@ -1,6 +1,5 @@ -
'indeterminate', } +import { TdFadeInOutAnimation } from '../common/common.module'; + @Component({ selector: 'td-loading', styleUrls: ['./loading.component.scss' ], templateUrl: './loading.component.html', + animations: [ + TdFadeInOutAnimation(), + ], }) export class TdLoadingComponent { @@ -93,6 +98,15 @@ export class TdLoadingComponent { return this.type === LoadingType.Linear; } + animationComplete(event: AnimationTransitionEvent): void { + // Check to see if its "in" or "out" animation to execute the proper callback + if (!event.fromState) { + this.inAnimationCompleted(); + } else { + this.outAnimationCompleted(); + } + } + inAnimationCompleted(): void { this._animationIn.next(undefined); } @@ -114,7 +128,9 @@ export class TdLoadingComponent { * Starts in animation and returns an observable for completition event. */ startInAnimation(): Observable { - this.animation = false; + setTimeout(() => { + this.animation = true; + }); /* need to switch back to the selected mode, so we have saved it in another variable * and then recover it. (issue with protractor) */ @@ -126,7 +142,7 @@ export class TdLoadingComponent { * Starts out animation and returns an observable for completition event. */ startOutAnimation(): Observable { - this.animation = true; + this.animation = false; /* need to switch back and forth from determinate/indeterminate so the setInterval() * inside md-progress-spinner stops and protractor doesnt timeout waiting to sync. */ diff --git a/src/platform/core/loading/services/loading.service.ts b/src/platform/core/loading/services/loading.service.ts index 4c4e273f20..051ee5bdd4 100644 --- a/src/platform/core/loading/services/loading.service.ts +++ b/src/platform/core/loading/services/loading.service.ts @@ -178,7 +178,7 @@ export class TdLoadingService { public setValue(name: string, value: number): boolean { if (this._loadingSources[name]) { let instance: TdLoadingComponent = this._context[name].loadingRef.instance; - if (instance.mode === LoadingMode.Determinate && !instance.animation) { + if (instance.mode === LoadingMode.Determinate && instance.animation) { instance.value = value; return true; } From a9572c4780c9fc4e7e6642c6c5e255ef0330b8f4 Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Sun, 15 Jan 2017 19:57:04 -0800 Subject: [PATCH 03/30] no more need for the reset flag to get the determinate loading at value 0 when removed --- src/platform/core/loading/loading.component.html | 4 ++-- src/platform/core/loading/loading.component.ts | 10 +--------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/platform/core/loading/loading.component.html b/src/platform/core/loading/loading.component.html index 3dd9dcf882..3a01a31c5c 100644 --- a/src/platform/core/loading/loading.component.html +++ b/src/platform/core/loading/loading.component.html @@ -7,14 +7,14 @@ layout-align="center center" layout-padding flex> - - diff --git a/src/platform/core/loading/loading.component.ts b/src/platform/core/loading/loading.component.ts index 6e65f01cb7..70b6134d97 100644 --- a/src/platform/core/loading/loading.component.ts +++ b/src/platform/core/loading/loading.component.ts @@ -28,12 +28,6 @@ export class TdLoadingComponent { private _animationOut: Subject = new Subject(); private _mode: LoadingMode = LoadingMode.Indeterminate; private _defaultMode: LoadingMode = LoadingMode.Indeterminate; - private _reset: boolean = true; - - // Flag to reset the loader value and animation before removing it from DOM - get reset(): boolean { - return this._reset; - } /** * Flag for animation @@ -112,14 +106,12 @@ export class TdLoadingComponent { } outAnimationCompleted(): void { - /* little hack to reset the loader value and animation before removing it from DOM + /* little hack to reset the loader value and animation before removing it from DOM * else, the loader will appear with prev value when its registered again * and will do an animation going prev value to 0. */ - this._reset = false; this.value = 0; setTimeout(() => { - this._reset = true; this._animationOut.next(undefined); }); } From 15bff8fc82e93c917f0f36445297ad0a4bfa6e93 Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Mon, 16 Jan 2017 10:33:14 -0800 Subject: [PATCH 04/30] add display animation change on fadeInOut animation --- src/platform/core/common/animations/fade/fadeInOut.animation.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/platform/core/common/animations/fade/fadeInOut.animation.ts b/src/platform/core/common/animations/fade/fadeInOut.animation.ts index ab04693eff..cc9650fbed 100644 --- a/src/platform/core/common/animations/fade/fadeInOut.animation.ts +++ b/src/platform/core/common/animations/fade/fadeInOut.animation.ts @@ -14,9 +14,11 @@ export function TdFadeInOutAnimation(duration: number = 150): AnimationEntryMeta return trigger('tdFadeInOut', [ state('false', style({ opacity: '0', + display: 'none', })), state('true', style({ opacity: '*', + display: '*', })), transition('0 => 1', animate(duration + 'ms ease-in')), transition('1 => 0', animate(duration + 'ms ease-out')), From 7e089edafd1fc67502d969badf236411dd75724a Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Mon, 16 Jan 2017 10:54:58 -0800 Subject: [PATCH 05/30] feature(loading): call loading module to replace or overlay templates + OnPush change detection + easier fullscreen config. --- src/platform/core/loading/_loading-theme.scss | 6 +- .../loading/directives/loading.directive.ts | 29 +++- .../core/loading/loading.component.html | 7 +- .../core/loading/loading.component.scss | 27 ++-- .../core/loading/loading.component.ts | 51 ++++-- src/platform/core/loading/loading.module.ts | 2 +- .../core/loading/services/loading.service.ts | 153 ++++++++++++------ 7 files changed, 191 insertions(+), 84 deletions(-) diff --git a/src/platform/core/loading/_loading-theme.scss b/src/platform/core/loading/_loading-theme.scss index e8239144a9..a26431ae17 100644 --- a/src/platform/core/loading/_loading-theme.scss +++ b/src/platform/core/loading/_loading-theme.scss @@ -2,9 +2,9 @@ @mixin td-loading-theme($theme) { $background: map-get($theme, background); - .td-loading { - &.td-overlay { - background: rgba(md-color($background, dialog), 0.9); + .td-loading-wrapper { + &.td-overlay .td-loading { + background: rgba(md-color($background, dialog), 0.8); } } } \ No newline at end of file diff --git a/src/platform/core/loading/directives/loading.directive.ts b/src/platform/core/loading/directives/loading.directive.ts index 055396647e..46403e9807 100644 --- a/src/platform/core/loading/directives/loading.directive.ts +++ b/src/platform/core/loading/directives/loading.directive.ts @@ -1,7 +1,7 @@ import { Directive, Input, OnInit, OnDestroy } from '@angular/core'; import { ViewContainerRef, TemplateRef } from '@angular/core'; -import { LoadingType, LoadingMode } from '../loading.component'; +import { LoadingType, LoadingMode, LoadingStrategy } from '../loading.component'; import { TdLoadingService, ILoadingOptions } from '../services/loading.service'; @Directive({ @@ -11,6 +11,7 @@ export class TdLoadingDirective implements OnInit, OnDestroy { private _type: LoadingType; private _mode: LoadingMode; + private _strategy: LoadingStrategy; private _name: string; /** @@ -28,6 +29,10 @@ export class TdLoadingDirective implements OnInit, OnDestroy { * Defaults to [LoadingType.Circular | 'circular']. */ @Input('loadingType') + set typeDeprecated(type: LoadingType) { + this.type = type; + } + @Input('tdLoadingType') set type(type: LoadingType) { switch (type) { case LoadingType.Linear: @@ -45,6 +50,10 @@ export class TdLoadingDirective implements OnInit, OnDestroy { * Defaults to [LoadingMode.Indeterminate | 'indeterminate']. */ @Input('loadingMode') + set modeDeprecated(mode: LoadingMode) { + this.mode = mode; + } + @Input('tdLoadingMode') set mode(mode: LoadingMode) { switch (mode) { case LoadingMode.Determinate: @@ -56,12 +65,24 @@ export class TdLoadingDirective implements OnInit, OnDestroy { } } - constructor(private _viewContainer: ViewContainerRef, + @Input('tdLoadingStrategy') + set strategy(stategy: LoadingStrategy) { + switch (stategy) { + case LoadingStrategy.Overlay: + this._strategy = LoadingStrategy.Overlay; + break; + default: + this._strategy = LoadingStrategy.Replace; + break; + } + } + + constructor(private _viewContainerRef: ViewContainerRef, private _templateRef: TemplateRef, private _loadingService: TdLoadingService) {} ngOnInit(): void { - this._viewContainer.createEmbeddedView(this._templateRef); + this._viewContainerRef.createEmbeddedView(this._templateRef); this._registerComponent(); } @@ -82,6 +103,6 @@ export class TdLoadingDirective implements OnInit, OnDestroy { type: this._type, mode: this._mode, }; - this._loadingService.createReplaceComponent(options, this._viewContainer, this._templateRef); + this._loadingService.createComponent(this._strategy, options, this._viewContainerRef, this._templateRef); } } diff --git a/src/platform/core/loading/loading.component.html b/src/platform/core/loading/loading.component.html index 3a01a31c5c..ad38e17bf4 100644 --- a/src/platform/core/loading/loading.component.html +++ b/src/platform/core/loading/loading.component.html @@ -1,8 +1,7 @@ -
+
+
+
\ No newline at end of file diff --git a/src/platform/core/loading/loading.component.scss b/src/platform/core/loading/loading.component.scss index 8195c92798..cf3f312441 100644 --- a/src/platform/core/loading/loading.component.scss +++ b/src/platform/core/loading/loading.component.scss @@ -1,17 +1,24 @@ -.td-loading { +.td-loading-wrapper { + position: relative; + display: block; + &.td-fullscreen { + position: inherit; + } &.td-overlay { - position: fixed; - margin: 0; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: 1000; - md-progress-bar { - position: fixed; + .td-loading { + position: absolute; + margin: 0; top: 0; left: 0; right: 0; + bottom: 0; + z-index: 1000; + md-progress-bar { + position: absolute; + top: 0; + left: 0; + right: 0; + } } } } diff --git a/src/platform/core/loading/loading.component.ts b/src/platform/core/loading/loading.component.ts index 70b6134d97..0dcb919164 100644 --- a/src/platform/core/loading/loading.component.ts +++ b/src/platform/core/loading/loading.component.ts @@ -1,7 +1,10 @@ -import { Component, AnimationTransitionEvent } from '@angular/core'; +import { Component, AnimationTransitionEvent, ViewChild, TemplateRef, ChangeDetectorRef, ChangeDetectionStrategy } from '@angular/core'; +import { TemplatePortal } from '@angular/material'; import { Subject } from 'rxjs/Subject'; import { Observable } from 'rxjs/Observable'; +import { LoadingStyle } from './services/loading.service'; + export enum LoadingType { Circular = 'circular', Linear = 'linear', @@ -12,9 +15,15 @@ export enum LoadingMode { Indeterminate = 'indeterminate', } +export enum LoadingStrategy { + Overlay = 'overlay', + Replace = 'replace', +} + import { TdFadeInOutAnimation } from '../common/common.module'; @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, selector: 'td-loading', styleUrls: ['./loading.component.scss' ], templateUrl: './loading.component.html', @@ -28,6 +37,7 @@ export class TdLoadingComponent { private _animationOut: Subject = new Subject(); private _mode: LoadingMode = LoadingMode.Indeterminate; private _defaultMode: LoadingMode = LoadingMode.Indeterminate; + private _value: number = 0; /** * Flag for animation @@ -44,16 +54,20 @@ export class TdLoadingComponent { return this._mode; } + content: TemplatePortal; + /** * Sets value of [TdLoadingComponent] if mode is 'LoadingMode.Determinate' */ - value: number = 0; + set value(value: number) { + this._value = value; + this._changeDetectorRef.markForCheck(); + } + get value(): number { + return this._value; + } - /** - * overlay: boolean - * Sets if [TdLoadingComponent] is fullscreen or not. - */ - overlay: boolean = false; + style: LoadingStyle = LoadingStyle.None; /** * height: number @@ -67,11 +81,16 @@ export class TdLoadingComponent { */ type: LoadingType = LoadingType.Circular; + constructor(private _changeDetectorRef: ChangeDetectorRef) {} + getHeight(): string { - if (this.height) { - return `${this.height}px`; + // Ignore height if style is `overlay` or `fullscreen`. + // Add height if child elements have a height and style is `none`, else return default height. + if (this.isOverlay() || this.isFullScreen()) { + return undefined; + } else { + return this.height ? `${this.height}px` : '150px'; } - return '150px'; } getCircleDiameter(): string { @@ -92,6 +111,14 @@ export class TdLoadingComponent { return this.type === LoadingType.Linear; } + isFullScreen(): boolean { + return this.style === LoadingStyle.FullScreen; + } + + isOverlay(): boolean { + return this.style === LoadingStyle.Overlay; + } + animationComplete(event: AnimationTransitionEvent): void { // Check to see if its "in" or "out" animation to execute the proper callback if (!event.fromState) { @@ -111,6 +138,7 @@ export class TdLoadingComponent { * and will do an animation going prev value to 0. */ this.value = 0; + this._changeDetectorRef.markForCheck(); setTimeout(() => { this._animationOut.next(undefined); }); @@ -122,11 +150,13 @@ export class TdLoadingComponent { startInAnimation(): Observable { setTimeout(() => { this.animation = true; + this._changeDetectorRef.markForCheck(); }); /* need to switch back to the selected mode, so we have saved it in another variable * and then recover it. (issue with protractor) */ this._mode = this._defaultMode; + this._changeDetectorRef.markForCheck(); return this._animationIn.asObservable(); } @@ -139,6 +169,7 @@ export class TdLoadingComponent { * inside md-progress-spinner stops and protractor doesnt timeout waiting to sync. */ this._mode = LoadingMode.Determinate; + this._changeDetectorRef.markForCheck(); return this._animationOut.asObservable(); } } diff --git a/src/platform/core/loading/loading.module.ts b/src/platform/core/loading/loading.module.ts index 1f8b3a8e92..b3f0a9323e 100644 --- a/src/platform/core/loading/loading.module.ts +++ b/src/platform/core/loading/loading.module.ts @@ -19,7 +19,7 @@ const TD_LOADING_ENTRY_COMPONENTS: Type[] = [ TdLoadingComponent, ]; -export { LoadingType, LoadingMode } from './loading.component'; +export { LoadingType, LoadingMode, LoadingStrategy } from './loading.component'; export { TdLoadingService, ILoadingOptions } from './services/loading.service'; @NgModule({ diff --git a/src/platform/core/loading/services/loading.service.ts b/src/platform/core/loading/services/loading.service.ts index 051ee5bdd4..3f7d5209be 100644 --- a/src/platform/core/loading/services/loading.service.ts +++ b/src/platform/core/loading/services/loading.service.ts @@ -1,10 +1,17 @@ import { Injectable, ComponentFactoryResolver } from '@angular/core'; import { Injector, ComponentRef, ViewContainerRef, TemplateRef } from '@angular/core'; +import { TemplatePortal, Overlay, OverlayState, OverlayRef, OverlayOrigin, ComponentPortal } from '@angular/material'; import { Subject } from 'rxjs/Subject'; import { Observable } from 'rxjs/Observable'; import { Subscription } from 'rxjs/Subscription'; -import { TdLoadingComponent, LoadingType, LoadingMode } from '../loading.component'; +import { TdLoadingComponent, LoadingType, LoadingMode, LoadingStrategy } from '../loading.component'; + +export enum LoadingStyle { + FullScreen = 'fullscreen', + Overlay = 'overlay', + None = 'none', +} export interface ILoadingOptions { name: string; @@ -14,25 +21,62 @@ export interface ILoadingOptions { interface IInternalLoadingOptions extends ILoadingOptions { height?: number; - overlay?: boolean; + style?: LoadingStyle; } interface ILoadingRef { observable: Observable; - ref: ComponentRef; + componentRef: ComponentRef; + subject?: Subject; + times?: number; } @Injectable() export class TdLoadingService { - private _context: {[key: string]: {times?: number, loadingRef?: ComponentRef}} = {}; - private _loadingSources: {[key: string]: Subject} = {}; - private _loadingObservables: {[key: string]: Observable} = {}; + private _context: {[key: string]: ILoadingRef} = {}; constructor(private _componentFactoryResolver: ComponentFactoryResolver, + private _overlay: Overlay, private _injector: Injector) { } + createComponent(strategy: LoadingStrategy, options: ILoadingOptions, viewContainerRef: ViewContainerRef, + templateRef: TemplateRef): void { + if (strategy === LoadingStrategy.Overlay) { + this._context[options.name] = this.createOverlayComponent(options, viewContainerRef, templateRef); + } else { + this._context[options.name] = this.createReplaceComponent(options, viewContainerRef, templateRef); + } + } + + public createFullScreenComponent(options: ILoadingOptions): void { + (options).height = undefined; + (options).style = LoadingStyle.FullScreen; + let loadingRef: ILoadingRef = this._initializeContext(options); + let loading: boolean = false; + let overlayRef: OverlayRef; + loadingRef.observable + .subscribe((registered: number) => { + if (registered > 0 && !loading) { + loading = true; + overlayRef = this._createOverlay(); + loadingRef.componentRef = overlayRef.attach(new ComponentPortal(TdLoadingComponent)); + this._mapOptions(options, loadingRef.componentRef.instance); + loadingRef.componentRef.instance.startInAnimation(); + } else if (registered <= 0 && loading) { + loading = false; + let subs: Subscription = loadingRef.componentRef.instance.startOutAnimation().subscribe(() => { + subs.unsubscribe(); + loadingRef.componentRef.destroy(); + overlayRef.detach(); + overlayRef.dispose(); + }); + } + }); + this._context[options.name] = loadingRef; + } + /** * params: * - options: ILoadingOptions { @@ -44,26 +88,27 @@ export class TdLoadingService { * Creates an fullscreen loading mask and attaches it to the viewContainerRef. * Only displayed when the mask has a request registered on it. */ - public createOverlayComponent(options: ILoadingOptions, viewContainerRef: ViewContainerRef): void { + public createOverlayComponent(options: ILoadingOptions, viewContainerRef: ViewContainerRef, + templateRef: TemplateRef): ILoadingRef { (options).height = undefined; - (options).overlay = true; + (options).style = LoadingStyle.Overlay; let loadingRef: ILoadingRef = this._createComponent(options); let loading: boolean = false; + loadingRef.componentRef.instance.content = new TemplatePortal(templateRef, viewContainerRef); + viewContainerRef.clear(); + viewContainerRef.insert(loadingRef.componentRef.hostView, 0); loadingRef.observable .subscribe((registered: number) => { - let instance: TdLoadingComponent = loadingRef.ref.instance; if (registered > 0 && !loading) { loading = true; - viewContainerRef.insert(loadingRef.ref.hostView, 0); - instance.startInAnimation(); + loadingRef.componentRef.instance.startInAnimation(); } else if (registered <= 0 && loading) { loading = false; - let subs: Subscription = instance.startOutAnimation().subscribe(() => { - subs.unsubscribe(); - viewContainerRef.detach(viewContainerRef.indexOf(loadingRef.ref.hostView)); - }); + loadingRef.componentRef.instance.startOutAnimation(); } }); + this._context[options.name] = loadingRef; + return loadingRef; } /** @@ -79,33 +124,34 @@ export class TdLoadingService { * Replaces the templateRef with the mask when a request is registered on it. */ public createReplaceComponent(options: ILoadingOptions, viewContainerRef: ViewContainerRef, - templateRef: TemplateRef): void { + templateRef: TemplateRef): ILoadingRef { let nativeElement: HTMLElement = templateRef.elementRef.nativeElement; (options).height = nativeElement.nextElementSibling ? nativeElement.nextElementSibling.scrollHeight : undefined; - (options).overlay = false; + (options).style = LoadingStyle.None; let loadingRef: ILoadingRef = this._createComponent(options); let loading: boolean = false; loadingRef.observable .subscribe((registered: number) => { - let instance: TdLoadingComponent = loadingRef.ref.instance; if (registered > 0 && !loading) { loading = true; - let index: number = viewContainerRef.indexOf(loadingRef.ref.hostView); + let index: number = viewContainerRef.indexOf(loadingRef.componentRef.hostView); if (index < 0) { viewContainerRef.clear(); - viewContainerRef.insert(loadingRef.ref.hostView, 0); + viewContainerRef.insert(loadingRef.componentRef.hostView, 0); } - instance.startInAnimation(); + loadingRef.componentRef.instance.startInAnimation(); } else if (registered <= 0 && loading) { loading = false; - let subs: Subscription = instance.startOutAnimation().subscribe(() => { + let subs: Subscription = loadingRef.componentRef.instance.startOutAnimation().subscribe(() => { subs.unsubscribe(); viewContainerRef.createEmbeddedView(templateRef); - viewContainerRef.detach(viewContainerRef.indexOf(loadingRef.ref.hostView)); + viewContainerRef.detach(viewContainerRef.indexOf(loadingRef.componentRef.hostView)); }); } }); + this._context[options.name] = loadingRef; + return loadingRef; } /** @@ -116,9 +162,8 @@ export class TdLoadingService { */ public removeComponent(name: string): void { if (this._context[name]) { - this._loadingSources[name] = undefined; - delete this._loadingSources[name]; - this._context[name].loadingRef.destroy(); + this._context[name].subject.unsubscribe(); + this._context[name].componentRef.destroy(); this._context[name] = undefined; delete this._context[name]; } @@ -134,10 +179,10 @@ export class TdLoadingService { * Can optionally pass registers argument to set a number of register calls. */ public register(name: string, registers: number = 1): boolean { - if (this._loadingSources[name]) { + if (this._context[name]) { registers = registers < 1 ? 1 : registers; this._context[name].times += registers; - this._loadingSources[name].next(this._context[name].times); + this._context[name].subject.next(this._context[name].times); return true; } return false; @@ -153,14 +198,14 @@ export class TdLoadingService { * Can optionally pass resolves argument to set a number of resolve calls. */ public resolve(name: string, resolves: number = 1): boolean { - if (this._loadingSources[name]) { + if (this._context[name]) { resolves = resolves < 1 ? 1 : resolves; if (this._context[name].times > 0) { let times: number = this._context[name].times; times -= resolves; this._context[name].times = times < 0 ? 0 : times; } - this._loadingSources[name].next(this._context[name].times); + this._context[name].subject.next(this._context[name].times); return true; } return false; @@ -176,8 +221,8 @@ export class TdLoadingService { * Usage only available if its mode is 'determinate' and if loading is showing. */ public setValue(name: string, value: number): boolean { - if (this._loadingSources[name]) { - let instance: TdLoadingComponent = this._context[name].loadingRef.instance; + if (this._context[name]) { + let instance: TdLoadingComponent = this._context[name].componentRef.instance; if (instance.mode === LoadingMode.Determinate && instance.animation) { instance.value = value; return true; @@ -186,36 +231,47 @@ export class TdLoadingService { return false; } + private _createOverlay(): OverlayRef { + let state: OverlayState = new OverlayState(); + state.hasBackdrop = false; + state.positionStrategy = this._overlay.position().global().centerHorizontally().centerVertically(); + return this._overlay.create(state); + } + /** * Creates a generic [TdLoadingComponent] and its context. * Returns a promise that resolves to a [ILoadingRef] with the created [ComponentRef] and its referenced [Observable]. */ private _createComponent(options: IInternalLoadingOptions): ILoadingRef { + let compRef: ILoadingRef = this._initializeContext(options); + compRef.componentRef = this._componentFactoryResolver + .resolveComponentFactory(TdLoadingComponent).create(this._injector); + this._mapOptions(options, compRef.componentRef.instance); + return compRef; + } + + private _initializeContext(options: IInternalLoadingOptions): ILoadingRef { let name: string = options.name; if (!name) { throw 'Name is required for Loading Component.'; } - if (!this._context[name] || options.overlay) { - this._context[name] = {}; - } else { + if (this._context[name] && !(options.style === LoadingStyle.FullScreen)) { throw `Name duplication: Loading Component name conflict with ${name}.`; } - this._context[name].loadingRef = this._componentFactoryResolver - .resolveComponentFactory(TdLoadingComponent).create(this._injector); - this._context[name].times = 0; - this._mapOptions(options, this._context[name].loadingRef.instance); - let compRef: ILoadingRef = { - observable: this._registerLoadingComponent(name), - ref: this._context[name].loadingRef, + let subject: Subject = new Subject(); + return { + observable: subject.asObservable(), + subject: subject, + componentRef: undefined, + times: 0, }; - return compRef; } /** * Maps the [IInternalLoadingOptions] object to the [TdLoadingComponent] instance. */ private _mapOptions(options: IInternalLoadingOptions, instance: TdLoadingComponent): void { - instance.overlay = options.overlay; + instance.style = options.style; if (options.type !== undefined) { instance.type = options.type; } @@ -226,13 +282,4 @@ export class TdLoadingService { instance.mode = options.mode; } } - - /** - * Creates an observable for the parameter name reference, and returns it. - */ - private _registerLoadingComponent(name: string): Observable { - this._loadingSources[name] = new Subject(); - this._loadingObservables[name] = this._loadingSources[name].asObservable(); - return this._loadingObservables[name]; - } } From 48da19abc95369b27a7cf8a889126bae5a64932f Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Mon, 16 Jan 2017 11:08:09 -0800 Subject: [PATCH 06/30] add default main fullscreen mask `td-loading-main` to be called ignoring the name in `resolve`/`register` --- src/platform/core/loading/services/loading.service.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/platform/core/loading/services/loading.service.ts b/src/platform/core/loading/services/loading.service.ts index 3f7d5209be..ac651967d0 100644 --- a/src/platform/core/loading/services/loading.service.ts +++ b/src/platform/core/loading/services/loading.service.ts @@ -39,6 +39,9 @@ export class TdLoadingService { constructor(private _componentFactoryResolver: ComponentFactoryResolver, private _overlay: Overlay, private _injector: Injector) { + this.createFullScreenComponent({ + name: 'td-loading-main', + }); } createComponent(strategy: LoadingStrategy, options: ILoadingOptions, viewContainerRef: ViewContainerRef, @@ -178,7 +181,7 @@ export class TdLoadingService { * Resolves a request for the loading mask referenced by the name parameter. * Can optionally pass registers argument to set a number of register calls. */ - public register(name: string, registers: number = 1): boolean { + public register(name: string = 'td-loading-main', registers: number = 1): boolean { if (this._context[name]) { registers = registers < 1 ? 1 : registers; this._context[name].times += registers; @@ -197,7 +200,7 @@ export class TdLoadingService { * Registers a request for the loading mask referenced by the name parameter. * Can optionally pass resolves argument to set a number of resolve calls. */ - public resolve(name: string, resolves: number = 1): boolean { + public resolve(name: string = 'td-loading-main', resolves: number = 1): boolean { if (this._context[name]) { resolves = resolves < 1 ? 1 : resolves; if (this._context[name].times > 0) { From 888596f631d55cce139ca230fe409c93e3daafbe Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Mon, 16 Jan 2017 14:01:34 -0800 Subject: [PATCH 07/30] added code docs and deprecation messages --- .../loading/directives/loading.directive.ts | 42 ++++++++++++++----- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/src/platform/core/loading/directives/loading.directive.ts b/src/platform/core/loading/directives/loading.directive.ts index 46403e9807..6b0f3a9b15 100644 --- a/src/platform/core/loading/directives/loading.directive.ts +++ b/src/platform/core/loading/directives/loading.directive.ts @@ -2,7 +2,7 @@ import { Directive, Input, OnInit, OnDestroy } from '@angular/core'; import { ViewContainerRef, TemplateRef } from '@angular/core'; import { LoadingType, LoadingMode, LoadingStrategy } from '../loading.component'; -import { TdLoadingService, ILoadingOptions } from '../services/loading.service'; +import { TdLoadingService } from '../services/loading.service'; @Directive({ selector: '[tdLoading]', @@ -24,14 +24,21 @@ export class TdLoadingDirective implements OnInit, OnDestroy { } /** - * loadingType?: LoadingType or ['linear' | 'circular'] - * Sets the type of loading mask depending on value. - * Defaults to [LoadingType.Circular | 'circular']. + * @deprecated in 1.0.0-beta.1 + * + * Please use the `tdLoadingType` method. */ @Input('loadingType') set typeDeprecated(type: LoadingType) { + /* tslint:disable-next-line */ + console.warn("loadingType is deprecated. Please use tdLoadingType instead"); this.type = type; } + /** + * tdLoadingType?: LoadingType or ['linear' | 'circular'] + * Sets the type of loading mask depending on value. + * Defaults to [LoadingType.Circular | 'circular']. + */ @Input('tdLoadingType') set type(type: LoadingType) { switch (type) { @@ -45,14 +52,21 @@ export class TdLoadingDirective implements OnInit, OnDestroy { } /** - * LoadingMode?: LoadingMode or ['determinate' | 'indeterminate'] - * Sets the mode of loading mask depending on value. - * Defaults to [LoadingMode.Indeterminate | 'indeterminate']. + * @deprecated in 1.0.0-beta.1 + * + * Please use the `tdLoadingMode` method. */ @Input('loadingMode') set modeDeprecated(mode: LoadingMode) { + /* tslint:disable-next-line */ + console.warn("loadingMode is deprecated. Please use tdLoadingMode instead"); this.mode = mode; } + /** + * tdLoadingMode?: LoadingMode or ['determinate' | 'indeterminate'] + * Sets the mode of loading mask depending on value. + * Defaults to [LoadingMode.Indeterminate | 'indeterminate']. + */ @Input('tdLoadingMode') set mode(mode: LoadingMode) { switch (mode) { @@ -81,28 +95,34 @@ export class TdLoadingDirective implements OnInit, OnDestroy { private _templateRef: TemplateRef, private _loadingService: TdLoadingService) {} + /** + * Registers component in the DOM, so it will be available when calling resolve/register. + */ ngOnInit(): void { this._viewContainerRef.createEmbeddedView(this._templateRef); this._registerComponent(); } + /** + * Remove component when directive is destroyed. + */ ngOnDestroy(): void { this._loadingService.removeComponent(this._name); } /** * Creates [TdLoadingComponent] and attaches it to this directive's [ViewContainerRef]. - * Passes this directive's [TemplateRef] to detach/attach it from DOM when loading mask is on. + * Passes this directive's [TemplateRef] to modify DOM depending on loading `strategy`. */ private _registerComponent(): void { if (!this._name) { throw 'Name is needed to register loading directive'; } - let options: ILoadingOptions = { + this._loadingService.createComponent({ name: this._name, type: this._type, mode: this._mode, - }; - this._loadingService.createComponent(this._strategy, options, this._viewContainerRef, this._templateRef); + strategy: this._strategy, + }, this._viewContainerRef, this._templateRef); } } From 5b20d03c594e6747218a34dda37b607d1be4a79c Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Mon, 16 Jan 2017 14:39:07 -0800 Subject: [PATCH 08/30] reparated code into service (execution) and factory (creation) + renamed ILoadingOptions -> ITdLoadingConfig --- .../components/loading/loading.component.html | 18 +- .../components/loading/loading.component.ts | 35 +-- .../core/loading/loading.component.ts | 8 +- src/platform/core/loading/loading.module.ts | 5 +- .../core/loading/services/loading.factory.ts | 147 +++++++++++ .../core/loading/services/loading.service.ts | 247 ++++++------------ 6 files changed, 257 insertions(+), 203 deletions(-) create mode 100644 src/platform/core/loading/services/loading.factory.ts diff --git a/src/app/components/components/loading/loading.component.html b/src/app/components/components/loading/loading.component.html index 62f0ca3b15..ad7293e489 100644 --- a/src/app/components/components/loading/loading.component.html +++ b/src/app/components/components/loading/loading.component.html @@ -13,7 +13,7 @@

Indeterminate Mode

Circular Type

- +

Linear Type

- +
]]> @@ -188,7 +188,7 @@

Overlay strategy - accent color in (*) syntax

- +
@@ -207,7 +207,7 @@

Overlay strategy - accent color in (*) syntax

- +
]]> From c218f6741440732e7046ecafc50a5b2cbc9547fa Mon Sep 17 00:00:00 2001 From: Ed Morales Date: Wed, 18 Jan 2017 09:54:58 -0800 Subject: [PATCH 30/30] better explanation on demos --- .../components/loading/loading.component.html | 194 +++++++++--------- 1 file changed, 99 insertions(+), 95 deletions(-) diff --git a/src/app/components/components/loading/loading.component.html b/src/app/components/components/loading/loading.component.html index 9621a039a4..b9b61cccba 100644 --- a/src/app/components/components/loading/loading.component.html +++ b/src/app/components/components/loading/loading.component.html @@ -3,12 +3,23 @@ Circular or linear progress loader -

Default main loading mask

+

[tdLoading] directive with (*) syntax

+

with indetederminate [tdLoadingMode], circular [tdLoadingType], overlay [tdLoadingStrategy], accent [tdLoadingColor]

+
+
+ + + + + + +
+
- +
@@ -16,8 +27,18 @@

Default main loading mask

HTML:

+
+ + + + + + +
+
- +
]]>
@@ -26,66 +47,22 @@

Default main loading mask

{ - this._loadingService.resolve(); - }, 1500); - } - } - ]]> - -
-
-
- - - -

Configurable main loading mask

- - - -
- -
-
- - -

HTML:

- - - - - ]]> - -

Typescript:

- - { - this._loadingService.resolve('configFullscreenDemo'); - }, 1500); + toggleOverlayStarSyntax(): void { + if (this.overlayStarSyntax) { + this._loadingService.register('overlayStarSyntax'); + } else { + this._loadingService.resolve('overlayStarSyntax'); + } + this.overlayStarSyntax = !this.overlayStarSyntax; } } ]]> @@ -96,7 +73,8 @@

Configurable main loading mask

-

Replace strategy - determinate mode in template syntax

+

[tdLoading] directive with template syntax

+

with determinate [tdLoadingMode], linear [tdLoadingType], replace [tdLoadingStrategy], warn [tdLoadingColor]

@@ -173,22 +151,13 @@

Replace strategy - determinate mode in template syntax

-

Overlay strategy - accent color in (*) syntax

+

Preloaded [TdLoading] fullscreen mask

+

with indeterminate [mode], circular [type], primary [color] by default

-
-
- - - - - - -
-
- +
@@ -196,18 +165,8 @@

Overlay strategy - accent color in (*) syntax

HTML:

-
- - - - - - -
-
- +
]]>
@@ -216,22 +175,67 @@

Overlay strategy - accent color in (*) syntax

{ + this._loadingService.resolve(); + }, 1500); + } + } + ]]> + +
+
+
+
+ + +

Custom [TdLoading] fullscreen mask

+

with indeterminate [mode], linear [type], accent [color]

+ + + +
+ +
+
+ + +

HTML:

+ + + + + ]]> + +

Typescript:

+ + { + this._loadingService.resolve('configFullscreenDemo'); + }, 1500); } } ]]>