update
This commit is contained in:
		
							parent
							
								
									860d48005e
								
							
						
					
					
						commit
						aa4f9b4f8d
					
				
							
								
								
									
										58
									
								
								projects/core/src/lib/search/directives/search.directive.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								projects/core/src/lib/search/directives/search.directive.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,58 @@ | ||||
| import {Directive, HostListener, Input} from '@angular/core'; | ||||
| import {FilterType, ICompositeFilter, IDataSource, IFilter, ISimpleFilter} from "@openharbor/data"; | ||||
| 
 | ||||
| type FilterTypeString = `${FilterType}`; | ||||
| 
 | ||||
| @Directive({ | ||||
|   selector: '[duiSearch]', | ||||
|   standalone: true | ||||
| }) | ||||
| export class SearchDirective<TModel> { | ||||
|   @Input({ required: true }) dataSource!: IDataSource<TModel>; | ||||
|   @Input({ required: true }) filterPaths!: string[]; | ||||
|   @Input() filterType: FilterTypeString = FilterType.CONTAINS; | ||||
| 
 | ||||
|   filterValue?: string; | ||||
|   lastUsedFilter?: IFilter; | ||||
| 
 | ||||
|   @HostListener('search', ['$event']) onSearch(event: Event): void { | ||||
|     console.log('Search event triggered', event); | ||||
|     this.filterValue = (event.target as any)?.value ?? ''; | ||||
|     this.applySearch(); | ||||
|   } | ||||
| 
 | ||||
|   applySearch() { | ||||
|     const existingFilters = this.dataSource.filters; | ||||
| 
 | ||||
|     // adapt current filters to remove the previous one if exist
 | ||||
|     // and replace with new one.
 | ||||
|     const finalNewFilters = existingFilters | ||||
|       .filter(t => t !== this.lastUsedFilter); | ||||
| 
 | ||||
|     if (this.filterValue) { | ||||
|       const newFilter: ICompositeFilter = { | ||||
|         and: true, | ||||
|         type: FilterType.COMPOSITE, | ||||
|         filters: this.filterPaths.map(filterPath => (<ISimpleFilter>{ | ||||
|           path: filterPath, | ||||
|           type: this.filterType, | ||||
|           value: this.filterValue, | ||||
|           and: false | ||||
|         })) | ||||
|       }; | ||||
| 
 | ||||
|       finalNewFilters.push(newFilter); | ||||
| 
 | ||||
|       // update last used filter to replace it if changed.
 | ||||
|       this.lastUsedFilter = newFilter; | ||||
|     } else { | ||||
|       this.lastUsedFilter = undefined; | ||||
|     } | ||||
| 
 | ||||
|     // execute search.
 | ||||
|     this.dataSource.query({ | ||||
|       page: 1, | ||||
|       filters: finalNewFilters | ||||
|     }); | ||||
|   } | ||||
| } | ||||
| @ -5,3 +5,4 @@ | ||||
| export * from './lib/command/directives/command.directive'; | ||||
| export * from './lib/command/abstractions/command-directive-service.abstraction'; | ||||
| export * from './lib/command/directives/command-form.directive'; | ||||
| export * from './lib/search/directives/search.directive'; | ||||
|  | ||||
| @ -1,50 +1,49 @@ | ||||
| <div class="mat-elevation-z8"> | ||||
|   @if ($data) { | ||||
|     <table mat-table [dataSource]="$data" matSort | ||||
|        (matSortChange)="onSortChanged($event)"> | ||||
|       @for (column of _options.columns; track column.column) { | ||||
|         <ng-container [matColumnDef]="column.column"> | ||||
|           <th mat-header-cell *matHeaderCellDef | ||||
|               [mat-sort-header]="column.sorting && column.sorting.path ? column.sorting.path : column.column" | ||||
|               [disabled]="!(column.sorting?.enable)" | ||||
|               [sortActionDescription]="column.sorting && column.sorting.description ? (column.sorting.description(column.column) | async) ?? '' : 'Sort by ' + column.column"> | ||||
|             @if (column.title) { | ||||
|               {{ column.title(column.column) | async }} | ||||
|             } | ||||
|             @else { | ||||
|               {{ column.column | titlecase }} | ||||
|             } | ||||
|           </th> | ||||
| @if ($data) { | ||||
|   <table mat-table [dataSource]="$data" matSort | ||||
|      (matSortChange)="onSortChanged($event)"> | ||||
|     @for (column of _options.columns; track column.column) { | ||||
|       <ng-container [matColumnDef]="column.column"> | ||||
|         <th mat-header-cell *matHeaderCellDef | ||||
|             [mat-sort-header]="column.sorting && column.sorting.path ? column.sorting.path : column.column" | ||||
|             [disabled]="!(column.sorting?.enable)" | ||||
|             [sortActionDescription]="column.sorting && column.sorting.description ? (column.sorting.description(column.column) | async) ?? '' : 'Sort by ' + column.column"> | ||||
|           @if (column.title) { | ||||
|             {{ column.title(column.column) | async }} | ||||
|           } | ||||
|           @else { | ||||
|             {{ column.column | titlecase }} | ||||
|           } | ||||
|         </th> | ||||
| 
 | ||||
|           <td mat-cell *matCellDef="let element"> | ||||
|             @if (column.value) { | ||||
|               {{ column.value(element[column.column]) | async }} | ||||
|             } | ||||
|             @else { | ||||
|               {{ element[column.column] }} | ||||
|             } | ||||
|           </td> | ||||
|         </ng-container> | ||||
|       } | ||||
| 
 | ||||
|       <tr mat-header-row *matHeaderRowDef="getColumns()"></tr> | ||||
|       <tr mat-row *matRowDef="let row; columns: getColumns();"></tr> | ||||
|     </table> | ||||
| 
 | ||||
|     @if(_options.pagination.enable) { | ||||
|       <mat-paginator | ||||
|         [disabled]="isLoading" | ||||
|         [hidePageSize]="_options.pagination.hidePageSize" | ||||
|         [pageSizeOptions]="_options.pagination.pageSizeOptions" | ||||
|         (page)="onPaginationEvent($event)" | ||||
|         [length]="totalRecords" | ||||
|         showFirstLastButtons | ||||
|         aria-label="Select page of periodic elements"> | ||||
|       </mat-paginator> | ||||
|         <td mat-cell *matCellDef="let element"> | ||||
|           @if (column.value) { | ||||
|             {{ column.value(element[column.column]) | async }} | ||||
|           } | ||||
|           @else { | ||||
|             {{ element[column.column] }} | ||||
|           } | ||||
|         </td> | ||||
|       </ng-container> | ||||
|     } | ||||
| 
 | ||||
|     @if (isLoading) { | ||||
|       <mat-progress-bar mode="query"></mat-progress-bar> | ||||
|     } | ||||
|     <tr mat-header-row *matHeaderRowDef="getColumns()"></tr> | ||||
|     <tr mat-row *matRowDef="let row; columns: getColumns();"></tr> | ||||
|   </table> | ||||
| 
 | ||||
|   @if(_options.pagination.enable) { | ||||
|     <mat-paginator | ||||
|       [disabled]="isLoading" | ||||
|       [hidePageSize]="_options.pagination.hidePageSize" | ||||
|       [pageSizeOptions]="_options.pagination.pageSizeOptions" | ||||
|       (page)="onPaginationEvent($event)" | ||||
|       [length]="totalRecords" | ||||
|       showFirstLastButtons | ||||
|       aria-label="Select page of periodic elements"> | ||||
|     </mat-paginator> | ||||
|   } | ||||
| </div> | ||||
| 
 | ||||
|   @if (isLoading) { | ||||
|     <mat-progress-bar mode="query"></mat-progress-bar> | ||||
|   } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -85,7 +85,7 @@ export class DataGridComponent<TModel extends object> implements OnInit, OnDestr | ||||
|       enable: true, | ||||
|       hidePageSize: false, | ||||
|       pageSizeOptions: [10, 25, 50, 100], | ||||
|       pageSize: 25 | ||||
|       pageSize: 10 | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
| @ -101,6 +101,12 @@ export class DataGridComponent<TModel extends object> implements OnInit, OnDestr | ||||
|       ...this.options | ||||
|     }; | ||||
| 
 | ||||
|     this.setPageSize(this._options.pagination.pageSize); | ||||
| 
 | ||||
|     this.subscriptions.push(this.dataSource.loading$ | ||||
|       .subscribe(loading => this.isLoading = loading) | ||||
|     ); | ||||
| 
 | ||||
|     this.$data = this.dataSource.data$ | ||||
|       .pipe( | ||||
|         tap((result => { | ||||
| @ -110,10 +116,6 @@ export class DataGridComponent<TModel extends object> implements OnInit, OnDestr | ||||
|           return result?.data ?? []; | ||||
|         }) | ||||
|       ); | ||||
| 
 | ||||
|     this.subscriptions.push(this.dataSource.loading$ | ||||
|       .subscribe(loading => this.isLoading = loading) | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   ngOnDestroy() { | ||||
| @ -145,6 +147,7 @@ export class DataGridComponent<TModel extends object> implements OnInit, OnDestr | ||||
|       this.dataSource.sorts = this.dataSource.sorts.filter(sort => sort.path !== state.active); | ||||
|     } else { | ||||
|       let field = this.dataSource.sorts.find(field => field.path === state.active); | ||||
| 
 | ||||
|       if (field === undefined) { | ||||
|         field = { | ||||
|           path: state.active | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user