diff --git a/src/frontend/app/contact/autocomplete/contact-autocomplete.component.html b/src/frontend/app/contact/autocomplete/contact-autocomplete.component.html index 3875a6422a4bfd6a430588b8305ec0a91dffffc9..ad37047532df0d4e2a0a77ef8e785cc4bd66c7df 100644 --- a/src/frontend/app/contact/autocomplete/contact-autocomplete.component.html +++ b/src/frontend/app/contact/autocomplete/contact-autocomplete.component.html @@ -1,27 +1,28 @@ <form> <input type="hidden" [formControl]="controlAutocomplete"> - <mat-form-field floatLabel="never" class="input-form" *ngIf="(!controlAutocomplete.disabled && !singleMode) || (singleMode && controlAutocomplete.value.length === 0)"> + <mat-form-field floatLabel="never" class="input-form" + *ngIf="(!controlAutocomplete.disabled && !singleMode) || (singleMode && controlAutocomplete.value.length === 0)"> <mat-icon color="primary" class="fa fa-search" matPrefix style="padding-left: 20px;font-size: 15px;"></mat-icon> <input type="text" #autoCompleteInput [placeholder]="lang.searchContact" matInput [formControl]="myControl" - [matAutocomplete]="auto" (click)="$event.stopPropagation()" (focus)="resetAutocomplete()" maxlength="128"> - <button [disabled]="!canAdd" type="button" matSuffix mat-icon-button (click)="$event.stopPropagation();openContact()"> - <mat-icon class="fa fa-plus" [title]="lang.createContact"> - </mat-icon> - </button> + [matAutocomplete]="auto" (click)="$event.stopPropagation();noResultFound = null;" maxlength="128"> <mat-autocomplete #auto="matAutocomplete" (optionSelected)="selectOpt($event)"> <ng-container *ngIf="options.length > 0 && !loading"> <mat-option *ngFor="let option of filteredOptions | async" [value]="option"> <mat-card> <mat-card-header class="contact-header"> <div mat-card-avatar class="contact-header-image fa" - [class.fa-address-card]="option.type === 'contact'" [class.fa-users]="option.type ==='contactGroup'" + [class.fa-address-card]="option.type === 'contact'" + [class.fa-users]="option.type ==='contactGroup'" [class.fa-sitemap]="option.type ==='entity'" [class.fa-user]="option.type ==='user'" [title]="lang['contact_'+option.type]"> </div> - <mat-card-title *ngIf="!empty(option.firstname) || !empty(option.lastname)" [title]="option.civilityLabel + ' ' + option.firstname + ' ' + option.lastname"> - <sup *ngIf="!empty(option.civility)">{{option.civilityShortLabel}} </sup>{{option.firstname}} + <mat-card-title *ngIf="!empty(option.firstname) || !empty(option.lastname)" + [title]="option.civilityLabel + ' ' + option.firstname + ' ' + option.lastname"> + <sup + *ngIf="!empty(option.civility)">{{option.civilityShortLabel}} </sup>{{option.firstname}} {{option.lastname}}</mat-card-title> - <mat-card-title *ngIf="empty(option.firstname) && empty(option.lastname)" [title]="option.company">{{option.company}}</mat-card-title> + <mat-card-title *ngIf="empty(option.firstname) && empty(option.lastname)" + [title]="option.company">{{option.company}}</mat-card-title> <mat-card-subtitle [title]="option.function" *ngIf="!empty(option.function)"> {{option.function}} </mat-card-subtitle> @@ -32,7 +33,8 @@ </mat-card-header> <mat-card-content> <mat-list> - <mat-list-item class="contact-item" *ngIf="(!empty(option.firstname) || !empty(option.lastname)) && !empty(option.company)"> + <mat-list-item class="contact-item" + *ngIf="(!empty(option.firstname) || !empty(option.lastname)) && !empty(option.company)"> <mat-icon mat-list-icon class="contact-group far fa-building" [title]="lang.contactsParameters_company"></mat-icon> <p mat-line class="contact-content" [title]="option.company"> {{option.company}} @@ -61,45 +63,55 @@ *ngIf="!empty(option.addressNumber) || !empty(option.addressStreet) || !empty(option.addressAdditional2) || !empty(option.addressPostcode) || !empty(option.addressTown) || !empty(option.addressCountry)"> <mat-icon mat-list-icon class="contact-group fas fa-map-marker-alt"></mat-icon> <p mat-line class="contact-content" - *ngIf="!empty(option.addressNumber) || !empty(option.addressStreet)" [title]="option.addressStreet"> + *ngIf="!empty(option.addressNumber) || !empty(option.addressStreet)" + [title]="option.addressStreet"> {{option.addressNumber}} {{option.addressStreet}} </p> <p mat-line class="contact-content" *ngIf="!empty(option.addressAdditional2)" [title]="option.addressAdditional2"> ({{option.addressAdditional2}}) </p> <p mat-line class="contact-content" *ngIf="!empty(option.addressPostcode) || !empty(option.addressTown)" - [title]="option.addressPostcode + ' ' + option.addressTown"> {{option.addressPostcode}} + [title]="option.addressPostcode + ' ' + option.addressTown"> + {{option.addressPostcode}} {{option.addressTown}} </p> <p mat-line class="contact-content" *ngIf="!empty(option.addressCountry)" [title]="option.addressCountry"> {{option.addressCountry}} </p> </mat-list-item> </mat-list> </mat-card-content> - </mat-card > + </mat-card> </mat-option> </ng-container> <mat-option class="autoCompleteInfoResult smallInputInfo" *ngIf="options.length === 0 && !loading" disabled [innerHTML]="listInfo"> </mat-option> - <mat-option *ngIf="loading" disabled> + <mat-option class="autoCompleteInfoResult smallInputInfo create-contact" *ngIf="canAdd && noResultFound !== null && !loading" disabled> + <a style="cursor: pointer;" (click)="$event.stopPropagation();openContact()"> + {{lang.createContact}} ? + </a> + </mat-option> + <mat-option *ngIf="loading" disabled style="text-align: center;display: block;padding: 10px;"> <mat-spinner diameter="20"></mat-spinner> </mat-option> </mat-autocomplete> </mat-form-field> + <div style="text-align: right;" *ngIf="controlAutocomplete.value.length >= 2 && !controlAutocomplete.disabled"> + <button mat-button color="warn" (click)="resetAll()" style="font-size: 10px;">{{lang.deleteAll}}</button> + </div> <div class="itemList"> <mat-chip-list *ngIf="controlAutocomplete.value.length > 0" class="mat-chip-list-stacked itemChip" color="default"> <ng-container *ngIf="!loadingValues"> <mat-chip *ngFor="let item of controlAutocomplete.value;let i=index" class="listAutocomplete" - color="default" [removable]="!controlAutocomplete.disabled" (removed)="removeItem(i)" (click)="openContact(item)"> + color="default" [removable]="!controlAutocomplete.disabled" (removed)="removeItem(i)" + (click)="openContact(item)"> <span style="display: flex;flex: 1;align-items: center;"> <i class="fa" [class.fa-address-card]="this.valuesToDisplay[item.id].type === 'contact'" [class.fa-sitemap]="this.valuesToDisplay[item.id].type ==='entity'" [class.fa-user]="this.valuesToDisplay[item.id].type ==='user'" - [title]="lang[this.valuesToDisplay[item.id].type]" - style="padding-right:5px;"></i> - <ng-container *ngIf="!empty(this.valuesToDisplay[item.id].firstname)"> - {{this.valuesToDisplay[item.id].firstname}} - </ng-container> + [title]="lang[this.valuesToDisplay[item.id].type]" style="padding-right:5px;"></i> + <ng-container *ngIf="!empty(this.valuesToDisplay[item.id].firstname)"> + {{this.valuesToDisplay[item.id].firstname}} + </ng-container> {{this.valuesToDisplay[item.id].lastname}} <ng-container *ngIf="!empty(this.valuesToDisplay[item.id].company)"> diff --git a/src/frontend/app/contact/autocomplete/contact-autocomplete.component.scss b/src/frontend/app/contact/autocomplete/contact-autocomplete.component.scss index e10d5acc7fea65f3be66473fdd334d1e30b63922..a4b0cc28b2c6a993093a3aa1a88afc55619bf508 100644 --- a/src/frontend/app/contact/autocomplete/contact-autocomplete.component.scss +++ b/src/frontend/app/contact/autocomplete/contact-autocomplete.component.scss @@ -11,7 +11,7 @@ .mat-chip.mat-standard-chip { color: white; - background-color: lighten($primary,10%); + background-color: lighten($primary, 10%); } .noResult { @@ -40,7 +40,7 @@ } .mat-card:hover { - box-shadow: inset 0px 0px 5px 0px rgba(0,0,0,0.12); + box-shadow: inset 0px 0px 5px 0px rgba(0, 0, 0, 0.12); } .itemList { @@ -128,6 +128,7 @@ padding: 0px !important; margin: 0; } + .mat-list-item-content { padding: 0px; } @@ -141,6 +142,7 @@ height: auto !important; padding-top: 5px; padding-bottom: 5px; + ::ng-deep.mat-list-item-content { padding-top: 0px !important; padding-bottom: 0px !important; @@ -151,5 +153,17 @@ position: absolute; right: 8px; border-radius: 10px; - box-shadow: 0px 0px 1px 0px rgba(0,0,0,0.75); + box-shadow: 0px 0px 1px 0px rgba(0, 0, 0, 0.75); +} + +.create-contact { + text-align: center; + display: flex; + height: auto; + position: sticky; + bottom: 0px; + width: 95px; + padding: 0px; + background: white; + box-shadow: 1px 0px 2px 0px rgba(0,0,0,0.12); } \ No newline at end of file diff --git a/src/frontend/app/contact/autocomplete/contact-autocomplete.component.ts b/src/frontend/app/contact/autocomplete/contact-autocomplete.component.ts index 343ca0702b36adee176bab3133c857c75a1bf54f..68a3aa1ae70fbfd2b9d3ecbcc1a9fc19904a6fd1 100755 --- a/src/frontend/app/contact/autocomplete/contact-autocomplete.component.ts +++ b/src/frontend/app/contact/autocomplete/contact-autocomplete.component.ts @@ -35,6 +35,8 @@ export class ContactAutocompleteComponent implements OnInit { canAdd: boolean = false; canUpdate: boolean = false; + noResultFound: boolean = null; + listInfo: string; myControl = new FormControl(); filteredOptions: Observable<string[]>; @@ -78,10 +80,14 @@ export class ContactAutocompleteComponent implements OnInit { this.options = []; this.myControl.valueChanges .pipe( - //tap((value) => this.canAdd = value.length === 0 ? false : true), + tap(() => { + this.noResultFound = null; + this.options = []; + this.listInfo = this.lang.autocompleteInfo; + }), debounceTime(300), filter(value => value.length > 2), - distinctUntilChanged(), + //distinctUntilChanged(), tap(() => this.loading = true), switchMap((data: any) => this.getDatas(data)), map((data: any) => { @@ -90,8 +96,10 @@ export class ContactAutocompleteComponent implements OnInit { }), tap((data: any) => { if (data.length === 0) { + this.noResultFound = true; this.listInfo = this.lang.noAvailableValue; } else { + this.noResultFound = false; this.listInfo = ''; } this.options = data; @@ -222,6 +230,7 @@ export class ContactAutocompleteComponent implements OnInit { resetAutocomplete() { this.options = []; this.listInfo = this.lang.autocompleteInfo; + this.myControl.setValue(''); } private _filter(value: string): string[] { @@ -287,4 +296,9 @@ export class ContactAutocompleteComponent implements OnInit { return true; } } + + resetAll() { + this.controlAutocomplete.setValue([]); + this.valuesToDisplay = {}; + } } diff --git a/src/frontend/lang/lang-en.ts b/src/frontend/lang/lang-en.ts index ca3c5d488cc594602c7d86c25ba3232f08e6a96c..8eef1283ff136d657a596c0bc7682a84f7855035 100755 --- a/src/frontend/lang/lang-en.ts +++ b/src/frontend/lang/lang-en.ts @@ -1368,5 +1368,9 @@ export const LANG_EN = { "createContact": "Create a contact", "diffusionListUpdated": "Diffusion list updated", "saveModifications": "Save modifications", + "communicationMean": "Communication mean", + "communicationMeanDesc": "Link a contact with another Maarch instance", + "see": "see", "notSavedBecauseInvalid": "Configuration not updated because some datas are invalid", + "deleteAll": "Delete all", }; diff --git a/src/frontend/lang/lang-fr.ts b/src/frontend/lang/lang-fr.ts index ec8c7a99611f1cb6dfd5d1c686056c9e0469d210..66e9cdd7f3692f89d286c98d602f8320ee967f1d 100755 --- a/src/frontend/lang/lang-fr.ts +++ b/src/frontend/lang/lang-fr.ts @@ -1412,4 +1412,5 @@ export const LANG_FR = { "communicationMeanDesc": "Lie un contact à une autre instance de maarch", "see": "voir", "notSavedBecauseInvalid": "La configuration n'a pas été mise à jour car des données sont invalides", + "deleteAll": "Tout supprimer", }; diff --git a/src/frontend/lang/lang-nl.ts b/src/frontend/lang/lang-nl.ts index e786cd485d5f0dad3420fa8d0f31d2ac930b47aa..badb6c670cc505a2e379f9a7574ba108d6bc562a 100755 --- a/src/frontend/lang/lang-nl.ts +++ b/src/frontend/lang/lang-nl.ts @@ -1393,5 +1393,9 @@ export const LANG_NL = { "createContact": "Create a contact", //_TO_TRANSLATE "diffusionListUpdated": "Diffusion list updated", //_TO_TRANSLATE "saveModifications": "Save modifications", //_TO_TRANSLATE + "communicationMean": "Communication mean", //_TO_TRANSLATE + "communicationMeanDesc": "Link a contact with another Maarch instance", //_TO_TRANSLATE + "see": "see", //_TO_TRANSLATE "notSavedBecauseInvalid": "Configuration not updated because some datas are invalid", //_TO_TRANSLATE + "deleteAll": "Delete all", //_TO_TRANSLATE };