From b0e4f87a8aaf9b12b5177616169a91d118a5ee3f Mon Sep 17 00:00:00 2001 From: Sercan Yemen Date: Thu, 20 Jul 2017 18:12:09 +0300 Subject: [PATCH] mail.. --- src/app/core/pipes/getById.pipe.ts | 4 +- src/app/core/pipes/pipes.module.ts | 7 +- src/app/core/pipes/search.pipe.ts | 49 --- src/app/fuse-fake-db/fuse-fake-db.service.ts | 7 +- src/app/fuse-fake-db/mail.ts | 99 ++---- .../mail-details/mail-details.component.html | 26 +- .../mail-details/mail-details.component.scss | 2 + .../mail-details/mail-details.component.ts | 31 +- .../mail-list-item.component.html | 2 +- .../mail-list-item.component.scss | 2 +- .../mail-list-item.component.ts | 64 +++- .../mail/mail-list/mail-list.component.html | 13 +- .../mail/mail-list/mail-list.component.ts | 73 ++-- src/app/main/apps/mail/mail.component.html | 40 ++- src/app/main/apps/mail/mail.component.ts | 60 +++- src/app/main/apps/mail/mail.model.ts | 4 +- src/app/main/apps/mail/mail.module.ts | 14 + src/app/main/apps/mail/mail.service.ts | 312 ++++++++++++++---- .../sidenavs/main/main-sidenav.component.html | 25 +- .../sidenavs/main/main-sidenav.component.ts | 18 +- tslint.json | 2 +- 21 files changed, 557 insertions(+), 297 deletions(-) delete mode 100644 src/app/core/pipes/search.pipe.ts diff --git a/src/app/core/pipes/getById.pipe.ts b/src/app/core/pipes/getById.pipe.ts index fbbf6895..e2797aad 100644 --- a/src/app/core/pipes/getById.pipe.ts +++ b/src/app/core/pipes/getById.pipe.ts @@ -3,10 +3,10 @@ import { Pipe, PipeTransform } from '@angular/core'; @Pipe({name: 'getById'}) export class GetByIdPipe implements PipeTransform { - transform(value: any[], id: number, property: string ): any + transform(value: any[], id: number, property: string): any { const foundItem = value.find(item => { - if ( item.id ) + if ( item.id !== undefined ) { return item.id === id; } diff --git a/src/app/core/pipes/pipes.module.ts b/src/app/core/pipes/pipes.module.ts index a5f01259..613a8514 100644 --- a/src/app/core/pipes/pipes.module.ts +++ b/src/app/core/pipes/pipes.module.ts @@ -3,21 +3,18 @@ import { NgModule } from '@angular/core'; import { KeysPipe } from './keys.pipe'; import { GetByIdPipe } from './getById.pipe'; import { HtmlToPlaintextPipe } from './htmlToPlaintext.pipe'; -import { SearchPipe } from './search.pipe'; @NgModule({ declarations: [ KeysPipe, GetByIdPipe, - HtmlToPlaintextPipe, - SearchPipe + HtmlToPlaintextPipe ], imports : [], exports : [ KeysPipe, GetByIdPipe, - HtmlToPlaintextPipe, - SearchPipe + HtmlToPlaintextPipe ] }) diff --git a/src/app/core/pipes/search.pipe.ts b/src/app/core/pipes/search.pipe.ts deleted file mode 100644 index afa0e955..00000000 --- a/src/app/core/pipes/search.pipe.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Pipe, PipeTransform } from '@angular/core'; - -@Pipe({ - name: 'filter' -}) -export class SearchPipe implements PipeTransform -{ - transform(items: any, term: string): any - { - if ( term === undefined ) - { - return items; - } - - return this.filter(items, term); - } - - filter(items: any, term: string) - { - return items.filter(item => { - - for ( const property in item ) - { - if ( !item.hasOwnProperty(property) || !item[property] ) - { - console.log('continueing...'); - continue; - } - - if ( Array.isArray(item[property]) ) - { - console.log('is Array'); - return this.filter(item[property], term); - } - - if ( item[property].toString().toLowerCase().includes(term.toLowerCase()) ) - { - console.log('found!'); - return true; - } - } - - return false; - } - ); - } -} - - diff --git a/src/app/fuse-fake-db/fuse-fake-db.service.ts b/src/app/fuse-fake-db/fuse-fake-db.service.ts index 143b82d6..552e0cb8 100644 --- a/src/app/fuse-fake-db/fuse-fake-db.service.ts +++ b/src/app/fuse-fake-db/fuse-fake-db.service.ts @@ -1,13 +1,14 @@ -import {InMemoryDbService} from 'angular-in-memory-web-api'; -import {MailFakeDb} from './mail'; +import { InMemoryDbService } from 'angular-in-memory-web-api'; +import { MailFakeDb } from './mail'; export class FuseFakeDbService implements InMemoryDbService { createDb() { return { - 'mail-mails' : MailFakeDb.mails, + 'mail-mails' : MailFakeDb.mails, 'mail-folders': MailFakeDb.folders, + 'mail-filters': MailFakeDb.filters, 'mail-labels' : MailFakeDb.labels }; } diff --git a/src/app/fuse-fake-db/mail.ts b/src/app/fuse-fake-db/mail.ts index 54e365aa..af387198 100644 --- a/src/app/fuse-fake-db/mail.ts +++ b/src/app/fuse-fake-db/mail.ts @@ -47,11 +47,7 @@ export class MailFakeDb 'labels' : [ 1 ], - 'folders' : [ - 0, - 1, - 2 - ] + 'folder' : 0 }, { 'id' : '154588a0864d2881124', @@ -74,11 +70,7 @@ export class MailFakeDb 'important' : false, 'hasAttachments': false, 'labels' : [], - 'folders' : [ - 0, - 1, - 2 - ] + 'folder' : 0 }, { 'id' : '15453ba60d3baa5daaf', @@ -104,11 +96,7 @@ export class MailFakeDb 3, 2 ], - 'folders' : [ - 0, - 1, - 2 - ] + 'folder' : 0 }, { 'id' : '15453a06c08fb021776', @@ -134,11 +122,7 @@ export class MailFakeDb 3, 4 ], - 'folders' : [ - 0, - 1, - 2 - ] + 'folder' : 0 }, { 'id' : '154537435d5b32bf11a', @@ -161,11 +145,7 @@ export class MailFakeDb 'important' : false, 'hasAttachments': false, 'labels' : [], - 'folders' : [ - 0, - 1, - 2 - ] + 'folder' : 0 }, { 'id' : '1544e43dcdae6ebf876', @@ -190,11 +170,7 @@ export class MailFakeDb 'labels' : [ 2 ], - 'folders' : [ - 0, - 1, - 2 - ] + 'folder' : 0 }, { 'id' : '1543ee3a5b43e0f9f45', @@ -217,11 +193,7 @@ export class MailFakeDb 'important' : false, 'hasAttachments': false, 'labels' : [], - 'folders' : [ - 0, - 1, - 2 - ] + 'folder' : 0 }, { 'id' : '1543cc4515df3146112', @@ -244,11 +216,7 @@ export class MailFakeDb 'important' : false, 'hasAttachments': false, 'labels' : [], - 'folders' : [ - 0, - 1, - 2 - ] + 'folder' : 0 }, { 'id' : '154398a4770d7aaf9a2', @@ -271,11 +239,7 @@ export class MailFakeDb 'important' : false, 'hasAttachments': false, 'labels' : [], - 'folders' : [ - 0, - 1, - 2 - ] + 'folder' : 0 }, { 'id' : '15438351f87dcd68567', @@ -298,11 +262,7 @@ export class MailFakeDb 'important' : false, 'hasAttachments': false, 'labels' : [], - 'folders' : [ - 0, - 1, - 2 - ] + 'folder' : 0 }, { 'id' : '1542d75d929a603125', @@ -325,11 +285,7 @@ export class MailFakeDb 'important' : false, 'hasAttachments': false, 'labels' : [], - 'folders' : [ - 0, - 1, - 2 - ] + 'folder' : 0 }, { 'id' : '1541ca7af66da284177', @@ -352,11 +308,7 @@ export class MailFakeDb 'important' : false, 'hasAttachments': false, 'labels' : [], - 'folders' : [ - 0, - 1, - 2 - ] + 'folder' : 0 }, { 'id' : '154297167e781781745', @@ -379,11 +331,7 @@ export class MailFakeDb 'important' : false, 'hasAttachments': false, 'labels' : [], - 'folders' : [ - 0, - 1, - 2 - ] + 'folder' : 0 }, { 'id' : '15427f4c1b7f3953234', @@ -406,9 +354,7 @@ export class MailFakeDb 'important' : false, 'hasAttachments': false, 'labels' : [], - 'folders' : [ - 3 - ] + 'folder' : 3 }, { 'id' : '154204e45a59b168453', @@ -431,9 +377,7 @@ export class MailFakeDb 'important' : false, 'hasAttachments': false, 'labels' : [], - 'folders' : [ - 3 - ] + 'folder' : 3 }, { 'id' : '1541dd1e05dfc439216', @@ -456,9 +400,7 @@ export class MailFakeDb 'important' : false, 'hasAttachments': false, 'labels' : [], - 'folders' : [ - 3 - ] + 'folder' : 3 } ]; @@ -492,15 +434,18 @@ export class MailFakeDb 'handle': 'trash', 'title' : 'Trash', 'icon' : 'delete' - }, + } + ]; + + public static filters = [ { - 'id' : 5, + 'id' : 0, 'handle': 'starred', 'title' : 'Starred', 'icon' : 'star' }, { - 'id' : 6, + 'id' : 1, 'handle': 'important', 'title' : 'Important', 'icon' : 'label' diff --git a/src/app/main/apps/mail/mail-details/mail-details.component.html b/src/app/main/apps/mail/mail-details/mail-details.component.html index 3b7e5a5c..41d2c451 100644 --- a/src/app/main/apps/mail/mail-details/mail-details.component.html +++ b/src/app/main/apps/mail/mail-details/mail-details.component.html @@ -60,16 +60,9 @@ - - Show Details - - - - Hide Details + + Show Details + Hide Details
@@ -88,16 +81,13 @@
- - @@ -125,7 +115,7 @@ ({{mail.attachments.length}}) -
+
@@ -133,8 +123,8 @@
- View - Download + View + Download
({{attachment.size}})
diff --git a/src/app/main/apps/mail/mail-details/mail-details.component.scss b/src/app/main/apps/mail/mail-details/mail-details.component.scss index 2483238a..a74007ae 100644 --- a/src/app/main/apps/mail/mail-details/mail-details.component.scss +++ b/src/app/main/apps/mail/mail-details/mail-details.component.scss @@ -54,6 +54,8 @@ } .toggle-details { + user-select: none; + text-decoration: underline; padding-top: 16px; cursor: pointer; font-weight: 500; diff --git a/src/app/main/apps/mail/mail-details/mail-details.component.ts b/src/app/main/apps/mail/mail-details/mail-details.component.ts index bb9744a4..b4d56ae3 100644 --- a/src/app/main/apps/mail/mail-details/mail-details.component.ts +++ b/src/app/main/apps/mail/mail-details/mail-details.component.ts @@ -1,28 +1,43 @@ -import { Component, Input, OnInit } from '@angular/core'; -import { Mail } from '../mail.model'; +import { Component, OnDestroy, OnInit } from '@angular/core'; import { MailService } from '../mail.service'; +import { Mail } from '../mail.model'; +import { Subscription } from 'rxjs/Subscription'; @Component({ selector : 'fuse-mail-details', templateUrl: './mail-details.component.html', styleUrls : ['./mail-details.component.scss'] }) -export class MailDetailsComponent implements OnInit +export class MailDetailsComponent implements OnInit, OnDestroy { - @Input('selectedMail') public mail: Mail; - showDetails: boolean; + mail: Mail; labels: any[]; + showDetails = false; + + onCurrentMailChanged: Subscription; constructor( private mailService: MailService ) { - this.showDetails = false; } ngOnInit() { + // Set initial values this.labels = this.mailService.labels; + this.mail = this.mailService.currentMail; + + // Subscribe to update the current mail + this.onCurrentMailChanged = this.mailService.onCurrentMailChanged + .subscribe(currentMail => { + this.mail = currentMail; + }); + } + + ngOnDestroy() + { + this.onCurrentMailChanged.unsubscribe(); } toggleStar(event) @@ -31,7 +46,7 @@ export class MailDetailsComponent implements OnInit this.mail.toggleStar(); - this.mailService.update(this.mail); + this.mailService.updateMail(this.mail); } toggleImportant(event) @@ -40,7 +55,7 @@ export class MailDetailsComponent implements OnInit this.mail.toggleImportant(); - this.mailService.update(this.mail); + this.mailService.updateMail(this.mail); } } diff --git a/src/app/main/apps/mail/mail-list/mail-list-item/mail-list-item.component.html b/src/app/main/apps/mail/mail-list/mail-list-item/mail-list-item.component.html index a69ad022..447054c7 100644 --- a/src/app/main/apps/mail/mail-list/mail-list-item/mail-list-item.component.html +++ b/src/app/main/apps/mail/mail-list/mail-list-item/mail-list-item.component.html @@ -1,6 +1,6 @@
- +
diff --git a/src/app/main/apps/mail/mail-list/mail-list-item/mail-list-item.component.scss b/src/app/main/apps/mail/mail-list/mail-list-item/mail-list-item.component.scss index 65af7638..a2b87864 100644 --- a/src/app/main/apps/mail/mail-list/mail-list-item/mail-list-item.component.scss +++ b/src/app/main/apps/mail/mail-list/mail-list-item/mail-list-item.component.scss @@ -41,7 +41,7 @@ } } - &.selected-mail { + &.current-mail { background: #E3F2FD; .info { diff --git a/src/app/main/apps/mail/mail-list/mail-list-item/mail-list-item.component.ts b/src/app/main/apps/mail/mail-list/mail-list-item/mail-list-item.component.ts index e8bf868d..cdf04226 100644 --- a/src/app/main/apps/mail/mail-list/mail-list-item/mail-list-item.component.ts +++ b/src/app/main/apps/mail/mail-list/mail-list-item/mail-list-item.component.ts @@ -1,20 +1,22 @@ -import { Component, Input, OnInit } from '@angular/core'; +import { Component, Input, OnDestroy, OnInit } from '@angular/core'; import { Mail } from '../../mail.model'; import { MailService } from '../../mail.service'; -import { ActivatedRoute } from '@angular/router'; +import { Subscription } from 'rxjs/Subscription'; @Component({ selector : 'fuse-mail-list-item', templateUrl: './mail-list-item.component.html', styleUrls : ['./mail-list-item.component.scss'] }) -export class MailListItemComponent implements OnInit +export class MailListItemComponent implements OnInit, OnDestroy { @Input() mail: Mail; labels: any[]; + selected: boolean; + + onSelectedMailsChanged: Subscription; constructor( - private route: ActivatedRoute, private mailService: MailService ) { @@ -23,25 +25,75 @@ export class MailListItemComponent implements OnInit ngOnInit() { + // Set the initial values this.mail = new Mail(this.mail); this.labels = this.mailService.labels; + + if ( this.mailService.selectedMails.length > 0 ) + { + for ( const mail of this.mailService.selectedMails ) + { + if ( mail.id === this.mail.id ) + { + this.selected = true; + break; + } + } + } + + // Subscribe to update on selected mail change + this.onSelectedMailsChanged = + this.mailService.onSelectedMailsChanged + .subscribe(selectedMails => { + this.selected = false; + + if ( selectedMails.length > 0 ) + { + for ( const mail of selectedMails ) + { + if ( mail.id === this.mail.id ) + { + this.selected = true; + break; + } + } + } + }); } + ngOnDestroy() + { + this.onSelectedMailsChanged.unsubscribe(); + } + + onSelectedChange() + { + this.mailService.toggleSelectedMail(this.mail.id); + } + + /** + * Toggle star + * @param event + */ toggleStar(event) { event.stopPropagation(); this.mail.toggleStar(); - this.mailService.update(this.mail); + this.mailService.updateMail(this.mail); } + /** + * Toggle Important + * @param event + */ toggleImportant(event) { event.stopPropagation(); this.mail.toggleImportant(); - this.mailService.update(this.mail); + this.mailService.updateMail(this.mail); } } diff --git a/src/app/main/apps/mail/mail-list/mail-list.component.html b/src/app/main/apps/mail/mail-list/mail-list.component.html index 698a242d..98f777dc 100644 --- a/src/app/main/apps/mail/mail-list/mail-list.component.html +++ b/src/app/main/apps/mail/mail-list/mail-list.component.html @@ -2,15 +2,6 @@ There are no messages!
- - -{{search}} - -
-
-
-
- - + 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 a38e4512..0075e7ea 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,21 +1,22 @@ -import { Component, Input, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; import { Mail } from '../mail.model'; import { ActivatedRoute } from '@angular/router'; import { MailService } from '../mail.service'; import { Location } from '@angular/common'; +import { Subscription } from 'rxjs/Subscription'; @Component({ selector : 'fuse-mail-list', templateUrl: './mail-list.component.html', styleUrls : ['./mail-list.component.scss'] }) -export class MailListComponent implements OnInit +export class MailListComponent implements OnInit, OnDestroy { mails: Mail[]; + currentMail: Mail; - @Input('selectedMail') public selectedMail: Mail; - - search: string; + onMailsChanged: Subscription; + onCurrentMailChanged: Subscription; constructor( private route: ActivatedRoute, @@ -30,32 +31,56 @@ export class MailListComponent implements OnInit // Get mails for the first time this.mails = this.mailService.mails; + // Get current mail for the first time if available + this.currentMail = this.mailService.currentMail || null; + // Subscribe to update mails on changes - this.mailService.onMailsUpdated - .subscribe(mails => { - this.mails = mails; - }); + this.onMailsChanged = + this.mailService.onMailsChanged + .subscribe(mails => { + this.mails = mails; + }); - this.mailService.onSelectedMailUpdated - .subscribe(selectedMail => { - if ( !selectedMail ) - { - const labelHandle = this.route.snapshot.params.labelHandle, - folderHandle = this.route.snapshot.params.folderHandle; - - if ( labelHandle ) + // Subscribe to update current mail on changes + this.onCurrentMailChanged = + this.mailService.onCurrentMailChanged + .subscribe(currentMail => { + if ( !currentMail ) { - this.location.go('apps/mail/label/' + 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, + folderHandle = this.route.snapshot.params.folderHandle; + + if ( labelHandle ) + { + this.location.go('apps/mail/label/' + labelHandle); + } + else + { + this.location.go('apps/mail/' + folderHandle); + } } else { - this.location.go('apps/mail/' + folderHandle); + this.currentMail = currentMail; } - } - }); + }); } - selectMail(mailId) + ngOnDestroy() + { + this.onMailsChanged.unsubscribe(); + this.onCurrentMailChanged.unsubscribe(); + } + + /** + * Read mail + * @param mailId + */ + readMail(mailId) { const labelHandle = this.route.snapshot.params.labelHandle, folderHandle = this.route.snapshot.params.folderHandle; @@ -69,8 +94,8 @@ export class MailListComponent implements OnInit this.location.go('apps/mail/' + folderHandle + '/' + mailId); } - // Set selected mail - this.mailService.setSelectedMail(mailId); + // Set current mail + 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 406c341c..7961a215 100644 --- a/src/app/main/apps/mail/mail.component.html +++ b/src/app/main/apps/mail/mail.component.html @@ -42,7 +42,41 @@
- Content toolbar + + + + + + + + + + + + + + + + + + + + + + + + + +
@@ -51,9 +85,9 @@
- + - +
diff --git a/src/app/main/apps/mail/mail.component.ts b/src/app/main/apps/mail/mail.component.ts index 82649721..80388904 100644 --- a/src/app/main/apps/mail/mail.component.ts +++ b/src/app/main/apps/mail/mail.component.ts @@ -1,15 +1,20 @@ -import { Component, OnInit } from '@angular/core'; -import { Mail } from './mail.model'; +import { Component, OnDestroy, OnInit } from '@angular/core'; import { MailService } from './mail.service'; +import { Subscription } from 'rxjs/Subscription'; @Component({ selector : 'fuse-mail', templateUrl: './mail.component.html', styleUrls : ['./mail.component.scss'] }) -export class MailComponent implements OnInit +export class MailComponent implements OnInit, OnDestroy { - selectedMail: Mail; + hasSelectedMails: boolean; + isIndeterminate: boolean; + folders: any[]; + labels: any[]; + + onSelectedMailsChanged: Subscription; constructor( private mailService: MailService @@ -20,11 +25,48 @@ export class MailComponent implements OnInit ngOnInit() { - this.selectedMail = this.mailService.selectedMail; + // Get the values for the first time + this.labels = this.mailService.labels; + this.folders = this.mailService.folders; - this.mailService.onSelectedMailUpdated - .subscribe(selectedMail => { - this.selectedMail = selectedMail; - }); + this.onSelectedMailsChanged = + this.mailService.onSelectedMailsChanged + .subscribe(selectedMails => { + + setTimeout(() => { + this.hasSelectedMails = selectedMails.length > 0; + this.isIndeterminate = (selectedMails.length !== this.mailService.mails.length && selectedMails.length > 0); + }, 0); + }); + } + + ngOnDestroy() + { + this.onSelectedMailsChanged.unsubscribe(); + } + + toggleSelectAll() + { + this.mailService.toggleSelectAll(); + } + + selectMails(filterParameter?, filterValue?) + { + this.mailService.selectMails(filterParameter, filterValue); + } + + deselectMails() + { + this.mailService.deselectMails(); + } + + toggleLabelOnSelectedMails(labelId) + { + this.mailService.toggleLabelOnSelectedMails(labelId); + } + + 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 b61e420f..42ff6cf5 100644 --- a/src/app/main/apps/mail/mail.model.ts +++ b/src/app/main/apps/mail/mail.model.ts @@ -25,7 +25,7 @@ export class Mail size: string }[]; labels: string[]; - folders: string[]; + folder: string; constructor(mail) { @@ -41,7 +41,7 @@ export class Mail this.hasAttachments = mail.hasAttachments; this.attachments = mail.attachments; this.labels = mail.labels; - this.folders = mail.folders; + this.folder = mail.folder; } toggleStar() diff --git a/src/app/main/apps/mail/mail.module.ts b/src/app/main/apps/mail/mail.module.ts index 88f486d5..48276a58 100644 --- a/src/app/main/apps/mail/mail.module.ts +++ b/src/app/main/apps/mail/mail.module.ts @@ -23,6 +23,20 @@ const routes: Routes = [ mail: MailService } }, + { + path : 'filter/:filterHandle', + component: MailComponent, + resolve : { + mail: MailService + } + }, + { + path : 'filter/:filterHandle/:mailId', + component: MailComponent, + resolve : { + mail: MailService + } + }, { path : ':folderHandle', component: MailComponent, diff --git a/src/app/main/apps/mail/mail.service.ts b/src/app/main/apps/mail/mail.service.ts index b9a718d2..a415c03d 100644 --- a/src/app/main/apps/mail/mail.service.ts +++ b/src/app/main/apps/mail/mail.service.ts @@ -9,24 +9,35 @@ import { Subject } from 'rxjs/Subject'; export class MailService implements Resolve { mails: Mail[]; - selectedMail: Mail; - labels: any[]; - folders: any[]; + selectedMails: Mail[]; + currentMail: Mail; + folders: any[]; + filters: any[]; + labels: any[]; routeParams: any; - onMailsUpdated = new Subject(); - onSelectedMailUpdated = new Subject(); - onLabelsUpdated = new Subject(); - onFoldersUpdated = new Subject(); + onMailsChanged = new Subject(); + onSelectedMailsChanged = new Subject(); + onCurrentMailChanged = new Subject(); + + onFoldersChanged = new Subject(); + onFiltersChanged = new Subject(); + onLabelsChanged = new Subject(); constructor( private http: Http ) { - + this.selectedMails = []; } + /** + * Resolve + * @param {ActivatedRouteSnapshot} route + * @param {RouterStateSnapshot} state + * @returns {Observable | Promise | any} + */ resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | Promise | any { this.routeParams = route.params; @@ -34,17 +45,18 @@ export class MailService implements Resolve return new Promise((resolve, reject) => { Promise.all([ this.getFolders(), + this.getFilters(), this.getLabels(), this.getMails() ]).then( () => { if ( this.routeParams.mailId ) { - this.setSelectedMail(this.routeParams.mailId); + this.setCurrentMail(this.routeParams.mailId); } else { - this.setSelectedMail(null); + this.setCurrentMail(null); } resolve(); @@ -54,30 +66,58 @@ export class MailService implements Resolve }); } + /** + * Get all folders + * @returns {Promise} + */ getFolders(): Promise { return new Promise((resolve, reject) => { this.http.get('api/mail-folders') .subscribe(response => { this.folders = response.json().data; - this.onFoldersUpdated.next(this.folders); + this.onFoldersChanged.next(this.folders); resolve(this.folders); }, reject); }); } + /** + * Get all filters + * @returns {Promise} + */ + getFilters(): Promise + { + return new Promise((resolve, reject) => { + this.http.get('api/mail-filters') + .subscribe(response => { + this.filters = response.json().data; + this.onFiltersChanged.next(this.filters); + resolve(this.filters); + }, reject); + }); + } + + /** + * Get all labels + * @returns {Promise} + */ getLabels(): Promise { return new Promise((resolve, reject) => { this.http.get('api/mail-labels') .subscribe(response => { this.labels = response.json().data; - this.onLabelsUpdated.next(this.labels); + this.onLabelsChanged.next(this.labels); resolve(this.labels); }, reject); }); } + /** + * Get all mails + * @returns {Promise} + */ getMails(): Promise { if ( this.routeParams.labelHandle ) @@ -85,52 +125,73 @@ export class MailService implements Resolve return this.getMailsByLabel(this.routeParams.labelHandle); } + if ( this.routeParams.filterHandle ) + { + return this.getMailsByFilter(this.routeParams.filterHandle); + } + return this.getMailsByFolder(this.routeParams.folderHandle); } + /** + * Get mails by folder + * @param handle + * @returns {Promise} + */ getMailsByFolder(handle): Promise { return new Promise((resolve, reject) => { - if ( handle === 'starred' || handle === 'important' ) - { - this.http.get('api/mail-mails?' + handle + '=true') - .subscribe(mails => { + this.http.get('api/mail-folders?handle=' + handle) + .subscribe(folders => { - this.mails = mails.json().data.map(mail => { - return new Mail(mail); - }); + const folderId = folders.json().data[0].id; - this.onMailsUpdated.next(this.mails); + this.http.get('api/mail-mails?folder=' + folderId) + .subscribe(mails => { - resolve(this.mails); + this.mails = mails.json().data.map(mail => { + return new Mail(mail); + }); - }, reject); - } - else - { - this.http.get('api/mail-folders?handle=' + handle) - .subscribe(folders => { + this.onMailsChanged.next(this.mails); - const folderId = folders.json().data[0].id; + resolve(this.mails); - this.http.get('api/mail-mails?folders=' + folderId) - .subscribe(mails => { - - this.mails = mails.json().data.map(mail => { - return new Mail(mail); - }); - - this.onMailsUpdated.next(this.mails); - - resolve(this.mails); - - }, reject); - }); - } + }, reject); + }); }); } + /** + * Get mails by filter + * @param handle + * @returns {Promise} + */ + getMailsByFilter(handle): Promise + { + return new Promise((resolve, reject) => { + + this.http.get('api/mail-mails?' + handle + '=true') + .subscribe(mails => { + + this.mails = mails.json().data.map(mail => { + return new Mail(mail); + }); + + this.onMailsChanged.next(this.mails); + + resolve(this.mails); + + }, reject); + }); + } + + /** + * Get mails by label + * @param handle + * @returns {Promise} + */ getMailsByLabel(handle): Promise { return new Promise((resolve, reject) => { @@ -146,7 +207,7 @@ export class MailService implements Resolve return new Mail(mail); }); - this.onMailsUpdated.next(this.mails); + this.onMailsChanged.next(this.mails); resolve(this.mails); @@ -155,42 +216,167 @@ export class MailService implements Resolve }); } - getMailById(id): Promise + /** + * Toggle selected mail by id + * @param id + */ + toggleSelectedMail(id) { - return new Promise((resolve, reject) => { - this.http.get('api/mail-mails/' + id) - .subscribe(mail => { - resolve(mail.json().data); - }, reject); - }); + // First, check if we already have that mail as selected... + if ( this.selectedMails.length > 0 ) + { + for ( const mail of this.selectedMails ) + { + // ...delete the selected mail + if ( mail.id === id ) + { + const index = this.selectedMails.indexOf(mail); + + if ( index !== -1 ) + { + this.selectedMails.splice(index, 1); + + // Trigger the next event + this.onSelectedMailsChanged.next(this.selectedMails); + + // Return + return; + } + } + } + } + + // If we don't have it, push as selected + this.selectedMails.push( + this.mails.find(mail => { + return mail.id === id; + }) + ); + + // Trigger the next event + this.onSelectedMailsChanged.next(this.selectedMails); } - setSelectedMail(id) + /** + * Toggle select all + */ + toggleSelectAll() { - this.selectedMail = this.mails.find(mail => { + if ( this.selectedMails.length > 0 ) + { + this.deselectMails(); + } + else + { + this.selectMails(); + } + + } + + selectMails(filterParameter?, filterValue?) + { + this.selectedMails = []; + + // If there is no filter, select all mails + if ( filterParameter === undefined || filterValue === undefined ) + { + this.selectedMails = this.mails; + } + else + { + this.selectedMails.push(... + this.mails.filter(mail => { + return mail[filterParameter] === filterValue; + }) + ); + } + + // Trigger the next event + this.onSelectedMailsChanged.next(this.selectedMails); + } + + deselectMails() + { + this.selectedMails = []; + + // Trigger the next event + this.onSelectedMailsChanged.next(this.selectedMails); + } + + /** + * Set current mail by id + * @param id + */ + setCurrentMail(id) + { + this.currentMail = this.mails.find(mail => { return mail.id === id; }); - this.onSelectedMailUpdated.next(this.selectedMail); + this.onCurrentMailChanged.next(this.currentMail); } - update(mail) + /** + * Toggle label on selected mails + * @param labelId + */ + toggleLabelOnSelectedMails(labelId) + { + this.selectedMails.map(mail => { + + const index = mail.labels.indexOf(labelId); + + if ( index !== -1 ) + { + mail.labels.splice(index, 1); + } + else + { + mail.labels.push(labelId); + } + + this.updateMail(mail); + }); + } + + /** + * Set folder on selected mails + * @param folderId + */ + setFolderOnSelectedMails(folderId) + { + this.selectedMails.map(mail => { + mail.folder = folderId; + + this.updateMail(mail); + }); + + this.deselectMails(); + } + + /** + * Update the mail + * @param mail + * @returns {Promise} + */ + updateMail(mail) { return new Promise((resolve, reject) => { - this.http.post('api/mail-mails/' + mail.id, {...mail}).subscribe(response => { + this.http.post('api/mail-mails/' + mail.id, {...mail}) + .subscribe(response => { - this.getMails().then(mails => { + this.getMails().then(mails => { - if ( mails && this.selectedMail ) - { - this.setSelectedMail(this.selectedMail.id); - } + if ( mails && this.currentMail ) + { + this.setCurrentMail(this.currentMail.id); + } - resolve(mails); + resolve(mails); - }, reject); - }); + }, reject); + }); }); } diff --git a/src/app/main/apps/mail/sidenavs/main/main-sidenav.component.html b/src/app/main/apps/mail/sidenavs/main/main-sidenav.component.html index b252e44d..09102a6f 100644 --- a/src/app/main/apps/mail/sidenavs/main/main-sidenav.component.html +++ b/src/app/main/apps/mail/sidenavs/main/main-sidenav.component.html @@ -26,19 +26,28 @@ -