This commit is contained in:
Sercan Yemen 2017-07-18 19:34:12 +03:00
parent 29bb2198d3
commit c3cb5c8942
15 changed files with 385 additions and 183 deletions

View File

@ -5,7 +5,6 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import 'hammerjs'; import 'hammerjs';
import { MailModule } from './main/apps/mail/mail.module';
import { ChatModule } from './main/apps/chat/chat.module'; import { ChatModule } from './main/apps/chat/chat.module';
import { ProjectModule } from './main/apps/dashboards/project/project.module'; import { ProjectModule } from './main/apps/dashboards/project/project.module';
import { FuseLayoutService } from './core/services/layout.service'; import { FuseLayoutService } from './core/services/layout.service';
@ -18,10 +17,6 @@ import { FuseMdSidenavHelperService } from './core/directives/md-sidenav-helper/
import { UIPageLayoutsModule } from './main/ui/page-layouts/page-layouts.module'; import { UIPageLayoutsModule } from './main/ui/page-layouts/page-layouts.module';
import { FuseLayoutModule } from './core/components/layout/layout.module'; import { FuseLayoutModule } from './core/components/layout/layout.module';
import { PerfectScrollbarConfigInterface, PerfectScrollbarModule } from 'ngx-perfect-scrollbar'; import { PerfectScrollbarConfigInterface, PerfectScrollbarModule } from 'ngx-perfect-scrollbar';
import { environment } from 'environments/environment';
import { MailListComponent } from './main/apps/mail/mail-list/mail-list.component';
import { MailDetailsComponent } from './main/apps/mail/mail-details/mail-details.component';
import { MailDataService } from './main/apps/mail/mail-data.service';
import { HttpModule } from '@angular/http'; import { HttpModule } from '@angular/http';
import { InMemoryWebApiModule } from 'angular-in-memory-web-api'; import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
import { FuseFakeDbService } from './fuse-fake-db/fuse-fake-db.service'; import { FuseFakeDbService } from './fuse-fake-db/fuse-fake-db.service';
@ -54,7 +49,7 @@ const appRoutes: Routes = [
SharedModule, SharedModule,
RouterModule.forRoot(appRoutes), RouterModule.forRoot(appRoutes),
InMemoryWebApiModule.forRoot(FuseFakeDbService, { delay: 500 }), InMemoryWebApiModule.forRoot(FuseFakeDbService, {delay: 125}),
PerfectScrollbarModule.forRoot(PERFECT_SCROLLBAR_CONFIG), PerfectScrollbarModule.forRoot(PERFECT_SCROLLBAR_CONFIG),
@ -67,7 +62,6 @@ const appRoutes: Routes = [
UIPageLayoutsModule UIPageLayoutsModule
], ],
providers : [ providers : [
MailDataService,
FuseNavigationService, FuseNavigationService,
FuseLayoutService, FuseLayoutService,
FuseMatchMedia, FuseMatchMedia,

View File

@ -1,43 +0,0 @@
import { Injectable } from '@angular/core';
import {ActivatedRouteSnapshot, Resolve, Route, RouterStateSnapshot} from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Http } from '@angular/http';
@Injectable()
export class MailDataService implements Resolve<any>
{
constructor(
private http: Http
)
{
}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> | any
{
console.log(route.params);
console.log(route.paramMap.get('labelHandle'));
// route.params.subscribe(params => {
// });
return new Promise((resolve, reject) =>
{
console.log('resolve...');
this.http.get('api/mail-mails').subscribe(response =>
{
console.info(response);
resolve(response);
}, reject);
});
}
getMailsByFolder(handle)
{
}
saveMailSubject(subject)
{
}
}

View File

@ -13,14 +13,12 @@
</div> </div>
<div class="actions" fxLayout="row" fxLayoutAlign="start center"> <div class="actions" fxLayout="row" fxLayoutAlign="start center">
<button md-button class="mat-icon-button" ng-click="vm.togglemailStatus('starred')" <button md-button class="mat-icon-button" (click)="toggleStar($event)" aria-label="Toggle star">
aria-label="Toggle starred">
<md-icon *ngIf="mail.starred">star</md-icon> <md-icon *ngIf="mail.starred">star</md-icon>
<md-icon *ngIf="!mail.starred">star_outline</md-icon> <md-icon *ngIf="!mail.starred">star_outline</md-icon>
</button> </button>
<button md-button class="mat-icon-button" ng-click="vm.togglemailStatus('important')" <button md-button class="mat-icon-button" (click)="toggleImportant($event)" aria-label="Toggle important">
aria-label="Toggle important">
<md-icon *ngIf="mail.important">label</md-icon> <md-icon *ngIf="mail.important">label</md-icon>
<md-icon *ngIf="!mail.important">label_outline</md-icon> <md-icon *ngIf="!mail.important">label_outline</md-icon>
</button> </button>
@ -118,7 +116,8 @@
<div *ngIf="mail.attachments" class="mail-attachments"> <div *ngIf="mail.attachments" class="mail-attachments">
<div class="title"> <div class="title">
<span>Attachments</span> ({{mail.attachments.length}}) <span>Attachments</span>
({{mail.attachments.length}})
</div> </div>
<div class="attachment-list" layout-wrap fxLayout="row"> <div class="attachment-list" layout-wrap fxLayout="row">

View File

@ -1,5 +1,7 @@
import { Component, Input, OnInit } from '@angular/core'; import { Component, Input, OnInit } from '@angular/core';
import {MailModel} from '../mail.model'; import { Mail } from '../mail.model';
import { MailService } from '../mail.service';
import { ActivatedRoute } from '@angular/router';
@Component({ @Component({
selector : 'fuse-mail-details', selector : 'fuse-mail-details',
@ -8,16 +10,38 @@ import {MailModel} from '../mail.model';
}) })
export class MailDetailsComponent implements OnInit export class MailDetailsComponent implements OnInit
{ {
@Input('selectedMail') public mail: MailModel; @Input('selectedMail') public mail: Mail;
showDetails: boolean; showDetails: boolean;
constructor() constructor(
private route: ActivatedRoute,
private mailService: MailService
)
{ {
this.showDetails = false; this.showDetails = false;
} }
ngOnInit() ngOnInit()
{ {
}
toggleStar(event)
{
event.stopPropagation();
this.mail.toggleStar();
this.mailService.update(this.mail);
}
toggleImportant(event)
{
event.stopPropagation();
this.mail.toggleImportant();
this.mailService.update(this.mail);
} }
} }

View File

@ -35,16 +35,12 @@
<div class="time">{{mail.time}}</div> <div class="time">{{mail.time}}</div>
<div class="actions" fxLayout="row" fxLayoutAlign="start center"> <div class="actions" fxLayout="row" fxLayoutAlign="start center">
<button md-button class="mat-icon-button" <button md-button class="mat-icon-button" (click)="toggleStar($event)" aria-label="Toggle star">
ng-click="vm.togglemailStatus('starred', mail, $event)"
aria-label="Toggle starred">
<md-icon *ngIf="mail.starred">star</md-icon> <md-icon *ngIf="mail.starred">star</md-icon>
<md-icon *ngIf="!mail.starred">star_outline</md-icon> <md-icon *ngIf="!mail.starred">star_outline</md-icon>
</button> </button>
<button md-button class="mat-icon-button" <button md-button class="mat-icon-button" (click)="toggleImportant($event)" aria-label="Toggle important">
ng-click="vm.togglemailStatus('important', mail, $event)"
aria-label="Toggle important">
<md-icon *ngIf="mail.important">label</md-icon> <md-icon *ngIf="mail.important">label</md-icon>
<md-icon *ngIf="!mail.important">label_outline</md-icon> <md-icon *ngIf="!mail.important">label_outline</md-icon>
</button> </button>

View File

@ -1,5 +1,7 @@
import { Component, Input, OnInit } from '@angular/core'; import { Component, Input, OnInit } from '@angular/core';
import { MailModel } from '../../mail.model'; import { Mail } from '../../mail.model';
import { MailService } from '../../mail.service';
import { ActivatedRoute, ActivatedRouteSnapshot } from '@angular/router';
@Component({ @Component({
selector : 'fuse-mail-list-item', selector : 'fuse-mail-list-item',
@ -8,14 +10,36 @@ import { MailModel } from '../../mail.model';
}) })
export class MailListItemComponent implements OnInit export class MailListItemComponent implements OnInit
{ {
@Input() mail: MailModel; @Input() mail: Mail;
constructor() constructor(
private route: ActivatedRoute,
private mailService: MailService
)
{ {
} }
ngOnInit() ngOnInit()
{ {
this.mail = new Mail(this.mail);
} }
toggleStar(event)
{
event.stopPropagation();
this.mail.toggleStar();
this.mailService.update(this.mail);
}
toggleImportant(event)
{
event.stopPropagation();
this.mail.toggleImportant();
this.mailService.update(this.mail);
}
} }

View File

@ -1,15 +1,3 @@
<fuse-mail-list-item *ngFor="let mail of mails" [mail]="mail" md-ripple (click)="selectMail(mail.id)"
<button md-button (click)="onSave()">Save</button> [ngClass]="{'selected-mail':mail?.id === selectedMail?.id}">
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<fuse-mail-list-item *ngFor="let mail of mails" [mail]="mail" md-ripple (click)="selectMail(mail)"
[ngClass]="{'selected-mail':mail === selectedMail}">
</fuse-mail-list-item> </fuse-mail-list-item>

View File

@ -1,8 +1,7 @@
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; import { Component, Input, OnInit } from '@angular/core';
import {MailModel} from '../mail.model'; import { Mail } from '../mail.model';
import {MailDataService} from '../mail-data.service'; import { ActivatedRoute, Router } from '@angular/router';
import {Http} from '@angular/http'; import { MailService } from '../mail.service';
import {ActivatedRoute} from '@angular/router';
@Component({ @Component({
selector : 'fuse-mail-list', selector : 'fuse-mail-list',
@ -11,62 +10,44 @@ import {ActivatedRoute} from '@angular/router';
}) })
export class MailListComponent implements OnInit export class MailListComponent implements OnInit
{ {
mails: MailModel[]; mails: Mail[];
@Input('selectedMail') public selectedMail: MailModel; @Input('selectedMail') public selectedMail: Mail;
@Output() onMailSelect = new EventEmitter<MailModel>();
constructor(private mailDataService: MailDataService, constructor(
private http: Http, private route: ActivatedRoute,
private route: ActivatedRoute) private router: Router,
private mailService: MailService
)
{ {
route.data.subscribe(response =>
{
console.info(response.mailDB.json());
this.mails = response.mailDB.json().data;
});
} }
ngOnInit() ngOnInit()
{ {
// Get mails for the first time
this.mails = this.mailService.mails;
// Subscribe to update mails on changes
} this.mailService.onMailsUpdated
.subscribe(mails => {
onSave() console.log('mailsUpdated');
{ this.mails = mails;
/*this.http.get('api/mails?important=true&labels=1').subscribe(response =>
{
console.log(response);
});*/
this.http.get('api/mail-mails').subscribe(response =>
{
console.log(response.json());
}); });
/*this.http.get('api/mail/folders/0').subscribe(response =>
{
console.log(response);
});*/
/*this.http.post('api/mails', {id: '2', subject: 'Test test'}).subscribe(response =>
{
console.log(response);
this.http.get('api/mails/2').subscribe(response2 =>
{
console.log(response2);
});
});*/
} }
selectMail(mail) selectMail(mailId)
{ {
this.selectedMail = mail; const labelHandle = this.route.snapshot.params.labelHandle,
this.onMailSelect.emit(mail); folderHandle = this.route.snapshot.params.folderHandle;
if ( labelHandle )
{
this.router.navigate(['apps/mail/label', labelHandle, mailId]);
}
else
{
this.router.navigate(['apps/mail', folderHandle, mailId]);
}
} }
} }

View File

@ -51,7 +51,7 @@
<div fxLayout="row" fxFill> <div fxLayout="row" fxFill>
<fuse-mail-list fxFlex [selectedMail]="selectedMail" (onMailSelect)="onMailSelect($event)"></fuse-mail-list> <fuse-mail-list fxFlex [selectedMail]="selectedMail"></fuse-mail-list>
<fuse-mail-details fxFlex [selectedMail]="selectedMail"></fuse-mail-details> <fuse-mail-details fxFlex [selectedMail]="selectedMail"></fuse-mail-details>

View File

@ -1,7 +1,6 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router'; import { Mail } from './mail.model';
import { MailModel } from './mail.model'; import { MailService } from './mail.service';
import { MailDataService } from './mail-data.service';
@Component({ @Component({
selector : 'fuse-mail', selector : 'fuse-mail',
@ -10,23 +9,22 @@ import { MailDataService } from './mail-data.service';
}) })
export class MailComponent implements OnInit export class MailComponent implements OnInit
{ {
selectedMail: MailModel; selectedMail: Mail;
constructor( constructor(
private route: ActivatedRoute, private mailService: MailService
private mailDataService: MailDataService
) )
{ {
console.log('mail component inited');
} }
ngOnInit() ngOnInit()
{ {
this.selectedMail = this.mailService.selectedMail;
} this.mailService.onSelectedMailUpdated
.subscribe(selectedMail => {
onMailSelect(mail) this.selectedMail = selectedMail;
{ });
this.selectedMail = mail;
} }
} }

View File

@ -1,7 +1,6 @@
export class MailModel export class Mail
{ {
id: string; id: string;
subject: string;
from: { from: {
name: string, name: string,
avatar: string, avatar: string,
@ -11,26 +10,47 @@ export class MailModel
name: string, name: string,
email: string email: string
}[]; }[];
subject: string;
message: string; message: string;
time: string; time: string;
read: boolean; read: boolean;
starred: boolean; starred: boolean;
important: boolean; important: boolean;
hasAttachments: boolean; hasAttachments: boolean;
attachments: [ attachments: {
{
type: string, type: string,
fileName: string, fileName: string,
preview: string, preview: string,
url: string, url: string,
size: string size: string
} }[];
];
labels: string[]; labels: string[];
folders: any[]; folders: string[];
constructor() constructor(mail)
{ {
this.id = mail.id;
this.from = mail.from;
this.to = mail.to;
this.subject = mail.subject;
this.message = mail.message;
this.time = mail.time;
this.read = mail.read;
this.starred = mail.starred;
this.important = mail.important;
this.hasAttachments = mail.hasAttachments;
this.attachments = mail.attachments;
this.labels = mail.labels;
this.folders = mail.folders;
}
toggleStar()
{
this.starred = !this.starred;
}
toggleImportant()
{
this.important = !this.important;
} }
} }

View File

@ -6,37 +6,35 @@ import { MainSidenavComponent } from './sidenavs/main/main-sidenav.component';
import { MailListItemComponent } from './mail-list/mail-list-item/mail-list-item.component'; import { MailListItemComponent } from './mail-list/mail-list-item/mail-list-item.component';
import { MailListComponent } from './mail-list/mail-list.component'; import { MailListComponent } from './mail-list/mail-list.component';
import { MailDetailsComponent } from './mail-details/mail-details.component'; import { MailDetailsComponent } from './mail-details/mail-details.component';
import { InMemoryWebApiModule } from 'angular-in-memory-web-api'; import { MailService } from './mail.service';
import { HttpModule } from '@angular/http';
import {MailDataService} from './mail-data.service';
const routes: Routes = [ const routes: Routes = [
{ {
path : 'label/:labelHandle', path : 'label/:labelHandle',
component: MailComponent, component: MailComponent,
resolve : { resolve : {
mailDB: MailDataService mail: MailService
} }
}, },
{ {
path : 'label/:labelHandle/:mailId', path : 'label/:labelHandle/:mailId',
component: MailComponent, component: MailComponent,
resolve : { resolve : {
mailDB: MailDataService mail: MailService
} }
}, },
{ {
path : ':folderHandle', path : ':folderHandle',
component: MailComponent, component: MailComponent,
resolve : { resolve : {
mailDB: MailDataService mail: MailService
} }
}, },
{ {
path : ':folderHandle/:mailId', path : ':folderHandle/:mailId',
component: MailComponent, component: MailComponent,
resolve : { resolve : {
mailDB: MailDataService mail: MailService
} }
}, },
{ {
@ -55,11 +53,11 @@ const routes: Routes = [
], ],
imports : [ imports : [
SharedModule, SharedModule,
HttpModule, RouterModule.forChild(routes)
RouterModule.forChild(routes),
InMemoryWebApiModule
], ],
providers : [] providers : [
MailService
]
}) })
export class MailModule export class MailModule
{ {

View File

@ -0,0 +1,198 @@
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Http } from '@angular/http';
import { Mail } from './mail.model';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class MailService implements Resolve<any>
{
mails: Mail[];
selectedMail: Mail;
labels: any[];
folders: any[];
routeParams: any;
onMailsUpdated = new Subject<Mail[]>();
onSelectedMailUpdated = new Subject<Mail>();
onLabelsUpdated = new Subject<any[]>();
onFoldersUpdated = new Subject<any[]>();
constructor(
private http: Http
)
{
}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> | any
{
this.routeParams = route.params;
return new Promise((resolve, reject) => {
Promise.all([
this.getFolders(),
this.getLabels(),
this.getMails()
]).then(
() => {
if ( this.routeParams.mailId )
{
this.setSelectedMail(this.routeParams.mailId);
}
else
{
this.setSelectedMail(null);
}
resolve();
},
reject
);
});
}
getFolders(): Promise<any>
{
return new Promise((resolve, reject) => {
this.http.get('api/mail-folders')
.subscribe(response => {
this.folders = response.json().data;
this.onFoldersUpdated.next(this.folders);
resolve(this.folders);
}, reject);
});
}
getLabels(): Promise<any>
{
return new Promise((resolve, reject) => {
this.http.get('api/mail-labels')
.subscribe(response => {
this.labels = response.json().data;
this.onLabelsUpdated.next(this.labels);
resolve(this.labels);
}, reject);
});
}
getMails(): Promise<Mail[]>
{
if ( this.routeParams.labelHandle )
{
return this.getMailsByLabel(this.routeParams.labelHandle);
}
return this.getMailsByFolder(this.routeParams.folderHandle);
}
getMailsByFolder(handle): Promise<Mail[]>
{
return new Promise((resolve, reject) => {
if ( handle === 'starred' || handle === 'important' )
{
this.http.get('api/mail-mails?' + handle + '=true')
.subscribe(mails => {
this.mails = mails.json().data.map(mail => {
return new Mail(mail);
});
this.onMailsUpdated.next(this.mails);
resolve(this.mails);
}, reject);
}
else
{
this.http.get('api/mail-folders?handle=' + handle)
.subscribe(folders => {
const folderId = folders.json().data[0].id;
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);
});
}
});
}
getMailsByLabel(handle): Promise<Mail[]>
{
return new Promise((resolve, reject) => {
this.http.get('api/mail-labels?handle=' + handle)
.subscribe(labels => {
const labelId = labels.json().data[0].id;
this.http.get('api/mail-mails?labels=' + labelId)
.subscribe(mails => {
this.mails = mails.json().data.map(mail => {
return new Mail(mail);
});
this.onMailsUpdated.next(this.mails);
resolve(this.mails);
}, reject);
});
});
}
getMailById(id): Promise<Mail>
{
return new Promise((resolve, reject) => {
this.http.get('api/mail-mails/' + id)
.subscribe(mail => {
resolve(mail.json().data);
}, reject);
});
}
setSelectedMail(id)
{
this.selectedMail = this.mails.find(mail => {
return mail.id === id;
});
this.onSelectedMailUpdated.next(this.selectedMail);
}
update(mail)
{
return new Promise((resolve, reject) => {
this.http.post('api/mail-mails/' + mail.id, {...mail}).subscribe(response => {
console.log(response);
this.getMails().then(mails => {
if ( mails && this.selectedMail )
{
this.setSelectedMail(this.selectedMail.id);
}
resolve(mails);
}, reject);
});
});
}
}

View File

@ -22,12 +22,21 @@
<!-- SIDENAV CONTENT --> <!-- SIDENAV CONTENT -->
<div class="content" perfect-scrollbar> <div class="content" perfect-scrollbar>
<a routerLink="/apps/mail/inbox">Inbox</a> <md-list>
<a routerLink="/apps/mail/sent">Sent</a> <div md-subheader>FOLDERS</div>
<a routerLink="/apps/mail/drafts">Drafts</a> <md-list-item *ngFor="let folder of folders">
<a routerLink="/apps/mail/spam">Spam</a> <a md-line [routerLink]="'/apps/mail/' + folder.handle">
{{ folder.title }}
</a>
</md-list-item>
<a routerLink="/apps/mail/true">Spam</a> <div md-subheader>LABELS</div>
<md-list-item *ngFor="let label of labels">
<a md-line [routerLink]="'/apps/mail/label/' + label.handle">
{{ label.title }}
</a>
</md-list-item>
</md-list>
</div> </div>
<!-- / SIDENAV CONTENT --> <!-- / SIDENAV CONTENT -->

View File

@ -1,4 +1,5 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { MailService } from '../../mail.service';
@Component({ @Component({
selector : 'fuse-mail-main-sidenav', selector : 'fuse-mail-main-sidenav',
@ -7,20 +8,35 @@ import {Component, OnInit} from '@angular/core';
}) })
export class MainSidenavComponent implements OnInit export class MainSidenavComponent implements OnInit
{ {
labels: any[];
folders: any[];
accounts: object; accounts: object;
selectedAccount: string; selectedAccount: string;
constructor() constructor(
private mailService: MailService
)
{ {
// Data // Data
this.accounts = { this.accounts = {
'creapond' : 'johndoe@creapond.com', 'creapond' : 'johndoe@creapond.com',
'withinpixels': 'johndoe@withinpixels.com' 'withinpixels': 'johndoe@withinpixels.com'
}; };
this.selectedAccount = 'creapond'; this.selectedAccount = 'creapond';
} }
ngOnInit() ngOnInit()
{ {
this.labels = this.mailService.labels;
this.folders = this.mailService.folders;
this.mailService.onLabelsUpdated.subscribe(labels => {
this.labels = this.mailService.labels;
});
this.mailService.onFoldersUpdated.subscribe(folders => {
this.folders = this.mailService.folders;
});
} }
} }