import { Component, OnInit, ViewChild, ViewContainerRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../translate.component'; import { NotificationService } from '../notification.service'; import { MatDialog } from '@angular/material/dialog'; import { MatSidenav } from '@angular/material/sidenav'; import { ActivatedRoute, Router, ParamMap } from '@angular/router'; import { HeaderService } from '../../service/header.service'; import { FiltersListService } from '../../service/filtersList.service'; import { Overlay } from '@angular/cdk/overlay'; import { AppService } from '../../service/app.service'; import { ActionsService } from '../actions/actions.service'; import { tap, catchError, map, finalize, filter } from 'rxjs/operators'; import { of, Subscription } from 'rxjs'; import { DocumentViewerComponent } from '../viewer/document-viewer.component'; import { IndexingFormComponent } from '../indexation/indexing-form/indexing-form.component'; import { ConfirmComponent } from '../../plugins/modal/confirm.component'; import { ContactsListModalComponent } from '../contact/list/modal/contacts-list-modal.component'; import { DiffusionsListComponent } from '../diffusions/diffusions-list.component'; import { ContactService } from '../../service/contact.service'; import { VisaWorkflowComponent } from '../visa/visa-workflow.component'; import { PrivilegeService } from '../../service/privileges.service'; import { AvisWorkflowComponent } from '../avis/avis-workflow.component'; import { FunctionsService } from '../../service/functions.service'; import { PrintedFolderModalComponent } from '../printedFolder/printed-folder-modal.component'; @Component({ templateUrl: "process.component.html", styleUrls: [ 'process.component.scss', '../indexation/indexing-form/indexing-form.component.scss' ], providers: [NotificationService, AppService, ActionsService, ContactService], }) export class ProcessComponent implements OnInit { lang: any = LANG; loading: boolean = false; detailMode: boolean = false; navButton: any = null; isMailing: boolean = false; currentResourceLock: any = null; actionsList: any[] = []; currentUserId: number = null; currentBasketId: number = null; currentGroupId: number = null; selectedAction: any = { id: 0, label: '', component: '', default: false, categoryUse: [] }; currentResourceInformations: any = {}; processTool: any[] = [ { id: 'dashboard', icon: 'fas fa-columns', label: this.lang.newsFeed, count: 0 }, { id: 'history', icon: 'fas fa-history', label: this.lang.history, count: 0 }, { id: 'notes', icon: 'fas fa-pen-square', label: this.lang.notesAlt, count: 0 }, { id: 'attachments', icon: 'fas fa-paperclip', label: this.lang.attachments, count: 0 }, { id: 'linkedResources', icon: 'fas fa-link', label: this.lang.links, count: 0 }, { id: 'diffusionList', icon: 'fas fa-share-alt', label: this.lang.diffusionList, editMode: false, count: 0 }, { id: 'emails', icon: 'fas fa-envelope', label: this.lang.mailsSentAlt, count: 0 }, { id: 'visaCircuit', icon: 'fas fa-list-ol', label: this.lang.visaWorkflow, count: 0 }, { id: 'opinionCircuit', icon: 'fas fa-comment-alt', label: this.lang.avis, count: 0 }, { id: 'info', icon: 'fas fa-info-circle', label: this.lang.informations, count: 0 } ]; modalModule: any[] = []; currentTool: string = 'dashboard'; subscription: Subscription; actionEnded: boolean = false; canEditData: boolean = false; autoAction: boolean = false; integrationsInfo: any = { inSignatureBook: { icon: 'fas fa-file-signature', } }; @ViewChild('snav', { static: true }) sidenavLeft: MatSidenav; @ViewChild('snav2', { static: true }) sidenavRight: MatSidenav; @ViewChild('appDocumentViewer', { static: true }) appDocumentViewer: DocumentViewerComponent; @ViewChild('indexingForm', { static: false }) indexingForm: IndexingFormComponent; @ViewChild('appDiffusionsList', { static: false }) appDiffusionsList: DiffusionsListComponent; @ViewChild('appVisaWorkflow', { static: false }) appVisaWorkflow: VisaWorkflowComponent; @ViewChild('appAvisWorkflow', { static: false }) appAvisWorkflow: AvisWorkflowComponent; senderLightInfo: any = { 'displayName': null, 'fillingRate': null }; hasContact: boolean = false; resourceFollowed: boolean = false; constructor( private route: ActivatedRoute, private _activatedRoute: ActivatedRoute, public http: HttpClient, public dialog: MatDialog, private headerService: HeaderService, public filtersListService: FiltersListService, private notify: NotificationService, public overlay: Overlay, public viewContainerRef: ViewContainerRef, public appService: AppService, public actionService: ActionsService, private contactService: ContactService, private router: Router, public privilegeService: PrivilegeService, public functions: FunctionsService ) { // Event after process action this.subscription = this.actionService.catchAction().subscribe(message => { this.actionEnded = true; clearInterval(this.currentResourceLock); this.router.navigate([`/basketList/users/${this.currentUserId}/groups/${this.currentGroupId}/baskets/${this.currentBasketId}`]); }); } ngOnInit(): void { this.loading = true; this.headerService.setHeader(this.lang.eventProcessDoc); this.route.params.subscribe(params => { if (typeof params['detailResId'] !== "undefined") { this.initDetailPage(params); } else { this.initProcessPage(params); } }, (err: any) => { this.notify.handleErrors(err); }); } initProcessPage(params: any) { this.detailMode = false; this.currentUserId = params['userSerialId']; this.currentGroupId = params['groupSerialId']; this.currentBasketId = params['basketId']; this.currentResourceInformations = { resId: params['resId'], mailtracking: false }; this.navButton = { icon: 'fa fa-inbox', label: this.lang.backBasket, route: `/basketList/users/${this.currentUserId}/groups/${this.currentGroupId}/baskets/${this.currentBasketId}` } this.lockResource(); this.loadBadges(); this.loadResource(); if (this.appService.getViewMode()) { setTimeout(() => { this.sidenavLeft.open(); }, 800); } this.http.get(`../../rest/resourcesList/users/${this.currentUserId}/groups/${this.currentGroupId}/baskets/${this.currentBasketId}/actions?resId=${this.currentResourceInformations.resId}`).pipe( map((data: any) => { data.actions = data.actions.map((action: any, index: number) => { return { id: action.id, label: action.label, component: action.component, categoryUse: action.categories } }); return data; }), tap((data: any) => { this.selectedAction = data.actions[0]; this.actionsList = data.actions; }), catchError((err: any) => { this.notify.handleErrors(err); return of(false); }) ).subscribe(); } initDetailPage(params: any) { this._activatedRoute.queryParamMap.subscribe((paramMap: ParamMap) => { this.isMailing = !this.functions.empty(paramMap.get('isMailing')) ; }); console.log(this.isMailing); this.detailMode = true; this.currentResourceInformations = { resId: params['detailResId'], mailtracking: false }; this.navButton = { icon: 'fas fa-arrow-left', label: this.lang.back, route: `__GOBACK` } this.loadBadges(); this.loadResource(); if (this.appService.getViewMode()) { setTimeout(() => { this.sidenavLeft.open(); }, 800); } } isActionEnded() { return this.actionEnded; } loadResource() { this.http.get(`../../rest/resources/${this.currentResourceInformations.resId}?light=true`).pipe( tap((data: any) => { this.currentResourceInformations = data; this.resourceFollowed = data.followed; this.loadSenders(); this.setEditDataPrivilege(); this.loadAvaibleIntegrations(data.integrations); this.headerService.setHeader(this.detailMode ? this.lang.detailDoc : this.lang.eventProcessDoc, this.lang[this.currentResourceInformations.categoryId]); }), finalize(() => this.loading = false), catchError((err: any) => { this.notify.handleErrors(err); return of(false); }) ).subscribe(); } setEditDataPrivilege() { if (this.detailMode) { this.canEditData = this.privilegeService.hasCurrentUserPrivilege('edit_resource') && this.currentResourceInformations.statusAlterable; if (this.isMailing && this.isToolEnabled('attachments')) { this.currentTool = 'attachments'; } } else { this.http.get(`../../rest/resources/${this.currentResourceInformations.resId}/users/${this.currentUserId}/groups/${this.currentGroupId}/baskets/${this.currentBasketId}/processingData`).pipe( tap((data: any) => { if (data.listEventData !== null) { if (this.isToolEnabled(data.listEventData.defaultTab)) { this.currentTool = data.listEventData.defaultTab; } this.canEditData = data.listEventData.canUpdate; } }), catchError((err: any) => { this.notify.handleErrors(err); return of(false); }) ).subscribe(); } } loadAvaibleIntegrations(integrationsData: any) { this.integrationsInfo['inSignatureBook'].enable = !this.functions.empty(integrationsData['inSignatureBook']) ? integrationsData['inSignatureBook'] : false; this.http.get(`../../rest/externalConnectionsEnabled`).pipe( tap((data: any) => { Object.keys(data.connection).filter(connectionId => connectionId !== 'maarchParapheur').forEach(connectionId => { if (connectionId === 'maileva') { this.integrationsInfo['inShipping'] = { icon: 'fas fa-shipping-fast' } } }); }), catchError((err: any) => { this.notify.handleSoftErrors(err); return of(false); }) ).subscribe(); } toggleIntegration(integrationId: string) { this.http.put(`../../rest/resourcesList/integrations`, { resources: [this.currentResourceInformations.resId], integrations: { [integrationId]: !this.currentResourceInformations.integrations[integrationId] } }).pipe( tap(() => { this.currentResourceInformations.integrations[integrationId] = !this.currentResourceInformations.integrations[integrationId]; this.notify.success(this.lang.actionDone); }), catchError((err: any) => { this.notify.handleSoftErrors(err); return of(false); }) ).subscribe(); } loadBadges() { this.http.get(`../../rest/resources/${this.currentResourceInformations.resId}/items`).pipe( tap((data: any) => { this.processTool.forEach(element => { element.count = data[element.id] !== undefined ? data[element.id] : 0; }); }), catchError((err: any) => { this.notify.handleSoftErrors(err); return of(false); }) ).subscribe(); } loadSenders() { if (this.currentResourceInformations.senders === undefined || this.currentResourceInformations.senders.length === 0) { this.hasContact = false; this.senderLightInfo = { 'displayName': this.lang.noSelectedContact, 'filling': null }; } else if (this.currentResourceInformations.senders.length == 1) { this.hasContact = true; if (this.currentResourceInformations.senders[0].type === 'contact') { this.http.get('../../rest/contacts/' + this.currentResourceInformations.senders[0].id).pipe( tap((data: any) => { const arrInfo = []; if (this.empty(data.firstname) && this.empty(data.lastname)) { if (!this.functions.empty(data.fillingRate)) { this.senderLightInfo = { 'displayName': data.company, 'filling': this.contactService.getFillingColor(data.fillingRate.thresholdLevel) }; } else { this.senderLightInfo = { 'displayName': data.company }; } } else { arrInfo.push(data.firstname); arrInfo.push(data.lastname); if (!this.empty(data.company)) { arrInfo.push('(' + data.company + ')'); } if (!this.functions.empty(data.fillingRate)) { this.senderLightInfo = { 'displayName': arrInfo.filter(info => info !== '').join(' '), 'filling': this.contactService.getFillingColor(data.fillingRate.thresholdLevel) }; } else { this.senderLightInfo = { 'displayName': arrInfo.filter(info => info !== '').join(' ') }; } } }) ).subscribe(); } else if (this.currentResourceInformations.senders[0].type == 'entity') { this.http.get('../../rest/entities/' + this.currentResourceInformations.senders[0].id).pipe( tap((data: any) => { this.senderLightInfo = { 'displayName': data.entity_label, 'filling': null }; }) ).subscribe(); } else if (this.currentResourceInformations.senders[0].type == 'user') { this.http.get('../../rest/users/' + this.currentResourceInformations.senders[0].id).pipe( tap((data: any) => { this.senderLightInfo = { 'displayName': data.firstname + ' ' + data.lastname, 'filling': null }; }) ).subscribe(); } } else if (this.currentResourceInformations.senders.length > 1) { this.hasContact = true; this.senderLightInfo = { 'displayName': this.currentResourceInformations.senders.length + ' ' + this.lang.senders, 'filling': null }; } } lockResource() { this.http.put(`../../rest/resourcesList/users/${this.currentUserId}/groups/${this.currentGroupId}/baskets/${this.currentBasketId}/lock`, { resources: [this.currentResourceInformations.resId] }).pipe( catchError((err: any) => { this.notify.handleErrors(err); return of(false); }) ).subscribe(); this.currentResourceLock = setInterval(() => { this.http.put(`../../rest/resourcesList/users/${this.currentUserId}/groups/${this.currentGroupId}/baskets/${this.currentBasketId}/lock`, { resources: [this.currentResourceInformations.resId] }).pipe( catchError((err: any) => { this.notify.handleErrors(err); return of(false); }) ).subscribe(); }, 50000); } unlockResource() { clearInterval(this.currentResourceLock); this.http.put(`../../rest/resourcesList/users/${this.currentUserId}/groups/${this.currentGroupId}/baskets/${this.currentBasketId}/unlock`, { resources: [this.currentResourceInformations.resId] }).pipe( catchError((err: any) => { this.notify.handleErrors(err); return of(false); }) ).subscribe(); } onSubmit() { if (this.currentTool === 'info' || this.isModalOpen('info')) { this.processAction(); } else { if (this.isToolModified()) { const dialogRef = this.openConfirmModification(); dialogRef.afterClosed().pipe( filter((data: string) => data === 'ok'), tap(() => { this.saveTool(); }), finalize(() => { this.autoAction = true; this.currentTool = 'info'; }), catchError((err: any) => { this.notify.handleErrors(err); return of(false); }) ).subscribe(); } else { this.autoAction = true; this.currentTool = 'info'; } } } triggerProcessAction() { if (this.autoAction) { this.processAction(); this.autoAction = !this.autoAction; } } processAction() { if (this.indexingForm.isValidForm()) { if (this.isToolModified()) { const dialogRef = this.openConfirmModification(); dialogRef.afterClosed().pipe( tap((data: string) => { if (data !== 'ok') { this.refreshTool(); } }), filter((data: string) => data === 'ok'), tap(() => { this.saveTool(); }), finalize(() => this.actionService.launchAction(this.selectedAction, this.currentUserId, this.currentGroupId, this.currentBasketId, [this.currentResourceInformations.resId], this.currentResourceInformations, false)), catchError((err: any) => { this.notify.handleErrors(err); return of(false); }) ).subscribe(); } else { this.actionService.launchAction(this.selectedAction, this.currentUserId, this.currentGroupId, this.currentBasketId, [this.currentResourceInformations.resId], this.currentResourceInformations, false); } } else { this.notify.error(this.lang.mustFixErrors); } } showActionInCurrentCategory(action: any) { if (this.selectedAction.categoryUse.indexOf(this.currentResourceInformations.categoryId) === -1) { const newAction = this.actionsList.filter(action => action.categoryUse.indexOf(this.currentResourceInformations.categoryId) > -1)[0]; if (newAction !== undefined) { this.selectedAction = this.actionsList.filter(action => action.categoryUse.indexOf(this.currentResourceInformations.categoryId) > -1)[0]; } else { this.selectedAction = { id: 0, label: '', component: '', default: false, categoryUse: [] }; } } return action.categoryUse.indexOf(this.currentResourceInformations.categoryId) > -1; } selectAction(action: any) { this.selectedAction = action; } createModal() { this.modalModule.push(this.processTool.filter(module => module.id === this.currentTool)[0]); } removeModal(index: number) { if (this.modalModule[index].id === 'info' && this.indexingForm.isResourceModified()) { const dialogRef = this.openConfirmModification(); dialogRef.afterClosed().pipe( tap((data: string) => { if (data !== 'ok') { this.modalModule.splice(index, 1); } }), filter((data: string) => data === 'ok'), tap(() => { this.indexingForm.saveData(); setTimeout(() => { this.loadResource(); }, 400); this.modalModule.splice(index, 1); }), catchError((err: any) => { this.notify.handleErrors(err); return of(false); }) ).subscribe(); } else { this.modalModule.splice(index, 1); } } isModalOpen(tool = this.currentTool) { return this.modalModule.map(module => module.id).indexOf(tool) > -1; } ngOnDestroy() { // unsubscribe to ensure no memory leaks this.subscription.unsubscribe(); } changeTab(tabId: string) { if (this.isToolModified() && !this.isModalOpen()) { const dialogRef = this.openConfirmModification(); dialogRef.afterClosed().pipe( tap((data: string) => { if (data !== 'ok') { this.currentTool = tabId; } }), filter((data: string) => data === 'ok'), tap(() => { this.saveTool(); setTimeout(() => { this.loadResource(); }, 400); this.currentTool = tabId; }), catchError((err: any) => { this.notify.handleErrors(err); return of(false); }) ).subscribe(); } else { this.currentTool = tabId; } } openConfirmModification() { return this.dialog.open(ConfirmComponent, { autoFocus: false, disableClose: true, data: { title: this.lang.confirm, msg: this.lang.saveModifiedData, buttonValidate: this.lang.yes, buttonCancel: this.lang.no } }); } confirmModification() { this.indexingForm.saveData(); setTimeout(() => { this.loadResource(); }, 400); } refreshBadge(nbRres: any, id: string) { this.processTool.filter(tool => tool.id === id)[0].count = nbRres; } openContact() { if (this.hasContact) { this.dialog.open(ContactsListModalComponent, { data: { title: `${this.currentResourceInformations.chrono} - ${this.currentResourceInformations.subject}`, mode: 'senders', resId: this.currentResourceInformations.resId } }); } } saveListinstance() { this.appDiffusionsList.saveListinstance(); } saveVisaWorkflow() { this.appVisaWorkflow.saveVisaWorkflow(); } isToolModified() { if (this.currentTool === 'info' && this.indexingForm !== undefined && this.indexingForm.isResourceModified()) { return true; } else if (this.currentTool === 'diffusionList' && this.appDiffusionsList !== undefined && this.appDiffusionsList.isModified()) { return true; } else if (this.currentTool === 'visaCircuit' && this.appVisaWorkflow !== undefined && this.appVisaWorkflow.isModified()) { return true; } else if (this.currentTool === 'opinionCircuit' && this.appAvisWorkflow !== undefined && this.appAvisWorkflow.isModified()) { return true; } else { return false; } } refreshTool() { const tmpTool = this.currentTool; this.currentTool = ''; setTimeout(() => { this.currentTool = tmpTool; }, 0); } async saveTool() { if (this.currentTool === 'info' && this.indexingForm !== undefined) { await this.indexingForm.saveData(); this.loadBadges(); } else if (this.currentTool === 'diffusionList' && this.appDiffusionsList !== undefined) { await this.appDiffusionsList.saveListinstance(); this.loadBadges(); } else if (this.currentTool === 'visaCircuit' && this.appVisaWorkflow !== undefined) { await this.appVisaWorkflow.saveVisaWorkflow(); this.loadBadges(); } else if (this.currentTool === 'opinionCircuit' && this.appAvisWorkflow !== undefined) { await this.appAvisWorkflow.saveAvisWorkflow(); this.loadBadges(); } } empty(value: string) { if (value === null || value === undefined) { return true; } else if (Array.isArray(value)) { if (value.length > 0) { return false; } else { return true; } } else if (String(value) !== '') { return false; } else { return true; } } toggleFollow() { this.resourceFollowed = !this.resourceFollowed; if (this.resourceFollowed) { this.http.post('../../rest/resources/follow', { resources: [this.currentResourceInformations.resId] }).pipe( catchError((err: any) => { this.notify.handleErrors(err); return of(false); }) ).subscribe(); } else { this.http.request('DELETE', '../../rest/resources/unfollow', { body: { resources: [this.currentResourceInformations.resId] } }).pipe( catchError((err: any) => { this.notify.handleErrors(err); return of(false); }) ).subscribe(); } } isToolEnabled(id: string) { if (id === 'history') { if (!this.privilegeService.hasCurrentUserPrivilege('view_full_history') && !this.privilegeService.hasCurrentUserPrivilege('view_doc_history')) { return false } else { return true; } } else { return true; } } openPrintedFolderPrompt() { this.dialog.open(PrintedFolderModalComponent, { data: { resId: this.currentResourceInformations.resId } }); } }