diff --git a/src/app/app.module.ts b/src/app/app.module.ts index de296e12..b664f2fb 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -3,6 +3,7 @@ import { BrowserModule } from '@angular/platform-browser'; import { HttpClientModule } from '@angular/common/http'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { RouterModule, Routes } from '@angular/router'; +import { MatMomentDateModule } from '@angular/material-moment-adapter'; import { InMemoryWebApiModule } from 'angular-in-memory-web-api'; import { TranslateModule } from '@ngx-translate/core'; import 'hammerjs'; @@ -64,6 +65,9 @@ const appRoutes: Routes = [ passThruUnknownUrl: true }), + // Material moment date module + MatMomentDateModule, + // Fuse modules FuseModule.forRoot(fuseConfig), FuseSharedModule, diff --git a/src/app/main/apps/academy/course.service.ts b/src/app/main/apps/academy/course.service.ts index 024a65cd..4143dd4e 100644 --- a/src/app/main/apps/academy/course.service.ts +++ b/src/app/main/apps/academy/course.service.ts @@ -6,7 +6,7 @@ import { BehaviorSubject, Observable } from 'rxjs'; @Injectable() export class AcademyCourseService implements Resolve { - onCourseChanged: BehaviorSubject = new BehaviorSubject({}); + onCourseChanged: BehaviorSubject; /** * Constructor @@ -17,6 +17,8 @@ export class AcademyCourseService implements Resolve private _httpClient: HttpClient ) { + // Set the defaults + this.onCourseChanged = new BehaviorSubject({}); } // ----------------------------------------------------------------------------------------------------- diff --git a/src/app/main/apps/academy/courses.service.ts b/src/app/main/apps/academy/courses.service.ts index 5f8776cb..06613028 100644 --- a/src/app/main/apps/academy/courses.service.ts +++ b/src/app/main/apps/academy/courses.service.ts @@ -6,8 +6,8 @@ import { BehaviorSubject, Observable } from 'rxjs'; @Injectable() export class AcademyCoursesService implements Resolve { - onCategoriesChanged: BehaviorSubject = new BehaviorSubject({}); - onCoursesChanged: BehaviorSubject = new BehaviorSubject({}); + onCategoriesChanged: BehaviorSubject; + onCoursesChanged: BehaviorSubject; /** * Constructor @@ -18,6 +18,9 @@ export class AcademyCoursesService implements Resolve private _httpClient: HttpClient ) { + // Set the defaults + this.onCategoriesChanged = new BehaviorSubject({}); + this.onCoursesChanged = new BehaviorSubject({}); } // ----------------------------------------------------------------------------------------------------- diff --git a/src/app/main/apps/apps.module.ts b/src/app/main/apps/apps.module.ts index 98a60a34..8ead8245 100644 --- a/src/app/main/apps/apps.module.ts +++ b/src/app/main/apps/apps.module.ts @@ -14,7 +14,7 @@ const routes = [ }, { path : 'mail', - loadChildren: './mail/mail.module#FuseMailModule' + loadChildren: './mail/mail.module#MailModule' }, { path : 'mail-ngrx', diff --git a/src/app/main/apps/calendar/calendar.module.ts b/src/app/main/apps/calendar/calendar.module.ts index e72231d6..dd9c0c0b 100644 --- a/src/app/main/apps/calendar/calendar.module.ts +++ b/src/app/main/apps/calendar/calendar.module.ts @@ -1,6 +1,6 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; -import { MatButtonModule, MatDatepickerModule, MatFormFieldModule, MatIconModule, MatInputModule, MatSlideToggleModule, MatToolbarModule } from '@angular/material'; +import { MatButtonModule, MatDatepickerModule, MatDialogModule, MatFormFieldModule, MatIconModule, MatInputModule, MatSlideToggleModule, MatToolbarModule } from '@angular/material'; import { ColorPickerModule } from 'ngx-color-picker'; import { CalendarModule as AngularCalendarModule } from 'angular-calendar'; @@ -32,6 +32,7 @@ const routes: Routes = [ MatButtonModule, MatDatepickerModule, + MatDialogModule, MatFormFieldModule, MatIconModule, MatInputModule, diff --git a/src/app/main/apps/calendar/calendar.service.ts b/src/app/main/apps/calendar/calendar.service.ts index 3d0554c3..21dc56e9 100644 --- a/src/app/main/apps/calendar/calendar.service.ts +++ b/src/app/main/apps/calendar/calendar.service.ts @@ -7,7 +7,7 @@ import { Observable, Subject } from 'rxjs'; export class CalendarService implements Resolve { events: any; - onEventsUpdated = new Subject(); + onEventsUpdated: Subject; /** * Constructor @@ -18,7 +18,8 @@ export class CalendarService implements Resolve private _httpClient: HttpClient ) { - + // Set the defaults + this.onEventsUpdated = new Subject(); } // ----------------------------------------------------------------------------------------------------- diff --git a/src/app/main/apps/calendar/event-form/event-form.component.html b/src/app/main/apps/calendar/event-form/event-form.component.html index 32a805f4..40deeb94 100644 --- a/src/app/main/apps/calendar/event-form/event-form.component.html +++ b/src/app/main/apps/calendar/event-form/event-form.component.html @@ -2,7 +2,7 @@ {{dialogTitle}} - @@ -117,7 +117,7 @@ @@ -98,7 +98,7 @@ @@ -86,7 +86,7 @@
- diff --git a/src/app/main/apps/mail-ngrx/dialogs/compose/compose.component.ts b/src/app/main/apps/mail-ngrx/dialogs/compose/compose.component.ts index 65286173..4e3d6d6f 100644 --- a/src/app/main/apps/mail-ngrx/dialogs/compose/compose.component.ts +++ b/src/app/main/apps/mail-ngrx/dialogs/compose/compose.component.ts @@ -3,27 +3,44 @@ import { FormBuilder, FormGroup } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material'; @Component({ - selector : 'fuse-mail-compose', + selector : 'mail-compose', templateUrl : './compose.component.html', styleUrls : ['./compose.component.scss'], encapsulation: ViewEncapsulation.None }) -export class FuseMailNgrxComposeDialogComponent +export class MailNgrxComposeDialogComponent { composeForm: FormGroup; + /** + * Constructor + * + * @param {MatDialogRef} _matDialogRef + * @param _data + * @param {FormBuilder} _formBuilder + */ constructor( - public dialogRef: MatDialogRef, - @Inject(MAT_DIALOG_DATA) private data: any, - private formBuilder: FormBuilder + private _matDialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) private _data: any, + private _formBuilder: FormBuilder ) { + // Set the defaults this.composeForm = this.createComposeForm(); } - - createComposeForm() + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Create compose form + * + * @returns {FormGroup} + */ + createComposeForm(): FormGroup { - return this.formBuilder.group({ + return this._formBuilder.group({ from : { value : ['johndoe@creapond.com'], disabled: [true] diff --git a/src/app/main/apps/mail-ngrx/mail-details/mail-details.component.ts b/src/app/main/apps/mail-ngrx/mail-details/mail-details.component.ts index f3640888..3c80a9e1 100644 --- a/src/app/main/apps/mail-ngrx/mail-details/mail-details.component.ts +++ b/src/app/main/apps/mail-ngrx/mail-details/mail-details.component.ts @@ -2,38 +2,62 @@ import { ChangeDetectionStrategy, Component, Input, OnChanges } from '@angular/c import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; -import { Mail } from '../mail.model'; -import * as fromStore from '../store'; -import { MailNgrxService } from '../mail.service'; +import { Mail } from 'app/main/apps/mail-ngrx/mail.model'; +import * as fromStore from 'app/main/apps/mail-ngrx/store'; +import { MailNgrxService } from 'app/main/apps/mail-ngrx/mail.service'; @Component({ - selector : 'fuse-mail-details', + selector : 'mail-details', templateUrl : './mail-details.component.html', styleUrls : ['./mail-details.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) -export class FuseMailNgrxDetailsComponent implements OnChanges +export class MailNgrxDetailsComponent implements OnChanges { - labels$: Observable; - @Input('mail') mailInput: Mail; - mail: Mail; - showDetails = false; + @Input('mail') + mailInput: Mail; + labels$: Observable; + mail: Mail; + showDetails: boolean; + + /** + * Constructor + * + * @param {MailNgrxService} _mailNgrxService + * @param {Store} _store + */ constructor( - private mailService: MailNgrxService, - private store: Store + private _mailNgrxService: MailNgrxService, + private _store: Store ) { - this.labels$ = this.store.select(fromStore.getLabelsArr); + // Set the defaults + this.labels$ = this._store.select(fromStore.getLabelsArr); + this.showDetails = false; } - ngOnChanges() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On changes + */ + ngOnChanges(): void { this.updateModel(this.mailInput); this.markAsRead(); } - markAsRead() + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Mark as read + */ + markAsRead(): void { if ( this.mail && !this.mail.read ) { @@ -42,28 +66,46 @@ export class FuseMailNgrxDetailsComponent implements OnChanges } } - toggleStar(event) + /** + * Toggle star + * + * @param event + */ + toggleStar(event): void { event.stopPropagation(); this.mail.toggleStar(); this.updateMail(); } - toggleImportant(event) + /** + * Toggle important + * + * @param event + */ + toggleImportant(event): void { event.stopPropagation(); this.mail.toggleImportant(); this.updateMail(); } - updateModel(data) + /** + * Update model + * + * @param data + */ + updateModel(data): void { this.mail = !data ? null : new Mail({...data}); } - updateMail() + /** + * Update the mail + */ + updateMail(): void { - this.store.dispatch(new fromStore.UpdateMail(this.mail)); + this._store.dispatch(new fromStore.UpdateMail(this.mail)); this.updateModel(this.mail); } } diff --git a/src/app/main/apps/mail-ngrx/mail-list/mail-list-item/mail-list-item.component.ts b/src/app/main/apps/mail-ngrx/mail-list/mail-list-item/mail-list-item.component.ts index f4a2d719..4ec6b611 100644 --- a/src/app/main/apps/mail-ngrx/mail-list/mail-list-item/mail-list-item.component.ts +++ b/src/app/main/apps/mail-ngrx/mail-list/mail-list-item/mail-list-item.component.ts @@ -7,12 +7,12 @@ import { Mail } from '../../mail.model'; import * as fromStore from '../../store'; @Component({ - selector : 'fuse-mail-list-item', + selector : 'mail-list-item', templateUrl : './mail-list-item.component.html', styleUrls : ['./mail-list-item.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) -export class FuseMailNgrxListItemComponent implements OnInit +export class MailNgrxListItemComponent implements OnInit { @Input() mail: Mail; @HostBinding('class.selected') selected: boolean; diff --git a/src/app/main/apps/mail-ngrx/mail-list/mail-list.component.html b/src/app/main/apps/mail-ngrx/mail-list/mail-list.component.html index bb5903db..94e1ff3b 100644 --- a/src/app/main/apps/mail-ngrx/mail-list/mail-list.component.html +++ b/src/app/main/apps/mail-ngrx/mail-list/mail-list.component.html @@ -3,7 +3,7 @@
- - + +
diff --git a/src/app/main/apps/mail-ngrx/mail-list/mail-list.component.ts b/src/app/main/apps/mail-ngrx/mail-list/mail-list.component.ts index 0b1c0ac7..54237b1e 100644 --- a/src/app/main/apps/mail-ngrx/mail-list/mail-list.component.ts +++ b/src/app/main/apps/mail-ngrx/mail-list/mail-list.component.ts @@ -1,49 +1,64 @@ import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; -import { Mail } from '../mail.model'; -import { MailNgrxService } from '../mail.service'; +import { Mail } from 'app/main/apps/mail-ngrx/mail.model'; +import { MailNgrxService } from 'app/main/apps/mail-ngrx/mail.service'; @Component({ - selector : 'fuse-mail-list', + selector : 'mail-list', templateUrl : './mail-list.component.html', styleUrls : ['./mail-list.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) -export class FuseMailNgrxListComponent +export class MailNgrxListComponent { - @Input() mails: Mail[]; - @Input() currentMail: Mail[]; + @Input() + mails: Mail[]; + @Input() + currentMail: Mail[]; + + /** + * Constructor + * + * @param {ActivatedRoute} _activatedRoute + * @param {MailNgrxService} _mailNgrxService + * @param {Router} _router + */ constructor( - private route: ActivatedRoute, - private mailService: MailNgrxService, - private router: Router + private _activatedRoute: ActivatedRoute, + private _mailNgrxService: MailNgrxService, + private _router: Router ) { } + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + /** * Read mail + * * @param mailId */ - readMail(mailId) + readMail(mailId): void { - const labelHandle = this.route.snapshot.params.labelHandle, - filterHandle = this.route.snapshot.params.filterHandle, - folderHandle = this.route.snapshot.params.folderHandle; + const labelHandle = this._activatedRoute.snapshot.params.labelHandle, + filterHandle = this._activatedRoute.snapshot.params.filterHandle, + folderHandle = this._activatedRoute.snapshot.params.folderHandle; if ( labelHandle ) { - this.router.navigate(['apps/mail-ngrx/label/' + labelHandle + '/' + mailId]); + this._router.navigate(['apps/mail-ngrx/label/' + labelHandle + '/' + mailId]); } else if ( filterHandle ) { - this.router.navigate(['apps/mail-ngrx/filter/' + filterHandle + '/' + mailId]); + this._router.navigate(['apps/mail-ngrx/filter/' + filterHandle + '/' + mailId]); } else { - this.router.navigate(['apps/mail-ngrx/' + folderHandle + '/' + mailId]); + this._router.navigate(['apps/mail-ngrx/' + folderHandle + '/' + mailId]); } } } diff --git a/src/app/main/apps/mail-ngrx/mail.component.html b/src/app/main/apps/mail-ngrx/mail.component.html index 13a31fbc..701983ae 100644 --- a/src/app/main/apps/mail-ngrx/mail.component.html +++ b/src/app/main/apps/mail-ngrx/mail.component.html @@ -9,7 +9,7 @@ - + @@ -88,7 +88,7 @@
-
@@ -98,8 +98,8 @@
- - + +
diff --git a/src/app/main/apps/mail-ngrx/mail.component.scss b/src/app/main/apps/mail-ngrx/mail.component.scss index cca33765..f401db44 100644 --- a/src/app/main/apps/mail-ngrx/mail.component.scss +++ b/src/app/main/apps/mail-ngrx/mail.component.scss @@ -40,16 +40,16 @@ @include media-breakpoint(xs) { - fuse-mail-list { + mail-list { border-right: none; } - fuse-mail-list, - fuse-mail-details { + mail-list, + mail-details { flex: 1 0 100%; } - fuse-mail-details { + mail-details { display: none !important; } @@ -65,11 +65,11 @@ .content { - fuse-mail-list { + mail-list { display: none !important; } - fuse-mail-details { + mail-details { display: flex !important; } } diff --git a/src/app/main/apps/mail-ngrx/mail.component.ts b/src/app/main/apps/mail-ngrx/mail.component.ts index 9fbbcad6..51833271 100644 --- a/src/app/main/apps/mail-ngrx/mail.component.ts +++ b/src/app/main/apps/mail-ngrx/mail.component.ts @@ -10,16 +10,17 @@ import { FuseConfigService } from '@fuse/services/config.service'; import { Mail } from 'app/main/apps/mail-ngrx/mail.model'; import { MailNgrxService } from 'app/main/apps/mail-ngrx/mail.service'; import * as fromStore from 'app/main/apps/mail-ngrx/store'; + import { locale as english } from 'app/main/apps/mail-ngrx/i18n/en'; import { locale as turkish } from 'app/main/apps/mail-ngrx/i18n/tr'; @Component({ - selector : 'fuse-mail', + selector : 'mail-ngrx', templateUrl : './mail.component.html', styleUrls : ['./mail.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) -export class FuseMailNgrxComponent implements OnInit, OnDestroy +export class MailNgrxComponent implements OnInit, OnDestroy { hasSelectedMails: boolean; isIndeterminate: boolean; @@ -33,31 +34,49 @@ export class FuseMailNgrxComponent implements OnInit, OnDestroy mails: Mail[]; selectedMailIds: string[]; + /** + * Constructor + * + * @param {FuseConfigService} _fuseConfigService + * @param {MailNgrxService} _mailNgrxService + * @param {FuseTranslationLoaderService} _fuseTranslationLoaderService + * @param {Store} _store + * @param {ChangeDetectorRef} _changeDetectorRef + */ constructor( - private configService: FuseConfigService, - private mailService: MailNgrxService, - private translationLoader: FuseTranslationLoaderService, - private store: Store, - private cd: ChangeDetectorRef + private _fuseConfigService: FuseConfigService, + private _mailNgrxService: MailNgrxService, + private _fuseTranslationLoaderService: FuseTranslationLoaderService, + private _store: Store, + private _changeDetectorRef: ChangeDetectorRef ) { - this.searchInput = new FormControl(''); - this.translationLoader.loadTranslations(english, turkish); - this.currentMail$ = this.store.select(fromStore.getCurrentMail); - this.mails$ = this.store.select(fromStore.getMailsArr); - this.folders$ = this.store.select(fromStore.getFoldersArr); - this.labels$ = this.store.select(fromStore.getLabelsArr); - this.selectedMailIds$ = this.store.select(fromStore.getSelectedMailIds); - this.searchText$ = this.store.select(fromStore.getSearchText); - this.mails = []; - this.selectedMailIds = []; - - this.configService.config = { + // Configure the layout + this._fuseConfigService.config = { routerAnimation: 'none' }; + + // Set the defaults + this.searchInput = new FormControl(''); + this._fuseTranslationLoaderService.loadTranslations(english, turkish); + this.currentMail$ = this._store.select(fromStore.getCurrentMail); + this.mails$ = this._store.select(fromStore.getMailsArr); + this.folders$ = this._store.select(fromStore.getFoldersArr); + this.labels$ = this._store.select(fromStore.getLabelsArr); + this.selectedMailIds$ = this._store.select(fromStore.getSelectedMailIds); + this.searchText$ = this._store.select(fromStore.getSearchText); + this.mails = []; + this.selectedMailIds = []; } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { this.mails$.subscribe(mails => { this.mails = mails; @@ -79,16 +98,28 @@ export class FuseMailNgrxComponent implements OnInit, OnDestroy debounceTime(300), distinctUntilChanged() ).subscribe(searchText => { - this.store.dispatch(new fromStore.SetSearchText(searchText)); + this._store.dispatch(new fromStore.SetSearchText(searchText)); }); } - ngOnDestroy() + /** + * On destroy + */ + ngOnDestroy(): void { - this.cd.detach(); + this._changeDetectorRef.detach(); } - toggleSelectAll(ev) + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Toggle select all + * + * @param ev + */ + toggleSelectAll(ev): void { ev.preventDefault(); @@ -102,41 +133,69 @@ export class FuseMailNgrxComponent implements OnInit, OnDestroy } } - selectAllMails() + /** + * Select all mails + */ + selectAllMails(): void { - this.store.dispatch(new fromStore.SelectAllMails()); + this._store.dispatch(new fromStore.SelectAllMails()); } - deselectAllMails() + /** + * Deselect all mails + */ + deselectAllMails(): void { - this.store.dispatch(new fromStore.DeselectAllMails()); + this._store.dispatch(new fromStore.DeselectAllMails()); } - selectMailsByParameter(parameter, value) + /** + * Select mails by parameter + * + * @param parameter + * @param value + */ + selectMailsByParameter(parameter, value): void { - this.store.dispatch(new fromStore.SelectMailsByParameter({ + this._store.dispatch(new fromStore.SelectMailsByParameter({ parameter, value })); } - toggleLabelOnSelectedMails(labelId) + /** + * Toggle label on selected mails + * + * @param labelId + */ + toggleLabelOnSelectedMails(labelId): void { - this.store.dispatch(new fromStore.AddLabelOnSelectedMails(labelId)); + this._store.dispatch(new fromStore.AddLabelOnSelectedMails(labelId)); } - setFolderOnSelectedMails(folderId) + /** + * Set folder on selected mails + * + * @param folderId + */ + setFolderOnSelectedMails(folderId): void { - this.store.dispatch(new fromStore.SetFolderOnSelectedMails(folderId)); + this._store.dispatch(new fromStore.SetFolderOnSelectedMails(folderId)); } - deSelectCurrentMail() + /** + * Deselect current mail + */ + deselectCurrentMail(): void { - this.store.dispatch(new fromStore.SetCurrentMail('')); + this._store.dispatch(new fromStore.SetCurrentMail('')); } - refresh() + /** + * Refresh + */ + refresh(): void { - this.cd.markForCheck(); + this._changeDetectorRef.markForCheck(); } } diff --git a/src/app/main/apps/mail-ngrx/mail.model.ts b/src/app/main/apps/mail-ngrx/mail.model.ts index 725bc915..0c015c30 100644 --- a/src/app/main/apps/mail-ngrx/mail.model.ts +++ b/src/app/main/apps/mail-ngrx/mail.model.ts @@ -27,6 +27,11 @@ export class Mail labels: string[]; folder: string; + /** + * Constructor + * + * @param mail + */ constructor(mail) { this.id = mail.id; @@ -44,22 +49,34 @@ export class Mail this.folder = mail.folder; } - toggleStar() + /** + * Toggle star + */ + toggleStar(): void { this.starred = !this.starred; } - toggleImportant() + /** + * Toggle important + */ + toggleImportant(): void { this.important = !this.important; } - markRead() + /** + * Mark as read + */ + markRead(): void { this.read = true; } - markUnRead() + /** + * Mark as unread + */ + markUnread(): void { this.read = false; } diff --git a/src/app/main/apps/mail-ngrx/mail.module.ts b/src/app/main/apps/mail-ngrx/mail.module.ts index 84653891..78ca98e7 100644 --- a/src/app/main/apps/mail-ngrx/mail.module.ts +++ b/src/app/main/apps/mail-ngrx/mail.module.ts @@ -5,45 +5,45 @@ import { TranslateModule } from '@ngx-translate/core'; import { FuseSharedModule } from '@fuse/shared.module'; -import { MailAppStoreModule } from 'app/main/apps/mail-ngrx/store/store.module'; import * as fromGuards from 'app/main/apps/mail-ngrx/store/guards/index'; -import { FuseMailNgrxComponent } from 'app/main/apps/mail-ngrx/mail.component'; -import { FuseMailNgrxListComponent } from 'app/main/apps/mail-ngrx/mail-list/mail-list.component'; -import { FuseMailNgrxListItemComponent } from 'app/main/apps/mail-ngrx/mail-list/mail-list-item/mail-list-item.component'; -import { FuseMailNgrxDetailsComponent } from 'app/main/apps/mail-ngrx/mail-details/mail-details.component'; -import { FuseMailNgrxMainSidenavComponent } from 'app/main/apps/mail-ngrx/sidenavs/main/main-sidenav.component'; -import { FuseMailNgrxComposeDialogComponent } from 'app/main/apps/mail-ngrx/dialogs/compose/compose.component'; +import { MailNgrxStoreModule } from 'app/main/apps/mail-ngrx/store/store.module'; +import { MailNgrxComponent } from 'app/main/apps/mail-ngrx/mail.component'; +import { MailNgrxListComponent } from 'app/main/apps/mail-ngrx/mail-list/mail-list.component'; +import { MailNgrxListItemComponent } from 'app/main/apps/mail-ngrx/mail-list/mail-list-item/mail-list-item.component'; +import { MailNgrxDetailsComponent } from 'app/main/apps/mail-ngrx/mail-details/mail-details.component'; +import { MailNgrxMainSidenavComponent } from 'app/main/apps/mail-ngrx/sidenavs/main/main-sidenav.component'; +import { MailNgrxComposeDialogComponent } from 'app/main/apps/mail-ngrx/dialogs/compose/compose.component'; import { MailNgrxService } from 'app/main/apps/mail-ngrx/mail.service'; const routes: Routes = [ { path : 'label/:labelHandle', - component : FuseMailNgrxComponent, + component : MailNgrxComponent, canActivate: [fromGuards.ResolveGuard] }, { path : 'label/:labelHandle/:mailId', - component : FuseMailNgrxComponent, + component : MailNgrxComponent, canActivate: [fromGuards.ResolveGuard] }, { - path : 'filter/:filterHandle', - component: FuseMailNgrxComponent, + path : 'filter/:filterHandle', + component : MailNgrxComponent, canActivate: [fromGuards.ResolveGuard] }, { - path : 'filter/:filterHandle/:mailId', - component: FuseMailNgrxComponent, + path : 'filter/:filterHandle/:mailId', + component : MailNgrxComponent, canActivate: [fromGuards.ResolveGuard] }, { - path : ':folderHandle', - component: FuseMailNgrxComponent, + path : ':folderHandle', + component : MailNgrxComponent, canActivate: [fromGuards.ResolveGuard] }, { - path : ':folderHandle/:mailId', - component: FuseMailNgrxComponent, + path : ':folderHandle/:mailId', + component : MailNgrxComponent, canActivate: [fromGuards.ResolveGuard] }, { @@ -54,12 +54,12 @@ const routes: Routes = [ @NgModule({ declarations : [ - FuseMailNgrxComponent, - FuseMailNgrxListComponent, - FuseMailNgrxListItemComponent, - FuseMailNgrxDetailsComponent, - FuseMailNgrxMainSidenavComponent, - FuseMailNgrxComposeDialogComponent + MailNgrxComponent, + MailNgrxListComponent, + MailNgrxListItemComponent, + MailNgrxDetailsComponent, + MailNgrxMainSidenavComponent, + MailNgrxComposeDialogComponent ], imports : [ RouterModule.forChild(routes), @@ -80,13 +80,13 @@ const routes: Routes = [ FuseSharedModule, - MailAppStoreModule + MailNgrxStoreModule ], providers : [ MailNgrxService, fromGuards.ResolveGuard ], - entryComponents: [FuseMailNgrxComposeDialogComponent] + entryComponents: [MailNgrxComposeDialogComponent] }) export class FuseMailNgrxModule { diff --git a/src/app/main/apps/mail-ngrx/mail.service.ts b/src/app/main/apps/mail-ngrx/mail.service.ts index 26cbd9a8..ec1a6aad 100644 --- a/src/app/main/apps/mail-ngrx/mail.service.ts +++ b/src/app/main/apps/mail-ngrx/mail.service.ts @@ -16,72 +16,108 @@ export class MailNgrxService selectedMails: Mail[]; mails: Mail[]; + /** + * Constructor + * + * @param {HttpClient} _httpClient + * @param {Store} _store + */ constructor( - private http: HttpClient, - private store: Store + private _httpClient: HttpClient, + private _store: Store ) { - this.store.select(getFoldersArr).subscribe(folders => { + this._store.select(getFoldersArr).subscribe(folders => { this.foldersArr = folders; }); - this.store.select(getFiltersArr).subscribe(filters => { + + this._store.select(getFiltersArr).subscribe(filters => { this.filtersArr = filters; }); - this.store.select(getLabelsArr).subscribe(labels => { + + this._store.select(getLabelsArr).subscribe(labels => { this.labelsArr = labels; }); - this.store.select(getMailsArr).subscribe(mails => { + + this._store.select(getMailsArr).subscribe(mails => { this.mails = mails; }); this.selectedMails = []; } + /** + * Get all mails + * + * @returns {Observable} + */ getAllMails(): Observable { - return this.http.get('api/mail-mails'); + return this._httpClient.get('api/mail-mails'); } + /** + * Get folders + * + * @returns {Observable} + */ getFolders(): Observable { - return this.http.get('api/mail-folders'); + return this._httpClient.get('api/mail-folders'); } + /** + * Get filters + * + * @returns {Observable} + */ getFilters(): Observable { - return this.http.get('api/mail-filters'); + return this._httpClient.get('api/mail-filters'); } + /** + * Get labels + * + * @returns {Observable} + */ getLabels(): Observable { - return this.http.get('api/mail-labels'); + return this._httpClient.get('api/mail-labels'); } + /** + * Get mails + * + * @param handle + * @returns {Observable} + */ getMails(handle): Observable { if ( handle.id === 'labelHandle' ) { const labelId = this.labelsArr.find(label => label.handle === handle.value).id; - return this.http.get('api/mail-mails?labels=' + labelId); + return this._httpClient.get('api/mail-mails?labels=' + labelId); } else if ( handle.id === 'filterHandle' ) { - return this.http.get('api/mail-mails?' + handle.value + '=true'); + return this._httpClient.get('api/mail-mails?' + handle.value + '=true'); } else // folderHandle { const folderId = this.foldersArr.find(folder => folder.handle === handle.value).id; - return this.http.get('api/mail-mails?folder=' + folderId); + return this._httpClient.get('api/mail-mails?folder=' + folderId); } } /** * Update the mail + * * @param mail * @returns {Promise} */ - updateMail(mail) + updateMail(mail): any { - return this.http.post('api/mail-mails/' + mail.id, {...mail}); + return this._httpClient.post('api/mail-mails/' + mail.id, {...mail}); } } diff --git a/src/app/main/apps/mail-ngrx/sidenavs/main/main-sidenav.component.ts b/src/app/main/apps/mail-ngrx/sidenavs/main/main-sidenav.component.ts index 742a497d..11dfcfab 100644 --- a/src/app/main/apps/mail-ngrx/sidenavs/main/main-sidenav.component.ts +++ b/src/app/main/apps/mail-ngrx/sidenavs/main/main-sidenav.component.ts @@ -4,17 +4,17 @@ import { FormGroup } from '@angular/forms'; import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; -import { MailNgrxService } from '../../mail.service'; -import * as fromStore from './../../store'; -import { FuseMailNgrxComposeDialogComponent } from '../../dialogs/compose/compose.component'; +import { MailNgrxService } from 'app/main/apps/mail-ngrx/mail.service'; +import * as fromStore from 'app/main/apps/mail-ngrx/store'; +import { MailNgrxComposeDialogComponent } from 'app/main/apps/mail-ngrx/dialogs/compose/compose.component'; @Component({ - selector : 'fuse-mail-main-sidenav', + selector : 'mail-main-sidenav', templateUrl : './main-sidenav.component.html', styleUrls : ['./main-sidenav.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) -export class FuseMailNgrxMainSidenavComponent +export class MailNgrxMainSidenavComponent { labels: any[]; accounts: object; @@ -25,30 +25,43 @@ export class FuseMailNgrxMainSidenavComponent filters$: Observable; labels$: Observable; + /** + * Constructor + * + * @param {MailNgrxService} _mailNgrxService + * @param {MatDialog} _matDialog + * @param {Store} _store + */ constructor( - private mailService: MailNgrxService, - public dialog: MatDialog, - private store: Store + private _mailNgrxService: MailNgrxService, + private _matDialog: MatDialog, + private _store: Store ) { - // Data + // Set the defaults this.accounts = { 'creapond' : 'johndoe@creapond.com', 'withinpixels': 'johndoe@withinpixels.com' }; - this.selectedAccount = 'creapond'; - - this.folders$ = this.store.select(fromStore.getFoldersArr); - this.filters$ = this.store.select(fromStore.getFiltersArr); - this.labels$ = this.store.select(fromStore.getLabelsArr); + this.folders$ = this._store.select(fromStore.getFoldersArr); + this.filters$ = this._store.select(fromStore.getFiltersArr); + this.labels$ = this._store.select(fromStore.getLabelsArr); } - composeDialog() + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Compose dialog + */ + composeDialog(): void { - this.dialogRef = this.dialog.open(FuseMailNgrxComposeDialogComponent, { + this.dialogRef = this._matDialog.open(MailNgrxComposeDialogComponent, { panelClass: 'mail-compose-dialog' }); + this.dialogRef.afterClosed() .subscribe(response => { if ( !response ) diff --git a/src/app/main/apps/mail-ngrx/store/guards/resolve.guard.ts b/src/app/main/apps/mail-ngrx/store/guards/resolve.guard.ts index 6fa3324d..a563cd62 100644 --- a/src/app/main/apps/mail-ngrx/store/guards/resolve.guard.ts +++ b/src/app/main/apps/mail-ngrx/store/guards/resolve.guard.ts @@ -16,11 +16,16 @@ export class ResolveGuard implements CanActivate { routerState: any; + /** + * Constructor + * + * @param {Store} _store + */ constructor( - private store: Store + private _store: Store ) { - this.store.select(getRouterState).subscribe(routerState => { + this._store.select(getRouterState).subscribe(routerState => { if ( routerState ) { this.routerState = routerState.state; @@ -28,6 +33,13 @@ export class ResolveGuard implements CanActivate }); } + /** + * Can activate + * + * @param {ActivatedRouteSnapshot} route + * @param {RouterStateSnapshot} state + * @returns {Observable} + */ canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable { return this.checkStore().pipe( @@ -36,32 +48,42 @@ export class ResolveGuard implements CanActivate ); } + /** + * Check store + * + * @returns {Observable} + */ checkStore(): Observable { return forkJoin( - this.getFolders(), - this.getFilters(), - this.getLabels() - ) + this.getFolders(), + this.getFilters(), + this.getLabels() + ) .pipe( - filter(([foldersLoaded, filtersLoaded, labelsLoaded]) => filtersLoaded && foldersLoaded && labelsLoaded), + filter(([foldersLoaded, filtersLoaded, labelsLoaded]) => !!(foldersLoaded && filtersLoaded && labelsLoaded)), take(1), switchMap(() => this.getMails() ), take(1), - map(() => this.store.dispatch(new fromStore.SetCurrentMail(this.routerState.params.mailId))) + map(() => this._store.dispatch(new fromStore.SetCurrentMail(this.routerState.params.mailId))) ); } - getFolders() + /** + * Get folders + * + * @returns {Observable} + */ + getFolders(): any { - return this.store.select(getFoldersLoaded) + return this._store.select(getFoldersLoaded) .pipe( tap(loaded => { if ( !loaded ) { - this.store.dispatch(new fromStore.GetFolders([])); + this._store.dispatch(new fromStore.GetFolders([])); } }), filter(loaded => loaded), @@ -71,16 +93,17 @@ export class ResolveGuard implements CanActivate /** * Get Filters + * * @returns {Observable} */ - getFilters() + getFilters(): any { - return this.store.select(getFiltersLoaded) + return this._store.select(getFiltersLoaded) .pipe( tap(loaded => { if ( !loaded ) { - this.store.dispatch(new fromStore.GetFilters([])); + this._store.dispatch(new fromStore.GetFilters([])); } }), filter(loaded => loaded), @@ -92,14 +115,14 @@ export class ResolveGuard implements CanActivate * Get Labels * @returns {Observable} */ - getLabels() + getLabels(): any { - return this.store.select(getLabelsLoaded) + return this._store.select(getLabelsLoaded) .pipe( tap(loaded => { if ( !loaded ) { - this.store.dispatch(new fromStore.GetLabels([])); + this._store.dispatch(new fromStore.GetLabels([])); } }), filter(loaded => loaded), @@ -109,19 +132,20 @@ export class ResolveGuard implements CanActivate /** * Get Mails + * * @returns {Observable} */ - getMails() + getMails(): any { - return this.store.select(getMailsLoaded) + return this._store.select(getMailsLoaded) .pipe( tap((loaded: any) => { if ( !this.routerState.params[loaded.id] || this.routerState.params[loaded.id] !== loaded.value ) { - this.store.dispatch(new fromStore.GetMails()); - this.store.dispatch(new fromStore.SetSearchText('')); - this.store.dispatch(new fromStore.DeselectAllMails()); + this._store.dispatch(new fromStore.GetMails()); + this._store.dispatch(new fromStore.SetSearchText('')); + this._store.dispatch(new fromStore.DeselectAllMails()); } }), filter((loaded: any) => { diff --git a/src/app/main/apps/mail-ngrx/store/reducers/filters.reducer.ts b/src/app/main/apps/mail-ngrx/store/reducers/filters.reducer.ts index 1251a19d..ed8e8e05 100644 --- a/src/app/main/apps/mail-ngrx/store/reducers/filters.reducer.ts +++ b/src/app/main/apps/mail-ngrx/store/reducers/filters.reducer.ts @@ -2,7 +2,7 @@ import * as FiltersActions from 'app/main/apps/mail-ngrx/store/actions/filters.a export interface FiltersState { - entities: { [id: number]: any }; + entities?: { [id: number]: any }; loading: boolean; loaded: boolean; } diff --git a/src/app/main/apps/mail-ngrx/store/reducers/folders.reducer.ts b/src/app/main/apps/mail-ngrx/store/reducers/folders.reducer.ts index 9fe04dc5..37056ad5 100644 --- a/src/app/main/apps/mail-ngrx/store/reducers/folders.reducer.ts +++ b/src/app/main/apps/mail-ngrx/store/reducers/folders.reducer.ts @@ -2,7 +2,7 @@ import * as FoldersActions from 'app/main/apps/mail-ngrx/store/actions/folders.a export interface FoldersState { - entities: { [id: number]: any }; + entities?: { [id: number]: any }; loading: boolean; loaded: boolean; } diff --git a/src/app/main/apps/mail-ngrx/store/reducers/labels.reducer.ts b/src/app/main/apps/mail-ngrx/store/reducers/labels.reducer.ts index f6052b5b..af819e67 100644 --- a/src/app/main/apps/mail-ngrx/store/reducers/labels.reducer.ts +++ b/src/app/main/apps/mail-ngrx/store/reducers/labels.reducer.ts @@ -2,7 +2,7 @@ import * as LabelsActions from 'app/main/apps/mail-ngrx/store/actions/labels.act export interface LabelsState { - entities: { [id: number]: any }; + entities?: { [id: number]: any }; loading: boolean; loaded: boolean; } diff --git a/src/app/main/apps/mail-ngrx/store/reducers/mails.reducer.ts b/src/app/main/apps/mail-ngrx/store/reducers/mails.reducer.ts index cd62c048..d33cbf2b 100644 --- a/src/app/main/apps/mail-ngrx/store/reducers/mails.reducer.ts +++ b/src/app/main/apps/mail-ngrx/store/reducers/mails.reducer.ts @@ -3,7 +3,7 @@ import { Mail } from 'app/main/apps/mail-ngrx/mail.model'; export interface MailsState { - entities: { [id: number]: Mail }; + entities?: { [id: number]: Mail }; currentMail: any; selectedMailIds: string[]; searchText: string; diff --git a/src/app/main/apps/mail-ngrx/store/store.module.ts b/src/app/main/apps/mail-ngrx/store/store.module.ts index 0a955f92..bc9c41a2 100644 --- a/src/app/main/apps/mail-ngrx/store/store.module.ts +++ b/src/app/main/apps/mail-ngrx/store/store.module.ts @@ -12,6 +12,6 @@ import { effects } from 'app/main/apps/mail-ngrx/store/effects'; ], providers: [] }) -export class MailAppStoreModule +export class MailNgrxStoreModule { } diff --git a/src/app/main/apps/mail/dialogs/compose/compose.component.html b/src/app/main/apps/mail/dialogs/compose/compose.component.html index b6e132d8..7a8971bd 100644 --- a/src/app/main/apps/mail/dialogs/compose/compose.component.html +++ b/src/app/main/apps/mail/dialogs/compose/compose.component.html @@ -2,7 +2,7 @@ New Message - @@ -91,7 +91,7 @@
-
- - + +
diff --git a/src/app/main/apps/mail/mail-list/mail-list.component.ts b/src/app/main/apps/mail/mail-list/mail-list.component.ts index be4341d5..b59ec11e 100644 --- a/src/app/main/apps/mail/mail-list/mail-list.component.ts +++ b/src/app/main/apps/mail/mail-list/mail-list.component.ts @@ -1,109 +1,134 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { Location } from '@angular/common'; import { ActivatedRoute } from '@angular/router'; -import { Subscription } from 'rxjs'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import { fuseAnimations } from '@fuse/animations'; -import { Mail } from '../mail.model'; -import { MailService } from '../mail.service'; +import { Mail } from 'app/main/apps/mail/mail.model'; +import { MailService } from 'app/main/apps/mail/mail.service'; @Component({ - selector : 'fuse-mail-list', + selector : 'mail-list', templateUrl: './mail-list.component.html', styleUrls : ['./mail-list.component.scss'], animations : fuseAnimations }) -export class FuseMailListComponent implements OnInit, OnDestroy +export class MailListComponent implements OnInit, OnDestroy { mails: Mail[]; currentMail: Mail; - onMailsChanged: Subscription; - onCurrentMailChanged: Subscription; + // Private + private _unsubscribeAll: Subject; + /** + * Constructor + * + * @param {ActivatedRoute} _activatedRoute + * @param {MailService} _mailService + * @param {Location} _location + */ constructor( - private route: ActivatedRoute, - private mailService: MailService, - private location: Location + private _activatedRoute: ActivatedRoute, + private _mailService: MailService, + private _location: Location ) { + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { // Subscribe to update mails on changes - this.onMailsChanged = - this.mailService.onMailsChanged - .subscribe(mails => { - this.mails = mails; - }); + this._mailService.onMailsChanged + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(mails => { + this.mails = mails; + }); // Subscribe to update current mail on changes - this.onCurrentMailChanged = - this.mailService.onCurrentMailChanged - .subscribe(currentMail => { - if ( !currentMail ) + this._mailService.onCurrentMailChanged + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(currentMail => { + if ( !currentMail ) + { + // Set the current mail id to null to deselect the current mail + this.currentMail = null; + + // Handle the location changes + const labelHandle = this._activatedRoute.snapshot.params.labelHandle, + filterHandle = this._activatedRoute.snapshot.params.filterHandle, + folderHandle = this._activatedRoute.snapshot.params.folderHandle; + + if ( labelHandle ) { - // Set the current mail id to null to deselect the current mail - this.currentMail = null; - - // Handle the location changes - const labelHandle = this.route.snapshot.params.labelHandle, - filterHandle = this.route.snapshot.params.filterHandle, - folderHandle = this.route.snapshot.params.folderHandle; - - if ( labelHandle ) - { - this.location.go('apps/mail/label/' + labelHandle); - } - else if ( filterHandle ) - { - this.location.go('apps/mail/filter/' + filterHandle); - } - else - { - this.location.go('apps/mail/' + folderHandle); - } + this._location.go('apps/mail/label/' + labelHandle); + } + else if ( filterHandle ) + { + this._location.go('apps/mail/filter/' + filterHandle); } else { - this.currentMail = currentMail; + this._location.go('apps/mail/' + folderHandle); } - }); - } - - ngOnDestroy() - { - this.onMailsChanged.unsubscribe(); - this.onCurrentMailChanged.unsubscribe(); + } + else + { + this.currentMail = currentMail; + } + }); } + /** + * On destroy + */ + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + /** * Read mail + * * @param mailId */ - readMail(mailId) + readMail(mailId): void { - const labelHandle = this.route.snapshot.params.labelHandle, - filterHandle = this.route.snapshot.params.filterHandle, - folderHandle = this.route.snapshot.params.folderHandle; + const labelHandle = this._activatedRoute.snapshot.params.labelHandle, + filterHandle = this._activatedRoute.snapshot.params.filterHandle, + folderHandle = this._activatedRoute.snapshot.params.folderHandle; if ( labelHandle ) { - this.location.go('apps/mail/label/' + labelHandle + '/' + mailId); + this._location.go('apps/mail/label/' + labelHandle + '/' + mailId); } else if ( filterHandle ) { - this.location.go('apps/mail/filter/' + filterHandle + '/' + mailId); + this._location.go('apps/mail/filter/' + filterHandle + '/' + mailId); } else { - this.location.go('apps/mail/' + folderHandle + '/' + mailId); + this._location.go('apps/mail/' + folderHandle + '/' + mailId); } // Set current mail - this.mailService.setCurrentMail(mailId); + this._mailService.setCurrentMail(mailId); } - } diff --git a/src/app/main/apps/mail/mail.component.html b/src/app/main/apps/mail/mail.component.html index 004880f8..570edba8 100644 --- a/src/app/main/apps/mail/mail.component.html +++ b/src/app/main/apps/mail/mail.component.html @@ -9,7 +9,7 @@ - + @@ -86,7 +86,7 @@
-
@@ -96,8 +96,8 @@
- - + +
diff --git a/src/app/main/apps/mail/mail.component.scss b/src/app/main/apps/mail/mail.component.scss index cca33765..f401db44 100644 --- a/src/app/main/apps/mail/mail.component.scss +++ b/src/app/main/apps/mail/mail.component.scss @@ -40,16 +40,16 @@ @include media-breakpoint(xs) { - fuse-mail-list { + mail-list { border-right: none; } - fuse-mail-list, - fuse-mail-details { + mail-list, + mail-details { flex: 1 0 100%; } - fuse-mail-details { + mail-details { display: none !important; } @@ -65,11 +65,11 @@ .content { - fuse-mail-list { + mail-list { display: none !important; } - fuse-mail-details { + mail-details { display: flex !important; } } diff --git a/src/app/main/apps/mail/mail.component.ts b/src/app/main/apps/mail/mail.component.ts index c8bdc84c..2142b9c3 100644 --- a/src/app/main/apps/mail/mail.component.ts +++ b/src/app/main/apps/mail/mail.component.ts @@ -1,22 +1,23 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { FormControl } from '@angular/forms'; - -import { Subscription } from 'rxjs'; -import { debounceTime, distinctUntilChanged } from 'rxjs/operators'; +import { Subject } from 'rxjs'; +import { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators'; import { FuseTranslationLoaderService } from '@fuse/services/translation-loader.service'; -import { Mail } from './mail.model'; -import { MailService } from './mail.service'; -import { locale as english } from './i18n/en'; -import { locale as turkish } from './i18n/tr'; +import { Mail } from 'app/main/apps/mail/mail.model'; +import { MailService } from 'app/main/apps/mail/mail.service'; + +import { locale as english } from 'app/main/apps/mail//i18n/en'; +import { locale as turkish } from 'app/main/apps/mail//i18n/tr'; +import { FuseConfigService } from '@fuse/services/config.service'; @Component({ - selector : 'fuse-mail', + selector : 'mail', templateUrl: './mail.component.html', styleUrls : ['./mail.component.scss'] }) -export class FuseMailComponent implements OnInit, OnDestroy +export class MailComponent implements OnInit, OnDestroy { hasSelectedMails: boolean; isIndeterminate: boolean; @@ -26,110 +27,162 @@ export class FuseMailComponent implements OnInit, OnDestroy searchInput: FormControl; currentMail: Mail; - onSelectedMailsChanged: Subscription; - onFoldersChanged: Subscription; - onFiltersChanged: Subscription; - onLabelsChanged: Subscription; - onCurrentMailChanged: Subscription; + // Private + private _unsubscribeAll: Subject; + /** + * Constructor + * + * @param {MailService} _mailService + * @param {FuseConfigService} _fuseConfigService + * @param {FuseTranslationLoaderService} _fuseTranslationLoaderService + */ constructor( - private mailService: MailService, - private fuseTranslationLoader: FuseTranslationLoaderService + private _mailService: MailService, + private _fuseConfigService: FuseConfigService, + private _fuseTranslationLoaderService: FuseTranslationLoaderService ) { + // Configure the layout + this._fuseConfigService.config = { + routerAnimation: 'none' + }; + + // Load the translations + this._fuseTranslationLoaderService.loadTranslations(english, turkish); + + // Set the defaults this.searchInput = new FormControl(''); - this.fuseTranslationLoader.loadTranslations(english, turkish); + + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { - this.onSelectedMailsChanged = - this.mailService.onSelectedMailsChanged - .subscribe(selectedMails => { + this._mailService.onSelectedMailsChanged + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(selectedMails => { + setTimeout(() => { + this.hasSelectedMails = selectedMails.length > 0; + this.isIndeterminate = (selectedMails.length !== this._mailService.mails.length && selectedMails.length > 0); + }, 0); + }); - setTimeout(() => { - this.hasSelectedMails = selectedMails.length > 0; - this.isIndeterminate = (selectedMails.length !== this.mailService.mails.length && selectedMails.length > 0); - }, 0); - }); + this._mailService.onFoldersChanged + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(folders => { + this.folders = this._mailService.folders; + }); - this.onFoldersChanged = - this.mailService.onFoldersChanged - .subscribe(folders => { - this.folders = this.mailService.folders; - }); + this._mailService.onFiltersChanged + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(folders => { + this.filters = this._mailService.filters; + }); - this.onFiltersChanged = - this.mailService.onFiltersChanged - .subscribe(folders => { - this.filters = this.mailService.filters; - }); + this._mailService.onLabelsChanged + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(labels => { + this.labels = this._mailService.labels; + }); - this.onLabelsChanged = - this.mailService.onLabelsChanged - .subscribe(labels => { - this.labels = this.mailService.labels; - }); - - this.onCurrentMailChanged = - this.mailService.onCurrentMailChanged - .subscribe(currentMail => { - if ( !currentMail ) - { - this.currentMail = null; - } - else - { - this.currentMail = currentMail; - } - }); + this._mailService.onCurrentMailChanged + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(currentMail => { + if ( !currentMail ) + { + this.currentMail = null; + } + else + { + this.currentMail = currentMail; + } + }); this.searchInput.valueChanges.pipe( + takeUntil(this._unsubscribeAll), debounceTime(300), distinctUntilChanged() ) .subscribe(searchText => { - this.mailService.onSearchTextChanged.next(searchText); + this._mailService.onSearchTextChanged.next(searchText); }); } - ngOnDestroy() + /** + * On destroy + */ + ngOnDestroy(): void { - this.onSelectedMailsChanged.unsubscribe(); - this.onFoldersChanged.unsubscribe(); - this.onFiltersChanged.unsubscribe(); - this.onLabelsChanged.unsubscribe(); - this.onCurrentMailChanged.unsubscribe(); - + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); } - toggleSelectAll() + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Toggle select all + */ + toggleSelectAll(): void { - this.mailService.toggleSelectAll(); + this._mailService.toggleSelectAll(); } - selectMails(filterParameter?, filterValue?) + /** + * Select mails + * + * @param filterParameter + * @param filterValue + */ + selectMails(filterParameter?, filterValue?): void { - this.mailService.selectMails(filterParameter, filterValue); + this._mailService.selectMails(filterParameter, filterValue); } - deselectMails() + /** + * Deselect mails + */ + deselectMails(): void { - this.mailService.deselectMails(); + this._mailService.deselectMails(); } - deSelectCurrentMail() + /** + * Deselect current mail + */ + deselectCurrentMail(): void { - this.mailService.onCurrentMailChanged.next(null); + this._mailService.onCurrentMailChanged.next(null); } - toggleLabelOnSelectedMails(labelId) + /** + * Toggle label on selected mails + * + * @param labelId + */ + toggleLabelOnSelectedMails(labelId): void { - this.mailService.toggleLabelOnSelectedMails(labelId); + this._mailService.toggleLabelOnSelectedMails(labelId); } - setFolderOnSelectedMails(folderId) + /** + * Set folder on selected mails + * + * @param folderId + */ + setFolderOnSelectedMails(folderId): void { - this.mailService.setFolderOnSelectedMails(folderId); + this._mailService.setFolderOnSelectedMails(folderId); } } diff --git a/src/app/main/apps/mail/mail.model.ts b/src/app/main/apps/mail/mail.model.ts index 42ff6cf5..7b36a600 100644 --- a/src/app/main/apps/mail/mail.model.ts +++ b/src/app/main/apps/mail/mail.model.ts @@ -27,6 +27,11 @@ export class Mail labels: string[]; folder: string; + /** + * Constructor + * + * @param mail + */ constructor(mail) { this.id = mail.id; diff --git a/src/app/main/apps/mail/mail.module.ts b/src/app/main/apps/mail/mail.module.ts index a9b177f9..4066b864 100644 --- a/src/app/main/apps/mail/mail.module.ts +++ b/src/app/main/apps/mail/mail.module.ts @@ -1,59 +1,57 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; - import { MatButtonModule, MatCheckboxModule, MatDialogModule, MatFormFieldModule, MatIconModule, MatInputModule, MatMenuModule, MatRippleModule, MatSelectModule, MatSidenavModule, MatToolbarModule } from '@angular/material'; - import { TranslateModule } from '@ngx-translate/core'; import { FuseSharedModule } from '@fuse/shared.module'; -import { MailService } from './mail.service'; -import { FuseMailComponent } from './mail.component'; -import { FuseMailMainSidenavComponent } from './sidenavs/main/main-sidenav.component'; -import { FuseMailListItemComponent } from './mail-list/mail-list-item/mail-list-item.component'; -import { FuseMailListComponent } from './mail-list/mail-list.component'; -import { FuseMailDetailsComponent } from './mail-details/mail-details.component'; -import { FuseMailComposeDialogComponent } from './dialogs/compose/compose.component'; +import { MailService } from 'app/main/apps/mail/mail.service'; +import { MailComponent } from 'app/main/apps/mail/mail.component'; +import { MailListComponent } from 'app/main/apps/mail/mail-list/mail-list.component'; +import { MailListItemComponent } from 'app/main/apps/mail/mail-list/mail-list-item/mail-list-item.component'; +import { MailDetailsComponent } from 'app/main/apps/mail/mail-details/mail-details.component'; +import { MailMainSidenavComponent } from 'app/main/apps/mail/sidenavs/main/main-sidenav.component'; +import { MailComposeDialogComponent } from 'app/main/apps/mail/dialogs/compose/compose.component'; const routes: Routes = [ { path : 'label/:labelHandle', - component: FuseMailComponent, + component: MailComponent, resolve : { mail: MailService } }, { path : 'label/:labelHandle/:mailId', - component: FuseMailComponent, + component: MailComponent, resolve : { mail: MailService } }, { path : 'filter/:filterHandle', - component: FuseMailComponent, + component: MailComponent, resolve : { mail: MailService } }, { path : 'filter/:filterHandle/:mailId', - component: FuseMailComponent, + component: MailComponent, resolve : { mail: MailService } }, { path : ':folderHandle', - component: FuseMailComponent, + component: MailComponent, resolve : { mail: MailService } }, { path : ':folderHandle/:mailId', - component: FuseMailComponent, + component: MailComponent, resolve : { mail: MailService } @@ -66,12 +64,12 @@ const routes: Routes = [ @NgModule({ declarations : [ - FuseMailComponent, - FuseMailListComponent, - FuseMailListItemComponent, - FuseMailDetailsComponent, - FuseMailMainSidenavComponent, - FuseMailComposeDialogComponent + MailComponent, + MailListComponent, + MailListItemComponent, + MailDetailsComponent, + MailMainSidenavComponent, + MailComposeDialogComponent ], imports : [ RouterModule.forChild(routes), @@ -95,8 +93,10 @@ const routes: Routes = [ providers : [ MailService ], - entryComponents: [FuseMailComposeDialogComponent] + entryComponents: [ + MailComposeDialogComponent + ] }) -export class FuseMailModule +export class MailModule { } diff --git a/src/app/main/apps/mail/mail.service.ts b/src/app/main/apps/mail/mail.service.ts index de0c7d50..95dcdca8 100644 --- a/src/app/main/apps/mail/mail.service.ts +++ b/src/app/main/apps/mail/mail.service.ts @@ -5,7 +5,7 @@ import { BehaviorSubject, Observable } from 'rxjs'; import { FuseUtils } from '@fuse/utils'; -import { Mail } from './mail.model'; +import { Mail } from 'app/main/apps/mail/mail.model'; @Injectable() export class MailService implements Resolve @@ -20,22 +20,37 @@ export class MailService implements Resolve labels: any[]; routeParams: any; - onMailsChanged: BehaviorSubject = new BehaviorSubject([]); - onSelectedMailsChanged: BehaviorSubject = new BehaviorSubject([]); - onCurrentMailChanged: BehaviorSubject = new BehaviorSubject([]); + onMailsChanged: BehaviorSubject; + onSelectedMailsChanged: BehaviorSubject; + onCurrentMailChanged: BehaviorSubject; + onFoldersChanged: BehaviorSubject; + onFiltersChanged: BehaviorSubject; + onLabelsChanged: BehaviorSubject; + onSearchTextChanged: BehaviorSubject; - onFoldersChanged: BehaviorSubject = new BehaviorSubject([]); - onFiltersChanged: BehaviorSubject = new BehaviorSubject([]); - onLabelsChanged: BehaviorSubject = new BehaviorSubject([]); - onSearchTextChanged: BehaviorSubject = new BehaviorSubject(''); - - constructor(private http: HttpClient) + /** + * Constructor + * + * @param {HttpClient} _httpClient + */ + constructor( + private _httpClient: HttpClient + ) { + // Set the defaults this.selectedMails = []; + this.onMailsChanged = new BehaviorSubject([]); + this.onSelectedMailsChanged = new BehaviorSubject([]); + this.onCurrentMailChanged = new BehaviorSubject([]); + this.onFoldersChanged = new BehaviorSubject([]); + this.onFiltersChanged = new BehaviorSubject([]); + this.onLabelsChanged = new BehaviorSubject([]); + this.onSearchTextChanged = new BehaviorSubject(''); } /** - * Resolve + * Resolver + * * @param {ActivatedRouteSnapshot} route * @param {RouterStateSnapshot} state * @returns {Observable | Promise | any} @@ -83,12 +98,13 @@ export class MailService implements Resolve /** * Get all folders + * * @returns {Promise} */ getFolders(): Promise { return new Promise((resolve, reject) => { - this.http.get('api/mail-folders') + this._httpClient.get('api/mail-folders') .subscribe((response: any) => { this.folders = response; this.onFoldersChanged.next(this.folders); @@ -99,12 +115,13 @@ export class MailService implements Resolve /** * Get all filters + * * @returns {Promise} */ getFilters(): Promise { return new Promise((resolve, reject) => { - this.http.get('api/mail-filters') + this._httpClient.get('api/mail-filters') .subscribe((response: any) => { this.filters = response; this.onFiltersChanged.next(this.filters); @@ -115,12 +132,13 @@ export class MailService implements Resolve /** * Get all labels + * * @returns {Promise} */ getLabels(): Promise { return new Promise((resolve, reject) => { - this.http.get('api/mail-labels') + this._httpClient.get('api/mail-labels') .subscribe((response: any) => { this.labels = response; this.onLabelsChanged.next(this.labels); @@ -131,6 +149,7 @@ export class MailService implements Resolve /** * Get all mails + * * @returns {Promise} */ getMails(): Promise @@ -150,6 +169,7 @@ export class MailService implements Resolve /** * Get mails by folder + * * @param handle * @returns {Promise} */ @@ -157,12 +177,12 @@ export class MailService implements Resolve { return new Promise((resolve, reject) => { - this.http.get('api/mail-folders?handle=' + handle) + this._httpClient.get('api/mail-folders?handle=' + handle) .subscribe((folders: any) => { const folderId = folders[0].id; - this.http.get('api/mail-mails?folder=' + folderId) + this._httpClient.get('api/mail-mails?folder=' + folderId) .subscribe((mails: any) => { this.mails = mails.map(mail => { @@ -182,6 +202,7 @@ export class MailService implements Resolve /** * Get mails by filter + * * @param handle * @returns {Promise} */ @@ -189,7 +210,7 @@ export class MailService implements Resolve { return new Promise((resolve, reject) => { - this.http.get('api/mail-mails?' + handle + '=true') + this._httpClient.get('api/mail-mails?' + handle + '=true') .subscribe((mails: any) => { this.mails = mails.map(mail => { @@ -208,18 +229,19 @@ export class MailService implements Resolve /** * Get mails by label + * * @param handle * @returns {Promise} */ getMailsByLabel(handle): Promise { return new Promise((resolve, reject) => { - this.http.get('api/mail-labels?handle=' + handle) + this._httpClient.get('api/mail-labels?handle=' + handle) .subscribe((labels: any) => { const labelId = labels[0].id; - this.http.get('api/mail-mails?labels=' + labelId) + this._httpClient.get('api/mail-mails?labels=' + labelId) .subscribe((mails: any) => { this.mails = mails.map(mail => { @@ -239,9 +261,10 @@ export class MailService implements Resolve /** * Toggle selected mail by id + * * @param id */ - toggleSelectedMail(id) + toggleSelectedMail(id): void { // First, check if we already have that mail as selected... if ( this.selectedMails.length > 0 ) @@ -281,7 +304,7 @@ export class MailService implements Resolve /** * Toggle select all */ - toggleSelectAll() + toggleSelectAll(): void { if ( this.selectedMails.length > 0 ) { @@ -294,7 +317,13 @@ export class MailService implements Resolve } - selectMails(filterParameter?, filterValue?) + /** + * Select mails + * + * @param filterParameter + * @param filterValue + */ + selectMails(filterParameter?, filterValue?): void { this.selectedMails = []; @@ -316,7 +345,10 @@ export class MailService implements Resolve this.onSelectedMailsChanged.next(this.selectedMails); } - deselectMails() + /** + * Deselect mails + */ + deselectMails(): void { this.selectedMails = []; @@ -326,9 +358,10 @@ export class MailService implements Resolve /** * Set current mail by id + * * @param id */ - setCurrentMail(id) + setCurrentMail(id): void { this.currentMail = this.mails.find(mail => { return mail.id === id; @@ -339,9 +372,10 @@ export class MailService implements Resolve /** * Toggle label on selected mails + * * @param labelId */ - toggleLabelOnSelectedMails(labelId) + toggleLabelOnSelectedMails(labelId): void { this.selectedMails.map(mail => { @@ -362,9 +396,10 @@ export class MailService implements Resolve /** * Set folder on selected mails + * * @param folderId */ - setFolderOnSelectedMails(folderId) + setFolderOnSelectedMails(folderId): void { this.selectedMails.map(mail => { mail.folder = folderId; @@ -377,14 +412,15 @@ export class MailService implements Resolve /** * Update the mail + * * @param mail * @returns {Promise} */ - updateMail(mail) + updateMail(mail): Promise { return new Promise((resolve, reject) => { - this.http.post('api/mail-mails/' + mail.id, {...mail}) + this._httpClient.post('api/mail-mails/' + mail.id, {...mail}) .subscribe(response => { this.getMails().then(mails => { @@ -400,5 +436,4 @@ export class MailService implements Resolve }); }); } - } diff --git a/src/app/main/apps/mail/sidenavs/main/main-sidenav.component.ts b/src/app/main/apps/mail/sidenavs/main/main-sidenav.component.ts index f086c281..dab4d5b5 100644 --- a/src/app/main/apps/mail/sidenavs/main/main-sidenav.component.ts +++ b/src/app/main/apps/mail/sidenavs/main/main-sidenav.component.ts @@ -1,20 +1,21 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { FormGroup } from '@angular/forms'; import { MatDialog } from '@angular/material'; -import { Subscription } from 'rxjs'; import { fuseAnimations } from '@fuse/animations'; -import { MailService } from '../../mail.service'; -import { FuseMailComposeDialogComponent } from '../../dialogs/compose/compose.component'; +import { MailService } from 'app/main/apps/mail/mail.service'; +import { MailComposeDialogComponent } from 'app/main/apps/mail/dialogs/compose/compose.component'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; @Component({ - selector : 'fuse-mail-main-sidenav', + selector : 'mail-main-sidenav', templateUrl: './main-sidenav.component.html', styleUrls : ['./main-sidenav.component.scss'], animations : fuseAnimations }) -export class FuseMailMainSidenavComponent implements OnInit, OnDestroy +export class MailMainSidenavComponent implements OnInit, OnDestroy { folders: any[]; filters: any[]; @@ -23,55 +24,79 @@ export class FuseMailMainSidenavComponent implements OnInit, OnDestroy selectedAccount: string; dialogRef: any; - onFoldersChanged: Subscription; - onFiltersChanged: Subscription; - onLabelsChanged: Subscription; + // Private + private _unsubscribeAll: Subject; + /** + * Constructor + * + * @param {MailService} _mailService + * @param {MatDialog} _matDialog + */ constructor( - private mailService: MailService, - public dialog: MatDialog + private _mailService: MailService, + public _matDialog: MatDialog ) { - // Data + // Set the defaults this.accounts = { 'creapond' : 'johndoe@creapond.com', 'withinpixels': 'johndoe@withinpixels.com' }; - this.selectedAccount = 'creapond'; + + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { - this.onFoldersChanged = - this.mailService.onFoldersChanged - .subscribe(folders => { - this.folders = folders; - }); + this._mailService.onFoldersChanged + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(folders => { + this.folders = folders; + }); - this.onFiltersChanged = - this.mailService.onFiltersChanged - .subscribe(filters => { - this.filters = filters; - }); + this._mailService.onFiltersChanged + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(filters => { + this.filters = filters; + }); - this.onLabelsChanged = - this.mailService.onLabelsChanged - .subscribe(labels => { - this.labels = labels; - }); + this._mailService.onLabelsChanged + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(labels => { + this.labels = labels; + }); } - ngOnDestroy() + /** + * On destroy + */ + ngOnDestroy(): void { - this.onFoldersChanged.unsubscribe(); - this.onFiltersChanged.unsubscribe(); - this.onLabelsChanged.unsubscribe(); + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); } - - composeDialog() + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Compose dialog + */ + composeDialog(): void { - this.dialogRef = this.dialog.open(FuseMailComposeDialogComponent, { + this.dialogRef = this._matDialog.open(MailComposeDialogComponent, { panelClass: 'mail-compose-dialog' }); this.dialogRef.afterClosed() diff --git a/src/app/main/apps/scrumboard/board.model.ts b/src/app/main/apps/scrumboard/board.model.ts index 3f061428..3b987661 100644 --- a/src/app/main/apps/scrumboard/board.model.ts +++ b/src/app/main/apps/scrumboard/board.model.ts @@ -67,6 +67,11 @@ export class Board color: string }[]; + /** + * Constructor + * + * @param board + */ constructor(board) { this.name = board.name || 'Untitled Board'; diff --git a/src/app/main/apps/scrumboard/board/add-list/add-list.component.ts b/src/app/main/apps/scrumboard/board/add-list/add-list.component.ts index fc0fcddb..bf74e6b1 100644 --- a/src/app/main/apps/scrumboard/board/add-list/add-list.component.ts +++ b/src/app/main/apps/scrumboard/board/add-list/add-list.component.ts @@ -2,49 +2,77 @@ import { Component, EventEmitter, Output, ViewChild } from '@angular/core'; import { FormBuilder, FormGroup } from '@angular/forms'; @Component({ - selector : 'fuse-scrumboard-board-add-list', + selector : 'scrumboard-board-add-list', templateUrl: './add-list.component.html', styleUrls : ['./add-list.component.scss'] }) -export class FuseScrumboardBoardAddListComponent +export class ScrumboardBoardAddListComponent { - formActive = false; + formActive: boolean; form: FormGroup; - @Output() onlistAdd = new EventEmitter(); - @ViewChild('nameInput') nameInputField; + @Output() + onListAdd: EventEmitter; + + @ViewChild('nameInput') + nameInputField; + + /** + * Constructor + * + * @param {FormBuilder} _formBuilder + */ constructor( - private formBuilder: FormBuilder + private _formBuilder: FormBuilder ) { + // Set the defaults + this.formActive = false; + this.onListAdd = new EventEmitter(); } - - openForm() + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Open form + */ + openForm(): void { - this.form = this.formBuilder.group({ + this.form = this._formBuilder.group({ name: [''] }); this.formActive = true; this.focusNameField(); } - closeForm() + /** + * Close form + */ + closeForm(): void { this.formActive = false; } - focusNameField() + /** + * Focus to the name field + */ + focusNameField(): void { setTimeout(() => { this.nameInputField.nativeElement.focus(); }); } - onFormSubmit() + /** + * On form submit + */ + onFormSubmit(): void { if ( this.form.valid ) { - this.onlistAdd.next(this.form.getRawValue().name); + this.onListAdd.next(this.form.getRawValue().name); this.formActive = false; } } diff --git a/src/app/main/apps/scrumboard/board/board.component.html b/src/app/main/apps/scrumboard/board/board.component.html index f2d4cfae..e98bb873 100644 --- a/src/app/main/apps/scrumboard/board/board.component.html +++ b/src/app/main/apps/scrumboard/board/board.component.html @@ -26,10 +26,10 @@ fxFlex="1 0 100%" fxFlex.gt-xs="1 0 auto" fxFlexOrder="1" fxFlexOrder.gt-xs="2"> remove_red_eye - - + @@ -58,21 +58,21 @@ *fuseIfOnDom [@animateStagger]="{value:'50'}"> - - + - - + + @@ -82,7 +82,7 @@ - + diff --git a/src/app/main/apps/scrumboard/board/board.component.ts b/src/app/main/apps/scrumboard/board/board.component.ts index 85ac0bc8..d225089c 100644 --- a/src/app/main/apps/scrumboard/board/board.component.ts +++ b/src/app/main/apps/scrumboard/board/board.component.ts @@ -1,65 +1,100 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { Location } from '@angular/common'; import { ActivatedRoute } from '@angular/router'; - -import { Subscription } from 'rxjs'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import { fuseAnimations } from '@fuse/animations'; -import { List } from '../list.model'; -import { ScrumboardService } from '../scrumboard.service'; +import { ScrumboardService } from 'app/main/apps/scrumboard/scrumboard.service'; +import { List } from 'app/main/apps/scrumboard/list.model'; @Component({ - selector : 'fuse-scrumboard-board', + selector : 'scrumboard-board', templateUrl: './board.component.html', styleUrls : ['./board.component.scss'], animations : fuseAnimations }) -export class FuseScrumboardBoardComponent implements OnInit, OnDestroy +export class ScrumboardBoardComponent implements OnInit, OnDestroy { board: any; - onBoardChanged: Subscription; + + // Private + private _unsubscribeAll: Subject; constructor( - private route: ActivatedRoute, - private location: Location, - private scrumboardService: ScrumboardService + private _activatedRoute: ActivatedRoute, + private _location: Location, + private _scrumboardService: ScrumboardService ) { + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { - this.onBoardChanged = - this.scrumboardService.onBoardChanged - .subscribe(board => { - this.board = board; - }); + this._scrumboardService.onBoardChanged + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(board => { + this.board = board; + }); } - ngOnDestroy() + /** + * On destroy + */ + ngOnDestroy(): void { - this.onBoardChanged.unsubscribe(); + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); } - onListAdd(newListName) + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * On list add + * + * @param newListName + */ + onListAdd(newListName): void { if ( newListName === '' ) { return; } - this.scrumboardService.addList(new List({name: newListName})); + this._scrumboardService.addList(new List({name: newListName})); } - onBoardNameChanged(newName) + /** + * On board name changed + * + * @param newName + */ + onBoardNameChanged(newName): void { - this.scrumboardService.updateBoard(); - this.location.go('/apps/scrumboard/boards/' + this.board.id + '/' + this.board.uri); + this._scrumboardService.updateBoard(); + this._location.go('/apps/scrumboard/boards/' + this.board.id + '/' + this.board.uri); } - onDrop(ev) + /** + * On drop + * + * @param ev + */ + onDrop(ev): void { - this.scrumboardService.updateBoard(); + this._scrumboardService.updateBoard(); } } diff --git a/src/app/main/apps/scrumboard/board/dialogs/card/card.component.html b/src/app/main/apps/scrumboard/board/dialogs/card/card.component.html index caa2f1b3..3dbb896a 100644 --- a/src/app/main/apps/scrumboard/board/dialogs/card/card.component.html +++ b/src/app/main/apps/scrumboard/board/dialogs/card/card.component.html @@ -35,8 +35,8 @@ - + @@ -130,7 +130,7 @@ - diff --git a/src/app/main/apps/scrumboard/board/dialogs/card/card.component.ts b/src/app/main/apps/scrumboard/board/dialogs/card/card.component.ts index a8c8dff9..4bc04c73 100644 --- a/src/app/main/apps/scrumboard/board/dialogs/card/card.component.ts +++ b/src/app/main/apps/scrumboard/board/dialogs/card/card.component.ts @@ -1,74 +1,108 @@ import { Component, Inject, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core'; import { NgForm } from '@angular/forms/src/forms'; import { MAT_DIALOG_DATA, MatDialog, MatDialogRef, MatMenuTrigger } from '@angular/material'; - -import { Subscription } from 'rxjs'; +import { Subject } from 'rxjs'; import { FuseConfirmDialogComponent } from '@fuse/components/confirm-dialog/confirm-dialog.component'; import { FuseUtils } from '@fuse/utils'; -import { ScrumboardService } from '../../../scrumboard.service'; +import { ScrumboardService } from 'app/main/apps/scrumboard/scrumboard.service'; +import { takeUntil } from 'rxjs/operators'; @Component({ - selector : 'fuse-scrumboard-board-card-dialog', + selector : 'scrumboard-board-card-dialog', templateUrl : './card.component.html', styleUrls : ['./card.component.scss'], encapsulation: ViewEncapsulation.None }) -export class FuseScrumboardCardDialogComponent implements OnInit, OnDestroy +export class ScrumboardCardDialogComponent implements OnInit, OnDestroy { card: any; board: any; list: any; - onBoardChanged: Subscription; toggleInArray = FuseUtils.toggleInArray; - - @ViewChild('checklistMenuTrigger') checklistMenu: MatMenuTrigger; - @ViewChild('newCheckListTitleField') newCheckListTitleField; - confirmDialogRef: MatDialogRef; + @ViewChild('checklistMenuTrigger') + checklistMenu: MatMenuTrigger; + + @ViewChild('newCheckListTitleField') + newCheckListTitleField; + + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {MatDialogRef} _matDialogRef + * @param _data + * @param {MatDialog} _matDialog + * @param {ScrumboardService} _scrumboardService + */ constructor( - public dialogRef: MatDialogRef, - @Inject(MAT_DIALOG_DATA) private data: any, - public dialog: MatDialog, - private scrumboardService: ScrumboardService + private _matDialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) private _data: any, + private _matDialog: MatDialog, + private _scrumboardService: ScrumboardService ) { - + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { - this.onBoardChanged = - this.scrumboardService.onBoardChanged - .subscribe(board => { - this.board = board; + this._scrumboardService.onBoardChanged + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(board => { + this.board = board; - this.card = this.board.cards.find((_card) => { - return this.data.cardId === _card.id; - }); - - this.list = this.board.lists.find((_list) => { - return this.data.listId === _list.id; - }); + this.card = this.board.cards.find((_card) => { + return this._data.cardId === _card.id; }); + + this.list = this.board.lists.find((_list) => { + return this._data.listId === _list.id; + }); + }); } /** - * Remove Due date + * On destroy */ - removeDueDate() + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Remove due date + */ + removeDueDate(): void { this.card.due = ''; this.updateCard(); } /** - * Toggle Subscribe + * Toggle subscribe */ - toggleSubscribe() + toggleSubscribe(): void { this.card.subscribed = !this.card.subscribed; @@ -76,10 +110,11 @@ export class FuseScrumboardCardDialogComponent implements OnInit, OnDestroy } /** - * Toggle Cover Image + * Toggle cover image + * * @param attachmentId */ - toggleCoverImage(attachmentId) + toggleCoverImage(attachmentId): void { if ( this.card.idAttachmentCover === attachmentId ) { @@ -94,10 +129,11 @@ export class FuseScrumboardCardDialogComponent implements OnInit, OnDestroy } /** - * Remove Attachment + * Remove attachment + * * @param attachment */ - removeAttachment(attachment) + removeAttachment(attachment): void { if ( attachment.id === this.card.idAttachmentCover ) { @@ -110,10 +146,11 @@ export class FuseScrumboardCardDialogComponent implements OnInit, OnDestroy } /** - * Remove Checklist + * Remove checklist + * * @param checklist */ - removeChecklist(checklist) + removeChecklist(checklist): void { this.card.checklists.splice(this.card.checklists.indexOf(checklist), 1); @@ -121,10 +158,11 @@ export class FuseScrumboardCardDialogComponent implements OnInit, OnDestroy } /** - * Update Checked Count + * Update checked count + * * @param list */ - updateCheckedCount(list) + updateCheckedCount(list): void { const checkItems = list.checkItems; let checkedItems = 0; @@ -154,11 +192,12 @@ export class FuseScrumboardCardDialogComponent implements OnInit, OnDestroy } /** - * Remove Checklist Item + * Remove checklist item + * * @param checkItem * @param checklist */ - removeChecklistItem(checkItem, checklist) + removeChecklistItem(checkItem, checklist): void { checklist.checkItems.splice(checklist.checkItems.indexOf(checkItem), 1); @@ -168,11 +207,12 @@ export class FuseScrumboardCardDialogComponent implements OnInit, OnDestroy } /** - * Add Check Item + * Add check item + * * @param {NgForm} form * @param checkList */ - addCheckItem(form: NgForm, checkList) + addCheckItem(form: NgForm, checkList): void { const checkItemVal = form.value.checkItem; @@ -196,10 +236,11 @@ export class FuseScrumboardCardDialogComponent implements OnInit, OnDestroy } /** - * Add Checklist + * Add checklist + * * @param {NgForm} form */ - addChecklist(form: NgForm) + addChecklist(form: NgForm): void { this.card.checklists.push({ id : FuseUtils.generateGUID(), @@ -215,9 +256,9 @@ export class FuseScrumboardCardDialogComponent implements OnInit, OnDestroy } /** - * On Checklist Menu Open + * On checklist menu open */ - onChecklistMenuOpen() + onChecklistMenuOpen(): void { setTimeout(() => { this.newCheckListTitleField.nativeElement.focus(); @@ -225,10 +266,11 @@ export class FuseScrumboardCardDialogComponent implements OnInit, OnDestroy } /** - * Add New Comment + * Add new comment + * * @param {NgForm} form */ - addNewComment(form: NgForm) + addNewComment(form: NgForm): void { const newCommentText = form.value.newComment; @@ -246,11 +288,11 @@ export class FuseScrumboardCardDialogComponent implements OnInit, OnDestroy } /** - * Remove Card + * Remove card */ - removeCard() + removeCard(): void { - this.confirmDialogRef = this.dialog.open(FuseConfirmDialogComponent, { + this.confirmDialogRef = this._matDialog.open(FuseConfirmDialogComponent, { disableClose: false }); @@ -259,22 +301,17 @@ export class FuseScrumboardCardDialogComponent implements OnInit, OnDestroy this.confirmDialogRef.afterClosed().subscribe(result => { if ( result ) { - this.dialogRef.close(); - this.scrumboardService.removeCard(this.card.id, this.list.id); + this._matDialogRef.close(); + this._scrumboardService.removeCard(this.card.id, this.list.id); } }); } /** - * Update Card + * Update card */ - updateCard() + updateCard(): void { - this.scrumboardService.updateCard(this.card); - } - - ngOnDestroy() - { - this.onBoardChanged.unsubscribe(); + this._scrumboardService.updateCard(this.card); } } diff --git a/src/app/main/apps/scrumboard/board/dialogs/card/label-selector/label-selector.component.ts b/src/app/main/apps/scrumboard/board/dialogs/card/label-selector/label-selector.component.ts index 3008a485..46cb3bca 100644 --- a/src/app/main/apps/scrumboard/board/dialogs/card/label-selector/label-selector.component.ts +++ b/src/app/main/apps/scrumboard/board/dialogs/card/label-selector/label-selector.component.ts @@ -1,68 +1,110 @@ import { Component, EventEmitter, Input, OnDestroy, OnInit, Output, ViewEncapsulation } from '@angular/core'; - -import { Subscription } from 'rxjs'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import { fuseAnimations } from '@fuse/animations'; import { FuseUtils } from '@fuse/utils'; -import { ScrumboardService } from '../../../../scrumboard.service'; +import { ScrumboardService } from 'app/main/apps/scrumboard/scrumboard.service'; @Component({ - selector : 'fuse-scrumboard-label-selector', + selector : 'scrumboard-label-selector', templateUrl : './label-selector.component.html', styleUrls : ['./label-selector.component.scss'], encapsulation: ViewEncapsulation.None, animations : fuseAnimations }) -export class FuseScrumboardLabelSelectorComponent implements OnInit, OnDestroy +export class ScrumboardLabelSelectorComponent implements OnInit, OnDestroy { + @Input('card') + card: any; + + @Output() + onCardLabelsChange: EventEmitter; + board: any; - @Input('card') card: any; - @Output() onCardLabelsChange = new EventEmitter(); - - labelsMenuView = 'labels'; + labelsMenuView: string; selectedLabel: any; - newLabel = { - 'id' : '', - 'name' : '', - 'color': 'mat-blue-400-bg' - }; - toggleInArray = FuseUtils.toggleInArray; + newLabel: any; + toggleInArray: any; - onBoardChanged: Subscription; + // Private + private _unsubscribeAll: Subject; + /** + * Constructor + * + * @param {ScrumboardService} _scrumboardService + */ constructor( - private scrumboardService: ScrumboardService + private _scrumboardService: ScrumboardService ) { + // Set the defaults + this.onCardLabelsChange = new EventEmitter(); + this.labelsMenuView = 'labels'; + this.newLabel = { + 'id' : '', + 'name' : '', + 'color': 'mat-blue-400-bg' + }; + this.toggleInArray = FuseUtils.toggleInArray; + + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { - this.onBoardChanged = - this.scrumboardService.onBoardChanged - .subscribe(board => { - this.board = board; - }); + this._scrumboardService.onBoardChanged + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(board => { + this.board = board; + }); } - ngOnDestroy() + /** + * On destroy + */ + ngOnDestroy(): void { - this.onBoardChanged.unsubscribe(); + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); } - cardLabelsChanged() + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Card labels changed + */ + cardLabelsChanged(): void { this.onCardLabelsChange.next(); } - onLabelChange() + /** + * On label change + */ + onLabelChange(): void { - this.scrumboardService.updateBoard(); + this._scrumboardService.updateBoard(); } - addNewLabel() + /** + * Add new label + */ + addNewLabel(): void { this.newLabel.id = FuseUtils.generateGUID(); this.board.labels.push(Object.assign({}, this.newLabel)); diff --git a/src/app/main/apps/scrumboard/board/edit-board-name/edit-board-name.component.ts b/src/app/main/apps/scrumboard/board/edit-board-name/edit-board-name.component.ts index 68f67b92..66ab3c71 100644 --- a/src/app/main/apps/scrumboard/board/edit-board-name/edit-board-name.component.ts +++ b/src/app/main/apps/scrumboard/board/edit-board-name/edit-board-name.component.ts @@ -2,25 +2,41 @@ import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core import { FormBuilder, FormGroup } from '@angular/forms'; @Component({ - selector : 'fuse-scrumboard-edit-board-name', + selector : 'scrumboard-edit-board-name', templateUrl: './edit-board-name.component.html', styleUrls : ['./edit-board-name.component.scss'] }) -export class FuseScrumboardEditBoardNameComponent +export class ScrumboardEditBoardNameComponent { - formActive = false; + formActive: boolean; form: FormGroup; - @Input() board; - @Output() onNameChanged = new EventEmitter(); - @ViewChild('nameInput') nameInputField; + + @Input() + board; + + @Output() + onNameChanged: EventEmitter; + + @ViewChild('nameInput') + nameInputField; constructor( private formBuilder: FormBuilder ) { + // Set the defaults + this.formActive = false; + this.onNameChanged = new EventEmitter(); } - openForm() + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Open form + */ + openForm(): void { this.form = this.formBuilder.group({ name: [this.board.name] @@ -29,19 +45,28 @@ export class FuseScrumboardEditBoardNameComponent this.focusNameField(); } - closeForm() + /** + * Close form + */ + closeForm(): void { this.formActive = false; } - focusNameField() + /** + * Focus to the name field + */ + focusNameField(): void { setTimeout(() => { this.nameInputField.nativeElement.focus(); }); } - onFormSubmit() + /** + * On form submit + */ + onFormSubmit(): void { if ( this.form.valid ) { @@ -52,5 +77,4 @@ export class FuseScrumboardEditBoardNameComponent this.formActive = false; } } - } diff --git a/src/app/main/apps/scrumboard/board/list/add-card/add-card.component.ts b/src/app/main/apps/scrumboard/board/list/add-card/add-card.component.ts index e3381072..4a2268d3 100644 --- a/src/app/main/apps/scrumboard/board/list/add-card/add-card.component.ts +++ b/src/app/main/apps/scrumboard/board/list/add-card/add-card.component.ts @@ -2,45 +2,73 @@ import { Component, EventEmitter, Output, ViewChild } from '@angular/core'; import { FormBuilder, FormGroup } from '@angular/forms'; @Component({ - selector : 'fuse-scrumboard-board-add-card', + selector : 'scrumboard-board-add-card', templateUrl: './add-card.component.html', styleUrls : ['./add-card.component.scss'] }) -export class FuseScrumboardBoardAddCardComponent +export class ScrumboardBoardAddCardComponent { - formActive = false; + formActive: boolean; form: FormGroup; - @Output() onCardAdd = new EventEmitter(); - @ViewChild('nameInput') nameInputField; + @Output() + onCardAdd: EventEmitter; + + @ViewChild('nameInput') + nameInputField; + + /** + * Constructor + * + * @param {FormBuilder} _formBuilder + */ constructor( - private formBuilder: FormBuilder + private _formBuilder: FormBuilder ) { + // Set the defaults + this.formActive = false; + this.onCardAdd = new EventEmitter(); } - - openForm() + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Open the form + */ + openForm(): void { - this.form = this.formBuilder.group({ + this.form = this._formBuilder.group({ name: '' }); this.formActive = true; this.focusNameField(); } - closeForm() + /** + * Close the form + */ + closeForm(): void { this.formActive = false; } - focusNameField() + /** + * Focus to the name field + */ + focusNameField(): void { setTimeout(() => { this.nameInputField.nativeElement.focus(); }); } - onFormSubmit() + /** + * On form submit + */ + onFormSubmit(): void { if ( this.form.valid ) { diff --git a/src/app/main/apps/scrumboard/board/list/card/card.component.ts b/src/app/main/apps/scrumboard/board/list/card/card.component.ts index 9ec11bd9..0c47bf23 100644 --- a/src/app/main/apps/scrumboard/board/list/card/card.component.ts +++ b/src/app/main/apps/scrumboard/board/list/card/card.component.ts @@ -3,40 +3,57 @@ import { ActivatedRoute } from '@angular/router'; import * as moment from 'moment'; @Component({ - selector : 'fuse-scrumboard-board-card', + selector : 'scrumboard-board-card', templateUrl : './card.component.html', styleUrls : ['./card.component.scss'], encapsulation: ViewEncapsulation.None }) -export class FuseScrumboardBoardCardComponent implements OnInit +export class ScrumboardBoardCardComponent implements OnInit { - @Input() cardId; + @Input() + cardId; + card: any; board: any; + /** + * Constructor + * + * @param {ActivatedRoute} _activatedRoute + */ constructor( - private route: ActivatedRoute, + private _activatedRoute: ActivatedRoute ) { } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { - this.board = this.route.snapshot.data.board; + this.board = this._activatedRoute.snapshot.data.board; this.card = this.board.cards.filter((card) => { return this.cardId === card.id; })[0]; } + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + /** * Is the card overdue? * * @param cardDate * @returns {boolean} */ - isOverdue(cardDate) + isOverdue(cardDate): boolean { return moment() > moment(new Date(cardDate)); } - } diff --git a/src/app/main/apps/scrumboard/board/list/edit-list-name/edit-list-name.component.ts b/src/app/main/apps/scrumboard/board/list/edit-list-name/edit-list-name.component.ts index 56591cb1..55cf831d 100644 --- a/src/app/main/apps/scrumboard/board/list/edit-list-name/edit-list-name.component.ts +++ b/src/app/main/apps/scrumboard/board/list/edit-list-name/edit-list-name.component.ts @@ -2,46 +2,76 @@ import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core import { FormBuilder, FormGroup } from '@angular/forms'; @Component({ - selector : 'fuse-scrumboard-board-edit-list-name', + selector : 'scrumboard-board-edit-list-name', templateUrl: './edit-list-name.component.html', styleUrls : ['./edit-list-name.component.scss'] }) -export class FuseScrumboardBoardEditListNameComponent +export class ScrumboardBoardEditListNameComponent { - formActive = false; + formActive: boolean; form: FormGroup; - @Input() list; - @Output() onNameChanged = new EventEmitter(); - @ViewChild('nameInput') nameInputField; + @Input() + list; + + @Output() + onNameChanged: EventEmitter; + + @ViewChild('nameInput') + nameInputField; + + /** + * Constructor + * + * @param {FormBuilder} _formBuilder + */ constructor( - private formBuilder: FormBuilder + private _formBuilder: FormBuilder ) { + // Set the defaults + this.formActive = false; + this.onNameChanged = new EventEmitter(); } - openForm() + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Open the form + */ + openForm(): void { - this.form = this.formBuilder.group({ + this.form = this._formBuilder.group({ name: [this.list.name] }); this.formActive = true; this.focusNameField(); } - closeForm() + /** + * Close the form + */ + closeForm(): void { this.formActive = false; } - focusNameField() + /** + * Focus to the name field + */ + focusNameField(): void { setTimeout(() => { this.nameInputField.nativeElement.focus(); }); } - onFormSubmit() + /** + * On form submit + */ + onFormSubmit(): void { if ( this.form.valid ) { @@ -50,5 +80,4 @@ export class FuseScrumboardBoardEditListNameComponent this.formActive = false; } } - } diff --git a/src/app/main/apps/scrumboard/board/list/list.component.html b/src/app/main/apps/scrumboard/board/list/list.component.html index 2899c33c..33324778 100644 --- a/src/app/main/apps/scrumboard/board/list/list.component.html +++ b/src/app/main/apps/scrumboard/board/list/list.component.html @@ -3,11 +3,11 @@
- - +
diff --git a/src/app/main/apps/scrumboard/board/list/list.component.ts b/src/app/main/apps/scrumboard/board/list/list.component.ts index d90ecc5e..15093f75 100644 --- a/src/app/main/apps/scrumboard/board/list/list.component.ts +++ b/src/app/main/apps/scrumboard/board/list/list.component.ts @@ -1,78 +1,122 @@ import { Component, Input, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { MatDialog, MatDialogRef } from '@angular/material'; - -import { Subscription } from 'rxjs'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import { FuseConfirmDialogComponent } from '@fuse/components/confirm-dialog/confirm-dialog.component'; import { FusePerfectScrollbarDirective } from '@fuse/directives/fuse-perfect-scrollbar/fuse-perfect-scrollbar.directive'; -import { Card } from '../../card.model'; -import { ScrumboardService } from '../../scrumboard.service'; -import { FuseScrumboardCardDialogComponent } from '../dialogs/card/card.component'; +import { ScrumboardService } from 'app/main/apps/scrumboard/scrumboard.service'; +import { Card } from 'app/main/apps/scrumboard/card.model'; +import { ScrumboardCardDialogComponent } from 'app/main/apps/scrumboard/board/dialogs/card/card.component'; @Component({ - selector : 'fuse-scrumboard-board-list', + selector : 'scrumboard-board-list', templateUrl : './list.component.html', styleUrls : ['./list.component.scss'], encapsulation: ViewEncapsulation.None }) -export class FuseScrumboardBoardListComponent implements OnInit, OnDestroy +export class ScrumboardBoardListComponent implements OnInit, OnDestroy { board: any; dialogRef: any; - @Input() list; - @ViewChild(FusePerfectScrollbarDirective) listScroll: FusePerfectScrollbarDirective; + @Input() + list; + + @ViewChild(FusePerfectScrollbarDirective) + listScroll: FusePerfectScrollbarDirective; - onBoardChanged: Subscription; confirmDialogRef: MatDialogRef; + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {ActivatedRoute} _activatedRoute + * @param {ScrumboardService} _scrumboardService + * @param {MatDialog} _matDialog + */ constructor( - private route: ActivatedRoute, - private scrumboardService: ScrumboardService, - public dialog: MatDialog + private _activatedRoute: ActivatedRoute, + private _scrumboardService: ScrumboardService, + private _matDialog: MatDialog ) { + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { - this.onBoardChanged = - this.scrumboardService.onBoardChanged - .subscribe(board => { - this.board = board; - }); + this._scrumboardService.onBoardChanged + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(board => { + this.board = board; + }); } - ngOnDestroy() + /** + * On destroy + */ + ngOnDestroy(): void { - this.onBoardChanged.unsubscribe(); + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); } - onListNameChanged(newListName) + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * On list name changed + * + * @param newListName + */ + onListNameChanged(newListName): void { this.list.name = newListName; } - onCardAdd(newCardName) + /** + * On card added + * + * @param newCardName + */ + onCardAdd(newCardName): void { if ( newCardName === '' ) { return; } - this.scrumboardService.addCard(this.list.id, new Card({name: newCardName})); + this._scrumboardService.addCard(this.list.id, new Card({name: newCardName})); setTimeout(() => { this.listScroll.scrollToBottom(0, 400); }); - } - removeList(listId) + /** + * Remove list + * + * @param listId + */ + removeList(listId): void { - this.confirmDialogRef = this.dialog.open(FuseConfirmDialogComponent, { + this.confirmDialogRef = this._matDialog.open(FuseConfirmDialogComponent, { disableClose: false }); @@ -81,14 +125,19 @@ export class FuseScrumboardBoardListComponent implements OnInit, OnDestroy this.confirmDialogRef.afterClosed().subscribe(result => { if ( result ) { - this.scrumboardService.removeList(listId); + this._scrumboardService.removeList(listId); } }); } - openCardDialog(cardId) + /** + * Open card dialog + * + * @param cardId + */ + openCardDialog(cardId): void { - this.dialogRef = this.dialog.open(FuseScrumboardCardDialogComponent, { + this.dialogRef = this._matDialog.open(ScrumboardCardDialogComponent, { panelClass: 'scrumboard-card-dialog', data : { cardId: cardId, @@ -101,8 +150,13 @@ export class FuseScrumboardBoardListComponent implements OnInit, OnDestroy }); } - onDrop(ev) + /** + * On drop + * + * @param ev + */ + onDrop(ev): void { - this.scrumboardService.updateBoard(); + this._scrumboardService.updateBoard(); } } diff --git a/src/app/main/apps/scrumboard/board/sidenavs/settings/board-color-selector/board-color-selector.component.ts b/src/app/main/apps/scrumboard/board/sidenavs/settings/board-color-selector/board-color-selector.component.ts index f5f0f0f6..239ee075 100644 --- a/src/app/main/apps/scrumboard/board/sidenavs/settings/board-color-selector/board-color-selector.component.ts +++ b/src/app/main/apps/scrumboard/board/sidenavs/settings/board-color-selector/board-color-selector.component.ts @@ -1,46 +1,78 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; - -import { Subscription } from 'rxjs'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import { MatColors } from '@fuse/mat-colors'; -import { ScrumboardService } from '../../../../scrumboard.service'; +import { ScrumboardService } from 'app/main/apps/scrumboard/scrumboard.service'; @Component({ - selector : 'fuse-scrumboard-board-color-selector', + selector : 'scrumboard-board-color-selector', templateUrl: './board-color-selector.component.html', styleUrls : ['./board-color-selector.component.scss'] }) -export class FuseScrumboardBoardColorSelectorComponent implements OnInit, OnDestroy +export class ScrumboardBoardColorSelectorComponent implements OnInit, OnDestroy { colors: any; board: any; - onBoardChanged: Subscription; + // Private + private _unsubscribeAll: Subject; + + /** + * Constructor + * + * @param {ScrumboardService} _scrumboardService + */ constructor( - private scrumboardService: ScrumboardService + private _scrumboardService: ScrumboardService ) { + // Set the defaults this.colors = MatColors.all; + + // Set the private defaults + this._unsubscribeAll = new Subject(); } - ngOnInit() + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { - this.onBoardChanged = - this.scrumboardService.onBoardChanged - .subscribe(board => { - this.board = board; - }); + this._scrumboardService.onBoardChanged + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(board => { + this.board = board; + }); } - ngOnDestroy() + /** + * On destroy + */ + ngOnDestroy(): void { - this.onBoardChanged.unsubscribe(); + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); } - setColor(color) + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Set the color + * + * @param color + */ + setColor(color): void { this.board.settings.color = color; - this.scrumboardService.updateBoard(); + this._scrumboardService.updateBoard(); } } diff --git a/src/app/main/apps/scrumboard/board/sidenavs/settings/settings.component.html b/src/app/main/apps/scrumboard/board/sidenavs/settings/settings.component.html index e407b7ec..effbb249 100644 --- a/src/app/main/apps/scrumboard/board/sidenavs/settings/settings.component.html +++ b/src/app/main/apps/scrumboard/board/sidenavs/settings/settings.component.html @@ -28,7 +28,7 @@