mirror of
				https://github.com/richard-loafle/fuse-angular.git
				synced 2025-10-31 19:33:34 +00:00 
			
		
		
		
	Mail App: mail item, list style, selected mail..
This commit is contained in:
		
							parent
							
								
									c4f03469f9
								
							
						
					
					
						commit
						e33b16c727
					
				| @ -18,7 +18,7 @@ $card-header-height-sm: $header-height-sm - $card-toolbar-height; | |||||||
|         right: 0; |         right: 0; | ||||||
|         left: 0; |         left: 0; | ||||||
|         height: $header-height; |         height: $header-height; | ||||||
|         background-color: mat-color($mat-blue, 500); |         background-color: mat-color($accent); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Carded layout |     // Carded layout | ||||||
|  | |||||||
| @ -1,3 +1,140 @@ | |||||||
| <p> | <div *ngIf="mail"> | ||||||
|   mail-details works! | 
 | ||||||
| </p> |     <div class="mail-header" fxLayout="row" fxLayoutAlign="space-between center"> | ||||||
|  | 
 | ||||||
|  |         <div> | ||||||
|  |             <div class="subject" flex>{{mail.subject}}</div> | ||||||
|  | 
 | ||||||
|  |             <div class="labels"> | ||||||
|  |                 <div class="label" *ngFor="let labelId of mail.labels"> | ||||||
|  |                     {{labelId}} | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |         <div class="actions" fxLayout="row" fxLayoutAlign="start center"> | ||||||
|  |             <button md-button class="mat-icon-button" ng-click="vm.togglemailStatus('starred')" | ||||||
|  |                     aria-label="Toggle starred"> | ||||||
|  |                 <md-icon *ngIf="mail.starred">star</md-icon> | ||||||
|  |                 <md-icon *ngIf="!mail.starred">star_outline</md-icon> | ||||||
|  |             </button> | ||||||
|  | 
 | ||||||
|  |             <button md-button class="mat-icon-button" ng-click="vm.togglemailStatus('important')" | ||||||
|  |                     aria-label="Toggle important"> | ||||||
|  |                 <md-icon *ngIf="mail.important">label</md-icon> | ||||||
|  |                 <md-icon *ngIf="!mail.important">label_outline</md-icon> | ||||||
|  |             </button> | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |     <div class="mail-content"> | ||||||
|  | 
 | ||||||
|  |         <div class="info" fxLayout="row" fxLayoutAlign="space-between start"> | ||||||
|  | 
 | ||||||
|  |             <div fxFlex fxLayout="column" fxLayoutAlign="start start"> | ||||||
|  | 
 | ||||||
|  |                 <div fxLayout="row" fxLayoutAlign="start start"> | ||||||
|  | 
 | ||||||
|  |                     <div> | ||||||
|  |                         <img *ngIf="mail.from.avatar" alt="{{mail.from.name}}" | ||||||
|  |                              src="{{mail.from.avatar}}" class="avatar"/> | ||||||
|  | 
 | ||||||
|  |                         <div *ngIf="!mail.from.avatar" class="avatar" ms-random-class="vm.colors"> | ||||||
|  |                             {{mail.from.name[0]}} | ||||||
|  |                         </div> | ||||||
|  |                     </div> | ||||||
|  | 
 | ||||||
|  |                     <div fxLayout="column" fxLayoutAlign="start start"> | ||||||
|  | 
 | ||||||
|  |                         <div class="name"> | ||||||
|  |                             {{mail.from.name}} | ||||||
|  |                         </div> | ||||||
|  | 
 | ||||||
|  |                         <div class="to" fxLayout="row" fxLayoutAlign="start center"> | ||||||
|  |                             <div class="to-text">to</div> | ||||||
|  |                             <div>{{mail.to[0].name}}</div> | ||||||
|  |                         </div> | ||||||
|  |                     </div> | ||||||
|  |                 </div> | ||||||
|  | 
 | ||||||
|  |                 <a class="toggle-details" | ||||||
|  |                    *ngIf="!showDetails" | ||||||
|  |                    (click)="showDetails = !showDetails"> | ||||||
|  |                     Show Details | ||||||
|  |                 </a> | ||||||
|  | 
 | ||||||
|  |                 <a class="toggle-details" | ||||||
|  |                    *ngIf="showDetails" | ||||||
|  |                    (click)="showDetails = !showDetails"> | ||||||
|  |                     Hide Details | ||||||
|  |                 </a> | ||||||
|  | 
 | ||||||
|  |                 <div *ngIf="showDetails" class="details" fxLayout="row" fxLayoutAlign="start start"> | ||||||
|  | 
 | ||||||
|  |                     <div fxLayout="column"> | ||||||
|  |                         <span class="title">From:</span> | ||||||
|  |                         <span class="title">To:</span> | ||||||
|  |                         <span class="title">Date:</span> | ||||||
|  |                     </div> | ||||||
|  | 
 | ||||||
|  |                     <div fxLayout="column"> | ||||||
|  |                         <span class="detail">{{mail.from.email}}</span> | ||||||
|  |                         <span class="detail">{{mail.to[0].email}}</span> | ||||||
|  |                         <span class="detail">{{mail.time}}</span> | ||||||
|  |                     </div> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  | 
 | ||||||
|  |             <button md-button | ||||||
|  |                     [mdMenuTriggerFor]="moreMenu" | ||||||
|  |                     aria-label="More" class="mat-icon-button" | ||||||
|  |                     ng-click="$mdOpenMenu($event)"> | ||||||
|  |                 <md-icon>more_vert</md-icon> | ||||||
|  |             </button> | ||||||
|  | 
 | ||||||
|  |             <md-menu #moreMenu="mdMenu"> | ||||||
|  |                 <button md-menu-item aria-label="Reply" | ||||||
|  |                         ng-click="vm.replyDialog($event)"> | ||||||
|  |                     <md-icon>reply</md-icon> | ||||||
|  |                     <span>Reply</span> | ||||||
|  |                 </button> | ||||||
|  | 
 | ||||||
|  |                 <button md-menu-item aria-label="Forward"> | ||||||
|  |                     <md-icon>forward</md-icon> | ||||||
|  |                     <span>Forward</span> | ||||||
|  |                 </button> | ||||||
|  | 
 | ||||||
|  |                 <button md-menu-item aria-label="Print"> | ||||||
|  |                     <md-icon>print</md-icon> | ||||||
|  |                     <span>Print</span> | ||||||
|  |                 </button> | ||||||
|  |             </md-menu> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |         <div [innerHTML]="mail.message"></div> | ||||||
|  | 
 | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |     <div *ngIf="mail.attachments" class="mail-attachments"> | ||||||
|  | 
 | ||||||
|  |         <div class="title"> | ||||||
|  |             <span>Attachments</span> ({{mail.attachments.length}}) | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |         <div class="attachment-list" layout-wrap fxLayout="row"> | ||||||
|  | 
 | ||||||
|  |             <div class="attachment" fxLayout="column" | ||||||
|  |                  *ngFor="let attachment of mail.attachments"> | ||||||
|  | 
 | ||||||
|  |                 <img class="preview" src="{{attachment.preview}}"> | ||||||
|  | 
 | ||||||
|  |                 <div fxLayout="column"> | ||||||
|  |                     <a href="#" class="md-accent-color link">View</a> | ||||||
|  |                     <a href="#" class="md-accent-color link">Download</a> | ||||||
|  |                     <div class="size">({{attachment.size}})</div> | ||||||
|  |                 </div> | ||||||
|  | 
 | ||||||
|  |             </div> | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|  | </div> | ||||||
|  | |||||||
| @ -0,0 +1,106 @@ | |||||||
|  | @import 'src/app/core/scss/fuse'; | ||||||
|  | 
 | ||||||
|  | :host { | ||||||
|  |     background: #FFFFFF; | ||||||
|  |     padding: 24px; | ||||||
|  | 
 | ||||||
|  |     .mail-header { | ||||||
|  |         padding-bottom: 24px; | ||||||
|  |         border-bottom: 1px solid rgba(0, 0, 0, 0.12); | ||||||
|  | 
 | ||||||
|  |         .actions { | ||||||
|  |             min-width: 88px; | ||||||
|  | 
 | ||||||
|  |             .mat-icon-button { | ||||||
|  |                 padding: 0; | ||||||
|  |                 width: 32px; | ||||||
|  |                 height: 32px; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         .subject { | ||||||
|  |             font-size: 17px; | ||||||
|  |             font-weight: 500; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         .label { | ||||||
|  |             display: inline-block; | ||||||
|  |             font-size: 11px; | ||||||
|  |             padding: 0 5px; | ||||||
|  |             margin: 8px 6px 0 0; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     .mail-content { | ||||||
|  |         padding: 24px 0; | ||||||
|  | 
 | ||||||
|  |         .to { | ||||||
|  |             color: rgba(0, 0, 0, 0.54); | ||||||
|  | 
 | ||||||
|  |             .to-text { | ||||||
|  |                 margin-right: 4px; | ||||||
|  |                 text-transform: lowercase; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         .info { | ||||||
|  |             padding-bottom: 16px; | ||||||
|  | 
 | ||||||
|  |             .avatar { | ||||||
|  |                 margin-right: 16px; | ||||||
|  |                 background-color: mat-color($accent); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             .name { | ||||||
|  |                 margin-right: 8px; | ||||||
|  |                 font-weight: 500; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             .toggle-details { | ||||||
|  |                 padding-top: 16px; | ||||||
|  |                 cursor: pointer; | ||||||
|  |                 font-weight: 500; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             .details { | ||||||
|  |                 padding-top: 8px; | ||||||
|  | 
 | ||||||
|  |                 .title { | ||||||
|  |                     font-weight: 500; | ||||||
|  |                     margin-right: 6px; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 .detail { | ||||||
|  |                     color: rgba(0, 0, 0, 0.54); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     .mail-attachments { | ||||||
|  |         padding: 24px 0; | ||||||
|  |         border-top: 1px solid rgba(0, 0, 0, 0.12); | ||||||
|  | 
 | ||||||
|  |         .title { | ||||||
|  |             margin-bottom: 16px; | ||||||
|  |             font-weight: 500; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         .attachment { | ||||||
|  | 
 | ||||||
|  |             .preview { | ||||||
|  |                 width: 100px; | ||||||
|  |                 margin: 0 16px 8px 0; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             .link { | ||||||
|  |                 margin-bottom: 2px; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             .size { | ||||||
|  |                 font-size: 11px; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -1,15 +1,23 @@ | |||||||
| import { Component, OnInit } from '@angular/core'; | import {Component, Input, OnInit} from '@angular/core'; | ||||||
|  | import {MailModel} from '../mail.model'; | ||||||
| 
 | 
 | ||||||
| @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 | ||||||
|  | { | ||||||
|  |     @Input('selectedMail') public mail: MailModel; | ||||||
|  |     showDetails: boolean; | ||||||
| 
 | 
 | ||||||
|   constructor() { } |     constructor() | ||||||
|  |     { | ||||||
|  |         this.showDetails = false; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|   ngOnInit() { |     ngOnInit() | ||||||
|   } |     { | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  | |||||||
| @ -6,20 +6,20 @@ | |||||||
| 
 | 
 | ||||||
|         <div class="name" fxLayout="row" fxLayoutAlign="start center"> |         <div class="name" fxLayout="row" fxLayoutAlign="start center"> | ||||||
| 
 | 
 | ||||||
|             <img class="avatar" *ngIf="mail.from.avatar" alt="{{mail.from.name}}" src="{{mail.from.avatar}}"/> |             <img class="avatar" *ngIf="mail.from?.avatar" alt="{{mail.from?.name}}" src="{{mail.from?.avatar}}"/> | ||||||
| 
 | 
 | ||||||
|             <div class="avatar" *ngIf="!mail.from.avatar">{{mail.from.name[0]}}</div> |             <div class="avatar" *ngIf="!mail.from?.avatar">{{mail.from?.name[0]}}</div> | ||||||
| 
 | 
 | ||||||
|             <span class="text-truncate">{{mail.from.name}}</span> |             <span class="text-truncate" *ngIf="mail?.from">{{mail.from?.name}}</span> | ||||||
| 
 | 
 | ||||||
|             <md-icon *ngIf="mail.hasAttachments" class="has-attachment">attachment</md-icon> |             <md-icon *ngIf="mail.hasAttachments">attachment</md-icon> | ||||||
|         </div> |         </div> | ||||||
| 
 | 
 | ||||||
|         <div class="subject text-truncate"> |         <div class="subject text-truncate"> | ||||||
|             {{mail.subject}} |             {{mail.subject}} | ||||||
|         </div> |         </div> | ||||||
| 
 | 
 | ||||||
|         <div class="message text-truncate"> |         <div class="message text-truncate" *ngIf="mail?.message"> | ||||||
| 
 | 
 | ||||||
|             {{mail.message | htmlToPlaintext | slice:0:180}}{{mail.message.length > 180 ? '...' : ''}} |             {{mail.message | htmlToPlaintext | slice:0:180}}{{mail.message.length > 180 ? '...' : ''}} | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,4 +1,7 @@ | |||||||
|  | @import 'src/app/core/scss/fuse'; | ||||||
|  | 
 | ||||||
| :host { | :host { | ||||||
|  |     flex-shrink: 0; | ||||||
|     background: #FAFAFA; |     background: #FAFAFA; | ||||||
|     position: relative; |     position: relative; | ||||||
|     padding: 16px 24px; |     padding: 16px 24px; | ||||||
| @ -38,7 +41,7 @@ | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     &.current-thread { |     &.selected-mail { | ||||||
|         background: #E3F2FD; |         background: #E3F2FD; | ||||||
| 
 | 
 | ||||||
|         .info { |         .info { | ||||||
| @ -67,11 +70,7 @@ | |||||||
|                 width: 32px; |                 width: 32px; | ||||||
|                 height: 32px; |                 height: 32px; | ||||||
|                 line-height: 32px; |                 line-height: 32px; | ||||||
|             } |                 background-color: mat-color($accent); | ||||||
| 
 |  | ||||||
|             .has-attachment { |  | ||||||
|                 margin-left: 8px; |  | ||||||
|                 transform: rotate(90deg); |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -16,7 +16,6 @@ export class MailListItemComponent implements OnInit | |||||||
| 
 | 
 | ||||||
|     ngOnInit() |     ngOnInit() | ||||||
|     { |     { | ||||||
|         console.log('mail list item inited'); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  | |||||||
| @ -1 +1,3 @@ | |||||||
| <fuse-mail-list-item *ngFor="let mail of mails" [mail]="mail" md-ripple></fuse-mail-list-item> | <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> | ||||||
|  | |||||||
| @ -1,4 +1,8 @@ | |||||||
| :host{ | :host{ | ||||||
|     display: flex; |     display: flex; | ||||||
|     flex-direction: column; |     flex-direction: column; | ||||||
|  |     background: #FAFAFA; | ||||||
|  |     position: relative; | ||||||
|  |     padding: 0; | ||||||
|  |     border-right: 1px solid rgba(0,0,0,.12); | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,5 +1,6 @@ | |||||||
| import { Component, OnInit } from '@angular/core'; | import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; | ||||||
| import { AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database'; | import {AngularFireDatabase, FirebaseListObservable} from 'angularfire2/database'; | ||||||
|  | import {MailModel} from '../mail.model'; | ||||||
| 
 | 
 | ||||||
| @Component({ | @Component({ | ||||||
|     selector   : 'fuse-mail-list', |     selector   : 'fuse-mail-list', | ||||||
| @ -10,14 +11,16 @@ export class MailListComponent implements OnInit | |||||||
| { | { | ||||||
|     mailsDB: FirebaseListObservable<any[]>; |     mailsDB: FirebaseListObservable<any[]>; | ||||||
|     mails: any; |     mails: any; | ||||||
|  |     @Input('selectedMail') public selectedMail: MailModel; | ||||||
|  |     @Output() onMailSelect = new EventEmitter<MailModel>(); | ||||||
| 
 | 
 | ||||||
|     constructor(private db: AngularFireDatabase) |     constructor(private db: AngularFireDatabase) | ||||||
|     { |     { | ||||||
|         this.mailsDB = this.db.list('/mail/data', { |         this.mailsDB = this.db.list('/mail/data', { | ||||||
|             query: { |             // query: {
 | ||||||
|                 orderByChild: 'important', |             //     orderByChild: 'important',
 | ||||||
|                 equalTo     : true |             //     equalTo     : true
 | ||||||
|             } |             // }
 | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -49,6 +52,13 @@ export class MailListComponent implements OnInit | |||||||
|         console.log(this.mails); |         console.log(this.mails); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     selectMail(mail) | ||||||
|  |     { | ||||||
|  |         console.info('mail selected', mail); | ||||||
|  |         this.selectedMail = mail; | ||||||
|  |         this.onMailSelect.emit(mail); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     onGet() |     onGet() | ||||||
|     { |     { | ||||||
|         this.mails.subscribe((response) => |         this.mails.subscribe((response) => | ||||||
|  | |||||||
| @ -51,9 +51,9 @@ | |||||||
| 
 | 
 | ||||||
|                     <div fxLayout="row" fxFill> |                     <div fxLayout="row" fxFill> | ||||||
| 
 | 
 | ||||||
|                         <fuse-mail-list fxFlex></fuse-mail-list> |                         <fuse-mail-list fxFlex [selectedMail]="selectedMail" (onMailSelect)="onMailSelect($event)"></fuse-mail-list> | ||||||
| 
 | 
 | ||||||
|                         <fuse-mail-details fxFlex></fuse-mail-details> |                         <fuse-mail-details fxFlex [selectedMail]="selectedMail"></fuse-mail-details> | ||||||
| 
 | 
 | ||||||
|                     </div> |                     </div> | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| import { Component, OnInit } from '@angular/core'; | import {Component, OnInit} from '@angular/core'; | ||||||
| import { AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database'; | import {AngularFireDatabase, FirebaseListObservable} from 'angularfire2/database'; | ||||||
| import { ActivatedRoute, Data } from '@angular/router'; | import {ActivatedRoute, Data} from '@angular/router'; | ||||||
|  | import {MailModel} from './mail.model'; | ||||||
| 
 | 
 | ||||||
| @Component({ | @Component({ | ||||||
|     selector   : 'fuse-mail', |     selector   : 'fuse-mail', | ||||||
| @ -10,6 +11,7 @@ import { ActivatedRoute, Data } from '@angular/router'; | |||||||
| export class MailComponent implements OnInit | export class MailComponent implements OnInit | ||||||
| { | { | ||||||
|     mails: FirebaseListObservable<any[]>; |     mails: FirebaseListObservable<any[]>; | ||||||
|  |     selectedMail: MailModel; | ||||||
| 
 | 
 | ||||||
|     constructor(private db: AngularFireDatabase, private route: ActivatedRoute) |     constructor(private db: AngularFireDatabase, private route: ActivatedRoute) | ||||||
|     { |     { | ||||||
| @ -33,4 +35,10 @@ export class MailComponent implements OnInit | |||||||
|             console.warn(data['mails']); |             console.warn(data['mails']); | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     onMailSelect(mail) | ||||||
|  |     { | ||||||
|  |         console.info('on mail select', mail); | ||||||
|  |         this.selectedMail = mail; | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -11,7 +11,6 @@ export class MailModel | |||||||
|         name: string, |         name: string, | ||||||
|         email: string |         email: string | ||||||
|     }[]; |     }[]; | ||||||
| 
 |  | ||||||
|     message: string; |     message: string; | ||||||
|     time: string; |     time: string; | ||||||
|     read: boolean; |     read: boolean; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user