Skip to content
Snippets Groups Projects
sent-resource-page.component.ts 31 KiB
Newer Older
import { COMMA } from '@angular/cdk/keycodes';
import { Component, OnInit, Inject } from '@angular/core';
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, distinctUntilChanged } from 'rxjs/operators';
import { FunctionsService } from '../../../service/functions.service';
import { CdkDragDrop, transferArrayItem } from '@angular/cdk/drag-drop';
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';
declare function $j(selector: any): any;
    selector: 'app-sent-resource-page',
    templateUrl: "sent-resource-page.component.html",
    styleUrls: ['sent-resource-page.component.scss'],
export class SentResourcePageComponent implements OnInit {
    readonly separatorKeysCodes: number[] = [COMMA];
    availableEmailModels: any[] = [];
    availableSignEmailModels: any[] = [];

    resourceData: any = null;
    availableSenders: any[] = [];
    currentSender: any = {};

    recipients: any[] = [];

    copies: any[] = [];

    invisibleCopies: any[] = [];

    recipientsInput: FormControl = new FormControl();

    emailSignListForm = new FormControl();
    templateEmailListForm = new FormControl();

    filteredEmails: Observable<string[]>;

    showCopies: boolean = false;
    showInvisibleCopies: boolean = false;

    emailCreatorId: number = null;
    emailsubject: string = '';
    emailContent: string = '';
            title: this.lang.attachMainDocument,
            title: this.lang.attachNote,
            title: this.lang.attachAttachment,
    canManage: boolean = false;
    htmlMode: boolean = true;
    constructor(
        public http: HttpClient,
        private notify: NotificationService,
        @Inject(MAT_DIALOG_DATA) public data: any,
        public dialogRef: MatDialogRef<SentResourcePageComponent>,
        public functions: FunctionsService,
        private contactService: ContactService,
        public privilegeService: PrivilegeService,
        public headerService: HeaderService
        Object.keys(this.emailAttachTool).forEach(element => {
            if (element === 'document') {
                this.emailAttach[element] = {
                    isLinked: false,
                    original: false
                };
            } else {
                this.emailAttach[element] = [];
            }
        });
        await this.getAttachElements();
        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);

        if (this.canManageMail()) {
            this.initEmailModelsList();
            this.initEmailsList();
            this.initSignEmailModelsList();

            await this.getResourceData();
            await this.getUserEmails();

            if (this.emailStatus !== 'DRAFT') {
                this.setDefaultInfo();
            }
        }
        //this.loading = false;
        setTimeout(() => {
            this.initMce();
        }, 0);
            base_url: '../../node_modules/tinymce/',
            setup: (editor: any) => {
                editor.on('init', (e: any) => {
                    this.loading = false;
                });
            },
            readonly: this.emailStatus === 'SENT',
            suffix: '.min',
            language: this.lang.langISO.replace('-', '_'),
            language_url: `../../node_modules/tinymce-i18n/langs/${this.lang.langISO.replace('-', '_')}.js`,
            menubar: false,
            statusbar: false,
            plugins: [
            ],
            external_plugins: {
                'maarch_b64image': "../../src/frontend/plugins/tinymce/maarch_b64image/plugin.min.js"
            },
            toolbar_sticky: true,
            toolbar_drawer: 'floating',
            toolbar: this.emailStatus !== 'SENT' ?
                'undo redo | fontselect fontsizeselect | bold italic underline strikethrough forecolor | maarch_b64image | \
            alignleft aligncenter alignright alignjustify \
            bullist numlist outdent indent | removeformat' : false
        const input = event.input;
        const value = event.value;

        if ((value || '').trim()) {
                    email: value.trim(),
                    badFormat: this.isBadEmailFormat(value.trim())
    isBadEmailFormat(email: string) {
        const regex = /^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$/g;

    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({
    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');

                div.innerHTML = tinymce.get('emailSignature').getContent();

                if (div.getElementsByClassName('signature').length > 0) {

                    const signatureContent = div.getElementsByClassName('signature')[0].innerHTML;

                    div.getElementsByClassName('signature')[0].remove();

                    tinymce.get('emailSignature').setContent(`${div.innerHTML}${data.mergedDocument}<div class="signature">${signatureContent}</div>`);
                    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();
    }

    mergeSignEmailTemplate(templateId: any) {

        this.emailSignListForm.reset();

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

                div.innerHTML = tinymce.get('emailSignature').getContent();

                if (div.getElementsByClassName('signature').length > 0) {

                    div.getElementsByClassName('signature')[0].remove();

                    tinymce.get('emailSignature').setContent(`${div.innerHTML}<div class="signature">${data.emailSignature.content}</div>`);
                    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();
    }

        if (this.canManageMail()) {
            const index = this[type].indexOf(item);
            if (index >= 0) {
                this[type].splice(index, 1);
            }
    getEmailData(emailId: number) {
        return new Promise((resolve) => {
            this.http.get(`../../rest/emails/${emailId}`).pipe(
                tap((data: any) => {
                    this.emailCreatorId = data.userId;
                    this.recipients = data.recipients.map((item: any) => {
                        return {
                            label: item,
                            badFormat: this.isBadEmailFormat(item)
                        }
                    });
                    this.copies = data.cc.map((item: any) => {
                        return {
                            label: item,
                            badFormat: this.isBadEmailFormat(item)
                    this.invisibleCopies = data.cci.map((item: any) => {
                        return {
                            label: 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;

                        entityId: data.sender.entityId,
                        label: data.sender.label,
                        email: data.sender.email
                    };
                    Object.keys(data.document).forEach(element => {
                        if (['id', 'isLinked', 'original'].indexOf(element) === -1) {
                            this.emailAttach[element] = [];
                            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] = this.emailAttach[element].concat(elem.map((item: any) => {
                                            format: dataAttach.original || dataAttach.original === undefined ? item.format : 'pdf',
                                            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.format = data.document.original || data.document.original === undefined ? this.emailAttachTool.document.list[0].format : 'pdf',
                            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
                    };
                    this.recipients = [{
                        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.withoutEmail
                    }];

                    this.emailStatus = 'SENT';
                }),
                exhaustMap(() => this.http.get(`../../rest/acknowledgementReceipts/${emailId}/content`)),
                tap((data: any) => {
                    this.pdfMode = data.format === 'pdf';

                    if (this.pdfMode) {
                        this.emailsubject = this.lang.ARPaper;
                        this.emailContent = data.encodedDocument;
                    } else {
                        this.emailsubject = this.lang.ARelectronic;
                        this.emailContent = this.b64DecodeUnicode(data.encodedDocument);
                    resolve(true);
                }),
                catchError((err) => {
                    this.notify.handleSoftErrors(err);
                    resolve(false);
                    return of(false);
                })
            ).subscribe();
        });
    }

    getResourceData() {
        return new Promise((resolve) => {
            this.http.get(`../../rest/resources/${this.data.resId}?light=true`).pipe(
                tap((data: any) => {
                    this.resourceData = data;
                    this.emailAttach.document.chrono = this.resourceData.chrono;
                    this.emailAttach.document.label = this.resourceData.subject;
                    resolve(true);
                }),
                catchError((err) => {
                    this.notify.handleSoftErrors(err);
                    resolve(false);
                    return of(false);
                })
            ).subscribe();
        });
    setDefaultInfo() {
        this.emailsubject = `[${this.resourceData.chrono}] ${this.resourceData.subject}`;
        this.emailsubject = this.emailsubject.substring(0, 70);
        this.currentSender = this.availableSenders[0];
        if (!this.functions.empty(this.resourceData.senders)) {
            this.resourceData.senders.forEach((sender: any) => {
                this.setSender(sender.id);
            });
        }
    }

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

    getUserEmails() {
        return new Promise((resolve) => {
            this.http.get('../../rest/currentUser/availableEmails').pipe(
                tap((data: any) => {
                    this.availableSenders = data.emails;
                    resolve(true);
                }),
                catchError((err) => {
                    this.notify.handleSoftErrors(err);
                    resolve(false);
                    return of(false);
                })
            ).subscribe();
        });
    getAttachElements() {
        return new Promise((resolve) => {
            this.http.get(`../../rest/resources/${this.data.resId}/emailsInitialization`).pipe(
                        if (element === 'resource') {
                            this.emailAttachTool.document.list = [];
                            if (!this.functions.empty(data[element])) {
                                this.emailAttachTool.document.list = [data[element]];
                            }
                        } else {
                            this.emailAttachTool[element].list = data[element].map((item: any) => {
                                if (item.attachInMail) {
                                    this.toggleAttachMail(item, element, 'original');
                                }                                
                                    original: item.original !== undefined ? item.original : true,
                                    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);
                })
    initEmailsList() {
        this.recipientsInput.valueChanges.pipe(
            filter(value => value !== null),
            tap((value) => {
                if (value.length === 0) {
                    this.filteredEmails = of([]);
                }
            }),
            distinctUntilChanged(),
            switchMap(data => this.http.get('../../rest/autocomplete/correspondents', { params: { "search": data, "searchEmails": 'true' } })),
                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);
                this.notify.handleSoftErrors(err);
        ).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([]);
    }

        if (this.data.emailId === null) {
            if (!this.isAllEmailRightFormat()) {
                this.notify.error(this.lang.badEmailsFormat);
                if (this.emailsubject === '') {
                    const dialogRef = this.dialog.open(ConfirmComponent, { panelClass: 'maarch-modal', autoFocus: false, disableClose: true, data: { title: this.lang.confirm, msg: this.lang.warnEmptySubject } });
                    dialogRef.afterClosed().pipe(
                        filter((data: string) => data === 'ok'),
                        tap(() => {
    createEmail(closeModal: boolean = true) {
        this.http.post(`../../rest/emails`, this.formatEmail()).pipe(
                    // this.notify.success(this.lang.draftSaved);
                    this.notify.success(`${this.lang.sendingEmail}...`);
                }

                if (closeModal) {
                    this.closeModal('success');
                }

            }),
            catchError((err) => {
                this.notify.handleSoftErrors(err);
                return of(false);
            })
        ).subscribe();
    }

    deleteEmail() {
        const dialogRef = this.dialog.open(ConfirmComponent, { panelClass: 'maarch-modal', 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(
                    // this.notify.success(this.lang.draftUpdated);
                    this.notify.success(`${this.lang.sendingEmail}...`);
            }),
            catchError((err) => {
                this.notify.handleSoftErrors(err);
                return of(false);
            })
Alex ORLUC's avatar
Alex ORLUC committed
        ).subscribe();
        if (this.canManageMail()) {
            this.emailStatus = 'DRAFT';
            if (this.data.emailId === null) {
                if (!this.functions.empty(tinymce.get('emailSignature').getContent())) {
                    this.createEmail(true);
                } else {
                    this.closeModal();
                }
            } else {
                this.updateEmail(true);
            }
    drop(event: CdkDragDrop<string[]>) {

        if (event.previousContainer !== event.container) {
            transferArrayItem(event.previousContainer.data,
                event.container.data,
                event.previousIndex,
                event.currentIndex);
        }

    toggleAttachMail(item: any, type: string, mode: string) {
            if (this.emailAttach.document.isLinked === false) {
                this.emailAttach.document.isLinked = true;
                this.emailAttach.document.format = mode !== 'pdf' ? item.format : 'pdf',
                this.emailAttach.document.original = mode !== 'pdf';
                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({
                    ...item,
                    format: mode !== 'pdf' ? item.format : 'pdf',
                    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);
        this.htmlMode = !this.htmlMode;
        if (this.htmlMode) {
            tinymce.get('emailSignature').setContent(tinymce.get('emailSignature').getContent());
        } else {
            const dialogRef = this.dialog.open(ConfirmComponent, { panelClass: 'maarch-modal', 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();
        Object.keys(this.emailAttach).forEach(element => {
            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
        };
            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)) : [],
            object: this.emailsubject,
            body: this.htmlMode ? tinymce.get('emailSignature').getContent() : tinymce.get('emailSignature').getContent({ format: 'text' }),
    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;
        }
    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;
        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;
    }

    compareSenders(sender1: any, sender2: any) {
        return (sender1.label === sender2.label || ((sender1.label === null || sender2.label === null) && (sender1.entityId === null || sender2.entityId === null))) && sender1.entityId === sender2.entityId && sender1.email === sender2.email;
    }


    b64DecodeUnicode(str: string) {
        // Going backwards: from bytestream, to percent-encoding, to original string.
        return decodeURIComponent(atob(str).split('').map(function(c) {
            return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
        }).join(''));
    }