This commit is contained in:
Sercan Yemen 2017-07-19 17:58:36 +03:00
parent 2e4d040139
commit b9569a5ba8
18 changed files with 203 additions and 70 deletions

View File

@ -3,16 +3,4 @@
#main-navigation { #main-navigation {
margin: 0; margin: 0;
padding: 0; padding: 0;
.nav-item {
.nav-link {
background-color: map-get($background, raised-button);
color: map_get($foreground, text);
&:hover {
background-color: map-get($background, hover);
}
}
}
} }

View File

@ -1,28 +1,28 @@
import {NgModule} from '@angular/core'; import { NgModule } from '@angular/core';
import {MaterialModule} from './material.module'; import { FormsModule } from '@angular/forms';
import {FlexLayoutModule} from '@angular/flex-layout'; import { CommonModule } from '@angular/common';
import {FormsModule} from '@angular/forms';
import {CommonModule} from '@angular/common'; import { MaterialModule } from './material.module';
import { FlexLayoutModule } from '@angular/flex-layout';
import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar';
import { import {
FuseMdSidenavHelperDirective, FuseMdSidenavHelperDirective,
FuseMdSidenavTogglerDirective FuseMdSidenavTogglerDirective
} from '../directives/md-sidenav-helper/md-sidenav-helper.directive'; } from '../directives/md-sidenav-helper/md-sidenav-helper.directive';
import {PerfectScrollbarModule} from 'ngx-perfect-scrollbar'; import { FusePipesModule } from '../pipes/pipes.module';
import {KeysPipe} from '../pipes/keys';
import {HtmlToPlaintextPipe} from '../pipes//htmlToPlaintext';
@NgModule({ @NgModule({
declarations: [ declarations: [
FuseMdSidenavHelperDirective, FuseMdSidenavHelperDirective,
FuseMdSidenavTogglerDirective, FuseMdSidenavTogglerDirective
KeysPipe,
HtmlToPlaintextPipe
], ],
imports : [ imports : [
FlexLayoutModule, FlexLayoutModule,
MaterialModule, MaterialModule,
CommonModule, CommonModule,
FormsModule, FormsModule,
FusePipesModule,
PerfectScrollbarModule PerfectScrollbarModule
], ],
exports : [ exports : [
@ -32,9 +32,8 @@ import {HtmlToPlaintextPipe} from '../pipes//htmlToPlaintext';
FormsModule, FormsModule,
FuseMdSidenavHelperDirective, FuseMdSidenavHelperDirective,
FuseMdSidenavTogglerDirective, FuseMdSidenavTogglerDirective,
PerfectScrollbarModule, FusePipesModule,
KeysPipe, PerfectScrollbarModule
HtmlToPlaintextPipe
] ]
}) })

View File

@ -0,0 +1,22 @@
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({name: 'getById'})
export class GetByIdPipe implements PipeTransform
{
transform(value: any[], id: number, property: string ): any
{
const foundItem = value.find(item => {
if ( item.id )
{
return item.id === id;
}
return false;
});
if ( foundItem )
{
return foundItem[property];
}
}
}

View File

@ -0,0 +1,23 @@
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({name: 'keys'})
export class KeysPipe implements PipeTransform
{
transform(value: any, args: string[]): any
{
const keys: any[] = [];
for ( const key in value )
{
if ( value.hasOwnProperty(key) )
{
keys.push({
key : key,
value: value[key]
});
}
}
return keys;
}
}

View File

@ -1,15 +0,0 @@
import {Pipe, PipeTransform} from '@angular/core';
@Pipe({name: 'keys'})
export class KeysPipe implements PipeTransform
{
transform(value: any, args: string[]): any
{
let keys: any[] = [];
for ( let key in value )
{
keys.push({key: key, value: value[key]});
}
return keys;
}
}

View File

@ -0,0 +1,27 @@
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
],
imports : [],
exports : [
KeysPipe,
GetByIdPipe,
HtmlToPlaintextPipe,
SearchPipe
]
})
export class FusePipesModule
{
}

View File

@ -0,0 +1,49 @@
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;
}
);
}
}

View File

@ -1,3 +1,8 @@
<div *ngIf="!mail" fxLayout="column" fxLayoutAlign="center center" fxFlex>
<md-icon>email</md-icon>
<span class="hint-text">Select a message to read</span>
</div>
<div *ngIf="mail"> <div *ngIf="mail">
<div class="mail-header" fxLayout="row" fxLayoutAlign="space-between center"> <div class="mail-header" fxLayout="row" fxLayoutAlign="space-between center">
@ -6,8 +11,8 @@
<div class="subject" flex>{{mail.subject}}</div> <div class="subject" flex>{{mail.subject}}</div>
<div class="labels"> <div class="labels">
<div class="label" *ngFor="let labelId of mail.labels"> <div class="label" *ngFor="let labelId of mail.labels"
{{labelId}} [ngStyle]="{background: labels | getById:labelId:'color'}">{{labels | getById:labelId:'title'}}
</div> </div>
</div> </div>
</div> </div>
@ -128,8 +133,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">View</a> <a href="#" class="md-accent-color link" onclick="event.preventDefault()">View</a>
<a href="#" class="md-accent-color link">Download</a> <a href="#" class="md-accent-color link" onclick="event.preventDefault()">Download</a>
<div class="size">({{attachment.size}})</div> <div class="size">({{attachment.size}})</div>
</div> </div>

View File

@ -1,6 +1,9 @@
@import 'src/app/core/scss/fuse'; @import 'src/app/core/scss/fuse';
:host { :host {
display: flex;
flex-direction: column;
flex: 1;
background: #FFFFFF; background: #FFFFFF;
padding: 24px; padding: 24px;
@ -10,12 +13,6 @@
.actions { .actions {
min-width: 88px; min-width: 88px;
.mat-icon-button {
padding: 0;
width: 32px;
height: 32px;
}
} }
.subject { .subject {

View File

@ -1,7 +1,6 @@
import { Component, Input, OnInit } from '@angular/core'; import { Component, Input, 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';
@Component({ @Component({
selector : 'fuse-mail-details', selector : 'fuse-mail-details',
@ -12,9 +11,9 @@ export class MailDetailsComponent implements OnInit
{ {
@Input('selectedMail') public mail: Mail; @Input('selectedMail') public mail: Mail;
showDetails: boolean; showDetails: boolean;
labels: any[];
constructor( constructor(
private route: ActivatedRoute,
private mailService: MailService private mailService: MailService
) )
{ {
@ -23,7 +22,7 @@ export class MailDetailsComponent implements OnInit
ngOnInit() ngOnInit()
{ {
this.labels = this.mailService.labels;
} }
toggleStar(event) toggleStar(event)

View File

@ -24,7 +24,9 @@
{{mail.message | htmlToPlaintext | slice:0:180}}{{mail.message.length > 180 ? '...' : ''}} {{mail.message | htmlToPlaintext | slice:0:180}}{{mail.message.length > 180 ? '...' : ''}}
<div class="labels"> <div class="labels">
<div class="label" *ngFor="let labelId of mail.labels">{{labelId}}</div> <div class="label" *ngFor="let labelId of mail.labels"
[ngStyle]="{background: labels | getById:labelId:'color'}">{{labels | getById:labelId:'title'}}
</div>
</div> </div>
</div> </div>

View File

@ -1,7 +1,7 @@
import { Component, Input, OnInit } from '@angular/core'; import { Component, Input, 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, ActivatedRouteSnapshot } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
@Component({ @Component({
selector : 'fuse-mail-list-item', selector : 'fuse-mail-list-item',
@ -11,6 +11,7 @@ import { ActivatedRoute, ActivatedRouteSnapshot } from '@angular/router';
export class MailListItemComponent implements OnInit export class MailListItemComponent implements OnInit
{ {
@Input() mail: Mail; @Input() mail: Mail;
labels: any[];
constructor( constructor(
private route: ActivatedRoute, private route: ActivatedRoute,
@ -23,6 +24,7 @@ export class MailListItemComponent implements OnInit
ngOnInit() ngOnInit()
{ {
this.mail = new Mail(this.mail); this.mail = new Mail(this.mail);
this.labels = this.mailService.labels;
} }
toggleStar(event) toggleStar(event)

View File

@ -1,3 +1,16 @@
<fuse-mail-list-item *ngFor="let mail of mails" [mail]="mail" md-ripple (click)="selectMail(mail.id)" <div *ngIf="mails.length === 0" fxLayout="column" fxLayoutAlign="center center" fxFlex>
<span class="hint-text">There are no messages!</span>
</div>
<input type="text" [(ngModel)]="search">
{{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}"> [ngClass]="{'selected-mail':mail?.id === selectedMail?.id}">
</fuse-mail-list-item> </fuse-mail-list-item>

View File

@ -1,7 +1,8 @@
import { Component, Input, OnInit } from '@angular/core'; import { Component, Input, OnInit } from '@angular/core';
import { Mail } from '../mail.model'; import { Mail } from '../mail.model';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { MailService } from '../mail.service'; import { MailService } from '../mail.service';
import { Location } from '@angular/common';
@Component({ @Component({
selector : 'fuse-mail-list', selector : 'fuse-mail-list',
@ -14,10 +15,12 @@ export class MailListComponent implements OnInit
@Input('selectedMail') public selectedMail: Mail; @Input('selectedMail') public selectedMail: Mail;
search: string;
constructor( constructor(
private route: ActivatedRoute, private route: ActivatedRoute,
private router: Router, private mailService: MailService,
private mailService: MailService private location: Location
) )
{ {
} }
@ -30,9 +33,26 @@ export class MailListComponent implements OnInit
// Subscribe to update mails on changes // Subscribe to update mails on changes
this.mailService.onMailsUpdated this.mailService.onMailsUpdated
.subscribe(mails => { .subscribe(mails => {
console.log('mailsUpdated');
this.mails = 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 )
{
this.location.go('apps/mail/label/' + labelHandle);
}
else
{
this.location.go('apps/mail/' + folderHandle);
}
}
});
} }
selectMail(mailId) selectMail(mailId)
@ -42,12 +62,15 @@ export class MailListComponent implements OnInit
if ( labelHandle ) if ( labelHandle )
{ {
this.router.navigate(['apps/mail/label', labelHandle, mailId]); this.location.go('apps/mail/label/' + labelHandle + '/' + mailId);
} }
else else
{ {
this.router.navigate(['apps/mail', folderHandle, mailId]); this.location.go('apps/mail/' + folderHandle + '/' + mailId);
} }
// Set selected mail
this.mailService.setSelectedMail(mailId);
} }
} }

View File

@ -47,13 +47,13 @@
<!-- / CONTENT TOOLBAR --> <!-- / CONTENT TOOLBAR -->
<!-- CONTENT --> <!-- CONTENT -->
<div class="content" perfect-scrollbar> <div class="content">
<div fxLayout="row" fxFill> <div fxLayout="row" fxFill>
<fuse-mail-list fxFlex [selectedMail]="selectedMail"></fuse-mail-list> <fuse-mail-list fxFlex [selectedMail]="selectedMail" perfect-scrollbar></fuse-mail-list>
<fuse-mail-details fxFlex [selectedMail]="selectedMail"></fuse-mail-details> <fuse-mail-details fxFlex [selectedMail]="selectedMail" perfect-scrollbar></fuse-mail-details>
</div> </div>

View File

@ -177,9 +177,8 @@ export class MailService implements Resolve<any>
update(mail) update(mail)
{ {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.http.post('api/mail-mails/' + mail.id, {...mail}).subscribe(response => {
console.log(response); this.http.post('api/mail-mails/' + mail.id, {...mail}).subscribe(response => {
this.getMails().then(mails => { this.getMails().then(mails => {

View File

@ -27,7 +27,7 @@
<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 item of folders">
<a class="nav-link" md-ripple [routerLink]="'/apps/mail/' + item.handle"> <a class="nav-link" md-ripple [routerLink]="'/apps/mail/' + item.handle" routerLinkActive="active">
<md-icon class="nav-link-icon" *ngIf="item.icon">{{item.icon}}</md-icon> <md-icon class="nav-link-icon" *ngIf="item.icon">{{item.icon}}</md-icon>
<span>{{item.title}}</span> <span>{{item.title}}</span>
</a> </a>
@ -36,7 +36,7 @@
<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 item of labels">
<a class="nav-link" md-ripple [routerLink]="'/apps/mail/label/' + item.handle"> <a class="nav-link" md-ripple [routerLink]="'/apps/mail/label/' + item.handle" routerLinkActive="active">
<md-icon class="nav-link-icon" [ngStyle]="{'color':item.color}">label</md-icon> <md-icon class="nav-link-icon" [ngStyle]="{'color':item.color}">label</md-icon>
<span>{{item.title}}</span> <span>{{item.title}}</span>
</a> </a>