diff --git a/angular.json b/angular.json index b3d10f35..aa359a2c 100644 --- a/angular.json +++ b/angular.json @@ -25,7 +25,7 @@ "assets": [ "src/favicon.ico", "src/assets", - "src/app/main/content/components/angular-material" + "src/app/main/components/angular-material" ], "styles": [ "src/styles.scss" diff --git a/src/@fuse/components/confirm-dialog/confirm-dialog.component.ts b/src/@fuse/components/confirm-dialog/confirm-dialog.component.ts index 90eac6e5..0730cb1e 100644 --- a/src/@fuse/components/confirm-dialog/confirm-dialog.component.ts +++ b/src/@fuse/components/confirm-dialog/confirm-dialog.component.ts @@ -10,7 +10,14 @@ export class FuseConfirmDialogComponent { public confirmMessage: string; - constructor(public dialogRef: MatDialogRef) + /** + * Constructor + * + * @param {MatDialogRef} dialogRef + */ + constructor( + public dialogRef: MatDialogRef + ) { } diff --git a/src/@fuse/components/countdown/countdown.component.ts b/src/@fuse/components/countdown/countdown.component.ts index b00ad897..b519f64a 100644 --- a/src/@fuse/components/countdown/countdown.component.ts +++ b/src/@fuse/components/countdown/countdown.component.ts @@ -1,8 +1,6 @@ -import { Component, Input, OnInit } from '@angular/core'; - -import { interval } from 'rxjs'; -import { map } from 'rxjs/operators'; - +import { Component, Input, OnDestroy, OnInit } from '@angular/core'; +import { interval, Subject } from 'rxjs'; +import { map, takeUntil } from 'rxjs/operators'; import * as moment from 'moment'; @Component({ @@ -10,46 +8,82 @@ import * as moment from 'moment'; templateUrl: './countdown.component.html', styleUrls : ['./countdown.component.scss'] }) -export class FuseCountdownComponent implements OnInit +export class FuseCountdownComponent implements OnInit, OnDestroy { - @Input('eventDate') eventDate; + // Event date + @Input('eventDate') + eventDate; + countdown: any; + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + */ constructor() { + // Set the defaults this.countdown = { days : '', hours : '', minutes: '', seconds: '' }; + + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { const currDate = moment(); const eventDate = moment(this.eventDate); + // Get the difference in between the current date and event date let diff = eventDate.diff(currDate, 'seconds'); - const countDown = interval(1000).pipe( - map(value => { - return diff = diff - 1; - }), - map(value => { - const timeLeft = moment.duration(value, 'seconds'); + // Create a subscribable interval + const countDown = interval(1000) + .pipe( + map(value => { + return diff = diff - 1; + }), + map(value => { + const timeLeft = moment.duration(value, 'seconds'); - return { - days : timeLeft.asDays().toFixed(0), - hours : timeLeft.hours(), - minutes: timeLeft.minutes(), - seconds: timeLeft.seconds() - }; - }) - ); + return { + days : timeLeft.asDays().toFixed(0), + hours : timeLeft.hours(), + minutes: timeLeft.minutes(), + seconds: timeLeft.seconds() + }; + }) + ); - countDown.subscribe(value => { - this.countdown = value; - }); + // Subscribe to the countdown interval + countDown + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(value => { + this.countdown = value; + }); + } + + /** + * On destroy + */ + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); } } diff --git a/src/@fuse/components/demo/demo-content/demo-content.component.ts b/src/@fuse/components/demo/demo-content/demo-content.component.ts index 1e697894..eca3708b 100644 --- a/src/@fuse/components/demo/demo-content/demo-content.component.ts +++ b/src/@fuse/components/demo/demo-content/demo-content.component.ts @@ -7,6 +7,9 @@ import { Component } from '@angular/core'; }) export class FuseDemoContentComponent { + /** + * Constructor + */ constructor() { } diff --git a/src/@fuse/components/demo/demo-sidenav/demo-sidenav.component.ts b/src/@fuse/components/demo/demo-sidenav/demo-sidenav.component.ts index dde5b68f..9fb575e6 100644 --- a/src/@fuse/components/demo/demo-sidenav/demo-sidenav.component.ts +++ b/src/@fuse/components/demo/demo-sidenav/demo-sidenav.component.ts @@ -7,6 +7,9 @@ import { Component } from '@angular/core'; }) export class FuseDemoSidenavComponent { + /** + * Constructor + */ constructor() { } diff --git a/src/@fuse/components/highlight/highlight.component.ts b/src/@fuse/components/highlight/highlight.component.ts index e58be26d..69f8d0da 100644 --- a/src/@fuse/components/highlight/highlight.component.ts +++ b/src/@fuse/components/highlight/highlight.component.ts @@ -1,28 +1,55 @@ -import { Component, ContentChild, ElementRef, Input, OnInit } from '@angular/core'; +import { Component, ContentChild, ElementRef, Input, OnDestroy, OnInit } from '@angular/core'; import { HttpClient } from '@angular/common/http'; - +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import * as Prism from 'prismjs/prism'; -import './prism-languages'; +import '@fuse/components/highlight/prism-languages'; @Component({ selector : 'fuse-highlight', - template : ' ', + template : '', styleUrls: ['./highlight.component.scss'] }) -export class FuseHighlightComponent implements OnInit +export class FuseHighlightComponent implements OnInit, OnDestroy { - @ContentChild('source') source: ElementRef; - @Input('lang') lang: string; - @Input('path') path: string; + // Source + @ContentChild('source') + source: ElementRef; + // Lang + @Input('lang') + lang: string; + + // Path + @Input('path') + path: string; + + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {ElementRef} _elementRef + * @param {HttpClient} _httpClient + */ constructor( - private elementRef: ElementRef, - private http: HttpClient + private _elementRef: ElementRef, + private _httpClient: HttpClient ) { + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { // If there is no language defined, return... if ( !this.lang ) @@ -34,11 +61,13 @@ export class FuseHighlightComponent implements OnInit if ( this.path ) { // Get the source - this.http.get(this.path, {responseType: 'text'}).subscribe((response) => { + this._httpClient.get(this.path, {responseType: 'text'}) + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe((response) => { - // Highlight it - this.highlight(response); - }); + // Highlight it + this.highlight(response); + }); } // If the path is not defined and the source element exists... @@ -49,7 +78,26 @@ export class FuseHighlightComponent implements OnInit } } - highlight(sourceCode) + /** + * On destroy + */ + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Highlight the given source code + * + * @param sourceCode + */ + highlight(sourceCode): void { // Split the source into lines const sourceLines = sourceCode.split('\n'); @@ -94,9 +142,8 @@ export class FuseHighlightComponent implements OnInit const highlightedCode = Prism.highlight(source, Prism.languages[this.lang]); // Replace the innerHTML of the component with the highlighted code - this.elementRef.nativeElement.innerHTML = + this._elementRef.nativeElement.innerHTML = '
' + highlightedCode + '
'; - } } diff --git a/src/@fuse/components/index.ts b/src/@fuse/components/index.ts index 1cbd9d98..0a8fb885 100644 --- a/src/@fuse/components/index.ts +++ b/src/@fuse/components/index.ts @@ -2,7 +2,6 @@ export * from './confirm-dialog/confirm-dialog.module'; export * from './countdown/countdown.module'; export * from './demo/demo.module'; export * from './highlight/highlight.module'; -export * from './layouts/layouts.module'; export * from './material-color-picker/material-color-picker.module'; export * from './navigation/navigation.module'; export * from './search-bar/search-bar.module'; diff --git a/src/@fuse/components/layouts/layouts.module.ts b/src/@fuse/components/layouts/layouts.module.ts deleted file mode 100644 index c63b7335..00000000 --- a/src/@fuse/components/layouts/layouts.module.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; - -import { FuseVerticalNavBasicLayoutComponent } from '@fuse/components/layouts/vertical-nav/basic/basic.component'; - -@NgModule({ - declarations: [ - FuseVerticalNavBasicLayoutComponent - ], - imports : [ - CommonModule - ], - exports : [ - FuseVerticalNavBasicLayoutComponent - ] -}) -export class FuseLayoutsModule -{ -} diff --git a/src/@fuse/components/layouts/vertical-nav/basic/basic.component.html b/src/@fuse/components/layouts/vertical-nav/basic/basic.component.html deleted file mode 100644 index a2cc7980..00000000 --- a/src/@fuse/components/layouts/vertical-nav/basic/basic.component.html +++ /dev/null @@ -1,77 +0,0 @@ - - -
- - - - - - - - - - - - -
- - - - - - - -
- - - - - - - - - - - - - - - -
- - - - - - - -
- - - - - - - -
- - - - - - - -
- - diff --git a/src/@fuse/components/layouts/vertical-nav/basic/basic.component.ts b/src/@fuse/components/layouts/vertical-nav/basic/basic.component.ts deleted file mode 100644 index 17a17f17..00000000 --- a/src/@fuse/components/layouts/vertical-nav/basic/basic.component.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Component, ViewEncapsulation } from '@angular/core'; - -@Component({ - selector : 'fuse-vertical-nav-basic-layout', - templateUrl : './basic.component.html', - styleUrls : ['./basic.component.scss'], - encapsulation: ViewEncapsulation.None -}) -export class FuseVerticalNavBasicLayoutComponent -{ - constructor() - { - } -} diff --git a/src/@fuse/components/navigation/horizontal/nav-collapse/nav-horizontal-collapse.component.ts b/src/@fuse/components/navigation/horizontal/nav-collapse/nav-horizontal-collapse.component.ts index e24976bc..f0fe6903 100644 --- a/src/@fuse/components/navigation/horizontal/nav-collapse/nav-horizontal-collapse.component.ts +++ b/src/@fuse/components/navigation/horizontal/nav-collapse/nav-horizontal-collapse.component.ts @@ -1,8 +1,9 @@ -import { Component, HostBinding, HostListener, Input, OnDestroy } from '@angular/core'; -import { Subscription } from 'rxjs'; +import { Component, HostBinding, HostListener, Input, OnDestroy, OnInit } from '@angular/core'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; -import { fuseAnimations } from '../../../../animations/index'; -import { FuseConfigService } from '../../../../services/config.service'; +import { fuseAnimations } from '@fuse/animations'; +import { FuseConfigService } from '@fuse/services/config.service'; @Component({ selector : 'fuse-nav-horizontal-collapse', @@ -10,42 +11,76 @@ import { FuseConfigService } from '../../../../services/config.service'; styleUrls : ['./nav-horizontal-collapse.component.scss'], animations : fuseAnimations }) -export class FuseNavHorizontalCollapseComponent implements OnDestroy +export class FuseNavHorizontalCollapseComponent implements OnInit, OnDestroy { - onConfigChanged: Subscription; - fuseSettings: any; + fuseConfig: any; isOpen = false; - @HostBinding('class') classes = 'nav-item nav-collapse'; - @Input() item: any; + @HostBinding('class') + classes = 'nav-item nav-collapse'; + @Input() + item: any; + + // Private + private _unsubscribeAll: Subject; + + constructor( + private _fuseConfigService: FuseConfigService + ) + { + // Set the private defaults + this._unsubscribeAll = new Subject(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void + { + // Subscribe to config changes + this._fuseConfigService.config + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe( + (config) => { + this.fuseConfig = config; + } + ); + } + + /** + * On destroy + */ + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Open + */ @HostListener('mouseenter') - open() + open(): void { this.isOpen = true; } + /** + * Close + */ @HostListener('mouseleave') - close() + close(): void { this.isOpen = false; } - - constructor( - private fuseConfig: FuseConfigService - ) - { - this.onConfigChanged = - this.fuseConfig.onConfigChanged - .subscribe( - (newSettings) => { - this.fuseSettings = newSettings; - } - ); - } - - ngOnDestroy() - { - this.onConfigChanged.unsubscribe(); - } } diff --git a/src/@fuse/components/navigation/horizontal/nav-item/nav-horizontal-item.component.ts b/src/@fuse/components/navigation/horizontal/nav-item/nav-horizontal-item.component.ts index 8f9d0b25..58e3dab5 100644 --- a/src/@fuse/components/navigation/horizontal/nav-item/nav-horizontal-item.component.ts +++ b/src/@fuse/components/navigation/horizontal/nav-item/nav-horizontal-item.component.ts @@ -7,6 +7,17 @@ import { Component, HostBinding, Input } from '@angular/core'; }) export class FuseNavHorizontalItemComponent { - @HostBinding('class') classes = 'nav-item'; - @Input() item: any; + @HostBinding('class') + classes = 'nav-item'; + + @Input() + item: any; + + /** + * Constructor + */ + constructor() + { + + } } diff --git a/src/@fuse/components/navigation/navigation.component.ts b/src/@fuse/components/navigation/navigation.component.ts index 9a2e5a5c..82a2409c 100644 --- a/src/@fuse/components/navigation/navigation.component.ts +++ b/src/@fuse/components/navigation/navigation.component.ts @@ -8,9 +8,15 @@ import { Component, Input, ViewEncapsulation } from '@angular/core'; }) export class FuseNavigationComponent { - @Input() layout = 'vertical'; - @Input() navigation: any; + @Input() + layout = 'vertical'; + @Input() + navigation: any; + + /** + * Constructor + */ constructor() { diff --git a/src/@fuse/components/navigation/navigation.service.ts b/src/@fuse/components/navigation/navigation.service.ts index cbf2e11e..677c5ca3 100644 --- a/src/@fuse/components/navigation/navigation.service.ts +++ b/src/@fuse/components/navigation/navigation.service.ts @@ -9,16 +9,24 @@ export class FuseNavigationService onItemCollapsed: Subject = new Subject; onItemCollapseToggled: Subject = new Subject; + /** + * Constructor + */ constructor() { } + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + /** * Get flattened navigation array + * * @param navigation * @returns {any[]} */ - getFlatNavigation(navigation) + getFlatNavigation(navigation): any { for ( const navItem of navigation ) { diff --git a/src/@fuse/components/navigation/vertical/nav-collapse/nav-vertical-collapse.component.ts b/src/@fuse/components/navigation/vertical/nav-collapse/nav-vertical-collapse.component.ts index 65afb2c8..ad046c1f 100644 --- a/src/@fuse/components/navigation/vertical/nav-collapse/nav-vertical-collapse.component.ts +++ b/src/@fuse/components/navigation/vertical/nav-collapse/nav-vertical-collapse.component.ts @@ -1,7 +1,10 @@ -import { Component, HostBinding, Input, OnInit } from '@angular/core'; -import { FuseNavigationService } from '../../navigation.service'; +import { Component, HostBinding, Input, OnDestroy, OnInit } from '@angular/core'; import { NavigationEnd, Router } from '@angular/router'; -import { fuseAnimations } from '../../../../animations/index'; +import { Subject } from 'rxjs'; +import { filter, takeUntil } from 'rxjs/operators'; + +import { FuseNavigationService } from '../../navigation.service'; +import { fuseAnimations } from '@fuse/animations'; @Component({ selector : 'fuse-nav-vertical-collapse', @@ -9,38 +12,67 @@ import { fuseAnimations } from '../../../../animations/index'; styleUrls : ['./nav-vertical-collapse.component.scss'], animations : fuseAnimations }) -export class FuseNavVerticalCollapseComponent implements OnInit +export class FuseNavVerticalCollapseComponent implements OnInit, OnDestroy { - @Input() item: any; - @HostBinding('class') classes = 'nav-collapse nav-item'; - @HostBinding('class.open') public isOpen = false; + @Input() + item: any; + @HostBinding('class') + classes = 'nav-collapse nav-item'; + + @HostBinding('class.open') + public isOpen = false; + + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {FuseNavigationService} _fuseNavigationService + * @param {Router} _router + */ constructor( - private navigationService: FuseNavigationService, - private router: Router + private _fuseNavigationService: FuseNavigationService, + private _router: Router ) { - // Listen for route changes - router.events.subscribe( - (event) => { - if ( event instanceof NavigationEnd ) + // Set the private defaults + this._unsubscribeAll = new Subject(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void + { + // Listen for router events + this._router.events + .pipe( + filter(event => event instanceof NavigationEnd), + takeUntil(this._unsubscribeAll) + ) + .subscribe((event: NavigationEnd) => { + + // Check if the url can be found in + // one of the children of this item + if ( this.isUrlInChildren(this.item, event.urlAfterRedirects) ) { - // Check if the url can be found in - // one of the children of this item - if ( this.isUrlInChildren(this.item, event.urlAfterRedirects) ) - { - this.expand(); - } - else - { - this.collapse(); - } + this.expand(); } - } - ); + else + { + this.collapse(); + } + }); // Listen for collapsing of any navigation item - this.navigationService.onItemCollapsed + this._fuseNavigationService.onItemCollapsed + .pipe(takeUntil(this._unsubscribeAll)) .subscribe( (clickedItem) => { if ( clickedItem && clickedItem.children ) @@ -54,7 +86,7 @@ export class FuseNavVerticalCollapseComponent implements OnInit // Check if the url can be found in // one of the children of this item - if ( this.isUrlInChildren(this.item, this.router.url) ) + if ( this.isUrlInChildren(this.item, this._router.url) ) { return; } @@ -67,13 +99,10 @@ export class FuseNavVerticalCollapseComponent implements OnInit } } ); - } - ngOnInit() - { // Check if the url can be found in // one of the children of this item - if ( this.isUrlInChildren(this.item, this.router.url) ) + if ( this.isUrlInChildren(this.item, this._router.url) ) { this.expand(); } @@ -83,26 +112,40 @@ export class FuseNavVerticalCollapseComponent implements OnInit } } + /** + * On destroy + */ + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + /** * Toggle collapse * * @param ev */ - toggleOpen(ev) + toggleOpen(ev): void { ev.preventDefault(); this.isOpen = !this.isOpen; // Navigation collapse toggled... - this.navigationService.onItemCollapsed.next(this.item); - this.navigationService.onItemCollapseToggled.next(); + this._fuseNavigationService.onItemCollapsed.next(this.item); + this._fuseNavigationService.onItemCollapseToggled.next(); } /** * Expand the collapsable navigation */ - expand() + expand(): void { if ( this.isOpen ) { @@ -110,13 +153,13 @@ export class FuseNavVerticalCollapseComponent implements OnInit } this.isOpen = true; - this.navigationService.onItemCollapseToggled.next(); + this._fuseNavigationService.onItemCollapseToggled.next(); } /** * Collapse the collapsable navigation */ - collapse() + collapse(): void { if ( !this.isOpen ) { @@ -124,7 +167,7 @@ export class FuseNavVerticalCollapseComponent implements OnInit } this.isOpen = false; - this.navigationService.onItemCollapseToggled.next(); + this._fuseNavigationService.onItemCollapseToggled.next(); } /** @@ -133,9 +176,9 @@ export class FuseNavVerticalCollapseComponent implements OnInit * * @param parent * @param item - * @return {any} + * @returns {boolean} */ - isChildrenOf(parent, item) + isChildrenOf(parent, item): boolean { if ( !parent.children ) { @@ -162,9 +205,9 @@ export class FuseNavVerticalCollapseComponent implements OnInit * * @param parent * @param url - * @returns {any} + * @returns {boolean} */ - isUrlInChildren(parent, url) + isUrlInChildren(parent, url): boolean { if ( !parent.children ) { diff --git a/src/@fuse/components/navigation/vertical/nav-group/nav-vertical-group.component.ts b/src/@fuse/components/navigation/vertical/nav-group/nav-vertical-group.component.ts index 56151d6f..8ec510e2 100644 --- a/src/@fuse/components/navigation/vertical/nav-group/nav-vertical-group.component.ts +++ b/src/@fuse/components/navigation/vertical/nav-group/nav-vertical-group.component.ts @@ -7,9 +7,15 @@ import { Component, HostBinding, Input } from '@angular/core'; }) export class FuseNavVerticalGroupComponent { - @HostBinding('class') classes = 'nav-group nav-item'; - @Input() item: any; + @HostBinding('class') + classes = 'nav-group nav-item'; + @Input() + item: any; + + /** + * Constructor + */ constructor() { } diff --git a/src/@fuse/components/navigation/vertical/nav-item/nav-vertical-item.component.ts b/src/@fuse/components/navigation/vertical/nav-item/nav-vertical-item.component.ts index 071ed1ee..481628c0 100644 --- a/src/@fuse/components/navigation/vertical/nav-item/nav-vertical-item.component.ts +++ b/src/@fuse/components/navigation/vertical/nav-item/nav-vertical-item.component.ts @@ -7,9 +7,15 @@ import { Component, HostBinding, Input } from '@angular/core'; }) export class FuseNavVerticalItemComponent { - @HostBinding('class') classes = 'nav-item'; - @Input() item: any; + @HostBinding('class') + classes = 'nav-item'; + @Input() + item: any; + + /** + * Constructor + */ constructor() { } diff --git a/src/@fuse/components/search-bar/search-bar.component.ts b/src/@fuse/components/search-bar/search-bar.component.ts index 16fa6ed6..eb80bba9 100644 --- a/src/@fuse/components/search-bar/search-bar.component.ts +++ b/src/@fuse/components/search-bar/search-bar.component.ts @@ -1,5 +1,6 @@ -import { Component, EventEmitter, Output } from '@angular/core'; -import { Subscription } from 'rxjs'; +import { Component, EventEmitter, OnDestroy, OnInit, Output } from '@angular/core'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import { FuseConfigService } from '@fuse/services/config.service'; @@ -8,38 +9,89 @@ import { FuseConfigService } from '@fuse/services/config.service'; templateUrl: './search-bar.component.html', styleUrls : ['./search-bar.component.scss'] }) -export class FuseSearchBarComponent +export class FuseSearchBarComponent implements OnInit, OnDestroy { collapsed: boolean; + fuseConfig: any; toolbarColor: string; - @Output() onInput: EventEmitter = new EventEmitter(); - onConfigChanged: Subscription; + @Output() + onInput: EventEmitter = new EventEmitter(); + + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {FuseConfigService} _fuseConfigService + */ constructor( - private fuseConfig: FuseConfigService + private _fuseConfigService: FuseConfigService ) { + // Set the defaults this.collapsed = true; - this.onConfigChanged = - this.fuseConfig.onConfigChanged - .subscribe( - (newSettings) => { - this.toolbarColor = newSettings.colorClasses.toolbar; - } - ); + + // Set the private defaults + this._unsubscribeAll = new Subject(); } - collapse() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void + { + // Subscribe to config changes + this._fuseConfigService.config + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe( + (config) => { + this.toolbarColor = config.colorClasses.toolbar; + } + ); + } + + /** + * On destroy + */ + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Collapse + */ + collapse(): void { this.collapsed = true; } - expand() + /** + * Expand + */ + expand(): void { this.collapsed = false; } - search(event) + /** + * Search + * + * @param event + */ + search(event): void { const value = event.target.value; diff --git a/src/@fuse/components/shortcuts/shortcuts.component.ts b/src/@fuse/components/shortcuts/shortcuts.component.ts index 0e33d8ef..42db3bcb 100644 --- a/src/@fuse/components/shortcuts/shortcuts.component.ts +++ b/src/@fuse/components/shortcuts/shortcuts.component.ts @@ -1,7 +1,7 @@ import { Component, ElementRef, Input, OnDestroy, OnInit, Renderer2, ViewChild } from '@angular/core'; import { ObservableMedia } from '@angular/flex-layout'; - -import { Subscription } from 'rxjs'; +import { Subject, Subscription } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import { CookieService } from 'ngx-cookie-service'; import { FuseMatchMediaService } from '@fuse/services/match-media.service'; @@ -21,42 +21,67 @@ export class FuseShortcutsComponent implements OnInit, OnDestroy searching = false; mobileShortcutsPanelActive = false; toolbarColor: string; - matchMediaSubscription: Subscription; - onConfigChanged: Subscription; - @Input() navigation: any; + @Input() + navigation: any; - @ViewChild('searchInput') searchInputField; - @ViewChild('shortcuts') shortcutsEl: ElementRef; + @ViewChild('searchInput') + searchInputField; + @ViewChild('shortcuts') + shortcutsEl: ElementRef; + + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {Renderer2} _renderer + * @param {CookieService} _cookieService + * @param {FuseMatchMediaService} _fuseMatchMediaService + * @param {FuseNavigationService} _fuseNavigationService + * @param {FuseConfigService} _fuseConfigService + * @param {ObservableMedia} _observableMedia + */ constructor( - private renderer: Renderer2, - private observableMedia: ObservableMedia, - private fuseMatchMedia: FuseMatchMediaService, - private fuseNavigationService: FuseNavigationService, - private fuseConfig: FuseConfigService, - private cookieService: CookieService + private _renderer: Renderer2, + private _cookieService: CookieService, + private _fuseMatchMediaService: FuseMatchMediaService, + private _fuseNavigationService: FuseNavigationService, + private _fuseConfigService: FuseConfigService, + private _observableMedia: ObservableMedia ) { - this.onConfigChanged = - this.fuseConfig.onConfigChanged - .subscribe( - (newSettings) => { - this.toolbarColor = newSettings.colorClasses.toolbar; - } - ); + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() - { - // Get the navigation items and flatten them - this.filteredNavigationItems = this.navigationItems = this.fuseNavigationService.getFlatNavigation(this.navigation); + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- - const cookieExists = this.cookieService.check('FUSE2.shortcuts'); + /** + * On init + */ + ngOnInit(): void + { + // Subscribe to config changes + this._fuseConfigService.config + .subscribe( + (config) => { + this.toolbarColor = config.colorClasses.toolbar; + } + ); + + // Get the navigation items and flatten them + this.filteredNavigationItems = this.navigationItems = this._fuseNavigationService.getFlatNavigation(this.navigation); + + const cookieExists = this._cookieService.check('FUSE2.shortcuts'); if ( cookieExists ) { - this.shortcutItems = JSON.parse(this.cookieService.get('FUSE2.shortcuts')); + this.shortcutItems = JSON.parse(this._cookieService.get('FUSE2.shortcuts')); } else { @@ -89,21 +114,36 @@ export class FuseShortcutsComponent implements OnInit, OnDestroy ]; } - this.matchMediaSubscription = - this.fuseMatchMedia.onMediaChange.subscribe(() => { - if ( this.observableMedia.isActive('gt-sm') ) + this._fuseMatchMediaService.onMediaChange + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { + if ( this._observableMedia.isActive('gt-sm') ) { this.hideMobileShortcutsPanel(); } }); } - ngOnDestroy() + /** + * On destroy + */ + ngOnDestroy(): void { - this.matchMediaSubscription.unsubscribe(); + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); } - search(event) + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Search + * + * @param event + */ + search(event): void { const value = event.target.value.toLowerCase(); @@ -122,7 +162,13 @@ export class FuseShortcutsComponent implements OnInit, OnDestroy }); } - toggleShortcut(event, itemToToggle) + /** + * Toggle shortcut + * + * @param event + * @param itemToToggle + */ + toggleShortcut(event, itemToToggle): void { event.stopPropagation(); @@ -133,7 +179,7 @@ export class FuseShortcutsComponent implements OnInit, OnDestroy this.shortcutItems.splice(i, 1); // Save to the cookies - this.cookieService.set('FUSE2.shortcuts', JSON.stringify(this.shortcutItems)); + this._cookieService.set('FUSE2.shortcuts', JSON.stringify(this.shortcutItems)); return; } @@ -142,32 +188,47 @@ export class FuseShortcutsComponent implements OnInit, OnDestroy this.shortcutItems.push(itemToToggle); // Save to the cookies - this.cookieService.set('FUSE2.shortcuts', JSON.stringify(this.shortcutItems)); + this._cookieService.set('FUSE2.shortcuts', JSON.stringify(this.shortcutItems)); } - isInShortcuts(navigationItem) + /** + * Is in shortcuts? + * + * @param navigationItem + * @returns {any} + */ + isInShortcuts(navigationItem): any { return this.shortcutItems.find(item => { return item.url === navigationItem.url; }); } - onMenuOpen() + /** + * On menu open + */ + onMenuOpen(): void { setTimeout(() => { this.searchInputField.nativeElement.focus(); }); } - showMobileShortcutsPanel() + /** + * Show mobile shortcuts + */ + showMobileShortcutsPanel(): void { this.mobileShortcutsPanelActive = true; - this.renderer.addClass(this.shortcutsEl.nativeElement, 'show-mobile-panel'); + this._renderer.addClass(this.shortcutsEl.nativeElement, 'show-mobile-panel'); } - hideMobileShortcutsPanel() + /** + * Hide mobile shortcuts + */ + hideMobileShortcutsPanel(): void { this.mobileShortcutsPanelActive = false; - this.renderer.removeClass(this.shortcutsEl.nativeElement, 'show-mobile-panel'); + this._renderer.removeClass(this.shortcutsEl.nativeElement, 'show-mobile-panel'); } } diff --git a/src/@fuse/components/sidebar/sidebar.component.ts b/src/@fuse/components/sidebar/sidebar.component.ts index 16c90880..5462686d 100644 --- a/src/@fuse/components/sidebar/sidebar.component.ts +++ b/src/@fuse/components/sidebar/sidebar.component.ts @@ -1,11 +1,12 @@ import { Component, ElementRef, HostBinding, HostListener, Input, OnDestroy, OnInit, Renderer2, ViewEncapsulation } from '@angular/core'; import { animate, AnimationBuilder, AnimationPlayer, style } from '@angular/animations'; import { ObservableMedia } from '@angular/flex-layout'; -import { Subscription } from 'rxjs'; +import { Subject, Subscription } from 'rxjs'; import { FuseSidebarService } from './sidebar.service'; import { FuseMatchMediaService } from '@fuse/services/match-media.service'; import { FuseConfigService } from '@fuse/services/config.service'; +import { takeUntil } from 'rxjs/internal/operators'; @Component({ selector : 'fuse-sidebar', @@ -35,6 +36,52 @@ export class FuseSidebarComponent implements OnInit, OnDestroy @HostBinding('class.locked-open') isLockedOpen: boolean; + // Folded unfolded + @HostBinding('class.unfolded') + unfolded: boolean; + + // Private + private _folded: boolean; + private _fuseConfig: any; + private _wasActive: boolean; + private _backdrop: HTMLElement | null = null; + private _player: AnimationPlayer; + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {AnimationBuilder} _animationBuilder + * @param {ElementRef} _elementRef + * @param {FuseConfigService} _fuseConfigService + * @param {FuseMatchMediaService} _fuseMatchMediaService + * @param {FuseSidebarService} _fuseSidebarService + * @param {ObservableMedia} _observableMedia + * @param {Renderer2} _renderer + */ + constructor( + private _animationBuilder: AnimationBuilder, + private _elementRef: ElementRef, + private _fuseConfigService: FuseConfigService, + private _fuseMatchMediaService: FuseMatchMediaService, + private _fuseSidebarService: FuseSidebarService, + private _observableMedia: ObservableMedia, + private _renderer: Renderer2 + ) + { + // Set the defaults + this.opened = false; + this.folded = false; + this.align = 'left'; + + // Set the private defaults + this._unsubscribeAll = new Subject(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Accessors + // ----------------------------------------------------------------------------------------------------- + // Folded @HostBinding('class.folded') @Input() @@ -59,12 +106,12 @@ export class FuseSidebarComponent implements OnInit, OnDestroy // Get the sibling and set the style rule if ( this.align === 'left' ) { - sibling = this.elementRef.nativeElement.nextElementSibling; + sibling = this._elementRef.nativeElement.nextElementSibling; styleRule = 'marginLeft'; } else { - sibling = this.elementRef.nativeElement.previousElementSibling; + sibling = this._elementRef.nativeElement.previousElementSibling; styleRule = 'marginRight'; } @@ -78,13 +125,13 @@ export class FuseSidebarComponent implements OnInit, OnDestroy if ( value ) { // Set the style - this.renderer.setStyle(sibling, styleRule, styleValue); + this._renderer.setStyle(sibling, styleRule, styleValue); } // If unfolded... else { // Remove the style - this.renderer.removeStyle(sibling, styleRule); + this._renderer.removeStyle(sibling, styleRule); } } @@ -93,51 +140,24 @@ export class FuseSidebarComponent implements OnInit, OnDestroy return this._folded; } - // Folded unfolded - @HostBinding('class.unfolded') - unfolded: boolean; - - // Private - private _folded: boolean; - private _wasActive: boolean; - private _backdrop: HTMLElement | null = null; - private _player: AnimationPlayer; - private _onMediaChangeSubscription: Subscription; - - /** - * Constructor - * - * @param {Renderer2} renderer - * @param {ElementRef} elementRef - * @param {AnimationBuilder} animationBuilder - * @param {ObservableMedia} observableMedia - * @param {FuseConfigService} fuseConfigService - * @param {FuseSidebarService} fuseSidebarService - * @param {FuseMatchMediaService} fuseMatchMediaService - */ - constructor( - private renderer: Renderer2, - private elementRef: ElementRef, - private animationBuilder: AnimationBuilder, - private observableMedia: ObservableMedia, - private fuseConfigService: FuseConfigService, - private fuseSidebarService: FuseSidebarService, - private fuseMatchMediaService: FuseMatchMediaService - ) - { - // Set the defaults - this.opened = false; - this.folded = false; - this.align = 'left'; - } + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- /** * On init */ ngOnInit(): void { + // Subscribe to config changes + this._fuseConfigService.config + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe((config) => { + this._fuseConfig = config; + }); + // Register the sidebar - this.fuseSidebarService.register(this.name, this); + this._fuseSidebarService.register(this.name, this); // Setup alignment this._setupAlignment(); @@ -158,12 +178,17 @@ export class FuseSidebarComponent implements OnInit, OnDestroy } // Unregister the sidebar - this.fuseSidebarService.unregister(this.name); + this._fuseSidebarService.unregister(this.name); - // Unsubscribe from the media watcher subscription - this._onMediaChangeSubscription.unsubscribe(); + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); } + // ----------------------------------------------------------------------------------------------------- + // @ Private methods + // ----------------------------------------------------------------------------------------------------- + /** * Set the sidebar alignment * @@ -175,11 +200,11 @@ export class FuseSidebarComponent implements OnInit, OnDestroy // element depending on the align attribute if ( this.align === 'right' ) { - this.renderer.addClass(this.elementRef.nativeElement, 'right-aligned'); + this._renderer.addClass(this._elementRef.nativeElement, 'right-aligned'); } else { - this.renderer.addClass(this.elementRef.nativeElement, 'left-aligned'); + this._renderer.addClass(this._elementRef.nativeElement, 'left-aligned'); } } @@ -200,12 +225,12 @@ export class FuseSidebarComponent implements OnInit, OnDestroy this._wasActive = false; // Act on every media change - this._onMediaChangeSubscription = - - this.fuseMatchMediaService.onMediaChange.subscribe(() => { + this._fuseMatchMediaService.onMediaChange + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { // Get the active status - const isActive = this.observableMedia.isActive(this.lockedOpen); + const isActive = this._observableMedia.isActive(this.lockedOpen); // If the both status are the same, don't act if ( this._wasActive === isActive ) @@ -224,7 +249,7 @@ export class FuseSidebarComponent implements OnInit, OnDestroy // Read the folded setting from the config // and fold the sidebar if it's true - if ( this.fuseConfigService.config.layout.navigationFolded ) + if ( this._fuseConfig.layout.navigation.folded ) { this.fold(); } @@ -250,6 +275,10 @@ export class FuseSidebarComponent implements OnInit, OnDestroy }); } + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + /** * Open the sidebar */ @@ -382,17 +411,17 @@ export class FuseSidebarComponent implements OnInit, OnDestroy showBackdrop(): void { // Create the backdrop element - this._backdrop = this.renderer.createElement('div'); + this._backdrop = this._renderer.createElement('div'); // Add a class to the backdrop element this._backdrop.classList.add('fuse-sidebar-overlay'); // Append the backdrop to the parent of the sidebar - this.renderer.appendChild(this.elementRef.nativeElement.parentElement, this._backdrop); + this._renderer.appendChild(this._elementRef.nativeElement.parentElement, this._backdrop); // Create the enter animation and attach it to the player this._player = - this.animationBuilder + this._animationBuilder .build([ animate('300ms ease', style({opacity: 1})) ]).create(this._backdrop); @@ -419,7 +448,7 @@ export class FuseSidebarComponent implements OnInit, OnDestroy // Create the leave animation and attach it to the player this._player = - this.animationBuilder + this._animationBuilder .build([ animate('300ms ease', style({opacity: 0})) ]).create(this._backdrop); diff --git a/src/@fuse/components/theme-options/theme-options.component.html b/src/@fuse/components/theme-options/theme-options.component.html index 57d63d2d..1e0f8ac7 100644 --- a/src/@fuse/components/theme-options/theme-options.component.html +++ b/src/@fuse/components/theme-options/theme-options.component.html @@ -13,7 +13,7 @@

Layout:

- Vertical Horizontal @@ -21,7 +21,7 @@

Navigation:

- Top Left @@ -30,13 +30,13 @@

Navigation Fold (for vertical navigation):

- + Folded

Toolbar:

- Below Above @@ -44,7 +44,7 @@

Footer:

- Below Above @@ -52,7 +52,7 @@

Layout Mode:

- Boxed Fullwidth @@ -65,20 +65,20 @@

Toolbar Color

- +

Navigation Bar Color

- +

Footer Color

- +
@@ -87,7 +87,7 @@

Router Animation:

- + None diff --git a/src/@fuse/components/theme-options/theme-options.component.ts b/src/@fuse/components/theme-options/theme-options.component.ts index 1e817c91..8eb0a39b 100644 --- a/src/@fuse/components/theme-options/theme-options.component.ts +++ b/src/@fuse/components/theme-options/theme-options.component.ts @@ -1,6 +1,7 @@ import { Component, ElementRef, HostBinding, Input, OnDestroy, OnInit, Renderer2, ViewChild } from '@angular/core'; import { style, animate, AnimationBuilder, AnimationPlayer } from '@angular/animations'; -import { Subscription } from 'rxjs'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import { fuseAnimations } from '@fuse/animations'; import { FuseConfigService } from '@fuse/services/config.service'; @@ -14,39 +15,59 @@ import { FuseNavigationService } from '@fuse/components/navigation/navigation.se }) export class FuseThemeOptionsComponent implements OnInit, OnDestroy { - @Input() navigation; - @ViewChild('openButton') openButton; - @ViewChild('panel') panel; - @ViewChild('overlay') overlay: ElementRef; + @Input() + navigation; - public player: AnimationPlayer; - config: any; + @ViewChild('openButton') + openButton; - onConfigChanged: Subscription; + @ViewChild('panel') + panel; + + @ViewChild('overlay') + overlay: ElementRef; + + player: AnimationPlayer; + fuseConfig: any; @HostBinding('class.bar-closed') barClosed: boolean; + // Private + private _unsubscribeAll: Subject; + constructor( - private animationBuilder: AnimationBuilder, - private fuseConfig: FuseConfigService, - private navigationService: FuseNavigationService, - private renderer: Renderer2 + private _animationBuilder: AnimationBuilder, + private _fuseConfigService: FuseConfigService, + private _fuseNavigationService: FuseNavigationService, + private _renderer: Renderer2 ) { + // Set the defaults this.barClosed = true; - this.onConfigChanged = - this.fuseConfig.onConfigChanged - .subscribe( - (newConfig) => { - this.config = newConfig; - } - ); + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { - this.renderer.listen(this.overlay.nativeElement, 'click', () => { + // Subscribe to the config changes + this._fuseConfigService.config + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe((config) => { + this.fuseConfig = config; + } + ); + + // Listen for the overlay's click event + this._renderer.listen(this.overlay.nativeElement, 'click', () => { this.closeBar(); }); @@ -72,20 +93,52 @@ export class FuseThemeOptionsComponent implements OnInit, OnDestroy }); } - ngOnDestroy() + /** + * On destroy + */ + ngOnDestroy(): void { - this.onConfigChanged.unsubscribe(); + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); } - onSettingsChange() + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * On config change + */ + onConfigChange(): void { - this.fuseConfig.setConfig(this.config); + this._fuseConfigService.config = this.fuseConfig; } - closeBar() + /** + * Open the bar + */ + openBar(): void + { + this.barClosed = false; + + this.player = + this._animationBuilder + .build([ + style({transform: 'translate3d(100%,0,0)'}), + animate('400ms ease', style({transform: 'translate3d(0,0,0)'})) + ]).create(this.panel.nativeElement); + + this.player.play(); + } + + /** + * Close the bar + */ + closeBar(): void { this.player = - this.animationBuilder + this._animationBuilder .build([ style({transform: 'translate3d(0,0,0)'}), animate('400ms ease', style({transform: 'translate3d(100%,0,0)'})) @@ -97,18 +150,4 @@ export class FuseThemeOptionsComponent implements OnInit, OnDestroy this.barClosed = true; }); } - - openBar() - { - this.barClosed = false; - - this.player = - this.animationBuilder - .build([ - style({transform: 'translate3d(100%,0,0)'}), - animate('400ms ease', style({transform: 'translate3d(0,0,0)'})) - ]).create(this.panel.nativeElement); - - this.player.play(); - } } diff --git a/src/@fuse/components/widget/widget-toggle.directive.ts b/src/@fuse/components/widget/widget-toggle.directive.ts index 0c278925..7b5f81c8 100644 --- a/src/@fuse/components/widget/widget-toggle.directive.ts +++ b/src/@fuse/components/widget/widget-toggle.directive.ts @@ -5,7 +5,14 @@ import { Directive, ElementRef } from '@angular/core'; }) export class FuseWidgetToggleDirective { - constructor(public el: ElementRef) + /** + * Constructor + * + * @param {ElementRef} elementRef + */ + constructor( + public elementRef: ElementRef + ) { } } diff --git a/src/@fuse/components/widget/widget.component.ts b/src/@fuse/components/widget/widget.component.ts index 46ecdbb2..7246fc85 100644 --- a/src/@fuse/components/widget/widget.component.ts +++ b/src/@fuse/components/widget/widget.component.ts @@ -10,19 +10,38 @@ import { FuseWidgetToggleDirective } from './widget-toggle.directive'; export class FuseWidgetComponent implements AfterContentInit { - @HostBinding('class.flipped') flipped = false; - @ContentChildren(FuseWidgetToggleDirective, {descendants: true}) toggleButtons: QueryList; + @HostBinding('class.flipped') + flipped = false; - constructor(private el: ElementRef, private renderer: Renderer2) + @ContentChildren(FuseWidgetToggleDirective, {descendants: true}) + toggleButtons: QueryList; + + /** + * Constructor + * + * @param {ElementRef} _elementRef + * @param {Renderer2} _renderer + */ + constructor( + private _elementRef: ElementRef, + private _renderer: Renderer2 + ) { } - ngAfterContentInit() - { - setTimeout(() => { + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + /** + * After content init + */ + ngAfterContentInit(): void + { + // Listen for the flip button click + setTimeout(() => { this.toggleButtons.forEach(flipButton => { - this.renderer.listen(flipButton.el.nativeElement, 'click', (event) => { + this._renderer.listen(flipButton.elementRef.nativeElement, 'click', (event) => { event.preventDefault(); event.stopPropagation(); this.toggle(); @@ -31,7 +50,14 @@ export class FuseWidgetComponent implements AfterContentInit }); } - toggle() + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Toggle the flipped status + */ + toggle(): void { this.flipped = !this.flipped; } diff --git a/src/@fuse/directives/fuse-if-on-dom/fuse-if-on-dom.directive.ts b/src/@fuse/directives/fuse-if-on-dom/fuse-if-on-dom.directive.ts index 403bce13..cfe1cfb3 100644 --- a/src/@fuse/directives/fuse-if-on-dom/fuse-if-on-dom.directive.ts +++ b/src/@fuse/directives/fuse-if-on-dom/fuse-if-on-dom.directive.ts @@ -7,26 +7,40 @@ export class FuseIfOnDomDirective implements AfterContentChecked { isCreated = false; + /** + * Constructor + * + * @param {ElementRef} _elementRef + * @param {TemplateRef} _templateRef + * @param {ViewContainerRef} _viewContainerRef + */ constructor( - private templateRef: TemplateRef, - private viewContainer: ViewContainerRef, - private element: ElementRef + private _elementRef: ElementRef, + private _templateRef: TemplateRef, + private _viewContainerRef: ViewContainerRef ) { } - ngAfterContentChecked() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * After content checked + */ + ngAfterContentChecked(): void { - if ( document.body.contains(this.element.nativeElement) && !this.isCreated ) + if ( document.body.contains(this._elementRef.nativeElement) && !this.isCreated ) { setTimeout(() => { - this.viewContainer.createEmbeddedView(this.templateRef); + this._viewContainerRef.createEmbeddedView(this._templateRef); }, 300); this.isCreated = true; } - else if ( this.isCreated && !document.body.contains(this.element.nativeElement) ) + else if ( this.isCreated && !document.body.contains(this._elementRef.nativeElement) ) { - this.viewContainer.clear(); + this._viewContainerRef.clear(); this.isCreated = false; } } diff --git a/src/@fuse/directives/fuse-mat-sidenav/fuse-mat-sidenav.directive.ts b/src/@fuse/directives/fuse-mat-sidenav/fuse-mat-sidenav.directive.ts index 52efd771..52570a7b 100644 --- a/src/@fuse/directives/fuse-mat-sidenav/fuse-mat-sidenav.directive.ts +++ b/src/@fuse/directives/fuse-mat-sidenav/fuse-mat-sidenav.directive.ts @@ -1,7 +1,8 @@ import { Directive, Input, OnInit, HostListener, OnDestroy, HostBinding } from '@angular/core'; import { MatSidenav } from '@angular/material'; import { ObservableMedia } from '@angular/flex-layout'; -import { Subscription } from 'rxjs'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import { FuseMatchMediaService } from '@fuse/services/match-media.service'; import { FuseMatSidenavHelperService } from '@fuse/directives/fuse-mat-sidenav/fuse-mat-sidenav.service'; @@ -11,56 +12,88 @@ import { FuseMatSidenavHelperService } from '@fuse/directives/fuse-mat-sidenav/f }) export class FuseMatSidenavHelperDirective implements OnInit, OnDestroy { - matchMediaSubscription: Subscription; - @HostBinding('class.mat-is-locked-open') isLockedOpen = true; - @Input('fuseMatSidenavHelper') id: string; - @Input('mat-is-locked-open') matIsLockedOpenBreakpoint: string; + @HostBinding('class.mat-is-locked-open') + isLockedOpen = true; + @Input('fuseMatSidenavHelper') + id: string; + + @Input('mat-is-locked-open') + matIsLockedOpenBreakpoint: string; + + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {FuseMatchMediaService} _fuseMatchMediaService + * @param {FuseMatSidenavHelperService} _fuseMatSidenavHelperService + * @param {MatSidenav} _matSidenav + * @param {ObservableMedia} _observableMedia + */ constructor( - private fuseMatSidenavService: FuseMatSidenavHelperService, - private fuseMatchMedia: FuseMatchMediaService, - private observableMedia: ObservableMedia, - private matSidenav: MatSidenav + private _fuseMatchMediaService: FuseMatchMediaService, + private _fuseMatSidenavHelperService: FuseMatSidenavHelperService, + private _matSidenav: MatSidenav, + private _observableMedia: ObservableMedia ) { + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() - { - this.fuseMatSidenavService.setSidenav(this.id, this.matSidenav); + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- - if ( this.observableMedia.isActive(this.matIsLockedOpenBreakpoint) ) + /** + * On init + */ + ngOnInit(): void + { + // Register the sidenav to the service + this._fuseMatSidenavHelperService.setSidenav(this.id, this._matSidenav); + + if ( this._observableMedia.isActive(this.matIsLockedOpenBreakpoint) ) { this.isLockedOpen = true; - this.matSidenav.mode = 'side'; - this.matSidenav.toggle(true); + this._matSidenav.mode = 'side'; + this._matSidenav.toggle(true); } else { this.isLockedOpen = false; - this.matSidenav.mode = 'over'; - this.matSidenav.toggle(false); + this._matSidenav.mode = 'over'; + this._matSidenav.toggle(false); } - this.matchMediaSubscription = this.fuseMatchMedia.onMediaChange.subscribe(() => { - if ( this.observableMedia.isActive(this.matIsLockedOpenBreakpoint) ) - { - this.isLockedOpen = true; - this.matSidenav.mode = 'side'; - this.matSidenav.toggle(true); - } - else - { - this.isLockedOpen = false; - this.matSidenav.mode = 'over'; - this.matSidenav.toggle(false); - } - }); + this._fuseMatchMediaService.onMediaChange + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { + if ( this._observableMedia.isActive(this.matIsLockedOpenBreakpoint) ) + { + this.isLockedOpen = true; + this._matSidenav.mode = 'side'; + this._matSidenav.toggle(true); + } + else + { + this.isLockedOpen = false; + this._matSidenav.mode = 'over'; + this._matSidenav.toggle(false); + } + }); } - ngOnDestroy() + /** + * On destroy + */ + ngOnDestroy(): void { - this.matchMediaSubscription.unsubscribe(); + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); } } @@ -69,15 +102,29 @@ export class FuseMatSidenavHelperDirective implements OnInit, OnDestroy }) export class FuseMatSidenavTogglerDirective { - @Input('fuseMatSidenavToggler') id; + @Input('fuseMatSidenavToggler') + id; - constructor(private fuseMatSidenavService: FuseMatSidenavHelperService) + /** + * Constructor + * + * @param {FuseMatSidenavHelperService} _fuseMatSidenavHelperService + */ + constructor( + private _fuseMatSidenavHelperService: FuseMatSidenavHelperService) { } + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * On click + */ @HostListener('click') onClick() { - this.fuseMatSidenavService.getSidenav(this.id).toggle(); + this._fuseMatSidenavHelperService.getSidenav(this.id).toggle(); } } diff --git a/src/@fuse/directives/fuse-mat-sidenav/fuse-mat-sidenav.service.ts b/src/@fuse/directives/fuse-mat-sidenav/fuse-mat-sidenav.service.ts index 748d9480..893c7fd4 100644 --- a/src/@fuse/directives/fuse-mat-sidenav/fuse-mat-sidenav.service.ts +++ b/src/@fuse/directives/fuse-mat-sidenav/fuse-mat-sidenav.service.ts @@ -6,17 +6,36 @@ export class FuseMatSidenavHelperService { sidenavInstances: MatSidenav[]; + /** + * Constructor + */ constructor() { this.sidenavInstances = []; } - setSidenav(id, instance) + // ----------------------------------------------------------------------------------------------------- + // @ Accessors + // ----------------------------------------------------------------------------------------------------- + + /** + * Set sidenav + * + * @param id + * @param instance + */ + setSidenav(id, instance): void { this.sidenavInstances[id] = instance; } - getSidenav(id) + /** + * Get sidenav + * + * @param id + * @returns {any} + */ + getSidenav(id): any { return this.sidenavInstances[id]; } diff --git a/src/@fuse/directives/fuse-perfect-scrollbar/fuse-perfect-scrollbar.directive.ts b/src/@fuse/directives/fuse-perfect-scrollbar/fuse-perfect-scrollbar.directive.ts index 89c3dea2..9e4a7c9a 100644 --- a/src/@fuse/directives/fuse-perfect-scrollbar/fuse-perfect-scrollbar.directive.ts +++ b/src/@fuse/directives/fuse-perfect-scrollbar/fuse-perfect-scrollbar.directive.ts @@ -1,6 +1,7 @@ import { AfterViewInit, Directive, ElementRef, HostListener, OnDestroy, OnInit } from '@angular/core'; import { Platform } from '@angular/cdk/platform'; -import { Subscription } from 'rxjs'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import PerfectScrollbar from 'perfect-scrollbar'; @@ -11,36 +12,58 @@ import { FuseConfigService } from '@fuse/services/config.service'; }) export class FusePerfectScrollbarDirective implements OnInit, AfterViewInit, OnDestroy { - onConfigChanged: Subscription; isDisableCustomScrollbars = false; isMobile = false; isInitialized = true; ps: PerfectScrollbar; + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {ElementRef} elementRef + * @param {FuseConfigService} _fuseConfigService + * @param {Platform} _platform + */ constructor( - public element: ElementRef, - private fuseConfig: FuseConfigService, - private platform: Platform + public elementRef: ElementRef, + private _fuseConfigService: FuseConfigService, + private _platform: Platform ) { + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { - this.onConfigChanged = - this.fuseConfig.onConfigChanged.subscribe( + this._fuseConfigService.config + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe( (settings) => { this.isDisableCustomScrollbars = !settings.customScrollbars; } ); - if ( this.platform.ANDROID || this.platform.IOS ) + if ( this._platform.ANDROID || this._platform.IOS ) { this.isMobile = true; } } - ngAfterViewInit() + /** + * After view init + */ + ngAfterViewInit(): void { if ( this.isMobile || this.isDisableCustomScrollbars ) { @@ -49,24 +72,38 @@ export class FusePerfectScrollbarDirective implements OnInit, AfterViewInit, OnD } // Initialize the perfect-scrollbar - this.ps = new PerfectScrollbar(this.element.nativeElement, { + this.ps = new PerfectScrollbar(this.elementRef.nativeElement, { wheelPropagation: true }); } - ngOnDestroy() + /** + * On destroy + */ + ngOnDestroy(): void { if ( !this.isInitialized || !this.ps ) { return; } - this.onConfigChanged.unsubscribe(); + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); // Destroy the perfect-scrollbar this.ps.destroy(); } + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Document click + * + * @param {Event} event + */ @HostListener('document:click', ['$event']) documentClick(event: Event): void { @@ -82,7 +119,10 @@ export class FusePerfectScrollbarDirective implements OnInit, AfterViewInit, OnD this.ps.update(); } - update() + /** + * Update the scrollbar + */ + update(): void { if ( !this.isInitialized ) { @@ -93,62 +133,108 @@ export class FusePerfectScrollbarDirective implements OnInit, AfterViewInit, OnD this.ps.update(); } - destroy() + /** + * Destroy the scrollbar + */ + destroy(): void { this.ngOnDestroy(); } - scrollToX(x: number, speed?: number) + /** + * Scroll to X + * + * @param {number} x + * @param {number} speed + */ + scrollToX(x: number, speed?: number): void { this.animateScrolling('scrollLeft', x, speed); } - scrollToY(y: number, speed?: number) + /** + * Scroll to Y + * + * @param {number} y + * @param {number} speed + */ + scrollToY(y: number, speed?: number): void { this.animateScrolling('scrollTop', y, speed); } - scrollToTop(offset?: number, speed?: number) + /** + * Scroll to top + * + * @param {number} offset + * @param {number} speed + */ + scrollToTop(offset?: number, speed?: number): void { this.animateScrolling('scrollTop', (offset || 0), speed); } - scrollToLeft(offset?: number, speed?: number) + /** + * Scroll to left + * + * @param {number} offset + * @param {number} speed + */ + scrollToLeft(offset?: number, speed?: number): void { this.animateScrolling('scrollLeft', (offset || 0), speed); } - scrollToRight(offset?: number, speed?: number) + /** + * Scroll to right + * + * @param {number} offset + * @param {number} speed + */ + scrollToRight(offset?: number, speed?: number): void { - const width = this.element.nativeElement.scrollWidth; + const width = this.elementRef.nativeElement.scrollWidth; this.animateScrolling('scrollLeft', width - (offset || 0), speed); } - scrollToBottom(offset?: number, speed?: number) + /** + * Scroll to bottom + * + * @param {number} offset + * @param {number} speed + */ + scrollToBottom(offset?: number, speed?: number): void { - const height = this.element.nativeElement.scrollHeight; + const height = this.elementRef.nativeElement.scrollHeight; this.animateScrolling('scrollTop', height - (offset || 0), speed); } - animateScrolling(target: string, value: number, speed?: number) + /** + * Animate scrolling + * + * @param {string} target + * @param {number} value + * @param {number} speed + */ + animateScrolling(target: string, value: number, speed?: number): void { if ( !speed ) { - this.element.nativeElement[target] = value; + this.elementRef.nativeElement[target] = value; // PS has weird event sending order, this is a workaround for that this.update(); this.update(); } - else if ( value !== this.element.nativeElement[target] ) + else if ( value !== this.elementRef.nativeElement[target] ) { let newValue = 0; let scrollCount = 0; let oldTimestamp = performance.now(); - let oldValue = this.element.nativeElement[target]; + let oldValue = this.elementRef.nativeElement[target]; const cosParameter = (oldValue - value) / 2; @@ -158,11 +244,11 @@ export class FusePerfectScrollbarDirective implements OnInit, AfterViewInit, OnD newValue = Math.round(value + cosParameter + cosParameter * Math.cos(scrollCount)); // Only continue animation if scroll position has not changed - if ( this.element.nativeElement[target] === oldValue ) + if ( this.elementRef.nativeElement[target] === oldValue ) { if ( scrollCount >= Math.PI ) { - this.element.nativeElement[target] = value; + this.elementRef.nativeElement[target] = value; // PS has weird event sending order, this is a workaround for that this.update(); @@ -171,7 +257,7 @@ export class FusePerfectScrollbarDirective implements OnInit, AfterViewInit, OnD } else { - this.element.nativeElement[target] = oldValue = newValue; + this.elementRef.nativeElement[target] = oldValue = newValue; oldTimestamp = newTimestamp; diff --git a/src/@fuse/pipes/camelCaseToDash.pipe.ts b/src/@fuse/pipes/camelCaseToDash.pipe.ts index edac85b0..1b184300 100644 --- a/src/@fuse/pipes/camelCaseToDash.pipe.ts +++ b/src/@fuse/pipes/camelCaseToDash.pipe.ts @@ -3,7 +3,14 @@ import { Pipe, PipeTransform } from '@angular/core'; @Pipe({name: 'camelCaseToDash'}) export class CamelCaseToDashPipe implements PipeTransform { - transform(value: string, args: any[] = []) + /** + * Transform + * + * @param {string} value + * @param {any[]} args + * @returns {string} + */ + transform(value: string, args: any[] = []): string { return value ? String(value).replace(/([A-Z])/g, (g) => `-${g[0].toLowerCase()}`) : ''; } diff --git a/src/@fuse/pipes/filter.pipe.ts b/src/@fuse/pipes/filter.pipe.ts index dc709edf..40772a79 100644 --- a/src/@fuse/pipes/filter.pipe.ts +++ b/src/@fuse/pipes/filter.pipe.ts @@ -4,6 +4,14 @@ import { FuseUtils } from '@fuse/utils'; @Pipe({name: 'filter'}) export class FilterPipe implements PipeTransform { + /** + * Transform + * + * @param {any[]} mainArr + * @param {string} searchText + * @param {string} property + * @returns {any} + */ transform(mainArr: any[], searchText: string, property: string): any { return FuseUtils.filterArrayByString(mainArr, searchText); diff --git a/src/@fuse/pipes/getById.pipe.ts b/src/@fuse/pipes/getById.pipe.ts index 5993697f..46887158 100644 --- a/src/@fuse/pipes/getById.pipe.ts +++ b/src/@fuse/pipes/getById.pipe.ts @@ -6,6 +6,14 @@ import { Pipe, PipeTransform } from '@angular/core'; }) export class GetByIdPipe implements PipeTransform { + /** + * Transform + * + * @param {any[]} value + * @param {number} id + * @param {string} property + * @returns {any} + */ transform(value: any[], id: number, property: string): any { const foundItem = value.find(item => { diff --git a/src/@fuse/pipes/htmlToPlaintext.pipe.ts b/src/@fuse/pipes/htmlToPlaintext.pipe.ts index e7c5d56c..e1058fd3 100644 --- a/src/@fuse/pipes/htmlToPlaintext.pipe.ts +++ b/src/@fuse/pipes/htmlToPlaintext.pipe.ts @@ -3,7 +3,14 @@ import { Pipe, PipeTransform } from '@angular/core'; @Pipe({name: 'htmlToPlaintext'}) export class HtmlToPlaintextPipe implements PipeTransform { - transform(value: string, args: any[] = []) + /** + * Transform + * + * @param {string} value + * @param {any[]} args + * @returns {string} + */ + transform(value: string, args: any[] = []): string { return value ? String(value).replace(/<[^>]+>/gm, '') : ''; } diff --git a/src/@fuse/pipes/keys.pipe.ts b/src/@fuse/pipes/keys.pipe.ts index 03b6355a..9e6426a9 100644 --- a/src/@fuse/pipes/keys.pipe.ts +++ b/src/@fuse/pipes/keys.pipe.ts @@ -3,6 +3,13 @@ import { Pipe, PipeTransform } from '@angular/core'; @Pipe({name: 'keys'}) export class KeysPipe implements PipeTransform { + /** + * Transform + * + * @param value + * @param {string[]} args + * @returns {any} + */ transform(value: any, args: string[]): any { const keys: any[] = []; diff --git a/src/@fuse/services/config.service.ts b/src/@fuse/services/config.service.ts index 385ae3fe..8f07ee15 100644 --- a/src/@fuse/services/config.service.ts +++ b/src/@fuse/services/config.service.ts @@ -1,93 +1,96 @@ import { Inject, Injectable, InjectionToken } from '@angular/core'; -import { NavigationEnd, NavigationStart, Router } from '@angular/router'; +import { NavigationStart, Router } from '@angular/router'; import { Platform } from '@angular/cdk/platform'; -import { BehaviorSubject } from 'rxjs'; - +import { BehaviorSubject, Observable } from 'rxjs'; +import { filter } from 'rxjs/operators'; import * as _ from 'lodash'; -// Create the injection token for the custom config +// Create the injection token for the custom settings export const FUSE_CONFIG = new InjectionToken('fuseCustomConfig'); @Injectable() export class FuseConfigService { - config: any; - defaultConfig: any; - isSetConfigRan = false; - - onConfigChanged: BehaviorSubject; + // Private + private _configSubject: BehaviorSubject; + private readonly _defaultConfig: any; /** * Constructor * - * @param router - * @param platform - * @param config + * @param {Platform} _platform + * @param {Router} _router + * @param _config */ constructor( - private router: Router, - public platform: Platform, - @Inject(FUSE_CONFIG) config + private _platform: Platform, + private _router: Router, + @Inject(FUSE_CONFIG) private _config ) { - // Set the default config from the user provided one (forRoot) - this.defaultConfig = config; + // Set the default config from the user provided config (from forRoot) + this._defaultConfig = _config; - /** - * Disable Custom Scrollbars if Browser is Mobile - */ - if ( this.platform.ANDROID || this.platform.IOS ) - { - this.defaultConfig.customScrollbars = false; - } - - // Set the config from the default config - this.config = _.cloneDeep(this.defaultConfig); - - // Reload the default settings for the - // layout on every navigation start - router.events.subscribe( - (event) => { - - if ( event instanceof NavigationStart ) - { - this.isSetConfigRan = false; - } - - if ( event instanceof NavigationEnd ) - { - if ( this.isSetConfigRan ) - { - return; - } - - this.setConfig({ - layout: this.defaultConfig.layout - } - ); - } - } - ); - - // Create the behavior subject - this.onConfigChanged = new BehaviorSubject(this.config); + // Initialize the service + this._init(); } + // ----------------------------------------------------------------------------------------------------- + // @ Accessors + // ----------------------------------------------------------------------------------------------------- + /** - * Set the new config from given object - * - * @param config + * Set and get the config */ - setConfig(config): void + set config(value) { - // Set the SetConfigRan true - this.isSetConfigRan = true; + // Get the value from the behavior subject + let config = this._configSubject.getValue(); - // Merge the config - this.config = _.merge({}, this.config, config); + // Merge the new config + config = _.merge({}, config, value); - // Trigger the event - this.onConfigChanged.next(this.config); + // Notify the observers + this._configSubject.next(config); + } + + get config(): any | Observable + { + return this._configSubject.asObservable(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Private methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Initialize + * + * @private + */ + private _init(): void + { + /** + * Disable custom scrollbars if browser is mobile + */ + if ( this._platform.ANDROID || this._platform.IOS ) + { + this._defaultConfig.customScrollbars = false; + } + + // Set the settings from the default settings + this._configSubject = new BehaviorSubject(_.cloneDeep(this._defaultConfig)); + + // Reload the default settings on every navigation start if + // the current settings are different from defaults + this._router.events + .pipe(filter(event => event instanceof NavigationStart)) + .subscribe(() => { + if ( !_.isEqual(this._configSubject.getValue(), this._defaultConfig) ) + { + this._configSubject.next(_.cloneDeep(this._defaultConfig)); + } + }); } } diff --git a/src/@fuse/services/copier.service.ts b/src/@fuse/services/copier.service.ts index 99880d4e..1b431b0b 100644 --- a/src/@fuse/services/copier.service.ts +++ b/src/@fuse/services/copier.service.ts @@ -11,16 +11,20 @@ import { Injectable } from '@angular/core'; @Injectable() export class FuseCopierService { - private textarea: HTMLTextAreaElement; - /** Copy the text value to the clipboard. */ + /** + * Copy the text value to the clipboard + * + * @param {string} text + * @returns {boolean} + */ copyText(text: string): boolean { this.createTextareaAndSelect(text); const copySuccessful = document.execCommand('copy'); - this.removeFake(); + this._removeFake(); return copySuccessful; } @@ -28,8 +32,10 @@ export class FuseCopierService /** * Creates a hidden textarea element, sets its value from `text` property, * and makes a selection on it. + * + * @param {string} text */ - private createTextareaAndSelect(text: string) + private createTextareaAndSelect(text: string): void { // Create a fake element to hold the contents to copy this.textarea = document.createElement('textarea'); @@ -53,8 +59,12 @@ export class FuseCopierService this.textarea.setSelectionRange(0, this.textarea.value.length); } - /** Remove the text area from the DOM. */ - private removeFake() + /** + * Remove the text area from the DOM + * + * @private + */ + private _removeFake(): void { if ( this.textarea ) { diff --git a/src/@fuse/services/match-media.service.ts b/src/@fuse/services/match-media.service.ts index 2121e8be..22159936 100644 --- a/src/@fuse/services/match-media.service.ts +++ b/src/@fuse/services/match-media.service.ts @@ -8,16 +8,41 @@ export class FuseMatchMediaService activeMediaQuery: string; onMediaChange: BehaviorSubject = new BehaviorSubject(''); - constructor(private observableMedia: ObservableMedia) + /** + * Constructor + * + * @param {ObservableMedia} _observableMedia + */ + constructor( + private _observableMedia: ObservableMedia + ) { + // Set the defaults this.activeMediaQuery = ''; - this.observableMedia.subscribe((change: MediaChange) => { - if ( this.activeMediaQuery !== change.mqAlias ) - { - this.activeMediaQuery = change.mqAlias; - this.onMediaChange.next(change.mqAlias); - } - }); + // Initialize + this._init(); + + } + + // ----------------------------------------------------------------------------------------------------- + // @ Private methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Initialize + * + * @private + */ + private _init(): void + { + this._observableMedia + .subscribe((change: MediaChange) => { + if ( this.activeMediaQuery !== change.mqAlias ) + { + this.activeMediaQuery = change.mqAlias; + this.onMediaChange.next(change.mqAlias); + } + }); } } diff --git a/src/@fuse/services/splash-screen.service.ts b/src/@fuse/services/splash-screen.service.ts index fe85cde8..6ad009d9 100644 --- a/src/@fuse/services/splash-screen.service.ts +++ b/src/@fuse/services/splash-screen.service.ts @@ -6,23 +6,45 @@ import { NavigationEnd, Router } from '@angular/router'; @Injectable() export class FuseSplashScreenService { - splashScreenEl; - public player: AnimationPlayer; + splashScreenEl: any; + player: AnimationPlayer; + /** + * Constructor + * + * @param {AnimationBuilder} _animationBuilder + * @param _document + * @param {Router} _router + */ constructor( - private animationBuilder: AnimationBuilder, - @Inject(DOCUMENT) private document: any, - private router: Router + private _animationBuilder: AnimationBuilder, + @Inject(DOCUMENT) private _document: any, + private _router: Router ) + { + // Initialize + this._init(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Private methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Initialize + * + * @private + */ + private _init(): void { // Get the splash screen element - this.splashScreenEl = this.document.body.querySelector('#fuse-splash-screen'); + this.splashScreenEl = this._document.body.querySelector('#fuse-splash-screen'); // If the splash screen element exists... if ( this.splashScreenEl ) { // Hide it on the first NavigationEnd event - const hideOnLoad = this.router.events.subscribe((event) => { + const hideOnLoad = this._router.events.subscribe((event) => { if ( event instanceof NavigationEnd ) { setTimeout(() => { @@ -38,10 +60,17 @@ export class FuseSplashScreenService } } - show() + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Show the splash screen + */ + show(): void { this.player = - this.animationBuilder + this._animationBuilder .build([ style({ opacity: '0', @@ -55,10 +84,13 @@ export class FuseSplashScreenService }, 0); } - hide() + /** + * Hide the splash screen + */ + hide(): void { this.player = - this.animationBuilder + this._animationBuilder .build([ style({opacity: '1'}), animate('400ms ease', style({ diff --git a/src/@fuse/services/translation-loader.service.ts b/src/@fuse/services/translation-loader.service.ts index 27283713..a26d7027 100644 --- a/src/@fuse/services/translation-loader.service.ts +++ b/src/@fuse/services/translation-loader.service.ts @@ -10,18 +10,34 @@ export interface Locale @Injectable() export class FuseTranslationLoaderService { - constructor(private translate: TranslateService) + /** + * Constructor + * + * @param {TranslateService} _translateService + */ + constructor( + private _translateService: TranslateService + ) { } - public loadTranslations(...args: Locale[]): void + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Load translations + * + * @param {Locale} args + */ + loadTranslations(...args: Locale[]): void { const locales = [...args]; locales.forEach((locale) => { // use setTranslation() with the third argument set to true // to append translations instead of replacing them - this.translate.setTranslation(locale.lang, locale.data, true); + this._translateService.setTranslation(locale.lang, locale.data, true); }); } } diff --git a/src/@fuse/utils/index.ts b/src/@fuse/utils/index.ts index c246c033..5d1cb06a 100644 --- a/src/@fuse/utils/index.ts +++ b/src/@fuse/utils/index.ts @@ -1,6 +1,13 @@ export class FuseUtils { - public static filterArrayByString(mainArr, searchText) + /** + * Filter array by string + * + * @param mainArr + * @param searchText + * @returns {any} + */ + public static filterArrayByString(mainArr, searchText): any { if ( searchText === '' ) { @@ -14,7 +21,14 @@ export class FuseUtils }); } - public static searchInObj(itemObj, searchText) + /** + * Search in object + * + * @param itemObj + * @param searchText + * @returns {boolean} + */ + public static searchInObj(itemObj, searchText): boolean { for ( const prop in itemObj ) { @@ -51,7 +65,14 @@ export class FuseUtils } } - public static searchInArray(arr, searchText) + /** + * Search in array + * + * @param arr + * @param searchText + * @returns {boolean} + */ + public static searchInArray(arr, searchText): boolean { for ( const value of arr ) { @@ -73,14 +94,26 @@ export class FuseUtils } } - public static searchInString(value, searchText) + /** + * Search in string + * + * @param value + * @param searchText + * @returns {any} + */ + public static searchInString(value, searchText): any { return value.toLowerCase().includes(searchText); } - public static generateGUID() + /** + * Generate a unique GUID + * + * @returns {string} + */ + public static generateGUID(): string { - function S4() + function S4(): string { return Math.floor((1 + Math.random()) * 0x10000) .toString(16) @@ -90,7 +123,13 @@ export class FuseUtils return S4() + S4(); } - public static toggleInArray(item, array) + /** + * Toggle in array + * + * @param item + * @param array + */ + public static toggleInArray(item, array): void { if ( array.indexOf(item) === -1 ) { @@ -102,7 +141,13 @@ export class FuseUtils } } - public static handleize(text) + /** + * Handleize + * + * @param text + * @returns {string} + */ + public static handleize(text): string { return text.toString().toLowerCase() .replace(/\s+/g, '-') // Replace spaces with - diff --git a/src/app/app.component.html b/src/app/app.component.html index 720092b3..1281ba0b 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,8 +1 @@ - - - - - - - - \ No newline at end of file + diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 9a7d71d2..06408631 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -5,8 +5,9 @@ import { FuseSplashScreenService } from '@fuse/services/splash-screen.service'; import { FuseTranslationLoaderService } from '@fuse/services/translation-loader.service'; import { FuseNavigationService } from '@fuse/components/navigation/navigation.service'; -import { locale as navigationEnglish } from './navigation/i18n/en'; -import { locale as navigationTurkish } from './navigation/i18n/tr'; +import { navigation } from 'app/navigation/navigation'; +import { locale as navigationEnglish } from 'app/navigation/i18n/en'; +import { locale as navigationTurkish } from 'app/navigation/i18n/tr'; @Component({ selector : 'fuse-root', @@ -15,23 +16,36 @@ import { locale as navigationTurkish } from './navigation/i18n/tr'; }) export class AppComponent { + navigation: any; + + /** + * Constructor + * + * @param {FuseNavigationService} _fuseNavigationService + * @param {FuseSplashScreenService} _fuseSplashScreenService + * @param {FuseTranslationLoaderService} _fuseTranslationLoaderService + * @param {TranslateService} _translateService + */ constructor( - private translate: TranslateService, - private fuseNavigationService: FuseNavigationService, - private fuseSplashScreen: FuseSplashScreenService, - private fuseTranslationLoader: FuseTranslationLoaderService + private _fuseNavigationService: FuseNavigationService, + private _fuseSplashScreenService: FuseSplashScreenService, + private _fuseTranslationLoaderService: FuseTranslationLoaderService, + private _translateService: TranslateService ) { + // Navigation + this.navigation = navigation; + // Add languages - this.translate.addLangs(['en', 'tr']); + this._translateService.addLangs(['en', 'tr']); // Set the default language - this.translate.setDefaultLang('en'); + this._translateService.setDefaultLang('en'); // Set the navigation translations - this.fuseTranslationLoader.loadTranslations(navigationEnglish, navigationTurkish); + this._fuseTranslationLoaderService.loadTranslations(navigationEnglish, navigationTurkish); // Use a language - this.translate.use('en'); + this._translateService.use('en'); } } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index a9b4fa1b..de296e12 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -8,23 +8,23 @@ import { TranslateModule } from '@ngx-translate/core'; import 'hammerjs'; import { FuseModule } from '@fuse/fuse.module'; -import { FuseLayoutsModule } from '@fuse/components'; import { FuseSharedModule } from '@fuse/shared.module'; -import { fuseConfig } from './fuse-config'; +import { fuseConfig } from 'app/fuse-config'; -import { AppComponent } from './app.component'; -import { FuseFakeDbService } from './fuse-fake-db/fuse-fake-db.service'; -import { AppStoreModule } from './store/store.module'; +import { FuseFakeDbService } from 'app/fuse-fake-db/fuse-fake-db.service'; +import { AppComponent } from 'app/app.component'; +import { AppStoreModule } from 'app/store/store.module'; +import { LayoutModule } from 'app/layout/layout.module'; const appRoutes: Routes = [ { path : 'apps', - loadChildren: './main/apps/apps.module#FuseAppsModule' + loadChildren: './main/apps/apps.module#AppsModule' }, { path : 'pages', - loadChildren: './main/pages/pages.module#FusePagesModule' + loadChildren: './main/pages/pages.module#PagesModule' }, { path : 'ui', @@ -32,15 +32,15 @@ const appRoutes: Routes = [ }, { path : 'services', - loadChildren: './main/services/services.module#FuseServicesModule' + loadChildren: './main/services/services.module#ServicesModule' }, { path : 'components', - loadChildren: './main/components/components.module#FuseComponentsModule' + loadChildren: './main/components/components.module#ComponentsModule' }, { path : 'components-third-party', - loadChildren: './main/components-third-party/components-third-party.module#FuseComponentsThirdPartyModule' + loadChildren: './main/components-third-party/components-third-party.module#ComponentsThirdPartyModule' }, { path : '**', @@ -64,11 +64,12 @@ const appRoutes: Routes = [ passThruUnknownUrl: true }), - // Fuse Main and Shared modules + // Fuse modules FuseModule.forRoot(fuseConfig), - FuseLayoutsModule, FuseSharedModule, + // App modules + LayoutModule, AppStoreModule ], bootstrap : [ diff --git a/src/app/fuse-config.ts b/src/app/fuse-config/index.ts similarity index 86% rename from src/app/fuse-config.ts rename to src/app/fuse-config/index.ts index 15c37aa7..7bb7e6bb 100644 --- a/src/app/fuse-config.ts +++ b/src/app/fuse-config/index.ts @@ -2,12 +2,12 @@ * Default Fuse Configuration * * You can edit these options to change the default options. All these options also can be changed per component - * basis. See `app/main/content/pages/authentication/login/login.component.ts` constructor method to learn more + * basis. See `app/main/pages/authentication/login/login.component.ts` constructor method to learn more * about changing these options per component basis. */ export const fuseConfig = { layout : { - style : 'vertical', + style : 'vertical-basic', navigation: { position: 'left', folded : false diff --git a/src/app/layout/content/content.component.html b/src/app/layout/blocks/content/content.component.html similarity index 100% rename from src/app/layout/content/content.component.html rename to src/app/layout/blocks/content/content.component.html diff --git a/src/app/layout/content/content.component.scss b/src/app/layout/blocks/content/content.component.scss similarity index 100% rename from src/app/layout/content/content.component.scss rename to src/app/layout/blocks/content/content.component.scss diff --git a/src/app/layout/blocks/content/content.component.ts b/src/app/layout/blocks/content/content.component.ts new file mode 100644 index 00000000..481247a5 --- /dev/null +++ b/src/app/layout/blocks/content/content.component.ts @@ -0,0 +1,110 @@ +import { Component, HostBinding, OnDestroy, OnInit } from '@angular/core'; +import { ActivatedRoute, NavigationEnd, Router } from '@angular/router'; +import { Subject } from 'rxjs'; +import { filter, map } from 'rxjs/operators'; +import { takeUntil } from 'rxjs/operators'; + +import { fuseAnimations } from '@fuse/animations'; +import { FuseConfigService } from '@fuse/services/config.service'; + +@Component({ + selector : 'content', + templateUrl: './content.component.html', + styleUrls : ['./content.component.scss'], + animations : fuseAnimations +}) +export class ContentComponent implements OnInit, OnDestroy +{ + fuseConfig: any; + + @HostBinding('@routerTransitionUp') + routeAnimationUp = false; + + @HostBinding('@routerTransitionDown') + routeAnimationDown = false; + + @HostBinding('@routerTransitionRight') + routeAnimationRight = false; + + @HostBinding('@routerTransitionLeft') + routeAnimationLeft = false; + + @HostBinding('@routerTransitionFade') + routeAnimationFade = false; + + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {ActivatedRoute} _activatedRoute + * @param {FuseConfigService} _fuseConfigService + * @param {Router} _router + */ + constructor( + private _activatedRoute: ActivatedRoute, + private _fuseConfigService: FuseConfigService, + private _router: Router + ) + { + // Set the private defaults + this._unsubscribeAll = new Subject(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void + { + // Subscribe to the router events for router animations + this._router.events + .pipe( + filter((event) => event instanceof NavigationEnd), + map(() => this._activatedRoute) + ) + .subscribe(() => { + switch ( this.fuseConfig.routerAnimation ) + { + case 'fadeIn': + this.routeAnimationFade = !this.routeAnimationFade; + break; + case 'slideUp': + this.routeAnimationUp = !this.routeAnimationUp; + break; + case 'slideDown': + this.routeAnimationDown = !this.routeAnimationDown; + break; + case 'slideRight': + this.routeAnimationRight = !this.routeAnimationRight; + break; + case 'slideLeft': + this.routeAnimationLeft = !this.routeAnimationLeft; + break; + } + }); + + // Subscribe to config changes + this._fuseConfigService.config + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe( + (config) => { + this.fuseConfig = config; + } + ); + } + + /** + * On destroy + */ + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); + } +} diff --git a/src/app/layout/content/content.module.ts b/src/app/layout/blocks/content/content.module.ts similarity index 63% rename from src/app/layout/content/content.module.ts rename to src/app/layout/blocks/content/content.module.ts index 2be7d794..5b2c42d7 100644 --- a/src/app/layout/content/content.module.ts +++ b/src/app/layout/blocks/content/content.module.ts @@ -3,21 +3,20 @@ import { RouterModule } from '@angular/router'; import { FuseSharedModule } from '@fuse/shared.module'; -import { FuseContentComponent } from 'app/layout/content/content.component'; +import { ContentComponent } from 'app/layout/blocks/content/content.component'; @NgModule({ declarations: [ - FuseContentComponent + ContentComponent ], imports : [ RouterModule, - FuseSharedModule, ], exports: [ - FuseContentComponent + ContentComponent ] }) -export class FuseContentModule +export class ContentModule { } diff --git a/src/app/layout/footer/footer.component.html b/src/app/layout/blocks/footer/footer.component.html similarity index 100% rename from src/app/layout/footer/footer.component.html rename to src/app/layout/blocks/footer/footer.component.html diff --git a/src/app/layout/footer/footer.component.scss b/src/app/layout/blocks/footer/footer.component.scss similarity index 100% rename from src/app/layout/footer/footer.component.scss rename to src/app/layout/blocks/footer/footer.component.scss diff --git a/src/app/layout/footer/footer.component.ts b/src/app/layout/blocks/footer/footer.component.ts similarity index 66% rename from src/app/layout/footer/footer.component.ts rename to src/app/layout/blocks/footer/footer.component.ts index 4065e363..0a12144e 100644 --- a/src/app/layout/footer/footer.component.ts +++ b/src/app/layout/blocks/footer/footer.component.ts @@ -1,13 +1,15 @@ import { Component } from '@angular/core'; @Component({ - selector : 'fuse-footer', + selector : 'footer', templateUrl: './footer.component.html', styleUrls : ['./footer.component.scss'] }) -export class FuseFooterComponent +export class FooterComponent { - + /** + * Constructor + */ constructor() { } diff --git a/src/app/layout/footer/footer.module.ts b/src/app/layout/blocks/footer/footer.module.ts similarity index 62% rename from src/app/layout/footer/footer.module.ts rename to src/app/layout/blocks/footer/footer.module.ts index 10b7c9e1..058b7aad 100644 --- a/src/app/layout/footer/footer.module.ts +++ b/src/app/layout/blocks/footer/footer.module.ts @@ -1,18 +1,15 @@ import { NgModule } from '@angular/core'; -import { RouterModule } from '@angular/router'; import { MatButtonModule, MatIconModule, MatToolbarModule } from '@angular/material'; import { FuseSharedModule } from '@fuse/shared.module'; -import { FuseFooterComponent } from 'app/layout/footer/footer.component'; +import { FooterComponent } from 'app/layout/blocks/footer/footer.component'; @NgModule({ declarations: [ - FuseFooterComponent + FooterComponent ], imports : [ - RouterModule, - MatButtonModule, MatIconModule, MatToolbarModule, @@ -20,9 +17,9 @@ import { FuseFooterComponent } from 'app/layout/footer/footer.component'; FuseSharedModule ], exports : [ - FuseFooterComponent + FooterComponent ] }) -export class FuseFooterModule +export class FooterModule { } diff --git a/src/app/layout/navbar/navbar.component.html b/src/app/layout/blocks/navbar/navbar.component.html similarity index 100% rename from src/app/layout/navbar/navbar.component.html rename to src/app/layout/blocks/navbar/navbar.component.html diff --git a/src/app/layout/navbar/navbar.component.scss b/src/app/layout/blocks/navbar/navbar.component.scss similarity index 97% rename from src/app/layout/navbar/navbar.component.scss rename to src/app/layout/blocks/navbar/navbar.component.scss index 0a09af21..09837358 100644 --- a/src/app/layout/navbar/navbar.component.scss +++ b/src/app/layout/blocks/navbar/navbar.component.scss @@ -1,4 +1,4 @@ -@import "../../../@fuse/scss/fuse"; +@import "src/@fuse/scss/fuse"; body { @@ -44,7 +44,7 @@ fuse-sidebar { } } -fuse-navbar { +navbar { &:not(.top-navbar) { height: 100%; diff --git a/src/app/layout/blocks/navbar/navbar.component.ts b/src/app/layout/blocks/navbar/navbar.component.ts new file mode 100644 index 00000000..0ef3d7a3 --- /dev/null +++ b/src/app/layout/blocks/navbar/navbar.component.ts @@ -0,0 +1,133 @@ +import { Component, Input, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core'; +import { NavigationEnd, Router } from '@angular/router'; +import { Subject } from 'rxjs'; +import { filter, takeUntil } from 'rxjs/operators'; + +import { FusePerfectScrollbarDirective } from '@fuse/directives/fuse-perfect-scrollbar/fuse-perfect-scrollbar.directive'; +import { FuseSidebarService } from '@fuse/components/sidebar/sidebar.service'; + +import { navigation } from 'app/navigation/navigation'; +import { FuseNavigationService } from '@fuse/components/navigation/navigation.service'; + +@Component({ + selector : 'navbar', + templateUrl : './navbar.component.html', + styleUrls : ['./navbar.component.scss'], + encapsulation: ViewEncapsulation.None +}) +export class NavbarComponent implements OnInit, OnDestroy +{ + // Layout + @Input() + layout; + + fusePerfectScrollbarUpdateTimeout: any; + navigation: any; + + // Private + private _fusePerfectScrollbar: FusePerfectScrollbarDirective; + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {FuseNavigationService} _fuseNavigationService + * @param {FuseSidebarService} _fuseSidebarService + * @param {Router} _router + */ + constructor( + private _fuseNavigationService: FuseNavigationService, + private _fuseSidebarService: FuseSidebarService, + private _router: Router + ) + { + // Set the defaults + this.layout = 'vertical'; + this.navigation = navigation; + + // Set the private defaults + this._unsubscribeAll = new Subject(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Accessors + // ----------------------------------------------------------------------------------------------------- + + // Directive + @ViewChild(FusePerfectScrollbarDirective) + set directive(theDirective: FusePerfectScrollbarDirective) + { + if ( !theDirective ) + { + return; + } + + this._fusePerfectScrollbar = theDirective; + + this._fuseNavigationService.onItemCollapseToggled + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { + this.fusePerfectScrollbarUpdateTimeout = setTimeout(() => { + this._fusePerfectScrollbar.update(); + }, 310); + }); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void + { + this._router.events + .pipe( + filter((event) => event instanceof NavigationEnd), + takeUntil(this._unsubscribeAll) + ) + .subscribe(() => { + if ( this._fuseSidebarService.getSidebar('navbar') ) + { + this._fuseSidebarService.getSidebar('navbar').close(); + } + } + ); + } + + /** + * On destroy + */ + ngOnDestroy(): void + { + if ( this.fusePerfectScrollbarUpdateTimeout ) + { + clearTimeout(this.fusePerfectScrollbarUpdateTimeout); + } + + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Toggle sidebar opened status + */ + toggleSidebarOpened(): void + { + this._fuseSidebarService.getSidebar('navbar').toggleOpen(); + } + + /** + * Toggle sidebar folded status + */ + toggleSidebarFolded(): void + { + this._fuseSidebarService.getSidebar('navbar').toggleFold(); + } +} diff --git a/src/app/layout/navbar/navbar.module.ts b/src/app/layout/blocks/navbar/navbar.module.ts similarity index 64% rename from src/app/layout/navbar/navbar.module.ts rename to src/app/layout/blocks/navbar/navbar.module.ts index 589de6d9..03d2e2a7 100644 --- a/src/app/layout/navbar/navbar.module.ts +++ b/src/app/layout/blocks/navbar/navbar.module.ts @@ -1,20 +1,16 @@ import { NgModule } from '@angular/core'; -import { RouterModule } from '@angular/router'; - import { MatButtonModule, MatIconModule } from '@angular/material'; +import { FuseNavigationModule } from '@fuse/components'; import { FuseSharedModule } from '@fuse/shared.module'; -import { FuseNavbarComponent } from 'app/layout/navbar/navbar.component'; -import { FuseNavigationModule } from '@fuse/components'; +import { NavbarComponent } from 'app/layout/blocks/navbar/navbar.component'; @NgModule({ declarations: [ - FuseNavbarComponent + NavbarComponent ], imports : [ - RouterModule, - MatButtonModule, MatIconModule, @@ -22,9 +18,9 @@ import { FuseNavigationModule } from '@fuse/components'; FuseNavigationModule ], exports : [ - FuseNavbarComponent + NavbarComponent ] }) -export class FuseNavbarModule +export class NavbarModule { } diff --git a/src/app/layout/quick-panel/quick-panel.component.html b/src/app/layout/blocks/quick-panel/quick-panel.component.html similarity index 100% rename from src/app/layout/quick-panel/quick-panel.component.html rename to src/app/layout/blocks/quick-panel/quick-panel.component.html diff --git a/src/app/layout/quick-panel/quick-panel.component.scss b/src/app/layout/blocks/quick-panel/quick-panel.component.scss similarity index 90% rename from src/app/layout/quick-panel/quick-panel.component.scss rename to src/app/layout/blocks/quick-panel/quick-panel.component.scss index be16d852..2b116c1a 100644 --- a/src/app/layout/quick-panel/quick-panel.component.scss +++ b/src/app/layout/blocks/quick-panel/quick-panel.component.scss @@ -1,4 +1,4 @@ -fuse-quick-panel { +quick-panel { display: flex; width: 280px; min-width: 280px; diff --git a/src/app/layout/blocks/quick-panel/quick-panel.component.ts b/src/app/layout/blocks/quick-panel/quick-panel.component.ts new file mode 100644 index 00000000..ba235aa4 --- /dev/null +++ b/src/app/layout/blocks/quick-panel/quick-panel.component.ts @@ -0,0 +1,76 @@ +import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; + +@Component({ + selector : 'quick-panel', + templateUrl : './quick-panel.component.html', + styleUrls : ['./quick-panel.component.scss'], + encapsulation: ViewEncapsulation.None +}) +export class QuickPanelComponent implements OnInit, OnDestroy +{ + date: Date; + events: any[]; + notes: any[]; + settings: any; + + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {HttpClient} _httpClient + */ + constructor( + private _httpClient: HttpClient + ) + { + // Set the defaults + this.date = new Date(); + this.settings = { + notify: true, + cloud : false, + retro : true + }; + + // Set the private defaults + this._unsubscribeAll = new Subject(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void + { + // Subscribe to the events + this._httpClient.get('api/quick-panel-events') + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe((response: any) => { + this.events = response; + }); + + // Subscribe to the notes + this._httpClient.get('api/quick-panel-notes') + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe((response: any) => { + this.notes = response; + }); + } + + /** + * On destroy + */ + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); + } +} diff --git a/src/app/layout/quick-panel/quick-panel.module.ts b/src/app/layout/blocks/quick-panel/quick-panel.module.ts similarity index 60% rename from src/app/layout/quick-panel/quick-panel.module.ts rename to src/app/layout/blocks/quick-panel/quick-panel.module.ts index 0a863545..0d4062cc 100644 --- a/src/app/layout/quick-panel/quick-panel.module.ts +++ b/src/app/layout/blocks/quick-panel/quick-panel.module.ts @@ -1,18 +1,15 @@ import { NgModule } from '@angular/core'; -import { RouterModule } from '@angular/router'; import { MatDividerModule, MatListModule, MatSlideToggleModule } from '@angular/material'; import { FuseSharedModule } from '@fuse/shared.module'; -import { FuseQuickPanelComponent } from 'app/layout/quick-panel/quick-panel.component'; +import { QuickPanelComponent } from 'app/layout/blocks/quick-panel/quick-panel.component'; @NgModule({ declarations: [ - FuseQuickPanelComponent + QuickPanelComponent ], imports : [ - RouterModule, - MatDividerModule, MatListModule, MatSlideToggleModule, @@ -20,9 +17,9 @@ import { FuseQuickPanelComponent } from 'app/layout/quick-panel/quick-panel.comp FuseSharedModule, ], exports: [ - FuseQuickPanelComponent + QuickPanelComponent ] }) -export class FuseQuickPanelModule +export class QuickPanelModule { } diff --git a/src/app/layout/toolbar/toolbar.component.html b/src/app/layout/blocks/toolbar/toolbar.component.html similarity index 99% rename from src/app/layout/toolbar/toolbar.component.html rename to src/app/layout/blocks/toolbar/toolbar.component.html index e39c26f2..d1d3cf8e 100644 --- a/src/app/layout/toolbar/toolbar.component.html +++ b/src/app/layout/blocks/toolbar/toolbar.component.html @@ -98,5 +98,7 @@ + + diff --git a/src/app/layout/toolbar/toolbar.component.scss b/src/app/layout/blocks/toolbar/toolbar.component.scss similarity index 96% rename from src/app/layout/toolbar/toolbar.component.scss rename to src/app/layout/blocks/toolbar/toolbar.component.scss index 25abc217..ea7692af 100644 --- a/src/app/layout/toolbar/toolbar.component.scss +++ b/src/app/layout/blocks/toolbar/toolbar.component.scss @@ -1,4 +1,4 @@ -@import '../../../@fuse/scss/fuse'; +@import "src/@fuse/scss/fuse"; :host { position: relative; diff --git a/src/app/layout/blocks/toolbar/toolbar.component.ts b/src/app/layout/blocks/toolbar/toolbar.component.ts new file mode 100644 index 00000000..34ab33fc --- /dev/null +++ b/src/app/layout/blocks/toolbar/toolbar.component.ts @@ -0,0 +1,182 @@ +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { NavigationEnd, NavigationStart, Router } from '@angular/router'; +import { Subject } from 'rxjs'; +import { filter, takeUntil } from 'rxjs/operators'; +import { TranslateService } from '@ngx-translate/core'; +import * as _ from 'lodash'; + +import { FuseConfigService } from '@fuse/services/config.service'; +import { FuseSidebarService } from '@fuse/components/sidebar/sidebar.service'; + +import { navigation } from 'app/navigation/navigation'; + +@Component({ + selector : 'toolbar', + templateUrl: './toolbar.component.html', + styleUrls : ['./toolbar.component.scss'] +}) + +export class ToolbarComponent implements OnInit, OnDestroy +{ + horizontalNav: boolean; + languages: any; + noNav: boolean; + navigation: any; + selectedLanguage: any; + showLoadingBar: boolean; + userStatusOptions: any[]; + + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {FuseConfigService} _fuseConfigService + * @param {FuseSidebarService} _fuseSidebarService + * @param {Router} _router + * @param {TranslateService} _translateService + */ + constructor( + private _fuseConfigService: FuseConfigService, + private _fuseSidebarService: FuseSidebarService, + private _router: Router, + private _translateService: TranslateService + ) + { + // Set the defaults + this.userStatusOptions = [ + { + 'title': 'Online', + 'icon' : 'icon-checkbox-marked-circle', + 'color': '#4CAF50' + }, + { + 'title': 'Away', + 'icon' : 'icon-clock', + 'color': '#FFC107' + }, + { + 'title': 'Do not Disturb', + 'icon' : 'icon-minus-circle', + 'color': '#F44336' + }, + { + 'title': 'Invisible', + 'icon' : 'icon-checkbox-blank-circle-outline', + 'color': '#BDBDBD' + }, + { + 'title': 'Offline', + 'icon' : 'icon-checkbox-blank-circle-outline', + 'color': '#616161' + } + ]; + + this.languages = [ + { + id : 'en', + title: 'English', + flag : 'us' + }, + { + id : 'tr', + title: 'Turkish', + flag : 'tr' + } + ]; + + this.navigation = navigation; + + // Set the private defaults + this._unsubscribeAll = new Subject(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void + { + // Subscribe to the router events to show/hide the loading bar + this._router.events + .pipe( + filter((event) => event instanceof NavigationStart), + takeUntil(this._unsubscribeAll) + ) + .subscribe((event) => { + this.showLoadingBar = true; + }); + + this._router.events + .pipe( + filter((event) => event instanceof NavigationEnd) + ) + .subscribe((event) => { + this.showLoadingBar = false; + }); + + // Subscribe to the config changes + this._fuseConfigService.config + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe((settings) => { + this.horizontalNav = settings.layout.navigation.position === 'top'; + this.noNav = settings.layout.navigation.position === 'none'; + }); + + // Set the selected language from default languages + this.selectedLanguage = _.find(this.languages, {'id': this._translateService.currentLang}); + } + + /** + * On destroy + */ + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Toggle sidebar opened + * + * @param key + */ + toggleSidebarOpened(key): void + { + this._fuseSidebarService.getSidebar(key).toggleOpen(); + } + + /** + * Search + * + * @param value + */ + search(value): void + { + // Do your search here... + console.log(value); + } + + /** + * Set the language + * + * @param langId + */ + setLanguage(langId): void + { + // Set the selected language for toolbar + this.selectedLanguage = _.find(this.languages, {'id': langId}); + + // Use the selected language for translations + this._translateService.use(langId); + } +} diff --git a/src/app/layout/toolbar/toolbar.module.ts b/src/app/layout/blocks/toolbar/toolbar.module.ts similarity index 80% rename from src/app/layout/toolbar/toolbar.module.ts rename to src/app/layout/blocks/toolbar/toolbar.module.ts index 57272437..4217e99a 100644 --- a/src/app/layout/toolbar/toolbar.module.ts +++ b/src/app/layout/blocks/toolbar/toolbar.module.ts @@ -2,18 +2,17 @@ import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; import { MatButtonModule, MatIconModule, MatMenuModule, MatProgressBarModule, MatToolbarModule } from '@angular/material'; +import { FuseSearchBarModule, FuseShortcutsModule } from '@fuse/components'; import { FuseSharedModule } from '@fuse/shared.module'; -import { FuseToolbarComponent } from 'app/layout/toolbar/toolbar.component'; -import { FuseSearchBarModule, FuseShortcutsModule } from '@fuse/components'; +import { ToolbarComponent } from 'app/layout/blocks/toolbar/toolbar.component'; @NgModule({ declarations: [ - FuseToolbarComponent + ToolbarComponent ], imports : [ RouterModule, - MatButtonModule, MatIconModule, MatMenuModule, @@ -25,9 +24,9 @@ import { FuseSearchBarModule, FuseShortcutsModule } from '@fuse/components'; FuseShortcutsModule ], exports : [ - FuseToolbarComponent + ToolbarComponent ] }) -export class FuseToolbarModule +export class ToolbarModule { } diff --git a/src/app/layout/content/content.component.ts b/src/app/layout/content/content.component.ts deleted file mode 100644 index 1f2aedee..00000000 --- a/src/app/layout/content/content.component.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { Component, HostBinding, OnDestroy } from '@angular/core'; -import { ActivatedRoute, NavigationEnd, Router } from '@angular/router'; - -import { Subscription } from 'rxjs'; -import { filter, map } from 'rxjs/operators'; - -import { fuseAnimations } from '@fuse/animations/index'; -import { FuseConfigService } from '@fuse/services/config.service'; - -@Component({ - selector : 'fuse-content', - templateUrl: './content.component.html', - styleUrls : ['./content.component.scss'], - animations : fuseAnimations -}) -export class FuseContentComponent implements OnDestroy -{ - onConfigChanged: Subscription; - fuseSettings: any; - - @HostBinding('@routerTransitionUp') routeAnimationUp = false; - @HostBinding('@routerTransitionDown') routeAnimationDown = false; - @HostBinding('@routerTransitionRight') routeAnimationRight = false; - @HostBinding('@routerTransitionLeft') routeAnimationLeft = false; - @HostBinding('@routerTransitionFade') routeAnimationFade = false; - - constructor( - private router: Router, - private activatedRoute: ActivatedRoute, - private fuseConfig: FuseConfigService - ) - { - this.router.events.pipe( - filter((event) => event instanceof NavigationEnd), - map(() => this.activatedRoute) - ).subscribe((event) => { - switch ( this.fuseSettings.routerAnimation ) - { - case 'fadeIn': - this.routeAnimationFade = !this.routeAnimationFade; - break; - case 'slideUp': - this.routeAnimationUp = !this.routeAnimationUp; - break; - case 'slideDown': - this.routeAnimationDown = !this.routeAnimationDown; - break; - case 'slideRight': - this.routeAnimationRight = !this.routeAnimationRight; - break; - case 'slideLeft': - this.routeAnimationLeft = !this.routeAnimationLeft; - break; - } - }); - - this.onConfigChanged = - this.fuseConfig.onConfigChanged - .subscribe( - (newSettings) => { - this.fuseSettings = newSettings; - } - ); - } - - ngOnDestroy() - { - this.onConfigChanged.unsubscribe(); - } -} diff --git a/src/app/layout/layout.module.ts b/src/app/layout/layout.module.ts new file mode 100644 index 00000000..0d168275 --- /dev/null +++ b/src/app/layout/layout.module.ts @@ -0,0 +1,15 @@ +import { NgModule } from '@angular/core'; + +import { VerticalNavBasicLayoutModule } from 'app/layout/vertical/basic/basic.module'; + +@NgModule({ + imports: [ + VerticalNavBasicLayoutModule + ], + exports: [ + VerticalNavBasicLayoutModule + ] +}) +export class LayoutModule +{ +} diff --git a/src/app/layout/navbar/navbar.component.ts b/src/app/layout/navbar/navbar.component.ts deleted file mode 100644 index 340ba35d..00000000 --- a/src/app/layout/navbar/navbar.component.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { Component, Input, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core'; -import { NavigationEnd, Router } from '@angular/router'; - -import { Subscription } from 'rxjs'; - -import { FusePerfectScrollbarDirective } from '@fuse/directives/fuse-perfect-scrollbar/fuse-perfect-scrollbar.directive'; -import { FuseSidebarService } from '@fuse/components/sidebar/sidebar.service'; - -import { navigation } from 'app/navigation/navigation'; -import { FuseNavigationService } from '@fuse/components/navigation/navigation.service'; -import { FuseSidebarComponent } from '@fuse/components/sidebar/sidebar.component'; - -@Component({ - selector : 'fuse-navbar', - templateUrl : './navbar.component.html', - styleUrls : ['./navbar.component.scss'], - encapsulation: ViewEncapsulation.None -}) -export class FuseNavbarComponent implements OnInit, OnDestroy -{ - private fusePerfectScrollbar: FusePerfectScrollbarDirective; - - @ViewChild(FusePerfectScrollbarDirective) set directive(theDirective: FusePerfectScrollbarDirective) - { - if ( !theDirective ) - { - return; - } - - this.fusePerfectScrollbar = theDirective; - - this.navigationServiceWatcher = - this.navigationService.onItemCollapseToggled.subscribe(() => { - this.fusePerfectScrollbarUpdateTimeout = setTimeout(() => { - this.fusePerfectScrollbar.update(); - }, 310); - }); - } - - @Input() layout; - navigation: any; - navigationServiceWatcher: Subscription; - fusePerfectScrollbarUpdateTimeout; - - constructor( - private sidebarService: FuseSidebarService, - private navigationService: FuseNavigationService, - private router: Router - ) - { - // Navigation data - this.navigation = navigation; - - // Default layout - this.layout = 'vertical'; - } - - ngOnInit() - { - this.router.events.subscribe( - (event) => { - if ( event instanceof NavigationEnd ) - { - if ( this.sidebarService.getSidebar('navbar') ) - { - this.sidebarService.getSidebar('navbar').close(); - } - } - } - ); - } - - ngOnDestroy() - { - if ( this.fusePerfectScrollbarUpdateTimeout ) - { - clearTimeout(this.fusePerfectScrollbarUpdateTimeout); - } - - if ( this.navigationServiceWatcher ) - { - this.navigationServiceWatcher.unsubscribe(); - } - } - - toggleSidebarOpened() - { - this.sidebarService.getSidebar('navbar').toggleOpen(); - } - - toggleSidebarFolded() - { - this.sidebarService.getSidebar('navbar').toggleFold(); - } -} diff --git a/src/app/layout/quick-panel/quick-panel.component.ts b/src/app/layout/quick-panel/quick-panel.component.ts deleted file mode 100644 index 6163e058..00000000 --- a/src/app/layout/quick-panel/quick-panel.component.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { Component, OnInit, ViewEncapsulation } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; - -@Component({ - selector : 'fuse-quick-panel', - templateUrl : './quick-panel.component.html', - styleUrls : ['./quick-panel.component.scss'], - encapsulation: ViewEncapsulation.None -}) -export class FuseQuickPanelComponent implements OnInit -{ - date: Date; - settings: any; - notes: any[]; - events: any[]; - - constructor(private http: HttpClient) - { - this.date = new Date(); - this.settings = { - notify: true, - cloud : false, - retro : true - }; - } - - ngOnInit() - { - this.http.get('api/quick-panel-notes') - .subscribe((response: any) => { - this.notes = response; - }); - - this.http.get('api/quick-panel-events') - .subscribe((response: any) => { - this.events = response; - }); - - } - -} diff --git a/src/app/layout/toolbar/toolbar.component.ts b/src/app/layout/toolbar/toolbar.component.ts deleted file mode 100644 index f5cab4b4..00000000 --- a/src/app/layout/toolbar/toolbar.component.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { NavigationEnd, NavigationStart, Router } from '@angular/router'; -import { TranslateService } from '@ngx-translate/core'; -import * as _ from 'lodash'; - -import { FuseConfigService } from '@fuse/services/config.service'; -import { FuseSidebarService } from '@fuse/components/sidebar/sidebar.service'; - -import { navigation } from 'app/navigation/navigation'; - -@Component({ - selector : 'fuse-toolbar', - templateUrl: './toolbar.component.html', - styleUrls : ['./toolbar.component.scss'] -}) - -export class FuseToolbarComponent implements OnInit -{ - userStatusOptions: any[]; - languages: any; - selectedLanguage: any; - showLoadingBar: boolean; - horizontalNav: boolean; - noNav: boolean; - navigation: any; - - constructor( - private router: Router, - private fuseConfig: FuseConfigService, - private sidebarService: FuseSidebarService, - private translate: TranslateService - ) - { - this.userStatusOptions = [ - { - 'title': 'Online', - 'icon' : 'icon-checkbox-marked-circle', - 'color': '#4CAF50' - }, - { - 'title': 'Away', - 'icon' : 'icon-clock', - 'color': '#FFC107' - }, - { - 'title': 'Do not Disturb', - 'icon' : 'icon-minus-circle', - 'color': '#F44336' - }, - { - 'title': 'Invisible', - 'icon' : 'icon-checkbox-blank-circle-outline', - 'color': '#BDBDBD' - }, - { - 'title': 'Offline', - 'icon' : 'icon-checkbox-blank-circle-outline', - 'color': '#616161' - } - ]; - - this.languages = [ - { - id : 'en', - title: 'English', - flag : 'us' - }, - { - id : 'tr', - title: 'Turkish', - flag : 'tr' - } - ]; - - router.events.subscribe( - (event) => { - if ( event instanceof NavigationStart ) - { - this.showLoadingBar = true; - } - if ( event instanceof NavigationEnd ) - { - this.showLoadingBar = false; - } - }); - - this.fuseConfig.onConfigChanged.subscribe((settings) => { - this.horizontalNav = settings.layout.navigation === 'top'; - this.noNav = settings.layout.navigation === 'none'; - }); - - this.navigation = navigation; - } - - ngOnInit() - { - this.selectedLanguage = _.find(this.languages, {'id': this.translate.currentLang}); - } - - toggleSidebarOpened(key) - { - this.sidebarService.getSidebar(key).toggleOpen(); - } - - search(value) - { - // Do your search here... - console.log(value); - } - - setLanguage(langId) - { - // Set the selected language for toolbar - this.selectedLanguage = _.find(this.languages, {'id': langId}); - - // Use the selected language for translations - this.translate.use(langId); - } -} diff --git a/src/app/layout/vertical/basic/basic.component.html b/src/app/layout/vertical/basic/basic.component.html new file mode 100644 index 00000000..a12d2561 --- /dev/null +++ b/src/app/layout/vertical/basic/basic.component.html @@ -0,0 +1,77 @@ + + +
+ + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + + + + +
+
+ + +
+ + + + + + + +
+ + + +
+
+ + +
+ + + + + + + +
+ + \ No newline at end of file diff --git a/src/@fuse/components/layouts/vertical-nav/basic/basic.component.scss b/src/app/layout/vertical/basic/basic.component.scss similarity index 94% rename from src/@fuse/components/layouts/vertical-nav/basic/basic.component.scss rename to src/app/layout/vertical/basic/basic.component.scss index 793e79b4..3220c433 100644 --- a/src/@fuse/components/layouts/vertical-nav/basic/basic.component.scss +++ b/src/app/layout/vertical/basic/basic.component.scss @@ -1,6 +1,6 @@ @import "src/@fuse/scss/fuse"; -fuse-vertical-nav-basic-layout { +vertical-nav-basic-layout { display: flex; flex-direction: column; width: 100%; @@ -21,7 +21,7 @@ fuse-vertical-nav-basic-layout { height: auto !important; } - #fuse-main-content { + #main-content { display: flex; flex: 1; flex-direction: column; @@ -39,7 +39,7 @@ fuse-vertical-nav-basic-layout { flex: 1; overflow: hidden; - fuse-content { + content { position: relative; display: flex; flex: 1; diff --git a/src/app/layout/vertical/basic/basic.component.ts b/src/app/layout/vertical/basic/basic.component.ts new file mode 100644 index 00000000..ad498b0e --- /dev/null +++ b/src/app/layout/vertical/basic/basic.component.ts @@ -0,0 +1,64 @@ +import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; + +import { FuseConfigService } from '@fuse/services/config.service'; +import { navigation } from 'app/navigation/navigation'; + +@Component({ + selector : 'vertical-nav-basic-layout', + templateUrl : './basic.component.html', + styleUrls : ['./basic.component.scss'], + encapsulation: ViewEncapsulation.None +}) +export class VerticalNavBasicLayoutComponent implements OnInit, OnDestroy +{ + fuseConfig: any; + navigation: any; + + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {FuseConfigService} _fuseConfigService + */ + constructor( + private _fuseConfigService: FuseConfigService + ) + { + // Set the defaults + this.navigation = navigation; + + // Set the private defaults + this._unsubscribeAll = new Subject(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void + { + // Subscribe to config changes + this._fuseConfigService.config + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe((config) => { + this.fuseConfig = config; + }); + } + + /** + * On destroy + */ + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); + } +} diff --git a/src/app/layout/vertical/basic/basic.module.ts b/src/app/layout/vertical/basic/basic.module.ts new file mode 100644 index 00000000..1f7a8949 --- /dev/null +++ b/src/app/layout/vertical/basic/basic.module.ts @@ -0,0 +1,38 @@ +import { NgModule } from '@angular/core'; +import { MatSidenavModule } from '@angular/material'; + +import { FuseSidebarModule, FuseThemeOptionsModule } from '@fuse/components'; +import { FuseSharedModule } from '@fuse/shared.module'; + +import { ContentModule } from 'app/layout/blocks/content/content.module'; +import { FooterModule } from 'app/layout/blocks/footer/footer.module'; +import { NavbarModule } from 'app/layout/blocks/navbar/navbar.module'; +import { QuickPanelModule } from 'app/layout/blocks/quick-panel/quick-panel.module'; +import { ToolbarModule } from 'app/layout/blocks/toolbar/toolbar.module'; + +import { VerticalNavBasicLayoutComponent } from 'app/layout/vertical/basic/basic.component'; + +@NgModule({ + declarations: [ + VerticalNavBasicLayoutComponent + ], + imports : [ + MatSidenavModule, + + FuseSharedModule, + FuseSidebarModule, + FuseThemeOptionsModule, + + ContentModule, + FooterModule, + NavbarModule, + QuickPanelModule, + ToolbarModule + ], + exports : [ + VerticalNavBasicLayoutComponent + ] +}) +export class VerticalNavBasicLayoutModule +{ +} diff --git a/src/app/main/apps/academy/academy.module.ts b/src/app/main/apps/academy/academy.module.ts index e1935402..277cf520 100644 --- a/src/app/main/apps/academy/academy.module.ts +++ b/src/app/main/apps/academy/academy.module.ts @@ -5,22 +5,23 @@ import { MatButtonModule, MatFormFieldModule, MatIconModule, MatInputModule, Mat import { FuseSharedModule } from '@fuse/shared.module'; -import { FuseAcademyCoursesComponent } from './courses/courses.component'; -import { FuseAcademyCourseComponent } from './course/course.component'; -import { AcademyCoursesService } from './courses.service'; -import { AcademyCourseService } from './course.service'; +import { AcademyCoursesComponent } from 'app/main/apps/academy/courses/courses.component'; +import { AcademyCourseComponent } from 'app/main/apps/academy/course/course.component'; +import { AcademyCoursesService } from 'app/main/apps/academy/courses.service'; +import { AcademyCourseService } from 'app/main/apps/academy/course.service'; + const routes = [ { path : 'courses', - component: FuseAcademyCoursesComponent, + component: AcademyCoursesComponent, resolve : { academy: AcademyCoursesService } }, { path : 'courses/:courseId/:courseSlug', - component: FuseAcademyCourseComponent, + component: AcademyCourseComponent, resolve : { academy: AcademyCourseService } @@ -33,8 +34,8 @@ const routes = [ @NgModule({ declarations: [ - FuseAcademyCoursesComponent, - FuseAcademyCourseComponent + AcademyCoursesComponent, + AcademyCourseComponent ], imports : [ RouterModule.forChild(routes), @@ -53,6 +54,6 @@ const routes = [ AcademyCourseService ] }) -export class FuseAcademyModule +export class AcademyModule { } diff --git a/src/app/main/apps/academy/course.service.ts b/src/app/main/apps/academy/course.service.ts index 1d007e82..024a65cd 100644 --- a/src/app/main/apps/academy/course.service.ts +++ b/src/app/main/apps/academy/course.service.ts @@ -8,12 +8,23 @@ export class AcademyCourseService implements Resolve { onCourseChanged: BehaviorSubject = new BehaviorSubject({}); - constructor(private http: HttpClient) + /** + * Constructor + * + * @param {HttpClient} _httpClient + */ + constructor( + private _httpClient: HttpClient + ) { } + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + /** - * The Academy App Main Resolver + * Resolver * * @param {ActivatedRouteSnapshot} route * @param {RouterStateSnapshot} state @@ -34,10 +45,17 @@ export class AcademyCourseService implements Resolve }); } + /** + * Get course + * + * @param courseId + * @param courseSlug + * @returns {Promise} + */ getCourse(courseId, courseSlug): Promise { return new Promise((resolve, reject) => { - this.http.get('api/academy-course/' + courseId + '/' + courseSlug) + this._httpClient.get('api/academy-course/' + courseId + '/' + courseSlug) .subscribe((response: any) => { this.onCourseChanged.next(response); resolve(response); diff --git a/src/app/main/apps/academy/course/course.component.ts b/src/app/main/apps/academy/course/course.component.ts index ab249eae..a3970fa5 100644 --- a/src/app/main/apps/academy/course/course.component.ts +++ b/src/app/main/apps/academy/course/course.component.ts @@ -1,71 +1,114 @@ import { AfterViewInit, ChangeDetectorRef, Component, OnDestroy, OnInit, QueryList, ViewChildren, ViewEncapsulation } from '@angular/core'; -import { Subscription } from 'rxjs'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import { FusePerfectScrollbarDirective } from '@fuse/directives/fuse-perfect-scrollbar/fuse-perfect-scrollbar.directive'; import { fuseAnimations } from '@fuse/animations'; -import { AcademyCourseService } from '../course.service'; +import { AcademyCourseService } from 'app/main/apps/academy/course.service'; @Component({ - selector : 'fuse-academy-course', + selector : 'academy-course', templateUrl : './course.component.html', styleUrls : ['./course.component.scss'], encapsulation: ViewEncapsulation.None, animations : fuseAnimations }) -export class FuseAcademyCourseComponent implements OnInit, OnDestroy, AfterViewInit +export class AcademyCourseComponent implements OnInit, OnDestroy, AfterViewInit { + animationDirection: 'left' | 'right' | 'none'; course: any; - courseSubscription: Subscription; - currentStep = 0; - courseStepContent; - animationDirection: 'left' | 'right' | 'none' = 'none'; - @ViewChildren(FusePerfectScrollbarDirective) fuseScrollbarDirectives: QueryList; + courseStepContent: any; + currentStep: number; + @ViewChildren(FusePerfectScrollbarDirective) + fuseScrollbarDirectives: QueryList; + + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {AcademyCourseService} _academyCourseService + * @param {ChangeDetectorRef} _changeDetectorRef + */ constructor( - private courseService: AcademyCourseService, - private changeDetectorRef: ChangeDetectorRef + private _academyCourseService: AcademyCourseService, + private _changeDetectorRef: ChangeDetectorRef ) { + // Set the defaults + this.animationDirection = 'none'; + this.currentStep = 0; + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { // Subscribe to courses - this.courseSubscription = - this.courseService.onCourseChanged - .subscribe(course => { - this.course = course; - }); + this._academyCourseService.onCourseChanged + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(course => { + this.course = course; + }); } - ngAfterViewInit() + /** + * After view init + */ + ngAfterViewInit(): void { this.courseStepContent = this.fuseScrollbarDirectives.find((fuseScrollbarDirective) => { - return fuseScrollbarDirective.element.nativeElement.id === 'course-step-content'; + return fuseScrollbarDirective.elementRef.nativeElement.id === 'course-step-content'; }); } - ngOnDestroy() + /** + * On destroy + */ + ngOnDestroy(): void { - this.courseSubscription.unsubscribe(); + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); } - gotoStep(step) + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Go to step + * + * @param step + */ + gotoStep(step): void { // Decide the animation direction this.animationDirection = this.currentStep < step ? 'left' : 'right'; // Run change detection so the change // in the animation direction registered - this.changeDetectorRef.detectChanges(); + this._changeDetectorRef.detectChanges(); // Set the current step this.currentStep = step; } - gotoNextStep() + /** + * Go to next step + */ + gotoNextStep(): void { if ( this.currentStep === this.course.totalSteps - 1 ) { @@ -77,13 +120,16 @@ export class FuseAcademyCourseComponent implements OnInit, OnDestroy, AfterViewI // Run change detection so the change // in the animation direction registered - this.changeDetectorRef.detectChanges(); + this._changeDetectorRef.detectChanges(); // Increase the current step this.currentStep++; } - gotoPreviousStep() + /** + * Go to previous step + */ + gotoPreviousStep(): void { if ( this.currentStep === 0 ) { @@ -95,7 +141,7 @@ export class FuseAcademyCourseComponent implements OnInit, OnDestroy, AfterViewI // Run change detection so the change // in the animation direction registered - this.changeDetectorRef.detectChanges(); + this._changeDetectorRef.detectChanges(); // Decrease the current step this.currentStep--; diff --git a/src/app/main/apps/academy/courses.service.ts b/src/app/main/apps/academy/courses.service.ts index 59356eca..5f8776cb 100644 --- a/src/app/main/apps/academy/courses.service.ts +++ b/src/app/main/apps/academy/courses.service.ts @@ -9,12 +9,23 @@ export class AcademyCoursesService implements Resolve onCategoriesChanged: BehaviorSubject = new BehaviorSubject({}); onCoursesChanged: BehaviorSubject = new BehaviorSubject({}); - constructor(private http: HttpClient) + /** + * Constructor + * + * @param {HttpClient} _httpClient + */ + constructor( + private _httpClient: HttpClient + ) { } + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + /** - * The Academy App Main Resolver + * Resolver * * @param {ActivatedRouteSnapshot} route * @param {RouterStateSnapshot} state @@ -36,10 +47,15 @@ export class AcademyCoursesService implements Resolve }); } + /** + * Get categories + * + * @returns {Promise} + */ getCategories(): Promise { return new Promise((resolve, reject) => { - this.http.get('api/academy-categories') + this._httpClient.get('api/academy-categories') .subscribe((response: any) => { this.onCategoriesChanged.next(response); resolve(response); @@ -47,10 +63,15 @@ export class AcademyCoursesService implements Resolve }); } + /** + * Get courses + * + * @returns {Promise} + */ getCourses(): Promise { return new Promise((resolve, reject) => { - this.http.get('api/academy-courses') + this._httpClient.get('api/academy-courses') .subscribe((response: any) => { this.onCoursesChanged.next(response); resolve(response); diff --git a/src/app/main/apps/academy/courses/courses.component.ts b/src/app/main/apps/academy/courses/courses.component.ts index 58b82cfb..defd378d 100644 --- a/src/app/main/apps/academy/courses/courses.component.ts +++ b/src/app/main/apps/academy/courses/courses.component.ts @@ -1,59 +1,88 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; -import { Subscription } from 'rxjs'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import { fuseAnimations } from '@fuse/animations'; -import { AcademyCoursesService } from '../courses.service'; +import { AcademyCoursesService } from 'app/main/apps/academy/courses.service'; @Component({ - selector : 'fuse-academy-courses', + selector : 'academy-courses', templateUrl: './courses.component.html', styleUrls : ['./courses.component.scss'], - animations : fuseAnimations + animations : fuseAnimations }) -export class FuseAcademyCoursesComponent implements OnInit, OnDestroy +export class AcademyCoursesComponent implements OnInit, OnDestroy { categories: any[]; courses: any[]; coursesFilteredByCategory: any[]; filteredCourses: any[]; + currentCategory: string; + searchTerm: string; - categoriesSubscription: Subscription; - coursesSubscription: Subscription; - - currentCategory = 'all'; - searchTerm = ''; + // Private + private _unsubscribeAll: Subject; + /** + * Constructor + * + * @param {AcademyCoursesService} _academyCoursesService + */ constructor( - private coursesService: AcademyCoursesService + private _academyCoursesService: AcademyCoursesService ) { + // Set the defaults + this.currentCategory = 'all'; + this.searchTerm = ''; + + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { // Subscribe to categories - this.categoriesSubscription = - this.coursesService.onCategoriesChanged - .subscribe(categories => { - this.categories = categories; - }); + this._academyCoursesService.onCategoriesChanged + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(categories => { + this.categories = categories; + }); // Subscribe to courses - this.coursesSubscription = - this.coursesService.onCoursesChanged - .subscribe(courses => { - this.filteredCourses = this.coursesFilteredByCategory = this.courses = courses; - }); + this._academyCoursesService.onCoursesChanged + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(courses => { + this.filteredCourses = this.coursesFilteredByCategory = this.courses = courses; + }); } - ngOnDestroy() + /** + * On destroy + */ + ngOnDestroy(): void { - this.categoriesSubscription.unsubscribe(); - this.coursesSubscription.unsubscribe(); + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); } - filterCoursesByCategory() + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Filter courses by category + */ + filterCoursesByCategory(): void { // Filter if ( this.currentCategory === 'all' ) @@ -75,7 +104,10 @@ export class FuseAcademyCoursesComponent implements OnInit, OnDestroy this.filterCoursesByTerm(); } - filterCoursesByTerm() + /** + * Filter courses by term + */ + filterCoursesByTerm(): void { const searchTerm = this.searchTerm.toLowerCase(); diff --git a/src/app/main/apps/apps.module.ts b/src/app/main/apps/apps.module.ts index 63671052..98a60a34 100644 --- a/src/app/main/apps/apps.module.ts +++ b/src/app/main/apps/apps.module.ts @@ -1,18 +1,16 @@ import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; -import { FuseAngularMaterialModule } from '../components/angular-material/angular-material.module'; - import { FuseSharedModule } from '@fuse/shared.module'; const routes = [ { path : 'dashboards/analytics', - loadChildren: './dashboards/analytics/analytics.module#FuseAnalyticsDashboardModule' + loadChildren: './dashboards/analytics/analytics.module#AnalyticsDashboardModule' }, { path : 'dashboards/project', - loadChildren: './dashboards/project/project.module#FuseProjectDashboardModule' + loadChildren: './dashboards/project/project.module#ProjectDashboardModule' }, { path : 'mail', @@ -24,19 +22,19 @@ const routes = [ }, { path : 'chat', - loadChildren: './chat/chat.module#FuseChatModule' + loadChildren: './chat/chat.module#ChatModule' }, { path : 'calendar', - loadChildren: './calendar/calendar.module#FuseCalendarModule' + loadChildren: './calendar/calendar.module#CalendarModule' }, { path : 'e-commerce', - loadChildren: './e-commerce/e-commerce.module#FuseEcommerceModule' + loadChildren: './e-commerce/e-commerce.module#EcommerceModule' }, { path : 'academy', - loadChildren: './academy/academy.module#FuseAcademyModule' + loadChildren: './academy/academy.module#AcademyModule' }, { path : 'todo', @@ -44,11 +42,11 @@ const routes = [ }, { path : 'file-manager', - loadChildren: './file-manager/file-manager.module#FuseFileManagerModule' + loadChildren: './file-manager/file-manager.module#FileManagerModule' }, { path : 'contacts', - loadChildren: './contacts/contacts.module#FuseContactsModule' + loadChildren: './contacts/contacts.module#ContactsModule' }, { path : 'scrumboard', @@ -58,12 +56,10 @@ const routes = [ @NgModule({ imports : [ - FuseSharedModule, RouterModule.forChild(routes), - FuseAngularMaterialModule - ], - declarations: [] + FuseSharedModule + ] }) -export class FuseAppsModule +export class AppsModule { } diff --git a/src/app/main/apps/calendar/calendar.component.ts b/src/app/main/apps/calendar/calendar.component.ts index 998bab05..94074ddd 100644 --- a/src/app/main/apps/calendar/calendar.component.ts +++ b/src/app/main/apps/calendar/calendar.component.ts @@ -8,34 +8,35 @@ import { CalendarEvent, CalendarEventAction, CalendarEventTimesChangedEvent, Cal import { FuseConfirmDialogComponent } from '@fuse/components/confirm-dialog/confirm-dialog.component'; import { fuseAnimations } from '@fuse/animations'; -import { FuseCalendarEventFormDialogComponent } from './event-form/event-form.component'; -import { CalendarEventModel } from './event.model'; -import { CalendarService } from './calendar.service'; +import { CalendarService } from 'app/main/apps/calendar/calendar.service'; +import { CalendarEventModel } from 'app/main/apps/calendar/event.model'; +import { CalendarEventFormDialogComponent } from 'app/main/apps/calendar/event-form/event-form.component'; @Component({ - selector : 'fuse-calendar', + selector : 'calendar', templateUrl : './calendar.component.html', styleUrls : ['./calendar.component.scss'], encapsulation: ViewEncapsulation.None, animations : fuseAnimations }) -export class FuseCalendarComponent implements OnInit +export class CalendarComponent implements OnInit { + actions: CalendarEventAction[]; + activeDayIsOpen: boolean; + confirmDialogRef: MatDialogRef; + dialogRef: any; + events: CalendarEvent[]; + refresh: Subject = new Subject(); + selectedDay: any; view: string; viewDate: Date; - events: CalendarEvent[]; - public actions: CalendarEventAction[]; - activeDayIsOpen: boolean; - refresh: Subject = new Subject(); - dialogRef: any; - confirmDialogRef: MatDialogRef; - selectedDay: any; constructor( - public dialog: MatDialog, - public calendarService: CalendarService + private _matDialog: MatDialog, + private _calendarService: CalendarService ) { + // Set the defaults this.view = 'month'; this.viewDate = new Date(); this.activeDayIsOpen = true; @@ -62,29 +63,41 @@ export class FuseCalendarComponent implements OnInit this.setEvents(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { /** * Watch re-render-refresh for updating db */ this.refresh.subscribe(updateDB => { - // console.warn('REFRESH'); if ( updateDB ) { - // console.warn('UPDATE DB'); - this.calendarService.updateEvents(this.events); + this._calendarService.updateEvents(this.events); } }); - this.calendarService.onEventsUpdated.subscribe(events => { + this._calendarService.onEventsUpdated.subscribe(events => { this.setEvents(); this.refresh.next(); }); } - setEvents() + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Set events + */ + setEvents(): void { - this.events = this.calendarService.events.map(item => { + this.events = this._calendarService.events.map(item => { item.actions = this.actions; return new CalendarEventModel(item); }); @@ -92,10 +105,11 @@ export class FuseCalendarComponent implements OnInit /** * Before View Renderer + * * @param {any} header * @param {any} body */ - beforeMonthViewRender({header, body}) + beforeMonthViewRender({header, body}): void { // console.info('beforeMonthViewRender'); /** @@ -118,6 +132,7 @@ export class FuseCalendarComponent implements OnInit /** * Day clicked + * * @param {MonthViewDay} day */ dayClicked(day: CalendarMonthViewDay): void @@ -144,6 +159,7 @@ export class FuseCalendarComponent implements OnInit /** * Event times changed * Event dropped or resized + * * @param {CalendarEvent} event * @param {Date} newStart * @param {Date} newEnd @@ -158,11 +174,12 @@ export class FuseCalendarComponent implements OnInit /** * Delete Event + * * @param event */ - deleteEvent(event) + deleteEvent(event): void { - this.confirmDialogRef = this.dialog.open(FuseConfirmDialogComponent, { + this.confirmDialogRef = this._matDialog.open(FuseConfirmDialogComponent, { disableClose: false }); @@ -182,14 +199,15 @@ export class FuseCalendarComponent implements OnInit /** * Edit Event + * * @param {string} action * @param {CalendarEvent} event */ - editEvent(action: string, event: CalendarEvent) + editEvent(action: string, event: CalendarEvent): void { const eventIndex = this.events.indexOf(event); - this.dialogRef = this.dialog.open(FuseCalendarEventFormDialogComponent, { + this.dialogRef = this._matDialog.open(CalendarEventFormDialogComponent, { panelClass: 'event-form-dialog', data : { event : event, @@ -233,7 +251,7 @@ export class FuseCalendarComponent implements OnInit */ addEvent(): void { - this.dialogRef = this.dialog.open(FuseCalendarEventFormDialogComponent, { + this.dialogRef = this._matDialog.open(CalendarEventFormDialogComponent, { panelClass: 'event-form-dialog', data : { action: 'new', diff --git a/src/app/main/apps/calendar/calendar.module.ts b/src/app/main/apps/calendar/calendar.module.ts index 769f78d5..e72231d6 100644 --- a/src/app/main/apps/calendar/calendar.module.ts +++ b/src/app/main/apps/calendar/calendar.module.ts @@ -1,22 +1,20 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; - import { MatButtonModule, MatDatepickerModule, MatFormFieldModule, MatIconModule, MatInputModule, MatSlideToggleModule, MatToolbarModule } from '@angular/material'; - -import { CalendarModule } from 'angular-calendar'; import { ColorPickerModule } from 'ngx-color-picker'; +import { CalendarModule as AngularCalendarModule } from 'angular-calendar'; import { FuseSharedModule } from '@fuse/shared.module'; import { FuseConfirmDialogModule } from '@fuse/components'; -import { CalendarService } from './calendar.service'; -import { FuseCalendarComponent } from './calendar.component'; -import { FuseCalendarEventFormDialogComponent } from './event-form/event-form.component'; +import { CalendarComponent } from 'app/main/apps/calendar/calendar.component'; +import { CalendarService } from 'app/main/apps/calendar/calendar.service'; +import { CalendarEventFormDialogComponent } from 'app/main/apps/calendar/event-form/event-form.component'; const routes: Routes = [ { path : '**', - component: FuseCalendarComponent, + component: CalendarComponent, children : [], resolve : { chat: CalendarService @@ -26,8 +24,8 @@ const routes: Routes = [ @NgModule({ declarations : [ - FuseCalendarComponent, - FuseCalendarEventFormDialogComponent + CalendarComponent, + CalendarEventFormDialogComponent ], imports : [ RouterModule.forChild(routes), @@ -40,7 +38,7 @@ const routes: Routes = [ MatSlideToggleModule, MatToolbarModule, - CalendarModule.forRoot(), + AngularCalendarModule.forRoot(), ColorPickerModule, FuseSharedModule, @@ -49,8 +47,10 @@ const routes: Routes = [ providers : [ CalendarService ], - entryComponents: [FuseCalendarEventFormDialogComponent] + entryComponents: [ + CalendarEventFormDialogComponent + ] }) -export class FuseCalendarModule +export class CalendarModule { } diff --git a/src/app/main/apps/calendar/calendar.service.ts b/src/app/main/apps/calendar/calendar.service.ts index bdd8e4d4..3d0554c3 100644 --- a/src/app/main/apps/calendar/calendar.service.ts +++ b/src/app/main/apps/calendar/calendar.service.ts @@ -9,11 +9,29 @@ export class CalendarService implements Resolve events: any; onEventsUpdated = new Subject(); - constructor(private http: HttpClient) + /** + * Constructor + * + * @param {HttpClient} _httpClient + */ + constructor( + private _httpClient: HttpClient + ) { } + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Resolver + * + * @param {ActivatedRouteSnapshot} route + * @param {RouterStateSnapshot} state + * @returns {Observable | Promise | any} + */ resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | Promise | any { return new Promise((resolve, reject) => { @@ -28,11 +46,16 @@ export class CalendarService implements Resolve }); } - getEvents() + /** + * Get events + * + * @returns {Promise} + */ + getEvents(): Promise { return new Promise((resolve, reject) => { - this.http.get('api/calendar/events') + this._httpClient.get('api/calendar/events') .subscribe((response: any) => { this.events = response.data; this.onEventsUpdated.next(this.events); @@ -41,10 +64,16 @@ export class CalendarService implements Resolve }); } - updateEvents(events) + /** + * Update events + * + * @param events + * @returns {Promise} + */ + updateEvents(events): Promise { return new Promise((resolve, reject) => { - this.http.post('api/calendar/events', { + this._httpClient.post('api/calendar/events', { id : 'events', data: [...events] }) diff --git a/src/app/main/apps/calendar/event-form/event-form.component.ts b/src/app/main/apps/calendar/event-form/event-form.component.ts index 0730e7b9..95c4c181 100644 --- a/src/app/main/apps/calendar/event-form/event-form.component.ts +++ b/src/app/main/apps/calendar/event-form/event-form.component.ts @@ -1,11 +1,11 @@ import { Component, Inject, ViewEncapsulation } from '@angular/core'; import { FormBuilder, FormControl, FormGroup } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material'; +import { CalendarEvent } from 'angular-calendar'; import { MatColors } from '@fuse/mat-colors'; -import { CalendarEvent } from 'angular-calendar'; -import { CalendarEventModel } from '../event.model'; +import { CalendarEventModel } from 'app/main/apps/calendar/event.model'; @Component({ selector : 'fuse-calendar-event-form-dialog', @@ -14,22 +14,29 @@ import { CalendarEventModel } from '../event.model'; encapsulation: ViewEncapsulation.None }) -export class FuseCalendarEventFormDialogComponent +export class CalendarEventFormDialogComponent { - event: CalendarEvent; - dialogTitle: string; - eventForm: FormGroup; action: string; + event: CalendarEvent; + eventForm: FormGroup; + dialogTitle: string; presetColors = MatColors.presets; + /** + * Constructor + * + * @param {MatDialogRef} dialogRef + * @param _data + * @param {FormBuilder} _formBuilder + */ constructor( - public dialogRef: MatDialogRef, - @Inject(MAT_DIALOG_DATA) private data: any, - private formBuilder: FormBuilder + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) private _data: any, + private _formBuilder: FormBuilder ) { - this.event = data.event; - this.action = data.action; + this.event = _data.event; + this.action = _data.action; if ( this.action === 'edit' ) { @@ -39,27 +46,36 @@ export class FuseCalendarEventFormDialogComponent { this.dialogTitle = 'New Event'; this.event = new CalendarEventModel({ - start: data.date, - end : data.date + start: _data.date, + end : _data.date }); } this.eventForm = this.createEventForm(); } - createEventForm() + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Create the event form + * + * @returns {FormGroup} + */ + createEventForm(): FormGroup { return new FormGroup({ title : new FormControl(this.event.title), start : new FormControl(this.event.start), end : new FormControl(this.event.end), allDay: new FormControl(this.event.allDay), - color : this.formBuilder.group({ + color : this._formBuilder.group({ primary : new FormControl(this.event.color.primary), secondary: new FormControl(this.event.color.secondary) }), meta : - this.formBuilder.group({ + this._formBuilder.group({ location: new FormControl(this.event.meta.location), notes : new FormControl(this.event.meta.notes) }) diff --git a/src/app/main/apps/calendar/event.model.ts b/src/app/main/apps/calendar/event.model.ts index 6e121f2e..4fe605e6 100644 --- a/src/app/main/apps/calendar/event.model.ts +++ b/src/app/main/apps/calendar/event.model.ts @@ -23,6 +23,11 @@ export class CalendarEventModel notes: string }; + /** + * Constructor + * + * @param data + */ constructor(data?) { data = data || {}; diff --git a/src/app/main/apps/chat/chat-start/chat-start.component.ts b/src/app/main/apps/chat/chat-start/chat-start.component.ts index 2651c617..adc689ea 100644 --- a/src/app/main/apps/chat/chat-start/chat-start.component.ts +++ b/src/app/main/apps/chat/chat-start/chat-start.component.ts @@ -3,12 +3,12 @@ import { Component } from '@angular/core'; import { fuseAnimations } from '@fuse/animations'; @Component({ - selector : 'fuse-chat-start', + selector : 'chat-start', templateUrl: './chat-start.component.html', styleUrls : ['./chat-start.component.scss'], animations : fuseAnimations }) -export class FuseChatStartComponent +export class ChatStartComponent { constructor() { diff --git a/src/app/main/apps/chat/chat-view/chat-view.component.html b/src/app/main/apps/chat/chat-view/chat-view.component.html index 62e1e32b..747600d3 100644 --- a/src/app/main/apps/chat/chat-view/chat-view.component.html +++ b/src/app/main/apps/chat/chat-view/chat-view.component.html @@ -87,7 +87,7 @@ - diff --git a/src/app/main/apps/chat/chat-view/chat-view.component.scss b/src/app/main/apps/chat/chat-view/chat-view.component.scss index 362b701d..3d8efac0 100644 --- a/src/app/main/apps/chat/chat-view/chat-view.component.scss +++ b/src/app/main/apps/chat/chat-view/chat-view.component.scss @@ -99,7 +99,7 @@ } .chat-footer { - min-height: 64px; + min-height: 72px; max-height: 96px; background-color: #F3F4F5; color: rgba(0, 0, 0, 0.87); @@ -116,6 +116,7 @@ overflow: auto; max-height: 80px; transition: height 200ms ease; + &.grow { height: 80px; } diff --git a/src/app/main/apps/chat/chat-view/chat-view.component.ts b/src/app/main/apps/chat/chat-view/chat-view.component.ts index bf687945..4f40e8fe 100644 --- a/src/app/main/apps/chat/chat-view/chat-view.component.ts +++ b/src/app/main/apps/chat/chat-view/chat-view.component.ts @@ -1,16 +1,18 @@ -import { AfterViewInit, Component, OnInit, ViewChild, ViewChildren } from '@angular/core'; +import { AfterViewInit, Component, OnDestroy, OnInit, ViewChild, ViewChildren } from '@angular/core'; import { NgForm } from '@angular/forms'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import { FusePerfectScrollbarDirective } from '@fuse/directives/fuse-perfect-scrollbar/fuse-perfect-scrollbar.directive'; -import { ChatService } from '../chat.service'; +import { ChatService } from 'app/main/apps/chat/chat.service'; @Component({ - selector : 'fuse-chat-view', + selector : 'chat-view', templateUrl: './chat-view.component.html', styleUrls : ['./chat-view.component.scss'] }) -export class FuseChatViewComponent implements OnInit, AfterViewInit +export class ChatViewComponent implements OnInit, OnDestroy, AfterViewInit { user: any; chat: any; @@ -18,18 +20,44 @@ export class FuseChatViewComponent implements OnInit, AfterViewInit contact: any; replyInput: any; selectedChat: any; - @ViewChild(FusePerfectScrollbarDirective) directiveScroll: FusePerfectScrollbarDirective; - @ViewChildren('replyInput') replyInputField; - @ViewChild('replyForm') replyForm: NgForm; - constructor(private chatService: ChatService) + @ViewChild(FusePerfectScrollbarDirective) + directiveScroll: FusePerfectScrollbarDirective; + + @ViewChildren('replyInput') + replyInputField; + + @ViewChild('replyForm') + replyForm: NgForm; + + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {ChatService} _chatService + */ + constructor( + private _chatService: ChatService + ) { + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { - this.user = this.chatService.user; - this.chatService.onChatSelected + this.user = this._chatService.user; + this._chatService.onChatSelected + .pipe(takeUntil(this._unsubscribeAll)) .subscribe(chatData => { if ( chatData ) { @@ -41,18 +69,41 @@ export class FuseChatViewComponent implements OnInit, AfterViewInit }); } - ngAfterViewInit() + /** + * After view init + */ + ngAfterViewInit(): void { this.replyInput = this.replyInputField.first.nativeElement; this.readyToReply(); } - selectContact() + /** + * On destroy + */ + ngOnDestroy(): void { - this.chatService.selectContact(this.contact); + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); } - readyToReply() + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Select contact + */ + selectContact(): void + { + this._chatService.selectContact(this.contact); + } + + /** + * Ready to reply + */ + readyToReply(): void { setTimeout(() => { this.replyForm.reset(); @@ -62,14 +113,22 @@ export class FuseChatViewComponent implements OnInit, AfterViewInit } - focusReplyInput() + /** + * Focus to the reply input + */ + focusReplyInput(): void { setTimeout(() => { this.replyInput.focus(); }); } - scrollToBottom(speed?: number) + /** + * Scroll to the bottom + * + * @param {number} speed + */ + scrollToBottom(speed?: number): void { speed = speed || 400; if ( this.directiveScroll ) @@ -82,7 +141,10 @@ export class FuseChatViewComponent implements OnInit, AfterViewInit } } - reply(event) + /** + * Reply + */ + reply(): void { // Message const message = { @@ -95,9 +157,8 @@ export class FuseChatViewComponent implements OnInit, AfterViewInit this.dialog.push(message); // Update the server - this.chatService.updateDialog(this.selectedChat.chatId, this.dialog).then(response => { + this._chatService.updateDialog(this.selectedChat.chatId, this.dialog).then(response => { this.readyToReply(); }); - } } diff --git a/src/app/main/apps/chat/chat.component.html b/src/app/main/apps/chat/chat.component.html index 2a903f8f..6967d337 100644 --- a/src/app/main/apps/chat/chat.component.html +++ b/src/app/main/apps/chat/chat.component.html @@ -15,20 +15,20 @@ - + - + - + - + diff --git a/src/app/main/apps/chat/chat.component.ts b/src/app/main/apps/chat/chat.component.ts index 31005479..fba6d3cb 100644 --- a/src/app/main/apps/chat/chat.component.ts +++ b/src/app/main/apps/chat/chat.component.ts @@ -1,30 +1,61 @@ -import { Component, OnInit, ViewEncapsulation } from '@angular/core'; +import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import { fuseAnimations } from '@fuse/animations'; -import { ChatService } from './chat.service'; +import { ChatService } from 'app/main/apps/chat/chat.service'; @Component({ - selector : 'fuse-chat', + selector : 'chat', templateUrl : './chat.component.html', styleUrls : ['./chat.component.scss'], encapsulation: ViewEncapsulation.None, animations : fuseAnimations }) -export class FuseChatComponent implements OnInit +export class ChatComponent implements OnInit, OnDestroy { selectedChat: any; - constructor(private chatService: ChatService) + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {ChatService} _chatService + */ + constructor( + private _chatService: ChatService + ) { + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { - this.chatService.onChatSelected + this._chatService.onChatSelected + .pipe(takeUntil(this._unsubscribeAll)) .subscribe(chatData => { this.selectedChat = chatData; }); } + /** + * On destroy + */ + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); + } } diff --git a/src/app/main/apps/chat/chat.module.ts b/src/app/main/apps/chat/chat.module.ts index 2b80c69b..a54b46e5 100644 --- a/src/app/main/apps/chat/chat.module.ts +++ b/src/app/main/apps/chat/chat.module.ts @@ -5,20 +5,20 @@ import { MatButtonModule, MatCardModule, MatFormFieldModule, MatIconModule, MatI import { FuseSharedModule } from '@fuse/shared.module'; -import { ChatService } from './chat.service'; -import { FuseChatComponent } from './chat.component'; -import { FuseChatViewComponent } from './chat-view/chat-view.component'; -import { FuseChatStartComponent } from './chat-start/chat-start.component'; -import { FuseChatChatsSidenavComponent } from './sidenavs/left/chats/chats.component'; -import { FuseChatUserSidenavComponent } from './sidenavs/left/user/user.component'; -import { FuseChatLeftSidenavComponent } from './sidenavs/left/left.component'; -import { FuseChatRightSidenavComponent } from './sidenavs/right/right.component'; -import { FuseChatContactSidenavComponent } from './sidenavs/right/contact/contact.component'; +import { ChatService } from 'app/main/apps/chat/chat.service'; +import { ChatComponent } from 'app/main/apps/chat/chat.component'; +import { ChatStartComponent } from 'app/main/apps/chat/chat-start/chat-start.component'; +import { ChatViewComponent } from 'app/main/apps/chat/chat-view/chat-view.component'; +import { ChatChatsSidenavComponent } from 'app/main/apps/chat/sidenavs/left/chats/chats.component'; +import { ChatUserSidenavComponent } from 'app/main/apps/chat/sidenavs/left/user/user.component'; +import { ChatLeftSidenavComponent } from 'app/main/apps/chat/sidenavs/left/left.component'; +import { ChatRightSidenavComponent } from 'app/main/apps/chat/sidenavs/right/right.component'; +import { ChatContactSidenavComponent } from 'app/main/apps/chat/sidenavs/right/contact/contact.component'; const routes: Routes = [ { path : '**', - component: FuseChatComponent, + component: ChatComponent, children : [], resolve : { chat: ChatService @@ -28,14 +28,14 @@ const routes: Routes = [ @NgModule({ declarations: [ - FuseChatComponent, - FuseChatViewComponent, - FuseChatStartComponent, - FuseChatChatsSidenavComponent, - FuseChatUserSidenavComponent, - FuseChatLeftSidenavComponent, - FuseChatRightSidenavComponent, - FuseChatContactSidenavComponent + ChatComponent, + ChatViewComponent, + ChatStartComponent, + ChatChatsSidenavComponent, + ChatUserSidenavComponent, + ChatLeftSidenavComponent, + ChatRightSidenavComponent, + ChatContactSidenavComponent ], imports : [ RouterModule.forChild(routes), @@ -57,6 +57,6 @@ const routes: Routes = [ ChatService ] }) -export class FuseChatModule +export class ChatModule { } diff --git a/src/app/main/apps/chat/sidenavs/left/chats/chats.component.ts b/src/app/main/apps/chat/sidenavs/left/chats/chats.component.ts index d2261bfd..98a8c3a6 100644 --- a/src/app/main/apps/chat/sidenavs/left/chats/chats.component.ts +++ b/src/app/main/apps/chat/sidenavs/left/chats/chats.component.ts @@ -1,72 +1,132 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; import { ObservableMedia } from '@angular/flex-layout'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import { fuseAnimations } from '@fuse/animations'; import { FuseMatSidenavHelperService } from '@fuse/directives/fuse-mat-sidenav/fuse-mat-sidenav.service'; -import { ChatService } from '../../../chat.service'; +import { ChatService } from 'app/main/apps/chat/chat.service'; @Component({ - selector : 'fuse-chat-chats-sidenav', + selector : 'chat-chats-sidenav', templateUrl: './chats.component.html', styleUrls : ['./chats.component.scss'], animations : fuseAnimations }) -export class FuseChatChatsSidenavComponent implements OnInit +export class ChatChatsSidenavComponent implements OnInit, OnDestroy { - user: any; chats: any[]; - contacts: any[]; chatSearch: any; - searchText = ''; + contacts: any[]; + searchText: string; + user: any; + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {ChatService} _chatService + * @param {FuseMatSidenavHelperService} _fuseMatSidenavHelperService + * @param {ObservableMedia} _observableMedia + */ constructor( - private chatService: ChatService, - private fuseMatSidenavService: FuseMatSidenavHelperService, - public media: ObservableMedia + private _chatService: ChatService, + private _fuseMatSidenavHelperService: FuseMatSidenavHelperService, + public _observableMedia: ObservableMedia ) { + // Set the defaults this.chatSearch = { name: '' }; + this.searchText = ''; + + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { - this.user = this.chatService.user; - this.chats = this.chatService.chats; - this.contacts = this.chatService.contacts; + this.user = this._chatService.user; + this.chats = this._chatService.chats; + this.contacts = this._chatService.contacts; - this.chatService.onChatsUpdated.subscribe(updatedChats => { - this.chats = updatedChats; - }); + this._chatService.onChatsUpdated + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(updatedChats => { + this.chats = updatedChats; + }); - this.chatService.onUserUpdated.subscribe(updatedUser => { - this.user = updatedUser; - }); + this._chatService.onUserUpdated + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(updatedUser => { + this.user = updatedUser; + }); } - getChat(contact) + /** + * On destroy + */ + ngOnDestroy(): void { - this.chatService.getChat(contact); + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); + } - if ( !this.media.isActive('gt-md') ) + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Get chat + * + * @param contact + */ + getChat(contact): void + { + this._chatService.getChat(contact); + + if ( !this._observableMedia.isActive('gt-md') ) { - this.fuseMatSidenavService.getSidenav('chat-left-sidenav').toggle(); + this._fuseMatSidenavHelperService.getSidenav('chat-left-sidenav').toggle(); } } - setUserStatus(status) + /** + * Set user status + * + * @param status + */ + setUserStatus(status): void { - this.chatService.setUserStatus(status); + this._chatService.setUserStatus(status); } - changeLeftSidenavView(view) + /** + * Change left sidenav view + * + * @param view + */ + changeLeftSidenavView(view): void { - this.chatService.onLeftSidenavViewChanged.next(view); + this._chatService.onLeftSidenavViewChanged.next(view); } - logout() + /** + * Logout + */ + logout(): void { console.log('logout triggered'); } diff --git a/src/app/main/apps/chat/sidenavs/left/left.component.html b/src/app/main/apps/chat/sidenavs/left/left.component.html index 5595a45f..3c23e7eb 100644 --- a/src/app/main/apps/chat/sidenavs/left/left.component.html +++ b/src/app/main/apps/chat/sidenavs/left/left.component.html @@ -1,11 +1,11 @@
- - + + - - + +
diff --git a/src/app/main/apps/chat/sidenavs/left/left.component.ts b/src/app/main/apps/chat/sidenavs/left/left.component.ts index 0854b6b3..a3f988a3 100644 --- a/src/app/main/apps/chat/sidenavs/left/left.component.ts +++ b/src/app/main/apps/chat/sidenavs/left/left.component.ts @@ -1,29 +1,63 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import { fuseAnimations } from '@fuse/animations'; -import { ChatService } from '../../chat.service'; +import { ChatService } from 'app/main/apps/chat/chat.service'; @Component({ - selector : 'fuse-chat-left-sidenav', + selector : 'chat-left-sidenav', templateUrl: './left.component.html', styleUrls : ['./left.component.scss'], animations : fuseAnimations }) -export class FuseChatLeftSidenavComponent implements OnInit +export class ChatLeftSidenavComponent implements OnInit, OnDestroy { view: string; - constructor(private chatService: ChatService) + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {ChatService} _chatService + */ + constructor( + private _chatService: ChatService + ) { + // Set the defaults this.view = 'chats'; + + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { - this.chatService.onLeftSidenavViewChanged.subscribe(view => { - this.view = view; - }); + this._chatService.onLeftSidenavViewChanged + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(view => { + this.view = view; + }); } + /** + * On destroy + */ + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); + } } diff --git a/src/app/main/apps/chat/sidenavs/left/user/user.component.ts b/src/app/main/apps/chat/sidenavs/left/user/user.component.ts index 7250c2b8..8cbf54e1 100644 --- a/src/app/main/apps/chat/sidenavs/left/user/user.component.ts +++ b/src/app/main/apps/chat/sidenavs/left/user/user.component.ts @@ -1,48 +1,87 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { FormControl, FormGroup } from '@angular/forms'; -import { debounceTime, distinctUntilChanged } from 'rxjs/operators'; +import { Subject } from 'rxjs'; +import { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators'; -import { ChatService } from '../../../chat.service'; +import { ChatService } from 'app/main/apps/chat/chat.service'; @Component({ - selector : 'fuse-chat-user-sidenav', + selector : 'chat-user-sidenav', templateUrl: './user.component.html', styleUrls : ['./user.component.scss'] }) -export class FuseChatUserSidenavComponent implements OnInit, OnDestroy +export class ChatUserSidenavComponent implements OnInit, OnDestroy { user: any; - onFormChange: any; userForm: FormGroup; - constructor(private chatService: ChatService) + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {ChatService} _chatService + */ + constructor( + private _chatService: ChatService + ) { - this.user = this.chatService.user; + // Set the private defaults + this._unsubscribeAll = new Subject(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void + { + this.user = this._chatService.user; + this.userForm = new FormGroup({ mood : new FormControl(this.user.mood), status: new FormControl(this.user.status) }); + + this.userForm.valueChanges + .pipe( + takeUntil(this._unsubscribeAll), + debounceTime(500), + distinctUntilChanged() + ) + .subscribe(data => { + this.user.mood = data.mood; + this.user.status = data.status; + this._chatService.updateUserData(this.user); + }); } - ngOnInit() + /** + * On destroy + */ + ngOnDestroy(): void { - this.onFormChange = this.userForm.valueChanges.pipe( - debounceTime(500), - distinctUntilChanged() - ).subscribe(data => { - this.user.mood = data.mood; - this.user.status = data.status; - this.chatService.updateUserData(this.user); - }); + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); } - changeLeftSidenavView(view) + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Change left sidenav view + * + * @param view + */ + changeLeftSidenavView(view): void { - this.chatService.onLeftSidenavViewChanged.next(view); + this._chatService.onLeftSidenavViewChanged.next(view); } - ngOnDestroy() - { - this.onFormChange.unsubscribe(); - } } diff --git a/src/app/main/apps/chat/sidenavs/right/contact/contact.component.ts b/src/app/main/apps/chat/sidenavs/right/contact/contact.component.ts index be6a10a2..85f25438 100644 --- a/src/app/main/apps/chat/sidenavs/right/contact/contact.component.ts +++ b/src/app/main/apps/chat/sidenavs/right/contact/contact.component.ts @@ -1,26 +1,57 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; -import { ChatService } from '../../../chat.service'; +import { ChatService } from 'app/main/apps/chat/chat.service'; @Component({ - selector : 'fuse-chat-contact-sidenav', + selector : 'chat-contact-sidenav', templateUrl: './contact.component.html', styleUrls : ['./contact.component.scss'] }) -export class FuseChatContactSidenavComponent implements OnInit +export class ChatContactSidenavComponent implements OnInit, OnDestroy { contact: any; - constructor(private chatService: ChatService) - { + // Private + private _unsubscribeAll: Subject; + /** + * Constructor + * + * @param {ChatService} _chatService + */ + constructor( + private _chatService: ChatService + ) + { + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { - this.chatService.onContactSelected.subscribe(contact => { + this._chatService.onContactSelected + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(contact => { this.contact = contact; }); } + /** + * On destroy + */ + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); + } } diff --git a/src/app/main/apps/chat/sidenavs/right/right.component.html b/src/app/main/apps/chat/sidenavs/right/right.component.html index 35e7b937..1b28582a 100644 --- a/src/app/main/apps/chat/sidenavs/right/right.component.html +++ b/src/app/main/apps/chat/sidenavs/right/right.component.html @@ -1,8 +1,8 @@
- - + +
diff --git a/src/app/main/apps/chat/sidenavs/right/right.component.ts b/src/app/main/apps/chat/sidenavs/right/right.component.ts index 7ed97497..cb08c0c6 100644 --- a/src/app/main/apps/chat/sidenavs/right/right.component.ts +++ b/src/app/main/apps/chat/sidenavs/right/right.component.ts @@ -1,29 +1,59 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import { fuseAnimations } from '@fuse/animations'; -import { ChatService } from '../../chat.service'; +import { ChatService } from 'app/main/apps/chat/chat.service'; @Component({ - selector : 'fuse-chat-right-sidenav', + selector : 'chat-right-sidenav', templateUrl: './right.component.html', styleUrls : ['./right.component.scss'], animations : fuseAnimations }) -export class FuseChatRightSidenavComponent implements OnInit +export class ChatRightSidenavComponent implements OnInit, OnDestroy { view: string; - constructor(private chatService: ChatService) + // Private + private _unsubscribeAll: Subject; + + constructor( + private _chatService: ChatService + ) { + // Set the defaults this.view = 'contact'; + + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { - this.chatService.onRightSidenavViewChanged.subscribe(view => { - this.view = view; - }); + this._chatService.onRightSidenavViewChanged + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(view => { + this.view = view; + }); + } + + /** + * On destroy + */ + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); } } diff --git a/src/app/main/apps/contacts/contact-form/contact-form.component.ts b/src/app/main/apps/contacts/contact-form/contact-form.component.ts index 767024b5..81cb180e 100644 --- a/src/app/main/apps/contacts/contact-form/contact-form.component.ts +++ b/src/app/main/apps/contacts/contact-form/contact-form.component.ts @@ -2,37 +2,41 @@ import { Component, Inject, ViewEncapsulation } from '@angular/core'; import { FormBuilder, FormGroup } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material'; -import { CalendarEvent } from 'angular-calendar'; - -import { Contact } from '../contact.model'; +import { Contact } from 'app/main/apps/contacts/contact.model'; @Component({ - selector : 'fuse-contacts-contact-form-dialog', + selector : 'contacts-contact-form-dialog', templateUrl : './contact-form.component.html', styleUrls : ['./contact-form.component.scss'], encapsulation: ViewEncapsulation.None }) -export class FuseContactsContactFormDialogComponent +export class ContactsContactFormDialogComponent { - event: CalendarEvent; - dialogTitle: string; - contactForm: FormGroup; action: string; contact: Contact; + contactForm: FormGroup; + dialogTitle: string; + /** + * Constructor + * + * @param {MatDialogRef} _dialogRef + * @param _data + * @param {FormBuilder} _formBuilder + */ constructor( - public dialogRef: MatDialogRef, - @Inject(MAT_DIALOG_DATA) private data: any, - private formBuilder: FormBuilder + private _dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) private _data: any, + private _formBuilder: FormBuilder ) { - this.action = data.action; + this.action = _data.action; if ( this.action === 'edit' ) { this.dialogTitle = 'Edit Contact'; - this.contact = data.contact; + this.contact = _data.contact; } else { @@ -43,9 +47,18 @@ export class FuseContactsContactFormDialogComponent this.contactForm = this.createContactForm(); } - createContactForm() + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Create contact form + * + * @returns {FormGroup} + */ + createContactForm(): FormGroup { - return this.formBuilder.group({ + return this._formBuilder.group({ id : [this.contact.id], name : [this.contact.name], lastName: [this.contact.lastName], diff --git a/src/app/main/apps/contacts/contact-list/contact-list.component.scss b/src/app/main/apps/contacts/contact-list/contact-list.component.scss index 14510b4a..a8b26b96 100644 --- a/src/app/main/apps/contacts/contact-list/contact-list.component.scss +++ b/src/app/main/apps/contacts/contact-list/contact-list.component.scss @@ -1,6 +1,6 @@ @import "src/@fuse/scss/fuse"; -fuse-contacts-contact-list { +contacts-contact-list { display: flex; flex: 1 1 auto; width: 100%; diff --git a/src/app/main/apps/contacts/contact-list/contact-list.component.ts b/src/app/main/apps/contacts/contact-list/contact-list.component.ts index b41d1693..2443be7a 100644 --- a/src/app/main/apps/contacts/contact-list/contact-list.component.ts +++ b/src/app/main/apps/contacts/contact-list/contact-list.component.ts @@ -2,24 +2,26 @@ import { Component, OnDestroy, OnInit, TemplateRef, ViewChild, ViewEncapsulation import { FormGroup } from '@angular/forms'; import { MatDialog, MatDialogRef } from '@angular/material'; import { DataSource } from '@angular/cdk/collections'; -import { Observable, Subscription } from 'rxjs'; +import { Observable, Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import { fuseAnimations } from '@fuse/animations'; import { FuseConfirmDialogComponent } from '@fuse/components/confirm-dialog/confirm-dialog.component'; -import { FuseContactsContactFormDialogComponent } from '../contact-form/contact-form.component'; -import { ContactsService } from '../contacts.service'; +import { ContactsService } from 'app/main/apps/contacts/contacts.service'; +import { ContactsContactFormDialogComponent } from 'app/main/apps/contacts/contact-form/contact-form.component'; @Component({ - selector : 'fuse-contacts-contact-list', + selector : 'contacts-contact-list', templateUrl : './contact-list.component.html', styleUrls : ['./contact-list.component.scss'], encapsulation: ViewEncapsulation.None, animations : fuseAnimations }) -export class FuseContactsContactListComponent implements OnInit, OnDestroy +export class ContactsContactListComponent implements OnInit, OnDestroy { - @ViewChild('dialogContent') dialogContent: TemplateRef; + @ViewChild('dialogContent') + dialogContent: TemplateRef; contacts: any; user: any; @@ -27,24 +29,41 @@ export class FuseContactsContactListComponent implements OnInit, OnDestroy displayedColumns = ['checkbox', 'avatar', 'name', 'email', 'phone', 'jobTitle', 'buttons']; selectedContacts: any[]; checkboxes: {}; - - onContactsChangedSubscription: Subscription; - onFilterChangedSubscription: Subscription; - onSelectedContactsChangedSubscription: Subscription; - onUserDataChangedSubscription: Subscription; - dialogRef: any; - confirmDialogRef: MatDialogRef; + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {ContactsService} _contactsService + * @param {MatDialog} _matDialog + */ constructor( - private contactsService: ContactsService, - public dialog: MatDialog + private _contactsService: ContactsService, + public _matDialog: MatDialog ) { - this.onContactsChangedSubscription = - this.contactsService.onContactsChanged.subscribe(contacts => { + // Set the private defaults + this._unsubscribeAll = new Subject(); + } + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void + { + this.dataSource = new FilesDataSource(this._contactsService); + + this._contactsService.onContactsChanged + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(contacts => { this.contacts = contacts; this.checkboxes = {}; @@ -53,8 +72,9 @@ export class FuseContactsContactListComponent implements OnInit, OnDestroy }); }); - this.onSelectedContactsChangedSubscription = - this.contactsService.onSelectedContactsChanged.subscribe(selectedContacts => { + this._contactsService.onSelectedContactsChanged + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(selectedContacts => { for ( const id in this.checkboxes ) { if ( !this.checkboxes.hasOwnProperty(id) ) @@ -67,33 +87,41 @@ export class FuseContactsContactListComponent implements OnInit, OnDestroy this.selectedContacts = selectedContacts; }); - this.onUserDataChangedSubscription = - this.contactsService.onUserDataChanged.subscribe(user => { + this._contactsService.onUserDataChanged + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(user => { this.user = user; }); - this.onFilterChangedSubscription = - this.contactsService.onFilterChanged.subscribe(() => { - this.contactsService.deselectContacts(); + this._contactsService.onFilterChanged + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { + this._contactsService.deselectContacts(); }); } - ngOnInit() + /** + * On destroy + */ + ngOnDestroy(): void { - this.dataSource = new FilesDataSource(this.contactsService); + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); } - ngOnDestroy() - { - this.onContactsChangedSubscription.unsubscribe(); - this.onFilterChangedSubscription.unsubscribe(); - this.onSelectedContactsChangedSubscription.unsubscribe(); - this.onUserDataChangedSubscription.unsubscribe(); - } + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- - editContact(contact) + /** + * Edit contact + * + * @param contact + */ + editContact(contact): void { - this.dialogRef = this.dialog.open(FuseContactsContactFormDialogComponent, { + this.dialogRef = this._matDialog.open(ContactsContactFormDialogComponent, { panelClass: 'contact-form-dialog', data : { contact: contact, @@ -116,7 +144,7 @@ export class FuseContactsContactListComponent implements OnInit, OnDestroy */ case 'save': - this.contactsService.updateContact(formData.getRawValue()); + this._contactsService.updateContact(formData.getRawValue()); break; /** @@ -134,9 +162,9 @@ export class FuseContactsContactListComponent implements OnInit, OnDestroy /** * Delete Contact */ - deleteContact(contact) + deleteContact(contact): void { - this.confirmDialogRef = this.dialog.open(FuseConfirmDialogComponent, { + this.confirmDialogRef = this._matDialog.open(FuseConfirmDialogComponent, { disableClose: false }); @@ -145,19 +173,29 @@ export class FuseContactsContactListComponent implements OnInit, OnDestroy this.confirmDialogRef.afterClosed().subscribe(result => { if ( result ) { - this.contactsService.deleteContact(contact); + this._contactsService.deleteContact(contact); } this.confirmDialogRef = null; }); } - onSelectedChange(contactId) + /** + * On selected change + * + * @param contactId + */ + onSelectedChange(contactId): void { - this.contactsService.toggleSelectedContact(contactId); + this._contactsService.toggleSelectedContact(contactId); } - toggleStar(contactId) + /** + * Toggle star + * + * @param contactId + */ + toggleStar(contactId): void { if ( this.user.starred.includes(contactId) ) { @@ -168,24 +206,37 @@ export class FuseContactsContactListComponent implements OnInit, OnDestroy this.user.starred.push(contactId); } - this.contactsService.updateUserData(this.user); + this._contactsService.updateUserData(this.user); } } export class FilesDataSource extends DataSource { - constructor(private contactsService: ContactsService) + /** + * Constructor + * + * @param {ContactsService} _contactsService + */ + constructor( + private _contactsService: ContactsService + ) { super(); } - /** Connect function called by the table to retrieve one stream containing the data to render. */ + /** + * Connect function called by the table to retrieve one stream containing the data to render. + * @returns {Observable} + */ connect(): Observable { - return this.contactsService.onContactsChanged; + return this._contactsService.onContactsChanged; } - disconnect() + /** + * Disconnect + */ + disconnect(): void { } } diff --git a/src/app/main/apps/contacts/contact.model.ts b/src/app/main/apps/contacts/contact.model.ts index efc5e687..3a5df6c6 100644 --- a/src/app/main/apps/contacts/contact.model.ts +++ b/src/app/main/apps/contacts/contact.model.ts @@ -15,6 +15,11 @@ export class Contact birthday: string; notes: string; + /** + * Constructor + * + * @param contact + */ constructor(contact) { { diff --git a/src/app/main/apps/contacts/contacts.component.html b/src/app/main/apps/contacts/contacts.component.html index 56f9661c..8c7b73f4 100644 --- a/src/app/main/apps/contacts/contacts.component.html +++ b/src/app/main/apps/contacts/contacts.component.html @@ -36,7 +36,7 @@ - + @@ -45,7 +45,7 @@ - + @@ -56,7 +56,7 @@
- +
diff --git a/src/app/main/apps/contacts/contacts.component.ts b/src/app/main/apps/contacts/contacts.component.ts index da705aad..dea74ea6 100644 --- a/src/app/main/apps/contacts/contacts.component.ts +++ b/src/app/main/apps/contacts/contacts.component.ts @@ -1,40 +1,94 @@ import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core'; import { FormControl, FormGroup } from '@angular/forms'; import { MatDialog } from '@angular/material'; - -import { Subscription } from 'rxjs'; -import { debounceTime, distinctUntilChanged } from 'rxjs/operators'; +import { Subject } from 'rxjs'; +import { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators'; import { fuseAnimations } from '@fuse/animations'; -import { FuseContactsContactFormDialogComponent } from './contact-form/contact-form.component'; -import { ContactsService } from './contacts.service'; +import { ContactsService } from 'app/main/apps/contacts/contacts.service'; +import { ContactsContactFormDialogComponent } from 'app/main/apps/contacts/contact-form/contact-form.component'; @Component({ - selector : 'fuse-contacts', + selector : 'contacts', templateUrl : './contacts.component.html', styleUrls : ['./contacts.component.scss'], encapsulation: ViewEncapsulation.None, animations : fuseAnimations }) -export class FuseContactsComponent implements OnInit, OnDestroy +export class ContactsComponent implements OnInit, OnDestroy { + dialogRef: any; hasSelectedContacts: boolean; searchInput: FormControl; - dialogRef: any; - onSelectedContactsChangedSubscription: Subscription; + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {ContactsService} _contactsService + * @param {MatDialog} _matDialog + */ constructor( - private contactsService: ContactsService, - public dialog: MatDialog + private _contactsService: ContactsService, + public _matDialog: MatDialog ) { + // Set the defaults this.searchInput = new FormControl(''); + + // Set the private defaults + this._unsubscribeAll = new Subject(); } - newContact() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { - this.dialogRef = this.dialog.open(FuseContactsContactFormDialogComponent, { + this._contactsService.onSelectedContactsChanged + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(selectedContacts => { + this.hasSelectedContacts = selectedContacts.length > 0; + }); + + this.searchInput.valueChanges + .pipe( + takeUntil(this._unsubscribeAll), + debounceTime(300), + distinctUntilChanged() + ) + .subscribe(searchText => { + this._contactsService.onSearchTextChanged.next(searchText); + }); + } + + /** + * On destroy + */ + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * New contact + */ + newContact(): void + { + this.dialogRef = this._matDialog.open(ContactsContactFormDialogComponent, { panelClass: 'contact-form-dialog', data : { action: 'new' @@ -48,32 +102,7 @@ export class FuseContactsComponent implements OnInit, OnDestroy return; } - this.contactsService.updateContact(response.getRawValue()); - + this._contactsService.updateContact(response.getRawValue()); }); - - } - - ngOnInit() - { - this.onSelectedContactsChangedSubscription = - this.contactsService.onSelectedContactsChanged - .subscribe(selectedContacts => { - this.hasSelectedContacts = selectedContacts.length > 0; - }); - - this.searchInput.valueChanges - .pipe( - debounceTime(300), - distinctUntilChanged() - ) - .subscribe(searchText => { - this.contactsService.onSearchTextChanged.next(searchText); - }); - } - - ngOnDestroy() - { - this.onSelectedContactsChangedSubscription.unsubscribe(); } } diff --git a/src/app/main/apps/contacts/contacts.module.ts b/src/app/main/apps/contacts/contacts.module.ts index fd3a1a5a..e1125816 100644 --- a/src/app/main/apps/contacts/contacts.module.ts +++ b/src/app/main/apps/contacts/contacts.module.ts @@ -7,17 +7,17 @@ import { MatButtonModule, MatCheckboxModule, MatDatepickerModule, MatFormFieldMo import { FuseSharedModule } from '@fuse/shared.module'; import { FuseConfirmDialogModule } from '@fuse/components'; -import { FuseContactsMainSidenavComponent } from './sidenavs/main/main.component'; -import { FuseContactsComponent } from './contacts.component'; -import { ContactsService } from './contacts.service'; -import { FuseContactsContactListComponent } from './contact-list/contact-list.component'; -import { FuseContactsSelectedBarComponent } from './selected-bar/selected-bar.component'; -import { FuseContactsContactFormDialogComponent } from './contact-form/contact-form.component'; +import { ContactsComponent } from 'app/main/apps/contacts/contacts.component'; +import { ContactsService } from 'app/main/apps/contacts/contacts.service'; +import { ContactsContactListComponent } from 'app/main/apps/contacts/contact-list/contact-list.component'; +import { ContactsSelectedBarComponent } from 'app/main/apps/contacts/selected-bar/selected-bar.component'; +import { ContactsMainSidenavComponent } from 'app/main/apps/contacts/sidenavs/main/main.component'; +import { ContactsContactFormDialogComponent } from 'app/main/apps/contacts/contact-form/contact-form.component'; const routes: Routes = [ { path : '**', - component: FuseContactsComponent, + component: ContactsComponent, resolve : { contacts: ContactsService } @@ -26,11 +26,11 @@ const routes: Routes = [ @NgModule({ declarations : [ - FuseContactsComponent, - FuseContactsContactListComponent, - FuseContactsSelectedBarComponent, - FuseContactsMainSidenavComponent, - FuseContactsContactFormDialogComponent + ContactsComponent, + ContactsContactListComponent, + ContactsSelectedBarComponent, + ContactsMainSidenavComponent, + ContactsContactFormDialogComponent ], imports : [ RouterModule.forChild(routes), @@ -54,8 +54,10 @@ const routes: Routes = [ providers : [ ContactsService ], - entryComponents: [FuseContactsContactFormDialogComponent] + entryComponents: [ + ContactsContactFormDialogComponent + ] }) -export class FuseContactsModule +export class ContactsModule { } diff --git a/src/app/main/apps/contacts/contacts.service.ts b/src/app/main/apps/contacts/contacts.service.ts index 66563638..35da8fbd 100644 --- a/src/app/main/apps/contacts/contacts.service.ts +++ b/src/app/main/apps/contacts/contacts.service.ts @@ -5,7 +5,7 @@ import { BehaviorSubject, Observable, Subject } from 'rxjs'; import { FuseUtils } from '@fuse/utils'; -import { Contact } from './contact.model'; +import { Contact } from 'app/main/apps/contacts/contact.model'; @Injectable() export class ContactsService implements Resolve @@ -23,12 +23,24 @@ export class ContactsService implements Resolve searchText: string; filterBy: string; - constructor(private http: HttpClient) + /** + * Constructor + * + * @param {HttpClient} _httpClient + */ + constructor( + private _httpClient: HttpClient + ) { } + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + /** - * The Contacts App Main Resolver + * Resolver + * * @param {ActivatedRouteSnapshot} route * @param {RouterStateSnapshot} state * @returns {Observable | Promise | any} @@ -61,10 +73,15 @@ export class ContactsService implements Resolve }); } + /** + * Get contacts + * + * @returns {Promise} + */ getContacts(): Promise { return new Promise((resolve, reject) => { - this.http.get('api/contacts-contacts') + this._httpClient.get('api/contacts-contacts') .subscribe((response: any) => { this.contacts = response; @@ -99,10 +116,15 @@ export class ContactsService implements Resolve ); } + /** + * Get user data + * + * @returns {Promise} + */ getUserData(): Promise { return new Promise((resolve, reject) => { - this.http.get('api/contacts-user/5725a6802d10e277a0f35724') + this._httpClient.get('api/contacts-user/5725a6802d10e277a0f35724') .subscribe((response: any) => { this.user = response; this.onUserDataChanged.next(this.user); @@ -114,9 +136,10 @@ export class ContactsService implements Resolve /** * Toggle selected contact by id + * * @param id */ - toggleSelectedContact(id) + toggleSelectedContact(id): void { // First, check if we already have that contact as selected... if ( this.selectedContacts.length > 0 ) @@ -145,7 +168,7 @@ export class ContactsService implements Resolve /** * Toggle select all */ - toggleSelectAll() + toggleSelectAll(): void { if ( this.selectedContacts.length > 0 ) { @@ -157,11 +180,17 @@ export class ContactsService implements Resolve } } - selectContacts(filterParameter?, filterValue?) + /** + * Select contacts + * + * @param filterParameter + * @param filterValue + */ + selectContacts(filterParameter?, filterValue?): void { this.selectedContacts = []; - // If there is no filter, select all todos + // If there is no filter, select all contacts if ( filterParameter === undefined || filterValue === undefined ) { this.selectedContacts = []; @@ -169,24 +198,22 @@ export class ContactsService implements Resolve this.selectedContacts.push(contact.id); }); } - else - { - /* this.selectedContacts.push(... - this.contacts.filter(todo => { - return todo[filterParameter] === filterValue; - }) - );*/ - } // Trigger the next event this.onSelectedContactsChanged.next(this.selectedContacts); } - updateContact(contact) + /** + * Update contact + * + * @param contact + * @returns {Promise} + */ + updateContact(contact): Promise { return new Promise((resolve, reject) => { - this.http.post('api/contacts-contacts/' + contact.id, {...contact}) + this._httpClient.post('api/contacts-contacts/' + contact.id, {...contact}) .subscribe(response => { this.getContacts(); resolve(response); @@ -194,10 +221,16 @@ export class ContactsService implements Resolve }); } - updateUserData(userData) + /** + * Update user data + * + * @param userData + * @returns {Promise} + */ + updateUserData(userData): Promise { return new Promise((resolve, reject) => { - this.http.post('api/contacts-user/' + this.user.id, {...userData}) + this._httpClient.post('api/contacts-user/' + this.user.id, {...userData}) .subscribe(response => { this.getUserData(); this.getContacts(); @@ -206,7 +239,10 @@ export class ContactsService implements Resolve }); } - deselectContacts() + /** + * Deselect contacts + */ + deselectContacts(): void { this.selectedContacts = []; @@ -214,14 +250,22 @@ export class ContactsService implements Resolve this.onSelectedContactsChanged.next(this.selectedContacts); } - deleteContact(contact) + /** + * Delete contact + * + * @param contact + */ + deleteContact(contact): void { const contactIndex = this.contacts.indexOf(contact); this.contacts.splice(contactIndex, 1); this.onContactsChanged.next(this.contacts); } - deleteSelectedContacts() + /** + * Delete selected contacts + */ + deleteSelectedContacts(): void { for ( const contactId of this.selectedContacts ) { diff --git a/src/app/main/apps/contacts/selected-bar/selected-bar.component.ts b/src/app/main/apps/contacts/selected-bar/selected-bar.component.ts index d9c09a5b..fa499a69 100644 --- a/src/app/main/apps/contacts/selected-bar/selected-bar.component.ts +++ b/src/app/main/apps/contacts/selected-bar/selected-bar.component.ts @@ -1,63 +1,110 @@ -import { Component } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; import { MatDialog, MatDialogRef } from '@angular/material'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import { FuseConfirmDialogComponent } from '@fuse/components/confirm-dialog/confirm-dialog.component'; -import { ContactsService } from '../contacts.service'; +import { ContactsService } from 'app/main/apps/contacts/contacts.service'; @Component({ - selector : 'fuse-selected-bar', + selector : 'selected-bar', templateUrl: './selected-bar.component.html', styleUrls : ['./selected-bar.component.scss'] }) -export class FuseContactsSelectedBarComponent +export class ContactsSelectedBarComponent implements OnInit, OnDestroy { - selectedContacts: string[]; + confirmDialogRef: MatDialogRef; hasSelectedContacts: boolean; isIndeterminate: boolean; - confirmDialogRef: MatDialogRef; + selectedContacts: string[]; + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {ContactsService} _contactsService + * @param {MatDialog} _matDialog + */ constructor( - private contactsService: ContactsService, - public dialog: MatDialog + private _contactsService: ContactsService, + public _matDialog: MatDialog ) { - this.contactsService.onSelectedContactsChanged + // Set the private defaults + this._unsubscribeAll = new Subject(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void + { + this._contactsService.onSelectedContactsChanged + .pipe(takeUntil(this._unsubscribeAll)) .subscribe(selectedContacts => { this.selectedContacts = selectedContacts; setTimeout(() => { this.hasSelectedContacts = selectedContacts.length > 0; - this.isIndeterminate = (selectedContacts.length !== this.contactsService.contacts.length && selectedContacts.length > 0); + this.isIndeterminate = (selectedContacts.length !== this._contactsService.contacts.length && selectedContacts.length > 0); }, 0); }); - } - selectAll() + /** + * On destroy + */ + ngOnDestroy(): void { - this.contactsService.selectContacts(); + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); } - deselectAll() + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Select all + */ + selectAll(): void { - this.contactsService.deselectContacts(); + this._contactsService.selectContacts(); } - deleteSelectedContacts() + /** + * Deselect all + */ + deselectAll(): void { - this.confirmDialogRef = this.dialog.open(FuseConfirmDialogComponent, { + this._contactsService.deselectContacts(); + } + + /** + * Delete selected contacts + */ + deleteSelectedContacts(): void + { + this.confirmDialogRef = this._matDialog.open(FuseConfirmDialogComponent, { disableClose: false }); this.confirmDialogRef.componentInstance.confirmMessage = 'Are you sure you want to delete all selected contacts?'; - this.confirmDialogRef.afterClosed().subscribe(result => { - if ( result ) - { - this.contactsService.deleteSelectedContacts(); - } - this.confirmDialogRef = null; - }); + this.confirmDialogRef.afterClosed() + .subscribe(result => { + if ( result ) + { + this._contactsService.deleteSelectedContacts(); + } + this.confirmDialogRef = null; + }); } - } diff --git a/src/app/main/apps/contacts/sidenavs/main/main.component.ts b/src/app/main/apps/contacts/sidenavs/main/main.component.ts index de4b2275..a9196309 100644 --- a/src/app/main/apps/contacts/sidenavs/main/main.component.ts +++ b/src/app/main/apps/contacts/sidenavs/main/main.component.ts @@ -1,37 +1,75 @@ -import { Component, OnDestroy } from '@angular/core'; -import { Subscription } from 'rxjs'; +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; -import { ContactsService } from '../../contacts.service'; +import { ContactsService } from 'app/main/apps/contacts/contacts.service'; @Component({ - selector : 'fuse-contacts-main-sidenav', + selector : 'contacts-main-sidenav', templateUrl: './main.component.html', styleUrls : ['./main.component.scss'] }) -export class FuseContactsMainSidenavComponent implements OnDestroy +export class ContactsMainSidenavComponent implements OnInit, OnDestroy { user: any; filterBy: string; - - onUserDataChangedSubscription: Subscription; - constructor(private contactsService: ContactsService) + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {ContactsService} _contactsService + */ + constructor( + private _contactsService: ContactsService + ) { - this.filterBy = this.contactsService.filterBy || 'all'; - this.onUserDataChangedSubscription = - this.contactsService.onUserDataChanged.subscribe(user => { + // Set the private defaults + this._unsubscribeAll = new Subject(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void + { + this.filterBy = this._contactsService.filterBy || 'all'; + + this._contactsService.onUserDataChanged + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(user => { this.user = user; }); } - changeFilter(filter) - { - this.filterBy = filter; - this.contactsService.onFilterChanged.next(this.filterBy); - } - + /** + * On destroy + */ ngOnDestroy() { - this.onUserDataChangedSubscription.unsubscribe(); + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Change the filter + * + * @param filter + */ + changeFilter(filter): void + { + this.filterBy = filter; + this._contactsService.onFilterChanged.next(this.filterBy); } } diff --git a/src/app/main/apps/dashboards/analytics/analytics.component.ts b/src/app/main/apps/dashboards/analytics/analytics.component.ts index c1b78979..41829f65 100644 --- a/src/app/main/apps/dashboards/analytics/analytics.component.ts +++ b/src/app/main/apps/dashboards/analytics/analytics.component.ts @@ -1,36 +1,56 @@ -import { Component, ViewEncapsulation } from '@angular/core'; +import { Component, OnInit, ViewEncapsulation } from '@angular/core'; -import { AnalyticsDashboardService } from './analytics.service'; import { fuseAnimations } from '@fuse/animations'; +import { AnalyticsDashboardService } from 'app/main/apps/dashboards/analytics/analytics.service'; + @Component({ - selector : 'fuse-analytics-dashboard', + selector : 'analytics-dashboard', templateUrl : './analytics.component.html', styleUrls : ['./analytics.component.scss'], encapsulation: ViewEncapsulation.None, animations : fuseAnimations }) -export class FuseAnalyticsDashboardComponent +export class AnalyticsDashboardComponent implements OnInit { widgets: any; widget1SelectedYear = '2016'; widget5SelectedDay = 'today'; + /** + * Constructor + * + * @param {AnalyticsDashboardService} _analyticsDashboardService + */ constructor( - private analyticsDashboardService: AnalyticsDashboardService + private _analyticsDashboardService: AnalyticsDashboardService ) { - // Get the widgets from the service - this.widgets = this.analyticsDashboardService.widgets; - // Register the custom chart.js plugin - this.registerCustomChartJSPlugin(); + this._registerCustomChartJSPlugin(); } + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void + { + // Get the widgets from the service + this.widgets = this._analyticsDashboardService.widgets; + } + + // ----------------------------------------------------------------------------------------------------- + // @ Private methods + // ----------------------------------------------------------------------------------------------------- + /** * Register a custom plugin */ - registerCustomChartJSPlugin() + private _registerCustomChartJSPlugin(): void { (window).Chart.plugins.register({ afterDatasetsDraw: function (chart, easing) { diff --git a/src/app/main/apps/dashboards/analytics/analytics.module.ts b/src/app/main/apps/dashboards/analytics/analytics.module.ts index 710521ca..6e4cd406 100644 --- a/src/app/main/apps/dashboards/analytics/analytics.module.ts +++ b/src/app/main/apps/dashboards/analytics/analytics.module.ts @@ -1,8 +1,6 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; - import { MatButtonModule, MatFormFieldModule, MatIconModule, MatMenuModule, MatSelectModule, MatTabsModule } from '@angular/material'; - import { AgmCoreModule } from '@agm/core'; import { ChartsModule } from 'ng2-charts'; import { NgxChartsModule } from '@swimlane/ngx-charts'; @@ -10,14 +8,13 @@ import { NgxChartsModule } from '@swimlane/ngx-charts'; import { FuseSharedModule } from '@fuse/shared.module'; import { FuseWidgetModule } from '@fuse/components/widget/widget.module'; -import { FuseAnalyticsDashboardComponent } from './analytics.component'; -import { AnalyticsDashboardService } from './analytics.service'; - +import { AnalyticsDashboardComponent } from 'app/main/apps/dashboards/analytics/analytics.component'; +import { AnalyticsDashboardService } from 'app/main/apps/dashboards/analytics/analytics.service'; const routes: Routes = [ { path : '**', - component: FuseAnalyticsDashboardComponent, + component: AnalyticsDashboardComponent, resolve : { data: AnalyticsDashboardService } @@ -26,7 +23,7 @@ const routes: Routes = [ @NgModule({ declarations: [ - FuseAnalyticsDashboardComponent + AnalyticsDashboardComponent ], imports : [ RouterModule.forChild(routes), @@ -51,7 +48,7 @@ const routes: Routes = [ AnalyticsDashboardService ] }) -export class FuseAnalyticsDashboardModule +export class AnalyticsDashboardModule { } diff --git a/src/app/main/apps/dashboards/analytics/analytics.service.ts b/src/app/main/apps/dashboards/analytics/analytics.service.ts index 47d3097c..69f1fddb 100644 --- a/src/app/main/apps/dashboards/analytics/analytics.service.ts +++ b/src/app/main/apps/dashboards/analytics/analytics.service.ts @@ -8,14 +8,20 @@ export class AnalyticsDashboardService implements Resolve { widgets: any[]; + /** + * Constructor + * + * @param {HttpClient} _httpClient + */ constructor( - private http: HttpClient + private _httpClient: HttpClient ) { } /** - * Resolve + * Resolver + * * @param {ActivatedRouteSnapshot} route * @param {RouterStateSnapshot} state * @returns {Observable | Promise | any} @@ -35,10 +41,15 @@ export class AnalyticsDashboardService implements Resolve }); } + /** + * Get widgets + * + * @returns {Promise} + */ getWidgets(): Promise { return new Promise((resolve, reject) => { - this.http.get('api/analytics-dashboard-widgets') + this._httpClient.get('api/analytics-dashboard-widgets') .subscribe((response: any) => { this.widgets = response; resolve(response); diff --git a/src/app/main/apps/dashboards/project/project.component.ts b/src/app/main/apps/dashboards/project/project.component.ts index deeadfff..fb26613c 100644 --- a/src/app/main/apps/dashboards/project/project.component.ts +++ b/src/app/main/apps/dashboards/project/project.component.ts @@ -1,21 +1,20 @@ import { Component, OnInit, ViewEncapsulation } from '@angular/core'; import { DataSource } from '@angular/cdk/collections'; import { BehaviorSubject, Observable } from 'rxjs'; - import * as shape from 'd3-shape'; import { fuseAnimations } from '@fuse/animations'; -import { ProjectDashboardService } from './project.service'; +import { ProjectDashboardService } from 'app/main/apps/dashboards/project/project.service'; @Component({ - selector : 'fuse-project-dashboard', + selector : 'project-dashboard', templateUrl : './project.component.html', styleUrls : ['./project.component.scss'], encapsulation: ViewEncapsulation.None, animations : fuseAnimations }) -export class FuseProjectDashboardComponent implements OnInit +export class ProjectDashboardComponent implements OnInit { projects: any[]; selectedProject: any; @@ -30,12 +29,15 @@ export class FuseProjectDashboardComponent implements OnInit dateNow = Date.now(); - constructor(private projectDashboardService: ProjectDashboardService) + /** + * Constructor + * + * @param {ProjectDashboardService} _projectDashboardService + */ + constructor( + private _projectDashboardService: ProjectDashboardService + ) { - this.projects = this.projectDashboardService.projects; - this.selectedProject = this.projects[0]; - this.widgets = this.projectDashboardService.widgets; - /** * Widget 5 */ @@ -139,8 +141,19 @@ export class FuseProjectDashboardComponent implements OnInit } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { + this.projects = this._projectDashboardService.projects; + this.selectedProject = this.projects[0]; + this.widgets = this._projectDashboardService.widgets; + /** * Widget 11 */ @@ -152,18 +165,30 @@ export class FuseProjectDashboardComponent implements OnInit export class FilesDataSource extends DataSource { - constructor(private widget11) + /** + * Constructor + * + * @param _widget11 + */ + constructor(private _widget11) { super(); } - /** Connect function called by the table to retrieve one stream containing the data to render. */ + /** + * Connect function called by the table to retrieve one stream containing the data to render. + * + * @returns {Observable} + */ connect(): Observable { - return this.widget11.onContactsChanged; + return this._widget11.onContactsChanged; } - disconnect() + /** + * Disconnect + */ + disconnect(): void { } } diff --git a/src/app/main/apps/dashboards/project/project.module.ts b/src/app/main/apps/dashboards/project/project.module.ts index 23dcf8d9..88290f27 100644 --- a/src/app/main/apps/dashboards/project/project.module.ts +++ b/src/app/main/apps/dashboards/project/project.module.ts @@ -1,21 +1,19 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { CdkTableModule } from '@angular/cdk/table'; - import { MatButtonModule, MatDividerModule, MatFormFieldModule, MatIconModule, MatMenuModule, MatSelectModule, MatSidenavModule, MatTableModule, MatTabsModule } from '@angular/material'; - import { NgxChartsModule } from '@swimlane/ngx-charts'; import { FuseSharedModule } from '@fuse/shared.module'; import { FuseWidgetModule } from '@fuse/components/widget/widget.module'; -import { FuseProjectDashboardComponent } from './project.component'; -import { ProjectDashboardService } from './project.service'; +import { ProjectDashboardComponent } from 'app/main/apps/dashboards/project/project.component'; +import { ProjectDashboardService } from 'app/main/apps/dashboards/project/project.service'; const routes: Routes = [ { path : '**', - component: FuseProjectDashboardComponent, + component: ProjectDashboardComponent, resolve : { data: ProjectDashboardService } @@ -24,7 +22,7 @@ const routes: Routes = [ @NgModule({ declarations: [ - FuseProjectDashboardComponent + ProjectDashboardComponent ], imports : [ RouterModule.forChild(routes), @@ -49,7 +47,7 @@ const routes: Routes = [ ProjectDashboardService ] }) -export class FuseProjectDashboardModule +export class ProjectDashboardModule { } diff --git a/src/app/main/apps/dashboards/project/project.service.ts b/src/app/main/apps/dashboards/project/project.service.ts index a1ee2128..d697fd32 100644 --- a/src/app/main/apps/dashboards/project/project.service.ts +++ b/src/app/main/apps/dashboards/project/project.service.ts @@ -9,14 +9,20 @@ export class ProjectDashboardService implements Resolve projects: any[]; widgets: any[]; + /** + * Constructor + * + * @param {HttpClient} _httpClient + */ constructor( - private http: HttpClient + private _httpClient: HttpClient ) { } /** - * Resolve + * Resolver + * * @param {ActivatedRouteSnapshot} route * @param {RouterStateSnapshot} state * @returns {Observable | Promise | any} @@ -38,10 +44,15 @@ export class ProjectDashboardService implements Resolve }); } + /** + * Get projects + * + * @returns {Promise} + */ getProjects(): Promise { return new Promise((resolve, reject) => { - this.http.get('api/project-dashboard-projects') + this._httpClient.get('api/project-dashboard-projects') .subscribe((response: any) => { this.projects = response; resolve(response); @@ -49,10 +60,15 @@ export class ProjectDashboardService implements Resolve }); } + /** + * Get widgets + * + * @returns {Promise} + */ getWidgets(): Promise { return new Promise((resolve, reject) => { - this.http.get('api/project-dashboard-widgets') + this._httpClient.get('api/project-dashboard-widgets') .subscribe((response: any) => { this.widgets = response; resolve(response); diff --git a/src/app/main/apps/e-commerce/dashboard/dashboard.component.ts b/src/app/main/apps/e-commerce/dashboard/dashboard.component.ts index 5039c66f..684c021f 100644 --- a/src/app/main/apps/e-commerce/dashboard/dashboard.component.ts +++ b/src/app/main/apps/e-commerce/dashboard/dashboard.component.ts @@ -1,17 +1,17 @@ -import { Component, ViewEncapsulation } from '@angular/core'; +import { Component, OnInit, ViewEncapsulation } from '@angular/core'; import { fuseAnimations } from '@fuse/animations'; -import { EcommerceDashboardService } from './dashboard.service'; +import { EcommerceDashboardService } from 'app/main/apps/e-commerce/dashboard/dashboard.service'; @Component({ - selector : 'fuse-e-commerce-dashboard', + selector : 'e-commerce-dashboard', templateUrl : './dashboard.component.html', styleUrls : ['./dashboard.component.scss'], encapsulation: ViewEncapsulation.None, animations : fuseAnimations }) -export class FuseEcommerceDashboardComponent +export class EcommerceDashboardComponent implements OnInit { projects: any[]; selectedProject: any; @@ -21,12 +21,10 @@ export class FuseEcommerceDashboardComponent widget6: any = {}; widget7: any = {}; - constructor(private projectsDashboardService: EcommerceDashboardService) + constructor( + private _eCommerceDashboardService: EcommerceDashboardService + ) { - this.projects = this.projectsDashboardService.projects; - this.selectedProject = this.projects[0]; - this.widgets = this.projectsDashboardService.widgets; - /** * Widget 5 */ @@ -74,4 +72,18 @@ export class FuseEcommerceDashboardComponent }; } + + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void + { + this.projects = this._eCommerceDashboardService.projects; + this.selectedProject = this.projects[0]; + this.widgets = this._eCommerceDashboardService.widgets; + } } diff --git a/src/app/main/apps/e-commerce/dashboard/dashboard.service.ts b/src/app/main/apps/e-commerce/dashboard/dashboard.service.ts index 8810da76..625a215b 100644 --- a/src/app/main/apps/e-commerce/dashboard/dashboard.service.ts +++ b/src/app/main/apps/e-commerce/dashboard/dashboard.service.ts @@ -9,21 +9,26 @@ export class EcommerceDashboardService implements Resolve projects: any[]; widgets: any[]; + /** + * Constructor + * + * @param {HttpClient} _httpClient + */ constructor( - private http: HttpClient + private _httpClient: HttpClient ) { } /** - * Resolve + * Resolver + * * @param {ActivatedRouteSnapshot} route * @param {RouterStateSnapshot} state * @returns {Observable | Promise | any} */ resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | Promise | any { - return new Promise((resolve, reject) => { Promise.all([ @@ -38,10 +43,15 @@ export class EcommerceDashboardService implements Resolve }); } + /** + * Get projects + * + * @returns {Promise} + */ getProjects(): Promise { return new Promise((resolve, reject) => { - this.http.get('api/project-dashboard-projects') + this._httpClient.get('api/project-dashboard-projects') .subscribe((response: any) => { this.projects = response; resolve(response); @@ -49,10 +59,15 @@ export class EcommerceDashboardService implements Resolve }); } + /** + * Get widgets + * + * @returns {Promise} + */ getWidgets(): Promise { return new Promise((resolve, reject) => { - this.http.get('api/e-commerce-dashboard') + this._httpClient.get('api/e-commerce-dashboard') .subscribe((response: any) => { this.widgets = response; resolve(response); diff --git a/src/app/main/apps/e-commerce/e-commerce.module.ts b/src/app/main/apps/e-commerce/e-commerce.module.ts index f6a09c35..b01a6ff2 100644 --- a/src/app/main/apps/e-commerce/e-commerce.module.ts +++ b/src/app/main/apps/e-commerce/e-commerce.module.ts @@ -1,65 +1,63 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { CdkTableModule } from '@angular/cdk/table'; - -import { MatButtonModule, MatChipsModule, MatFormFieldModule, MatIconModule, MatInputModule, MatPaginatorModule, MatRippleModule, MatSelectModule, MatSortModule, MatTableModule, MatTabsModule } from '@angular/material'; - +import { MatButtonModule, MatChipsModule, MatFormFieldModule, MatIconModule, MatInputModule, MatPaginatorModule, MatRippleModule, MatSelectModule, MatSnackBarModule, MatSortModule, MatTableModule, MatTabsModule } from '@angular/material'; import { NgxChartsModule } from '@swimlane/ngx-charts'; import { AgmCoreModule } from '@agm/core'; import { FuseSharedModule } from '@fuse/shared.module'; import { FuseWidgetModule } from '@fuse/components/widget/widget.module'; -import { FuseEcommerceDashboardComponent } from './dashboard/dashboard.component'; -import { EcommerceDashboardService } from './dashboard/dashboard.service'; -import { FuseEcommerceProductsComponent } from './products/products.component'; -import { EcommerceProductsService } from './products/products.service'; -import { FuseEcommerceProductComponent } from './product/product.component'; -import { EcommerceProductService } from './product/product.service'; -import { FuseEcommerceOrdersComponent } from './orders/orders.component'; -import { EcommerceOrdersService } from './orders/orders.service'; -import { FuseEcommerceOrderComponent } from './order/order.component'; -import { EcommerceOrderService } from './order/order.service'; +import { EcommerceDashboardComponent } from 'app/main/apps/e-commerce/dashboard/dashboard.component'; +import { EcommerceDashboardService } from 'app/main/apps/e-commerce/dashboard/dashboard.service'; +import { EcommerceProductsComponent } from 'app/main/apps/e-commerce/products/products.component'; +import { EcommerceProductsService } from 'app/main/apps/e-commerce/products/products.service'; +import { EcommerceProductComponent } from 'app/main/apps/e-commerce/product/product.component'; +import { EcommerceProductService } from 'app/main/apps/e-commerce/product/product.service'; +import { EcommerceOrdersComponent } from 'app/main/apps/e-commerce/orders/orders.component'; +import { EcommerceOrdersService } from 'app/main/apps/e-commerce/orders/orders.service'; +import { EcommerceOrderComponent } from 'app/main/apps/e-commerce/order/order.component'; +import { EcommerceOrderService } from 'app/main/apps/e-commerce/order/order.service'; const routes: Routes = [ { path : 'dashboard', - component: FuseEcommerceDashboardComponent, + component: EcommerceDashboardComponent, resolve : { data: EcommerceDashboardService } }, { path : 'products', - component: FuseEcommerceProductsComponent, + component: EcommerceProductsComponent, resolve : { data: EcommerceProductsService } }, { path : 'products/:id', - component: FuseEcommerceProductComponent, + component: EcommerceProductComponent, resolve : { data: EcommerceProductService } }, { path : 'products/:id/:handle', - component: FuseEcommerceProductComponent, + component: EcommerceProductComponent, resolve : { data: EcommerceProductService } }, { path : 'orders', - component: FuseEcommerceOrdersComponent, + component: EcommerceOrdersComponent, resolve : { data: EcommerceOrdersService } }, { path : 'orders/:id', - component: FuseEcommerceOrderComponent, + component: EcommerceOrderComponent, resolve : { data: EcommerceOrderService } @@ -68,11 +66,11 @@ const routes: Routes = [ @NgModule({ declarations: [ - FuseEcommerceDashboardComponent, - FuseEcommerceProductsComponent, - FuseEcommerceProductComponent, - FuseEcommerceOrdersComponent, - FuseEcommerceOrderComponent + EcommerceDashboardComponent, + EcommerceProductsComponent, + EcommerceProductComponent, + EcommerceOrdersComponent, + EcommerceOrderComponent ], imports : [ RouterModule.forChild(routes), @@ -87,6 +85,7 @@ const routes: Routes = [ MatRippleModule, MatSelectModule, MatSortModule, + MatSnackBarModule, MatTableModule, MatTabsModule, @@ -106,6 +105,6 @@ const routes: Routes = [ EcommerceOrderService ] }) -export class FuseEcommerceModule +export class EcommerceModule { } diff --git a/src/app/main/apps/e-commerce/order/order.component.ts b/src/app/main/apps/e-commerce/order/order.component.ts index be7260a3..e51c56e8 100644 --- a/src/app/main/apps/e-commerce/order/order.component.ts +++ b/src/app/main/apps/e-commerce/order/order.component.ts @@ -1,12 +1,13 @@ import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core'; import { FormBuilder, FormGroup } from '@angular/forms'; -import { Subscription } from 'rxjs'; +import { Subject} from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import { fuseAnimations } from '@fuse/animations'; -import { Order } from './order.model'; -import { EcommerceOrderService } from './order.service'; -import { orderStatuses } from './order-statuses'; +import { orderStatuses } from 'app/main/apps/e-commerce/order/order-statuses'; +import { Order } from 'app/main/apps/e-commerce/order/order.model'; +import { EcommerceOrderService } from 'app/main/apps/e-commerce/order/order.service'; @Component({ selector : 'fuse-e-commerce-order', @@ -15,41 +16,73 @@ import { orderStatuses } from './order-statuses'; encapsulation: ViewEncapsulation.None, animations : fuseAnimations }) -export class FuseEcommerceOrderComponent implements OnInit, OnDestroy +export class EcommerceOrderComponent implements OnInit, OnDestroy { - order = new Order(); - onOrderChanged: Subscription; + order: Order; + orderStatuses: any; statusForm: FormGroup; - orderStatuses = orderStatuses; + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {EcommerceOrderService} _ecommerceOrderService + * @param {FormBuilder} _formBuilder + */ constructor( - private orderService: EcommerceOrderService, - private formBuilder: FormBuilder, + private _ecommerceOrderService: EcommerceOrderService, + private _formBuilder: FormBuilder ) { + // Set the defaults + this.order = new Order(); + this.orderStatuses = orderStatuses; + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { // Subscribe to update order on changes - this.onOrderChanged = - this.orderService.onOrderChanged - .subscribe(order => { - this.order = new Order(order); - }); + this._ecommerceOrderService.onOrderChanged + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(order => { + this.order = new Order(order); + }); - this.statusForm = this.formBuilder.group({ + this.statusForm = this._formBuilder.group({ newStatus: [''] }); } - ngOnDestroy() + /** + * On destroy + */ + ngOnDestroy(): void { - this.onOrderChanged.unsubscribe(); + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); } - updateStatus() + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Update status + */ + updateStatus(): void { const newStatusId = Number.parseInt(this.statusForm.get('newStatus').value); diff --git a/src/app/main/apps/e-commerce/order/order.model.ts b/src/app/main/apps/e-commerce/order/order.model.ts index 9c2fb68d..dd3d4a39 100644 --- a/src/app/main/apps/e-commerce/order/order.model.ts +++ b/src/app/main/apps/e-commerce/order/order.model.ts @@ -15,6 +15,11 @@ export class Order payment: any; shippingDetails: any[]; + /** + * Constructor + * + * @param order + */ constructor(order?) { order = order || {}; diff --git a/src/app/main/apps/e-commerce/order/order.service.ts b/src/app/main/apps/e-commerce/order/order.service.ts index b1f74180..46a7f2fc 100644 --- a/src/app/main/apps/e-commerce/order/order.service.ts +++ b/src/app/main/apps/e-commerce/order/order.service.ts @@ -10,21 +10,26 @@ export class EcommerceOrderService implements Resolve order: any; onOrderChanged: BehaviorSubject = new BehaviorSubject({}); + /** + * Constructor + * + * @param {HttpClient} _httpClient + */ constructor( - private http: HttpClient + private _httpClient: HttpClient ) { } /** - * Resolve + * Resolver + * * @param {ActivatedRouteSnapshot} route * @param {RouterStateSnapshot} state * @returns {Observable | Promise | any} */ resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | Promise | any { - this.routeParams = route.params; return new Promise((resolve, reject) => { @@ -40,10 +45,15 @@ export class EcommerceOrderService implements Resolve }); } + /** + * Get order + * + * @returns {Promise} + */ getOrder(): Promise { return new Promise((resolve, reject) => { - this.http.get('api/e-commerce-orders/' + this.routeParams.id) + this._httpClient.get('api/e-commerce-orders/' + this.routeParams.id) .subscribe((response: any) => { this.order = response; this.onOrderChanged.next(this.order); @@ -52,20 +62,32 @@ export class EcommerceOrderService implements Resolve }); } - saveOrder(order) + /** + * Save order + * + * @param order + * @returns {Promise} + */ + saveOrder(order): Promise { return new Promise((resolve, reject) => { - this.http.post('api/e-commerce-orders/' + order.id, order) + this._httpClient.post('api/e-commerce-orders/' + order.id, order) .subscribe((response: any) => { resolve(response); }, reject); }); } - addOrder(order) + /** + * Add order + * + * @param order + * @returns {Promise} + */ + addOrder(order): Promise { return new Promise((resolve, reject) => { - this.http.post('api/e-commerce-orders/', order) + this._httpClient.post('api/e-commerce-orders/', order) .subscribe((response: any) => { resolve(response); }, reject); diff --git a/src/app/main/apps/e-commerce/orders/orders.component.ts b/src/app/main/apps/e-commerce/orders/orders.component.ts index abc86808..5b1582ab 100644 --- a/src/app/main/apps/e-commerce/orders/orders.component.ts +++ b/src/app/main/apps/e-commerce/orders/orders.component.ts @@ -1,58 +1,117 @@ -import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'; +import { Component, ElementRef, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { MatPaginator, MatSort } from '@angular/material'; import { DataSource } from '@angular/cdk/collections'; - -import { merge, Observable, BehaviorSubject, fromEvent } from 'rxjs'; +import { merge, Observable, BehaviorSubject, fromEvent, Subject } from 'rxjs'; import { debounceTime, distinctUntilChanged, map } from 'rxjs/operators'; import { fuseAnimations } from '@fuse/animations'; import { FuseUtils } from '@fuse/utils'; -import { EcommerceOrdersService } from './orders.service'; +import { EcommerceOrdersService } from 'app/main/apps/e-commerce/orders/orders.service'; +import { takeUntil } from 'rxjs/internal/operators'; @Component({ - selector : 'fuse-e-commerce-orders', + selector : 'e-commerce-orders', templateUrl: './orders.component.html', styleUrls : ['./orders.component.scss'], animations : fuseAnimations }) -export class FuseEcommerceOrdersComponent implements OnInit +export class EcommerceOrdersComponent implements OnInit, OnDestroy { dataSource: FilesDataSource | null; displayedColumns = ['id', 'reference', 'customer', 'total', 'payment', 'status', 'date']; - @ViewChild(MatPaginator) paginator: MatPaginator; - @ViewChild('filter') filter: ElementRef; - @ViewChild(MatSort) sort: MatSort; + @ViewChild(MatPaginator) + paginator: MatPaginator; + @ViewChild('filter') + filter: ElementRef; + + @ViewChild(MatSort) + sort: MatSort; + + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {EcommerceOrdersService} _ecommerceOrdersService + */ constructor( - private ordersService: EcommerceOrdersService + private _ecommerceOrdersService: EcommerceOrdersService ) { + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() - { - this.dataSource = new FilesDataSource(this.ordersService, this.paginator, this.sort); + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- - fromEvent(this.filter.nativeElement, 'keyup').pipe( - debounceTime(150), - distinctUntilChanged() - ).subscribe(() => { - if ( !this.dataSource ) - { - return; - } - this.dataSource.filter = this.filter.nativeElement.value; - }); + /** + * On init + */ + ngOnInit(): void + { + this.dataSource = new FilesDataSource(this._ecommerceOrdersService, this.paginator, this.sort); + + fromEvent(this.filter.nativeElement, 'keyup') + .pipe( + takeUntil(this._unsubscribeAll), + debounceTime(150), + distinctUntilChanged() + ) + .subscribe(() => { + if ( !this.dataSource ) + { + return; + } + this.dataSource.filter = this.filter.nativeElement.value; + }); + } + + /** + * On destroy + */ + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); } } export class FilesDataSource extends DataSource { - _filterChange = new BehaviorSubject(''); - _filteredDataChange = new BehaviorSubject(''); + // Private + private _filterChange = new BehaviorSubject(''); + private _filteredDataChange = new BehaviorSubject(''); + /** + * Constructor + * + * @param {EcommerceOrdersService} _ecommerceOrdersService + * @param {MatPaginator} _matPaginator + * @param {MatSort} _matSort + */ + constructor( + private _ecommerceOrdersService: EcommerceOrdersService, + private _matPaginator: MatPaginator, + private _matSort: MatSort + ) + { + super(); + + this.filteredData = this._ecommerceOrdersService.orders; + } + + // ----------------------------------------------------------------------------------------------------- + // @ Accessors + // ----------------------------------------------------------------------------------------------------- + + // Filtered data get filteredData(): any { return this._filteredDataChange.value; @@ -63,6 +122,7 @@ export class FilesDataSource extends DataSource this._filteredDataChange.next(value); } + // Filter get filter(): string { return this._filterChange.value; @@ -73,29 +133,27 @@ export class FilesDataSource extends DataSource this._filterChange.next(filter); } - constructor( - private ordersService: EcommerceOrdersService, - private _paginator: MatPaginator, - private _sort: MatSort - ) - { - super(); - this.filteredData = this.ordersService.orders; - } + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- - /** Connect function called by the table to retrieve one stream containing the data to render. */ + /** + * Connect function called by the table to retrieve one stream containing the data to render. + * + * @returns {Observable} + */ connect(): Observable { const displayDataChanges = [ - this.ordersService.onOrdersChanged, - this._paginator.page, + this._ecommerceOrdersService.onOrdersChanged, + this._matPaginator.page, this._filterChange, - this._sort.sortChange + this._matSort.sortChange ]; return merge(...displayDataChanges).pipe(map(() => { - let data = this.ordersService.orders.slice(); + let data = this._ecommerceOrdersService.orders.slice(); data = this.filterData(data); @@ -104,14 +162,20 @@ export class FilesDataSource extends DataSource data = this.sortData(data); // Grab the page's slice of data. - const startIndex = this._paginator.pageIndex * this._paginator.pageSize; - return data.splice(startIndex, this._paginator.pageSize); + const startIndex = this._matPaginator.pageIndex * this._matPaginator.pageSize; + return data.splice(startIndex, this._matPaginator.pageSize); }) ); } - filterData(data) + /** + * Filter data + * + * @param data + * @returns {any} + */ + filterData(data): any { if ( !this.filter ) { @@ -120,9 +184,15 @@ export class FilesDataSource extends DataSource return FuseUtils.filterArrayByString(data, this.filter); } + /** + * Sort data + * + * @param data + * @returns {any[]} + */ sortData(data): any[] { - if ( !this._sort.active || this._sort.direction === '' ) + if ( !this._matSort.active || this._matSort.direction === '' ) { return data; } @@ -131,7 +201,7 @@ export class FilesDataSource extends DataSource let propertyA: number | string = ''; let propertyB: number | string = ''; - switch ( this._sort.active ) + switch ( this._matSort.active ) { case 'id': [propertyA, propertyB] = [a.id, b.id]; @@ -159,11 +229,14 @@ export class FilesDataSource extends DataSource const valueA = isNaN(+propertyA) ? propertyA : +propertyA; const valueB = isNaN(+propertyB) ? propertyB : +propertyB; - return (valueA < valueB ? -1 : 1) * (this._sort.direction === 'asc' ? 1 : -1); + return (valueA < valueB ? -1 : 1) * (this._matSort.direction === 'asc' ? 1 : -1); }); } - disconnect() + /** + * Disconnect + */ + disconnect(): void { } } diff --git a/src/app/main/apps/e-commerce/orders/orders.service.ts b/src/app/main/apps/e-commerce/orders/orders.service.ts index 4ade65c8..e557807a 100644 --- a/src/app/main/apps/e-commerce/orders/orders.service.ts +++ b/src/app/main/apps/e-commerce/orders/orders.service.ts @@ -9,21 +9,26 @@ export class EcommerceOrdersService implements Resolve orders: any[]; onOrdersChanged: BehaviorSubject = new BehaviorSubject({}); + /** + * Constructor + * + * @param {HttpClient} _httpClient + */ constructor( - private http: HttpClient + private _httpClient: HttpClient ) { } /** - * Resolve + * Resolver + * * @param {ActivatedRouteSnapshot} route * @param {RouterStateSnapshot} state * @returns {Observable | Promise | any} */ resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | Promise | any { - return new Promise((resolve, reject) => { Promise.all([ @@ -37,10 +42,15 @@ export class EcommerceOrdersService implements Resolve }); } + /** + * Get orders + * + * @returns {Promise} + */ getOrders(): Promise { return new Promise((resolve, reject) => { - this.http.get('api/e-commerce-orders') + this._httpClient.get('api/e-commerce-orders') .subscribe((response: any) => { this.orders = response; this.onOrdersChanged.next(this.orders); diff --git a/src/app/main/apps/e-commerce/product/product.component.ts b/src/app/main/apps/e-commerce/product/product.component.ts index 76eba648..01a9918a 100644 --- a/src/app/main/apps/e-commerce/product/product.component.ts +++ b/src/app/main/apps/e-commerce/product/product.component.ts @@ -1,68 +1,105 @@ import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core'; import { FormBuilder, FormGroup } from '@angular/forms'; +import { Location } from '@angular/common'; import { MatSnackBar } from '@angular/material'; -import { Subscription } from 'rxjs'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import { fuseAnimations } from '@fuse/animations'; import { FuseUtils } from '@fuse/utils'; -import { Product } from './product.model'; -import { EcommerceProductService } from './product.service'; -import { Location } from '@angular/common'; +import { Product } from 'app/main/apps/e-commerce/product/product.model'; +import { EcommerceProductService } from 'app/main/apps/e-commerce/product/product.service'; @Component({ - selector : 'fuse-e-commerce-product', + selector : 'e-commerce-product', templateUrl : './product.component.html', styleUrls : ['./product.component.scss'], encapsulation: ViewEncapsulation.None, animations : fuseAnimations }) -export class FuseEcommerceProductComponent implements OnInit, OnDestroy +export class EcommerceProductComponent implements OnInit, OnDestroy { - product = new Product(); - onProductChanged: Subscription; + product: Product; pageType: string; productForm: FormGroup; + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {EcommerceProductService} _ecommerceProductService + * @param {FormBuilder} _formBuilder + * @param {Location} _location + * @param {MatSnackBar} _matSnackBar + */ constructor( - private productService: EcommerceProductService, - private formBuilder: FormBuilder, - public snackBar: MatSnackBar, - private location: Location + private _ecommerceProductService: EcommerceProductService, + private _formBuilder: FormBuilder, + private _location: Location, + private _matSnackBar: MatSnackBar ) { + // Set the default + this.product = new Product(); + + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { // Subscribe to update product on changes - this.onProductChanged = - this.productService.onProductChanged - .subscribe(product => { + this._ecommerceProductService.onProductChanged + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(product => { - if ( product ) - { - this.product = new Product(product); - this.pageType = 'edit'; - } - else - { - this.pageType = 'new'; - this.product = new Product(); - } + if ( product ) + { + this.product = new Product(product); + this.pageType = 'edit'; + } + else + { + this.pageType = 'new'; + this.product = new Product(); + } - this.productForm = this.createProductForm(); - }); + this.productForm = this.createProductForm(); + }); } - ngOnDestroy() + /** + * On destroy + */ + ngOnDestroy(): void { - this.onProductChanged.unsubscribe(); + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); } - createProductForm() + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Create product form + * + * @returns {FormGroup} + */ + createProductForm(): FormGroup { - return this.formBuilder.group({ + return this._formBuilder.group({ id : [this.product.id], name : [this.product.name], handle : [this.product.handle], @@ -85,42 +122,50 @@ export class FuseEcommerceProductComponent implements OnInit, OnDestroy }); } - saveProduct() + /** + * Save product + */ + saveProduct(): void { const data = this.productForm.getRawValue(); data.handle = FuseUtils.handleize(data.name); - this.productService.saveProduct(data) + + this._ecommerceProductService.saveProduct(data) .then(() => { // Trigger the subscription with new data - this.productService.onProductChanged.next(data); + this._ecommerceProductService.onProductChanged.next(data); // Show the success message - this.snackBar.open('Product saved', 'OK', { + this._matSnackBar.open('Product saved', 'OK', { verticalPosition: 'top', duration : 2000 }); }); } - addProduct() + /** + * Add product + */ + addProduct(): void { const data = this.productForm.getRawValue(); data.handle = FuseUtils.handleize(data.name); - this.productService.addProduct(data) + + this._ecommerceProductService.addProduct(data) .then(() => { // Trigger the subscription with new data - this.productService.onProductChanged.next(data); + this._ecommerceProductService.onProductChanged.next(data); // Show the success message - this.snackBar.open('Product added', 'OK', { + this._matSnackBar.open('Product added', 'OK', { verticalPosition: 'top', duration : 2000 }); // Change the location with new one - this.location.go('apps/e-commerce/products/' + this.product.id + '/' + this.product.handle); + this._location.go('apps/e-commerce/products/' + this.product.id + '/' + this.product.handle); }); } } diff --git a/src/app/main/apps/e-commerce/product/product.model.ts b/src/app/main/apps/e-commerce/product/product.model.ts index a77e2596..3195482e 100644 --- a/src/app/main/apps/e-commerce/product/product.model.ts +++ b/src/app/main/apps/e-commerce/product/product.model.ts @@ -29,6 +29,11 @@ export class Product extraShippingFee: number; active: boolean; + /** + * Constructor + * + * @param product + */ constructor(product?) { product = product || {}; @@ -53,6 +58,11 @@ export class Product this.active = product.active || true; } + /** + * Add category + * + * @param {MatChipInputEvent} event + */ addCategory(event: MatChipInputEvent): void { const input = event.input; @@ -71,7 +81,12 @@ export class Product } } - removeCategory(category) + /** + * Remove category + * + * @param category + */ + removeCategory(category): void { const index = this.categories.indexOf(category); @@ -81,6 +96,11 @@ export class Product } } + /** + * Add tag + * + * @param {MatChipInputEvent} event + */ addTag(event: MatChipInputEvent): void { const input = event.input; @@ -99,7 +119,12 @@ export class Product } } - removeTag(tag) + /** + * Remove tag + * + * @param tag + */ + removeTag(tag): void { const index = this.tags.indexOf(tag); diff --git a/src/app/main/apps/e-commerce/product/product.service.ts b/src/app/main/apps/e-commerce/product/product.service.ts index 50f4aa73..70e79e47 100644 --- a/src/app/main/apps/e-commerce/product/product.service.ts +++ b/src/app/main/apps/e-commerce/product/product.service.ts @@ -10,21 +10,26 @@ export class EcommerceProductService implements Resolve product: any; onProductChanged: BehaviorSubject = new BehaviorSubject({}); + /** + * Constructor + * + * @param {HttpClient} _httpClient + */ constructor( - private http: HttpClient + private _httpClient: HttpClient ) { } /** - * Resolve + * Resolver + * * @param {ActivatedRouteSnapshot} route * @param {RouterStateSnapshot} state * @returns {Observable | Promise | any} */ resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | Promise | any { - this.routeParams = route.params; return new Promise((resolve, reject) => { @@ -40,6 +45,11 @@ export class EcommerceProductService implements Resolve }); } + /** + * Get product + * + * @returns {Promise} + */ getProduct(): Promise { return new Promise((resolve, reject) => { @@ -50,7 +60,7 @@ export class EcommerceProductService implements Resolve } else { - this.http.get('api/e-commerce-products/' + this.routeParams.id) + this._httpClient.get('api/e-commerce-products/' + this.routeParams.id) .subscribe((response: any) => { this.product = response; this.onProductChanged.next(this.product); @@ -60,20 +70,32 @@ export class EcommerceProductService implements Resolve }); } - saveProduct(product) + /** + * Save product + * + * @param product + * @returns {Promise} + */ + saveProduct(product): Promise { return new Promise((resolve, reject) => { - this.http.post('api/e-commerce-products/' + product.id, product) + this._httpClient.post('api/e-commerce-products/' + product.id, product) .subscribe((response: any) => { resolve(response); }, reject); }); } - addProduct(product) + /** + * Add product + * + * @param product + * @returns {Promise} + */ + addProduct(product): Promise { return new Promise((resolve, reject) => { - this.http.post('api/e-commerce-products/', product) + this._httpClient.post('api/e-commerce-products/', product) .subscribe((response: any) => { resolve(response); }, reject); diff --git a/src/app/main/apps/e-commerce/products/products.component.ts b/src/app/main/apps/e-commerce/products/products.component.ts index 4b36e25f..7a3df669 100644 --- a/src/app/main/apps/e-commerce/products/products.component.ts +++ b/src/app/main/apps/e-commerce/products/products.component.ts @@ -1,59 +1,134 @@ import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'; import { MatPaginator, MatSort } from '@angular/material'; import { DataSource } from '@angular/cdk/collections'; - -import { merge, Observable, BehaviorSubject, fromEvent } from 'rxjs'; +import { merge, Observable, BehaviorSubject, fromEvent, Subject } from 'rxjs'; import { debounceTime, distinctUntilChanged, map } from 'rxjs/operators'; import { fuseAnimations } from '@fuse/animations'; import { FuseUtils } from '@fuse/utils'; -import { EcommerceProductsService } from './products.service'; +import { EcommerceProductsService } from 'app/main/apps/e-commerce/products/products.service'; +import { takeUntil } from 'rxjs/internal/operators'; @Component({ - selector : 'fuse-e-commerce-products', + selector : 'e-commerce-products', templateUrl: './products.component.html', styleUrls : ['./products.component.scss'], animations : fuseAnimations }) -export class FuseEcommerceProductsComponent implements OnInit +export class EcommerceProductsComponent implements OnInit { dataSource: FilesDataSource | null; displayedColumns = ['id', 'image', 'name', 'category', 'price', 'quantity', 'active']; - @ViewChild(MatPaginator) paginator: MatPaginator; - @ViewChild('filter') filter: ElementRef; - @ViewChild(MatSort) sort: MatSort; + @ViewChild(MatPaginator) + paginator: MatPaginator; + + @ViewChild(MatSort) + sort: MatSort; + + @ViewChild('filter') + filter: ElementRef; + + // Private + private _unsubscribeAll: Subject; constructor( - private productsService: EcommerceProductsService + private _ecommerceProductsService: EcommerceProductsService ) { + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { - this.dataSource = new FilesDataSource(this.productsService, this.paginator, this.sort); + this.dataSource = new FilesDataSource(this._ecommerceProductsService, this.paginator, this.sort); - fromEvent(this.filter.nativeElement, 'keyup').pipe( - debounceTime(150), - distinctUntilChanged() - ).subscribe(() => { - if ( !this.dataSource ) - { - return; - } + fromEvent(this.filter.nativeElement, 'keyup') + .pipe( + takeUntil(this._unsubscribeAll), + debounceTime(150), + distinctUntilChanged() + ) + .subscribe(() => { + if ( !this.dataSource ) + { + return; + } - this.dataSource.filter = this.filter.nativeElement.value; - }); + this.dataSource.filter = this.filter.nativeElement.value; + }); } } export class FilesDataSource extends DataSource { - _filterChange = new BehaviorSubject(''); - _filteredDataChange = new BehaviorSubject(''); + private _filterChange = new BehaviorSubject(''); + private _filteredDataChange = new BehaviorSubject(''); + /** + * Constructor + * + * @param {EcommerceProductsService} _ecommerceProductsService + * @param {MatPaginator} _matPaginator + * @param {MatSort} _matSort + */ + constructor( + private _ecommerceProductsService: EcommerceProductsService, + private _matPaginator: MatPaginator, + private _matSort: MatSort + ) + { + super(); + + this.filteredData = this._ecommerceProductsService.products; + } + + /** + * Connect function called by the table to retrieve one stream containing the data to render. + * + * @returns {Observable} + */ + connect(): Observable + { + const displayDataChanges = [ + this._ecommerceProductsService.onProductsChanged, + this._matPaginator.page, + this._filterChange, + this._matSort.sortChange + ]; + + return merge(...displayDataChanges) + .pipe( + map(() => { + let data = this._ecommerceProductsService.products.slice(); + + data = this.filterData(data); + + this.filteredData = [...data]; + + data = this.sortData(data); + + // Grab the page's slice of data. + const startIndex = this._matPaginator.pageIndex * this._matPaginator.pageSize; + return data.splice(startIndex, this._matPaginator.pageSize); + } + )); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Accessors + // ----------------------------------------------------------------------------------------------------- + + // Filtered data get filteredData(): any { return this._filteredDataChange.value; @@ -64,6 +139,7 @@ export class FilesDataSource extends DataSource this._filteredDataChange.next(value); } + // Filter get filter(): string { return this._filterChange.value; @@ -74,44 +150,17 @@ export class FilesDataSource extends DataSource this._filterChange.next(filter); } - constructor( - private productsService: EcommerceProductsService, - private _paginator: MatPaginator, - private _sort: MatSort - ) - { - super(); - this.filteredData = this.productsService.products; - } + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- - /** Connect function called by the table to retrieve one stream containing the data to render. */ - connect(): Observable - { - const displayDataChanges = [ - this.productsService.onProductsChanged, - this._paginator.page, - this._filterChange, - this._sort.sortChange - ]; - - return merge(...displayDataChanges).pipe(map(() => { - - let data = this.productsService.products.slice(); - - data = this.filterData(data); - - this.filteredData = [...data]; - - data = this.sortData(data); - - // Grab the page's slice of data. - const startIndex = this._paginator.pageIndex * this._paginator.pageSize; - return data.splice(startIndex, this._paginator.pageSize); - } - )); - } - - filterData(data) + /** + * Filter data + * + * @param data + * @returns {any} + */ + filterData(data): any { if ( !this.filter ) { @@ -120,11 +169,15 @@ export class FilesDataSource extends DataSource return FuseUtils.filterArrayByString(data, this.filter); } - sortData(data) - : - any[] + /** + * Sort data + * + * @param data + * @returns {any[]} + */ + sortData(data): any[] { - if ( !this._sort.active || this._sort.direction === '' ) + if ( !this._matSort.active || this._matSort.direction === '' ) { return data; } @@ -133,7 +186,7 @@ export class FilesDataSource extends DataSource let propertyA: number | string = ''; let propertyB: number | string = ''; - switch ( this._sort.active ) + switch ( this._matSort.active ) { case 'id': [propertyA, propertyB] = [a.id, b.id]; @@ -158,11 +211,14 @@ export class FilesDataSource extends DataSource const valueA = isNaN(+propertyA) ? propertyA : +propertyA; const valueB = isNaN(+propertyB) ? propertyB : +propertyB; - return (valueA < valueB ? -1 : 1) * (this._sort.direction === 'asc' ? 1 : -1); + return (valueA < valueB ? -1 : 1) * (this._matSort.direction === 'asc' ? 1 : -1); }); } - disconnect() + /** + * Disconnect + */ + disconnect(): void { } } diff --git a/src/app/main/apps/e-commerce/products/products.service.ts b/src/app/main/apps/e-commerce/products/products.service.ts index 7b48839f..8c691e2e 100644 --- a/src/app/main/apps/e-commerce/products/products.service.ts +++ b/src/app/main/apps/e-commerce/products/products.service.ts @@ -9,21 +9,26 @@ export class EcommerceProductsService implements Resolve products: any[]; onProductsChanged: BehaviorSubject = new BehaviorSubject({}); + /** + * Constructor + * + * @param {HttpClient} _httpClient + */ constructor( - private http: HttpClient + private _httpClient: HttpClient ) { } /** - * Resolve + * Resolver + * * @param {ActivatedRouteSnapshot} route * @param {RouterStateSnapshot} state * @returns {Observable | Promise | any} */ resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | Promise | any { - return new Promise((resolve, reject) => { Promise.all([ @@ -37,10 +42,15 @@ export class EcommerceProductsService implements Resolve }); } + /** + * Get products + * + * @returns {Promise} + */ getProducts(): Promise { return new Promise((resolve, reject) => { - this.http.get('api/e-commerce-products') + this._httpClient.get('api/e-commerce-products') .subscribe((response: any) => { this.products = response; this.onProductsChanged.next(this.products); diff --git a/src/app/main/apps/file-manager/file-list/file-list.component.ts b/src/app/main/apps/file-manager/file-list/file-list.component.ts index e60a133e..1ae8d725 100644 --- a/src/app/main/apps/file-manager/file-list/file-list.component.ts +++ b/src/app/main/apps/file-manager/file-list/file-list.component.ts @@ -1,58 +1,118 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; import { DataSource } from '@angular/cdk/collections'; -import { Observable } from 'rxjs'; +import { Observable, Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; -import { FileManagerService } from '../file-manager.service'; -import { fuseAnimations } from '@fuse/animations/index'; +import { fuseAnimations } from '@fuse/animations'; + +import { FileManagerService } from 'app/main/apps/file-manager/file-manager.service'; @Component({ - selector : 'fuse-file-list', + selector : 'file-list', templateUrl: './file-list.component.html', styleUrls : ['./file-list.component.scss'], animations : fuseAnimations }) -export class FuseFileManagerFileListComponent implements OnInit +export class FileManagerFileListComponent implements OnInit, OnDestroy { files: any; dataSource: FilesDataSource | null; displayedColumns = ['icon', 'name', 'type', 'owner', 'size', 'modified', 'detail-button']; selected: any; - constructor(private fileManagerService: FileManagerService) + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {FileManagerService} _fileManagerService + */ + constructor( + private _fileManagerService: FileManagerService + ) { - this.fileManagerService.onFilesChanged.subscribe(files => { - this.files = files; - }); - this.fileManagerService.onFileSelected.subscribe(selected => { - this.selected = selected; - }); + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { - this.dataSource = new FilesDataSource(this.fileManagerService); + this.dataSource = new FilesDataSource(this._fileManagerService); + + this._fileManagerService.onFilesChanged + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(files => { + this.files = files; + }); + + this._fileManagerService.onFileSelected + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(selected => { + this.selected = selected; + }); } - onSelect(selected) + /** + * On destroy + */ + ngOnDestroy(): void { - this.fileManagerService.onFileSelected.next(selected); + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * On select + * + * @param selected + */ + onSelect(selected): void + { + this._fileManagerService.onFileSelected.next(selected); } } export class FilesDataSource extends DataSource { - constructor(private fileManagerService: FileManagerService) + /** + * Constructor + * + * @param {FileManagerService} _fileManagerService + */ + constructor( + private _fileManagerService: FileManagerService + ) { super(); } - /** Connect function called by the table to retrieve one stream containing the data to render. */ + /** + * Connect function called by the table to retrieve one stream containing the data to render. + * + * @returns {Observable} + */ connect(): Observable { - return this.fileManagerService.onFilesChanged; + return this._fileManagerService.onFilesChanged; } - disconnect() + /** + * Disconnect + */ + disconnect(): void { } } diff --git a/src/app/main/apps/file-manager/file-manager.component.html b/src/app/main/apps/file-manager/file-manager.component.html index 8c45ef3d..c8edfce0 100644 --- a/src/app/main/apps/file-manager/file-manager.component.html +++ b/src/app/main/apps/file-manager/file-manager.component.html @@ -5,7 +5,7 @@ - + @@ -61,7 +61,7 @@
- +
@@ -71,7 +71,7 @@ - + diff --git a/src/app/main/apps/file-manager/file-manager.component.ts b/src/app/main/apps/file-manager/file-manager.component.ts index d7a76819..16ac95f0 100644 --- a/src/app/main/apps/file-manager/file-manager.component.ts +++ b/src/app/main/apps/file-manager/file-manager.component.ts @@ -1,30 +1,63 @@ -import { Component, OnInit, ViewEncapsulation } from '@angular/core'; +import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import { fuseAnimations } from '@fuse/animations'; -import { FileManagerService } from './file-manager.service'; +import { FileManagerService } from 'app/main/apps/file-manager/file-manager.service'; @Component({ - selector : 'fuse-file-manager', + selector : 'file-manager', templateUrl : './file-manager.component.html', styleUrls : ['./file-manager.component.scss'], encapsulation: ViewEncapsulation.None, animations : fuseAnimations }) -export class FuseFileManagerComponent implements OnInit +export class FileManagerComponent implements OnInit, OnDestroy { selected: any; pathArr: string[]; - constructor(private fileManagerService: FileManagerService) + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {FileManagerService} _fileManagerService + */ + constructor( + private _fileManagerService: FileManagerService + ) { + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { - this.fileManagerService.onFileSelected.subscribe(selected => { + this._fileManagerService.onFileSelected + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(selected => { this.selected = selected; this.pathArr = selected.location.split('>'); }); } + + /** + * On destroy + */ + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); + } } diff --git a/src/app/main/apps/file-manager/file-manager.module.ts b/src/app/main/apps/file-manager/file-manager.module.ts index ed33ee01..b6f0d7bf 100644 --- a/src/app/main/apps/file-manager/file-manager.module.ts +++ b/src/app/main/apps/file-manager/file-manager.module.ts @@ -1,21 +1,20 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { CdkTableModule } from '@angular/cdk/table'; - import { MatButtonModule, MatIconModule, MatRippleModule, MatSidenavModule, MatSlideToggleModule, MatTableModule } from '@angular/material'; import { FuseSharedModule } from '@fuse/shared.module'; -import { FuseFileManagerComponent } from './file-manager.component'; -import { FileManagerService } from './file-manager.service'; -import { FuseFileManagerFileListComponent } from './file-list/file-list.component'; -import { FuseFileManagerMainSidenavComponent } from './sidenavs/main/main.component'; -import { FuseFileManagerDetailsSidenavComponent } from './sidenavs/details/details.component'; +import { FileManagerService } from 'app/main/apps/file-manager/file-manager.service'; +import { FileManagerComponent } from 'app/main/apps/file-manager/file-manager.component'; +import { FileManagerDetailsSidenavComponent } from 'app/main/apps/file-manager/sidenavs/details/details.component'; +import { FileManagerFileListComponent } from 'app/main/apps/file-manager/file-list/file-list.component'; +import { FileManagerMainSidenavComponent } from 'app/main/apps/file-manager/sidenavs/main/main.component'; const routes: Routes = [ { path : '**', - component: FuseFileManagerComponent, + component: FileManagerComponent, children : [], resolve : { files: FileManagerService @@ -25,10 +24,10 @@ const routes: Routes = [ @NgModule({ declarations: [ - FuseFileManagerComponent, - FuseFileManagerFileListComponent, - FuseFileManagerMainSidenavComponent, - FuseFileManagerDetailsSidenavComponent + FileManagerComponent, + FileManagerFileListComponent, + FileManagerMainSidenavComponent, + FileManagerDetailsSidenavComponent ], imports : [ RouterModule.forChild(routes), @@ -47,6 +46,6 @@ const routes: Routes = [ FileManagerService ] }) -export class FuseFileManagerModule +export class FileManagerModule { } diff --git a/src/app/main/apps/file-manager/file-manager.service.ts b/src/app/main/apps/file-manager/file-manager.service.ts index 0ef8bf8d..d8affd98 100644 --- a/src/app/main/apps/file-manager/file-manager.service.ts +++ b/src/app/main/apps/file-manager/file-manager.service.ts @@ -9,12 +9,19 @@ export class FileManagerService implements Resolve onFilesChanged: BehaviorSubject = new BehaviorSubject({}); onFileSelected: BehaviorSubject = new BehaviorSubject({}); - constructor(private http: HttpClient) + /** + * Constructor + * + * @param {HttpClient} _httpClient + */ + constructor( + private _httpClient: HttpClient + ) { } /** - * The File Manager App Main Resolver + * Resolver * * @param {ActivatedRouteSnapshot} route * @param {RouterStateSnapshot} state @@ -22,7 +29,6 @@ export class FileManagerService implements Resolve */ resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | Promise | any { - return new Promise((resolve, reject) => { Promise.all([ @@ -36,10 +42,15 @@ export class FileManagerService implements Resolve }); } + /** + * Get files + * + * @returns {Promise} + */ getFiles(): Promise { return new Promise((resolve, reject) => { - this.http.get('api/file-manager') + this._httpClient.get('api/file-manager') .subscribe((response: any) => { this.onFilesChanged.next(response); this.onFileSelected.next(response[0]); diff --git a/src/app/main/apps/file-manager/sidenavs/details/details.component.ts b/src/app/main/apps/file-manager/sidenavs/details/details.component.ts index 61385322..b6327e9b 100644 --- a/src/app/main/apps/file-manager/sidenavs/details/details.component.ts +++ b/src/app/main/apps/file-manager/sidenavs/details/details.component.ts @@ -1,30 +1,60 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; -import { fuseAnimations } from '@fuse/animations/index'; +import { fuseAnimations } from '@fuse/animations'; -import { FileManagerService } from '../../file-manager.service'; +import { FileManagerService } from 'app/main/apps/file-manager/file-manager.service'; @Component({ - selector : 'fuse-file-manager-details-sidenav', + selector : 'file-manager-details-sidenav', templateUrl: './details.component.html', styleUrls : ['./details.component.scss'], animations : fuseAnimations }) -export class FuseFileManagerDetailsSidenavComponent implements OnInit +export class FileManagerDetailsSidenavComponent implements OnInit, OnDestroy { - selected: any; - constructor(private fileManagerService: FileManagerService) - { + // Private + private _unsubscribeAll: Subject; + /** + * Constructor + * + * @param {FileManagerService} _fileManagerService + */ + constructor( + private _fileManagerService: FileManagerService + ) + { + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { - this.fileManagerService.onFileSelected.subscribe(selected => { - this.selected = selected; - }); + this._fileManagerService.onFileSelected + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(selected => { + this.selected = selected; + }); } + /** + * On destroy + */ + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); + } } diff --git a/src/app/main/apps/file-manager/sidenavs/main/main.component.ts b/src/app/main/apps/file-manager/sidenavs/main/main.component.ts index eea05124..817f6fb3 100644 --- a/src/app/main/apps/file-manager/sidenavs/main/main.component.ts +++ b/src/app/main/apps/file-manager/sidenavs/main/main.component.ts @@ -1,11 +1,11 @@ import { Component } from '@angular/core'; @Component({ - selector : 'fuse-file-manager-main-sidenav', + selector : 'file-manager-main-sidenav', templateUrl: './main.component.html', styleUrls : ['./main.component.scss'] }) -export class FuseFileManagerMainSidenavComponent +export class FileManagerMainSidenavComponent { selected: any; diff --git a/src/app/main/apps/mail-ngrx/mail.component.ts b/src/app/main/apps/mail-ngrx/mail.component.ts index c218a5d0..9fbbcad6 100644 --- a/src/app/main/apps/mail-ngrx/mail.component.ts +++ b/src/app/main/apps/mail-ngrx/mail.component.ts @@ -52,9 +52,9 @@ export class FuseMailNgrxComponent implements OnInit, OnDestroy this.mails = []; this.selectedMailIds = []; - this.configService.setConfig({ + this.configService.config = { routerAnimation: 'none' - }); + }; } ngOnInit() diff --git a/src/app/main/components-third-party/components-third-party.module.ts b/src/app/main/components-third-party/components-third-party.module.ts index afd4ef64..0b9ae8c9 100644 --- a/src/app/main/components-third-party/components-third-party.module.ts +++ b/src/app/main/components-third-party/components-third-party.module.ts @@ -1,15 +1,12 @@ import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; - import { MatButtonModule, MatCheckboxModule, MatIconModule } from '@angular/material'; - import { NgxDatatableModule } from '@swimlane/ngx-datatable'; import { FuseSharedModule } from '@fuse/shared.module'; -import { GoogleMapsModule } from './google-maps/google-maps.module'; - -import { FuseNgxDatatableComponent } from './datatable/ngx-datatable.component'; +import { GoogleMapsModule } from 'app/main/components-third-party/google-maps/google-maps.module'; +import { FuseNgxDatatableComponent } from 'app/main/components-third-party/datatable/ngx-datatable.component'; const routes = [ { @@ -36,6 +33,6 @@ const routes = [ GoogleMapsModule ], }) -export class FuseComponentsThirdPartyModule +export class ComponentsThirdPartyModule { } diff --git a/src/app/main/components/angular-material/angular-material.module.ts b/src/app/main/components/angular-material/angular-material.module.ts index da8cee00..2d7420d3 100644 --- a/src/app/main/components/angular-material/angular-material.module.ts +++ b/src/app/main/components/angular-material/angular-material.module.ts @@ -1,15 +1,14 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; -import { MaterialModule } from 'app/main/content/components/angular-material/material.module'; - import { FuseSharedModule } from '@fuse/shared.module'; import { FuseHighlightModule } from '@fuse/components'; import { FuseWidgetModule } from '@fuse/components/widget/widget.module'; -import { EXAMPLE_LIST } from './example-components'; -import { FuseExampleViewerComponent } from './example-viewer/example-viewer'; -import { FuseAngularMaterialComponent } from './angular-material.component'; +import { MaterialModule } from 'app/main/components/angular-material/material.module'; +import { EXAMPLE_LIST } from 'app/main/components/angular-material/example-components'; +import { FuseAngularMaterialComponent } from 'app/main/components/angular-material/angular-material.component'; +import { FuseExampleViewerComponent } from 'app/main/components/angular-material/example-viewer/example-viewer'; const routes: Routes = [ { diff --git a/src/app/main/components/components.module.ts b/src/app/main/components/components.module.ts index cbd8af11..e324f324 100644 --- a/src/app/main/components/components.module.ts +++ b/src/app/main/components/components.module.ts @@ -1,24 +1,20 @@ import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; - import { MatButtonModule, MatButtonToggleModule, MatFormFieldModule, MatIconModule, MatListModule, MatMenuModule, MatSelectModule, MatSlideToggleModule, MatTabsModule } from '@angular/material'; - import { NgxChartsModule } from '@swimlane/ngx-charts'; import { FuseSharedModule } from '@fuse/shared.module'; import { FuseCountdownModule, FuseHighlightModule, FuseMaterialColorPickerModule, FuseWidgetModule } from '@fuse/components'; - -import { FuseAngularMaterialModule } from './angular-material/angular-material.module'; -import { FuseCardsDocsComponent } from './cards/cards.component'; -import { FuseCountdownDocsComponent } from './countdown/countdown.component'; -import { FuseHighlightDocsComponent } from './highlight/highlight.component'; -import { FuseMaterialColorPickerDocsComponent } from './material-color-picker/material-color-picker.component'; -import { FuseMultiLanguageDocsComponent } from './multi-language/multi-language.component'; -import { FuseNavigationDocsComponent } from './navigation/navigation.component'; -import { FuseSearchBarDocsComponent } from './search-bar/search-bar.component'; -import { FuseSidebarDocsComponent } from './sidebar/sidebar.component'; -import { FuseShortcutsDocsComponent } from './shortcuts/shortcuts.component'; -import { FuseWidgetDocsComponent } from './widget/widget.component'; +import { FuseCardsDocsComponent } from 'app/main/components/cards/cards.component'; +import { FuseCountdownDocsComponent } from 'app/main/components/countdown/countdown.component'; +import { FuseHighlightDocsComponent } from 'app/main/components/highlight/highlight.component'; +import { FuseMaterialColorPickerDocsComponent } from 'app/main/components/material-color-picker/material-color-picker.component'; +import { FuseMultiLanguageDocsComponent } from 'app/main/components/multi-language/multi-language.component'; +import { FuseNavigationDocsComponent } from 'app/main/components/navigation/navigation.component'; +import { FuseSearchBarDocsComponent } from 'app/main/components/search-bar/search-bar.component'; +import { FuseSidebarDocsComponent } from 'app/main/components/sidebar/sidebar.component'; +import { FuseShortcutsDocsComponent } from 'app/main/components/shortcuts/shortcuts.component'; +import { FuseWidgetDocsComponent } from 'app/main/components/widget/widget.component'; const routes = [ { @@ -99,6 +95,6 @@ const routes = [ FuseAngularMaterialModule ] }) -export class FuseComponentsModule +export class ComponentsModule { } diff --git a/src/app/main/pages/authentication/forgot-password-2/forgot-password-2.component.ts b/src/app/main/pages/authentication/forgot-password-2/forgot-password-2.component.ts index 18752dc5..ec751674 100644 --- a/src/app/main/pages/authentication/forgot-password-2/forgot-password-2.component.ts +++ b/src/app/main/pages/authentication/forgot-password-2/forgot-password-2.component.ts @@ -1,50 +1,92 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import { FuseConfigService } from '@fuse/services/config.service'; import { fuseAnimations } from '@fuse/animations'; @Component({ - selector : 'fuse-forgot-password-2', + selector : 'forgot-password-2', templateUrl: './forgot-password-2.component.html', styleUrls : ['./forgot-password-2.component.scss'], animations : fuseAnimations }) -export class FuseForgotPassword2Component implements OnInit +export class ForgotPassword2Component implements OnInit, OnDestroy { forgotPasswordForm: FormGroup; forgotPasswordFormErrors: any; + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {FuseConfigService} _fuseConfigService + * @param {FormBuilder} _formBuilder + */ constructor( - private fuseConfig: FuseConfigService, - private formBuilder: FormBuilder + private _fuseConfigService: FuseConfigService, + private _formBuilder: FormBuilder ) { - this.fuseConfig.setConfig({ + // Configure the layout + this._fuseConfigService.config = { layout: { navigation: 'none', toolbar : 'none', footer : 'none' } - }); + }; + // Set the defaults this.forgotPasswordFormErrors = { email: {} }; + + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { - this.forgotPasswordForm = this.formBuilder.group({ + this.forgotPasswordForm = this._formBuilder.group({ email: ['', [Validators.required, Validators.email]] }); - this.forgotPasswordForm.valueChanges.subscribe(() => { - this.onForgotPasswordFormValuesChanged(); - }); + this.forgotPasswordForm.valueChanges + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { + this.onForgotPasswordFormValuesChanged(); + }); } - onForgotPasswordFormValuesChanged() + /** + * On destroy + */ + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * On form values changed + */ + onForgotPasswordFormValuesChanged(): void { for ( const field in this.forgotPasswordFormErrors ) { diff --git a/src/app/main/pages/authentication/forgot-password-2/forgot-password-2.module.ts b/src/app/main/pages/authentication/forgot-password-2/forgot-password-2.module.ts index 8192d5d0..bc985e94 100644 --- a/src/app/main/pages/authentication/forgot-password-2/forgot-password-2.module.ts +++ b/src/app/main/pages/authentication/forgot-password-2/forgot-password-2.module.ts @@ -1,22 +1,21 @@ import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; - import { MatButtonModule, MatFormFieldModule, MatInputModule } from '@angular/material'; import { FuseSharedModule } from '@fuse/shared.module'; -import { FuseForgotPassword2Component } from './forgot-password-2.component'; +import { ForgotPassword2Component } from 'app/main/pages/authentication/forgot-password-2/forgot-password-2.component'; const routes = [ { path : 'auth/forgot-password-2', - component: FuseForgotPassword2Component + component: ForgotPassword2Component } ]; @NgModule({ declarations: [ - FuseForgotPassword2Component + ForgotPassword2Component ], imports : [ RouterModule.forChild(routes), diff --git a/src/app/main/pages/authentication/forgot-password/forgot-password.component.ts b/src/app/main/pages/authentication/forgot-password/forgot-password.component.ts index eebeacf7..f27a85dd 100644 --- a/src/app/main/pages/authentication/forgot-password/forgot-password.component.ts +++ b/src/app/main/pages/authentication/forgot-password/forgot-password.component.ts @@ -1,50 +1,92 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import { FuseConfigService } from '@fuse/services/config.service'; import { fuseAnimations } from '@fuse/animations'; @Component({ - selector : 'fuse-forgot-password', + selector : 'forgot-password', templateUrl: './forgot-password.component.html', styleUrls : ['./forgot-password.component.scss'], animations : fuseAnimations }) -export class FuseForgotPasswordComponent implements OnInit +export class ForgotPasswordComponent implements OnInit, OnDestroy { forgotPasswordForm: FormGroup; forgotPasswordFormErrors: any; + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {FuseConfigService} _fuseConfigService + * @param {FormBuilder} _formBuilder + */ constructor( - private fuseConfig: FuseConfigService, - private formBuilder: FormBuilder + private _fuseConfigService: FuseConfigService, + private _formBuilder: FormBuilder ) { - this.fuseConfig.setConfig({ + // Configure the layout + this._fuseConfigService.config = { layout: { navigation: 'none', toolbar : 'none', footer : 'none' } - }); + }; + // Set the defaults this.forgotPasswordFormErrors = { email: {} }; + + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { - this.forgotPasswordForm = this.formBuilder.group({ + this.forgotPasswordForm = this._formBuilder.group({ email: ['', [Validators.required, Validators.email]] }); - this.forgotPasswordForm.valueChanges.subscribe(() => { - this.onForgotPasswordFormValuesChanged(); - }); + this.forgotPasswordForm.valueChanges + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { + this.onForgotPasswordFormValuesChanged(); + }); } - onForgotPasswordFormValuesChanged() + /** + * On destroy + */ + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * On form values changed + */ + onForgotPasswordFormValuesChanged(): void { for ( const field in this.forgotPasswordFormErrors ) { diff --git a/src/app/main/pages/authentication/forgot-password/forgot-password.module.ts b/src/app/main/pages/authentication/forgot-password/forgot-password.module.ts index 719e4496..c9ac1439 100644 --- a/src/app/main/pages/authentication/forgot-password/forgot-password.module.ts +++ b/src/app/main/pages/authentication/forgot-password/forgot-password.module.ts @@ -1,22 +1,21 @@ import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; - import { MatButtonModule, MatFormFieldModule, MatInputModule } from '@angular/material'; import { FuseSharedModule } from '@fuse/shared.module'; -import { FuseForgotPasswordComponent } from './forgot-password.component'; +import { ForgotPasswordComponent } from 'app/main/pages/authentication/forgot-password/forgot-password.component'; const routes = [ { path : 'auth/forgot-password', - component: FuseForgotPasswordComponent + component: ForgotPasswordComponent } ]; @NgModule({ declarations: [ - FuseForgotPasswordComponent + ForgotPasswordComponent ], imports : [ RouterModule.forChild(routes), @@ -25,7 +24,7 @@ const routes = [ MatFormFieldModule, MatInputModule, - FuseSharedModule, + FuseSharedModule ] }) export class ForgotPasswordModule diff --git a/src/app/main/pages/authentication/lock/lock.component.ts b/src/app/main/pages/authentication/lock/lock.component.ts index 11bd2125..ac1398a4 100644 --- a/src/app/main/pages/authentication/lock/lock.component.ts +++ b/src/app/main/pages/authentication/lock/lock.component.ts @@ -1,42 +1,65 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import { FuseConfigService } from '@fuse/services/config.service'; import { fuseAnimations } from '@fuse/animations'; @Component({ - selector : 'fuse-lock', + selector : 'lock', templateUrl: './lock.component.html', styleUrls : ['./lock.component.scss'], animations : fuseAnimations }) -export class FuseLockComponent implements OnInit +export class LockComponent implements OnInit, OnDestroy { lockForm: FormGroup; lockFormErrors: any; + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {FuseConfigService} _fuseConfigService + * @param {FormBuilder} _formBuilder + */ constructor( - private fuseConfig: FuseConfigService, - private formBuilder: FormBuilder + private _fuseConfigService: FuseConfigService, + private _formBuilder: FormBuilder ) { - this.fuseConfig.setConfig({ + // Configure the layout + this._fuseConfigService.config = { layout: { navigation: 'none', toolbar : 'none', footer : 'none' } - }); + }; + // Set the defaults this.lockFormErrors = { username: {}, password: {} }; + + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { - this.lockForm = this.formBuilder.group({ + this.lockForm = this._formBuilder.group({ username: [ { value : 'Katherine', @@ -46,12 +69,31 @@ export class FuseLockComponent implements OnInit password: ['', Validators.required] }); - this.lockForm.valueChanges.subscribe(() => { - this.onLockFormValuesChanged(); - }); + this.lockForm.valueChanges + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { + this.onLockFormValuesChanged(); + }); } - onLockFormValuesChanged() + /** + * On destroy + */ + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * On form values changed + */ + onLockFormValuesChanged(): void { for ( const field in this.lockFormErrors ) { diff --git a/src/app/main/pages/authentication/lock/lock.module.ts b/src/app/main/pages/authentication/lock/lock.module.ts index 0488d20b..22b267f2 100644 --- a/src/app/main/pages/authentication/lock/lock.module.ts +++ b/src/app/main/pages/authentication/lock/lock.module.ts @@ -1,22 +1,21 @@ import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; - import { MatButtonModule, MatFormFieldModule, MatIconModule, MatInputModule } from '@angular/material'; import { FuseSharedModule } from '@fuse/shared.module'; -import { FuseLockComponent } from './lock.component'; +import { LockComponent } from 'app/main/pages/authentication/lock/lock.component'; const routes = [ { path : 'auth/lock', - component: FuseLockComponent + component: LockComponent } ]; @NgModule({ declarations: [ - FuseLockComponent + LockComponent ], imports : [ RouterModule.forChild(routes), diff --git a/src/app/main/pages/authentication/login-2/login-2.component.ts b/src/app/main/pages/authentication/login-2/login-2.component.ts index bc735783..0531a0e2 100644 --- a/src/app/main/pages/authentication/login-2/login-2.component.ts +++ b/src/app/main/pages/authentication/login-2/login-2.component.ts @@ -1,52 +1,94 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import { FuseConfigService } from '@fuse/services/config.service'; import { fuseAnimations } from '@fuse/animations'; @Component({ - selector : 'fuse-login-2', + selector : 'login-2', templateUrl: './login-2.component.html', styleUrls : ['./login-2.component.scss'], animations : fuseAnimations }) -export class FuseLogin2Component implements OnInit +export class Login2Component implements OnInit, OnDestroy { loginForm: FormGroup; loginFormErrors: any; + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {FuseConfigService} _fuseConfigService + * @param {FormBuilder} _formBuilder + */ constructor( - private fuseConfig: FuseConfigService, - private formBuilder: FormBuilder + private _fuseConfigService: FuseConfigService, + private _formBuilder: FormBuilder ) { - this.fuseConfig.setConfig({ + // Configure the layout + this._fuseConfigService.config = { layout: { navigation: 'none', toolbar : 'none', footer : 'none' } - }); + }; + // Set the defaults this.loginFormErrors = { email : {}, password: {} }; + + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { - this.loginForm = this.formBuilder.group({ + this.loginForm = this._formBuilder.group({ email : ['', [Validators.required, Validators.email]], password: ['', Validators.required] }); - this.loginForm.valueChanges.subscribe(() => { - this.onLoginFormValuesChanged(); - }); + this.loginForm.valueChanges + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { + this.onLoginFormValuesChanged(); + }); } - onLoginFormValuesChanged() + /** + * On destroy + */ + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * On form values changed + */ + onLoginFormValuesChanged(): void { for ( const field in this.loginFormErrors ) { diff --git a/src/app/main/pages/authentication/login-2/login-2.module.ts b/src/app/main/pages/authentication/login-2/login-2.module.ts index 9f7f932d..d8f653a7 100644 --- a/src/app/main/pages/authentication/login-2/login-2.module.ts +++ b/src/app/main/pages/authentication/login-2/login-2.module.ts @@ -1,22 +1,21 @@ import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; - import { MatButtonModule, MatCheckboxModule, MatFormFieldModule, MatInputModule } from '@angular/material'; import { FuseSharedModule } from '@fuse/shared.module'; -import { FuseLogin2Component } from './login-2.component'; +import { Login2Component } from 'app/main/pages/authentication/login-2/login-2.component'; const routes = [ { path : 'auth/login-2', - component: FuseLogin2Component + component: Login2Component } ]; @NgModule({ declarations: [ - FuseLogin2Component + Login2Component ], imports : [ RouterModule.forChild(routes), diff --git a/src/app/main/pages/authentication/login/login.component.ts b/src/app/main/pages/authentication/login/login.component.ts index 85e8a952..6f272924 100644 --- a/src/app/main/pages/authentication/login/login.component.ts +++ b/src/app/main/pages/authentication/login/login.component.ts @@ -1,52 +1,94 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import { FuseConfigService } from '@fuse/services/config.service'; import { fuseAnimations } from '@fuse/animations'; @Component({ - selector : 'fuse-login', + selector : 'login', templateUrl: './login.component.html', styleUrls : ['./login.component.scss'], animations : fuseAnimations }) -export class FuseLoginComponent implements OnInit +export class LoginComponent implements OnInit, OnDestroy { loginForm: FormGroup; loginFormErrors: any; + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {FuseConfigService} _fuseConfigService + * @param {FormBuilder} _formBuilder + */ constructor( - private fuseConfig: FuseConfigService, - private formBuilder: FormBuilder + private _fuseConfigService: FuseConfigService, + private _formBuilder: FormBuilder ) { - this.fuseConfig.setConfig({ + // Configure the layout + this._fuseConfigService.config = { layout: { navigation: 'none', toolbar : 'none', footer : 'none' } - }); + }; + // Set the defaults this.loginFormErrors = { email : {}, password: {} }; + + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { - this.loginForm = this.formBuilder.group({ + this.loginForm = this._formBuilder.group({ email : ['', [Validators.required, Validators.email]], password: ['', Validators.required] }); - this.loginForm.valueChanges.subscribe(() => { - this.onLoginFormValuesChanged(); - }); + this.loginForm.valueChanges + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { + this.onLoginFormValuesChanged(); + }); } - onLoginFormValuesChanged() + /** + * On destroy + */ + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * On form values changed + */ + onLoginFormValuesChanged(): void { for ( const field in this.loginFormErrors ) { diff --git a/src/app/main/pages/authentication/login/login.module.ts b/src/app/main/pages/authentication/login/login.module.ts index e5ea2e03..12d5eebd 100644 --- a/src/app/main/pages/authentication/login/login.module.ts +++ b/src/app/main/pages/authentication/login/login.module.ts @@ -1,22 +1,21 @@ import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; - import { MatButtonModule, MatCheckboxModule, MatFormFieldModule, MatInputModule } from '@angular/material'; import { FuseSharedModule } from '@fuse/shared.module'; -import { FuseLoginComponent } from './login.component'; +import { LoginComponent } from 'app/main/pages/authentication/login/login.component'; const routes = [ { path : 'auth/login', - component: FuseLoginComponent + component: LoginComponent } ]; @NgModule({ declarations: [ - FuseLoginComponent + LoginComponent ], imports : [ RouterModule.forChild(routes), diff --git a/src/app/main/pages/authentication/mail-confirm/mail-confirm.component.ts b/src/app/main/pages/authentication/mail-confirm/mail-confirm.component.ts index 8430d99d..56b6788e 100644 --- a/src/app/main/pages/authentication/mail-confirm/mail-confirm.component.ts +++ b/src/app/main/pages/authentication/mail-confirm/mail-confirm.component.ts @@ -9,19 +9,24 @@ import { fuseAnimations } from '@fuse/animations'; styleUrls : ['./mail-confirm.component.scss'], animations : fuseAnimations }) -export class FuseMailConfirmComponent +export class MailConfirmComponent { - + /** + * Constructor + * + * @param {FuseConfigService} _fuseConfigService + */ constructor( - private fuseConfig: FuseConfigService + private _fuseConfigService: FuseConfigService ) { - this.fuseConfig.setConfig({ + // Configure the layout + this._fuseConfigService.config = { layout: { navigation: 'none', toolbar : 'none', footer : 'none' } - }); + }; } } diff --git a/src/app/main/pages/authentication/mail-confirm/mail-confirm.module.ts b/src/app/main/pages/authentication/mail-confirm/mail-confirm.module.ts index 1c56c4a9..bdd2df19 100644 --- a/src/app/main/pages/authentication/mail-confirm/mail-confirm.module.ts +++ b/src/app/main/pages/authentication/mail-confirm/mail-confirm.module.ts @@ -1,22 +1,21 @@ import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; - import { MatIconModule } from '@angular/material'; import { FuseSharedModule } from '@fuse/shared.module'; -import { FuseMailConfirmComponent } from './mail-confirm.component'; +import { MailConfirmComponent } from 'app/main/pages/authentication/mail-confirm/mail-confirm.component'; const routes = [ { path : 'auth/mail-confirm', - component: FuseMailConfirmComponent + component: MailConfirmComponent } ]; @NgModule({ declarations: [ - FuseMailConfirmComponent + MailConfirmComponent ], imports : [ RouterModule.forChild(routes), diff --git a/src/app/main/pages/authentication/register-2/register-2.component.ts b/src/app/main/pages/authentication/register-2/register-2.component.ts index 2c2f3350..fb403b1f 100644 --- a/src/app/main/pages/authentication/register-2/register-2.component.ts +++ b/src/app/main/pages/authentication/register-2/register-2.component.ts @@ -1,56 +1,98 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import { FuseConfigService } from '@fuse/services/config.service'; import { fuseAnimations } from '@fuse/animations'; @Component({ - selector : 'fuse-register-2', + selector : 'register-2', templateUrl: './register-2.component.html', styleUrls : ['./register-2.component.scss'], animations : fuseAnimations }) -export class FuseRegister2Component implements OnInit +export class Register2Component implements OnInit, OnDestroy { registerForm: FormGroup; registerFormErrors: any; + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {FuseConfigService} _fuseConfigService + * @param {FormBuilder} _formBuilder + */ constructor( - private fuseConfig: FuseConfigService, - private formBuilder: FormBuilder + private _fuseConfigService: FuseConfigService, + private _formBuilder: FormBuilder ) { - this.fuseConfig.setConfig({ + // Configure the layout + this._fuseConfigService.config = { layout: { navigation: 'none', toolbar : 'none', footer : 'none' } - }); + }; + // Set the defaults this.registerFormErrors = { name : {}, email : {}, password : {}, passwordConfirm: {} }; + + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { - this.registerForm = this.formBuilder.group({ + this.registerForm = this._formBuilder.group({ name : ['', Validators.required], email : ['', [Validators.required, Validators.email]], password : ['', Validators.required], passwordConfirm: ['', [Validators.required, confirmPassword]] }); - this.registerForm.valueChanges.subscribe(() => { + this.registerForm.valueChanges + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { this.onRegisterFormValuesChanged(); }); } - onRegisterFormValuesChanged() + /** + * On destroy + */ + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * On form values changed + */ + onRegisterFormValuesChanged(): void { for ( const field in this.registerFormErrors ) { @@ -73,7 +115,13 @@ export class FuseRegister2Component implements OnInit } } -function confirmPassword(control: AbstractControl) +/** + * Confirm password + * + * @param {AbstractControl} control + * @returns {{passwordsNotMatch: boolean}} + */ +function confirmPassword(control: AbstractControl): any { if ( !control.parent || !control ) { diff --git a/src/app/main/pages/authentication/register-2/register-2.module.ts b/src/app/main/pages/authentication/register-2/register-2.module.ts index 68458fb5..3b689cb3 100644 --- a/src/app/main/pages/authentication/register-2/register-2.module.ts +++ b/src/app/main/pages/authentication/register-2/register-2.module.ts @@ -1,22 +1,21 @@ import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; - import { MatButtonModule, MatCheckboxModule, MatFormFieldModule, MatInputModule } from '@angular/material'; import { FuseSharedModule } from '@fuse/shared.module'; -import { FuseRegister2Component } from './register-2.component'; +import { Register2Component } from 'app/main/pages/authentication/register-2/register-2.component'; const routes = [ { path : 'auth/register-2', - component: FuseRegister2Component + component: Register2Component } ]; @NgModule({ declarations: [ - FuseRegister2Component + Register2Component ], imports : [ RouterModule.forChild(routes), diff --git a/src/app/main/pages/authentication/register/register.component.ts b/src/app/main/pages/authentication/register/register.component.ts index fea8d9ec..0002f0cd 100644 --- a/src/app/main/pages/authentication/register/register.component.ts +++ b/src/app/main/pages/authentication/register/register.component.ts @@ -1,56 +1,92 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms'; import { FuseConfigService } from '@fuse/services/config.service'; import { fuseAnimations } from '@fuse/animations'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/internal/operators'; @Component({ - selector : 'fuse-register', + selector : 'register', templateUrl: './register.component.html', styleUrls : ['./register.component.scss'], animations : fuseAnimations }) -export class FuseRegisterComponent implements OnInit +export class RegisterComponent implements OnInit, OnDestroy { registerForm: FormGroup; registerFormErrors: any; + // Private + private _unsubscribeAll: Subject; + constructor( - private fuseConfig: FuseConfigService, - private formBuilder: FormBuilder + private _fuseConfigService: FuseConfigService, + private _formBuilder: FormBuilder ) { - this.fuseConfig.setConfig({ + // Configure the layout + this._fuseConfigService.config = { layout: { navigation: 'none', toolbar : 'none', footer : 'none' } - }); + }; + // Set the defaults this.registerFormErrors = { name : {}, email : {}, password : {}, passwordConfirm: {} }; + + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { - this.registerForm = this.formBuilder.group({ + this.registerForm = this._formBuilder.group({ name : ['', Validators.required], email : ['', [Validators.required, Validators.email]], password : ['', Validators.required], passwordConfirm: ['', [Validators.required, confirmPassword]] }); - this.registerForm.valueChanges.subscribe(() => { - this.onRegisterFormValuesChanged(); - }); + this.registerForm.valueChanges + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { + this.onRegisterFormValuesChanged(); + }); } - onRegisterFormValuesChanged() + /** + * On destroy + */ + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * On form values changed + */ + onRegisterFormValuesChanged(): void { for ( const field in this.registerFormErrors ) { @@ -73,7 +109,13 @@ export class FuseRegisterComponent implements OnInit } } -function confirmPassword(control: AbstractControl) +/** + * Confirm password + * + * @param {AbstractControl} control + * @returns {{passwordsNotMatch: boolean}} + */ +function confirmPassword(control: AbstractControl): any { if ( !control.parent || !control ) { diff --git a/src/app/main/pages/authentication/register/register.module.ts b/src/app/main/pages/authentication/register/register.module.ts index f2c80a88..117198e9 100644 --- a/src/app/main/pages/authentication/register/register.module.ts +++ b/src/app/main/pages/authentication/register/register.module.ts @@ -1,22 +1,21 @@ import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; - import { MatButtonModule, MatCheckboxModule, MatFormFieldModule, MatInputModule } from '@angular/material'; import { FuseSharedModule } from '@fuse/shared.module'; -import { FuseRegisterComponent } from './register.component'; +import { RegisterComponent } from 'app/main/pages/authentication/register/register.component'; const routes = [ { path : 'auth/register', - component: FuseRegisterComponent + component: RegisterComponent } ]; @NgModule({ declarations: [ - FuseRegisterComponent + RegisterComponent ], imports : [ RouterModule.forChild(routes), diff --git a/src/app/main/pages/authentication/reset-password-2/reset-password-2.component.ts b/src/app/main/pages/authentication/reset-password-2/reset-password-2.component.ts index dea9e605..da812b29 100644 --- a/src/app/main/pages/authentication/reset-password-2/reset-password-2.component.ts +++ b/src/app/main/pages/authentication/reset-password-2/reset-password-2.component.ts @@ -1,54 +1,90 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms'; import { FuseConfigService } from '@fuse/services/config.service'; import { fuseAnimations } from '@fuse/animations'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/internal/operators'; @Component({ - selector : 'fuse-reset-password-2', + selector : 'reset-password-2', templateUrl: './reset-password-2.component.html', styleUrls : ['./reset-password-2.component.scss'], animations : fuseAnimations }) -export class FuseResetPassword2Component implements OnInit +export class ResetPassword2Component implements OnInit, OnDestroy { resetPasswordForm: FormGroup; resetPasswordFormErrors: any; + // Private + private _unsubscribeAll: Subject; + constructor( - private fuseConfig: FuseConfigService, - private formBuilder: FormBuilder + private _fuseConfigService: FuseConfigService, + private _formBuilder: FormBuilder ) { - this.fuseConfig.setConfig({ + // Configure the layout + this._fuseConfigService.config = { layout: { navigation: 'none', toolbar : 'none', footer : 'none' } - }); + }; + // Set the defaults this.resetPasswordFormErrors = { email : {}, password : {}, passwordConfirm: {} }; + + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { - this.resetPasswordForm = this.formBuilder.group({ + this.resetPasswordForm = this._formBuilder.group({ email : ['', [Validators.required, Validators.email]], password : ['', Validators.required], passwordConfirm: ['', [Validators.required, confirmPassword]] }); - this.resetPasswordForm.valueChanges.subscribe(() => { - this.onResetPasswordFormValuesChanged(); - }); + this.resetPasswordForm.valueChanges + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { + this.onResetPasswordFormValuesChanged(); + }); } - onResetPasswordFormValuesChanged() + /** + * On destroy + */ + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * On form values changed + */ + onResetPasswordFormValuesChanged(): void { for ( const field in this.resetPasswordFormErrors ) { @@ -71,7 +107,13 @@ export class FuseResetPassword2Component implements OnInit } } -function confirmPassword(control: AbstractControl) +/** + * Confirm password + * + * @param {AbstractControl} control + * @returns {{passwordsNotMatch: boolean}} + */ +function confirmPassword(control: AbstractControl): any { if ( !control.parent || !control ) { diff --git a/src/app/main/pages/authentication/reset-password-2/reset-password-2.module.ts b/src/app/main/pages/authentication/reset-password-2/reset-password-2.module.ts index ef10b6f8..5d70a2a0 100644 --- a/src/app/main/pages/authentication/reset-password-2/reset-password-2.module.ts +++ b/src/app/main/pages/authentication/reset-password-2/reset-password-2.module.ts @@ -1,22 +1,21 @@ import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; - import { MatButtonModule, MatFormFieldModule, MatInputModule } from '@angular/material'; import { FuseSharedModule } from '@fuse/shared.module'; -import { FuseResetPassword2Component } from './reset-password-2.component'; +import { ResetPassword2Component } from 'app/main/pages/authentication/reset-password-2/reset-password-2.component'; const routes = [ { path : 'auth/reset-password-2', - component: FuseResetPassword2Component + component: ResetPassword2Component } ]; @NgModule({ declarations: [ - FuseResetPassword2Component + ResetPassword2Component ], imports : [ RouterModule.forChild(routes), diff --git a/src/app/main/pages/authentication/reset-password/reset-password.component.ts b/src/app/main/pages/authentication/reset-password/reset-password.component.ts index 3c86a632..749d5a4b 100644 --- a/src/app/main/pages/authentication/reset-password/reset-password.component.ts +++ b/src/app/main/pages/authentication/reset-password/reset-password.component.ts @@ -1,54 +1,96 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import { FuseConfigService } from '@fuse/services/config.service'; import { fuseAnimations } from '@fuse/animations'; @Component({ - selector : 'fuse-reset-password', + selector : 'reset-password', templateUrl: './reset-password.component.html', styleUrls : ['./reset-password.component.scss'], animations : fuseAnimations }) -export class FuseResetPasswordComponent implements OnInit +export class ResetPasswordComponent implements OnInit, OnDestroy { resetPasswordForm: FormGroup; resetPasswordFormErrors: any; + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {FuseConfigService} _fuseConfigService + * @param {FormBuilder} _formBuilder + */ constructor( - private fuseConfig: FuseConfigService, - private formBuilder: FormBuilder + private _fuseConfigService: FuseConfigService, + private _formBuilder: FormBuilder ) { - this.fuseConfig.setConfig({ + // Configure the layout + this._fuseConfigService.config = { layout: { navigation: 'none', toolbar : 'none', footer : 'none' } - }); + }; + // Set the defaults this.resetPasswordFormErrors = { email : {}, password : {}, passwordConfirm: {} }; + + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { - this.resetPasswordForm = this.formBuilder.group({ + this.resetPasswordForm = this._formBuilder.group({ email : ['', [Validators.required, Validators.email]], password : ['', Validators.required], passwordConfirm: ['', [Validators.required, confirmPassword]] }); - this.resetPasswordForm.valueChanges.subscribe(() => { - this.onResetPasswordFormValuesChanged(); - }); + this.resetPasswordForm.valueChanges + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { + this.onResetPasswordFormValuesChanged(); + }); } - onResetPasswordFormValuesChanged() + /** + * On destroy + */ + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * On form values changed + */ + onResetPasswordFormValuesChanged(): void { for ( const field in this.resetPasswordFormErrors ) { @@ -71,7 +113,13 @@ export class FuseResetPasswordComponent implements OnInit } } -function confirmPassword(control: AbstractControl) +/** + * Confirm password + * + * @param {AbstractControl} control + * @returns {{passwordsNotMatch: boolean}} + */ +function confirmPassword(control: AbstractControl): any { if ( !control.parent || !control ) { diff --git a/src/app/main/pages/authentication/reset-password/reset-password.module.ts b/src/app/main/pages/authentication/reset-password/reset-password.module.ts index 21f8e358..ed454e5d 100644 --- a/src/app/main/pages/authentication/reset-password/reset-password.module.ts +++ b/src/app/main/pages/authentication/reset-password/reset-password.module.ts @@ -1,22 +1,21 @@ import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; - import { MatButtonModule, MatFormFieldModule, MatInputModule } from '@angular/material'; import { FuseSharedModule } from '@fuse/shared.module'; -import { FuseResetPasswordComponent } from './reset-password.component'; +import { ResetPasswordComponent } from 'app/main/pages/authentication/reset-password/reset-password.component'; const routes = [ { path : 'auth/reset-password', - component: FuseResetPasswordComponent + component: ResetPasswordComponent } ]; @NgModule({ declarations: [ - FuseResetPasswordComponent + ResetPasswordComponent ], imports : [ RouterModule.forChild(routes), diff --git a/src/app/main/pages/coming-soon/coming-soon.component.ts b/src/app/main/pages/coming-soon/coming-soon.component.ts index 53b252c1..ba95f31c 100644 --- a/src/app/main/pages/coming-soon/coming-soon.component.ts +++ b/src/app/main/pages/coming-soon/coming-soon.component.ts @@ -20,13 +20,13 @@ export class FuseComingSoonComponent implements OnInit private formBuilder: FormBuilder ) { - this.fuseConfig.setConfig({ + this.fuseConfig.config = { layout: { navigation: 'none', toolbar : 'none', footer : 'none' } - }); + }; this.comingSoonFormErrors = { email: {} diff --git a/src/app/main/pages/errors/404/error-404.component.ts b/src/app/main/pages/errors/404/error-404.component.ts index 135c99da..d1e1f17c 100644 --- a/src/app/main/pages/errors/404/error-404.component.ts +++ b/src/app/main/pages/errors/404/error-404.component.ts @@ -13,12 +13,12 @@ export class FuseError404Component private fuseConfig: FuseConfigService ) { - this.fuseConfig.setConfig({ + this.fuseConfig.config = { layout: { navigation: 'none', toolbar : 'none', footer : 'none' } - }); + }; } } diff --git a/src/app/main/pages/errors/500/error-500.component.ts b/src/app/main/pages/errors/500/error-500.component.ts index b4014e47..4225f9a9 100644 --- a/src/app/main/pages/errors/500/error-500.component.ts +++ b/src/app/main/pages/errors/500/error-500.component.ts @@ -13,12 +13,12 @@ export class FuseError500Component private fuseConfig: FuseConfigService ) { - this.fuseConfig.setConfig({ + this.fuseConfig.config = { layout: { navigation: 'none', toolbar : 'none', footer : 'none' } - }); + }; } } diff --git a/src/app/main/pages/maintenance/maintenance.component.ts b/src/app/main/pages/maintenance/maintenance.component.ts index 8ba28d25..cdedd8f7 100644 --- a/src/app/main/pages/maintenance/maintenance.component.ts +++ b/src/app/main/pages/maintenance/maintenance.component.ts @@ -15,12 +15,12 @@ export class FuseMaintenanceComponent private fuseConfig: FuseConfigService ) { - this.fuseConfig.setConfig({ + this.fuseConfig.config = { layout: { navigation: 'none', toolbar : 'none', footer : 'none' } - }); + }; } } diff --git a/src/app/main/pages/pages.module.ts b/src/app/main/pages/pages.module.ts index 96a6ba58..8cef2f0e 100644 --- a/src/app/main/pages/pages.module.ts +++ b/src/app/main/pages/pages.module.ts @@ -1,30 +1,30 @@ import { NgModule } from '@angular/core'; -import { LoginModule } from './authentication/login/login.module'; -import { Login2Module } from './authentication/login-2/login-2.module'; -import { RegisterModule } from './authentication/register/register.module'; -import { Register2Module } from './authentication/register-2/register-2.module'; -import { ForgotPasswordModule } from './authentication/forgot-password/forgot-password.module'; -import { ForgotPassword2Module } from './authentication/forgot-password-2/forgot-password-2.module'; -import { ResetPasswordModule } from './authentication/reset-password/reset-password.module'; -import { ResetPassword2Module } from './authentication/reset-password-2/reset-password-2.module'; -import { LockModule } from './authentication/lock/lock.module'; -import { MailConfirmModule } from './authentication/mail-confirm/mail-confirm.module'; -import { ComingSoonModule } from './coming-soon/coming-soon.module'; -import { Error404Module } from './errors/404/error-404.module'; -import { Error500Module } from './errors/500/error-500.module'; -import { InvoiceCompactModule } from './invoices/compact/compact.module'; -import { InvoiceModernModule } from './invoices/modern/modern.module'; -import { MaintenanceModule } from './maintenance/maintenence.module'; -import { PricingModule } from './pricing/pricing.module'; -import { ProfileModule } from './profile/profile.module'; -import { SearchModule } from './search/search.module'; -import { FaqModule } from './faq/faq.module'; -import { KnowledgeBaseModule } from './knowledge-base/knowledge-base.module'; +import { LoginModule } from 'app/main/pages/authentication/login/login.module'; +import { Login2Module } from 'app/main/pages/authentication/login-2/login-2.module'; +import { RegisterModule } from 'app/main/pages/authentication/register/register.module'; +import { Register2Module } from 'app/main/pages/authentication/register-2/register-2.module'; +import { ForgotPasswordModule } from 'app/main/pages/authentication/forgot-password/forgot-password.module'; +import { ForgotPassword2Module } from 'app/main/pages/authentication/forgot-password-2/forgot-password-2.module'; +import { ResetPasswordModule } from 'app/main/pages/authentication/reset-password/reset-password.module'; +import { ResetPassword2Module } from 'app/main/pages/authentication/reset-password-2/reset-password-2.module'; +import { LockModule } from 'app/main/pages/authentication/lock/lock.module'; +import { MailConfirmModule } from 'app/main/pages/authentication/mail-confirm/mail-confirm.module'; +import { ComingSoonModule } from 'app/main/pages/coming-soon/coming-soon.module'; +import { Error404Module } from 'app/main/pages/errors/404/error-404.module'; +import { Error500Module } from 'app/main/pages/errors/500/error-500.module'; +import { InvoiceModernModule } from 'app/main/pages/invoices/modern/modern.module'; +import { InvoiceCompactModule } from 'app/main/pages/invoices/compact/compact.module'; +import { MaintenanceModule } from 'app/main/pages/maintenance/maintenence.module'; +import { PricingModule } from 'app/main/pages/pricing/pricing.module'; +import { ProfileModule } from 'app/main/pages/profile/profile.module'; +import { SearchModule } from 'app/main/pages/search/search.module'; +import { FaqModule } from 'app/main/pages/faq/faq.module'; +import { KnowledgeBaseModule } from 'app/main/pages/knowledge-base/knowledge-base.module'; @NgModule({ imports: [ - // Auth + // Authentication LoginModule, Login2Module, RegisterModule, @@ -66,7 +66,7 @@ import { KnowledgeBaseModule } from './knowledge-base/knowledge-base.module'; KnowledgeBaseModule ] }) -export class FusePagesModule +export class PagesModule { } diff --git a/src/app/main/services/services.module.ts b/src/app/main/services/services.module.ts index 6c44c3b3..202d3b15 100644 --- a/src/app/main/services/services.module.ts +++ b/src/app/main/services/services.module.ts @@ -1,13 +1,12 @@ import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; - import { MatIconModule } from '@angular/material'; import { FuseSharedModule } from '@fuse/shared.module'; import { FuseHighlightModule } from '@fuse/components'; -import { FuseConfigServiceDocsComponent } from './config/config.component'; -import { FuseSplashScreenServiceDocsComponent } from './splash-screen/splash-screen.component'; +import { FuseConfigServiceDocsComponent } from 'app/main/services/config/config.component'; +import { FuseSplashScreenServiceDocsComponent } from 'app/main/services/splash-screen/splash-screen.component'; const routes = [ { @@ -35,6 +34,6 @@ const routes = [ ], }) -export class FuseServicesModule +export class ServicesModule { } diff --git a/src/app/main/ui/ui.module.ts b/src/app/main/ui/ui.module.ts index 31acd6a4..f6798a1c 100644 --- a/src/app/main/ui/ui.module.ts +++ b/src/app/main/ui/ui.module.ts @@ -1,11 +1,11 @@ import { NgModule } from '@angular/core'; -import { UIFormsModule } from './forms/forms.module'; -import { UIIconsModule } from './icons/icons.module'; -import { UITypographyModule } from './typography/typography.module'; -import { UIHelperClassesModule } from './helper-classes/helper-classes.module'; -import { UIPageLayoutsModule } from './page-layouts/page-layouts.module'; -import { UIColorsModule } from './colors/colors.module'; +import { UIFormsModule } from 'app/main/ui/forms/forms.module'; +import { UIIconsModule } from 'app/main/ui/icons/icons.module'; +import { UITypographyModule } from 'app/main/ui/typography/typography.module'; +import { UIHelperClassesModule } from 'app/main/ui/helper-classes/helper-classes.module'; +import { UIPageLayoutsModule } from 'app/main/ui/page-layouts/page-layouts.module'; +import { UIColorsModule } from 'app/main/ui/colors/colors.module'; @NgModule({ imports: [ diff --git a/src/app/store/actions/router.action.ts b/src/app/store/actions/router.action.ts index 52fcf954..169d86d6 100644 --- a/src/app/store/actions/router.action.ts +++ b/src/app/store/actions/router.action.ts @@ -9,6 +9,11 @@ export class Go implements Action { readonly type = GO; + /** + * Constructor + * + * @param {{path: any[]; query?: object; extras?: NavigationExtras}} payload + */ constructor( public payload: { path: any[]; diff --git a/src/app/store/effects/router.effect.ts b/src/app/store/effects/router.effect.ts index f0935b78..a9cbf25e 100644 --- a/src/app/store/effects/router.effect.ts +++ b/src/app/store/effects/router.effect.ts @@ -1,15 +1,21 @@ import { Injectable } from '@angular/core'; import { Router } from '@angular/router'; import { Location } from '@angular/common'; - import { Effect, Actions } from '@ngrx/effects'; -import * as RouterActions from '../actions/router.action'; - import { tap, map } from 'rxjs/operators'; +import * as RouterActions from 'app/store/actions/router.action'; + @Injectable() export class RouterEffects { + /** + * Constructor + * + * @param {Actions} actions$ + * @param {Router} router + * @param {Location} location + */ constructor( private actions$: Actions, private router: Router, @@ -18,6 +24,9 @@ export class RouterEffects { } + /** + * Navigate + */ @Effect({dispatch: false}) navigate$ = this.actions$.ofType(RouterActions.GO).pipe( map((action: RouterActions.Go) => action.payload), @@ -26,11 +35,19 @@ export class RouterEffects }) ); + /** + * Navigate back + * @type {Observable} + */ @Effect({dispatch: false}) navigateBack$ = this.actions$ .ofType(RouterActions.BACK) .pipe(tap(() => this.location.back())); + /** + * Navigate forward + * @type {Observable} + */ @Effect({dispatch: false}) navigateForward$ = this.actions$ .ofType(RouterActions.FORWARD) diff --git a/src/app/store/reducers/index.ts b/src/app/store/reducers/index.ts index 42278dca..d8d0c987 100644 --- a/src/app/store/reducers/index.ts +++ b/src/app/store/reducers/index.ts @@ -1,10 +1,5 @@ -import { - ActivatedRouteSnapshot, - RouterStateSnapshot, - Params -} from '@angular/router'; +import { ActivatedRouteSnapshot, RouterStateSnapshot, Params } from '@angular/router'; import { createFeatureSelector, ActionReducerMap } from '@ngrx/store'; - import * as fromRouter from '@ngrx/router-store'; export interface RouterStateUrl diff --git a/src/app/store/store.module.ts b/src/app/store/store.module.ts index 29e51c04..1db8e786 100644 --- a/src/app/store/store.module.ts +++ b/src/app/store/store.module.ts @@ -3,9 +3,10 @@ import { EffectsModule } from '@ngrx/effects'; import { MetaReducer, StoreModule } from '@ngrx/store'; import { NgModule } from '@angular/core'; import { storeFreeze } from 'ngrx-store-freeze'; -import { environment } from '../../environments/environment'; import { RouterStateSerializer, StoreRouterConnectingModule } from '@ngrx/router-store'; -import { reducers, effects, CustomSerializer } from './index'; + +import { environment } from 'environments/environment'; +import { reducers, effects, CustomSerializer } from 'app/store'; export const metaReducers: MetaReducer[] = !environment.production ? [storeFreeze] diff --git a/src/tslint.json b/src/tslint.json index 04494aa2..d88db874 100644 --- a/src/tslint.json +++ b/src/tslint.json @@ -4,14 +4,23 @@ "directive-selector": [ true, "attribute", - "fuse", + [ + "fuse", + "" + ], "camelCase" ], "component-selector": [ true, "element", - "fuse", - "kebab-case" + [ + "fuse", + "" + ], + [ + "kebab-case", + "camelCase" + ] ] } } diff --git a/tslint.json b/tslint.json index 6583c181..eca56dcb 100644 --- a/tslint.json +++ b/tslint.json @@ -90,6 +90,11 @@ true, "allow-null-check" ], + "typedef": [ + true, + "call-signature", + "property-declaration" + ], "typedef-whitespace": [ true, {