UNPKG

adn-datatable

Version:

Datatable component integrable to any angular project.

1,128 lines (1,101 loc) 134 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ import { Component, Input, ViewChild, Renderer2, ElementRef, ViewChildren, QueryList } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; import { HttpClient, HttpHeaders } from '@angular/common/http'; /** * @record */ export function SearchDate() { } /** @type {?} */ SearchDate.prototype.dateColumn; /** @type {?} */ SearchDate.prototype.dateFrom; /** @type {?} */ SearchDate.prototype.dateTo; /** * @record */ export function Order() { } /** @type {?} */ Order.prototype.column; /** @type {?} */ Order.prototype.dir; /** * @record */ export function RequestBody() { } /** @type {?} */ RequestBody.prototype.userId; /** @type {?} */ RequestBody.prototype.draw; /** @type {?} */ RequestBody.prototype.start; /** @type {?} */ RequestBody.prototype.length; /** @type {?} */ RequestBody.prototype.searchText; /** @type {?} */ RequestBody.prototype.order; /** @type {?} */ RequestBody.prototype.searchables; /** @type {?} */ RequestBody.prototype.searchDate; /** * @record */ export function Info() { } /** @type {?} */ Info.prototype.admins; /** @type {?} */ Info.prototype.users; /** * @record */ export function ResponseBody() { } /** @type {?} */ ResponseBody.prototype.draw; /** @type {?} */ ResponseBody.prototype.recordsFiltered; /** @type {?} */ ResponseBody.prototype.data; /** @type {?} */ ResponseBody.prototype.info; export class DataTableComponent { /** * @param {?} http * @param {?} renderer */ constructor(http, renderer) { this.http = http; this.renderer = renderer; this.oddRowColor = "#fff"; this.evenRowColor = "#f6f6f6"; this.headerColor = "aliceblue"; this.ready = false; this.datatableWidth = "100%"; this.enableAddUser = true; this.existingUser = false; this.selectAllRows = false; this.showUsersPopup = false; this.showGrantPopup = false; this.showRevokePopup = false; this.requestBody = { userId: this.userId, draw: 0, start: 0, length: 10, searchText: "", order: { column: "", dir: "asc" }, searchables: [], searchDate: { dateColumn: "", dateFrom: "", dateTo: "" } }; this.responseBody = { draw: 0, recordsFiltered: 0, data: [], info: { admins: [], users: [] } }; this.dataDisplayed = []; this.infoTable = { admins: [], users: [] }; this.userSelected = ''; // Page number displayed this.page = 1; // Array of columnNames this.headersName = []; this.dateHeadersName = []; // Allows to switch between View mode and Edit mode this.editable = false; // Used in the angular multiselect this.dropdownList = []; this.selectedItems = new Map(); this.dropdownSettings = { singleSelection: false, text: "Filtrer", selectAllText: 'Tout sélectionner', unSelectAllText: 'Tout désélectionner', enableSearchFilter: true }; // Boolean to check if the table is ready to be displayed this.readyToDisplay = false; // Boolean to show the loading or not this.loading = false; this.dataSubject = new BehaviorSubject(""); this.data$ = this.dataSubject.asObservable(); //regex = /[0-9]{2}[-|\/]{1}[0-9]{2}[-|\/]{1}[0-9]{4}/; this.regex = /([12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]))/; this.val = false; } /** * @return {?} */ ngOnDestroy() { this.subscription.unsubscribe(); } /** * @return {?} */ ngAfterViewInit() { //adding color this.datatableRows.changes.subscribe(rows => { rows.toArray().forEach((row, index) => { if (index % 2) row.nativeElement.style["background"] = this.oddRowColor; else row.nativeElement.style["background"] = this.evenRowColor; }); this.datatableHeader.nativeElement.style["background-color"] = this.headerColor; this.datatableDiv.nativeElement.style["max-width"] = this.datatableWidth; }); //for( t in test) // t.setStyle({background-color:color}) // console.log(this.datatableDiv); // this.renderer.setStyle(this.datatableDiv, 'max-width', '80%'); // this.renderer.setStyle(this.datatableDiv, 'background', 'red'); console.log(this.datatableHeader); } /** * @param {?} changes * @return {?} */ ngOnChanges(changes) { if (changes["ready"] && this.ready) { this.emitData(); console.log('input changed'); } } /** * @return {?} */ ngOnInit() { // We subscribe to an emitter so every event directly affects the dataDisplayed object this.subscription = this.data$ .subscribe((toEmit) => { this.selectAllRows = false; if (this.readyToDisplay) { document.getElementById("row-all")['checked'] = false; } this.requestBody.userId = this.userId; console.log(toEmit); console.log(this.requestBody); this.requestBody.draw = this.requestBody.draw + 1; this.getData().subscribe((dataReceived) => { if (this.readyToDisplay == false) { this.headersName = []; this.dateHeadersName = []; /** @type {?} */ var original = this; //We need to fill the headersName array with the column name of the first item of the returned object Object.keys(dataReceived['data'][0]).forEach(function (key) { //Our test data object containes the column 'row' and 'deleted' from the datatable v1 if (key != "objectId" && key != "createdAt" && key != "updatedAt" && key != "AuthUserIds") { original.headersName.push(key); } }); this.headersName.forEach(column => { if (this.isDate(dataReceived['data'][0][column])) { this.dateHeadersName.push(column); } }); //We need to initialize the dropdown with the column names if (this.headersName.length > 0) { /** @type {?} */ let indexColumn = 0; this.dropdownList = []; for (let columnName of this.headersName) { this.dropdownList.push({ "id": indexColumn, "itemName": columnName }); indexColumn++; } } } this.responseBody = dataReceived; this.infoTable = this.responseBody.info; this.dataDisplayed = this.responseBody.data.slice(0, this.requestBody['length']); this.dataDisplayed.forEach(row => { row['selected'] = false; }); console.log(this.dataDisplayed); this.loading = false; this.readyToDisplay = true; }); }); } /** * @return {?} */ selectAll() { this.selectAllRows = document.getElementById("row-all")['checked']; console.log(this.selectAllRows); if (this.selectAllRows) { this.dataDisplayed.forEach((row) => { row['selected'] = true; }); } else { this.dataDisplayed.forEach((row) => { row['selected'] = false; }); } } /** * @param {?} indexRow * @return {?} */ selectRow(indexRow) { if (this.editable == false) { this.dataDisplayed[indexRow].selected = !this.dataDisplayed[indexRow].selected; } } /** * @return {?} */ changeUserCall() { /** @type {?} */ var user = document.getElementById("changeUserInput")['value']; if (user != '') { this.showUsersPopup = false; this.showRevokePopup = false; this.showGrantPopup = false; this.existingUser = false; this.userId = user; this.emitData(); } } /** * @return {?} */ logSelected() { console.log(this.dataDisplayed); } /** * @param {?} column * @return {?} */ headerNameClicked(column) { console.log("click on column " + column); /** @type {?} */ const currentOrderColumn = this.requestBody['order']['column']; if (currentOrderColumn != column) { this.requestBody['order']['column'] = column; } else if (currentOrderColumn == column) { this.requestBody['order']['dir'] = this.requestBody['order']['dir'] == "asc" ? "desc" : "asc"; } this.emitData(); } /** * @return {?} */ getData() { /** @type {?} */ const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) }; return this.http.post(this.apiUrl + '/get/' + this.tableObjectId, this.requestBody, httpOptions); } /** * @param {?} oldRow * @param {?} newRow * @return {?} */ modifyData(oldRow, newRow) { delete oldRow.selected; delete newRow.selected; /** @type {?} */ var modifyBody = { "oldRow": oldRow, "newRow": newRow, "userId": this.userId }; /** @type {?} */ const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) }; return this.http.post(this.apiUrl + '/modify/' + this.tableObjectId, modifyBody, httpOptions); } /** * @return {?} */ addUserCall() { /** @type {?} */ var user = document.getElementById("addUserInput")['value']; if (user != '' && !this.infoTable.users.includes(user)) { this.enableAddUser = false; this.existingUser = false; this.addUser(user).subscribe((dataReceived) => { console.log(dataReceived); this.enableAddUser = true; this.emitData(); }); } else if (this.infoTable.users.includes(user)) { this.existingUser = true; } } /** * @param {?} newUser * @return {?} */ addUser(newUser) { /** @type {?} */ var newUserBody = { "userId": newUser }; /** @type {?} */ const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) }; return this.http.put(this.apiUrl + '/users/' + this.tableObjectId, newUserBody, httpOptions); } /** * @param {?} user * @return {?} */ deleteUserCall(user) { if (this.infoTable.users.includes(user)) { this.deleteUser(user).subscribe((dataReceived) => { console.log(dataReceived); this.emitData(); }); } } /** * @param {?} user * @return {?} */ deleteUser(user) { /** @type {?} */ var userBody = { "userId": user }; /** @type {?} */ const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) }; return this.http.post(this.apiUrl + '/users/' + this.tableObjectId, userBody, httpOptions); } /** * @param {?} user * @return {?} */ grantAdminCall(user) { this.grantAdmin(user).subscribe((dataReceived) => { console.log(dataReceived); this.emitData(); }); } /** * @param {?} user * @return {?} */ grantAdmin(user) { /** @type {?} */ var userBody = { "userId": user }; /** @type {?} */ const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) }; return this.http.put(this.apiUrl + '/admins/' + this.tableObjectId, userBody, httpOptions); } /** * @param {?} user * @return {?} */ revokeAdminCall(user) { this.revokeAdmin(user).subscribe((dataReceived) => { console.log(dataReceived); this.emitData(); }); } /** * @param {?} user * @return {?} */ revokeAdmin(user) { /** @type {?} */ var userBody = { "userId": user }; /** @type {?} */ const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) }; return this.http.post(this.apiUrl + '/admins/' + this.tableObjectId, userBody, httpOptions); } /** * @param {?} user * @return {?} */ grantAccessToUserCall(user) { if (user != '') { /** @type {?} */ var rowsSelected = []; this.dataDisplayed.forEach(row => { if (row['selected'] == true) { rowsSelected.push(row['objectId']); } }); this.grantAccessToUser(user, rowsSelected).subscribe((dataReceived) => { console.log(dataReceived); this.emitData(); }); } } /** * @param {?} user * @param {?} rowsSelected * @return {?} */ grantAccessToUser(user, rowsSelected) { /** @type {?} */ var userBody = { "userId": user, "rowsSelected": rowsSelected }; /** @type {?} */ const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) }; return this.http.put(this.apiUrl + '/access/' + this.tableObjectId, userBody, httpOptions); } /** * @param {?} user * @return {?} */ revokeAccessFromUserCall(user) { if (user != '') { /** @type {?} */ var rowsSelected = []; this.dataDisplayed.forEach(row => { if (row['selected'] == true) { rowsSelected.push(row['objectId']); } }); this.revokeAccessFromUser(user, rowsSelected).subscribe((dataReceived) => { console.log(dataReceived); this.emitData(); }); } } /** * @param {?} user * @param {?} rowsSelected * @return {?} */ revokeAccessFromUser(user, rowsSelected) { /** @type {?} */ var userBody = { "userId": user, "rowsSelected": rowsSelected }; /** @type {?} */ const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) }; return this.http.post(this.apiUrl + '/access/' + this.tableObjectId, userBody, httpOptions); } /** * @return {?} */ emitData() { this.loading = true; this.dataSubject.next(String(Date.now())); } /** * @return {?} */ toggleEdit() { this.editable = !this.editable; this.dataDisplayed.forEach(row => { row.selected = false; }); console.log(this.dataDisplayed); } /** * @param {?} e * @param {?} rowNumber * @param {?} colName * @return {?} */ onValueUpdate(e, rowNumber, colName) { console.log("Modified row ", rowNumber, " cell ", colName, ". From value '", this.responseBody.data[rowNumber][colName], "' to value '", e.target.value, "'."); /** @type {?} */ const oldRow = JSON.parse(JSON.stringify(this.dataDisplayed[rowNumber])); /** @type {?} */ var newRow = JSON.parse(JSON.stringify(this.dataDisplayed[rowNumber])); newRow[colName] = e.target.value; this.modifyData(oldRow, newRow).subscribe((dataReceived) => { console.log(dataReceived); this.emitData(); }); } /** * @param {?} newDateValue * @param {?} rowNumber * @param {?} colName * @return {?} */ onDateValueUpdate(newDateValue, rowNumber, colName) { console.log("Modified row ", rowNumber, " cell ", colName, ". From value '", this.responseBody.data[rowNumber][colName], "' to value '", newDateValue, "'."); /** @type {?} */ const oldRow = JSON.parse(JSON.stringify(this.dataDisplayed[rowNumber])); /** @type {?} */ var newRow = JSON.parse(JSON.stringify(this.dataDisplayed[rowNumber])); newRow[colName] = newDateValue; this.modifyData(oldRow, newRow).subscribe((dataReceived) => { console.log(dataReceived); this.emitData(); }); } /** * @param {?} row * @return {?} */ deleteRow(row) { /** @type {?} */ const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) }; /** @type {?} */ const deleteBody = { "oldRow": row, "userId": this.userId }; this.http.post(this.apiUrl + '/delete/' + this.tableObjectId, deleteBody, httpOptions).subscribe((dataReceived) => { console.log(dataReceived); this.emitData(); }); } /** * @param {?} e * @return {?} */ autoGrowTextZone(e) { e.target.style.background = 'white'; e.target.style.border = '1px solid #ccc'; e.target.style.height = "0px"; e.target.style.height = (e.target.scrollHeight + 25) + "px"; //e.target.type= "date"; } /** * @param {?} e * @return {?} */ autoResizeTextZone(e) { e.target.style.background = 'transparent'; e.target.style.border = 'none'; e.target.style.height = "0px"; e.target.style.height = "100%"; //e.target.type = "text"; } /** * @param {?} value * @return {?} */ isDate(value) { if (this.regex.test(value)) { return true; } return false; } /** * @param {?} item * @return {?} */ onItemSelect(item) { if (!this.requestBody.searchables.includes(item["itemName"])) { this.requestBody.searchables.push(item["itemName"]); this.selectedItems.set(item["id"], item["itemName"]); } this.emitData(); } /** * @param {?} item * @return {?} */ OnItemDeSelect(item) { if (!this.requestBody.searchables.includes(item["itemName"])) { this.requestBody.searchables.push(item["itemName"]); //this.selectedItems.set(item["id"],item["itemName"]); } this.emitData(); } /** * @param {?} items * @return {?} */ onSelectAll(items) { for (let item of items) { if (!this.requestBody.searchables.includes(item["itemName"])) { this.requestBody.searchables.push(item["itemName"]); } } this.emitData(); } /** * @return {?} */ onDeSelectAll() { this.requestBody.searchables = []; this.emitData(); } /** * @param {?} searchEvent * @return {?} */ searchTextInColumns(searchEvent) { this.requestBody.searchText = searchEvent; this.requestBody.start = 0; this.emitData(); } /** * @param {?} newDateColumnValue * @return {?} */ changingDateColumn(newDateColumnValue) { this.requestBody.searchDate.dateColumn = newDateColumnValue; this.requestBody.start = 0; this.emitData(); } /** * @param {?} newDateFrom * @return {?} */ searchDateFromChange(newDateFrom) { this.requestBody.searchDate.dateFrom = newDateFrom; if (this.requestBody.searchDate.dateFrom > this.requestBody.searchDate.dateTo) { this.requestBody.searchDate.dateTo = ""; } this.emitData(); } /** * @param {?} newDateTo * @return {?} */ searchDateToChange(newDateTo) { this.requestBody.searchDate.dateTo = newDateTo; if (this.requestBody.searchDate.dateFrom > this.requestBody.searchDate.dateTo) { this.requestBody.searchDate.dateFrom = ""; } this.emitData(); } /** * @param {?} value * @return {?} */ castNumber(value) { return Number(value); } /** * @param {?} a * @param {?} b * @return {?} */ MathMin(a, b) { return Math.min(a, b); } /** * @return {?} */ pageBack() { //this.dataTable.offset -= Math.min(this.dataTable.limit, this.dataTable.offset); this.requestBody['start'] -= Math.min(Number(this.requestBody['length']), Number(this.requestBody['start'])); this.page -= 1; this.emitData(); } /** * @return {?} */ pageForward() { //this.dataTable.offset += this.dataTable.limit; console.log('old start :', this.requestBody['start']); this.requestBody['start'] = Number(this.requestBody['length']) + Number(this.requestBody['start']); console.log('length :', this.requestBody['length']); console.log('new start :', this.requestBody['start']); this.page += 1; this.emitData(); } /** * @return {?} */ pageFirst() { this.requestBody['start'] = 0; this.page = 1; this.emitData(); } /** * @return {?} */ pageLast() { this.requestBody['start'] = (this.maxPage - 1) * Number(this.requestBody['length']); this.page = this.maxPage; this.emitData(); } /** * @return {?} */ get maxPage() { return Math.ceil(this.responseBody.recordsFiltered / Number(this.requestBody['length'])); } } DataTableComponent.decorators = [ { type: Component, args: [{ selector: 'data-table-component', template: ` <div *ngIf="loading" class="loader"><div class="lds-ring"><div></div><div></div><div></div><div></div></div></div> <div #datatableDiv style="margin: auto;"> <br> <div id="changeUser" class="popup-demo"> <div style="display: inline"> <span style="margin-right: 20px;">Changer d'utilisateur (Demo only (user2 for test) - actuellement '{{requestBody.userId}}')</span> <input type="text" class="addUserInput" id="changeUserInput"> <button (click)="changeUserCall()" class="popupButton"> Changer d'utilisateur </button> </div> </div> <div *ngIf="readyToDisplay"> <button *ngIf="editable" (click)="toggleEdit()" class="validateButton"> Mode vue <img class="icon" src="../assets/img/view.png"> </button> <button *ngIf="!editable" (click)="toggleEdit()" class="validateButton"> Mode édition <img class="icon" src="../assets/img/edit.png"> </button> <div *ngIf="infoTable.admins.includes(requestBody.userId)"> <button (click)="showUsersPopup = false; showRevokePopup = false; showGrantPopup = !showGrantPopup; existingUser = false;" class="adminButton" [ngClass]="{'popupSelected': (showGrantPopup)}"> <img class="icon" src="../assets/img/unlock.png"> <span>Autoriser l'accés</span> </button> <button (click)="showUsersPopup = false; showRevokePopup = !showRevokePopup; showGrantPopup = false; existingUser = false;" class="adminButton" [ngClass]="{'popupSelected': (showRevokePopup)}"> <img class="icon" src="../assets/img/lock.png"> <span>Restreindre l'accés</span> </button> <button (click)="showUsersPopup = !showUsersPopup; showRevokePopup = false; showGrantPopup = false; existingUser = false;" class="adminButton" [ngClass]="{'popupSelected': (showUsersPopup)}"> <img class="icon" src="../assets/img/user.png"> <span>Gérer les utlisateurs</span> </button> </div> </div> <div *ngIf="showUsersPopup" id="usersPopup" class="popup"> <hr> <h4>Liste des utilisateurs</h4> <hr> <div style="display: inline"> <input type="text" class="addUserInput" id="addUserInput"> <button (click)="addUserCall()" class="popupButton"> Ajouter <img class="icon" src="../assets/img/add.png"> </button> </div> <div id="existingUser" *ngIf="existingUser" style="color: purple;"> <span>Ce nom d'utilisateur existe déja dans ce datatable.</span> </div> <div *ngFor="let user of infoTable.users;" class="divUser"> <img class="icon" *ngIf="!infoTable.admins.includes(user)" src="../assets/img/user.png"> <img class="icon" *ngIf="infoTable.admins.includes(user)" src="../assets/img/admin.png"> <span>{{user}}</span> <button *ngIf="!infoTable.admins.includes(user)" (click)="grantAdminCall(user)" class="popupButton">Attribuer <br>le rôle admin</button> <button *ngIf="infoTable.admins.includes(user)" (click)="revokeAdminCall(user)" class="popupButton">Retirer <br>le rôle admin</button> <button (click)="deleteUserCall(user)" class="popupButton">Supprimer <br>de la liste</button> </div> </div> <div *ngIf="showGrantPopup" id="usersPopup" class="popup"> <hr> <h4>Attribuer l'accés aux lignes sélectionnés à un utilisateur</h4> <select class="selectUser" #selectUserGrant (change)="userSelected = selectUserGrant.value;"> <option value=''></option> <option *ngFor="let user of infoTable.users; let indexColumn = index" value='{{user}}'>{{user}}</option> </select> <button (click)="grantAccessToUserCall(userSelected)" class="popupButton">Attribuer</button> </div> <div *ngIf="showRevokePopup" id="usersPopup" class="popup"> <hr> <h4>Retirer l'accés aux lignes sélectionnés à un utilisateur</h4> <select class="selectUser" #selectUserRevoke (change)="userSelected = selectUserRevoke.value;"> <option value=''></option> <option *ngFor="let user of infoTable.users; let indexColumn = index" value='{{user}}'>{{user}}</option> </select> <button (click)="revokeAccessFromUserCall(userSelected)" class="popupButton">Retirer</button> </div> <div *ngIf="readyToDisplay"> <div class="userFilters"> <div class="dateFilter" *ngIf="dateHeadersName.length > 0"> <div class="dateFilterTop"> <span>De </span> <input type="date" [(ngModel)]="requestBody.searchDate.dateFrom" (ngModelChange)="searchDateFromChange($event)" class=" dateInput"> <img class="icon" src="../assets/img/calendar.png"> <span> à </span> <input type="date" [(ngModel)]="requestBody.searchDate.dateTo" (ngModelChange)="searchDateToChange($event)" class=" dateInput"> <img class="icon" src="../assets/img/calendar.png"> </div> <div class="dateFilterBottom"> <span>Sur la colonne </span> <select class="selectDateColumn" #selectDateColumn (change)="changingDateColumn(selectDateColumn.value);"> <option value='""' *ngIf="requestBody.searchDate.dateColumn == ''">> Sélectionner une colonne de type date</option> <option value='""' *ngIf="requestBody.searchDate.dateColumn != ''">> Annuler</option> <option *ngFor="let column of dateHeadersName; let indexColumn = index" value='{{column}}'>{{column}}</option> </select> </div> </div> <div _ngcontent-c1="" class="o_cp_controller"> <div _ngcontent-c1="" class="o_control_panel"> <div _ngcontent-c1="" class="o_cp_searchview" role="search"> <div _ngcontent-c1="" aria-autocomplete="list" class="o_searchview" role="search"> <span _ngcontent-c1="" aria-label="Advanced Search..." class="o_searchview_more fa fa-search-minus" role="img" title="Recherche avancée..."></span><div _ngcontent-c1="" class="o_searchview_input_container"> <input _ngcontent-c1="" accesskey="Q" aria-haspopup="true" class="o_searchview_input" placeholder="Recherche…" role="searchbox" type="text" name="search" [(ngModel)]="requestBody.searchText" (ngModelChange)="searchTextInColumns($event)" autocomplete="on"> <div _ngcontent-c1="" class="dropdown-menu o_searchview_autocomplete" role="menu"></div></div></div></div> <div _ngcontent-c1="" class="o_cp_right"> <angular2-multiselect name="dropdown-1" [data]="dropdownList" [(ngModel)]="selectedItems[1]" [settings]="dropdownSettings" (onSelect)="onItemSelect($event)" (onDeSelect)="OnItemDeSelect($event)" (onSelectAll)="onSelectAll($event)" (onDeSelectAll)="onDeSelectAll()" disabled> </angular2-multiselect> </div></div></div> </div> <div id="datatable"> <div id="datatable-header" #datatableHeader> <div class="datatable-index"> <input type="checkbox" id="row-all" (click)="selectAll()"> <label *ngIf="!selectAllRows" for="row-all" style="font-size:10px;">Tout</label> <label *ngIf="selectAllRows" for="row-all" style="font-size:10px;">Aucun</label> </div> <div class="datatable-main"> <div class="datatable-cell" *ngFor="let columnName of headersName; let indexColumn = index" (click)="headerNameClicked(columnName)"> <span>{{columnName}}</span> <span class="column-sort-icon"> <span class="glyphicon glyphicon-sort column-sortable-icon" *ngIf="requestBody['order']['column'] != columnName"></span> <span *ngIf="requestBody['order']['column'] == columnName"> <span class="glyphicon glyphicon-triangle-top" *ngIf="requestBody['order']['dir'] == 'asc'"></span> <span class="glyphicon glyphicon-triangle-bottom" *ngIf="requestBody['order']['dir'] != 'asc'"></span> </span> </span> </div> <div class="datatable-cell datatable-action"> <span>Actions</span> </div> </div> </div> <div id="datatable-body"> <div #datatableRows *ngFor="let row of dataDisplayed; let indexRow = index" class="datatable-row" [ngClass]="{'selectedRow': (row.selected)}"> <div class="datatable-index"> <input type="checkbox" id="row-{{indexRow}}" [(ngModel)]="row.selected"> <label for="row-{{indexRow}}">{{requestBody['start']+indexRow+1}}</label> </div> <div class="datatable-main"> <div (click)="selectRow(indexRow)" id="row-{{indexRow}}-col-{{indexCell}}" class="datatable-cell datatable-main-cell" *ngFor="let columnName of headersName; let indexCell = index"> <textarea id="row-{{indexRow}}-col-{{indexCell}}" name="row-{{indexRow}}-col-{{indexCell}}" [ngModel]="dataDisplayed[indexRow][columnName]" (change)="onValueUpdate($event, indexRow, columnName)" (focus)="autoGrowTextZone($event)" (focusout)="autoResizeTextZone($event)" *ngIf="editable && !isDate(dataDisplayed[indexRow][columnName])" type="text" class="form-control input-sm" style="background-color: transparent;" ></textarea> <input id="row-{{indexRow}}-col-{{indexCell}}" name="row-{{indexRow}}-col-{{indexCell}}" [ngModel] ="dataDisplayed[indexRow][columnName] | date:'yyyy-MM-dd'" (ngModelChange)="onDateValueUpdate($event, indexRow, columnName)" (focus)="autoGrowTextZone($event)" (focusout)="autoResizeTextZone($event)" *ngIf="editable && isDate(dataDisplayed[indexRow][columnName])" type="date" class="form-control input-sm date dateInput" style="background-color: transparent;" > <span *ngIf="!editable">{{dataDisplayed[indexRow][columnName]}}</span> <hr *ngIf="columnName == searchColumnName" style="background: red;margin: 0;width: 100%;height: 1px;"> </div> <div class="datatable-cell datatable-main-cell"> <button (click)="deleteRow(row)" class="btn btn-sm btn-default" > <img class="icon" src="../assets/img/bin.png"> </button> </div> </div> </div> </div> </div> <div class="pagination-box"> <div class="pagination-range"> Affichage: <span [textContent]="requestBody['start'] + 1"></span> - <span [textContent]="MathMin( (castNumber(requestBody['start']) + castNumber(requestBody['length'])), responseBody.recordsFiltered)"></span> / <span [textContent]="responseBody.recordsFiltered"></span> </div> <div class="pagination-controllers"> <div class="pagination-limit"> <div class="input-group"> <span class="input-group-addon">Nombre de lignes par page:</span> <input #limitInput type="number" class="form-control" min="1" step="1" [ngModel]="requestBody['length']" (blur)="requestBody['length'] = castNumber(limitInput.value); emitData()" (keyup.enter)="requestBody['length'] = castNumber(limitInput.value); emitData()" (keyup.esc)="limitInput.value = castNumber(requestBody['length'])"/> </div> </div> <div class=" pagination-pages"> <button [disabled]="requestBody['start'] <= 0" (click)="pageFirst()" class="btn btn-default pagination-firstpage" id="pageFirst">&laquo;</button> <button [disabled]="requestBody['start'] <= 0" (click)="pageBack()" class="btn btn-default pagination-prevpage">&lsaquo;</button> <div class="pagination-page"> <div class="input-group"> <input #pageInput type="number" class="form-control" min="1" step="1" max="{{maxPage}}" [ngModel]="page" (blur)="page = castNumber(pageInput.value)" (keyup.enter)="page = castNumber(pageInput.value)" (keyup.esc)="pageInput.value = castNumber(page)"/> </div> </div> <button [disabled]="(requestBody['start'] + requestBody['length']) >= responseBody.recordsFiltered" (click)="pageForward()" class="btn btn-default pagination-nextpage">&rsaquo;</button> <button [disabled]="(requestBody['start'] + requestBody['length']) >= responseBody.recordsFiltered" (click)="pageLast()" class="btn btn-default pagination-lastpage">&raquo;</button> </div> </div> </div> </div> </div> `, styles: [`textarea{resize:none;overflow:hidden;height:100%;background:0 0;border:none;border-radius:0;outline:0;box-shadow:none}.icon{margin:3px;height:20px;width:20px}.searchIcon{margin-top:auto;margin-bottom:auto;height:30px;width:30px}.noDisplay{display:none}.validateButton{width:100%;border-radius:5px;font-size:large;font-weight:600}.userFilters{margin:auto;width:100%;height:auto;padding-top:50px;border-bottom:1px solid #ccc;display:inline-flex}.dateFilter{width:45%;font-size:15px}.dateFilter>*{width:100%;margin-bottom:10px}.dateFilterTop input{background-color:#fff}.selectDateColumn{text-align:center;border-radius:20px;margin-left:15px;width:60%;padding:5px 10px;background-color:#fff}.searchFilter{display:flex;align-items:center;justify-content:center;height:auto;background:#eee;border-radius:40px;width:50%;margin-left:2%;box-shadow:0 1px 5px #959595}.multiSelect{min-width:110px;margin-left:3%;width:50%}.searchText{min-width:110px;margin-left:2%;width:25%}.fullHeightInput{height:42px;box-shadow:none;border:2px solid #eee;box-shadow:0 1px 5px #959595}.dateInput{min-width:110px;width:34%;text-align:right;margin:1%;border:none;box-shadow:0 1px 5px #959595}#datatable{display:flex;flex-direction:column;width:100%;margin-top:50px;overflow-x:scroll}#datatable-header{display:flex;flex-direction:row;width:100%;font-weight:bolder}#datatable-header .datatable-cell{padding:10px}.datatable-main{display:flex;flex-direction:row}.datatable-index{display:flex;flex-direction:row;width:50px;border:.7px ridge #aaa;text-align:center;align-items:center;justify-content:center}.datatable-index span{width:50px}.datatable-index input{width:15px}.datatable-index label{width:35px}.datatable-action{display:flex;flex-direction:row;width:100px;border:.7px ridge #aaa;text-align:center;align-items:center;justify-content:center}.datatable-action button,.datatable-action span{width:100px}#datatable-body{display:flex;flex-direction:column;width:100%}.datatable-row{display:flex;flex-direction:row;width:100%}.datatable-row:hover button,.datatable-row:hover div{background:#dadada!important}.datatable-row:nth-child(odd) button,.datatable-row:nth-child(odd) div{background:#fff}.datatable-row:nth-child(even) button,.datatable-row:nth-child(even) div{background:#f6f6f6}.datatable-cell{width:150px;border:.7px ridge #aaa;text-align:center;padding:5px;align-items:center;justify-content:center;display:flex}.datatable-cell span{margin-right:2px}input[type=date]{padding:0}.column-sort-icon{float:right;margin-right:8px}.column-sort-icon .column-sortable-icon{color:#d3d3d3}.pagination-box{position:relative;margin-top:10px;margin-bottom:30px}.pagination-range{margin-top:7px;margin-left:3px;display:inline-block}.pagination-controllers{float:right}.pagination-controllers input{min-width:60px;text-align:right}.pagination-limit{margin-right:25px;display:inline-table;width:150px}.pagination-pages{display:inline-block}.pagination-page{width:110px;display:inline-table}.pagination-box button{outline:0!important}.pagination-firstpage,.pagination-lastpage,.pagination-nextpage,.pagination-prevpage{vertical-align:top}.pagination-reload{color:gray;font-size:12px}.loader{position:fixed;width:100vw;height:100vh;background:#fff;opacity:.5;display:flex;align-items:center;justify-content:center}.lds-ring{display:inline-block;position:relative;width:128px;height:128px}.lds-ring div{box-sizing:border-box;display:block;position:absolute;width:102px;height:102px;margin:10px;border:10px solid #aaa;border-radius:50%;-webkit-animation:1.2s cubic-bezier(.5,0,.5,1) infinite lds-ring;animation:1.2s cubic-bezier(.5,0,.5,1) infinite lds-ring;border-color:#aaa transparent transparent}.lds-ring div:nth-child(1){-webkit-animation-delay:-.45s;animation-delay:-.45s}.lds-ring div:nth-child(2){-webkit-animation-delay:-.3s;animation-delay:-.3s}.lds-ring div:nth-child(3){-webkit-animation-delay:-.15s;animation-delay:-.15s}@-webkit-keyframes lds-ring{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes lds-ring{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.xsmall{font-size:8px}.xsmall .icon[_ngcontent-c2]{margin:0;height:auto;max-width:10px}.xsmall .selected-list[_ngcontent-c3] .c-btn[_ngcontent-c3]{width:100%;box-shadow:0 1px 5px #aca3a3;padding:0;cursor:pointer;display:flex}.xsmall .dateInput[_ngcontent-c2]{min-width:0;height:40%}.xsmall .searchFilter[_ngcontent-c2]{width:50%;margin-left:0}.xsmall .dateFilter[_ngcontent-c2]{min-width:50%}.xsmall .multiSelect[_ngcontent-c2]{margin-left:7%;width:50%;height:auto}.xsmall .c-btn[_ngcontent-c3]{display:inline-block;background:#fff;border:1px solid #ccc;border-radius:3px;font-size:12px;color:#333}.xsmall .data-table[_ngcontent-c4]{table-layout:auto}.small{font-size:10px}.small .dateInput[_ngcontent-c2]{min-width:0;height:40%}.small .searchFilter[_ngcontent-c2]{width:50%;margin-left:0}.small .dateFilter[_ngcontent-c2]{min-width:50%}.small .multiSelect[_ngcontent-c2]{min-width:100px;margin-left:7%;width:50%;height:auto}.small .c-btn[_ngcontent-c3]{display:inline-block;background:#fff;border:1px solid #ccc;border-radius:3px;font-size:12px;color:#333}.o_control_panel[_ngcontent-c1]{display:flex;flex-flow:column wrap-reverse;padding-top:10px;padding-right:16px;padding-bottom:10px;background-color:#fff}.o_control_panel[_ngcontent-c1]>.o_cp_searchview[_ngcontent-c1]{width:50%;min-height:30px}@media (min-width:768px){.o_searchview[_ngcontent-c1]{border-bottom:1px solid #8f8f8f}}.o_searchview[_ngcontent-c1]{align-items:flex-end;position:relative;padding:0 20px 1px 0}.o_searchview[_ngcontent-c1] .o_searchview_more[_ngcontent-c1]{position:absolute;top:4px;left:auto;bottom:auto;right:0;font-size:16px;cursor:pointer}.o_searchview[_ngcontent-c1] .o_searchview_input_container[_ngcontent-c1]{position:relative;display:flex;flex-flow:row wrap}.o_searchview[_ngcontent-c1] .o_searchview_input_container[_ngcontent-c1] .o_searchview_input[_ngcontent-c1]{width:100px;flex:1 0 auto}.o_searchview[_ngcontent-c1] .o_searchview_input[_ngcontent-c1]{border:none;outline:0}[type=number][_ngcontent-c1],[type=password][_ngcontent-c1],[type=text][_ngcontent-c1],select[_ngcontent-c1],textarea[_ngcontent-c1]{width:100%;display:block;outline:0}button[_ngcontent-c1],input[_ngcontent-c1]{overflow:visible}button[_ngcontent-c1],input[_ngcontent-c1],optgroup[_ngcontent-c1],select[_ngcontent-c1],textarea[_ngcontent-c1]{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}.o_searchview[_ngcontent-c1] .o_searchview_input_container[_ngcontent-c1] .o_searchview_autocomplete[_ngcontent-c1]{position:absolute;top:100%;left:auto;bottom:auto;right:auto;width:100%}.dropdown-menu[_ngcontent-c1]{box-shadow:0 6px 12px -4px rgba(0,0,0,.25);position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1.08333333rem;color:#666;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid #dee2e6;border-radius:0}.o_control_panel[_ngcontent-c1]>.o_cp_right[_ngcontent-c1]{width:50%;margin-top:5px}.o_search_options[_ngcontent-c1]{margin:auto 0;display:block}.o_cp_controller{width:50%}.o_dropdown[_ngcontent-c1]{white-space:nowrap;display:inline-block;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn-group-vertical[_ngcontent-c1],.btn-group[_ngcontent-c1]{position:relative;display:inline-flex;vertical-align:middle}.adminButton{width:33.333%;border-radius:5px;font-size:large;font-weight:600}.adminButton img{width:20px;height:20px;margin-right:10px}.addUserInput,.selectUser{width:200px!important;display:inline!important;border-radius:5px}.selectedRow div{background-color:#add8e6!important}.popupButton{background:#ddd;color:#555;border:1px solid #aaa;border-radius:5px;margin:10px!important}.divUser{display:flex;align-items:inherit}.divUser span{display:block;width:200px;border-bottom:1px solid #aaa}.divUser button{width:150px}.popup{display:flex;flex-direction:column;align-items:center;background:#efefef;border-radius:0 0 10px 10px}.popup-demo{margin-bottom:40px;display:flex;flex-direction:column;align-items:center;background:#ddd;border:1px solid #333;border-radius:10px}.popupSelected{background-color:#aaa}#datatable-header,.datatable-row[_ngcontent-c1]:nth-child(even) button[_ngcontent-c1],.datatable-row[_ngcontent-c1]:nth-child(even) div[_ngcontent-c1],.datatable-row[_ngcontent-c1]:nth-child(odd) button[_ngcontent-c1],.datatable-row[_ngcontent-c1]:nth-child(odd) div[_ngcontent-c1]{background:0 0}`] },] }, ]; /** @nocollapse */ DataTableComponent.ctorParameters = () => [ { type: HttpClient }, { type: Renderer2 } ]; DataTableComponent.propDecorators = { datatableDiv: [{ type: ViewChild, args: ['datatableDiv',] }], datatableHeader: [{ type: ViewChild, args: ['datatableHeader',] }], datatableRows: [{ type: ViewChildren, args: ['datatableRows',] }], oddRowColor: [{ type: Input }], evenRowColor: [{ type: Input }], headerColor: [{ type: Input }], userId: [{ type: Input }], apiUrl: [{ type: Input }], ready: [{ type: Input }], tableObjectId: [{ type: Input }], datatableWidth: [{ type: Input }] }; if (false) { /** @type {?} */ DataTableComponent.prototype.datatableDiv; /** @type {?} */ DataTableComponent.prototype.datatableHeader; /** @type {?} */ DataTableComponent.prototype.datatableRows; /** @type {?} */ DataTableComponent.prototype.oddRowColor; /** @type {?} */ DataTableComponent.prototype.evenRowColor; /** @type {?} */ DataTableComponent.prototype.headerColor; /** @type {?} */ DataTableComponent.prototype.userId; /** @type {?} */ DataTableComponent.prototype.apiUrl; /** @type {?} */ DataTableComponent.prototype.ready; /** @type {?} */ DataTableComponent.prototype.tableObjectId; /** @type {?} */ DataTableComponent.prototype.datatableWidth; /** @type {?} */ DataTableComponent.prototype.enableAddUser; /** @type {?} */ DataTableComponent.prototype.existingUser; /** @type {?} */ DataTableComponent.prototype.selectAllRows; /** @type {?} */ DataTableComponent.prototype.showUsersPopup; /** @type {?} */ DataTableComponent.prototype.showGrantPopup; /** @type {?} */ DataTableComponent.prototype.showRevokePopup; /** @type {?} */ DataTableComponent.prototype.searchColumnName; /** @type {?} */ DataTableComponent.prototype.requestBody; /** @type {?} */ DataTableComponent.prototype.responseBody; /** @type {?} */ DataTableComponent.prototype.dataDisplayed; /** @type {?} */ DataTableComponent.prototype.infoTable; /** @type {?} */ DataTableComponent.prototype.userSelected; /** @type {?} */ DataTableComponent.prototype.page; /** @type {?} */ DataTableComponent.prototype.headersName; /** @type {?} */ DataTableComponent.prototype.dateHeadersName; /** @type {?} */ DataTableComponent.prototype.editable; /** @type {?} */ DataTableComponent.prototype.dropdownList; /** @type {?} */ DataTableComponent.prototype.selectedItems; /** @type {?} */ DataTableComponent.prototype.dropdownSettings; /** @type {?} */ DataTableComponent.prototype.readyToDisplay; /** @type {?} */ DataTableComponent.prototype.loading; /** @type {?} */ DataTableComponent.prototype.subscription; /** @type {?} */ DataTableComponent.prototype.subscriptionLoaded; /** @type {?} */ DataTableComponent.prototype.dataSubject; /** @type {?} */ DataTableComponent.prototype.data$; /** @type {?} */ DataTableComponent.prototype.regex; /** @type {?} */ DataTableComponent.prototype.val; /** @type {?} */ DataTableComponent.prototype.http; /** @type {?} */ DataTableComponent.prototype.renderer; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YS10YWJsZS1jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9hZG4tZGF0YXRhYmxlLyIsInNvdXJjZXMiOlsic3JjL2FwcC9kYXRhLXRhYmxlLWNvbXBvbmVudC9kYXRhLXRhYmxlLWNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQXFCLFNBQVMsRUFDcEMsU0FBUyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUE0QixNQUFNLG