diff --git a/src/frontend/app/administration/contact/customField/contacts-custom-fields-administration.component.ts b/src/frontend/app/administration/contact/customField/contacts-custom-fields-administration.component.ts index ac7044d0ef86e9b79eadb9ef8539761de38f2c61..82d265078c99830f3bbb48b534cc591e1579aab9 100644 --- a/src/frontend/app/administration/contact/customField/contacts-custom-fields-administration.component.ts +++ b/src/frontend/app/administration/contact/customField/contacts-custom-fields-administration.component.ts @@ -141,7 +141,7 @@ export class ContactsCustomFieldsAdministrationComponent implements OnInit { }), exhaustMap((data) => this.http.post('../../rest/contactsCustomFields', newCustomField)), tap((data: any) => { - newCustomField.id = data.customFieldId.id + newCustomField.id = data.id this.customFields.push(newCustomField); this.notify.success(this.lang.customFieldAdded); this.incrementCreation++; diff --git a/src/frontend/app/administration/contact/list/contacts-list-administration.component.html b/src/frontend/app/administration/contact/list/contacts-list-administration.component.html index 40c4f29ff54e10e3747b3f138a29025c950e8369..abb64ad75c71d2987e844714227880942f19317f 100644 --- a/src/frontend/app/administration/contact/list/contacts-list-administration.component.html +++ b/src/frontend/app/administration/contact/list/contacts-list-administration.component.html @@ -51,7 +51,7 @@ </mat-form-field> </div> <div class="table-head-tool"> - <mat-paginator #paginatorContactList [length]="resultsLength" [pageSize]="25" + <mat-paginator #paginatorContactList [length]="resultsLength" [pageSize]="10" class="paginatorResultList"></mat-paginator> </div> </div> diff --git a/src/frontend/app/administration/contact/list/contacts-list-administration.component.ts b/src/frontend/app/administration/contact/list/contacts-list-administration.component.ts index 1e1d3e482afc62eebcae25b2b0d8685835459588..e832611310aac8bbe047720170cd540bcfb2cf78 100644 --- a/src/frontend/app/administration/contact/list/contacts-list-administration.component.ts +++ b/src/frontend/app/administration/contact/list/contacts-list-administration.component.ts @@ -95,7 +95,7 @@ export class ContactsListAdministrationComponent implements OnInit { this.isLoadingResults = false; data = this.processPostData(data); this.resultsLength = data.count; - this.headerService.setHeader(this.lang.administration + ' ' + this.lang.contacts, '', 'fa fa-book'); + this.headerService.setHeader(this.lang.administration + ' ' + this.lang.contacts, '', ''); return data.contacts; }), catchError((err: any) => { @@ -210,8 +210,8 @@ export class ContactListHttpDao { getRepoIssues(sort: string, order: string, page: number, href: string, search: string): Observable<ContactList> { - let offset = page * 25; - const requestUrl = `${href}?limit=25&offset=${offset}&order=${order}&orderBy=${sort}&search=${search}`; + let offset = page * 10; + const requestUrl = `${href}?limit=10&offset=${offset}&order=${order}&orderBy=${sort}&search=${search}`; return this.http.get<ContactList>(requestUrl); } diff --git a/src/frontend/app/administration/contact/page/contacts-page-administration.component.html b/src/frontend/app/administration/contact/page/contacts-page-administration.component.html index 958ac3adc2892931d0705f94bad691e885326460..8a46de5ce777f0057b893484b93cee86398724fe 100644 --- a/src/frontend/app/administration/contact/page/contacts-page-administration.component.html +++ b/src/frontend/app/administration/contact/page/contacts-page-administration.component.html @@ -4,6 +4,14 @@ <header-panel [snavLeft]="snav"></header-panel> <menu-shortcut></menu-shortcut> <menu-nav></menu-nav> + <mat-nav-list> + <a mat-list-item *ngFor="let menu of subMenus | sortBy : 'label'" [routerLink]="menu.route"> + <mat-icon color="primary" mat-list-icon [class]="menu.icon"></mat-icon> + <p mat-line> + {{menu.label}} + </p> + </a> + </mat-nav-list> </mat-sidenav> <mat-sidenav-content> <div class="bg-head"> @@ -19,8 +27,7 @@ </div> </div> <div class="container" [class.fullContainer]="appService.getViewMode()"> - <div class="container-content"> - <button mat-button [matMenuTriggerFor]="menu">Plus d'informations...</button> + <div class="container-content" *ngIf="!loading"> <mat-menu #menu="matMenu"> <button mat-menu-item [matMenuTriggerFor]="mainInfo" [disabled]="noField('mainInfo')">Dénomination</button> @@ -58,31 +65,39 @@ <ng-container *ngFor="let unit of contactUnit"> <div *ngIf="!isEmptyUnit(unit.id)"> <mat-list> - <h3 mat-subheader class="unitTitle">{{unit.label}}</h3> - <ng-container *ngFor="let field of contactForm"> - <mat-list-item class="contact-item" *ngIf="field.unit === unit.id"> + <h3 mat-subheader class="unitTitle"><span style="flex:1">{{unit.label}}</span><a + *ngIf="unit.id === 'address'" (click)="addressBANMode=!addressBANMode" + style="cursor: pointer;">{{addressBANMode ? lang.switchManualAddress : lang.searchAddressDb}}</a> + </h3> + <ng-container *ngFor="let field of contactForm;let i=index"> + <mat-list-item class="contact-item" + *ngIf="(field.unit === unit.id && unit.id !== 'address') || (field.unit === unit.id && unit.id === 'address' && !addressBANMode)"> <p mat-line class="contact-content" *ngIf="field.default"> <ng-container *ngIf="field.type === 'string'"> <mat-form-field> <input matInput [formControl]="field.control" - [placeholder]="field.label" (blur)="checkCompany(field)"> + [placeholder]="field.label" (blur)="checkCompany(field)" + [required]="field.required"> <mat-hint *ngIf="companyFound !== null && field.id === 'company'" - align="end">Société <b>{{companyFound.company}}</b> trouvée ! cliquez <a - (click)="setAddress(companyFound)" + align="end">Société <b>{{companyFound.company}}</b> trouvée ! + cliquez <a (click)="setAddress(companyFound)" style="cursor: pointer;">ici</a> pour copier son adresse</mat-hint> + <mat-error *ngIf="field.control.hasError('required')"> + {{lang.requiredField}}</mat-error> </mat-form-field> </ng-container> <ng-container *ngIf="field.type === 'integer'"> <mat-form-field> <input type="number" matInput [formControl]="field.control" - [placeholder]="field.label" min="0" step="0.1"> + [placeholder]="field.label" min="0" step="0.1" + [required]="field.required"> </mat-form-field> </ng-container> <ng-container *ngIf="field.type === 'select'"> <plugin-select-search [label]="field.label" - [placeholderLabel]="field.label" [datas]="field.values" - (afterSelected)="launchEvent($event, field)"> + [formControlSelect]="field.control" [placeholderLabel]="field.label" + [datas]="field.values" (afterSelected)="launchEvent($event, field)"> </plugin-select-search> </ng-container> <ng-container *ngIf="field.type === 'date'"> @@ -138,103 +153,81 @@ </mat-chip-list> </ng-container> </p> - <button *ngIf="field.default && canDelete(field)" mat-icon-button matSuffix color="warn" - (click)="field.default = !field.default"> + <button *ngIf="field.default && canDelete(field)" mat-icon-button matSuffix + color="warn" (click)="field.default = !field.default"> <mat-icon class="fa fa-trash"></mat-icon> </button> </mat-list-item> - + <ng-container *ngIf="unit.id === 'address' && addressBANMode && i === 0"> + <mat-list-item> + <p mat-line class="contact-content"> + <mat-form-field appearance='outline' class="smallInput"> + <button mat-button matSuffix [matMenuTriggerFor]="menuDep" + (click)="$event.stopPropagation();initBanSearch()" + [title]="lang.targetDepartment"> + {{addressBANCurrentDepartment}} <i + class="fa fa-chevron-down"></i> + </button> + <mat-menu #menuDep="matMenu"> + <button mat-menu-item + *ngFor="let dep of departmentList">{{dep}}</button> + </mat-menu> + <mat-icon color="primary" class="fa fa-search" matPrefix + style="font-size: 15px;"></mat-icon> + <input type="text" #autoCompleteInput + [placeholder]="lang.searchAddressBan" matInput + [formControl]="addressBANControl" [matAutocomplete]="auto" + (click)="$event.stopPropagation()" + (focus)="resetAutocompleteAddressBan()" maxlength="128"> + <mat-autocomplete #auto="matAutocomplete" + (optionSelected)="selectAddressBan($event)"> + <ng-container + *ngIf="addressBANResult.length > 0 && !addressBANLoading"> + <mat-option + *ngFor="let addressBANResult of addressBANFilteredResult | async" + [value]="addressBANResult"> + {{addressBANResult.address}} + </mat-option> + </ng-container> + <mat-option class="autoCompleteInfoResult smallInputInfo" + *ngIf="addressBANResult.length === 0 && !loading" disabled + [innerHTML]="addressBANInfo"> + </mat-option> + <mat-option *ngIf="addressBANLoading" disabled> + <mat-spinner diameter="20"></mat-spinner> + </mat-option> + </mat-autocomplete> + </mat-form-field> + <mat-card style="margin:10px;" *ngIf="!emptyAddress()"> + <mat-list-item class="contact-address" (click)="goTo(contact)" + [title]="lang.address"> + <mat-icon mat-list-icon color="primary" + class="contact-group fas fa-map-marker-alt"></mat-icon> + <p mat-line class="contact-content"> + {{getValue('addressNumber')}} {{getValue('addressStreet')}} + </p> + <p mat-line class="contact-content"> + {{getValue('addressPostcode')}} {{getValue('addressTown')}} + </p> + <p mat-line class="contact-content"> + {{getValue('addressCountry')}} </p> + </mat-list-item> + </mat-card> + </p> + </mat-list-item> + </ng-container> </ng-container> </mat-list> </div> </ng-container> </div> - <div> + <div style="text-align:center;"> + <button mat-raised-button color="default" type="button" [matMenuTriggerFor]="menu">Plus + d'informations...</button> + <button mat-raised-button color="primary" type="button" (click)="onSubmit()">{{lang.validate}}</button> </div> - - - <!--<mat-list> - <h3 mat-subheader>Localisation</h3> - <mat-list-item class="contact-address" [title]="lang.address"> - <mat-icon mat-list-icon class="contact-group fas fa-map-marker-alt"></mat-icon> - <p mat-line class="contact-content addressLine_1"> - <span> - <mat-form-field> - <input matInput placeholder="{{lang.contactsParameters_address_number}}"> - </mat-form-field> - </span> - <span> - <mat-form-field> - <input matInput placeholder="{{lang.contactsParameters_address_street}}"> - </mat-form-field> - </span> - </p> - <p mat-line class="contact-content"> - <mat-form-field> - <input matInput placeholder="{{lang.contactsParameters_address_additional2}}"> - </mat-form-field> - </p> - <p mat-line class="contact-content addressLine_1"> - <span> - <mat-form-field> - <input matInput placeholder="{{lang.contactsParameters_address_postcode}}"> - </mat-form-field> - </span> - <span> - <mat-form-field> - <input matInput placeholder="{{lang.contactsParameters_address_town}}"> - </mat-form-field> - </span> - </p> - <p mat-line class="contact-content"> - <mat-form-field> - <input matInput placeholder="{{lang.contactsParameters_address_country}}"> - </mat-form-field> - </p> - </mat-list-item> - </mat-list> - <mat-list> - <h3 mat-subheader>Complément</h3> - <mat-list-item class="contact-address" [title]="lang.address"> - <mat-icon mat-list-icon class="contact-group fas fa-map-marker-alt"></mat-icon> - <p mat-line class="contact-content addressLine_1"> - <span> - <mat-form-field> - <input matInput placeholder="{{lang.contactsParameters_address_number}}"> - </mat-form-field> - </span> - <span> - <mat-form-field> - <input matInput placeholder="{{lang.contactsParameters_address_street}}"> - </mat-form-field> - </span> - </p> - <p mat-line class="contact-content"> - <mat-form-field> - <input matInput placeholder="{{lang.contactsParameters_address_additional2}}"> - </mat-form-field> - </p> - <p mat-line class="contact-content addressLine_1"> - <span> - <mat-form-field> - <input matInput placeholder="{{lang.contactsParameters_address_postcode}}"> - </mat-form-field> - </span> - <span> - <mat-form-field> - <input matInput placeholder="{{lang.contactsParameters_address_town}}"> - </mat-form-field> - </span> - </p> - <p mat-line class="contact-content"> - <mat-form-field> - <input matInput placeholder="{{lang.contactsParameters_address_country}}"> - </mat-form-field> - </p> - </mat-list-item> - </mat-list>--> </div> </div> </mat-sidenav-content> diff --git a/src/frontend/app/administration/contact/page/contacts-page-administration.component.scss b/src/frontend/app/administration/contact/page/contacts-page-administration.component.scss index 3d8f76aee6cda82914564afccae5834786feea23..f477cb8f2a72e827dc4212bcae3aa591ac756b6b 100644 --- a/src/frontend/app/administration/contact/page/contacts-page-administration.component.scss +++ b/src/frontend/app/administration/contact/page/contacts-page-administration.component.scss @@ -15,5 +15,32 @@ } .unitTitle { + display: flex; color: $primary; +} + +.contact-address { + cursor: pointer; + color: #337ab7; + + &:hover { + .contact-content { + text-decoration: underline; + } + } +} + +.smallInput { + font-size: 11px; + padding-left: 20px; + padding-right: 20px; + .mat-button { + width: 30px; + height: 30px; + color: $primary; + } + ::ng-deep.mat-form-field-infix { + padding : 0px; + padding-bottom: 5px; + } } \ No newline at end of file diff --git a/src/frontend/app/administration/contact/page/contacts-page-administration.component.ts b/src/frontend/app/administration/contact/page/contacts-page-administration.component.ts index fccb6c0b69ec5e42f5ee7db71a330feff11a79ee..564fffb693b0c0fb69720e71e55f852d6c4a2ab5 100644 --- a/src/frontend/app/administration/contact/page/contacts-page-administration.component.ts +++ b/src/frontend/app/administration/contact/page/contacts-page-administration.component.ts @@ -9,7 +9,7 @@ import { Observable, merge, Subject, of as observableOf, of } from 'rxjs'; import { MatPaginator, MatSort, MatDialog } from '@angular/material'; import { takeUntil, startWith, switchMap, map, catchError, filter, exhaustMap, tap, debounceTime, distinctUntilChanged, finalize } from 'rxjs/operators'; import { ConfirmComponent } from '../../../../plugins/modal/confirm.component'; -import { FormControl } from '@angular/forms'; +import { FormControl, Validators, ValidatorFn, AbstractControl } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; @Component({ @@ -27,6 +27,24 @@ export class ContactsPageAdministrationComponent implements OnInit { creationMode: boolean = true; + subMenus:any [] = [ + { + icon: 'fa fa-code', + route: '/administration/contactsCustomFields', + label : this.lang.customFields + }, + { + icon: 'fa fa-cog', + route: '/administration/contacts-parameters', + label : this.lang.contactsParameters + }, + { + icon: 'fa fa-users', + route: '/administration/contacts-groups', + label : this.lang.contactsGroups + }, + ]; + contactId: number = null; contactUnit = [ @@ -44,14 +62,16 @@ export class ContactsPageAdministrationComponent implements OnInit { } ]; - contactForm = [ + contactForm: any[] = [ { id: 'company', unit: 'mainInfo', label: this.lang.contactsParameters_company, type: 'string', control: new FormControl(), - default: true + required: false, + default: true, + values: [] }, { id: 'firstname', @@ -59,7 +79,9 @@ export class ContactsPageAdministrationComponent implements OnInit { label: this.lang.contactsParameters_firstname, type: 'string', control: new FormControl(), - default: false + required: false, + default: false, + values: [] }, { id: 'lastname', @@ -67,7 +89,9 @@ export class ContactsPageAdministrationComponent implements OnInit { label: this.lang.contactsParameters_lastname, type: 'string', control: new FormControl(), - default: false + required: false, + default: false, + values: [] }, { id: 'function', @@ -75,7 +99,9 @@ export class ContactsPageAdministrationComponent implements OnInit { label: this.lang.contactsParameters_function, type: 'string', control: new FormControl(), - default: false + required: false, + default: false, + values: [] }, { id: 'department', @@ -83,15 +109,9 @@ export class ContactsPageAdministrationComponent implements OnInit { label: this.lang.contactsParameters_department, type: 'string', control: new FormControl(), - default: false - }, - { - id: 'addressAdditional1', - unit: 'mainInfo', - label: this.lang.contactsParameters_address_additional1, - type: 'string', - control: new FormControl(), - default: false + required: false, + default: false, + values: [] }, { id: 'email', @@ -99,7 +119,9 @@ export class ContactsPageAdministrationComponent implements OnInit { label: this.lang.email, type: 'string', control: new FormControl(), - default: true + required: false, + default: true, + values: [] }, { id: 'phone', @@ -107,59 +129,92 @@ export class ContactsPageAdministrationComponent implements OnInit { label: this.lang.phoneNumber, type: 'string', control: new FormControl(), - default: true + required: false, + default: true, + values: [] }, { id: 'addressNumber', unit: 'address', - label: this.lang.contactsParameters_address_number, + label: this.lang.contactsParameters_addressNumber, type: 'string', control: new FormControl(), - default: false + required: false, + default: false, + values: [] }, { id: 'addressStreet', unit: 'address', - label: this.lang.contactsParameters_address_street, + label: this.lang.contactsParameters_addressStreet, + type: 'string', + control: new FormControl(), + required: false, + default: false, + values: [] + }, + { + id: 'addressAdditional1', + unit: 'address', + label: this.lang.contactsParameters_addressAdditional1, type: 'string', control: new FormControl(), - default: false + required: false, + default: false, + values: [] }, { id: 'addressAdditional2', unit: 'address', - label: this.lang.contactsParameters_address_additional2, + label: this.lang.contactsParameters_addressAdditional2, type: 'string', control: new FormControl(), - default: false + required: false, + default: false, + values: [] }, { id: 'addressPostcode', unit: 'address', - label: this.lang.contactsParameters_address_postcode, + label: this.lang.contactsParameters_addressPostcode, type: 'string', control: new FormControl(), - default: false + required: false, + default: false, + values: [] }, { id: 'addressTown', unit: 'address', - label: this.lang.contactsParameters_address_town, + label: this.lang.contactsParameters_addressTown, type: 'string', control: new FormControl(), - default: false + required: false, + default: false, + values: [] }, { id: 'addressCountry', unit: 'address', - label: this.lang.contactsParameters_address_country, + label: this.lang.contactsParameters_addressCountry, type: 'string', control: new FormControl(), - default: false + required: false, + default: false, + values: [] } ]; - companyFound:any = null; + addressBANInfo: string = ''; + addressBANMode: boolean = true; + addressBANControl = new FormControl(); + addressBANLoading: boolean = false; + addressBANResult: any[] = []; + addressBANFilteredResult: Observable<string[]>; + addressBANCurrentDepartment: string = '75'; + departmentList: any[] = []; + + companyFound: any = null; constructor( public http: HttpClient, @@ -171,6 +226,7 @@ export class ContactsPageAdministrationComponent implements OnInit { public dialog: MatDialog) { } ngOnInit(): void { + this.loading = true; this.route.params.subscribe((params: any) => { @@ -183,18 +239,12 @@ export class ContactsPageAdministrationComponent implements OnInit { this.http.get("../../rest/contactsCustomFields").pipe( tap((data: any) => { - data.customFields.forEach((element: any) => { - this.contactForm.push( - { - id: `customField_${element.id}`, - unit: 'complement', - label: element.label, - type: element.type, - control: new FormControl({ value: '', disabled: false }), - default: false - } - ); - }); + this.initCustomElementForm(data); + }), + exhaustMap(() => this.http.get("../../rest/contactsParameters")), + tap((data) => { + this.initElemForm(data); + this.initAutocompleteAddressBan(); }), finalize(() => this.loading = false), catchError((err: any) => { @@ -202,28 +252,36 @@ export class ContactsPageAdministrationComponent implements OnInit { return of(false); }) ).subscribe(); - - - this.loading = false; } else { window['MainHeaderComponent'].setSnav(this.sidenavLeft); window['MainHeaderComponent'].setSnavRight(this.sidenavRight); + this.headerService.setHeader(this.lang.contactModification); + this.creationMode = false; + this.addressBANMode = false; + this.contactForm.forEach(element => { element.default = false; }); - this.http.get("../../rest/contacts/" + params['id']).pipe( + + this.http.get("../../rest/contactsCustomFields").pipe( + tap((data: any) => { + this.initCustomElementForm(data); + }), + exhaustMap(() => this.http.get("../../rest/contactsParameters")), + tap((data) => { + this.initElemForm(data); + this.initAutocompleteAddressBan(); + }), + exhaustMap(() => this.http.get("../../rest/contacts/" + params['id'])), tap((data) => { this.contactId = params['id']; - let indexField = -1; - Object.keys(data).forEach(element => { - indexField = this.contactForm.map(field => field.id).indexOf(element); - if (!this.isEmptyValue(data[element]) && indexField > -1) { - this.contactForm[indexField].control.setValue(data[element]); - this.contactForm[indexField].default = true; - } - }); + this.setContactData(data); + }), + filter((data: any) => data.customFields !== null), + tap((data: any) => { + this.setContactCustomData(data); }), finalize(() => this.loading = false), catchError((err: any) => { @@ -235,34 +293,117 @@ export class ContactsPageAdministrationComponent implements OnInit { }); } + initElemForm(data: any) { + let valArr: ValidatorFn[] = []; + + valArr.push(Validators.required); + + data.contactsParameters.forEach((element: any) => { + if ((element.mandatory || element.filling) && this.creationMode) { + this.contactForm.filter(contact => contact.id === element.identifier)[0].default = true; + } + + if (element.mandatory) { + this.contactForm.filter(contact => contact.id === element.identifier)[0].required = true; + this.contactForm.filter(contact => contact.id === element.identifier)[0].control.setValidators(valArr); + } + }); + } + + initCustomElementForm(data: any) { + data.customFields.forEach((element: any) => { + this.contactForm.push( + { + id: `customField_${element.id}`, + unit: 'complement', + label: element.label, + type: element.type, + control: new FormControl({ value: '', disabled: false }), + required: false, + default: false, + values: element.values.map((val: any) => { return { id: val, label: val } }) + } + ); + }); + } + + setContactData(data: any) { + let indexField = -1; + Object.keys(data).forEach(element => { + indexField = this.contactForm.map(field => field.id).indexOf(element); + if (!this.isEmptyValue(data[element]) && indexField > -1) { + this.contactForm[indexField].control.setValue(data[element]); + this.contactForm[indexField].default = true; + } + }); + } + + setContactCustomData(data: any) { + let indexField = -1; + Object.keys(data.customFields).forEach(element => { + indexField = this.contactForm.map(field => field.id).indexOf('customField_' + element); + if (!this.isEmptyValue(data[element]) && indexField > -1) { + this.contactForm[indexField].control.setValue(data.customFields[element]); + this.contactForm[indexField].default = true; + } + }); + } + + initBanSearch() { + this.http.get("../../rest/ban/availableDepartments").pipe( + tap((data: any) => { + this.departmentList = data.departments; + }), + catchError((err: any) => { + this.notify.handleErrors(err); + return of(false); + }) + ).subscribe(); + } + + isValidForm() { + let state = true; + + this.contactForm.filter(contact => contact.default).forEach(element => { + if (element.control.status !== 'VALID') { + state = false; + } + element.control.markAsTouched() + }); + return state; + } + onSubmit() { - if (this.contactId !== null) { - this.updateContact(); + if (this.isValidForm()) { + if (this.contactId !== null) { + this.updateContact(); + } else { + this.createContact(); + } } else { - this.createContact(); + this.notify.error('Veuillez corriger les erreurs'); } + } createContact() { let contact: any = {}; - let customFiel:any = {}; - contact['customFields'] = []; + contact['customFields'] = {}; const regex = /customField_[.]*/g; this.contactForm.filter(field => field.default).forEach(element => { if (element.id.match(regex) !== null) { - customFiel[element.id.split('_')[1]] = element.control.value; - contact['customFields'].push(customFiel); + contact['customFields'][element.id.split('_')[1]] = element.control.value; } else { contact[element.id] = element.control.value; - } + } }); this.http.post("../../rest/contacts", contact).pipe( tap(() => { this.router.navigate(["/administration/contacts"]); this.notify.success(this.lang.contactAdded); }), - finalize(() => this.loading = false), + //finalize(() => this.loading = false), catchError((err: any) => { this.notify.handleErrors(err); return of(false); @@ -280,7 +421,7 @@ export class ContactsPageAdministrationComponent implements OnInit { this.router.navigate(["/administration/contacts"]); this.notify.success(this.lang.contactUpdated); }), - finalize(() => this.loading = false), + //finalize(() => this.loading = false), catchError((err: any) => { this.notify.handleErrors(err); return of(false); @@ -298,7 +439,7 @@ export class ContactsPageAdministrationComponent implements OnInit { initForm() { this.contactForm.forEach(element => { - element.control = new FormControl({ value: '', disabled: false }); + element.control = new FormControl({ value: '', disabled: false }); }); } @@ -337,13 +478,13 @@ export class ContactsPageAdministrationComponent implements OnInit { checkCompany(field: any) { if (field.id === 'company' && (this.companyFound === null || this.companyFound.company !== field.control.value)) { - this.http.get(`../../rest/contacts?search=${field.control.value}`).pipe( + this.http.get(`../../rest/autocomplete/contacts/company?search=${field.control.value}`).pipe( tap(() => this.companyFound = null), - filter((data:any) => data.contacts.length > 0), + filter((data: any) => data.length > 0), tap((data) => { - this.companyFound = data.contacts[0]; + this.companyFound = data[0]; }), - finalize(() => this.loading = false), + //finalize(() => this.loading = false), catchError((err: any) => { this.notify.handleErrors(err); return of(false); @@ -352,7 +493,7 @@ export class ContactsPageAdministrationComponent implements OnInit { } } - setAddress(contact: any) { + setAddress(contact: any, disableBan: boolean = true) { let indexField = -1; Object.keys(contact).forEach(element => { indexField = this.contactForm.map(field => field.id).indexOf(element); @@ -361,25 +502,107 @@ export class ContactsPageAdministrationComponent implements OnInit { this.contactForm[indexField].default = true; } }); + + this.addressBANMode = disableBan ? false : true; } canDelete(field: any) { if (field.id === "company") { const lastname = this.contactForm.filter(contact => contact.id === 'lastname')[0]; if (lastname.default && !this.isEmptyValue(lastname.control.value)) { + let valArr: ValidatorFn[] = []; + field.control.setValidators(valArr); + field.required = false; return true; } else { + let valArr: ValidatorFn[] = []; + valArr.push(Validators.required); + field.control.setValidators(valArr); + field.required = true; return false; } } else if (field.id === "lastname") { const company = this.contactForm.filter(contact => contact.id === 'company')[0]; if (company.default && !this.isEmptyValue(company.control.value)) { + let valArr: ValidatorFn[] = []; + field.control.setValidators(valArr); + field.required = false; return true; } else { + let valArr: ValidatorFn[] = []; + valArr.push(Validators.required); + field.control.setValidators(valArr); + field.required = true; return false; } + } else if (field.required) { + return false; } else { return true; } } + + initAutocompleteAddressBan() { + this.addressBANInfo = this.lang.autocompleteInfo; + this.addressBANResult = []; + this.addressBANControl.valueChanges + .pipe( + //tap((value) => this.canAdd = value.length === 0 ? false : true), + debounceTime(300), + filter(value => value.length > 2), + distinctUntilChanged(), + tap(() => this.addressBANLoading = true), + switchMap((data: any) => this.http.get('../../rest/autocomplete/banAddresses', { params: { "address": data, 'department': this.addressBANCurrentDepartment } })), + tap((data: any) => { + if (data.length === 0) { + this.addressBANInfo = this.lang.noAvailableValue; + } else { + this.addressBANInfo = ''; + } + this.addressBANResult = data; + this.addressBANFilteredResult = of(this.addressBANResult); + this.addressBANLoading = false; + }) + ).subscribe(); + } + + resetAutocompleteAddressBan() { + this.addressBANResult = []; + this.addressBANInfo = this.lang.autocompleteInfo; + } + + selectAddressBan(ev: any) { + let contact = { + addressNumber: ev.option.value.number, + addressStreet: ev.option.value.afnorName, + addressPostcode: ev.option.value.postalCode, + addressTown: ev.option.value.city, + addressCountry: 'FRANCE' + }; + this.setAddress(contact, false); + this.addressBANControl.setValue(''); + } + + getValue(identifier: string) { + return this.contactForm.filter(contact => contact.id === identifier)[0].control.value; + } + + emptyAddress() { + if (this.contactForm.filter(contact => this.isEmptyValue(contact.control.value) && ['addressNumber', 'addressStreet', 'addressPostcode', 'addressTown', 'addressCountry'].indexOf(contact.id) > -1).length > 0) { + return true; + } else { + return false; + } + } + + goTo() { + const contact = { + addressNumber: this.contactForm.filter(contact => contact.id === 'addressNumber')[0].control.value, + addressStreet: this.contactForm.filter(contact => contact.id === 'addressStreet')[0].control.value, + addressPostcode: this.contactForm.filter(contact => contact.id === 'addressPostcode')[0].control.value, + addressTown: this.contactForm.filter(contact => contact.id === 'addressTown')[0].control.value, + addressCountry: this.contactForm.filter(contact => contact.id === 'addressCountry')[0].control.value + }; + window.open(`https://www.google.com/maps/search/${contact.addressNumber}+${contact.addressStreet},+${contact.addressPostcode}+${contact.addressTown},+${contact.addressCountry}`, '_blank') + } } \ No newline at end of file diff --git a/src/frontend/lang/lang-en.ts b/src/frontend/lang/lang-en.ts index 7c1db015af9afbd6c8e4727c413d06a0fb356779..b16b4f57c48d2186f0b1e026d0a5e20166691086 100755 --- a/src/frontend/lang/lang-en.ts +++ b/src/frontend/lang/lang-en.ts @@ -1340,4 +1340,10 @@ export const LANG_EN = { "contactsList": "Contacts list", "listConfiguration": "Manage list display", "noticeGroupeOrder": "Drag and drop group to set order", + "searchAddressBan": "Search a BAN address", + "searchAddressDb": "Search in address database", + "switchManualAddress": "Switch to manual address", + "targetDepartment": "Target department", + "contactCreation": "Contact creation", + "contactModification": "Contact modification", }; diff --git a/src/frontend/lang/lang-fr.ts b/src/frontend/lang/lang-fr.ts index 3cbf1e018632042565e2b8b1a9eee20edf3b95b5..9e1d69ae80417a71a360ead5b0f2cbcc11f116fe 100755 --- a/src/frontend/lang/lang-fr.ts +++ b/src/frontend/lang/lang-fr.ts @@ -1378,4 +1378,10 @@ export const LANG_FR = { "contactsList": "Liste des contacts", "listConfiguration": "Paramétrer l'affichage de la liste", "noticeGroupeOrder": "Glisser-déposer les groupes pour définir l'ordre", + "searchAddressBan": "Recherche une adresse BAN", + "searchAddressDb": "Rechercher dans la base d'addresse", + "switchManualAddress": "Basculer en adresse manuelle", + "targetDepartment": "Département cible", + "contactCreation": "Création d'un contact", + "contactModification": "Modification d'un contact", }; diff --git a/src/frontend/lang/lang-nl.ts b/src/frontend/lang/lang-nl.ts index 2ab410b2cb8c293703365973f0c94e6a519a7d97..77c2129a23e82ccf5b57dc3abbea3775b1b0443d 100755 --- a/src/frontend/lang/lang-nl.ts +++ b/src/frontend/lang/lang-nl.ts @@ -1365,4 +1365,10 @@ export const LANG_NL = { "contactsList": "Contacts list", //_TO_TRANSLATE "listConfiguration": "Manage list display", //_TO_TRANSLATE "noticeGroupeOrder": "Drag and drop group to set order", //_TO_TRANSLATE + "searchAddressBan": "Search a BAN address", //_TO_TRANSLATE + "searchAddressDb": "Search in address database", //_TO_TRANSLATE + "switchManualAddress": "Switch to manual address", //_TO_TRANSLATE + "targetDepartment": "Target department", //_TO_TRANSLATE + "contactCreation": "Contact creation", //_TO_TRANSLATE + "contactModification": "Contact modification", //_TO_TRANSLATE };