mirror of
https://github.com/richard-loafle/fuse-angular.git
synced 2025-01-10 04:25:08 +00:00
mail..
This commit is contained in:
parent
b9569a5ba8
commit
b0e4f87a8a
|
@ -3,10 +3,10 @@ import { Pipe, PipeTransform } from '@angular/core';
|
||||||
@Pipe({name: 'getById'})
|
@Pipe({name: 'getById'})
|
||||||
export class GetByIdPipe implements PipeTransform
|
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 => {
|
const foundItem = value.find(item => {
|
||||||
if ( item.id )
|
if ( item.id !== undefined )
|
||||||
{
|
{
|
||||||
return item.id === id;
|
return item.id === id;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,21 +3,18 @@ import { NgModule } from '@angular/core';
|
||||||
import { KeysPipe } from './keys.pipe';
|
import { KeysPipe } from './keys.pipe';
|
||||||
import { GetByIdPipe } from './getById.pipe';
|
import { GetByIdPipe } from './getById.pipe';
|
||||||
import { HtmlToPlaintextPipe } from './htmlToPlaintext.pipe';
|
import { HtmlToPlaintextPipe } from './htmlToPlaintext.pipe';
|
||||||
import { SearchPipe } from './search.pipe';
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
KeysPipe,
|
KeysPipe,
|
||||||
GetByIdPipe,
|
GetByIdPipe,
|
||||||
HtmlToPlaintextPipe,
|
HtmlToPlaintextPipe
|
||||||
SearchPipe
|
|
||||||
],
|
],
|
||||||
imports : [],
|
imports : [],
|
||||||
exports : [
|
exports : [
|
||||||
KeysPipe,
|
KeysPipe,
|
||||||
GetByIdPipe,
|
GetByIdPipe,
|
||||||
HtmlToPlaintextPipe,
|
HtmlToPlaintextPipe
|
||||||
SearchPipe
|
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
import {InMemoryDbService} from 'angular-in-memory-web-api';
|
import { InMemoryDbService } from 'angular-in-memory-web-api';
|
||||||
import {MailFakeDb} from './mail';
|
import { MailFakeDb } from './mail';
|
||||||
|
|
||||||
export class FuseFakeDbService implements InMemoryDbService
|
export class FuseFakeDbService implements InMemoryDbService
|
||||||
{
|
{
|
||||||
createDb()
|
createDb()
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
'mail-mails' : MailFakeDb.mails,
|
'mail-mails' : MailFakeDb.mails,
|
||||||
'mail-folders': MailFakeDb.folders,
|
'mail-folders': MailFakeDb.folders,
|
||||||
|
'mail-filters': MailFakeDb.filters,
|
||||||
'mail-labels' : MailFakeDb.labels
|
'mail-labels' : MailFakeDb.labels
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,11 +47,7 @@ export class MailFakeDb
|
||||||
'labels' : [
|
'labels' : [
|
||||||
1
|
1
|
||||||
],
|
],
|
||||||
'folders' : [
|
'folder' : 0
|
||||||
0,
|
|
||||||
1,
|
|
||||||
2
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'id' : '154588a0864d2881124',
|
'id' : '154588a0864d2881124',
|
||||||
|
@ -74,11 +70,7 @@ export class MailFakeDb
|
||||||
'important' : false,
|
'important' : false,
|
||||||
'hasAttachments': false,
|
'hasAttachments': false,
|
||||||
'labels' : [],
|
'labels' : [],
|
||||||
'folders' : [
|
'folder' : 0
|
||||||
0,
|
|
||||||
1,
|
|
||||||
2
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'id' : '15453ba60d3baa5daaf',
|
'id' : '15453ba60d3baa5daaf',
|
||||||
|
@ -104,11 +96,7 @@ export class MailFakeDb
|
||||||
3,
|
3,
|
||||||
2
|
2
|
||||||
],
|
],
|
||||||
'folders' : [
|
'folder' : 0
|
||||||
0,
|
|
||||||
1,
|
|
||||||
2
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'id' : '15453a06c08fb021776',
|
'id' : '15453a06c08fb021776',
|
||||||
|
@ -134,11 +122,7 @@ export class MailFakeDb
|
||||||
3,
|
3,
|
||||||
4
|
4
|
||||||
],
|
],
|
||||||
'folders' : [
|
'folder' : 0
|
||||||
0,
|
|
||||||
1,
|
|
||||||
2
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'id' : '154537435d5b32bf11a',
|
'id' : '154537435d5b32bf11a',
|
||||||
|
@ -161,11 +145,7 @@ export class MailFakeDb
|
||||||
'important' : false,
|
'important' : false,
|
||||||
'hasAttachments': false,
|
'hasAttachments': false,
|
||||||
'labels' : [],
|
'labels' : [],
|
||||||
'folders' : [
|
'folder' : 0
|
||||||
0,
|
|
||||||
1,
|
|
||||||
2
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'id' : '1544e43dcdae6ebf876',
|
'id' : '1544e43dcdae6ebf876',
|
||||||
|
@ -190,11 +170,7 @@ export class MailFakeDb
|
||||||
'labels' : [
|
'labels' : [
|
||||||
2
|
2
|
||||||
],
|
],
|
||||||
'folders' : [
|
'folder' : 0
|
||||||
0,
|
|
||||||
1,
|
|
||||||
2
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'id' : '1543ee3a5b43e0f9f45',
|
'id' : '1543ee3a5b43e0f9f45',
|
||||||
|
@ -217,11 +193,7 @@ export class MailFakeDb
|
||||||
'important' : false,
|
'important' : false,
|
||||||
'hasAttachments': false,
|
'hasAttachments': false,
|
||||||
'labels' : [],
|
'labels' : [],
|
||||||
'folders' : [
|
'folder' : 0
|
||||||
0,
|
|
||||||
1,
|
|
||||||
2
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'id' : '1543cc4515df3146112',
|
'id' : '1543cc4515df3146112',
|
||||||
|
@ -244,11 +216,7 @@ export class MailFakeDb
|
||||||
'important' : false,
|
'important' : false,
|
||||||
'hasAttachments': false,
|
'hasAttachments': false,
|
||||||
'labels' : [],
|
'labels' : [],
|
||||||
'folders' : [
|
'folder' : 0
|
||||||
0,
|
|
||||||
1,
|
|
||||||
2
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'id' : '154398a4770d7aaf9a2',
|
'id' : '154398a4770d7aaf9a2',
|
||||||
|
@ -271,11 +239,7 @@ export class MailFakeDb
|
||||||
'important' : false,
|
'important' : false,
|
||||||
'hasAttachments': false,
|
'hasAttachments': false,
|
||||||
'labels' : [],
|
'labels' : [],
|
||||||
'folders' : [
|
'folder' : 0
|
||||||
0,
|
|
||||||
1,
|
|
||||||
2
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'id' : '15438351f87dcd68567',
|
'id' : '15438351f87dcd68567',
|
||||||
|
@ -298,11 +262,7 @@ export class MailFakeDb
|
||||||
'important' : false,
|
'important' : false,
|
||||||
'hasAttachments': false,
|
'hasAttachments': false,
|
||||||
'labels' : [],
|
'labels' : [],
|
||||||
'folders' : [
|
'folder' : 0
|
||||||
0,
|
|
||||||
1,
|
|
||||||
2
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'id' : '1542d75d929a603125',
|
'id' : '1542d75d929a603125',
|
||||||
|
@ -325,11 +285,7 @@ export class MailFakeDb
|
||||||
'important' : false,
|
'important' : false,
|
||||||
'hasAttachments': false,
|
'hasAttachments': false,
|
||||||
'labels' : [],
|
'labels' : [],
|
||||||
'folders' : [
|
'folder' : 0
|
||||||
0,
|
|
||||||
1,
|
|
||||||
2
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'id' : '1541ca7af66da284177',
|
'id' : '1541ca7af66da284177',
|
||||||
|
@ -352,11 +308,7 @@ export class MailFakeDb
|
||||||
'important' : false,
|
'important' : false,
|
||||||
'hasAttachments': false,
|
'hasAttachments': false,
|
||||||
'labels' : [],
|
'labels' : [],
|
||||||
'folders' : [
|
'folder' : 0
|
||||||
0,
|
|
||||||
1,
|
|
||||||
2
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'id' : '154297167e781781745',
|
'id' : '154297167e781781745',
|
||||||
|
@ -379,11 +331,7 @@ export class MailFakeDb
|
||||||
'important' : false,
|
'important' : false,
|
||||||
'hasAttachments': false,
|
'hasAttachments': false,
|
||||||
'labels' : [],
|
'labels' : [],
|
||||||
'folders' : [
|
'folder' : 0
|
||||||
0,
|
|
||||||
1,
|
|
||||||
2
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'id' : '15427f4c1b7f3953234',
|
'id' : '15427f4c1b7f3953234',
|
||||||
|
@ -406,9 +354,7 @@ export class MailFakeDb
|
||||||
'important' : false,
|
'important' : false,
|
||||||
'hasAttachments': false,
|
'hasAttachments': false,
|
||||||
'labels' : [],
|
'labels' : [],
|
||||||
'folders' : [
|
'folder' : 3
|
||||||
3
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'id' : '154204e45a59b168453',
|
'id' : '154204e45a59b168453',
|
||||||
|
@ -431,9 +377,7 @@ export class MailFakeDb
|
||||||
'important' : false,
|
'important' : false,
|
||||||
'hasAttachments': false,
|
'hasAttachments': false,
|
||||||
'labels' : [],
|
'labels' : [],
|
||||||
'folders' : [
|
'folder' : 3
|
||||||
3
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'id' : '1541dd1e05dfc439216',
|
'id' : '1541dd1e05dfc439216',
|
||||||
|
@ -456,9 +400,7 @@ export class MailFakeDb
|
||||||
'important' : false,
|
'important' : false,
|
||||||
'hasAttachments': false,
|
'hasAttachments': false,
|
||||||
'labels' : [],
|
'labels' : [],
|
||||||
'folders' : [
|
'folder' : 3
|
||||||
3
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -492,15 +434,18 @@ export class MailFakeDb
|
||||||
'handle': 'trash',
|
'handle': 'trash',
|
||||||
'title' : 'Trash',
|
'title' : 'Trash',
|
||||||
'icon' : 'delete'
|
'icon' : 'delete'
|
||||||
},
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
public static filters = [
|
||||||
{
|
{
|
||||||
'id' : 5,
|
'id' : 0,
|
||||||
'handle': 'starred',
|
'handle': 'starred',
|
||||||
'title' : 'Starred',
|
'title' : 'Starred',
|
||||||
'icon' : 'star'
|
'icon' : 'star'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'id' : 6,
|
'id' : 1,
|
||||||
'handle': 'important',
|
'handle': 'important',
|
||||||
'title' : 'Important',
|
'title' : 'Important',
|
||||||
'icon' : 'label'
|
'icon' : 'label'
|
||||||
|
|
|
@ -60,16 +60,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a class="toggle-details"
|
<a class="toggle-details" (click)="showDetails = !showDetails">
|
||||||
*ngIf="!showDetails"
|
<span *ngIf="!showDetails">Show Details</span>
|
||||||
(click)="showDetails = !showDetails">
|
<span *ngIf="showDetails">Hide Details</span>
|
||||||
Show Details
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a class="toggle-details"
|
|
||||||
*ngIf="showDetails"
|
|
||||||
(click)="showDetails = !showDetails">
|
|
||||||
Hide Details
|
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<div *ngIf="showDetails" class="details" fxLayout="row" fxLayoutAlign="start start">
|
<div *ngIf="showDetails" class="details" fxLayout="row" fxLayoutAlign="start start">
|
||||||
|
@ -88,16 +81,13 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button md-button
|
<button md-button [mdMenuTriggerFor]="moreMenu" aria-label="More" class="mat-icon-button"
|
||||||
[mdMenuTriggerFor]="moreMenu"
|
|
||||||
aria-label="More" class="mat-icon-button"
|
|
||||||
ng-click="$mdOpenMenu($event)">
|
ng-click="$mdOpenMenu($event)">
|
||||||
<md-icon>more_vert</md-icon>
|
<md-icon>more_vert</md-icon>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<md-menu #moreMenu="mdMenu">
|
<md-menu #moreMenu="mdMenu">
|
||||||
<button md-menu-item aria-label="Reply"
|
<button md-menu-item aria-label="Reply">
|
||||||
ng-click="vm.replyDialog($event)">
|
|
||||||
<md-icon>reply</md-icon>
|
<md-icon>reply</md-icon>
|
||||||
<span>Reply</span>
|
<span>Reply</span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -125,7 +115,7 @@
|
||||||
({{mail.attachments.length}})
|
({{mail.attachments.length}})
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="attachment-list" layout-wrap fxLayout="row">
|
<div class="attachment-list" fxLayout="row" fxLayoutWrap>
|
||||||
|
|
||||||
<div class="attachment" fxLayout="column"
|
<div class="attachment" fxLayout="column"
|
||||||
*ngFor="let attachment of mail.attachments">
|
*ngFor="let attachment of mail.attachments">
|
||||||
|
@ -133,8 +123,8 @@
|
||||||
<img class="preview" src="{{attachment.preview}}">
|
<img class="preview" src="{{attachment.preview}}">
|
||||||
|
|
||||||
<div fxLayout="column">
|
<div fxLayout="column">
|
||||||
<a href="#" class="md-accent-color link" onclick="event.preventDefault()">View</a>
|
<a href="#" onclick="event.preventDefault()">View</a>
|
||||||
<a href="#" class="md-accent-color link" onclick="event.preventDefault()">Download</a>
|
<a href="#" onclick="event.preventDefault()">Download</a>
|
||||||
<div class="size">({{attachment.size}})</div>
|
<div class="size">({{attachment.size}})</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.toggle-details {
|
.toggle-details {
|
||||||
|
user-select: none;
|
||||||
|
text-decoration: underline;
|
||||||
padding-top: 16px;
|
padding-top: 16px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
|
|
@ -1,28 +1,43 @@
|
||||||
import { Component, Input, OnInit } from '@angular/core';
|
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { Mail } from '../mail.model';
|
|
||||||
import { MailService } from '../mail.service';
|
import { MailService } from '../mail.service';
|
||||||
|
import { Mail } from '../mail.model';
|
||||||
|
import { Subscription } from 'rxjs/Subscription';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-mail-details',
|
selector : 'fuse-mail-details',
|
||||||
templateUrl: './mail-details.component.html',
|
templateUrl: './mail-details.component.html',
|
||||||
styleUrls : ['./mail-details.component.scss']
|
styleUrls : ['./mail-details.component.scss']
|
||||||
})
|
})
|
||||||
export class MailDetailsComponent implements OnInit
|
export class MailDetailsComponent implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
@Input('selectedMail') public mail: Mail;
|
mail: Mail;
|
||||||
showDetails: boolean;
|
|
||||||
labels: any[];
|
labels: any[];
|
||||||
|
showDetails = false;
|
||||||
|
|
||||||
|
onCurrentMailChanged: Subscription;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private mailService: MailService
|
private mailService: MailService
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
this.showDetails = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit()
|
ngOnInit()
|
||||||
{
|
{
|
||||||
|
// Set initial values
|
||||||
this.labels = this.mailService.labels;
|
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)
|
toggleStar(event)
|
||||||
|
@ -31,7 +46,7 @@ export class MailDetailsComponent implements OnInit
|
||||||
|
|
||||||
this.mail.toggleStar();
|
this.mail.toggleStar();
|
||||||
|
|
||||||
this.mailService.update(this.mail);
|
this.mailService.updateMail(this.mail);
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleImportant(event)
|
toggleImportant(event)
|
||||||
|
@ -40,7 +55,7 @@ export class MailDetailsComponent implements OnInit
|
||||||
|
|
||||||
this.mail.toggleImportant();
|
this.mail.toggleImportant();
|
||||||
|
|
||||||
this.mailService.update(this.mail);
|
this.mailService.updateMail(this.mail);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div fxLayout="row" fxLayoutAlign="start center">
|
<div fxLayout="row" fxLayoutAlign="start center">
|
||||||
|
|
||||||
<md-checkbox></md-checkbox>
|
<md-checkbox [(ngModel)]="selected" (ngModelChange)="onSelectedChange()" (click)="$event.stopPropagation();"></md-checkbox>
|
||||||
|
|
||||||
<div class="info" fxFlex FlexLayout="column">
|
<div class="info" fxFlex FlexLayout="column">
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.selected-mail {
|
&.current-mail {
|
||||||
background: #E3F2FD;
|
background: #E3F2FD;
|
||||||
|
|
||||||
.info {
|
.info {
|
||||||
|
|
|
@ -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 { Mail } from '../../mail.model';
|
||||||
import { MailService } from '../../mail.service';
|
import { MailService } from '../../mail.service';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { Subscription } from 'rxjs/Subscription';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-mail-list-item',
|
selector : 'fuse-mail-list-item',
|
||||||
templateUrl: './mail-list-item.component.html',
|
templateUrl: './mail-list-item.component.html',
|
||||||
styleUrls : ['./mail-list-item.component.scss']
|
styleUrls : ['./mail-list-item.component.scss']
|
||||||
})
|
})
|
||||||
export class MailListItemComponent implements OnInit
|
export class MailListItemComponent implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
@Input() mail: Mail;
|
@Input() mail: Mail;
|
||||||
labels: any[];
|
labels: any[];
|
||||||
|
selected: boolean;
|
||||||
|
|
||||||
|
onSelectedMailsChanged: Subscription;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private route: ActivatedRoute,
|
|
||||||
private mailService: MailService
|
private mailService: MailService
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -23,25 +25,75 @@ export class MailListItemComponent implements OnInit
|
||||||
|
|
||||||
ngOnInit()
|
ngOnInit()
|
||||||
{
|
{
|
||||||
|
// Set the initial values
|
||||||
this.mail = new Mail(this.mail);
|
this.mail = new Mail(this.mail);
|
||||||
this.labels = this.mailService.labels;
|
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)
|
toggleStar(event)
|
||||||
{
|
{
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
this.mail.toggleStar();
|
this.mail.toggleStar();
|
||||||
|
|
||||||
this.mailService.update(this.mail);
|
this.mailService.updateMail(this.mail);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle Important
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
toggleImportant(event)
|
toggleImportant(event)
|
||||||
{
|
{
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
this.mail.toggleImportant();
|
this.mail.toggleImportant();
|
||||||
|
|
||||||
this.mailService.update(this.mail);
|
this.mailService.updateMail(this.mail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,15 +2,6 @@
|
||||||
<span class="hint-text">There are no messages!</span>
|
<span class="hint-text">There are no messages!</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input type="text" [(ngModel)]="search">
|
<fuse-mail-list-item md-ripple *ngFor="let mail of mails" [mail]="mail" (click)="readMail(mail.id)"
|
||||||
|
[ngClass]="{'current-mail':mail?.id == currentMail?.id}">
|
||||||
{{search}}
|
|
||||||
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
<fuse-mail-list-item *ngFor="let mail of mails | filter:search" [mail]="mail" md-ripple (click)="selectMail(mail.id)"
|
|
||||||
[ngClass]="{'selected-mail':mail?.id === selectedMail?.id}">
|
|
||||||
</fuse-mail-list-item>
|
</fuse-mail-list-item>
|
||||||
|
|
|
@ -1,21 +1,22 @@
|
||||||
import { Component, Input, OnInit } from '@angular/core';
|
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { Mail } from '../mail.model';
|
import { Mail } from '../mail.model';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { MailService } from '../mail.service';
|
import { MailService } from '../mail.service';
|
||||||
import { Location } from '@angular/common';
|
import { Location } from '@angular/common';
|
||||||
|
import { Subscription } from 'rxjs/Subscription';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-mail-list',
|
selector : 'fuse-mail-list',
|
||||||
templateUrl: './mail-list.component.html',
|
templateUrl: './mail-list.component.html',
|
||||||
styleUrls : ['./mail-list.component.scss']
|
styleUrls : ['./mail-list.component.scss']
|
||||||
})
|
})
|
||||||
export class MailListComponent implements OnInit
|
export class MailListComponent implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
mails: Mail[];
|
mails: Mail[];
|
||||||
|
currentMail: Mail;
|
||||||
|
|
||||||
@Input('selectedMail') public selectedMail: Mail;
|
onMailsChanged: Subscription;
|
||||||
|
onCurrentMailChanged: Subscription;
|
||||||
search: string;
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
|
@ -30,32 +31,56 @@ export class MailListComponent implements OnInit
|
||||||
// Get mails for the first time
|
// Get mails for the first time
|
||||||
this.mails = this.mailService.mails;
|
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
|
// Subscribe to update mails on changes
|
||||||
this.mailService.onMailsUpdated
|
this.onMailsChanged =
|
||||||
.subscribe(mails => {
|
this.mailService.onMailsChanged
|
||||||
this.mails = mails;
|
.subscribe(mails => {
|
||||||
});
|
this.mails = mails;
|
||||||
|
});
|
||||||
|
|
||||||
this.mailService.onSelectedMailUpdated
|
// Subscribe to update current mail on changes
|
||||||
.subscribe(selectedMail => {
|
this.onCurrentMailChanged =
|
||||||
if ( !selectedMail )
|
this.mailService.onCurrentMailChanged
|
||||||
{
|
.subscribe(currentMail => {
|
||||||
const labelHandle = this.route.snapshot.params.labelHandle,
|
if ( !currentMail )
|
||||||
folderHandle = this.route.snapshot.params.folderHandle;
|
|
||||||
|
|
||||||
if ( labelHandle )
|
|
||||||
{
|
{
|
||||||
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
|
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,
|
const labelHandle = this.route.snapshot.params.labelHandle,
|
||||||
folderHandle = this.route.snapshot.params.folderHandle;
|
folderHandle = this.route.snapshot.params.folderHandle;
|
||||||
|
@ -69,8 +94,8 @@ export class MailListComponent implements OnInit
|
||||||
this.location.go('apps/mail/' + folderHandle + '/' + mailId);
|
this.location.go('apps/mail/' + folderHandle + '/' + mailId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set selected mail
|
// Set current mail
|
||||||
this.mailService.setSelectedMail(mailId);
|
this.mailService.setCurrentMail(mailId);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,41 @@
|
||||||
<!-- CONTENT TOOLBAR -->
|
<!-- CONTENT TOOLBAR -->
|
||||||
<div class="toolbar">
|
<div class="toolbar">
|
||||||
|
|
||||||
<span>Content toolbar</span>
|
<md-checkbox (click)="toggleSelectAll()" [checked]="hasSelectedMails"
|
||||||
|
[indeterminate]="isIndeterminate"></md-checkbox>
|
||||||
|
|
||||||
|
<button md-icon-button [mdMenuTriggerFor]="selectMenu">
|
||||||
|
<md-icon>arrow_drop_down</md-icon>
|
||||||
|
</button>
|
||||||
|
<md-menu #selectMenu="mdMenu">
|
||||||
|
<button md-menu-item (click)="selectMails()">All</button>
|
||||||
|
<button md-menu-item (click)="deselectMails()">None</button>
|
||||||
|
<button md-menu-item (click)="selectMails('read', true)">Read</button>
|
||||||
|
<button md-menu-item (click)="selectMails('read', false)">Unread</button>
|
||||||
|
<button md-menu-item (click)="selectMails('starred', true)">Starred</button>
|
||||||
|
<button md-menu-item (click)="selectMails('starred', false)">Unstarred</button>
|
||||||
|
<button md-menu-item (click)="selectMails('important', true)">Important</button>
|
||||||
|
<button md-menu-item (click)="selectMails('important', false)">Unimportant</button>
|
||||||
|
</md-menu>
|
||||||
|
|
||||||
|
<button md-icon-button (click)="setFolderOnSelectedMails(4)" *ngIf="hasSelectedMails">
|
||||||
|
<md-icon>delete</md-icon>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button md-icon-button [mdMenuTriggerFor]="folderMenu" *ngIf="hasSelectedMails">
|
||||||
|
<md-icon>folder</md-icon>
|
||||||
|
</button>
|
||||||
|
<md-menu #folderMenu="mdMenu">
|
||||||
|
<button md-menu-item *ngFor="let folder of folders" (click)="setFolderOnSelectedMails(folder.id)">{{folder.title}}</button>
|
||||||
|
</md-menu>
|
||||||
|
|
||||||
|
<button md-icon-button [mdMenuTriggerFor]="labelMenu" *ngIf="hasSelectedMails">
|
||||||
|
<md-icon>label</md-icon>
|
||||||
|
</button>
|
||||||
|
<md-menu #labelMenu="mdMenu">
|
||||||
|
<button md-menu-item *ngFor="let label of labels" (click)="toggleLabelOnSelectedMails(label.id)">{{label.title}}</button>
|
||||||
|
</md-menu>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<!-- / CONTENT TOOLBAR -->
|
<!-- / CONTENT TOOLBAR -->
|
||||||
|
|
||||||
|
@ -51,9 +85,9 @@
|
||||||
|
|
||||||
<div fxLayout="row" fxFill>
|
<div fxLayout="row" fxFill>
|
||||||
|
|
||||||
<fuse-mail-list fxFlex [selectedMail]="selectedMail" perfect-scrollbar></fuse-mail-list>
|
<fuse-mail-list fxFlex perfect-scrollbar></fuse-mail-list>
|
||||||
|
|
||||||
<fuse-mail-details fxFlex [selectedMail]="selectedMail" perfect-scrollbar></fuse-mail-details>
|
<fuse-mail-details fxFlex perfect-scrollbar></fuse-mail-details>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,20 @@
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { Mail } from './mail.model';
|
|
||||||
import { MailService } from './mail.service';
|
import { MailService } from './mail.service';
|
||||||
|
import { Subscription } from 'rxjs/Subscription';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-mail',
|
selector : 'fuse-mail',
|
||||||
templateUrl: './mail.component.html',
|
templateUrl: './mail.component.html',
|
||||||
styleUrls : ['./mail.component.scss']
|
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(
|
constructor(
|
||||||
private mailService: MailService
|
private mailService: MailService
|
||||||
|
@ -20,11 +25,48 @@ export class MailComponent implements OnInit
|
||||||
|
|
||||||
ngOnInit()
|
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
|
this.onSelectedMailsChanged =
|
||||||
.subscribe(selectedMail => {
|
this.mailService.onSelectedMailsChanged
|
||||||
this.selectedMail = selectedMail;
|
.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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ export class Mail
|
||||||
size: string
|
size: string
|
||||||
}[];
|
}[];
|
||||||
labels: string[];
|
labels: string[];
|
||||||
folders: string[];
|
folder: string;
|
||||||
|
|
||||||
constructor(mail)
|
constructor(mail)
|
||||||
{
|
{
|
||||||
|
@ -41,7 +41,7 @@ export class Mail
|
||||||
this.hasAttachments = mail.hasAttachments;
|
this.hasAttachments = mail.hasAttachments;
|
||||||
this.attachments = mail.attachments;
|
this.attachments = mail.attachments;
|
||||||
this.labels = mail.labels;
|
this.labels = mail.labels;
|
||||||
this.folders = mail.folders;
|
this.folder = mail.folder;
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleStar()
|
toggleStar()
|
||||||
|
|
|
@ -23,6 +23,20 @@ const routes: Routes = [
|
||||||
mail: MailService
|
mail: MailService
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path : 'filter/:filterHandle',
|
||||||
|
component: MailComponent,
|
||||||
|
resolve : {
|
||||||
|
mail: MailService
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path : 'filter/:filterHandle/:mailId',
|
||||||
|
component: MailComponent,
|
||||||
|
resolve : {
|
||||||
|
mail: MailService
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path : ':folderHandle',
|
path : ':folderHandle',
|
||||||
component: MailComponent,
|
component: MailComponent,
|
||||||
|
|
|
@ -9,24 +9,35 @@ import { Subject } from 'rxjs/Subject';
|
||||||
export class MailService implements Resolve<any>
|
export class MailService implements Resolve<any>
|
||||||
{
|
{
|
||||||
mails: Mail[];
|
mails: Mail[];
|
||||||
selectedMail: Mail;
|
selectedMails: Mail[];
|
||||||
labels: any[];
|
currentMail: Mail;
|
||||||
folders: any[];
|
|
||||||
|
|
||||||
|
folders: any[];
|
||||||
|
filters: any[];
|
||||||
|
labels: any[];
|
||||||
routeParams: any;
|
routeParams: any;
|
||||||
|
|
||||||
onMailsUpdated = new Subject<Mail[]>();
|
onMailsChanged = new Subject<Mail[]>();
|
||||||
onSelectedMailUpdated = new Subject<Mail>();
|
onSelectedMailsChanged = new Subject<Mail[]>();
|
||||||
onLabelsUpdated = new Subject<any[]>();
|
onCurrentMailChanged = new Subject<Mail>();
|
||||||
onFoldersUpdated = new Subject<any[]>();
|
|
||||||
|
onFoldersChanged = new Subject<any[]>();
|
||||||
|
onFiltersChanged = new Subject<any[]>();
|
||||||
|
onLabelsChanged = new Subject<any[]>();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private http: Http
|
private http: Http
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
this.selectedMails = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve
|
||||||
|
* @param {ActivatedRouteSnapshot} route
|
||||||
|
* @param {RouterStateSnapshot} state
|
||||||
|
* @returns {Observable<any> | Promise<any> | any}
|
||||||
|
*/
|
||||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> | any
|
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> | any
|
||||||
{
|
{
|
||||||
this.routeParams = route.params;
|
this.routeParams = route.params;
|
||||||
|
@ -34,17 +45,18 @@ export class MailService implements Resolve<any>
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
Promise.all([
|
Promise.all([
|
||||||
this.getFolders(),
|
this.getFolders(),
|
||||||
|
this.getFilters(),
|
||||||
this.getLabels(),
|
this.getLabels(),
|
||||||
this.getMails()
|
this.getMails()
|
||||||
]).then(
|
]).then(
|
||||||
() => {
|
() => {
|
||||||
if ( this.routeParams.mailId )
|
if ( this.routeParams.mailId )
|
||||||
{
|
{
|
||||||
this.setSelectedMail(this.routeParams.mailId);
|
this.setCurrentMail(this.routeParams.mailId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.setSelectedMail(null);
|
this.setCurrentMail(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
resolve();
|
resolve();
|
||||||
|
@ -54,30 +66,58 @@ export class MailService implements Resolve<any>
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all folders
|
||||||
|
* @returns {Promise<any>}
|
||||||
|
*/
|
||||||
getFolders(): Promise<any>
|
getFolders(): Promise<any>
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.http.get('api/mail-folders')
|
this.http.get('api/mail-folders')
|
||||||
.subscribe(response => {
|
.subscribe(response => {
|
||||||
this.folders = response.json().data;
|
this.folders = response.json().data;
|
||||||
this.onFoldersUpdated.next(this.folders);
|
this.onFoldersChanged.next(this.folders);
|
||||||
resolve(this.folders);
|
resolve(this.folders);
|
||||||
}, reject);
|
}, reject);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all filters
|
||||||
|
* @returns {Promise<any>}
|
||||||
|
*/
|
||||||
|
getFilters(): Promise<any>
|
||||||
|
{
|
||||||
|
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<any>}
|
||||||
|
*/
|
||||||
getLabels(): Promise<any>
|
getLabels(): Promise<any>
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.http.get('api/mail-labels')
|
this.http.get('api/mail-labels')
|
||||||
.subscribe(response => {
|
.subscribe(response => {
|
||||||
this.labels = response.json().data;
|
this.labels = response.json().data;
|
||||||
this.onLabelsUpdated.next(this.labels);
|
this.onLabelsChanged.next(this.labels);
|
||||||
resolve(this.labels);
|
resolve(this.labels);
|
||||||
}, reject);
|
}, reject);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all mails
|
||||||
|
* @returns {Promise<Mail[]>}
|
||||||
|
*/
|
||||||
getMails(): Promise<Mail[]>
|
getMails(): Promise<Mail[]>
|
||||||
{
|
{
|
||||||
if ( this.routeParams.labelHandle )
|
if ( this.routeParams.labelHandle )
|
||||||
|
@ -85,52 +125,73 @@ export class MailService implements Resolve<any>
|
||||||
return this.getMailsByLabel(this.routeParams.labelHandle);
|
return this.getMailsByLabel(this.routeParams.labelHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( this.routeParams.filterHandle )
|
||||||
|
{
|
||||||
|
return this.getMailsByFilter(this.routeParams.filterHandle);
|
||||||
|
}
|
||||||
|
|
||||||
return this.getMailsByFolder(this.routeParams.folderHandle);
|
return this.getMailsByFolder(this.routeParams.folderHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get mails by folder
|
||||||
|
* @param handle
|
||||||
|
* @returns {Promise<Mail[]>}
|
||||||
|
*/
|
||||||
getMailsByFolder(handle): Promise<Mail[]>
|
getMailsByFolder(handle): Promise<Mail[]>
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
if ( handle === 'starred' || handle === 'important' )
|
this.http.get('api/mail-folders?handle=' + handle)
|
||||||
{
|
.subscribe(folders => {
|
||||||
this.http.get('api/mail-mails?' + handle + '=true')
|
|
||||||
.subscribe(mails => {
|
|
||||||
|
|
||||||
this.mails = mails.json().data.map(mail => {
|
const folderId = folders.json().data[0].id;
|
||||||
return new Mail(mail);
|
|
||||||
});
|
|
||||||
|
|
||||||
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);
|
this.onMailsChanged.next(this.mails);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.http.get('api/mail-folders?handle=' + handle)
|
|
||||||
.subscribe(folders => {
|
|
||||||
|
|
||||||
const folderId = folders.json().data[0].id;
|
resolve(this.mails);
|
||||||
|
|
||||||
this.http.get('api/mail-mails?folders=' + folderId)
|
}, reject);
|
||||||
.subscribe(mails => {
|
});
|
||||||
|
|
||||||
this.mails = mails.json().data.map(mail => {
|
|
||||||
return new Mail(mail);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.onMailsUpdated.next(this.mails);
|
|
||||||
|
|
||||||
resolve(this.mails);
|
|
||||||
|
|
||||||
}, reject);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get mails by filter
|
||||||
|
* @param handle
|
||||||
|
* @returns {Promise<Mail[]>}
|
||||||
|
*/
|
||||||
|
getMailsByFilter(handle): Promise<Mail[]>
|
||||||
|
{
|
||||||
|
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<Mail[]>}
|
||||||
|
*/
|
||||||
getMailsByLabel(handle): Promise<Mail[]>
|
getMailsByLabel(handle): Promise<Mail[]>
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
@ -146,7 +207,7 @@ export class MailService implements Resolve<any>
|
||||||
return new Mail(mail);
|
return new Mail(mail);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.onMailsUpdated.next(this.mails);
|
this.onMailsChanged.next(this.mails);
|
||||||
|
|
||||||
resolve(this.mails);
|
resolve(this.mails);
|
||||||
|
|
||||||
|
@ -155,42 +216,167 @@ export class MailService implements Resolve<any>
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getMailById(id): Promise<Mail>
|
/**
|
||||||
|
* Toggle selected mail by id
|
||||||
|
* @param id
|
||||||
|
*/
|
||||||
|
toggleSelectedMail(id)
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) => {
|
// First, check if we already have that mail as selected...
|
||||||
this.http.get('api/mail-mails/' + id)
|
if ( this.selectedMails.length > 0 )
|
||||||
.subscribe(mail => {
|
{
|
||||||
resolve(mail.json().data);
|
for ( const mail of this.selectedMails )
|
||||||
}, reject);
|
{
|
||||||
});
|
// ...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;
|
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<any>}
|
||||||
|
*/
|
||||||
|
updateMail(mail)
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) => {
|
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 )
|
if ( mails && this.currentMail )
|
||||||
{
|
{
|
||||||
this.setSelectedMail(this.selectedMail.id);
|
this.setCurrentMail(this.currentMail.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
resolve(mails);
|
resolve(mails);
|
||||||
|
|
||||||
}, reject);
|
}, reject);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,19 +26,28 @@
|
||||||
|
|
||||||
<div class="nav-subheader">FOLDERS</div>
|
<div class="nav-subheader">FOLDERS</div>
|
||||||
|
|
||||||
<div class="nav-item" *ngFor="let item of folders">
|
<div class="nav-item" *ngFor="let folder of folders">
|
||||||
<a class="nav-link" md-ripple [routerLink]="'/apps/mail/' + item.handle" routerLinkActive="active">
|
<a class="nav-link" md-ripple [routerLink]="'/apps/mail/' + folder.handle" routerLinkActive="active">
|
||||||
<md-icon class="nav-link-icon" *ngIf="item.icon">{{item.icon}}</md-icon>
|
<md-icon class="nav-link-icon" *ngIf="folder.icon">{{folder.icon}}</md-icon>
|
||||||
<span>{{item.title}}</span>
|
<span>{{folder.title}}</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="nav-subheader">FILTERS</div>
|
||||||
|
|
||||||
|
<div class="nav-item" *ngFor="let filter of filters">
|
||||||
|
<a class="nav-link" md-ripple [routerLink]="'/apps/mail/filter/' + filter.handle" routerLinkActive="active">
|
||||||
|
<md-icon class="nav-link-icon" *ngIf="filter.icon">{{filter.icon}}</md-icon>
|
||||||
|
<span>{{filter.title}}</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="nav-subheader">LABELS</div>
|
<div class="nav-subheader">LABELS</div>
|
||||||
|
|
||||||
<div class="nav-item" *ngFor="let item of labels">
|
<div class="nav-item" *ngFor="let label of labels">
|
||||||
<a class="nav-link" md-ripple [routerLink]="'/apps/mail/label/' + item.handle" routerLinkActive="active">
|
<a class="nav-link" md-ripple [routerLink]="'/apps/mail/label/' + label.handle" routerLinkActive="active">
|
||||||
<md-icon class="nav-link-icon" [ngStyle]="{'color':item.color}">label</md-icon>
|
<md-icon class="nav-link-icon" [ngStyle]="{'color':label.color}">label</md-icon>
|
||||||
<span>{{item.title}}</span>
|
<span>{{label.title}}</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,9 @@ import { MailService } from '../../mail.service';
|
||||||
})
|
})
|
||||||
export class MainSidenavComponent implements OnInit
|
export class MainSidenavComponent implements OnInit
|
||||||
{
|
{
|
||||||
labels: any[];
|
|
||||||
folders: any[];
|
folders: any[];
|
||||||
|
filters: any[];
|
||||||
|
labels: any[];
|
||||||
accounts: object;
|
accounts: object;
|
||||||
selectedAccount: string;
|
selectedAccount: string;
|
||||||
|
|
||||||
|
@ -28,15 +29,20 @@ export class MainSidenavComponent implements OnInit
|
||||||
|
|
||||||
ngOnInit()
|
ngOnInit()
|
||||||
{
|
{
|
||||||
this.labels = this.mailService.labels;
|
|
||||||
this.folders = this.mailService.folders;
|
this.folders = this.mailService.folders;
|
||||||
|
this.filters = this.mailService.filters;
|
||||||
|
this.labels = this.mailService.labels;
|
||||||
|
|
||||||
this.mailService.onLabelsUpdated.subscribe(labels => {
|
this.mailService.onFoldersChanged.subscribe(folders => {
|
||||||
this.labels = this.mailService.labels;
|
this.folders = this.mailService.folders;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.mailService.onFoldersUpdated.subscribe(folders => {
|
this.mailService.onFiltersChanged.subscribe(folders => {
|
||||||
this.folders = this.mailService.folders;
|
this.filters = this.mailService.filters;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.mailService.onLabelsChanged.subscribe(labels => {
|
||||||
|
this.labels = this.mailService.labels;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
"label-position": true,
|
"label-position": true,
|
||||||
"max-line-length": [
|
"max-line-length": [
|
||||||
true,
|
true,
|
||||||
120
|
180
|
||||||
],
|
],
|
||||||
"member-access": false,
|
"member-access": false,
|
||||||
"member-ordering": [
|
"member-ordering": [
|
||||||
|
|
Loading…
Reference in New Issue
Block a user