- {{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 = () => {
|