filter Customer table + class TableFilter
This commit is contained in:
parent
d182637f41
commit
89437ca067
@ -45,6 +45,10 @@
|
||||
<logger name="org.bson" level="WARN"/>
|
||||
<logger name="org.hibernate.validator" level="WARN"/>
|
||||
<logger name="org.hibernate" level="WARN"/>
|
||||
<!-- HOWTO log Hibernate SQL queries with bind parameters
|
||||
<logger name="org.hibernate.SQL" additivity="false" level="DEBUG" />
|
||||
<logger name="org.hibernate.type" additivity="false" level="TRACE" />
|
||||
-->
|
||||
<logger name="org.hibernate.ejb.HibernatePersistence" level="OFF"/>
|
||||
<logger name="org.postgresql.jdbc" level="WARN"/>
|
||||
<logger name="org.springframework" level="WARN"/>
|
||||
|
@ -14,12 +14,26 @@
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr jhiSort [(predicate)]="predicate" [(ascending)]="reverse" [callback]="reset.bind(this)">
|
||||
<th jhiSortBy="id"><span jhiTranslate="global.field.id">ID</span> <fa-icon [icon]="'sort'"></fa-icon></th>
|
||||
<th jhiSortBy="reference"><span jhiTranslate="hsadminNgApp.customer.reference">Reference</span> <fa-icon [icon]="'sort'"></fa-icon></th>
|
||||
<th jhiSortBy="prefix"><span jhiTranslate="hsadminNgApp.customer.prefix">Prefix</span> <fa-icon [icon]="'sort'"></fa-icon></th>
|
||||
<th jhiSortBy="name"><span jhiTranslate="hsadminNgApp.customer.name">Name</span> <fa-icon [icon]="'sort'"></fa-icon></th>
|
||||
<th jhiSortBy="kind"><span jhiTranslate="hsadminNgApp.customer.kind">Kind</span> <fa-icon [icon]="'sort'"></fa-icon></thn></th>
|
||||
<th></th>
|
||||
<th jhiSortBy="id"><span jhiTranslate="global.field.id">ID</span> <fa-icon [icon]="'sort'"></fa-icon></th>
|
||||
<th jhiSortBy="reference"><span jhiTranslate="hsadminNgApp.customer.reference">Reference</span> <fa-icon [icon]="'sort'"></fa-icon></th>
|
||||
<th jhiSortBy="prefix"><span jhiTranslate="hsadminNgApp.customer.prefix">Prefix</span> <fa-icon [icon]="'sort'"></fa-icon></th>
|
||||
<th jhiSortBy="name"><span jhiTranslate="hsadminNgApp.customer.name">Name</span> <fa-icon [icon]="'sort'"></fa-icon></th>
|
||||
<th jhiSortBy="kind"><span jhiTranslate="hsadminNgApp.customer.kind">Kind</span> <fa-icon [icon]="'sort'"></fa-icon></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th><input type="text" class="form-control" [(ngModel)]="filter.criteria.reference" (keyup)="filter.trigger()"></th>
|
||||
<th><input type="text" class="form-control" [(ngModel)]="filter.criteria.prefix" (keyup)="filter.trigger()"></th>
|
||||
<th><input type="text" class="form-control" [(ngModel)]="filter.criteria.name" (keyup)="filter.trigger()"></th>
|
||||
<th>
|
||||
<select class="form-control" [(ngModel)]="filter.criteria.kind" (change)="filter.trigger()">
|
||||
<option value=""></option>
|
||||
<option>NATURAL</option>
|
||||
<option>LEGAL</option>
|
||||
</select>
|
||||
</th>
|
||||
<th><button class="btn btn-primary float-left" (click)="filter.reset()">Reset Filter</button></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody infinite-scroll (scrolled)="loadPage(page + 1)" [infiniteScrollDisabled]="page >= links['last']" [infiniteScrollDistance]="0">
|
||||
|
@ -8,6 +8,7 @@ import { AccountService } from 'app/core';
|
||||
|
||||
import { ITEMS_PER_PAGE } from 'app/shared';
|
||||
import { CustomerService } from './customer.service';
|
||||
import { TableFilter } from 'app/shared/util/tablefilter';
|
||||
|
||||
@Component({
|
||||
selector: 'jhi-customer',
|
||||
@ -23,6 +24,7 @@ export class CustomerComponent implements OnInit, OnDestroy {
|
||||
predicate: any;
|
||||
reverse: any;
|
||||
totalItems: number;
|
||||
filter: TableFilter<{ reference?: string; prefix?: string; name?: string; kind?: string }>;
|
||||
|
||||
constructor(
|
||||
protected customerService: CustomerService,
|
||||
@ -39,11 +41,15 @@ export class CustomerComponent implements OnInit, OnDestroy {
|
||||
};
|
||||
this.predicate = 'id';
|
||||
this.reverse = true;
|
||||
this.filter = new TableFilter({ reference: 'equals', prefix: 'contains', name: 'contains', kind: 'equals' }, 500, () => {
|
||||
this.loadAll();
|
||||
});
|
||||
}
|
||||
|
||||
loadAll() {
|
||||
this.customerService
|
||||
.query({
|
||||
...this.filter.buildQueryCriteria(),
|
||||
page: this.page,
|
||||
size: this.itemsPerPage,
|
||||
sort: this.sort()
|
||||
@ -96,6 +102,8 @@ export class CustomerComponent implements OnInit, OnDestroy {
|
||||
protected paginateCustomers(data: ICustomer[], headers: HttpHeaders) {
|
||||
this.links = this.parseLinks.parse(headers.get('link'));
|
||||
this.totalItems = parseInt(headers.get('X-Total-Count'), 10);
|
||||
this.page = 0;
|
||||
this.customers = [];
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
this.customers.push(data[i]);
|
||||
}
|
||||
|
40
src/main/webapp/app/shared/util/tablefilter.ts
Normal file
40
src/main/webapp/app/shared/util/tablefilter.ts
Normal file
@ -0,0 +1,40 @@
|
||||
import { Subject, Subscription } from 'rxjs';
|
||||
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
|
||||
|
||||
/**
|
||||
* Handles filtering in data tables by converting the user input to query criteria of the JHipster REST API.
|
||||
*
|
||||
* It also does not reload during a given debounce period.
|
||||
*/
|
||||
export class TableFilter<T extends {}> {
|
||||
criteria: T;
|
||||
|
||||
private criteriaChangedSubject = new Subject<void>();
|
||||
private criteriaChangedDebouncer: Subscription;
|
||||
|
||||
constructor(private query: T, private debounceMillis: number, private reload: () => void) {
|
||||
this.criteria = {} as any;
|
||||
this.criteriaChangedDebouncer = this.criteriaChangedSubject.pipe(debounceTime(debounceMillis)).subscribe(() => this.reload());
|
||||
}
|
||||
|
||||
trigger() {
|
||||
this.debounce();
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.criteria = {} as any;
|
||||
this.debounce();
|
||||
}
|
||||
|
||||
buildQueryCriteria() {
|
||||
let queryCriteria: T = {} as any;
|
||||
Object.keys(this.criteria).forEach(e => {
|
||||
queryCriteria[e + '.' + this.query[e]] = this.criteria[e];
|
||||
});
|
||||
return queryCriteria;
|
||||
}
|
||||
|
||||
private debounce() {
|
||||
this.criteriaChangedSubject.next();
|
||||
}
|
||||
}
|
86
src/test/javascript/spec/app/shared/util/tablefilter.spec.ts
Normal file
86
src/test/javascript/spec/app/shared/util/tablefilter.spec.ts
Normal file
@ -0,0 +1,86 @@
|
||||
import { TableFilter } from 'app/shared/util/tablefilter';
|
||||
|
||||
/* To run these tests in IntelliJ IDEA, you need a run configuration with
|
||||
Configuration File:
|
||||
~/Projekte/Hostsharing/hsadmin-ng/src/test/javascript/jest.conf.js
|
||||
and a Node Interpreter, e.g. if installed with nvm, this could be:
|
||||
~/.nvm/versions/node/v10.15.3/bin/node
|
||||
*/
|
||||
describe('TableFilter Tests', () => {
|
||||
describe('TableFilter', () => {
|
||||
let filter: TableFilter<{ name: string; number: string }>;
|
||||
let asynchronously: () => void;
|
||||
|
||||
beforeEach(() => {
|
||||
filter = new TableFilter({ name: 'contains', number: 'equals' }, 100, () => {
|
||||
asynchronously();
|
||||
});
|
||||
});
|
||||
|
||||
it('trigger() asynchronously calls the reload-handler', done => {
|
||||
// given
|
||||
filter.criteria.name = 'Test Filter Value';
|
||||
|
||||
// when
|
||||
filter.trigger();
|
||||
let triggerStartedAtMillis = Date.now();
|
||||
|
||||
// then
|
||||
asynchronously = () => {
|
||||
expect(Date.now()).toBeGreaterThan(triggerStartedAtMillis);
|
||||
done();
|
||||
};
|
||||
});
|
||||
|
||||
it('if trigger() is called multiple times during debounce, debounce period ands after last trigger()', done => {
|
||||
// given
|
||||
filter.criteria.name = 'Test Filter Value';
|
||||
|
||||
// when
|
||||
filter.trigger();
|
||||
let triggerStartedAtMillis = null;
|
||||
setTimeout(() => {
|
||||
filter.trigger();
|
||||
triggerStartedAtMillis = Date.now();
|
||||
}, 50);
|
||||
|
||||
// then
|
||||
asynchronously = () => {
|
||||
expect(triggerStartedAtMillis).not.toBeNull();
|
||||
expect(Date.now()).toBeGreaterThan(triggerStartedAtMillis);
|
||||
done();
|
||||
};
|
||||
});
|
||||
|
||||
it('when filter "name" is set to "test value", buildQueryCriteria() returns { "name.contains": "test value" }', () => {
|
||||
// given
|
||||
filter.criteria.name = 'test value';
|
||||
|
||||
// when
|
||||
let actual = filter.buildQueryCriteria();
|
||||
|
||||
// then
|
||||
expect(filter.buildQueryCriteria()).toEqual({ 'name.contains': 'test value' });
|
||||
});
|
||||
|
||||
it('reset() clears criteria and calls reload-handler, considering debounce period', done => {
|
||||
// given
|
||||
filter.criteria.name = 'Test Filter Value';
|
||||
|
||||
// when
|
||||
filter.trigger();
|
||||
let triggerStartedAtMillis = null;
|
||||
setTimeout(() => {
|
||||
filter.reset();
|
||||
triggerStartedAtMillis = Date.now();
|
||||
}, 50);
|
||||
|
||||
// then
|
||||
asynchronously = () => {
|
||||
expect(triggerStartedAtMillis).not.toBeNull();
|
||||
expect(Date.now()).toBeGreaterThan(triggerStartedAtMillis);
|
||||
done();
|
||||
};
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user