From f616e66f1555ce867e89e15870275a0a2d7ccdc7 Mon Sep 17 00:00:00 2001
From: Alex ORLUC <alex.orluc@maarch.org>
Date: Mon, 24 Feb 2020 17:51:20 +0100
Subject: [PATCH] FEAT #13120 TIME 2:45 front mailing create pj

---
 .../attachment-create.component.html          |  34 ++-
 .../attachment-create.component.scss          |  10 +
 .../attachment-create.component.ts            | 272 ++++++++++++++----
 .../app/viewer/document-viewer.component.ts   |   1 -
 src/frontend/lang/lang-en.ts                  |   5 +
 src/frontend/lang/lang-fr.ts                  |   5 +
 src/frontend/lang/lang-nl.ts                  |   8 +-
 .../select-search.component.html              |   2 +-
 .../select-search/select-search.component.ts  |   2 +
 9 files changed, 282 insertions(+), 57 deletions(-)

diff --git a/src/frontend/app/attachments/attachment-create/attachment-create.component.html b/src/frontend/app/attachments/attachment-create/attachment-create.component.html
index 60b218addda..e574f234ea9 100644
--- a/src/frontend/app/attachments/attachment-create/attachment-create.component.html
+++ b/src/frontend/app/attachments/attachment-create/attachment-create.component.html
@@ -6,11 +6,13 @@
         <span style="flex: 1;">
             {{lang.attachmentCreation}}
         </span>
-        <button *ngIf="!loading" [title]="lang.close" mat-icon-button
-            (click)="dialogRef.close();">
+        <button *ngIf="!loading" [title]="lang.close" mat-icon-button (click)="dialogRef.close();">
             <mat-icon class="fa fa-times"></mat-icon>
         </button></h1>
     <mat-dialog-content class="attach-content">
+        <div *ngIf="loading" class="loading">
+            <mat-spinner style="margin:auto;"></mat-spinner>
+        </div>
         <mat-tab-group #pjList style="width: 100%;" [(selectedIndex)]="indexTab" *ngIf="!loading">
             <mat-tab *ngFor="let attachment of attachments; let i=index" [disabled]="isDocLoading()">
                 <ng-template mat-tab-label>
@@ -49,8 +51,28 @@
                                     *ngIf="attachment['title'].valid && !isEmptyField(attachment['title'])"></i>
                             </div>
                         </div>
-                        <div class="attachment-form-item">
-                            <app-contact-autocomplete [control]="attachment['recipient']" style="width:100%;" [singleMode]="true" (retrieveDocumentEvent)="appDocumentViewer.saveDocService()">
+                        <div class="attachment-form-item" *ngIf="!functions.empty(attachment['recipient'])">
+                            <plugin-select-search [label]="lang.selectContact"
+                                [placeholderLabel]="lang.selectContact" [datas]="resourceContacts"
+                                [returnValue]="'object'" [formControlSelect]="selectedContact"
+                                (afterSelected)="selectContact($event)" style="width:100%;">
+                            </plugin-select-search>
+                            <div class="fieldState">
+                                <button mat-icon-button color="primary"
+                                    [title]="sendMassMode ? lang.disableMailing : lang.enableMailing"
+                                    [class.active]="sendMassMode" (click)="toggleSendMass()">
+                                    <mat-icon class="fas fa-mail-bulk"></mat-icon>
+                                </button>
+                                <i class="fas fa-asterisk noMandatory"></i>
+                            </div>
+                        </div>
+                        <div class="attachment-form-item" *ngIf="sendMassMode" style="display: block;">
+                            <div class="alert alert-info" role="alert" [innerHTML]="lang.mailingMsg"></div>
+                        </div>
+                        <div class="attachment-form-item" *ngIf="!sendMassMode">
+                            <app-contact-autocomplete *ngIf="!loadingContact" [control]="attachment['recipient']"
+                                style="width:100%;" [singleMode]="true"
+                                (retrieveDocumentEvent)="appDocumentViewer.saveDocService()">
                             </app-contact-autocomplete>
                             <div class="fieldState">
                                 <i class="fas fa-asterisk noMandatory"></i>
@@ -96,7 +118,7 @@
             </mat-tab>
             <mat-tab disabled class="addPJ">
                 <ng-template mat-tab-label>
-                    <span><button mat-icon-button [title]="lang.newAttachment"
+                    <span><button mat-icon-button [disabled]="sendMassMode" [title]="lang.newAttachment"
                             (click)="$event.stopPropagation();newPj()">
                             <mat-icon class="fa fa-plus"></mat-icon>
                         </button></span>
@@ -107,6 +129,8 @@
     <div mat-dialog-actions class="actions">
         <button mat-raised-button color="primary" *ngIf="creationMode && !loading" (click)="onSubmit()"
             [disabled]="isDocLoading()">{{lang.validate}}</button>
+        <button mat-raised-button color="primary" *ngIf="sendMassMode && !loading" (click)="onSubmit('mailing')"
+            [disabled]="isDocLoading()">{{lang.mailing}}</button>
         <button mat-raised-button mat-button *ngIf="creationMode && !loading" [disabled]="isDocLoading()"
             [mat-dialog-close]="">{{lang.cancel}}</button>
     </div>
diff --git a/src/frontend/app/attachments/attachment-create/attachment-create.component.scss b/src/frontend/app/attachments/attachment-create/attachment-create.component.scss
index 2a057806bc0..9f3880ae1c0 100644
--- a/src/frontend/app/attachments/attachment-create/attachment-create.component.scss
+++ b/src/frontend/app/attachments/attachment-create/attachment-create.component.scss
@@ -6,6 +6,12 @@
     }
 }
 
+.loading {
+    display: flex;
+    height: 100%;
+    width: 100%;
+}
+
 .attach-container {
     position: relative;
     display: flex;
@@ -100,4 +106,8 @@
     background: $primary;
     overflow: auto;
     color: white;
+}
+
+.active {
+    color: $secondary;
 }
\ No newline at end of file
diff --git a/src/frontend/app/attachments/attachment-create/attachment-create.component.ts b/src/frontend/app/attachments/attachment-create/attachment-create.component.ts
index 1b6335f007e..7a701cb1346 100644
--- a/src/frontend/app/attachments/attachment-create/attachment-create.component.ts
+++ b/src/frontend/app/attachments/attachment-create/attachment-create.component.ts
@@ -10,6 +10,9 @@ import { DocumentViewerComponent } from '../../viewer/document-viewer.component'
 import { SortPipe } from '../../../plugins/sorting.pipe';
 import { FormControl, FormGroup, Validators } from '@angular/forms';
 import { ConfirmComponent } from '../../../plugins/modal/confirm.component';
+import { FunctionsService } from '../../../service/functions.service';
+import { ContactService } from '../../../service/contact.service';
+import { ContactAutocompleteComponent } from '../../contact/autocomplete/contact-autocomplete.component';
 
 @Component({
     templateUrl: "attachment-create.component.html",
@@ -17,7 +20,7 @@ import { ConfirmComponent } from '../../../plugins/modal/confirm.component';
         'attachment-create.component.scss',
         '../../indexation/indexing-form/indexing-form.component.scss'
     ],
-    providers: [AppService, SortPipe],
+    providers: [AppService, SortPipe, ContactService],
 })
 
 export class AttachmentCreateComponent implements OnInit {
@@ -26,6 +29,8 @@ export class AttachmentCreateComponent implements OnInit {
 
     loading: boolean = true;
 
+    sendMassMode: boolean = false;
+
     sendingData: boolean = false;
 
     attachmentsTypes: any[] = [];
@@ -40,10 +45,17 @@ export class AttachmentCreateComponent implements OnInit {
 
     indexTab: number = 0;
 
+    resourceContacts: any[] = [];
+
+    selectedContact = new FormControl();
+
+    loadingContact: boolean = false;
+
     @Input('resId') resId: number = null;
 
 
     @ViewChildren('appDocumentViewer') appDocumentViewer: QueryList<DocumentViewerComponent>;
+    @ViewChildren('contactAutocomplete') contactAutocomplete: ContactAutocompleteComponent;
 
     constructor(
         public http: HttpClient,
@@ -52,41 +64,153 @@ export class AttachmentCreateComponent implements OnInit {
         public appService: AppService,
         private notify: NotificationService,
         private sortPipe: SortPipe,
-        public dialog: MatDialog) {
+        public dialog: MatDialog,
+        public functions: FunctionsService,
+        private contactService: ContactService, ) {
     }
 
-    ngOnInit(): void {
-        this.loadAttachmentTypes();
+    async ngOnInit(): Promise<void> {
+
+        await this.loadAttachmentTypes();
+
+        await this.loadResource();
+
+        this.loading = false;
     }
 
     loadAttachmentTypes() {
-        this.http.get('../../rest/attachmentsTypes').pipe(
-            tap((data: any) => {
-                Object.keys(data.attachmentsTypes).forEach(templateType => {
-                    if (data.attachmentsTypes[templateType].show) {
-                        this.attachmentsTypes.push({
-                            id: templateType,
-                            ...data.attachmentsTypes[templateType]
-                        });
+        return new Promise((resolve, reject) => {
+            this.http.get('../../rest/attachmentsTypes').pipe(
+                tap((data: any) => {
+                    Object.keys(data.attachmentsTypes).forEach(templateType => {
+                        if (data.attachmentsTypes[templateType].show) {
+                            this.attachmentsTypes.push({
+                                id: templateType,
+                                ...data.attachmentsTypes[templateType]
+                            });
+                        }
+                    });
+                    this.attachmentsTypes = this.sortPipe.transform(this.attachmentsTypes, 'label');
+                    resolve(true)
+                }),
+                catchError((err: any) => {
+                    this.notify.handleSoftErrors(err);
+                    this.dialogRef.close('');
+                    return of(false);
+                })
+            ).subscribe();
+        });
+    }
+
+    loadResource() {
+        return new Promise((resolve, reject) => {
+            this.http.get(`../../rest/resources/${this.data.resIdMaster}?light=true`).pipe(
+                tap(async (data: any) => {
+                    if (!this.functions.empty(data.senders) && data.senders.length > 0) {
+                        await this.getContacts(data.senders);
                     }
-                });
-                this.attachmentsTypes = this.sortPipe.transform(this.attachmentsTypes, 'label');
-            }),
-            exhaustMap(() => this.http.get(`../../rest/resources/${this.data.resIdMaster}?light=true`)),
-            tap((data: any) => {
-                this.attachments.push({
-                    title: new FormControl({ value: data.subject, disabled: false }, [Validators.required]),
-                    recipient: new FormControl({ value: '', disabled: false }),
-                    type: new FormControl({ value: '', disabled: false }, [Validators.required]),
-                    validationDate: new FormControl({ value: '', disabled: false }),
-                    format: new FormControl({ value: '', disabled: false }, [Validators.required]),
-                    encodedFile: new FormControl({ value: '', disabled: false }, [Validators.required])
-                });
 
-                this.attachFormGroup.push(new FormGroup(this.attachments[0]));
-            }),
-            finalize(() => this.loading = false)
-        ).subscribe();
+                    this.attachments.push({
+                        title: new FormControl({ value: data.subject, disabled: false }, [Validators.required]),
+                        recipient: new FormControl({ value: !this.functions.empty(data.senders) ? [{ id: data.senders[0].id, type: data.senders[0].type }] : '', disabled: false }),
+                        type: new FormControl({ value: '', disabled: false }, [Validators.required]),
+                        validationDate: new FormControl({ value: '', disabled: false }),
+                        format: new FormControl({ value: '', disabled: false }, [Validators.required]),
+                        encodedFile: new FormControl({ value: '', disabled: false }, [Validators.required])
+                    });
+
+                    this.attachFormGroup.push(new FormGroup(this.attachments[0]));
+
+                    if (data.senders.length > 1) {
+                        this.toggleSendMass();
+                    }
+
+                    resolve(true);
+                }),
+                catchError((err: any) => {
+                    this.notify.handleSoftErrors(err);
+                    this.dialogRef.close('');
+                    return of(false);
+                })
+            ).subscribe();
+        });
+    }
+
+    async getContacts(contacts: any) {
+        this.resourceContacts = [];
+        await Promise.all(contacts.map(async (elem: any) => {
+            await this.getContact(elem.id, elem.type);
+        }));
+
+        this.resourceContacts = this.sortPipe.transform(this.resourceContacts, 'label');
+    }
+
+    selectContact(contact: any) {
+
+        this.loadingContact = true;
+        const contactChosen = JSON.parse(JSON.stringify(this.resourceContacts.filter(resContact => resContact.id === contact.id && resContact.type === contact.type)[0]));
+
+        this.attachments[this.indexTab].recipient.setValue([contactChosen]);
+
+        setTimeout(() => {
+            this.loadingContact = false;
+        }, 0);
+
+        this.selectedContact.reset();
+    }
+
+    getContact(contactId: number, type: string) {
+        return new Promise((resolve, reject) => {
+            if (type === 'contact') {
+                this.http.get('../../rest/contacts/' + contactId).pipe(
+                    tap((data: any) => {
+                        this.resourceContacts.push({
+                            id: data.id,
+                            type: 'contact',
+                            label: this.contactService.formatContact(data)
+                        });
+                        resolve(true);
+                    }),
+                    catchError((err: any) => {
+                        this.notify.handleSoftErrors(err);
+                        resolve(false);
+                        return of(false);
+                    })
+                ).subscribe();
+            } else if (type === 'user') {
+                this.http.get('../../rest/users/' + contactId).pipe(
+                    tap((data: any) => {
+                        this.resourceContacts.push({
+                            id: data.id,
+                            type: 'user',
+                            label: `${data.firstname} ${data.lastname}`
+                        });
+                        resolve(true);
+                    }),
+                    catchError((err: any) => {
+                        this.notify.handleSoftErrors(err);
+                        resolve(false);
+                        return of(false);
+                    })
+                ).subscribe();
+            } else if (type === 'entity') {
+                this.http.get('../../rest/entities/' + contactId).pipe(
+                    tap((data: any) => {
+                        this.resourceContacts.push({
+                            id: data.id,
+                            type: 'entity',
+                            label: data.entity_label
+                        });
+                        resolve(true);
+                    }),
+                    catchError((err: any) => {
+                        this.notify.handleSoftErrors(err);
+                        resolve(false);
+                        return of(false);
+                    })
+                ).subscribe();
+            }
+        });
     }
 
     selectAttachType(attachment: any, type: any) {
@@ -111,32 +235,32 @@ export class AttachmentCreateComponent implements OnInit {
         return formattedAttachments;
     }
 
-    onSubmit() {
+    onSubmit(mode: string = 'default') {
         this.appDocumentViewer.toArray()[this.indexTab].getFile().pipe(
             tap((data) => {
                 this.attachments[this.indexTab].encodedFile.setValue(data.content);
                 this.attachments[this.indexTab].format.setValue(data.format);
             }),
-            tap(() => {
+            tap(async () => {
                 if (this.isValid()) {
+                    let resId: any = null;
                     this.sendingData = true;
                     const attach = this.formatAttachments();
-                    let arrayRoutes: any = [];
-                    this.attachments.forEach((element, index: number) => {
-                        arrayRoutes.push(this.http.post('../../rest/attachments', attach[index]));
-                    });
 
-                    forkJoin(arrayRoutes).pipe(
-                        tap(() => {
-                            this.notify.success(this.lang.attachmentAdded);
-                            this.dialogRef.close('success');
-                        }),
-                        finalize(() => this.sendingData = false),
-                        catchError((err: any) => {
-                            this.notify.handleErrors(err);
-                            return of(false);
-                        })
-                    ).subscribe();
+                    
+                    await Promise.all(this.attachments.map(async (element: any, index: number) => {
+                        resId = await this.saveAttachment(attach[index]);
+                    }));
+
+                    if (this.sendMassMode && resId !== null && mode === 'mailing') {
+                        await this.generateMailling(resId);
+                    }
+                    
+
+                    this.sendingData = false;
+                    this.notify.success(this.lang.attachmentAdded);
+                    this.dialogRef.close('success');
+
                 } else {
                     this.sendingData = false;
                     this.notify.error(this.lang.mustCompleteAllAttachments);
@@ -145,6 +269,38 @@ export class AttachmentCreateComponent implements OnInit {
         ).subscribe();
     }
 
+    saveAttachment(attachment: any) {
+        attachment.status = this.sendMassMode ? 'SEND_MASS' : 'A_TRA';
+
+        return new Promise((resolve, reject) => {
+            this.http.post(`../../rest/attachments`, attachment).pipe(
+                tap((data: any) => {
+                    resolve(data.id);
+                }),
+                catchError((err: any) => {
+                    this.notify.handleSoftErrors(err);
+                    this.dialogRef.close('');
+                    return of(false);
+                })
+            ).subscribe();
+        });
+    }
+
+    generateMailling(resId: number) {
+        return new Promise((resolve, reject) => {
+            this.http.post(`../../rest/attachments/${resId}/mailing`, {}).pipe(
+                tap(() => {
+                    resolve(true);
+                }),
+                catchError((err: any) => {
+                    this.notify.handleSoftErrors(err);
+                    this.dialogRef.close('');
+                    return of(false);
+                })
+            ).subscribe();
+        });
+    }
+
     isValid() {
         let state = true;
         this.attachFormGroup.forEach(formgroup => {
@@ -189,6 +345,9 @@ export class AttachmentCreateComponent implements OnInit {
             }
         });
         datas['resId'] = this.data.resIdMaster;
+        if (this.sendMassMode) {
+            datas['inMailing'] = true;
+        }
         this.appDocumentViewer.toArray()[i].setDatas(datas);
     }
 
@@ -200,18 +359,18 @@ export class AttachmentCreateComponent implements OnInit {
                 this.attachments[this.indexTab].format.setValue(data.format);
                 this.attachments.push({
                     title: new FormControl({ value: '', disabled: false }, [Validators.required]),
-                    recipient: new FormControl({ value: null, disabled: false }),
+                    recipient: new FormControl({ value: !this.functions.empty(this.resourceContacts[this.attachments.length]) ? [{ id: this.resourceContacts[this.attachments.length].id, type: this.resourceContacts[this.attachments.length].type }] : null, disabled: false }),
                     type: new FormControl({ value: '', disabled: false }, [Validators.required]),
                     validationDate: new FormControl({ value: null, disabled: false }),
                     encodedFile: new FormControl({ value: '', disabled: false }, [Validators.required]),
                     format: new FormControl({ value: '', disabled: false }, [Validators.required])
                 });
-        
+
                 this.attachFormGroup.push(new FormGroup(this.attachments[this.attachments.length - 1]));
                 this.indexTab = this.attachments.length - 1;
             }),
         ).subscribe();
-    
+
     }
 
     removePj(i: number) {
@@ -253,4 +412,19 @@ export class AttachmentCreateComponent implements OnInit {
             return true;
         }
     }
+
+    toggleSendMass() {
+        if (this.sendMassMode) {
+            this.sendMassMode = !this.sendMassMode;
+            this.selectedContact.enable();
+        } else {
+            if (this.attachments.length === 1) {
+                this.sendMassMode = !this.sendMassMode;
+                this.selectedContact.disable();
+            } else {
+                this.notify.error('Veuillez supprimer les <b>autres onglets PJ</b> avant de passer en <b>publipostage</b>.');
+            }
+
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/frontend/app/viewer/document-viewer.component.ts b/src/frontend/app/viewer/document-viewer.component.ts
index 720c433a261..a4d64c80f4f 100644
--- a/src/frontend/app/viewer/document-viewer.component.ts
+++ b/src/frontend/app/viewer/document-viewer.component.ts
@@ -545,7 +545,6 @@ export class DocumentViewerComponent implements OnInit {
             );
         } else {            
             await this.loadMainDocumentSubInformations();
-            console.log(this.file.subinfos.mainDocVersions.length);
             if (this.file.subinfos.mainDocVersions.length > 0) {
                 this.requestWithLoader(`../../rest/resources/${resId}/content?mode=base64`).subscribe(
                     (data: any) => {
diff --git a/src/frontend/lang/lang-en.ts b/src/frontend/lang/lang-en.ts
index 61d955cdacb..4a82094cc38 100755
--- a/src/frontend/lang/lang-en.ts
+++ b/src/frontend/lang/lang-en.ts
@@ -1568,4 +1568,9 @@ export const LANG_EN = {
     "generateSeparators" : "Generate separators for each elements",
     "theTag" : "The tag",
     "willBeDeletedAndMerged" : "will be deleted and merged with the tag",
+    "mailing" : "Mailing",
+    "enableMailing" : "Enable mailing",
+    "disableMailing" : "Disable mailing",
+    "selectContact" : "select a contact",
+    "mailingMsg" : "<b>Mailing enbled</b> : <br><br><p>A <b>master</b> attachment will be created without merged field <b>contact</b> (attachmentRecipient).</p><p>If you click on Mailing, the attachmenets will be generated <b>NOW</b>.<br><br>If you click on Validate, They will be generated <b>AFTER</b> <b>approver</b> validation of visa circuit.</p><p><b>One</b> attachment will be generated for <b>each contact</b> linked to the mail.</p>",
 };
diff --git a/src/frontend/lang/lang-fr.ts b/src/frontend/lang/lang-fr.ts
index bf152e93823..be54402cb10 100755
--- a/src/frontend/lang/lang-fr.ts
+++ b/src/frontend/lang/lang-fr.ts
@@ -1607,4 +1607,9 @@ export const LANG_FR = {
     "generateSeparators" : "Générer des intercalaires entre les élements",
     "theTag" : "Le mot-clé",
     "willBeDeletedAndMerged" : "sera supprimé et fusionné avec le mot-clé",
+    "mailing" : "Publipostage",
+    "enableMailing" : "Activer le publipostage",
+    "disableMailing" : "Désactiver le publipostage",
+    "selectContact" : "Sélectionner un contact",
+    "mailingMsg" : "<b>Publipostage activé</b> : <br><br><p>Un attachement <b>maître</b> sera créé sans le champ de fusion <b>contact</b> (attachmentRecipient).</p><p>Si vous cliquez sur Publipostage, les attachements seront générés <b>TOUT DE SUITE</b>.<br><br>Si vous cliquez sur Valider, ils seront générés <b>APRÈS</b> validation des <b>viseurs</b> du circuit de visa.</p><p><b>Un</b> attachement sera généré <b>par contact</b> associé au courrier.</p>",
 };
diff --git a/src/frontend/lang/lang-nl.ts b/src/frontend/lang/lang-nl.ts
index 558abea6a9c..f9506624206 100755
--- a/src/frontend/lang/lang-nl.ts
+++ b/src/frontend/lang/lang-nl.ts
@@ -1592,5 +1592,11 @@ export const LANG_NL = {
     "attachSummarySheet" : "Attach the summary sheet", //_TO_TRANSLATE
     "generateSeparators" : "Generate separators for each elements", //_TO_TRANSLATE
     "theTag" : "The tag",//_TO_TRANSLATE
-    "willBeDeletedAndMerged" : "will be deleted and merged with the tag",//_TO_TRANSLATE
+    "willBeDeletedAndMerged" : "will be deleted and merged with the tag", //_TO_TRANSLATE
+    "mailing" : "Mailing", //_TO_TRANSLATE
+    "enableMailing" : "Enable mailing",  //_TO_TRANSLATE
+    "disableMailing" : "Disable mailing", //_TO_TRANSLATE
+    "selectContact" : "select a contact", //_TO_TRANSLATE
+    "mailingMsg" : "<b>Mailing enbled</b> : <br><br><p>A <b>master</b> attachment will be created without merged field <b>contact</b> (attachmentRecipient).</p><p>If you click on Mailing, the attachmenets will be generated <b>NOW</b>.<br><br>If you click on Validate, They will be generated <b>AFTER</b> <b>approver</b> validation of visa circuit.</p><p><b>One</b> attachment will be generated for <b>each contact</b> linked to the mail.</p>", //_TO_TRANSLATE
+
 };
diff --git a/src/frontend/plugins/select-search/select-search.component.html b/src/frontend/plugins/select-search/select-search.component.html
index c0b056b9aba..b7c7506383b 100644
--- a/src/frontend/plugins/select-search/select-search.component.html
+++ b/src/frontend/plugins/select-search/select-search.component.html
@@ -19,7 +19,7 @@
       {{lang.noResult}}
     </div>
     <mat-option *ngIf="showResetOption" [value]="null"></mat-option>
-    <mat-option *ngFor="let value of filteredDatas | async" [value]="value.id"
+    <mat-option *ngFor="let value of filteredDatas | async" [value]="returnValue === 'id' ? value.id : value"
       [title]="value.title !== undefined ? value.title : value.label" [disabled]="value.disabled"
       [class.opt-group]="value.isTitle" [style.color]="value.color" [innerHTML]="value.label">
     </mat-option>
diff --git a/src/frontend/plugins/select-search/select-search.component.ts b/src/frontend/plugins/select-search/select-search.component.ts
index 0985a223a1e..b481e098e12 100644
--- a/src/frontend/plugins/select-search/select-search.component.ts
+++ b/src/frontend/plugins/select-search/select-search.component.ts
@@ -27,6 +27,8 @@ export class PluginSelectSearchComponent implements OnInit, OnDestroy, AfterView
 
     @Input('datas') datas: any = [];
 
+    @Input('returnValue') returnValue: 'id' | 'object' = 'id';
+
     @Input('label') label: string;
 
     @Input('showResetOption') showResetOption: boolean;
-- 
GitLab