From 490bca557113d2777353d3fcb1f8972ea96f0ea2 Mon Sep 17 00:00:00 2001
From: Guillaume Heurtier <guillaume.heurtier@maarch.org>
Date: Thu, 26 Nov 2020 17:47:21 +0100
Subject: [PATCH] FEAT #15338 TIME 3:30 added direct search in history

---
 .../controllers/BatchHistoryController.php    | 18 ++++++++
 .../history/controllers/HistoryController.php | 18 ++++++++
 ...istory-batch-administration.component.html |  7 ++-
 .../history-batch-administration.component.ts | 18 +++++---
 .../app/history/history.component.html        |  6 ++-
 src/frontend/app/history/history.component.ts | 45 +++++++++++--------
 6 files changed, 86 insertions(+), 26 deletions(-)

diff --git a/src/app/history/controllers/BatchHistoryController.php b/src/app/history/controllers/BatchHistoryController.php
index b846e9b6698..508a26e79d4 100755
--- a/src/app/history/controllers/BatchHistoryController.php
+++ b/src/app/history/controllers/BatchHistoryController.php
@@ -18,6 +18,7 @@ use Group\controllers\PrivilegeController;
 use History\models\BatchHistoryModel;
 use Slim\Http\Request;
 use Slim\Http\Response;
+use SrcCore\controllers\AutoCompleteController;
 
 class BatchHistoryController
 {
@@ -57,6 +58,23 @@ class BatchHistoryController
             $where[] = 'total_errors > 0';
         }
 
+        if (!empty($queryParams['search'])) {
+            $searchFields = ['info', 'module_name', 'event_date', 'total_processed', 'total_errors'];
+            $fields = AutoCompleteController::getInsensitiveFieldsForRequest(['fields' => $searchFields]);
+
+            $requestData = AutoCompleteController::getDataForRequest([
+                'search'        => $queryParams['search'],
+                'fields'        => $fields,
+                'where'         => $where,
+                'data'          => $data,
+                'fieldsNumber'  => 5,
+                'longField'     => true
+            ]);
+
+            $where = $requestData['where'];
+            $data = $requestData['data'];
+        }
+
         $order = !in_array($queryParams['order'], ['asc', 'desc']) ? '' : $queryParams['order'];
         $orderBy = !in_array($queryParams['orderBy'], ['event_date', 'module_name', 'total_processed', 'total_errors', 'info']) ? ['event_date DESC'] : ["{$queryParams['orderBy']} {$order}"];
 
diff --git a/src/app/history/controllers/HistoryController.php b/src/app/history/controllers/HistoryController.php
index b2d748f660c..a58998e04ed 100755
--- a/src/app/history/controllers/HistoryController.php
+++ b/src/app/history/controllers/HistoryController.php
@@ -18,6 +18,7 @@ use Action\models\ActionModel;
 use Group\controllers\PrivilegeController;
 use Resource\controllers\ResController;
 use Respect\Validation\Validator;
+use SrcCore\controllers\AutoCompleteController;
 use SrcCore\controllers\LogsController;
 use SrcCore\models\ValidatorModel;
 use History\models\HistoryModel;
@@ -110,6 +111,23 @@ class HistoryController
             $data[] = $eventTypes;
         }
 
+        if (!empty($queryParams['search'])) {
+            $searchFields = ['info', 'remote_ip', 'event_date'];
+            $fields = AutoCompleteController::getInsensitiveFieldsForRequest(['fields' => $searchFields]);
+
+            $requestData = AutoCompleteController::getDataForRequest([
+                'search'        => $queryParams['search'],
+                'fields'        => $fields,
+                'where'         => $where,
+                'data'          => $data,
+                'fieldsNumber'  => 3,
+                'longField'     => true
+            ]);
+
+            $where = $requestData['where'];
+            $data = $requestData['data'];
+        }
+
         $order = !in_array($queryParams['order'], ['asc', 'desc']) ? '' : $queryParams['order'];
         $orderBy = str_replace(['userLabel'], ['user_id'], $queryParams['orderBy']);
         $orderBy = !in_array($orderBy, ['event_date', 'user_id', 'info']) ? ['event_date DESC'] : ["{$orderBy} {$order}"];
diff --git a/src/frontend/app/administration/history/batch/history-batch-administration.component.html b/src/frontend/app/administration/history/batch/history-batch-administration.component.html
index 99e2989fd87..ac075d43357 100755
--- a/src/frontend/app/administration/history/batch/history-batch-administration.component.html
+++ b/src/frontend/app/administration/history/batch/history-batch-administration.component.html
@@ -89,8 +89,11 @@
                                         </mat-optgroup>
                                     </ng-container>
                                 </ng-container>
-
                             </mat-autocomplete>
+                            <button mat-button matSuffix mat-icon-button (click)="directSearchHistory()" [title]="'lang.search' | translate" style="float: right">
+                                <mat-icon color="primary" class="fa fa-search">
+                                </mat-icon>
+                            </button>
                         </mat-form-field>
                     </div>
                     <div class="table-head-tool">
@@ -154,4 +157,4 @@
             </div>
         </div>
     </mat-sidenav-content>
-</mat-sidenav-container>
\ No newline at end of file
+</mat-sidenav-container>
diff --git a/src/frontend/app/administration/history/batch/history-batch-administration.component.ts b/src/frontend/app/administration/history/batch/history-batch-administration.component.ts
index a194c2b6bd7..ff4e6b97dd8 100644
--- a/src/frontend/app/administration/history/batch/history-batch-administration.component.ts
+++ b/src/frontend/app/administration/history/batch/history-batch-administration.component.ts
@@ -119,8 +119,12 @@ export class HistoryBatchAdministrationComponent implements OnInit {
                 startWith({}),
                 switchMap(() => {
                     this.isLoadingResults = true;
+                    let searchValue = '';
+                    if (!this.functions.empty(this.searchHistory.value)) {
+                        searchValue = '&search=' + this.searchHistory.value;
+                    }
                     return this.resultListDatabase!.getRepoIssues(
-                        this.sort.active, this.sort.direction, this.paginator.pageIndex, this.routeUrl, this.filterUrl);
+                        this.sort.active, this.sort.direction, this.paginator.pageIndex, this.routeUrl, this.filterUrl, searchValue);
                 }),
                 map(data => {
                     this.isLoadingResults = false;
@@ -273,6 +277,10 @@ export class HistoryBatchAdministrationComponent implements OnInit {
             return this.filterList[type];
         }
     }
+
+    directSearchHistory() {
+        this.refreshDao();
+    }
 }
 
 export interface HistoryList {
@@ -283,11 +291,11 @@ export class HistoryListHttpDao {
 
     constructor(private http: HttpClient) { }
 
-    getRepoIssues(sort: string, order: string, page: number, href: string, search: string): Observable<HistoryList> {
+    getRepoIssues(sort: string, order: string, page: number, href: string, search: string, directSearchValue: string): Observable<HistoryList> {
 
-        let offset = page * 10;
-        const requestUrl = `${href}?limit=10&offset=${offset}&order=${order}&orderBy=${sort}${search}`;
+        const offset = page * 10;
+        const requestUrl = `${href}?limit=10&offset=${offset}&order=${order}&orderBy=${sort}${search}${directSearchValue}`;
 
         return this.http.get<HistoryList>(requestUrl);
     }
-}
\ No newline at end of file
+}
diff --git a/src/frontend/app/history/history.component.html b/src/frontend/app/history/history.component.html
index fa5afad2e58..0565aa34c06 100755
--- a/src/frontend/app/history/history.component.html
+++ b/src/frontend/app/history/history.component.html
@@ -26,6 +26,10 @@
                     </ng-container>
                 </ng-container>
             </mat-autocomplete>
+            <button mat-button matSuffix mat-icon-button (click)="directSearchHistory()" [title]="'lang.search' | translate" style="float: right">
+                <mat-icon color="primary" class="fa fa-search">
+                </mat-icon>
+            </button>
         </mat-form-field>
     </div>
     <button *ngIf="privilegeService.hasCurrentUserPrivilege('view_full_history') && privilegeService.hasCurrentUserPrivilege('view_doc_history')" color="primary" mat-icon-button [title]="!fullHistoryMode ? ('lang.viewAllHistory' | translate) : ('lang.viewActionsHistory' | translate)" (click)="switchHistoryMode()">
@@ -94,4 +98,4 @@
     <div class="mat-paginator"
         style="min-height:48px;min-height: 48px;display: flex;justify-content: end;align-items: center;padding-right: 20px;">
         {{resultsLength}} {{'lang.elements' | translate}}</div>
-</div>
\ No newline at end of file
+</div>
diff --git a/src/frontend/app/history/history.component.ts b/src/frontend/app/history/history.component.ts
index 143a369e99b..6e2a0e82843 100644
--- a/src/frontend/app/history/history.component.ts
+++ b/src/frontend/app/history/history.component.ts
@@ -7,7 +7,7 @@ import { Observable, merge, Subject, of as observableOf, of } from 'rxjs';
 import { MatDialog } from '@angular/material/dialog';
 import { MatPaginator } from '@angular/material/paginator';
 import { MatSort } from '@angular/material/sort';
-import { takeUntil, startWith, switchMap, map, catchError, filter, exhaustMap, tap, debounceTime, distinctUntilChanged, finalize } from 'rxjs/operators';
+import { takeUntil, startWith, switchMap, map, catchError, tap, finalize } from 'rxjs/operators';
 import { FormControl } from '@angular/forms';
 import { FunctionsService } from '@service/functions.service';
 import { LatinisePipe } from 'ngx-pipes';
@@ -15,16 +15,15 @@ import { PrivilegeService } from '@service/privileges.service';
 
 @Component({
     selector: 'app-history-list',
-    templateUrl: "history.component.html",
+    templateUrl: 'history.component.html',
     styleUrls: ['history.component.scss'],
 })
 export class HistoryComponent implements OnInit {
 
-    
     loading: boolean = false;
 
-    fullHistoryMode : boolean = true;
-    
+    fullHistoryMode: boolean = true;
+
     filtersChange = new EventEmitter();
 
     data: any;
@@ -56,7 +55,9 @@ export class HistoryComponent implements OnInit {
 
     loadingFilters: boolean = true;
 
-    @Input('resId') resId: number = null;
+    searchValue: any = '';
+
+    @Input() resId: number = null;
 
     @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
     @ViewChild('tableHistoryListSort', { static: true }) sort: MatSort;
@@ -77,7 +78,7 @@ export class HistoryComponent implements OnInit {
     ngOnInit(): void {
         if (this.resId !== null) {
             this.displayedColumnsHistory = ['event_date', 'info'];
-            this.fullHistoryMode = !this.privilegeService.hasCurrentUserPrivilege('view_doc_history')
+            this.fullHistoryMode = !this.privilegeService.hasCurrentUserPrivilege('view_doc_history');
         } else {
             this.displayedColumnsHistory = ['event_date', 'record_id', 'userLabel', 'info', 'remote_ip'];
         }
@@ -125,8 +126,12 @@ export class HistoryComponent implements OnInit {
                 startWith({}),
                 switchMap(() => {
                     this.isLoadingResults = true;
+                    let searchValue = '';
+                    if (!this.functions.empty(this.searchHistory.value)) {
+                        searchValue = '&search=' + this.searchHistory.value;
+                    }
                     return this.resultListDatabase!.getRepoIssues(
-                        this.sort.active, this.sort.direction, this.paginator.pageIndex, this.routeUrl, this.filterUrl, this.extraParamUrl);
+                        this.sort.active, this.sort.direction, this.paginator.pageIndex, this.routeUrl, this.filterUrl, this.extraParamUrl, searchValue);
                 }),
                 map(data => {
                     this.isLoadingResults = false;
@@ -147,8 +152,8 @@ export class HistoryComponent implements OnInit {
             return {
                 ...item,
                 userLabel : !this.functions.empty(item.userLabel) ? item.userLabel : this.translate.instant('lang.userDeleted')
-            }
-        })
+            };
+        });
         return data;
     }
 
@@ -167,8 +172,8 @@ export class HistoryComponent implements OnInit {
             this.loadingFilters = true;
             this.http.get(this.filterListUrl).pipe(
                 map((data: any) => {
-                    let deletedActions = data.actions.filter((action: any) => action.label === null).map((action: any) => action.id);
-                    let deletedUser = data.users.filter((user: any) => user.label === null).map((user: any) => user.login);
+                    const deletedActions = data.actions.filter((action: any) => action.label === null).map((action: any) => action.id);
+                    const deletedUser = data.users.filter((user: any) => user.label === null).map((user: any) => user.login);
 
                     data.actions = data.actions.filter((action: any) => action.label !== null);
                     if (deletedActions.length > 0) {
@@ -191,7 +196,7 @@ export class HistoryComponent implements OnInit {
                         return {
                             id: syst.id,
                             label: !this.functions.empty(this.translate.instant('lang.' + syst.id)) ? this.translate.instant('lang.' + syst.id) : syst.id
-                        }
+                        };
                     });
                     return data;
                 }),
@@ -269,7 +274,7 @@ export class HistoryComponent implements OnInit {
 
     generateUrlFilter() {
         this.filterUrl = '';
-        let arrTmpUrl: any[] = [];
+        const arrTmpUrl: any[] = [];
         Object.keys(this.filterUsed).forEach((type: any) => {
             this.filterUsed[type].forEach((filter: any) => {
                 if (!this.functions.empty(filter.id)) {
@@ -294,6 +299,10 @@ export class HistoryComponent implements OnInit {
             return this.filterList[type];
         }
     }
+
+    directSearchHistory() {
+        this.refreshDao();
+    }
 }
 
 export interface HistoryList {
@@ -304,11 +313,11 @@ export class HistoryListHttpDao {
 
     constructor(private http: HttpClient) { }
 
-    getRepoIssues(sort: string, order: string, page: number, href: string, search: string, extraParamUrl: string): Observable<HistoryList> {
+    getRepoIssues(sort: string, order: string, page: number, href: string, search: string, extraParamUrl: string, directSearchValue: string): Observable<HistoryList> {
 
-        let offset = page * 10;
-        const requestUrl = `${href}?limit=10&offset=${offset}&order=${order}&orderBy=${sort}${search}${extraParamUrl}`;
+        const offset = page * 10;
+        const requestUrl = `${href}?limit=10&offset=${offset}&order=${order}&orderBy=${sort}${search}${extraParamUrl}${directSearchValue}`;
 
         return this.http.get<HistoryList>(requestUrl);
     }
-}
\ No newline at end of file
+}
-- 
GitLab