Skip to content
This repository was archived by the owner on May 14, 2025. It is now read-only.

Commit 8e87245

Browse files
oodamienilayaperumalg
authored andcommitted
Add pager component
Resolves #760: - Update apps/runtime apps/streams/tasks list - Update tests
1 parent eab5bdd commit 8e87245

19 files changed

+277
-43
lines changed

ui/src/app/apps/apps/apps.component.html

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
<div class="description">
2020
<h1>Apps</h1>
2121
<p>
22-
This section lists all the available applications. You can <strong>register</strong> or <strong>unregister</strong> applications.
22+
This section lists all the available applications. You can <strong>register</strong> or
23+
<strong>unregister</strong> applications.
2324
</p>
2425
<div class="hidden visible-xs-block visible-sm-block" *ngIf="!isAppsEmpty()" [appRoles]="['ROLE_CREATE']">
2526
<a class="btn btn-primary" (click)="registerApps()">Register application(s)</a>
@@ -154,26 +155,35 @@ <h1>Apps</h1>
154155
</tbody>
155156
</table>
156157

157-
<div id="pagination" *ngIf="appRegistrations && appRegistrations.totalPages > 1">
158-
<pagination-controls *ngIf="appRegistrations.items.length > 0 "
159-
(pageChange)="getPage($event)"></pagination-controls>
158+
<div class="row">
159+
<div class="col-xs-12">
160+
<div id="pagination" *ngIf="appRegistrations && appRegistrations.totalPages > 1">
161+
<pagination-controls *ngIf="appRegistrations.items.length > 0 "
162+
(pageChange)="getPage($event)"></pagination-controls>
163+
</div>
164+
</div>
165+
<div class="col-xs-12" *ngIf="appRegistrations && appRegistrations?.totalElements > 0">
166+
<app-pager [page]="params.page" [total]="appRegistrations.totalElements" [size]="params.size"
167+
(onSizeChange)="changeSize($event)">
168+
</app-pager>
169+
</div>
160170
</div>
161171

162172
<div *ngIf="appRegistrations" id="empty">
163173
<div *ngIf="isAppsEmpty()" class="text-center">
164174
<div class="alert alert-warning" style="display:inline-block;margin:0 auto">
165175
<strong>No registered apps.</strong>
166-
<div [appRoles]="['ROLE_CREATE']">
167-
<p>You can register apps by clicking:</p>
168-
<button type="button" (click)="registerApps()" class="btn btn-primary">
169-
Register Application(s)
170-
</button>
171-
<button type="button" (click)="bulkImportApps()" class="btn btn-primary">
172-
Bulk Import Application(s)
173-
</button>
176+
<div [appRoles]="['ROLE_CREATE']">
177+
<p>You can register apps by clicking:</p>
178+
<button type="button" (click)="registerApps()" class="btn btn-primary">
179+
Register Application(s)
180+
</button>
181+
<button type="button" (click)="bulkImportApps()" class="btn btn-primary">
182+
Bulk Import Application(s)
183+
</button>
184+
</div>
174185
</div>
175186
</div>
176-
</div>
177187

178188
<div id="no-result" class="row"
179189
*ngIf="!isAppsEmpty() && appRegistrations.totalPages < 2 && appRegistrations.items.length == 0">

ui/src/app/apps/apps/apps.component.spec.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import {AppVersionsComponent} from '../app-versions/app-versions.component';
2828
import {BusyService} from '../../shared/services/busy.service';
2929
import { TruncatorComponent } from '../../shared/components/truncator/truncator.component';
3030
import { TruncatorWidthProviderDirective } from '../../shared/components/truncator/truncator-width-provider.directive';
31+
import { PagerComponent } from '../../shared/components/pager/pager.component';
3132

3233
describe('AppsComponent', () => {
3334
let component: AppsComponent;
@@ -49,6 +50,7 @@ describe('AppsComponent', () => {
4950
TruncatorComponent,
5051
TruncatorWidthProviderDirective,
5152
MasterCheckboxComponent,
53+
PagerComponent,
5254
RolesDirective
5355
],
5456
imports: [

ui/src/app/apps/apps/apps.component.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,18 @@ export class AppsComponent implements OnInit, OnDestroy {
272272
this.loadAppRegistrations();
273273
}
274274

275+
/**
276+
* Changes items per page
277+
* Reset the pagination (first page)
278+
* @param {number} size
279+
*/
280+
changeSize(size: number) {
281+
this.params.size = size;
282+
this.params.page = 0;
283+
this.updateContext();
284+
this.loadAppRegistrations();
285+
}
286+
275287
/**
276288
* Starts the unregistration process {@link AppRegistration}s
277289
* by opening a confirmation modal dialog.

ui/src/app/runtime/runtime-apps/runtime-apps.component.html

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,18 @@ <h1>Runtime applications</h1>
6363
</tbody>
6464
</table>
6565

66-
<div id="pagination" *ngIf="runtimeApps.items.length > 0 && runtimeApps.totalPages > 1">
67-
<pagination-controls (pageChange)="getPage($event)" [id]="runtimeApps.getPaginationInstance().id">
68-
</pagination-controls>
66+
<div class="row">
67+
<div class="col-xs-12">
68+
<div id="pagination" *ngIf="runtimeApps && runtimeApps.totalPages > 1">
69+
<pagination-controls (pageChange)="getPage($event)" [id]="runtimeApps.getPaginationInstance().id">
70+
</pagination-controls>
71+
</div>
72+
</div>
73+
<div class="col-xs-12" *ngIf="runtimeApps && runtimeApps?.totalElements > 0">
74+
<app-pager [page]="pagination.page" [total]="runtimeApps.totalElements" [size]="pagination.size"
75+
(onSizeChange)="changeSize($event)">
76+
</app-pager>
77+
</div>
6978
</div>
7079

7180
</div>

ui/src/app/runtime/runtime-apps/runtime-apps.component.spec.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {RuntimeAppComponent} from '../runtime-app/runtime-app.component';
1515
import {NgBusyModule} from 'ng-busy';
1616
import {MockModalService} from '../../tests/mocks/modal';
1717
import { LoaderComponent } from '../../shared/components/loader/loader.component';
18+
import { PagerComponent } from '../../shared/components/pager/pager.component';
1819

1920
describe('RuntimeAppsComponent', () => {
2021
let component: RuntimeAppsComponent;
@@ -29,7 +30,8 @@ describe('RuntimeAppsComponent', () => {
2930
RuntimeAppsComponent,
3031
KeyValuePipe,
3132
RuntimeAppStateComponent,
32-
LoaderComponent
33+
LoaderComponent,
34+
PagerComponent
3335
],
3436
imports: [
3537
NgBusyModule,
@@ -123,14 +125,14 @@ describe('RuntimeAppsComponent', () => {
123125
const spy = spyOn(runtimeAppsService, 'getRuntimeApps');
124126
fixture.debugElement.query(By.css('button[name=refresh]')).nativeElement.click();
125127
fixture.detectChanges();
126-
expect(spy).toHaveBeenCalledWith({ page: 0, size: 10});
128+
expect(spy).toHaveBeenCalledWith({ page: 0, size: 30});
127129
});
128130

129131
it('should navigation to the page 2', () => {
130132
const spy = spyOn(runtimeAppsService, 'getRuntimeApps');
131133
fixture.debugElement.queryAll(By.css('#pagination a'))[0].nativeElement.click();
132134
fixture.detectChanges();
133-
expect(spy).toHaveBeenCalledWith({ page: 1, size: 10});
135+
expect(spy).toHaveBeenCalledWith({ page: 1, size: 30});
134136
});
135137

136138
});

ui/src/app/runtime/runtime-apps/runtime-apps.component.ts

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import {Component, OnDestroy, OnInit} from '@angular/core';
2-
import {RuntimeApp} from '../model/runtime-app';
3-
import {Page} from '../../shared/model/page';
4-
import {RuntimeAppsService} from '../runtime-apps.service';
5-
import {BsModalService, BsModalRef} from 'ngx-bootstrap';
6-
import {Observable} from 'rxjs/Observable';
7-
import {RuntimeAppComponent} from '../runtime-app/runtime-app.component';
8-
import {PaginationParams} from '../../shared/components/shared.interface';
1+
import { Component, OnDestroy, OnInit } from '@angular/core';
2+
import { RuntimeApp } from '../model/runtime-app';
3+
import { Page } from '../../shared/model/page';
4+
import { RuntimeAppsService } from '../runtime-apps.service';
5+
import { BsModalService, BsModalRef } from 'ngx-bootstrap';
6+
import { Observable } from 'rxjs/Observable';
7+
import { RuntimeAppComponent } from '../runtime-app/runtime-app.component';
8+
import { PaginationParams } from '../../shared/components/shared.interface';
99

1010
/**
1111
* Component that loads Runtime applications.
@@ -27,7 +27,7 @@ export class RuntimeAppsComponent implements OnInit {
2727
/**
2828
* Pagination state
2929
*/
30-
pagination: PaginationParams = {page: 0, size: 10};
30+
pagination: PaginationParams = { page: 0, size: 30 };
3131

3232
/**
3333
* Modal reference
@@ -70,11 +70,22 @@ export class RuntimeAppsComponent implements OnInit {
7070
this.loadRuntimeApps();
7171
}
7272

73+
/**
74+
* Changes items per page
75+
* Reset the pagination (first page)
76+
* @param {number} size
77+
*/
78+
changeSize(size: number) {
79+
this.pagination.size = size;
80+
this.pagination.page = 0;
81+
this.loadRuntimeApps();
82+
}
83+
7384
/**
7485
* View a runtime application in a dedicate modal
7586
*/
7687
view(runtimeApp: RuntimeApp): void {
77-
this.modal = this.modalService.show(RuntimeAppComponent, {class: 'modal-xl'});
88+
this.modal = this.modalService.show(RuntimeAppComponent, { class: 'modal-xl' });
7889
this.modal.content.open(runtimeApp);
7990
}
8091

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import {
2+
Component, Output, EventEmitter, Input, OnChanges, SimpleChanges,
3+
ChangeDetectionStrategy
4+
} from '@angular/core';
5+
6+
/**
7+
* Pager component
8+
*
9+
* @author Damien Vitrac
10+
*/
11+
@Component({
12+
selector: 'app-pager',
13+
styleUrls: ['./styles.scss'],
14+
template: `
15+
<div class="app-pager">
16+
<div class="app-pager-text">
17+
items per page:
18+
</div>
19+
<div class="btn-group" dropdown>
20+
<button dropdownToggle type="button" class="select">
21+
{{ size }} <span class="caret"></span>
22+
</button>
23+
<ul class="dropdown-menu dropdown-menu-up" id="dropdown-basic" *dropdownMenu>
24+
<li *ngFor="let s of SIZE_LIST" [class.active]="s === size">
25+
<a (click)="sizeChange(s)" class="dropdown-item">{{ s }}</a>
26+
</li>
27+
</ul>
28+
</div>
29+
<span class="app-pager-divider"></span>
30+
<div class="app-pager-text">
31+
<strong>{{ values.from }}-{{ values.to }}</strong> items of <strong>{{ values.of }}</strong>
32+
</div>
33+
</div>
34+
`,
35+
changeDetection: ChangeDetectionStrategy.OnPush
36+
})
37+
export class PagerComponent implements OnChanges {
38+
39+
SIZE_LIST = [20, 30, 50, 100];
40+
41+
@Input() page: number;
42+
43+
@Input() total: number;
44+
45+
@Input() size: number;
46+
47+
@Output() onSizeChange = new EventEmitter<number>();
48+
49+
values = {
50+
from: 0,
51+
to: 0,
52+
of: 0
53+
};
54+
55+
constructor() {}
56+
57+
ngOnChanges(changes: SimpleChanges): void {
58+
let page = this.page;
59+
let size = this.size;
60+
let total = this.total;
61+
if (changes.page) {
62+
page = changes.page.currentValue;
63+
}
64+
if (changes.size) {
65+
size = changes.size.currentValue;
66+
}
67+
if (changes.total) {
68+
total = changes.total.currentValue;
69+
}
70+
this.values.from = ((page) * size) + 1;
71+
this.values.of = total;
72+
this.values.to = (page + 1) * size;
73+
74+
if (this.values.of < this.values.to) {
75+
this.values.to = this.values.of;
76+
}
77+
}
78+
79+
sizeChange(size) {
80+
this.onSizeChange.emit(size);
81+
}
82+
83+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
2+
.app-pager {
3+
vertical-align: top;
4+
text-align: right;
5+
6+
.dropdown-menu {
7+
min-width: 70px;
8+
}
9+
}
10+
11+
.app-pager-divider {
12+
display: inline-block;
13+
height: 22px;
14+
vertical-align: top;
15+
margin: 2px 10px;
16+
border-left: 1px solid #ccc;
17+
width: 1px;
18+
}
19+
20+
.app-pager-text {
21+
display: inline-block;
22+
height: 22px;
23+
vertical-align: top;
24+
}
25+
26+
.dropdown-item {
27+
cursor: pointer;
28+
}

ui/src/app/shared/shared.module.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import { StreamDslComponent } from './components/dsl/dsl.component';
4141
import { LoaderComponent } from './components/loader/loader.component';
4242
import { TruncatorComponent } from './components/truncator/truncator.component';
4343
import { TruncatorWidthProviderDirective } from './components/truncator/truncator-width-provider.directive';
44+
import { PagerComponent } from './components/pager/pager.component';
4445

4546
const busyConfig: BusyConfig = {
4647
message: 'Processing..',
@@ -98,7 +99,8 @@ const busyConfig: BusyConfig = {
9899
TruncatorWidthProviderDirective,
99100
OrderByPipe,
100101
ConfirmComponent,
101-
LoaderComponent
102+
LoaderComponent,
103+
PagerComponent
102104
],
103105
entryComponents: [
104106
ConfirmComponent
@@ -141,7 +143,8 @@ const busyConfig: BusyConfig = {
141143
OrderByPipe,
142144
ConfirmComponent,
143145
AutoResizeDirective,
144-
LoaderComponent
146+
LoaderComponent,
147+
PagerComponent
145148
]
146149
})
147150
export class SharedModule {

ui/src/app/streams/streams/streams.component.html

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,9 +171,18 @@ <h1 class="no-user-selection">Streams</h1>
171171
</tbody>
172172
</table>
173173

174-
<div id="pagination" *ngIf="streamDefinitions && streamDefinitions.totalPages > 1">
175-
<pagination-controls *ngIf="streamDefinitions.items.length > 0 "
176-
(pageChange)="getPage($event)"></pagination-controls>
174+
<div class="row">
175+
<div class="col-xs-12">
176+
<div id="pagination" *ngIf="streamDefinitions && streamDefinitions.totalPages > 1">
177+
<pagination-controls *ngIf="streamDefinitions.items.length > 0 "
178+
(pageChange)="getPage($event)"></pagination-controls>
179+
</div>
180+
</div>
181+
<div class="col-xs-12" *ngIf="streamDefinitions && streamDefinitions?.totalElements > 0">
182+
<app-pager [page]="params.page" [total]="streamDefinitions.totalElements" [size]="params.size"
183+
(onSizeChange)="changeSize($event)">
184+
</app-pager>
185+
</div>
177186
</div>
178187

179188
<div *ngIf="streamDefinitions" id="empty">

0 commit comments

Comments
 (0)