Skip to content

Commit 107b541

Browse files
authored
Issue #1531 - Pagination to be implemented in all widgets - For better user experience (#1544)
1 parent bbff9bd commit 107b541

File tree

6 files changed

+357
-47
lines changed

6 files changed

+357
-47
lines changed

src/components/apis/list-of-apis/ko/runtime/api-list.html

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
<div class="form-inline search-input">
22
<div class="d-block flex-grow">
33
<div class="input-group">
4-
<input type="search" role="searchbox" aria-label="Search APIs" placeholder="Search APIs" spellcheck="false" data-bind="textInput: pattern" />
4+
<input type="search" role="searchbox" aria-label="Search APIs" placeholder="Search APIs" spellcheck="false"
5+
data-bind="textInput: pattern" />
56
<button type="button" class="search-button" aria-label="Search APIs">
67
<i class="icon-emb icon-emb-magnifier"></i>
78
</button>
@@ -49,8 +50,7 @@
4950
<!-- ko foreach: { data: group.items, as: 'item' } -->
5051
<div class="table-row" role="row">
5152
<div class="col-5 text-truncate" role="cell">
52-
<a href="#"
53-
data-bind="attr: { href: $component.getReferenceUrl(item), title: item.displayName }">
53+
<a href="#" data-bind="attr: { href: $component.getReferenceUrl(item), title: item.displayName }">
5454
<span data-bind="text: item.displayName"></span>
5555
<!-- ko if: item.apiVersion -->
5656
- <span data-bind="text: item.apiVersion"></span>
@@ -70,7 +70,7 @@
7070
<div class="col-7" role="cell">
7171
<div tabindex="0" data-bind="markdown: { source: item.description, truncateAt: 250 }"></div>
7272
</div>
73-
<!-- /ko -->
73+
<!-- /ko -->
7474
</div>
7575
<!-- /ko -->
7676
<!-- /ko -->
@@ -88,8 +88,7 @@
8888
<!-- ko foreach: { data: apis, as: 'item' } -->
8989
<div class="table-row" role="row">
9090
<div class="col-5 text-truncate" role="cell">
91-
<a href="#"
92-
data-bind="attr: { href: $component.getReferenceUrl(item), title: item.displayName }">
91+
<a href="#" data-bind="attr: { href: $component.getReferenceUrl(item), title: item.displayName }">
9392
<span data-bind="text: item.displayName"></span>
9493
<!-- ko if: item.apiVersion -->
9594
- <span data-bind="text: item.apiVersion"></span>
@@ -124,29 +123,33 @@
124123
</div>
125124
<!-- /ko -->
126125

127-
<!-- ko if: hasPager -->
126+
<!-- ko if: needPaging -->
128127
<!-- ko ifnot: working -->
129128
<div class="table-footer" role="presentation">
130-
<ul class="pagination justify-content-center" role="navigation" aria-label="Pagination">
131-
<!-- ko if: hasPrevPage -->
132-
<li role="presentation">
133-
<a href="#" class="page-link" role="button" aria-label="Previous page"
134-
data-bind="click: prevPage, enable: hasPrevPage">
135-
<i class="icon-emb icon-emb-chevron-left"></i>
136-
</a>
129+
<ul aria-label="Pagination" class="pagination">
130+
<li data-bind="css: { disabled: !firstPageActive() }">
131+
<a data-bind="click: goToFirst">First</a>
137132
</li>
138-
<!-- /ko -->
139-
<li role="presentation">
140-
<span class="page-link" data-bind="text: page"></span>
133+
<li data-bind="css: { disabled: !previousPageActive() }">
134+
<a data-bind="click: goToPrevious">Previous</a>
141135
</li>
142-
<!-- ko if: hasNextPage -->
143-
<li role="presentation">
144-
<a href="#" class="page-link" role="button" aria-label="Next page"
145-
data-bind="click: nextPage, enable: hasNextPage">
146-
<i class="icon-emb icon-emb-chevron-right"></i>
147-
</a>
136+
137+
<!-- ko foreach: getPages() -->
138+
<li data-bind="css: { active: $component.page() === $data }">
139+
<a data-bind="click: $component.goToPage, text: $data"></a>
148140
</li>
149141
<!-- /ko -->
142+
143+
<li data-bind="css: { disabled: !nextPageActive() }">
144+
<a data-bind="click: goToNext">Next</a>
145+
</li>
146+
<li data-bind="css: { disabled: !lastPageActive() }">
147+
<a data-bind="click: goToLast">Last</a>
148+
</li>
149+
<li class="totalPages">
150+
<span
151+
data-bind="text: 'Total Pages : ' + $component.page() + ' of ' + $component.pageCount() + ' Pages'"></span>
152+
</li>
150153
</ul>
151154
</div>
152155
<!-- /ko -->

src/components/apis/list-of-apis/ko/runtime/api-list.ts

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export class ApiList {
2828
public readonly hasPrevPage: ko.Observable<boolean>;
2929
public readonly hasNextPage: ko.Observable<boolean>;
3030
public readonly groupByTag: ko.Observable<boolean>;
31+
public totalNoOfItems: ko.Observable<number>;
3132

3233
constructor(
3334
private readonly apiService: ApiService,
@@ -47,6 +48,7 @@ export class ApiList {
4748
this.apiGroups = ko.observableArray();
4849
this.groupByTag = ko.observable(false);
4950
this.defaultGroupByTagToEnabled = ko.observable(false);
51+
this.totalNoOfItems = ko.observable();
5052
}
5153

5254
@Param()
@@ -100,13 +102,15 @@ export class ApiList {
100102
this.apiGroups(apiGroups);
101103

102104
nextLink = pageOfTagResources.nextLink;
105+
this.totalNoOfItems(pageOfTagResources.count);
103106
}
104107
else {
105108
const pageOfApis = await this.apiService.getApis(query);
106109
const apis = pageOfApis ? pageOfApis.value : [];
107110
this.apis(apis);
108111

109112
nextLink = pageOfApis.nextLink;
113+
this.totalNoOfItems(pageOfApis.count);
110114
}
111115

112116
this.hasPrevPage(pageNumber > 0);
@@ -120,6 +124,136 @@ export class ApiList {
120124
}
121125
}
122126

127+
public pageCount(): number {
128+
return Math.ceil(this.totalNoOfItems() / Constants.defaultPageSize);
129+
};
130+
131+
public setCurrentPag(page: number): void {
132+
if (page < Constants.firstPage)
133+
page = Constants.firstPage;
134+
135+
if (page > this.lastPage())
136+
page = this.lastPage();
137+
138+
this.page(page);
139+
};
140+
141+
142+
public lastPage(): number {
143+
return this.pageCount();
144+
};
145+
146+
public nextPagePresent(): number {
147+
var next = this.page() + 1;
148+
if (next > this.lastPage())
149+
return null;
150+
return next;
151+
};
152+
153+
public previousPage(): number {
154+
var previous = this.page() - 1;
155+
if (previous < Constants.firstPage)
156+
return null;
157+
158+
return previous;
159+
};
160+
161+
public needPaging(): boolean {
162+
return this.pageCount() > 1;
163+
};
164+
165+
public nextPageActive(): boolean {
166+
return this.nextPagePresent() != null;
167+
};
168+
169+
public previousPageActive(): boolean {
170+
return this.previousPage() != null;
171+
};
172+
173+
public lastPageActive(): boolean {
174+
return (this.lastPage() != this.page());
175+
};
176+
177+
public firstPageActive(): boolean {
178+
return (Constants.firstPage != this.page());
179+
};
180+
181+
public generateAllPages(): number[] {
182+
var pages = [];
183+
for (var i = Constants.firstPage; i <= this.lastPage(); i++)
184+
pages.push(i);
185+
186+
return pages;
187+
};
188+
189+
public generateMaxPage(): number[] {
190+
var current = this.page();
191+
var pageCount = this.pageCount();
192+
var first = Constants.firstPage;
193+
194+
var upperLimit = current + (Constants.maxPageCount - 1) / 2;
195+
var downLimit = current - (Constants.maxPageCount - 1) / 2;
196+
197+
while (upperLimit > pageCount) {
198+
upperLimit--;
199+
if (downLimit > first)
200+
downLimit--;
201+
}
202+
203+
while (downLimit < first) {
204+
downLimit++;
205+
if (upperLimit < pageCount)
206+
upperLimit++;
207+
}
208+
209+
var pages = [];
210+
for (var i = downLimit; i <= upperLimit; i++) {
211+
pages.push(i);
212+
}
213+
return pages;
214+
};
215+
216+
public getPages(): ko.ObservableArray {
217+
this.page();
218+
this.totalNoOfItems();
219+
220+
if (this.pageCount() <= Constants.maxPageCount) {
221+
return ko.observableArray(this.generateAllPages());
222+
} else {
223+
return ko.observableArray(this.generateMaxPage());
224+
}
225+
};
226+
227+
public goToPage(page: number): void {
228+
if (page >= Constants.firstPage && page <= this.lastPage())
229+
this.page(page);
230+
this.loadPageOfApis();
231+
}
232+
233+
public goToFirst(): void {
234+
this.page(Constants.firstPage);
235+
this.loadPageOfApis();
236+
};
237+
238+
public goToPrevious(): void {
239+
var previous = this.previousPage();
240+
if (previous != null)
241+
this.page(previous);
242+
this.loadPageOfApis();
243+
};
244+
245+
public goToNext(): void {
246+
var next = this.nextPagePresent();
247+
if (next != null)
248+
this.page(next);
249+
this.loadPageOfApis();
250+
};
251+
252+
public goToLast(): void {
253+
this.page(this.lastPage());
254+
this.loadPageOfApis();
255+
};
256+
123257
public getReferenceUrl(api: Api): string {
124258
return this.routeHelper.getApiReferenceUrl(api.name, this.detailsPageUrl());
125259
}

src/components/products/product-list/ko/runtime/product-list.html

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -46,29 +46,33 @@
4646

4747
<!-- /ko -->
4848

49-
<!-- ko if: hasPager -->
49+
<!-- ko if: needPaging -->
5050
<!-- ko ifnot: working -->
51-
<div class="table-footer">
52-
<ul class="pagination justify-content-center" role="navigation" aria-label="Pagination">
53-
<!-- ko if: hasPrevPage -->
54-
<li>
55-
<a href="#" class="page-link" role="button" aria-label="Previous page"
56-
data-bind="click: prevPage, enable: hasPrevPage">
57-
<i class="icon-emb icon-emb-chevron-left"></i>
58-
</a>
51+
<div class="table-footer" role="presentation">
52+
<ul aria-label="Pagination" class="pagination">
53+
<li data-bind="css: { disabled: !firstPageActive() }">
54+
<a data-bind="click: goToFirst">First</a>
5955
</li>
60-
<!-- /ko -->
61-
<li>
62-
<span class="page-link" data-bind="text: page"></span>
56+
<li data-bind="css: { disabled: !previousPageActive() }">
57+
<a data-bind="click: goToPrevious">Previous</a>
6358
</li>
64-
<!-- ko if: hasNextPage -->
65-
<li>
66-
<a href="#" class="page-link" role="button" aria-label="Next page"
67-
data-bind="click: nextPage, enable: hasNextPage">
68-
<i class="icon-emb icon-emb-chevron-right"></i>
69-
</a>
59+
60+
<!-- ko foreach: getPages() -->
61+
<li data-bind="css: { active: $component.page() === $data }">
62+
<a data-bind="click: $component.goToPage, text: $data"></a>
7063
</li>
7164
<!-- /ko -->
65+
66+
<li data-bind="css: { disabled: !nextPageActive() }">
67+
<a data-bind="click: goToNext">Next</a>
68+
</li>
69+
<li data-bind="css: { disabled: !lastPageActive() }">
70+
<a data-bind="click: goToLast">Last</a>
71+
</li>
72+
<li class="totalPages">
73+
<span
74+
data-bind="text: 'Total Pages : ' + $component.page() + ' of ' + $component.pageCount() + ' Pages'"></span>
75+
</li>
7276
</ul>
7377
</div>
7478
<!-- /ko -->

0 commit comments

Comments
 (0)