diff --git a/apps/maarch_entreprise/Views/contacts-group-administration.component.html b/apps/maarch_entreprise/Views/contacts-group-administration.component.html index e350e66369f875aca1b292dffabbc33204de8df5..443b2dae739921ff39c5cec75523d3d71d0202d0 100755 --- a/apps/maarch_entreprise/Views/contacts-group-administration.component.html +++ b/apps/maarch_entreprise/Views/contacts-group-administration.component.html @@ -32,8 +32,8 @@ <div class="form-group"> <div class="col-sm-12"> <mat-form-field> - <input matInput [(ngModel)]="contactsGroup.label" required name="label" id="label" title="{{lang.label}}" - type="text" placeholder="{{lang.label}}" maxlength="32"> + <input matInput [(ngModel)]="contactsGroup.label" required name="label" id="label" title="{{lang.label}}" type="text" placeholder="{{lang.label}}" + maxlength="32"> </mat-form-field> </div> </div> @@ -72,40 +72,44 @@ </div> <div class="col-md-8" style="padding:5px;"> <mat-form-field hintLabel="3 caractères minium"> - <span matPrefix><mat-icon class="fa fa-user-plus" color="primary"></mat-icon> </span> - <input class="autocompleteSearch" type="text" placeholder="{{lang.linkContact}}" matInput [formControl]="searchTerm" autocomplete="off" (keypress)="launchLoading();"> + <span matPrefix> + <mat-icon class="fa fa-user-plus" color="primary"></mat-icon> </span> + <input class="autocompleteSearch" type="text" placeholder="{{lang.linkContact}}" matInput [formControl]="searchTerm" autocomplete="off" + (keyup)="launchLoading();" minlength="3"> </mat-form-field> </div> - <div class="col-md-6 col-xs-6 col-md-offset-6 col-xs-offset-6"> - <mat-paginator #paginator [length]="100" [pageSize]="10"> + <div class="col-md-6 col-xs-6"> + <div class="alert alert-danger" *ngIf="dataSource && dataSource.data.length == 1000" [innerHTML]="lang.limitDataReached_1000"></div> + </div> + <div class="col-md-6 col-xs-6"> + <mat-paginator #paginatorContactList [length]="0" [pageSize]="10"> </mat-paginator> </div> </div> - <mat-table #table="matSort" [dataSource]="dataSource" matSort matSortActive="contact" matSortDirection="asc" *ngIf="dataSource"> + <mat-progress-bar mode="indeterminate" *ngIf="!dataSource && !initAutoCompleteContact"></mat-progress-bar> + <mat-table #tableContactList [dataSource]="dataSource" *ngIf="dataSource"> <ng-container matColumnDef="select"> <mat-header-cell *matHeaderCellDef style="flex:1;"> - <mat-checkbox color="primary" (change)="$event ? masterToggle() : null" - [checked]="selection.hasValue() && isAllSelected()" - [indeterminate]="selection.hasValue() && !isAllSelected()"> + <mat-checkbox color="primary" (change)="$event ? masterToggle($event) : null" [checked]="selection.hasValue()"> </mat-checkbox> </mat-header-cell> <mat-cell *matCellDef="let element" style="flex:1;"> - <mat-checkbox color="primary" (click)="$event.stopPropagation()" - (change)="$event ? selection.toggle(element.addressId) : null" - [checked]="selection.isSelected(element.addressId)"> + <mat-checkbox id="check_{{element.addressId}}" color="primary" (click)="$event.stopPropagation()" (change)="$event ? selection.toggle(element.addressId) : null" + [disabled]="isInGrp(element)" [checked]="selection.isSelected(element.addressId)"> </mat-checkbox> </mat-cell> </ng-container> <ng-container matColumnDef="contact"> - <mat-header-cell *matHeaderCellDef mat-sort-header style="flex:3;">{{lang.contact}}</mat-header-cell> + <mat-header-cell *matHeaderCellDef style="flex:3;">{{lang.contact}}</mat-header-cell> <mat-cell *matCellDef="let element" style="flex:3;"> {{element.contact}} </mat-cell> </ng-container> <ng-container matColumnDef="address"> - <mat-header-cell *matHeaderCellDef mat-sort-header style="flex:3;">{{lang.address}}</mat-header-cell> + <mat-header-cell *matHeaderCellDef style="flex:3;">{{lang.address}}</mat-header-cell> <mat-cell *matCellDef="let element" style="flex:3;"> {{element.address}} </mat-cell> </ng-container> <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row> - <mat-row *matRowDef="let element; columns: displayedColumns;" (click)="selection.toggle(element.addressId)"></mat-row> + <mat-row *matRowDef="let element; columns: displayedColumns;" (click)="selectAddress(element.addressId);" [ngStyle]="{'opacity': !isInGrp(element) ? '' : '0.5'}" + style="cursor: pointer;"></mat-row> </mat-table> <div class="form-group"> <div class="col-sm-12" style="text-align:center;margin-top:30px"> @@ -118,7 +122,9 @@ </mat-sidenav-content> <mat-sidenav *ngIf="!creationMode" #snav2 [mode]="mobileQuery.matches ? 'over' : 'side'" [fixedInViewport]="mobileQuery.matches" fixedTopGap="56" position='end' [opened]="mobileQuery.matches ? false : true" style="overflow-x:hidden;width:40%;"> - <mat-list><h3 mat-subheader>{{lang.relatedContacts}}</h3></mat-list> + <mat-list> + <h3 mat-subheader>{{lang.relatedContacts}}</h3> + </mat-list> <div class="row" style="margin:0px;"> <div class="col-md-6 col-xs-6"> <mat-form-field> @@ -126,13 +132,13 @@ </mat-form-field> </div> <div class="col-md-6 col-xs-6"> - <mat-paginator #paginatorAdded [length]="100" [pageSize]="10"> + <mat-paginator #paginatorAdded [length]="0" [pageSize]="10"> </mat-paginator> </div> </div> <mat-table #tableAdded="matSort" [dataSource]="dataSourceAdded" matSort matSortActive="contact" matSortDirection="asc"> <ng-container matColumnDef="contact"> - <mat-header-cell *matHeaderCellDef style="flex:3;">{{lang.contact}}</mat-header-cell> + <mat-header-cell *matHeaderCellDef mat-sort-header style="flex:3;">{{lang.contact}}</mat-header-cell> <mat-cell *matCellDef="let element" style="flex:3;"> {{element.contact}} </mat-cell> </ng-container> <ng-container matColumnDef="address"> @@ -152,4 +158,4 @@ </mat-table> </mat-sidenav> </mat-sidenav-container> -</div> +</div> \ No newline at end of file diff --git a/apps/maarch_entreprise/js/angular/app/administration/contacts-group-administration.component.ts b/apps/maarch_entreprise/js/angular/app/administration/contacts-group-administration.component.ts index 981225f44c67cb09c5396994e809177df8b74fe9..03a43e5d8f9bbe585bdf2249bdcb1c453f41568e 100755 --- a/apps/maarch_entreprise/js/angular/app/administration/contacts-group-administration.component.ts +++ b/apps/maarch_entreprise/js/angular/app/administration/contacts-group-administration.component.ts @@ -6,7 +6,7 @@ import { LANG } from '../translate.component'; import { NotificationService } from '../notification.service'; import { FormControl } from '@angular/forms'; import { debounceTime, switchMap, distinctUntilChanged, filter } from 'rxjs/operators'; -import { MatPaginator, MatSort, MatTableDataSource, MatSidenav } from '@angular/material'; +import { MatPaginator, MatSort, MatTableDataSource, MatSidenav, MatProgressBarModule } from '@angular/material'; import { SelectionModel } from '@angular/cdk/collections'; declare function $j(selector: any): any; @@ -31,35 +31,33 @@ export class ContactsGroupAdministrationComponent implements OnInit { contactTypeSearch: string; loading: boolean = false; + initAutoCompleteContact = true; searchTerm: FormControl = new FormControl(); - searchResult:any = []; + searchResult: any = []; - displayedColumns = ['select', 'contact', 'address']; + displayedColumns = ['select', 'contact', 'address']; displayedColumnsAdded = ['contact', 'address', 'actions']; - dataSource : any; - dataSourceAdded : any; - selection = new SelectionModel<Element>(true, []); - - /** Whether the number of selected elements matches the total number of rows. */ - isAllSelected() { - const numSelected = this.selection.selected.length; - const numRows = this.dataSource.data.length; - return numSelected === numRows; - } + dataSource: any; + dataSourceAdded: any; + selection = new SelectionModel<Element>(true, []); /** Selects all rows if they are not all selected; otherwise clear selection. */ - masterToggle() { - this.isAllSelected() ? - this.selection.clear() : - this.dataSource.data.forEach((row: any) => { - this.selection.select(row.addressId) - }); + masterToggle(event: any) { + if (event.checked) { + this.dataSource.data.forEach((row: any) => { + if (!$j("#check_" + row.addressId + '-input').is(":disabled")) { + this.selection.select(row.addressId); + } + }); + } else { + this.selection.clear(); + } } @ViewChild('snav2') sidenav: MatSidenav; - @ViewChild(MatPaginator) paginator: MatPaginator; - @ViewChild('table') sort: MatSort; + @ViewChild('paginatorContactList') paginator: MatPaginator; + //@ViewChild('tableContactList') sortContactList: MatSort; @ViewChild('paginatorAdded') paginatorAdded: MatPaginator; @ViewChild('tableAdded') sortAdded: MatSort; @@ -79,13 +77,14 @@ export class ContactsGroupAdministrationComponent implements OnInit { debounceTime(500), filter(value => value.length > 2), distinctUntilChanged(), - switchMap(data => this.http.get(this.coreUrl + 'rest/autocomplete/contacts', {params: {"search" : data, "type" : this.contactTypeSearch}})) + switchMap(data => this.http.get(this.coreUrl + 'rest/autocomplete/contacts', { params: { "search": data, "type": this.contactTypeSearch } })) ).subscribe((response: any) => { - this.searchResult = response; - this.dataSource = new MatTableDataSource(this.searchResult); + this.searchResult = response; + this.dataSource = new MatTableDataSource(this.searchResult); this.dataSource.paginator = this.paginator; - this.dataSource.sort = this.sort; + //this.dataSource.sort = this.sortContactList; }); + } ngOnDestroy(): void { @@ -99,25 +98,25 @@ export class ContactsGroupAdministrationComponent implements OnInit { this.route.params.subscribe(params => { if (typeof params['id'] == "undefined") { - this.creationMode = true; + this.creationMode = true; this.contactsGroup.public = false; - this.loading = false; + this.loading = false; } else { this.creationMode = false; this.http.get(this.coreUrl + 'rest/contactsTypes') - .subscribe((data: any) => { - this.contactTypes = data.contactsTypes; - }); + .subscribe((data: any) => { + this.contactTypes = data.contactsTypes; + }); this.http.get(this.coreUrl + 'rest/contactsGroups/' + params['id']) .subscribe((data: any) => { this.contactsGroup = data.contactsGroup; setTimeout(() => { - this.dataSourceAdded = new MatTableDataSource(this.contactsGroup.contacts); + this.dataSourceAdded = new MatTableDataSource(this.contactsGroup.contacts); this.dataSourceAdded.paginator = this.paginatorAdded; - this.dataSourceAdded.sort = this.sortAdded; + this.dataSourceAdded.sort = this.sortAdded; }, 0); this.loading = false; @@ -126,29 +125,29 @@ export class ContactsGroupAdministrationComponent implements OnInit { }); } - saveContactsList(elem:any): void { - elem.textContent = this.lang.loading+'...'; + saveContactsList(elem: any): void { + elem.textContent = this.lang.loading + '...'; elem.disabled = true; - this.http.post(this.coreUrl + 'rest/contactsGroups/'+ this.contactsGroup.id+'/contacts', {'contacts': this.selection.selected}) + this.http.post(this.coreUrl + 'rest/contactsGroups/' + this.contactsGroup.id + '/contacts', { 'contacts': this.selection.selected }) .subscribe((data: any) => { this.notify.success(this.lang.contactAdded); this.selection.clear(); elem.textContent = this.lang.add; this.contactsGroup = data.contactsGroup; setTimeout(() => { - this.dataSourceAdded = new MatTableDataSource(this.contactsGroup.contacts); + this.dataSourceAdded = new MatTableDataSource(this.contactsGroup.contacts); this.dataSourceAdded.paginator = this.paginatorAdded; - this.dataSourceAdded.sort = this.sortAdded; + this.dataSourceAdded.sort = this.sortAdded; }, 0); }, (err) => { this.notify.error(err.error.errors); - }); + }); } onSubmit() { if (this.creationMode) { this.http.post(this.coreUrl + 'rest/contactsGroups', this.contactsGroup) - .subscribe((data:any) => { + .subscribe((data: any) => { this.router.navigate(['/administration/contacts-groups/' + data.contactsGroup]); this.notify.success(this.lang.contactsGroupAdded); }, (err) => { @@ -179,12 +178,12 @@ export class ContactsGroupAdministrationComponent implements OnInit { .subscribe(() => { var lastElement = this.contactsGroup.contacts.length - 1; this.contactsGroup.contacts[row] = this.contactsGroup.contacts[lastElement]; - this.contactsGroup.contacts[row].position = row; + this.contactsGroup.contacts[row].position = row; this.contactsGroup.contacts.splice(lastElement, 1); - this.dataSourceAdded = new MatTableDataSource(this.contactsGroup.contacts); + this.dataSourceAdded = new MatTableDataSource(this.contactsGroup.contacts); this.dataSourceAdded.paginator = this.paginatorAdded; - this.dataSourceAdded.sort = this.sortAdded; + this.dataSourceAdded.sort = this.sortAdded; this.notify.success(this.lang.contactDeletedFromGroup); }, (err) => { this.notify.error(err.error.errors); @@ -192,6 +191,25 @@ export class ContactsGroupAdministrationComponent implements OnInit { } launchLoading() { - this.dataSource = null; + if (this.searchTerm.value.length > 2) { + this.dataSource = null; + this.initAutoCompleteContact = false; + } + } + + isInGrp(address: any): boolean { + let isInGrp = false; + this.contactsGroup.contacts.forEach((row: any) => { + if (row.addressId == address.addressId) { + isInGrp = true; + } + }); + return isInGrp; + } + + selectAddress(addressId:any) { + if (!$j("#check_" + addressId + '-input').is(":disabled")) { + this.selection.toggle(addressId); + } } } diff --git a/apps/maarch_entreprise/js/angular/app/app-material.module.ts b/apps/maarch_entreprise/js/angular/app/app-material.module.ts index fe5c97a7ae893ea0472a718f25719392e9c0696d..2c231f9cc4baa0a147235101afbf2d39c06023de 100644 --- a/apps/maarch_entreprise/js/angular/app/app-material.module.ts +++ b/apps/maarch_entreprise/js/angular/app/app-material.module.ts @@ -58,6 +58,7 @@ import { MatCardModule, MatButtonToggleModule, MatProgressSpinnerModule, + MatProgressBarModule, MatToolbarModule, MatMenuModule, MatGridListModule, @@ -98,6 +99,7 @@ import { getFrenchPaginatorIntl } from './french-paginator-intl'; MatCardModule, MatButtonToggleModule, MatProgressSpinnerModule, + MatProgressBarModule, MatToolbarModule, MatMenuModule, MatGridListModule, @@ -130,6 +132,7 @@ import { getFrenchPaginatorIntl } from './french-paginator-intl'; MatCardModule, MatButtonToggleModule, MatProgressSpinnerModule, + MatProgressBarModule, MatToolbarModule, MatMenuModule, MatGridListModule, diff --git a/apps/maarch_entreprise/js/angular/lang/lang-en.ts b/apps/maarch_entreprise/js/angular/lang/lang-en.ts index 2fe8a4153ad76d4f809fe4aa864c99b5efc9e418..56786d32e83b5af7a683420a8881a498f6307682 100755 --- a/apps/maarch_entreprise/js/angular/lang/lang-en.ts +++ b/apps/maarch_entreprise/js/angular/lang/lang-en.ts @@ -189,6 +189,7 @@ export const LANG_EN = { "lastname" : "Lastname", "life_cycle" : "Life cycle", "limitDataReached" : "You have reached max display datas (<b>25000 datas</b>), refine your <b>date range</b>", + "limitDataReached_1000" : "You have reached max display datas (<b>1000 datas</b>).", "linkDetails" : "Access to details", "linkEntityToUserInfo" : "Click on entity of tree to link / unlink to this user", "linkGroup" : "Link a group", diff --git a/apps/maarch_entreprise/js/angular/lang/lang-fr.ts b/apps/maarch_entreprise/js/angular/lang/lang-fr.ts index 0b31db43566a4769560703a2b6fab21695662d62..a849904aeb6acbeea510d79cc17ccad4f3dfb1e3 100755 --- a/apps/maarch_entreprise/js/angular/lang/lang-fr.ts +++ b/apps/maarch_entreprise/js/angular/lang/lang-fr.ts @@ -242,6 +242,7 @@ export const LANG_FR = { "lastname" : "Nom", "life_cycle" : "Cycle de vie", "limitDataReached" : "Vous avez atteint la limite d'affichage (<b>25000 entrées</b>), veuillez affiner votre <b>plage de dates</b>", + "limitDataReached_1000" : "Limite de <b>1000 entrées</b> atteinte.", "linkDetails" : "Accédez à la fiche détaillée", "linkEntityToUserInfo" : "Cliquez sur une entité de l'arborescence pour l'associer / dissocier à l'utilisateur", "linkGroup" : "Associer un groupe",