mirror of
https://github.com/richard-loafle/fuse-angular.git
synced 2025-04-30 12:03:12 +00:00
374 lines
11 KiB
TypeScript
374 lines
11 KiB
TypeScript
import { Component, ElementRef, OnDestroy, OnInit, TemplateRef, ViewChild, ViewContainerRef, ViewEncapsulation } from '@angular/core';
|
|
import { ActivatedRoute, Router } from '@angular/router';
|
|
import { TemplatePortal } from '@angular/cdk/portal';
|
|
import { Overlay, OverlayRef } from '@angular/cdk/overlay';
|
|
import { MatButton } from '@angular/material/button';
|
|
import { Subject } from 'rxjs';
|
|
import { takeUntil } from 'rxjs/operators';
|
|
import { MailboxService } from 'app/modules/admin/apps/mailbox/mailbox.service';
|
|
import { Mail, MailFolder, MailLabel } from 'app/modules/admin/apps/mailbox/mailbox.types';
|
|
import { labelColorDefs } from 'app/modules/admin/apps/mailbox/mailbox.constants';
|
|
|
|
@Component({
|
|
selector : 'mailbox-details',
|
|
templateUrl : './details.component.html',
|
|
encapsulation: ViewEncapsulation.None
|
|
})
|
|
export class MailboxDetailsComponent implements OnInit, OnDestroy
|
|
{
|
|
@ViewChild('infoDetailsPanelOrigin') private _infoDetailsPanelOrigin: MatButton;
|
|
@ViewChild('infoDetailsPanel') private _infoDetailsPanel: TemplateRef<any>;
|
|
|
|
folders: MailFolder[];
|
|
labelColors: any;
|
|
labels: MailLabel[];
|
|
mail: Mail;
|
|
replyFormActive: boolean = false;
|
|
private _overlayRef: OverlayRef;
|
|
private _unsubscribeAll: Subject<any> = new Subject<any>();
|
|
|
|
/**
|
|
* Constructor
|
|
*/
|
|
constructor(
|
|
private _activatedRoute: ActivatedRoute,
|
|
private _elementRef: ElementRef,
|
|
private _mailboxService: MailboxService,
|
|
private _overlay: Overlay,
|
|
private _router: Router,
|
|
private _viewContainerRef: ViewContainerRef
|
|
)
|
|
{
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------------------------------
|
|
// @ Lifecycle hooks
|
|
// -----------------------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
* On init
|
|
*/
|
|
ngOnInit(): void
|
|
{
|
|
// Get the label colors
|
|
this.labelColors = labelColorDefs;
|
|
|
|
// Folders
|
|
this._mailboxService.folders$
|
|
.pipe(takeUntil(this._unsubscribeAll))
|
|
.subscribe((folders: MailFolder[]) => {
|
|
this.folders = folders;
|
|
});
|
|
|
|
// Labels
|
|
this._mailboxService.labels$
|
|
.pipe(takeUntil(this._unsubscribeAll))
|
|
.subscribe((labels: MailLabel[]) => {
|
|
this.labels = labels;
|
|
});
|
|
|
|
// Mail
|
|
this._mailboxService.mail$
|
|
.pipe(takeUntil(this._unsubscribeAll))
|
|
.subscribe((mail: Mail) => {
|
|
this.mail = mail;
|
|
});
|
|
|
|
// Selected mail changed
|
|
this._mailboxService.selectedMailChanged
|
|
.pipe(takeUntil(this._unsubscribeAll))
|
|
.subscribe(() => {
|
|
|
|
// De-activate the reply form
|
|
this.replyFormActive = false;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* On destroy
|
|
*/
|
|
ngOnDestroy(): void
|
|
{
|
|
// Unsubscribe from all subscriptions
|
|
this._unsubscribeAll.next();
|
|
this._unsubscribeAll.complete();
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------------------------------
|
|
// @ Public methods
|
|
// -----------------------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Get the current folder
|
|
*/
|
|
getCurrentFolder(): any
|
|
{
|
|
return this._activatedRoute.snapshot.paramMap.get('folder');
|
|
}
|
|
|
|
/**
|
|
* Move to folder
|
|
*
|
|
* @param folderSlug
|
|
*/
|
|
moveToFolder(folderSlug: string): void
|
|
{
|
|
// Find the folder details
|
|
const folder = this.folders.find(item => item.slug === folderSlug);
|
|
|
|
// Return if the current folder of the mail
|
|
// is already equals to the given folder
|
|
if ( this.mail.folder === folder.id )
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Update the mail object
|
|
this.mail.folder = folder.id;
|
|
|
|
// Update the mail on the server
|
|
this._mailboxService.updateMail(this.mail.id, {folder: this.mail.folder}).subscribe();
|
|
|
|
// Navigate to the parent
|
|
this._router.navigate(['./'], {relativeTo: this._activatedRoute.parent});
|
|
}
|
|
|
|
/**
|
|
* Toggle label
|
|
*
|
|
* @param label
|
|
*/
|
|
toggleLabel(label: MailLabel): void
|
|
{
|
|
let deleted = false;
|
|
|
|
// Update the mail object
|
|
if ( this.mail.labels.includes(label.id) )
|
|
{
|
|
// Set the deleted
|
|
deleted = true;
|
|
|
|
// Delete the label
|
|
this.mail.labels.splice(this.mail.labels.indexOf(label.id), 1);
|
|
}
|
|
else
|
|
{
|
|
// Add the label
|
|
this.mail.labels.push(label.id);
|
|
}
|
|
|
|
// Update the mail on the server
|
|
this._mailboxService.updateMail(this.mail.id, {labels: this.mail.labels}).subscribe();
|
|
|
|
// If the label was deleted...
|
|
if ( deleted )
|
|
{
|
|
// If the current activated route has a label parameter and it equals to the one we are removing...
|
|
if ( this._activatedRoute.snapshot.paramMap.get('label') && this._activatedRoute.snapshot.paramMap.get('label') === label.slug )
|
|
{
|
|
// Navigate to the parent
|
|
this._router.navigate(['./'], {relativeTo: this._activatedRoute.parent});
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Toggle important
|
|
*/
|
|
toggleImportant(): void
|
|
{
|
|
// Update the mail object
|
|
this.mail.important = !this.mail.important;
|
|
|
|
// Update the mail on the server
|
|
this._mailboxService.updateMail(this.mail.id, {important: this.mail.important}).subscribe();
|
|
|
|
// If the important was removed...
|
|
if ( !this.mail.important )
|
|
{
|
|
// If the current activated route has a filter parameter and it equals to the 'important'...
|
|
if ( this._activatedRoute.snapshot.paramMap.get('filter') && this._activatedRoute.snapshot.paramMap.get('filter') === 'important' )
|
|
{
|
|
// Navigate to the parent
|
|
this._router.navigate(['./'], {relativeTo: this._activatedRoute.parent});
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Toggle star
|
|
*/
|
|
toggleStar(): void
|
|
{
|
|
// Update the mail object
|
|
this.mail.starred = !this.mail.starred;
|
|
|
|
// Update the mail on the server
|
|
this._mailboxService.updateMail(this.mail.id, {starred: this.mail.starred}).subscribe();
|
|
|
|
// If the star was removed...
|
|
if ( !this.mail.starred )
|
|
{
|
|
// If the current activated route has a filter parameter and it equals to the 'starred'...
|
|
if ( this._activatedRoute.snapshot.paramMap.get('filter') && this._activatedRoute.snapshot.paramMap.get('filter') === 'starred' )
|
|
{
|
|
// Navigate to the parent
|
|
this._router.navigate(['./'], {relativeTo: this._activatedRoute.parent});
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Toggle unread
|
|
*
|
|
* @param unread
|
|
*/
|
|
toggleUnread(unread: boolean): void
|
|
{
|
|
// Update the mail object
|
|
this.mail.unread = unread;
|
|
|
|
// Update the mail on the server
|
|
this._mailboxService.updateMail(this.mail.id, {unread: this.mail.unread}).subscribe();
|
|
}
|
|
|
|
/**
|
|
* Reply
|
|
*/
|
|
reply(): void
|
|
{
|
|
// Activate the reply form
|
|
this.replyFormActive = true;
|
|
|
|
// Scroll to the bottom of the details pane
|
|
setTimeout(() => {
|
|
this._elementRef.nativeElement.scrollTop = this._elementRef.nativeElement.scrollHeight;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Reply all
|
|
*/
|
|
replyAll(): void
|
|
{
|
|
// Activate the reply form
|
|
this.replyFormActive = true;
|
|
|
|
// Scroll to the bottom of the details pane
|
|
setTimeout(() => {
|
|
this._elementRef.nativeElement.scrollTop = this._elementRef.nativeElement.scrollHeight;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Forward
|
|
*/
|
|
forward(): void
|
|
{
|
|
// Activate the reply form
|
|
this.replyFormActive = true;
|
|
|
|
// Scroll to the bottom of the details pane
|
|
setTimeout(() => {
|
|
this._elementRef.nativeElement.scrollTop = this._elementRef.nativeElement.scrollHeight;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Discard
|
|
*/
|
|
discard(): void
|
|
{
|
|
// Deactivate the reply form
|
|
this.replyFormActive = false;
|
|
}
|
|
|
|
/**
|
|
* Send
|
|
*/
|
|
send(): void
|
|
{
|
|
// Deactivate the reply form
|
|
this.replyFormActive = false;
|
|
}
|
|
|
|
/**
|
|
* Open info details panel
|
|
*/
|
|
openInfoDetailsPanel(): void
|
|
{
|
|
// Create the overlay
|
|
this._overlayRef = this._overlay.create({
|
|
backdropClass : '',
|
|
hasBackdrop : true,
|
|
scrollStrategy : this._overlay.scrollStrategies.block(),
|
|
positionStrategy: this._overlay.position()
|
|
.flexibleConnectedTo(this._infoDetailsPanelOrigin._elementRef.nativeElement)
|
|
.withFlexibleDimensions()
|
|
.withViewportMargin(16)
|
|
.withLockedPosition()
|
|
.withPositions([
|
|
{
|
|
originX : 'start',
|
|
originY : 'bottom',
|
|
overlayX: 'start',
|
|
overlayY: 'top'
|
|
},
|
|
{
|
|
originX : 'start',
|
|
originY : 'top',
|
|
overlayX: 'start',
|
|
overlayY: 'bottom'
|
|
},
|
|
{
|
|
originX : 'end',
|
|
originY : 'bottom',
|
|
overlayX: 'end',
|
|
overlayY: 'top'
|
|
},
|
|
{
|
|
originX : 'end',
|
|
originY : 'top',
|
|
overlayX: 'end',
|
|
overlayY: 'bottom'
|
|
}
|
|
])
|
|
});
|
|
|
|
// Create a portal from the template
|
|
const templatePortal = new TemplatePortal(this._infoDetailsPanel, this._viewContainerRef);
|
|
|
|
// Attach the portal to the overlay
|
|
this._overlayRef.attach(templatePortal);
|
|
|
|
// Subscribe to the backdrop click
|
|
this._overlayRef.backdropClick().subscribe(() => {
|
|
|
|
// If overlay exists and attached...
|
|
if ( this._overlayRef && this._overlayRef.hasAttached() )
|
|
{
|
|
// Detach it
|
|
this._overlayRef.detach();
|
|
}
|
|
|
|
// If template portal exists and attached...
|
|
if ( templatePortal && templatePortal.isAttached )
|
|
{
|
|
// Detach it
|
|
templatePortal.detach();
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Track by function for ngFor loops
|
|
*
|
|
* @param index
|
|
* @param item
|
|
*/
|
|
trackByFn(index: number, item: any): any
|
|
{
|
|
return item.id || index;
|
|
}
|
|
}
|