Newer
Older
import { COMMA } from '@angular/cdk/keycodes';
import { Component, OnInit, Inject } from '@angular/core';

Alex ORLUC
committed
import { HttpClient } from '@angular/common/http';
import { LANG } from '../../translate.component';
import { NotificationService } from '../../notification.service';
import { Observable, of } from 'rxjs';
import { MatDialog, MAT_DIALOG_DATA, MatDialogRef, MatChipInputEvent } from '@angular/material';
import { switchMap, map, catchError, filter, exhaustMap, tap, debounceTime, startWith, distinctUntilChanged } from 'rxjs/operators';

Alex ORLUC
committed
import { FormControl } from '@angular/forms';
import { FunctionsService } from '../../../service/functions.service';
import { CdkDragDrop, transferArrayItem } from '@angular/cdk/drag-drop';

Alex ORLUC
committed
import { ContactService } from '../../../service/contact.service';
import { AppService } from '../../../service/app.service';
import { ConfirmComponent } from '../../../plugins/modal/confirm.component';
import { PrivilegeService } from '../../../service/privileges.service';
import { HeaderService } from '../../../service/header.service';

Alex ORLUC
committed
declare function $j(selector: any): any;

Alex ORLUC
committed
declare var tinymce: any;

Alex ORLUC
committed
@Component({
selector: 'app-sent-resource-page',
templateUrl: "sent-resource-page.component.html",
styleUrls: ['sent-resource-page.component.scss'],

Alex ORLUC
committed
providers: [ContactService, AppService],

Alex ORLUC
committed
})
export class SentResourcePageComponent implements OnInit {

Alex ORLUC
committed
lang: any = LANG;
loading: boolean = true;
readonly separatorKeysCodes: number[] = [COMMA];

Alex ORLUC
committed
availableEmailModels: any[] = [];
availableSignEmailModels: any[] = [];
resourceData: any = null;
availableSenders: any[] = [];
currentSender: any = {};

Alex ORLUC
committed
recipients: any[] = [];
copies: any[] = [];
invisibleCopies: any[] = [];
fruits: any[] = [];
recipientsInput: FormControl = new FormControl();

Alex ORLUC
committed
emailSignListForm = new FormControl();
templateEmailListForm = new FormControl();
tinymceInput: string = '';
filteredEmails: Observable<string[]>;
emailsList: any[] = [];
currentSelected: any = null;
showCopies: boolean = false;
showInvisibleCopies: boolean = false;

Alex ORLUC
committed
emailId: number = null;

Alex ORLUC
committed
emailStatus: string = 'WAITING';

Alex ORLUC
committed
currentEmailAttachTool: string = '';
emailAttachTool: any = {

Alex ORLUC
committed
document: {
icon: 'fa fa-file',

Alex ORLUC
committed
list: []

Alex ORLUC
committed
notes: {
icon: 'fas fa-pen-square',

Alex ORLUC
committed
list: []

Alex ORLUC
committed
attachments: {
icon: 'fa fa-paperclip',

Alex ORLUC
committed
list: []
emailAttach: any = {};

Alex ORLUC
committed
lastClicked: any = Date.now();

Alex ORLUC
committed
pdfMode: boolean = false;
htmlMode: boolean = true;

Alex ORLUC
committed
constructor(
public http: HttpClient,
private notify: NotificationService,
@Inject(MAT_DIALOG_DATA) public data: any,

Alex ORLUC
committed
public dialog: MatDialog,
public dialogRef: MatDialogRef<SentResourcePageComponent>,

Alex ORLUC
committed
public functions: FunctionsService,
private contactService: ContactService,
public privilegeService: PrivilegeService,
public headerService: HeaderService

Alex ORLUC
committed
) { }
async ngOnInit(): Promise<void> {
Object.keys(this.emailAttachTool).forEach(element => {
if (element === 'document') {
this.emailAttach[element] = {

Alex ORLUC
committed
id: this.data.resId,
isLinked: false,
original: false
};
} else {
this.emailAttach[element] = [];
}
});

Alex ORLUC
committed
this.initEmailsList();
this.initSignEmailModelsList();

Alex ORLUC
committed
await this.getAttachElements();
await this.getResourceData();
await this.getUserEmails();
if (this.data.emailId && this.data.emailType === 'email') {
await this.getEmailData(this.data.emailId);
} else if (this.data.emailId && this.data.emailType === 'acknowledgementReceipt') {
await this.getAcknowledgementReceiptData(this.data.emailId);
this.loading = false;
setTimeout(() => {
this.initMce();
}, 0);

Alex ORLUC
committed
}
initMce() {
tinymce.init({
selector: "textarea#emailSignature",
readonly: this.emailStatus === 'SENT',

Alex ORLUC
committed
language: this.lang.langISO.replace('-', '_'),
language_url: `../../node_modules/tinymce-i18n/langs/${this.lang.langISO.replace('-', '_')}.js`,
menubar: false,
statusbar: false,
plugins: [
'autolink', 'autoresize'
],
external_plugins: {
'maarch_b64image': "../../src/frontend/plugins/tinymce/maarch_b64image/plugin.min.js"
},
toolbar_sticky: true,
toolbar_drawer: 'floating',
toolbar: this.emailStatus !== 'SENT' ?

Alex ORLUC
committed
'undo redo | fontselect fontsizeselect | bold italic underline strikethrough forecolor | maarch_b64image | \
alignleft aligncenter alignright alignjustify \
bullist numlist outdent indent | removeformat' : false

Alex ORLUC
committed
});

Alex ORLUC
committed
}
add(event: MatChipInputEvent, type: string): void {

Alex ORLUC
committed
const input = event.input;
const value = event.value;
if ((value || '').trim()) {
label: value.trim(),
email: value.trim(),
badFormat : this.isBadEmailFormat(value.trim())

Alex ORLUC
committed
}
if (input) {
input.value = '';
}
}
isBadEmailFormat(email: string) {
const regex = /^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$/g;
if (email.trim().match(regex) !== null) {
return false
} else {
return true;
}
}

Alex ORLUC
committed
closeModal(state: string = '') {
tinymce.remove();
this.dialogRef.close(state);
}
addEmail(item: any, type: string) {
this[type].splice(this[type].length - 1, 1);
if (item.type === 'contactGroup') {
this.http.get(`../../rest/contactsGroups/${item.id}`).pipe(
map((data: any) => {
data = data.contactsGroup.contacts.filter((contact: any) => !this.functions.empty(contact.email)).map((contact: any) => {
return {
label: contact.contact,
email: contact.email
}
});
return data;
}),
tap((data: any) => {
this[type] = this[type].concat(data);
}),
catchError((err) => {
this.notify.handleSoftErrors(err);
return of(false);
})
).subscribe();
} else {
this[type].push({
label: item.label,
email: item.email
});
}
}

Alex ORLUC
committed
mergeEmailTemplate(templateId: any) {
this.templateEmailListForm.reset();
this.http.post(`../../rest/templates/${templateId}/mergeEmail`, { data: { resId: this.data.resId } }).pipe(
tap((data: any) => {
var div = document.createElement('div');

Alex ORLUC
committed
div.innerHTML = tinymce.get('emailSignature').getContent();
if (div.getElementsByClassName('signature').length > 0) {
const signatureContent = div.getElementsByClassName('signature')[0].innerHTML;
div.getElementsByClassName('signature')[0].remove();

Alex ORLUC
committed
tinymce.get('emailSignature').setContent(`${div.innerHTML}${data.mergedDocument}<div class="signature">${signatureContent}</div>`);

Alex ORLUC
committed
tinymce.get('emailSignature').setContent(`${tinymce.get('emailSignature').getContent()}${data.mergedDocument}`);
if (!this.htmlMode) {
tinymce.get('emailSignature').setContent(tinymce.get('emailSignature').getContent({ format: 'text' }));
}
}),
catchError((err) => {
this.notify.handleSoftErrors(err);
return of(false);
})
).subscribe();
}

Alex ORLUC
committed
mergeSignEmailTemplate(templateId: any) {
this.emailSignListForm.reset();
this.http.get(`../../rest/currentUser/emailSignatures/${templateId}`).pipe(
tap((data: any) => {
var div = document.createElement('div');

Alex ORLUC
committed
div.innerHTML = tinymce.get('emailSignature').getContent();
if (div.getElementsByClassName('signature').length > 0) {
div.getElementsByClassName('signature')[0].remove();

Alex ORLUC
committed
tinymce.get('emailSignature').setContent(`${div.innerHTML}<div class="signature">${data.emailSignature.content}</div>`);

Alex ORLUC
committed
tinymce.get('emailSignature').setContent(`${tinymce.get('emailSignature').getContent()}<div class="signature">${data.emailSignature.content}</div>`);
if (!this.htmlMode) {
tinymce.get('emailSignature').setContent(tinymce.get('emailSignature').getContent({ format: 'text' }));
}
}),
catchError((err) => {
this.notify.handleSoftErrors(err);
return of(false);
})
).subscribe();
}

Alex ORLUC
committed
remove(item: any, type: string): void {
if (this.canManageMail()) {
const index = this[type].indexOf(item);

Alex ORLUC
committed
if (index >= 0) {
this[type].splice(index, 1);
}

Alex ORLUC
committed
}
}
getEmailData(emailId: number) {
this.http.get(`../../rest/emails/${emailId}`).pipe(
tap((data: any) => {
this.emailCreatorId = data.userId;
this.recipients = data.recipients.map((item: any) => {
return {
label: item,
email: item,
badFormat : this.isBadEmailFormat(item)
}
});
this.copies = data.cc.map((item: any) => {
return {
label: item,
email: item,
badFormat : this.isBadEmailFormat(item)
}
});;
this.invisibleCopies = data.cci.map((item: any) => {
return {
label: item,
email: item,
badFormat : this.isBadEmailFormat(item)
}
});
this.showCopies = this.copies.length > 0;
this.showInvisibleCopies = this.invisibleCopies.length > 0;
this.emailsubject = data.object;
this.emailStatus = data.status;
if (!this.canManageMail()) {
this.currentSender = {
label: data.sender.email,
email: data.sender.email,
entityId : data.sender.entityId
};
}
this.emailContent = data.body;
Object.keys(data.document).forEach(element => {
if (['id', 'isLinked', 'original'].indexOf(element) === -1) {
data.document[element].forEach((dataAttach: any) => {
const elem = this.emailAttachTool[element].list.filter((item: any) => item.id === dataAttach.id || item.id === dataAttach);
if (elem.length > 0) {
this.emailAttach[element] = elem.map((item: any) => {
return {
...item,
format: dataAttach.original || dataAttach.original === undefined ? item.format : 'pdf',
original: dataAttach.original,
size : dataAttach.original || dataAttach.original === undefined ? item.size : item.convertedDocument.size
}
})
}
});
} else if (element === 'isLinked' && data.document.isLinked === true) {
this.emailAttach.document.isLinked = true;
this.emailAttach.document.original = data.document.original;
this.emailAttach.document.size = this.emailAttach.document.original ? this.emailAttachTool.document.list[0].size : this.emailAttachTool.document.list[0].convertedDocument.size
resolve(true);
}),
catchError((err) => {
this.notify.handleSoftErrors(err);
resolve(false);
return of(false);
})
).subscribe();
});
}
getAcknowledgementReceiptData(emailId: number) {
return new Promise((resolve) => {
this.http.get(`../../rest/acknowledgementReceipts/${emailId}`).pipe(
tap((data: any) => {
this.currentSender = {
label: data.acknowledgementReceipt.userLabel,
email: data.acknowledgementReceipt.userLabel
};
label: !this.functions.empty(data.acknowledgementReceipt.contact) ? this.contactService.formatContact(data.acknowledgementReceipt.contact) : this.lang.contactDeleted,
email: !this.functions.empty(data.acknowledgementReceipt.contact.email) ? data.acknowledgementReceipt.contact.email : this.lang.contactDeleted
}];
this.emailsubject = this.lang.shipping;
this.emailStatus = 'SENT';
}),
exhaustMap(() => this.http.get(`../../rest/acknowledgementReceipts/${emailId}/content`)),
tap((data: any) => {
this.pdfMode = data.format === 'pdf';
if (this.pdfMode) {
this.emailContent = data.encodedDocument;
} else {
this.emailContent = atob(data.encodedDocument);
}
resolve(true);
}),
catchError((err) => {
this.notify.handleSoftErrors(err);
resolve(false);
return of(false);
})
).subscribe();
});
}
this.http.get(`../../rest/resources/${this.data.resId}?light=true`).pipe(
tap((data: any) => {
this.resourceData = data;
this.emailsubject = `[${this.resourceData.chrono}] ${this.resourceData.subject}`;
this.emailsubject = this.emailsubject.substring(0, 70);

Alex ORLUC
committed
this.emailAttach.document.chrono = this.resourceData.chrono;
this.emailAttach.document.label = this.resourceData.subject;

Alex ORLUC
committed
if (!this.functions.empty(this.resourceData.senders)) {
this.resourceData.senders.forEach((sender: any) => {
this.setSender(sender.id);
});
}
resolve(true);
}),
catchError((err) => {
this.notify.handleSoftErrors(err);
resolve(false);
return of(false);
})
).subscribe();
});
}
setSender(id: number) {
this.http.get(`../../rest/contacts/${id}`).pipe(
tap((data: any) => {
if (!this.functions.empty(data.email)) {
this.recipients.push(
{

Alex ORLUC
committed
label: this.contactService.formatContact(data),
}),
catchError((err) => {
this.notify.handleSoftErrors(err);
return of(false);
})
).subscribe();
}
getUserEmails() {
this.http.get('../../rest/currentUser/availableEmails').pipe(
tap((data: any) => {
this.availableSenders = data.emails;
this.currentSender = this.availableSenders[0];
resolve(true);
}),
catchError((err) => {
this.notify.handleSoftErrors(err);
resolve(false);
return of(false);
})
).subscribe();
});

Alex ORLUC
committed
this.http.get(`../../rest/resources/${this.data.resId}/emailsInitialization`).pipe(
tap((data: any) => {

Alex ORLUC
committed
Object.keys(data).forEach(element => {
if (element === 'resource') {
this.emailAttachTool.document.list = [];
if (!this.functions.empty(data[element])) {
this.emailAttachTool.document.list = [data[element]];
}

Alex ORLUC
committed
} else {
this.emailAttachTool[element].list = data[element].map((item: any) => {
return {
...item,
original: item.original !== undefined ? item.original : true,

Alex ORLUC
committed
title: item.chrono !== undefined ? `${item.chrono} - ${item.label} (${item.typeLabel})` : `${item.label} (${item.typeLabel})`
}
});
}
});
resolve(true);
}),
catchError((err: any) => {
this.notify.handleSoftErrors(err);
resolve(false);
return of(false);
})

Alex ORLUC
committed
).subscribe();

Alex ORLUC
committed
initEmailsList() {
this.recipientsInput.valueChanges.pipe(

Alex ORLUC
committed
debounceTime(300),
tap((value) => {
if (value.length === 0) {
this.filteredEmails = of([]);
}
}),

Alex ORLUC
committed
filter(value => value.length > 2),
switchMap(data => this.http.get('../../rest/autocomplete/correspondents', { params: { "search": data, "searchEmails": 'true' } })),

Alex ORLUC
committed
tap((data: any) => {
data = data.filter((contact: any) => !this.functions.empty(contact.email) || contact.type === 'contactGroup').map((contact: any) => {
let label = '';
if (contact.type === 'user' || contact.type === 'contact') {
if (!this.functions.empty(contact.firstname) || !this.functions.empty(contact.lastname)) {
label = contact.firstname + ' ' + contact.lastname;
} else {
label = contact.company;
}
} else if (contact.type === 'contactGroup') {
label = `${contact.firstname} ${contact.lastname}`;
} else {
label = `${contact.lastname}`;
}
return {
id: contact.id,
type: contact.type,
label: label,
email: contact.email
}
});
this.filteredEmails = of(data);

Alex ORLUC
committed
}),
catchError((err) => {
this.notify.handleSoftErrors(err);

Alex ORLUC
committed
return of(false);
})
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
).subscribe();
}
initEmailModelsList() {
this.http.get(`../../rest/resources/${this.data.resId}/emailTemplates`).pipe(
tap((data: any) => {
this.availableEmailModels = data.templates;
}),
catchError((err) => {
this.notify.handleSoftErrors(err);
return of(false);
})
).subscribe();
}
initSignEmailModelsList() {
this.http.get(`../../rest/currentUser/emailSignatures`).pipe(
tap((data: any) => {
this.availableSignEmailModels = data.emailSignatures;
}),
catchError((err) => {
this.notify.handleSoftErrors(err);
return of(false);
})
).subscribe();
}
resetAutocomplete() {
this.filteredEmails = of([]);
}

Alex ORLUC
committed
this.emailStatus = 'WAITING';
if (this.data.emailId === null) {
if (!this.isAllEmailRightFormat()) {
this.notify.error(this.lang.badEmailsFormat);

Alex ORLUC
committed
} else {
if (this.emailsubject === '') {
const dialogRef = this.dialog.open(ConfirmComponent, { autoFocus: false, disableClose: true, data: { title: this.lang.confirm, msg: this.lang.warnEmptySubject } });
dialogRef.afterClosed().pipe(
filter((data: string) => data === 'ok'),
tap(() => {
this.createEmail(true);
})
).subscribe();
} else {
this.createEmail(true);

Alex ORLUC
committed
}
} else {
this.updateEmail(true);

Alex ORLUC
committed
}
}
createEmail(closeModal: boolean = true) {
this.http.post(`../../rest/emails`, this.formatEmail()).pipe(

Alex ORLUC
committed
if (this.emailStatus === 'DRAFT') {
this.notify.success(this.lang.draftSaved);

Alex ORLUC
committed
} else {
this.notify.success(`${this.lang.sendingEmail}...`);

Alex ORLUC
committed
}
if (closeModal) {
this.closeModal('success');
}
}),
catchError((err) => {
this.notify.handleSoftErrors(err);
return of(false);
})
).subscribe();
}
deleteEmail() {
const dialogRef = this.dialog.open(ConfirmComponent, { autoFocus: false, disableClose: true, data: { title: this.lang.delete, msg: this.lang.confirmAction } });
dialogRef.afterClosed().pipe(
filter((data: string) => data === 'ok'),
exhaustMap(() => this.http.delete(`../../rest/emails/${this.data.emailId}`)),
tap(() => {
this.notify.success(this.lang.emailDeleted);
this.closeModal('success');
}),
catchError((err) => {
this.notify.handleSoftErrors(err);
return of(false);
})
).subscribe();
}
updateEmail(closeModal: boolean = true) {
this.http.put(`../../rest/emails/${this.data.emailId}`, this.formatEmail()).pipe(

Alex ORLUC
committed
if (this.emailStatus === 'DRAFT') {
this.notify.success(this.lang.draftUpdated);

Alex ORLUC
committed
} else {
this.notify.success(`${this.lang.sendingEmail}...`);

Alex ORLUC
committed
}
if (closeModal) {
this.closeModal('success');
}
}),
catchError((err) => {
this.notify.handleSoftErrors(err);
return of(false);
})

Alex ORLUC
committed
saveDraft() {
this.emailStatus = 'DRAFT';
if (this.data.emailId === null) {

Alex ORLUC
committed
this.createEmail();
} else {
this.updateEmail();
}
}
drop(event: CdkDragDrop<string[]>) {
if (event.previousContainer !== event.container) {
transferArrayItem(event.previousContainer.data,
event.container.data,
event.previousIndex,
event.currentIndex);
}

Alex ORLUC
committed
}
toggleAttachMail(item: any, type: string, mode: string) {
if (type === 'document') {
if (this.emailAttach.document.isLinked === false) {
this.emailAttach.document.isLinked = true;
this.emailAttach.document.original = mode === 'pdf' ? false : true;
this.emailAttach.document.size = mode === 'pdf' ? item.convertedDocument.size : item.size;
} else {
if (this.emailAttach[type].filter((attach: any) => attach.id === item.id).length === 0) {
this.emailAttach[type].push({

Alex ORLUC
committed
...item,
format: mode !== 'pdf' ? item.format : 'pdf',
original: mode === 'pdf' ? false : true,
size : mode === 'pdf' ? item.convertedDocument.size : item.size
});
}
}
}
removeAttachMail(index: number, type: string) {
if (type === 'document') {
this.emailAttach.document.isLinked = false;
this.emailAttach.document.original = false;
} else {
this.emailAttach[type].splice(index, 1);
swithEditionMode() {
this.htmlMode = !this.htmlMode;
if (this.htmlMode) {
$j('.tox-editor-header').show()
tinymce.get('emailSignature').setContent(tinymce.get('emailSignature').getContent());
} else {
const dialogRef = this.dialog.open(ConfirmComponent, { autoFocus: false, disableClose: true, data: { title: this.lang.switchInPlainText, msg: this.lang.confirmSwitchInPlanText } });
dialogRef.afterClosed().pipe(
tap((data: string) => {
if (data === 'ok') {
$j('.tox-editor-header').hide();
tinymce.get('emailSignature').setContent(tinymce.get('emailSignature').getContent({ format: 'text' }));
} else {
this.htmlMode = !this.htmlMode;
}
})
).subscribe();
}
}
formatEmail() {

Alex ORLUC
committed
let objAttach: any = {}
Object.keys(this.emailAttach).forEach(element => {

Alex ORLUC
committed
if (!this.functions.empty(this.emailAttach[element])) {
if (element === 'document') {
objAttach = {
id: this.emailAttach[element].id,
isLinked: this.emailAttach[element].isLinked,
original: this.emailAttach[element].original
}
} else if (element === 'notes') {
objAttach[element] = this.emailAttach[element].map((item: any) => item.id)
} else {
objAttach[element] = this.emailAttach[element].map((item: any) => {
return {
id: item.id,
original: item.original
}
})
}
let formatSender = {
email: this.currentSender.email,
entityId: !this.functions.empty(this.currentSender.entityId) ? this.currentSender.entityId : null
};

Alex ORLUC
committed

Alex ORLUC
committed
document: objAttach,
sender: formatSender,
recipients: this.recipients.map(recipient => recipient.email),
cc: this.showCopies ? this.copies.map(copy => copy.email) : [],
cci: this.showInvisibleCopies ? this.invisibleCopies.map((invCopy => invCopy.email)) : [],
body: this.htmlMode ? tinymce.get('emailSignature').getContent() : tinymce.get('emailSignature').getContent({ format: 'text' }),

Alex ORLUC
committed
status: this.emailStatus

Alex ORLUC
committed
return data;
isSelectedAttachMail(item: any, type: string) {
if (type === 'document') {
return this.emailAttach.document.isLinked;
} else {
return this.emailAttach[type].filter((attach: any) => attach.id === item.id).length > 0;
}

Alex ORLUC
committed
canManageMail() {
if ((this.data.emailId === null) || (this.emailStatus !== 'SENT' && this.headerService.user.id === this.emailCreatorId)) {
this.recipientsInput.enable();
return true;
} else {
this.recipientsInput.disable();
return false;

Alex ORLUC
committed
}
}
isAllEmailRightFormat() {
let state = true;
const allEmail = this.recipients.concat(this.copies).concat(this.invisibleCopies);
allEmail.map(item => item.email).forEach(email => {
if (this.isBadEmailFormat(email)) {
state = false;
}
});
return state;
}