diff --git a/projects/core/src/lib/search/directives/search.directive.ts b/projects/core/src/lib/search/directives/search.directive.ts new file mode 100644 index 0000000..c178d4d --- /dev/null +++ b/projects/core/src/lib/search/directives/search.directive.ts @@ -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 { + @Input({ required: true }) dataSource!: IDataSource; + @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 => ({ + 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 + }); + } +} diff --git a/projects/core/src/public-api.ts b/projects/core/src/public-api.ts index 234e08d..0abb39a 100644 --- a/projects/core/src/public-api.ts +++ b/projects/core/src/public-api.ts @@ -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'; diff --git a/projects/md-ui/src/lib/data-grid/data-grid/data-grid.component.html b/projects/md-ui/src/lib/data-grid/data-grid/data-grid.component.html index 42a02d6..808babf 100644 --- a/projects/md-ui/src/lib/data-grid/data-grid/data-grid.component.html +++ b/projects/md-ui/src/lib/data-grid/data-grid/data-grid.component.html @@ -1,50 +1,49 @@ -
- @if ($data) { - - @for (column of _options.columns; track column.column) { - - +@if ($data) { +
- @if (column.title) { - {{ column.title(column.column) | async }} - } - @else { - {{ column.column | titlecase }} - } -
+ @for (column of _options.columns; track column.column) { + + - - - } - - - -
+ @if (column.title) { + {{ column.title(column.column) | async }} + } + @else { + {{ column.column | titlecase }} + } + - @if (column.value) { - {{ column.value(element[column.column]) | async }} - } - @else { - {{ element[column.column] }} - } -
- - @if(_options.pagination.enable) { - - + + @if (column.value) { + {{ column.value(element[column.column]) | async }} + } + @else { + {{ element[column.column] }} + } + + } - @if (isLoading) { - - } + + + + + @if(_options.pagination.enable) { + + } -
+ + @if (isLoading) { + + } +} + diff --git a/projects/md-ui/src/lib/data-grid/data-grid/data-grid.component.ts b/projects/md-ui/src/lib/data-grid/data-grid/data-grid.component.ts index d89a160..57528ef 100644 --- a/projects/md-ui/src/lib/data-grid/data-grid/data-grid.component.ts +++ b/projects/md-ui/src/lib/data-grid/data-grid/data-grid.component.ts @@ -85,7 +85,7 @@ export class DataGridComponent implements OnInit, OnDestr enable: true, hidePageSize: false, pageSizeOptions: [10, 25, 50, 100], - pageSize: 25 + pageSize: 10 } }; @@ -101,6 +101,12 @@ export class DataGridComponent 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 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 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