From dccafcc900ad96a2b907b2b7fcfe5a3d23972ed2 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Thu, 2 May 2019 22:51:17 +0200 Subject: [PATCH] added TableFilter to share.component, TableFilter now with date range --- .../entities/customer/customer.component.html | 8 +-- .../entities/customer/customer.component.ts | 15 ++++- .../entities/share/share-update.component.ts | 1 - .../app/entities/share/share.component.html | 38 +++++++++--- .../app/entities/share/share.component.ts | 39 ++++++++++++ .../webapp/app/shared/util/tablefilter.ts | 45 ++++++++++++-- .../spec/app/shared/util/tablefilter.spec.ts | 59 +++++++++++++++---- 7 files changed, 171 insertions(+), 34 deletions(-) diff --git a/src/main/webapp/app/entities/customer/customer.component.html b/src/main/webapp/app/entities/customer/customer.component.html index 1eb35c75..f3183904 100644 --- a/src/main/webapp/app/entities/customer/customer.component.html +++ b/src/main/webapp/app/entities/customer/customer.component.html @@ -23,11 +23,11 @@ - - - + + + - diff --git a/src/main/webapp/app/entities/customer/customer.component.ts b/src/main/webapp/app/entities/customer/customer.component.ts index c3e4a5e0..7b66eb1d 100644 --- a/src/main/webapp/app/entities/customer/customer.component.ts +++ b/src/main/webapp/app/entities/customer/customer.component.ts @@ -41,9 +41,18 @@ 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(); - }); + this.filter = new TableFilter( + { + reference: 'reference.equals', + prefix: 'prefix.contains', + name: 'name.contains', + kind: 'kind.equals' + }, + 500, + () => { + this.loadAll(); + } + ); } loadAll() { diff --git a/src/main/webapp/app/entities/share/share-update.component.ts b/src/main/webapp/app/entities/share/share-update.component.ts index e7301309..b031a238 100644 --- a/src/main/webapp/app/entities/share/share-update.component.ts +++ b/src/main/webapp/app/entities/share/share-update.component.ts @@ -3,7 +3,6 @@ import { ActivatedRoute } from '@angular/router'; import { HttpResponse, HttpErrorResponse } from '@angular/common/http'; import { Observable } from 'rxjs'; import { filter, map } from 'rxjs/operators'; -import * as moment from 'moment'; import { JhiAlertService } from 'ng-jhipster'; import { IShare } from 'app/shared/model/share.model'; import { ShareService } from './share.service'; diff --git a/src/main/webapp/app/entities/share/share.component.html b/src/main/webapp/app/entities/share/share.component.html index 87d58b25..32883f8c 100644 --- a/src/main/webapp/app/entities/share/share.component.html +++ b/src/main/webapp/app/entities/share/share.component.html @@ -14,22 +14,42 @@ - - - - - - - + + + + + + + + + + + + + + + + - + - +
ID Document Date Value Date Action Quantity Membership ID Document Date Value Date Action Quantity Membership
+ + + +
{{share.id}}{{share.id}} {{share.documentDate | date:'mediumDate'}} {{share.valueDate | date:'mediumDate'}} {{share.action}}{{share.quantity}}{{share.quantity}}
{{share.membershipDisplayLabel}} diff --git a/src/main/webapp/app/entities/share/share.component.ts b/src/main/webapp/app/entities/share/share.component.ts index d636295f..32c7caaa 100644 --- a/src/main/webapp/app/entities/share/share.component.ts +++ b/src/main/webapp/app/entities/share/share.component.ts @@ -9,6 +9,9 @@ import { AccountService } from 'app/core'; import { ITEMS_PER_PAGE } from 'app/shared'; import { ShareService } from './share.service'; +import { TableFilter, queryYearAsDateRange, queryEquals } from 'app/shared/util/tablefilter'; +import { IMembership } from 'app/shared/model/membership.model'; +import { MembershipService } from 'app/entities/membership'; @Component({ selector: 'jhi-share', @@ -24,9 +27,18 @@ export class ShareComponent implements OnInit, OnDestroy { predicate: any; reverse: any; totalItems: number; + memberships: IMembership[]; + filter: TableFilter<{ + documentDate?: string; + valueDate?: string; + action?: string; + quantity?: string; + membershipId?: string; + }>; constructor( protected shareService: ShareService, + protected membershipService: MembershipService, protected jhiAlertService: JhiAlertService, protected eventManager: JhiEventManager, protected parseLinks: JhiParseLinks, @@ -40,11 +52,25 @@ export class ShareComponent implements OnInit, OnDestroy { }; this.predicate = 'id'; this.reverse = true; + this.filter = new TableFilter( + { + documentDate: queryYearAsDateRange, + valueDate: queryYearAsDateRange, + action: queryEquals, + quantity: queryEquals, + membershipId: queryEquals + }, + 500, + () => { + this.loadAll(); + } + ); } loadAll() { this.shareService .query({ + ...this.filter.buildQueryCriteria(), page: this.page, size: this.itemsPerPage, sort: this.sort() @@ -71,6 +97,13 @@ export class ShareComponent implements OnInit, OnDestroy { this.accountService.identity().then(account => { this.currentAccount = account; }); + this.membershipService + .query() + .pipe( + filter((mayBeOk: HttpResponse) => mayBeOk.ok), + map((response: HttpResponse) => response.body) + ) + .subscribe((res: IMembership[]) => (this.memberships = res), (res: HttpErrorResponse) => this.onError(res.message)); this.registerChangeInShares(); } @@ -94,9 +127,15 @@ export class ShareComponent implements OnInit, OnDestroy { return result; } + trackMembershipById(index: number, item: IMembership) { + return item.id; + } + protected paginateShares(data: IShare[], headers: HttpHeaders) { this.links = this.parseLinks.parse(headers.get('link')); this.totalItems = parseInt(headers.get('X-Total-Count'), 10); + this.page = 0; + this.shares = []; for (let i = 0; i < data.length; i++) { this.shares.push(data[i]); } diff --git a/src/main/webapp/app/shared/util/tablefilter.ts b/src/main/webapp/app/shared/util/tablefilter.ts index f26dba4b..19157c9e 100644 --- a/src/main/webapp/app/shared/util/tablefilter.ts +++ b/src/main/webapp/app/shared/util/tablefilter.ts @@ -1,6 +1,14 @@ import { Subject, Subscription } from 'rxjs'; import { debounceTime, distinctUntilChanged } from 'rxjs/operators'; +export interface QueryDeclarations { + [key: string]: string; +} +export type DynamicQueryDefinition = (name: string, value: string) => QueryDefinitions; +export interface QueryDefinitions { + [key: string]: string | DynamicQueryDefinition; +} + /** * Handles filtering in data tables by converting the user input to query criteria of the JHipster REST API. * @@ -12,12 +20,12 @@ export class TableFilter { private criteriaChangedSubject = new Subject(); private criteriaChangedDebouncer: Subscription; - constructor(private query: T, private debounceMillis: number, private reload: () => void) { + constructor(private query: QueryDefinitions, private debounceMillis: number, private reload: () => void) { this.criteria = {} as any; this.criteriaChangedDebouncer = this.criteriaChangedSubject.pipe(debounceTime(debounceMillis)).subscribe(() => this.reload()); } - trigger() { + trigger($event) { this.debounce(); } @@ -26,10 +34,17 @@ export class TableFilter { this.debounce(); } - buildQueryCriteria() { - const queryCriteria: T = {} as any; - Object.keys(this.criteria).forEach(e => { - queryCriteria[e + '.' + this.query[e]] = this.criteria[e]; + buildQueryCriteria(): QueryDeclarations { + let queryCriteria: any = {} as any; + Object.keys(this.criteria).forEach(name => { + const value = this.criteria[name]; + const queryDef = this.query[name]; + if (typeof queryDef !== 'function') { + queryCriteria[queryDef] = value; + } else { + const additionalQueryCriteria = queryDef(name, value); + queryCriteria = { ...queryCriteria, ...additionalQueryCriteria }; + } }); return queryCriteria; } @@ -38,3 +53,21 @@ export class TableFilter { this.criteriaChangedSubject.next(); } } + +export function queryYearAsDateRange(name: string, value: string) { + if (value.length === 'YYYY'.length) { + const queryCriteria: any = {} as any; + queryCriteria[name + '.greaterOrEqualThan'] = value + '-01-01'; + queryCriteria[name + '.lessOrEqualThan'] = value + '-12-31'; + return queryCriteria; + } + return null; +} + +export function queryEquals(name: string, value: string) { + return { [name + '.equals']: value }; +} + +export function queryContains(name: string, value: string) { + return { [name + '.contains']: value }; +} diff --git a/src/test/javascript/spec/app/shared/util/tablefilter.spec.ts b/src/test/javascript/spec/app/shared/util/tablefilter.spec.ts index ee5e9f02..da7b08c2 100644 --- a/src/test/javascript/spec/app/shared/util/tablefilter.spec.ts +++ b/src/test/javascript/spec/app/shared/util/tablefilter.spec.ts @@ -1,4 +1,4 @@ -import { TableFilter } from 'app/shared/util/tablefilter'; +import { queryContains, queryEquals, queryYearAsDateRange, TableFilter } from 'app/shared/util/tablefilter'; /* To run these tests in IntelliJ IDEA, you need a run configuration with Configuration File: @@ -8,13 +8,23 @@ import { TableFilter } from 'app/shared/util/tablefilter'; */ describe('TableFilter Tests', () => { describe('TableFilter', () => { - let filter: TableFilter<{ name: string; number: string }>; + const TEST_DEBOUNCE_MILLIS = 100; + + let filter: TableFilter<{ name?: string; number?: string; date?: string }>; let asynchronously: () => void; beforeEach(() => { - filter = new TableFilter({ name: 'contains', number: 'equals' }, 100, () => { - asynchronously(); - }); + filter = new TableFilter( + { + name: queryContains, + number: queryEquals, + date: queryYearAsDateRange + }, + TEST_DEBOUNCE_MILLIS, + () => { + asynchronously(); + } + ); }); it('trigger() asynchronously calls the reload-handler', done => { @@ -22,7 +32,7 @@ describe('TableFilter Tests', () => { filter.criteria.name = 'Test Filter Value'; // when - filter.trigger(); + filter.trigger({ target: { valid: true } }); const triggerStartedAtMillis = Date.now(); // then @@ -37,10 +47,10 @@ describe('TableFilter Tests', () => { filter.criteria.name = 'Test Filter Value'; // when - filter.trigger(); + filter.trigger({ target: { valid: true } }); let triggerStartedAtMillis = null; setTimeout(() => { - filter.trigger(); + filter.trigger({ target: { valid: true } }); triggerStartedAtMillis = Date.now(); }, 50); @@ -52,7 +62,7 @@ describe('TableFilter Tests', () => { }; }); - it('when filter "name" is set to "test value", buildQueryCriteria() returns { "name.contains": "test value" }', () => { + it('when filter "name" is set, buildQueryCriteria() returns a name.contains query', () => { // given filter.criteria.name = 'test value'; @@ -63,17 +73,44 @@ describe('TableFilter Tests', () => { expect(filter.buildQueryCriteria()).toEqual({ 'name.contains': 'test value' }); }); + it('when filter "number" is set, buildQueryCriteria() returns a number.equals query', () => { + // given + filter.criteria.number = '-42'; + + // when + const actual = filter.buildQueryCriteria(); + + // then + expect(filter.buildQueryCriteria()).toEqual({ 'number.equals': '-42' }); + }); + + it('when filter "date" is set to "2019", buildQueryCriteria() returns a date range query', () => { + // given + filter.criteria.date = '2019'; + + // when + const actual = filter.buildQueryCriteria(); + + // then + expect(filter.buildQueryCriteria()).toEqual({ 'date.greaterOrEqualThan': '2019-01-01', 'date.lessOrEqualThan': '2019-12-31' }); + }); + + it('queryYearAsDateRange() returns null if year is not 4-digit', () => { + expect(queryYearAsDateRange('date', '201')).toBeNull(); + expect(queryYearAsDateRange('date', '20191')).toBeNull(); + }); + it('reset() clears criteria and calls reload-handler, considering debounce period', done => { // given filter.criteria.name = 'Test Filter Value'; // when - filter.trigger(); + filter.trigger({ target: { valid: true } }); let triggerStartedAtMillis = null; setTimeout(() => { filter.reset(); triggerStartedAtMillis = Date.now(); - }, 50); + }, TEST_DEBOUNCE_MILLIS / 2); // then asynchronously = () => {