diff --git a/migration/20.03/migrateCustomValues.php b/migration/20.03/migrateCustomValues.php index 1fe3fc1af85b4d0cffbdf39c0ae3ed85e3332d6f..6f39176284ab03c4b3b7e1ae805ef14ccea553e1 100644 --- a/migration/20.03/migrateCustomValues.php +++ b/migration/20.03/migrateCustomValues.php @@ -49,6 +49,9 @@ foreach ($customs as $custom) { ]); $csColumn = "custom_fields->>''{$fieldId}''"; + if ($type == 'date') { + $csColumn = "($csColumn)::date"; + } \Basket\models\BasketModel::update(['postSet' => ['basket_clause' => "REPLACE(basket_clause, '{$migration['id']}', '{$csColumn}')"], 'where' => ['1 = ?'], 'data' => [1]]); foreach ($migration['modelId'] as $modelId) { diff --git a/sql/data_fr.sql b/sql/data_fr.sql index 6d5dbce664040f9199d63afb8d44e4a33af6d095..cd0713f8fba395e39151b777f1b9e9174ddedb2e 100755 --- a/sql/data_fr.sql +++ b/sql/data_fr.sql @@ -1270,7 +1270,7 @@ INSERT INTO tags (label) VALUES ('SPORT'); --TEMPLATES ------------ TRUNCATE TABLE templates; -INSERT INTO templates (template_id, template_label, template_comment, template_content, template_type, template_path, template_file_name, template_style, template_datasource, template_target, template_attachment_type) VALUES (3, 'Appel téléphonique', 'Appel Téléphonique', '', 'OFFICE', '0000#', 'appel_telephonique.docx', 'ODT: invitation', 'letterbox_attachment', 'indexingFile', 'all'); +--INSERT INTO templates (template_id, template_label, template_comment, template_content, template_type, template_path, template_file_name, template_style, template_datasource, template_target, template_attachment_type) VALUES (3, 'Appel téléphonique', 'Appel Téléphonique', '', 'OFFICE', '0000#', 'appel_telephonique.docx', 'ODT: invitation', 'letterbox_attachment', 'indexingFile', 'all'); INSERT INTO templates (template_id, template_label, template_comment, template_content, template_type, template_path, template_file_name, template_style, template_datasource, template_target, template_attachment_type) VALUES (2, '[notification] Notifications événement', 'Notifications des événements système', '<p><font face="verdana,geneva" size="1">Bonjour [recipient.firstname] [recipient.lastname],</font></p> <p><font face="verdana,geneva" size="1"> </font></p> <p><font face="verdana,geneva" size="1">Voici la liste des événements de l''application qui vous sont notifiés ([notification.description]) :</font></p> diff --git a/src/app/action/controllers/AcknowledgementReceiptTrait.php b/src/app/action/controllers/AcknowledgementReceiptTrait.php index 69f1a0482d12ba929cd172c492b44311987536d8..193ad93d6b5396bbbfa0edf542a39299324aeb51 100644 --- a/src/app/action/controllers/AcknowledgementReceiptTrait.php +++ b/src/app/action/controllers/AcknowledgementReceiptTrait.php @@ -21,6 +21,7 @@ use Docserver\models\DocserverModel; use Doctype\models\DoctypeModel; use Email\controllers\EmailController; use Entity\models\EntityModel; +use Group\controllers\PrivilegeController; use Resource\models\ResModel; use Resource\models\ResourceContactModel; use SrcCore\models\DatabaseModel; @@ -179,11 +180,25 @@ trait AcknowledgementReceiptTrait if (!empty($emailsToSend) && !empty($resource['destination'])) { $entity = EntityModel::getByEntityId(['entityId' => $resource['destination'], 'select' => ['email', 'id']]); } + + if (empty($entity['email']) || !PrivilegeController::hasPrivilege(['privilegeId' => 'use_mail_services', 'userId' => $currentUser['id']])) { + $emailSender = ['email' => $currentUser['mail']]; + } else { + $availableEmails = EmailController::getAvailableEmailsByUserId(['userId' => $currentUser['id']]); + $entities = array_column($availableEmails, 'entityId'); + + if (!in_array( $entity['id'], $entities)) { + $emailSender = ['email' => $currentUser['mail']]; + } else { + $emailSender = ['email' => $entity['email'], 'entityId' => $entity['id']]; + } + } + foreach ($emailsToSend as $email) { $isSent = EmailController::createEmail([ 'userId' => $currentUser['id'], 'data' => [ - 'sender' => empty($entity['email']) ? ['email' => $currentUser['mail']] : ['email' => $entity['email'], 'entityId' => $entity['id']], + 'sender' => $emailSender, 'recipients' => [$email['email']], 'object' => '[AR] ' . substr($subjectToSend, 0, 100), 'body' => base64_decode($email['encodedHtml']), diff --git a/src/app/attachment/controllers/AttachmentController.php b/src/app/attachment/controllers/AttachmentController.php index 486dd516404500ea8da8feb3431afd34f58fcd30..771a33ac87d9b4181d3c097f5a8eed8f55a044cf 100755 --- a/src/app/attachment/controllers/AttachmentController.php +++ b/src/app/attachment/controllers/AttachmentController.php @@ -75,7 +75,7 @@ class AttachmentController 'tableName' => 'res_letterbox', 'recordId' => $body['resIdMaster'], 'eventType' => 'ADD', - 'info' => _ATTACHMENT_ADDED . " : {$id}", + 'info' => _ATTACHMENT_ADDED . " : {$body['title']}", 'moduleId' => 'attachment', 'eventId' => 'attachmentAdd' ]); @@ -210,7 +210,7 @@ class AttachmentController 'tableName' => 'res_letterbox', 'recordId' => $attachment['res_id_master'], 'eventType' => 'UP', - 'info' => _ATTACHMENT_UPDATED . " : {$args['id']}", + 'info' => _ATTACHMENT_UPDATED . " : {$body['title']}", 'moduleId' => 'attachment', 'eventId' => 'attachmentModification' ]); @@ -253,6 +253,15 @@ class AttachmentController 'eventId' => 'attachmentSuppression', ]); + HistoryController::add([ + 'tableName' => 'res_letterbox', + 'recordId' => $attachment['res_id_master'], + 'eventType' => 'DEL', + 'info' => _ATTACHMENT_DELETED . " : {$attachment['title']}", + 'moduleId' => 'attachment', + 'eventId' => 'attachmentAdd' + ]); + return $response->withStatus(204); } @@ -321,7 +330,7 @@ class AttachmentController public function setInSignatureBook(Request $request, Response $response, array $aArgs) { - $attachment = AttachmentModel::getById(['id' => $aArgs['id'], 'select' => ['in_signature_book', 'res_id_master']]); + $attachment = AttachmentModel::getById(['id' => $aArgs['id'], 'select' => ['in_signature_book', 'res_id_master', 'title']]); if (empty($attachment)) { return $response->withStatus(400)->withJson(['errors' => 'Attachment not found']); } @@ -332,12 +341,30 @@ class AttachmentController AttachmentModel::setInSignatureBook(['id' => $aArgs['id'], 'inSignatureBook' => !$attachment['in_signature_book']]); + $info = $attachment['in_signature_book'] ? _ATTACH_REMOVE_FROM_SIGNATORY_BOOK : _ATTACH_ADD_TO_SIGNATORY_BOOK; + HistoryController::add([ + 'tableName' => 'res_attachments', + 'recordId' => $aArgs['id'], + 'eventType' => 'UP', + 'info' => $info . " : {$attachment['title']}", + 'moduleId' => 'attachment', + 'eventId' => 'attachmentModification', + ]); + HistoryController::add([ + 'tableName' => 'res_letterbox', + 'recordId' => $attachment['res_id_master'], + 'eventType' => 'UP', + 'info' => $info . " : " . $attachment['title'], + 'moduleId' => 'resource', + 'eventId' => 'resourceModification', + ]); + return $response->withJson(['success' => 'success']); } public function setInSendAttachment(Request $request, Response $response, array $aArgs) { - $attachment = AttachmentModel::getById(['id' => $aArgs['id'], 'select' => ['in_send_attach', 'res_id_master']]); + $attachment = AttachmentModel::getById(['id' => $aArgs['id'], 'select' => ['in_send_attach', 'res_id_master', 'title']]); if (empty($attachment)) { return $response->withStatus(400)->withJson(['errors' => 'Attachment not found']); } @@ -348,6 +375,24 @@ class AttachmentController AttachmentModel::setInSendAttachment(['id' => $aArgs['id'], 'inSendAttachment' => !$attachment['in_send_attach']]); + $info = $attachment['in_send_attach'] ? _ATTACH_REMOVE_FROM_SHIPPING : _ATTACH_ADD_TO_SHIPPING; + HistoryController::add([ + 'tableName' => 'res_attachments', + 'recordId' => $aArgs['id'], + 'eventType' => 'UP', + 'info' => $info . " : {$attachment['title']}", + 'moduleId' => 'attachment', + 'eventId' => 'attachmentModification', + ]); + HistoryController::add([ + 'tableName' => 'res_letterbox', + 'recordId' => $attachment['res_id_master'], + 'eventType' => 'UP', + 'info' => $info . " : " . $attachment['title'], + 'moduleId' => 'resource', + 'eventId' => 'resourceModification', + ]); + return $response->withJson(['success' => 'success']); } @@ -420,7 +465,7 @@ class AttachmentController } $attachment = AttachmentModel::get([ - 'select' => ['res_id', 'docserver_id', 'res_id_master', 'format'], + 'select' => ['res_id', 'docserver_id', 'res_id_master', 'format', 'title'], 'where' => ['res_id = ?', 'status not in (?)'], 'data' => [$args['id'], ['DEL']], 'limit' => 1 @@ -469,10 +514,19 @@ class AttachmentController 'recordId' => $args['id'], 'eventType' => 'VIEW', 'info' => _ATTACH_DISPLAYING . " : {$args['id']}", - 'moduleId' => 'attachments', + 'moduleId' => 'attachment', 'eventId' => 'resview', ]); + HistoryController::add([ + 'tableName' => 'res_letterbox', + 'recordId' => $attachment['res_id_master'], + 'eventType' => 'VIEW', + 'info' => _ATTACH_DISPLAYING . " : {$attachment['title']}", + 'moduleId' => 'attachment', + 'eventId' => 'resview' + ]); + $data = $request->getQueryParams(); if ($data['mode'] == 'base64') { return $response->withJson(['encodedDocument' => base64_encode($fileContent), 'originalFormat' => $attachment['format']]); @@ -494,7 +548,7 @@ class AttachmentController } $attachment = AttachmentModel::get([ - 'select' => ['res_id', 'docserver_id', 'path', 'filename', 'res_id_master'], + 'select' => ['res_id', 'docserver_id', 'path', 'filename', 'res_id_master', 'title'], 'where' => ['res_id = ?', 'status not in (?)'], 'data' => [$args['id'], ['DEL']], 'limit' => 1 @@ -551,10 +605,19 @@ class AttachmentController 'recordId' => $args['id'], 'eventType' => 'VIEW', 'info' => _ATTACH_DISPLAYING . " : {$id}", - 'moduleId' => 'attachments', + 'moduleId' => 'attachment', 'eventId' => 'resview', ]); + HistoryController::add([ + 'tableName' => 'res_letterbox', + 'recordId' => $attachmentTodisplay['res_id_master'], + 'eventType' => 'VIEW', + 'info' => _ATTACH_DISPLAYING . " : {$attachmentTodisplay['title']}", + 'moduleId' => 'attachment', + 'eventId' => 'resview' + ]); + return $response->withHeader('Content-Type', $mimeType); } diff --git a/src/app/email/controllers/EmailController.php b/src/app/email/controllers/EmailController.php index 443a6c449e26ecdfe2614630eb7d95b017b9ba22..90d5b3ff1d6e0614b894e1e97c689392856f9571 100644 --- a/src/app/email/controllers/EmailController.php +++ b/src/app/email/controllers/EmailController.php @@ -672,7 +672,7 @@ class EmailController return ['success' => 'success']; } - private static function getAvailableEmailsByUserId(array $args) + public static function getAvailableEmailsByUserId(array $args) { $currentUser = UserModel::getById(['select' => ['firstname', 'lastname', 'mail', 'user_id'], 'id' => $args['userId']]); diff --git a/src/app/resource/controllers/ResController.php b/src/app/resource/controllers/ResController.php index 57cb3f72f2ec0333c74abb3c87d6de9896015c63..287f2fa7621e99c609307daf18ecffb174b21b6e 100755 --- a/src/app/resource/controllers/ResController.php +++ b/src/app/resource/controllers/ResController.php @@ -795,6 +795,13 @@ class ResController extends ResourceControlController return $response->withStatus(400)->withJson(['errors' => 'Body param integrations is missing or not an array']); } + $documents = ResModel::get([ + 'select' => ['alt_identifier', 'res_id'], + 'where' => ['res_id in (?)'], + 'data' => [$body['resources']] + ]); + $documents = array_column($documents, 'alt_identifier', 'res_id'); + if (isset($body['integrations']['inSignatureBook']) && Validator::boolType()->validate($body['integrations']['inSignatureBook'])) { $inSignatureBook = $body['integrations']['inSignatureBook'] ? 'true' : 'false'; @@ -805,6 +812,18 @@ class ResController extends ResourceControlController 'where' => ['res_id in (?)'], 'data' => [$body['resources']] ]); + + $info = $body['integrations']['inSignatureBook'] ? _DOC_ADD_TO_SIGNATORY_BOOK : _DOC_REMOVE_FROM_SIGNATORY_BOOK; + foreach ($body['resources'] as $resId) { + HistoryController::add([ + 'tableName' => 'res_letterbox', + 'recordId' => $resId, + 'eventType' => 'UP', + 'info' => $info . " : " . $documents[$resId], + 'moduleId' => 'resource', + 'eventId' => 'resourceModification', + ]); + } } if (isset($body['integrations']['inShipping']) && Validator::boolType()->validate($body['integrations']['inShipping'])) { @@ -817,6 +836,18 @@ class ResController extends ResourceControlController 'where' => ['res_id in (?)'], 'data' => [$body['resources']] ]); + + $info = $body['integrations']['inShipping'] ? _DOC_ADD_TO_MAILEVA : _DOC_REMOVE_FROM_MAILEVA; + foreach ($body['resources'] as $resId) { + HistoryController::add([ + 'tableName' => 'res_letterbox', + 'recordId' => $resId, + 'eventType' => 'UP', + 'info' => $info . " : " . $documents[$resId], + 'moduleId' => 'resource', + 'eventId' => 'resourceModification', + ]); + } } return $response->withStatus(204); diff --git a/src/app/resource/controllers/ResourceControlController.php b/src/app/resource/controllers/ResourceControlController.php index ceada524ae0e5dc87b9c2d1d562908b237f03489..23ec692463af37e955f498ca0c6924f07be8da1d 100644 --- a/src/app/resource/controllers/ResourceControlController.php +++ b/src/app/resource/controllers/ResourceControlController.php @@ -383,8 +383,8 @@ class ResourceControlController } } elseif ($customField['type'] == 'string' && !Validator::stringType()->notEmpty()->validate($body['customFields'][$customFieldId])) { return ['errors' => "Body customFields[{$customFieldId}] is not a string"]; - } elseif ($customField['type'] == 'integer' && !Validator::intVal()->notEmpty()->validate($body['customFields'][$customFieldId])) { - return ['errors' => "Body customFields[{$customFieldId}] is not an integer"]; + } elseif ($customField['type'] == 'integer' && !Validator::floatVal()->notEmpty()->validate($body['customFields'][$customFieldId])) { + return ['errors' => "Body customFields[{$customFieldId}] is not a number"]; } elseif ($customField['type'] == 'date' && !Validator::date()->notEmpty()->validate($body['customFields'][$customFieldId])) { return ['errors' => "Body customFields[{$customFieldId}] is not a date"]; } diff --git a/src/core/lang/lang-en.php b/src/core/lang/lang-en.php index 15e7ee0311c669727acd1b2f658aeb3072c16ca5..b14c03c0644bc62061e8f6c07bcd4a92ce149254 100755 --- a/src/core/lang/lang-en.php +++ b/src/core/lang/lang-en.php @@ -470,3 +470,13 @@ define("_SENT_BY", "Sent by"); define('_TO_CCI', 'Copy hidden'); define('_PRIMARY_INFORMATION', 'Primary information'); define("_EMPTY_SUBJECT", "Empty subject"); + +define("_ATTACH_REMOVE_FROM_SIGNATORY_BOOK", "Attachment removed from signatory book"); +define("_ATTACH_ADD_TO_SIGNATORY_BOOK", "Attachment added to signatory book"); +define("_ATTACH_REMOVE_FROM_SHIPPING", "Attachment removed from Maileva shippings"); +define("_ATTACH_ADD_TO_SHIPPING", "Attachment added to Maileva shippings"); + +define("_DOC_ADD_TO_SIGNATORY_BOOK", "Mail added to signatory book"); +define("_DOC_REMOVE_FROM_SIGNATORY_BOOK", "Mail removed from signatory book"); +define("_DOC_ADD_TO_MAILEVA", "Mail added to Maileva shippings"); +define("_DOC_REMOVE_FROM_MAILEVA", "Mail removed from Maileva shippings"); diff --git a/src/core/lang/lang-fr.php b/src/core/lang/lang-fr.php index e666d6cfe6ecf21adb2d4624269ecb7b2e890397..a837b49212ee4dcd44e6bc2028c52ef28099ed9f 100755 --- a/src/core/lang/lang-fr.php +++ b/src/core/lang/lang-fr.php @@ -470,3 +470,13 @@ define("_SENT_BY", "Envoyé par"); define('_TO_CCI', 'En copie caché'); define('_PRIMARY_INFORMATION', 'Informations principales'); define("_EMPTY_SUBJECT", "Objet vide"); + +define("_ATTACH_REMOVE_FROM_SIGNATORY_BOOK", "Pièce jointe retirée du parapheur électronique"); +define("_ATTACH_ADD_TO_SIGNATORY_BOOK", "Pièce jointe intégrée au parapheur électronique"); +define("_ATTACH_REMOVE_FROM_SHIPPING", "Pièce jointe retirée des envois Maileva"); +define("_ATTACH_ADD_TO_SHIPPING", "Pièce jointe intégrée aux envois Maileva"); + +define("_DOC_ADD_TO_SIGNATORY_BOOK", "Courrier intégré au parapheur électronique"); +define("_DOC_REMOVE_FROM_SIGNATORY_BOOK", "Courrier retiré du parapheur électronique"); +define("_DOC_ADD_TO_MAILEVA", "Courrier intégré aux envois Maileva"); +define("_DOC_REMOVE_FROM_MAILEVA", "Courrier retiré des envois Maileva"); diff --git a/src/core/lang/lang-nl.php b/src/core/lang/lang-nl.php index aa72ded1831f9bb3caa57f5c91cd7aae6d2f29c1..1b4a7c791f378b9f02ea7bcda502d176749c85b3 100755 --- a/src/core/lang/lang-nl.php +++ b/src/core/lang/lang-nl.php @@ -473,3 +473,13 @@ define("_SENT_BY", "Sent by"); //TO TRANSLATE define('_TO_CCI', 'On copy hidden'); //TO TRANSLATE define('_PRIMARY_INFORMATION', 'Primary information'); //TO TRANSLATE define("_EMPTY_SUBJECT", "Empty subject"); //TO TRANSLATE + +define("_ATTACH_REMOVE_FROM_SIGNATORY_BOOK", "Attachment removed from signatory book"); //TO TRANSLATE +define("_ATTACH_ADD_TO_SIGNATORY_BOOK", "Attachment added to signatory book"); //TO TRANSLATE +define("_ATTACH_REMOVE_FROM_SHIPPING", "Attachment removed from Maileva shippings"); //TO TRANSLATE +define("_ATTACH_ADD_TO_SHIPPING", "Attachment added to Maileva shippings"); //TO TRANSLATE + +define("_DOC_ADD_TO_SIGNATORY_BOOK", "Mail added to signatory book"); //TO TRANSLATE +define("_DOC_REMOVE_FROM_SIGNATORY_BOOK", "Mail removed from signatory book"); //TO TRANSLATE +define("_DOC_ADD_TO_MAILEVA", "Mail added to Maileva shippings"); //TO TRANSLATE +define("_DOC_REMOVE_FROM_MAILEVA", "Mail removed from Maileva shippings"); //TO TRANSLATE diff --git a/src/frontend/app/attachments/attachments-page/attachment-page.component.html b/src/frontend/app/attachments/attachments-page/attachment-page.component.html index aa9a9a6bf5e97254c27126aa2acf4369bc550ad4..c29832ce4da0e6309d6fafc61b052f63f2861630 100644 --- a/src/frontend/app/attachments/attachments-page/attachment-page.component.html +++ b/src/frontend/app/attachments/attachments-page/attachment-page.component.html @@ -191,7 +191,7 @@ </ng-template> <app-document-viewer #appAttachmentViewer style="display:block;height:100%;width:100%;overflow: auto;" [editMode]="editMode" [resId]="data.resId" [resIdMaster]="attachment['resIdMaster'].value" [mode]="'attachment'" - [format]="attachment['format'].value" [attachType]="attachment['type'].value" [infoPanel]="snavLeft" + [format]="attachment['format'].value" [attachType]="attachment['type'].value" (triggerEvent)="setDatasViewer($event)" [title]="attachment.chrono.value + ' - ' + attachment.title.value"> </app-document-viewer> diff --git a/src/frontend/app/profile.component.html b/src/frontend/app/profile.component.html index dfb11e9c2923b7ff67ac167e2d20a4fe19e665fa..38af25256089d892771d4c3bc7c0f1d45a4f7200 100755 --- a/src/frontend/app/profile.component.html +++ b/src/frontend/app/profile.component.html @@ -865,7 +865,7 @@ </mat-cell> </ng-container> <ng-container matColumnDef="record_id"> - <mat-header-cell *matHeaderCellDef>{{lang.technicalId}}</mat-header-cell> + <mat-header-cell *matHeaderCellDef mat-sort-header>{{lang.technicalId}}</mat-header-cell> <mat-cell *matCellDef="let element">{{element.record_id}}</mat-cell> </ng-container> <ng-container matColumnDef="info"> diff --git a/src/frontend/app/profile.component.ts b/src/frontend/app/profile.component.ts index cbded5c015f94ef2b39fc5dfb4c615eb4da99db0..a032088fc2c09c775a59cf31a3288d5766cecbb7 100755 --- a/src/frontend/app/profile.component.ts +++ b/src/frontend/app/profile.component.ts @@ -2,7 +2,7 @@ import { Component, OnInit, NgZone, ViewChild, QueryList, ViewChildren, Template import { HttpClient } from '@angular/common/http'; import { LANG } from './translate.component'; import { NotificationService } from './notification.service'; -import { HeaderService } from '../service/header.service'; +import { HeaderService } from '../service/header.service'; import { debounceTime, switchMap, distinctUntilChanged, filter, tap } from 'rxjs/operators'; import { MatDialog, MatDialogRef } from '@angular/material/dialog'; import { MatExpansionPanel } from '@angular/material/expansion'; @@ -14,6 +14,7 @@ import { MatTableDataSource } from '@angular/material/table'; import { SelectionModel } from '@angular/cdk/collections'; import { FormControl, FormGroup, Validators, AbstractControl, ValidationErrors, ValidatorFn, FormBuilder } from '@angular/forms'; import { AppService } from '../service/app.service'; +import { FunctionsService } from '../service/functions.service'; declare function $j(selector: any): any; @@ -52,7 +53,7 @@ export class ProfileComponent implements OnInit { complexityNumber: { enabled: false, value: 0 }, complexitySpecial: { enabled: false, value: 0 }, renewal: { enabled: false, value: 0 }, - historyLastUse: {enabled:false, value:0}, + historyLastUse: { enabled: false, value: 0 }, }; signatureModel: any = { base64: "", @@ -76,7 +77,7 @@ export class ProfileComponent implements OnInit { loading: boolean = false; selectedIndex: number = 0; selectedIndexContactsGrp: number = 0; - loadingSign : boolean = false; + loadingSign: boolean = false; @ViewChild('snav2', { static: true }) sidenavRight: MatSidenav; @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; @@ -86,9 +87,9 @@ export class ProfileComponent implements OnInit { myBasketExpansionPanel: boolean = false; editorsList: any; masterToggleBaskets(event: any) { - if (event.checked) { + if (event.checked) { this.user.baskets.forEach((basket: any) => { - if ( !basket.userToDisplay) { + if (!basket.userToDisplay) { this.selectionBaskets.select(basket); } }); @@ -101,10 +102,10 @@ export class ProfileComponent implements OnInit { //Groups contacts contactsGroups: any[] = []; - displayedColumnsGroupsList: string[] = ['label', 'description','nbContacts','public', 'actions']; + displayedColumnsGroupsList: string[] = ['label', 'description', 'nbContacts', 'public', 'actions']; dataSourceGroupsList: any; @ViewChild('paginatorGroupsList', { static: false }) paginatorGroupsList: MatPaginator; - @ViewChild('tableGroupsListSort', { static: true }) sortGroupsList: MatSort; + @ViewChild('tableGroupsListSort', { static: false }) sortGroupsList: MatSort; applyFilterGroupsList(filterValue: string) { filterValue = filterValue.trim(); // Remove whitespace filterValue = filterValue.toLowerCase(); // MatTableDataSource defaults to lowercase matches @@ -142,7 +143,7 @@ export class ProfileComponent implements OnInit { displayedColumnsContactsList: string[] = ['contact', 'address', 'actions']; dataSourceContactsList: any; @ViewChild('paginatorContactsList', { static: false }) paginatorContactsList: MatPaginator; - @ViewChild('tableContactsListSort', { static: true }) sortContactsList: MatSort; + @ViewChild('tableContactsListSort', { static: false }) sortContactsList: MatSort; applyFilterContactsList(filterValue: string) { filterValue = filterValue.trim(); // Remove whitespace filterValue = filterValue.toLowerCase(); // MatTableDataSource defaults to lowercase matches @@ -153,7 +154,7 @@ export class ProfileComponent implements OnInit { displayedColumns = ['event_date', 'record_id', 'info']; dataSource: any; @ViewChild('paginatorHistory', { static: false }) paginatorHistory: MatPaginator; - @ViewChild('tableHistorySort', { static: true }) sortHistory: MatSort; + @ViewChild('tableHistorySort', { static: false }) sortHistory: MatSort; applyFilter(filterValue: string) { filterValue = filterValue.trim(); // Remove whitespace filterValue = filterValue.toLowerCase(); // MatTableDataSource defaults to lowercase matches @@ -162,14 +163,15 @@ export class ProfileComponent implements OnInit { constructor( - public http: HttpClient, - private zone: NgZone, - private notify: NotificationService, - public dialog: MatDialog, - private _formBuilder: FormBuilder, + public http: HttpClient, + private zone: NgZone, + private notify: NotificationService, + public dialog: MatDialog, + private _formBuilder: FormBuilder, private headerService: HeaderService, public appService: AppService, - private viewContainerRef: ViewContainerRef + private viewContainerRef: ViewContainerRef, + private functions: FunctionsService ) { $j("link[href='merged_css.php']").remove(); window['angularProfileComponent'] = { @@ -200,23 +202,24 @@ export class ProfileComponent implements OnInit { if (event.index == 2) { if (!this.appService.getViewMode()) { this.sidenavRight.open(); - } - //if (this.histories.length == 0) { - this.http.get('../../rest/history/users/' + this.user.id) - .subscribe((data: any) => { - this.histories = data.histories; - setTimeout(() => { - this.dataSource = new MatTableDataSource(this.histories); - this.dataSource.paginator = this.paginatorHistory; - this.dataSource.sort = this.sortHistory; - }, 0); - }, (err) => { - this.notify.error(err.error.errors); - }); - //} - } else if(event.index == 1) { + } + + this.http.get('../../rest/history/users/' + this.user.id) + .subscribe((data: any) => { + this.histories = data.histories; + setTimeout(() => { + this.dataSource = new MatTableDataSource(this.histories); + this.dataSource.sortingDataAccessor = this.functions.listSortingDataAccessor; + this.dataSource.paginator = this.paginatorHistory; + this.dataSource.sort = this.sortHistory; + }, 0); + }, (err) => { + this.notify.error(err.error.errors); + }); + + } else if (event.index == 1) { this.sidenavRight.close(); - } else if(!this.appService.getViewMode()){ + } else if (!this.appService.getViewMode()) { this.sidenavRight.open(); } } @@ -258,7 +261,7 @@ export class ProfileComponent implements OnInit { this.http.get('../../rest/contactsGroups') .subscribe((data) => { this.contactsGroups = []; - this.contactsGroup = { public: false, contacts:[] }; + this.contactsGroup = { public: false, contacts: [] }; let i = 0; data['contactsGroups'].forEach((ct: any) => { if (ct.owner == angularGlobals.user.id) { @@ -292,7 +295,7 @@ export class ProfileComponent implements OnInit { this.http.put('../../rest/contactsGroups/' + this.contactsGroup.id, this.contactsGroup) .subscribe(() => { this.notify.success(this.lang.contactsGroupUpdated); - this.initGroupsContact(); + this.initGroupsContact(); }, (err) => { this.notify.error(err.error.errors); }); @@ -411,7 +414,7 @@ export class ProfileComponent implements OnInit { this.http.get('../../rest/currentUser/profile') .subscribe((data: any) => { this.user = data; - + this.user.baskets.forEach((value: any, index: number) => { this.user.baskets[index]['disabled'] = false; this.user.redirectedBaskets.forEach((value2: any) => { @@ -472,7 +475,7 @@ export class ProfileComponent implements OnInit { } } - dndUploadSignature(event:any) { + dndUploadSignature(event: any) { if (event.mouseEvent.dataTransfer.files && event.mouseEvent.dataTransfer.files[0]) { var reader = new FileReader(); @@ -513,14 +516,14 @@ export class ProfileComponent implements OnInit { } addBasketRedirection(newUser: any) { - let basketsRedirect:any[] = []; + let basketsRedirect: any[] = []; this.selectionBaskets.selected.forEach((elem: any) => { basketsRedirect.push( { actual_user_id: newUser.serialId, - basket_id:elem.basket_id, - group_id:elem.groupSerialId, + basket_id: elem.basket_id, + group_id: elem.groupSerialId, originalOwner: null } ) @@ -541,7 +544,7 @@ export class ProfileComponent implements OnInit { } } - delBasketRedirection(basket: any,i: number) { + delBasketRedirection(basket: any, i: number) { let r = confirm(this.lang.confirmAction); if (r) { @@ -556,7 +559,7 @@ export class ProfileComponent implements OnInit { } } - delBasketAssignRedirection(basket: any,i: number) { + delBasketAssignRedirection(basket: any, i: number) { let r = confirm(this.lang.confirmAction); if (r) { @@ -576,11 +579,11 @@ export class ProfileComponent implements OnInit { if (r) { this.http.post("../../rest/users/" + this.user.id + "/redirectedBaskets", [ - { - "actual_user_id": newUser.serialId, - "basket_id": basket.basket_id, + { + "actual_user_id": newUser.serialId, + "basket_id": basket.basket_id, "group_id": basket.group_id, - "originalOwner": basket.owner_user_id, + "originalOwner": basket.owner_user_id, } ]) .subscribe((data: any) => { @@ -761,7 +764,7 @@ export class ProfileComponent implements OnInit { } updateUserPreferences() { - this.http.put('../../rest/currentUser/profile/preferences', {documentEdition: this.user.preferences.documentEdition}) + this.http.put('../../rest/currentUser/profile/preferences', { documentEdition: this.user.preferences.documentEdition }) .subscribe(() => { this.notify.success(this.lang.modificationSaved); this.headerService.resfreshCurrentUser(); @@ -783,7 +786,7 @@ export class ProfileComponent implements OnInit { changePasswd() { this.http.get('../../rest/passwordRules') .subscribe((data: any) => { - let valArr : ValidatorFn[] = []; + let valArr: ValidatorFn[] = []; let ruleTextArr: String[] = []; let otherRuleTextArr: String[] = []; @@ -792,12 +795,12 @@ export class ProfileComponent implements OnInit { data.rules.forEach((rule: any) => { if (rule.label == 'minLength') { this.passwordRules.minLength.enabled = rule.enabled; - this.passwordRules.minLength.value = rule.value; + this.passwordRules.minLength.value = rule.value; if (rule.enabled) { valArr.push(Validators.minLength(this.passwordRules.minLength.value)); ruleTextArr.push(rule.value + ' ' + this.lang['password' + rule.label]); } - + } else if (rule.label == 'complexityUpper') { this.passwordRules.complexityUpper.enabled = rule.enabled; @@ -806,7 +809,7 @@ export class ProfileComponent implements OnInit { valArr.push(this.regexValidator(new RegExp('[A-Z]'), { 'complexityUpper': '' })); ruleTextArr.push(this.lang['password' + rule.label]); } - + } else if (rule.label == 'complexityNumber') { this.passwordRules.complexityNumber.enabled = rule.enabled; @@ -815,11 +818,11 @@ export class ProfileComponent implements OnInit { valArr.push(this.regexValidator(new RegExp('[0-9]'), { 'complexityNumber': '' })); ruleTextArr.push(this.lang['password' + rule.label]); } - + } else if (rule.label == 'complexitySpecial') { this.passwordRules.complexitySpecial.enabled = rule.enabled; - this.passwordRules.complexitySpecial.value = rule.value; + this.passwordRules.complexitySpecial.value = rule.value; if (rule.enabled) { valArr.push(this.regexValidator(new RegExp('[^A-Za-z0-9]'), { 'complexitySpecial': '' })); ruleTextArr.push(this.lang['password' + rule.label]); @@ -828,13 +831,13 @@ export class ProfileComponent implements OnInit { this.passwordRules.renewal.enabled = rule.enabled; this.passwordRules.renewal.value = rule.value; if (rule.enabled) { - otherRuleTextArr.push(this.lang['password' + rule.label] + ' <b>' + rule.value + ' ' + this.lang.days + '</b>. ' + this.lang['password2' + rule.label]+'.'); + otherRuleTextArr.push(this.lang['password' + rule.label] + ' <b>' + rule.value + ' ' + this.lang.days + '</b>. ' + this.lang['password2' + rule.label] + '.'); } } else if (rule.label == 'historyLastUse') { this.passwordRules.historyLastUse.enabled = rule.enabled; this.passwordRules.historyLastUse.value = rule.value if (rule.enabled) { - otherRuleTextArr.push(this.lang['passwordhistoryLastUseDesc'] + ' <b>' + rule.value + '</b> ' + this.lang['passwordhistoryLastUseDesc2']+'.'); + otherRuleTextArr.push(this.lang['passwordhistoryLastUseDesc'] + ' <b>' + rule.value + '</b> ' + this.lang['passwordhistoryLastUseDesc2'] + '.'); } } @@ -846,23 +849,23 @@ export class ProfileComponent implements OnInit { this.notify.error(err.error.errors); }); - this.firstFormGroup = this._formBuilder.group({ - newPasswordCtrl: [ - '' - ], - retypePasswordCtrl: [ - '', - Validators.compose([Validators.required]) - ], - currentPasswordCtrl: [ - '', - Validators.compose([Validators.required]) - ] - - }, { - validator: this.matchValidator - }); - this.validPassword =false; + this.firstFormGroup = this._formBuilder.group({ + newPasswordCtrl: [ + '' + ], + retypePasswordCtrl: [ + '', + Validators.compose([Validators.required]) + ], + currentPasswordCtrl: [ + '', + Validators.compose([Validators.required]) + ] + + }, { + validator: this.matchValidator + }); + this.validPassword = false; this.firstFormGroup.controls['currentPasswordCtrl'].setErrors(null) this.firstFormGroup.controls['newPasswordCtrl'].setErrors(null) this.firstFormGroup.controls['retypePasswordCtrl'].setErrors(null) @@ -875,14 +878,14 @@ export class ProfileComponent implements OnInit { if (group.controls['newPasswordCtrl'].value == group.controls['retypePasswordCtrl'].value) { return false; } else { - group.controls['retypePasswordCtrl'].setErrors({'mismatch': true}) - return {'mismatch': true}; + group.controls['retypePasswordCtrl'].setErrors({ 'mismatch': true }) + return { 'mismatch': true }; } } getErrorMessage() { if (this.firstFormGroup.controls['newPasswordCtrl'].value != this.firstFormGroup.controls['retypePasswordCtrl'].value) { - this.firstFormGroup.controls['retypePasswordCtrl'].setErrors({'mismatch': true}); + this.firstFormGroup.controls['retypePasswordCtrl'].setErrors({ 'mismatch': true }); } else { this.firstFormGroup.controls['retypePasswordCtrl'].setErrors(null); } @@ -908,12 +911,12 @@ export class ProfileComponent implements OnInit { } } - showActions(basket:any){ - $j('#'+basket.basket_id+'_'+basket.group_id).show(); + showActions(basket: any) { + $j('#' + basket.basket_id + '_' + basket.group_id).show(); } - hideActions(basket:any){ - $j('#'+basket.basket_id+'_'+basket.group_id).hide(); + hideActions(basket: any) { + $j('#' + basket.basket_id + '_' + basket.group_id).hide(); } toggleAddGrp() { @@ -926,7 +929,7 @@ export class ProfileComponent implements OnInit { //$j('#contactsGroup').toggle(); } - changeTabContactGrp(event:any) { + changeTabContactGrp(event: any) { this.selectedIndexContactsGrp = event; if (event == 0) { this.initGroupsContact(); diff --git a/src/frontend/app/viewer/document-viewer.component.ts b/src/frontend/app/viewer/document-viewer.component.ts index 35b38bf8c2d19682a0af3824c8b03c7ea3378e5f..fb26ee2bc04910bc0bf917f6417300ef5369f1a4 100755 --- a/src/frontend/app/viewer/document-viewer.component.ts +++ b/src/frontend/app/viewer/document-viewer.component.ts @@ -7,7 +7,7 @@ import { AppService } from '../../service/app.service'; import { tap, catchError, filter, map, exhaustMap } from 'rxjs/operators'; import { of, Subject } from 'rxjs'; import { ConfirmComponent } from '../../plugins/modal/confirm.component'; -import { MatDialogRef, MatDialog, MatSidenav } from '@angular/material'; +import { MatDialogRef, MatDialog } from '@angular/material'; import { AlertComponent } from '../../plugins/modal/alert.component'; import { SortPipe } from '../../plugins/sorting.pipe'; import { PluginSelectSearchComponent } from '../../plugins/select-search/select-search.component'; @@ -16,7 +16,7 @@ import { EcplOnlyofficeViewerComponent } from '../../plugins/onlyoffice-api-js/o import { FunctionsService } from '../../service/functions.service'; import { DocumentViewerModalComponent } from './modal/document-viewer-modal.component'; import { PrivilegeService } from '../../service/privileges.service'; -import {VisaWorkflowModalComponent} from "../visa/modal/visa-workflow-modal.component"; +import { VisaWorkflowModalComponent } from "../visa/modal/visa-workflow-modal.component"; @Component({ @@ -31,8 +31,53 @@ import {VisaWorkflowModalComponent} from "../visa/modal/visa-workflow-modal.comp export class DocumentViewerComponent implements OnInit { + /** + * document name stored in server (in tmp folder) + */ @Input('tmpFilename') tmpFilename: string; - @Output('refreshDatas') refreshDatas = new EventEmitter<string>(); + + /** + * base64 of document (@format is required!) + */ + @Input('base64') base64: any = null; + @Input('format') format: string = null; + + /** + * Target of resource (document or attachment) + */ + @Input('mode') mode: 'mainDocument' | 'attachment' = 'mainDocument'; + + /** + * Resource of document or attachment (based on @mode) + */ + @Input('resId') resId: number = null; + + + /** + * Resource of document link to attachment (@mode = 'attachment' required!) + */ + @Input('resIdMaster') resIdMaster: number = null; + + /** + * Can manage document ? (create, delete, update) + */ + @Input('editMode') editMode: boolean = false; + + /** + * Title of new tab when open document in external tab + */ + @Input('title') title: string = ''; + + + /** + * To load specific attachment type in template list (to create document) + */ + @Input('attachType') attachType: string = null; + + /** + * Event emitter + */ + @Output('triggerEvent') triggerEvent = new EventEmitter<string>(); lang: any = LANG; @@ -64,21 +109,6 @@ export class DocumentViewerComponent implements OnInit { templateListForm = new FormControl(); - @Input('base64') base64: any = null; - @Input('resId') resId: number = null; - @Input('resIdMaster') resIdMaster: number = null; - @Input('infoPanel') infoPanel: MatSidenav = null; - @Input('editMode') editMode: boolean = false; - @Input('title') title: string = ''; - @Input('mode') mode: string = 'mainDocument'; - @Input('attachType') attachType: string = null; - @Input('format') format: string = null; - - @Output('triggerEvent') triggerEvent = new EventEmitter<string>(); - - private eventAction = new Subject<any>(); - - resourceDatas: any; loadingInfo: any = { @@ -856,7 +886,7 @@ export class DocumentViewerComponent implements OnInit { }); this.listTemplates = arrValues; }) - + ).subscribe(); } else { let arrTypes: any = []; @@ -879,9 +909,9 @@ export class DocumentViewerComponent implements OnInit { }), tap((data: any) => { this.listTemplates = data.templates; - + arrTypes = arrTypes.filter((type: any) => data.templates.map((template: any) => template.attachmentType).indexOf(type.id) > -1); - + arrTypes.forEach((arrType: any) => { arrValues.push({ id: arrType.id, @@ -901,10 +931,10 @@ export class DocumentViewerComponent implements OnInit { }); }); }); - + this.listTemplates = arrValues; }) - + ).subscribe(); } } @@ -954,7 +984,7 @@ export class DocumentViewerComponent implements OnInit { loadTmpDocument(base64Content: string, format: string) { return new Promise((resolve, reject) => { - this.http.post(`../../rest/convertedFile/encodedFile`, { format: format, encodedFile : base64Content}).pipe( + this.http.post(`../../rest/convertedFile/encodedFile`, { format: format, encodedFile: base64Content }).pipe( tap((data: any) => { console.log(data); this.file = { @@ -989,7 +1019,7 @@ export class DocumentViewerComponent implements OnInit { src: null }; }), - exhaustMap((data) => this.http.post(`../../rest/convertedFile/encodedFile`, { format: data.format, encodedFile : data.content})), + exhaustMap((data) => this.http.post(`../../rest/convertedFile/encodedFile`, { format: data.format, encodedFile: data.content })), tap((data: any) => { this.file.src = this.base64ToArrayBuffer(data.encodedResource); this.closeEditor();