@@ -22,3 +27,4 @@
+
diff --git a/src/app/shared/object-grid/object-grid.component.ts b/src/app/shared/object-grid/object-grid.component.ts
index 39c3d56f7f..1b5ab075e2 100644
--- a/src/app/shared/object-grid/object-grid.component.ts
+++ b/src/app/shared/object-grid/object-grid.component.ts
@@ -49,6 +49,11 @@ export class ObjectGridComponent implements OnInit {
*/
@Input() sortConfig: SortOptions;
+ /**
+ * Whether or not the pagination should be rendered as simple previous and next buttons instead of the normal pagination
+ */
+ @Input() showPaginator = true;
+
/**
* The whether or not the gear is hidden
*/
@@ -134,6 +139,17 @@ export class ObjectGridComponent implements OnInit {
* Event's payload equals to the newly selected sort field.
*/
@Output() sortFieldChange: EventEmitter
= new EventEmitter();
+
+ /**
+ * If showPaginator is set to true, emit when the previous button is clicked
+ */
+ @Output() prev = new EventEmitter();
+
+ /**
+ * If showPaginator is set to true, emit when the next button is clicked
+ */
+ @Output() next = new EventEmitter();
+
data: any = {};
columns$: Observable;
@@ -225,4 +241,18 @@ export class ObjectGridComponent implements OnInit {
this.paginationChange.emit(event);
}
+ /**
+ * Go to the previous page
+ */
+ goPrev() {
+ this.prev.emit(true);
+ }
+
+ /**
+ * Go to the next page
+ */
+ goNext() {
+ this.next.emit(true);
+ }
+
}
diff --git a/src/app/shared/object-list/object-list.component.html b/src/app/shared/object-list/object-list.component.html
index 43d2da77c4..492cb4cf07 100644
--- a/src/app/shared/object-list/object-list.component.html
+++ b/src/app/shared/object-list/object-list.component.html
@@ -2,15 +2,20 @@
[paginationOptions]="config"
[pageInfoState]="objects?.payload"
[collectionSize]="objects?.payload?.totalElements"
+ [objects]="objects"
[sortOptions]="sortConfig"
[hideGear]="hideGear"
[hidePagerWhenSinglePage]="hidePagerWhenSinglePage"
[hidePaginationDetail]="hidePaginationDetail"
+ [showPaginator]="showPaginator"
(pageChange)="onPageChange($event)"
(pageSizeChange)="onPageSizeChange($event)"
(sortDirectionChange)="onSortDirectionChange($event)"
(sortFieldChange)="onSortFieldChange($event)"
- (paginationChange)="onPaginationChange($event)">
+ (paginationChange)="onPaginationChange($event)"
+ (prev)="goPrev()"
+ (next)="goNext()"
+ >
-
();
+ /**
+ * If showPaginator is set to true, emit when the previous button is clicked
+ */
+ @Output() prev = new EventEmitter();
+
+ /**
+ * If showPaginator is set to true, emit when the next button is clicked
+ */
+ @Output() next = new EventEmitter();
+
/**
* The current listable objects
*/
@@ -192,4 +207,18 @@ export class ObjectListComponent {
onPaginationChange(event) {
this.paginationChange.emit(event);
}
+
+ /**
+ * Go to the previous page
+ */
+ goPrev() {
+ this.prev.emit(true);
+ }
+
+ /**
+ * Go to the next page
+ */
+ goNext() {
+ this.next.emit(true);
+ }
}
diff --git a/src/app/shared/pagination/pagination.component.html b/src/app/shared/pagination/pagination.component.html
index 2a9aa1a062..9f894c48d9 100644
--- a/src/app/shared/pagination/pagination.component.html
+++ b/src/app/shared/pagination/pagination.component.html
@@ -20,16 +20,32 @@
-
diff --git a/src/app/shared/pagination/pagination.component.spec.ts b/src/app/shared/pagination/pagination.component.spec.ts
index cf2d1c13fd..d0d1612833 100644
--- a/src/app/shared/pagination/pagination.component.spec.ts
+++ b/src/app/shared/pagination/pagination.component.spec.ts
@@ -177,132 +177,206 @@ describe('Pagination component', () => {
}));
- // synchronous beforeEach
- beforeEach(() => {
- html = `
-
-
- `;
+ describe('when showPaginator is false', () => {
+ // synchronous beforeEach
+ beforeEach(() => {
+ html = `
+
+
+ `;
+ testFixture = createTestComponent(html, TestComponent) as ComponentFixture
;
+ testComp = testFixture.componentInstance;
+ });
- testFixture = createTestComponent(html, TestComponent) as ComponentFixture;
- testComp = testFixture.componentInstance;
+ it('should create Pagination Component', inject([PaginationComponent], (app: PaginationComponent) => {
+ expect(app).toBeDefined();
+ }));
- });
+ it('should render', () => {
+ expect(testComp.paginationOptions.id).toEqual('test');
+ expect(testComp.paginationOptions.currentPage).toEqual(1);
+ expect(testComp.paginationOptions.pageSize).toEqual(10);
+ expectPages(testFixture, ['-« Previous', '+1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '» Next']);
+ });
- it('should create Pagination Component', inject([PaginationComponent], (app: PaginationComponent) => {
- expect(app).toBeDefined();
- }));
-
- it('should render', () => {
- expect(testComp.paginationOptions.id).toEqual('test');
- expect(testComp.paginationOptions.currentPage).toEqual(1);
- expect(testComp.paginationOptions.pageSize).toEqual(10);
- expectPages(testFixture, ['-« Previous', '+1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '» Next']);
- });
-
- it('should render and respond to page change', () => {
- testComp.collectionSize = 30;
- testFixture.detectChanges();
-
-
- currentPagination.next(Object.assign(new PaginationComponentOptions(), pagination, {currentPage: 3}));
- testFixture.detectChanges();
-
- expectPages(testFixture, ['« Previous', '1', '2', '+3', '-» Next']);
-
- currentPagination.next(Object.assign(new PaginationComponentOptions(), pagination, {currentPage: 2}));
- testFixture.detectChanges();
-
- expectPages(testFixture, ['« Previous', '1', '+2', '3', '» Next']);
- });
-
- it('should render and respond to collectionSize change', () => {
-
- testComp.collectionSize = 30;
- testFixture.detectChanges();
- expectPages(testFixture, ['-« Previous', '+1', '2', '3', '» Next']);
-
- testComp.collectionSize = 40;
- testFixture.detectChanges();
- expectPages(testFixture, ['-« Previous', '+1', '2', '3', '4', '» Next']);
- });
-
- it('should render and respond to pageSize change', () => {
- const paginationComponent: PaginationComponent = testFixture.debugElement.query(By.css('ds-pagination')).references.p;
-
- testComp.collectionSize = 30;
- testFixture.detectChanges();
- expectPages(testFixture, ['-« Previous', '+1', '2', '3', '» Next']);
-
- currentPagination.next(Object.assign(new PaginationComponentOptions(), pagination, {pageSize: 5}));
- testFixture.detectChanges();
-
- expectPages(testFixture, ['-« Previous', '+1', '2', '3', '4', '5', '6', '» Next']);
-
- currentPagination.next(Object.assign(new PaginationComponentOptions(), pagination, {pageSize: 10}));
- testFixture.detectChanges();
- expectPages(testFixture, ['-« Previous', '+1', '2', '3', '» Next']);
-
- currentPagination.next(Object.assign(new PaginationComponentOptions(), pagination, {pageSize: 20}));
- testFixture.detectChanges();
- expectPages(testFixture, ['-« Previous', '+1', '2', '» Next']);
- });
-
- it('should emit pageSizeChange event with correct value', fakeAsync(() => {
- const paginationComponent: PaginationComponent = testFixture.debugElement.query(By.css('ds-pagination')).references.p;
-
- spyOn(testComp, 'pageSizeChanged');
-
- testComp.pageSizeChanged(5);
- tick();
-
- expect(testComp.pageSizeChanged).toHaveBeenCalledWith(5);
- }));
-
- it('should call the updateRoute method on the paginationService with the correct params', fakeAsync(() => {
- testComp.collectionSize = 60;
-
- changePage(testFixture, 3);
- tick();
- expect(paginationService.updateRoute).toHaveBeenCalledWith('test', Object.assign({ page: '3'}), {}, false);
-
- changePage(testFixture, 0);
- tick();
- expect(paginationService.updateRoute).toHaveBeenCalledWith('test', Object.assign({ page: '2'}), {}, false);
- }));
-
- it('should set correct pageSize route parameters', fakeAsync(() => {
- routerStub = testFixture.debugElement.injector.get(Router) as any;
-
- testComp.collectionSize = 60;
-
- changePageSize(testFixture, '20');
- tick();
- expect(paginationService.updateRoute).toHaveBeenCalledWith('test', Object.assign({ pageId: 'test', page: 1, pageSize: 20}), {}, false);
- }));
-
- it('should respond to windows resize', () => {
- const paginationComponent: PaginationComponent = testFixture.debugElement.query(By.css('ds-pagination')).references.p;
- hostWindowServiceStub = testFixture.debugElement.injector.get(HostWindowService) as any;
-
- hostWindowServiceStub.setWidth(400);
-
- hostWindowServiceStub.isXs().subscribe((status) => {
- paginationComponent.isXs = status;
+ it('should render and respond to page change', () => {
+ testComp.collectionSize = 30;
testFixture.detectChanges();
- expectPages(testFixture, ['-« Previous', '+1', '2', '3', '4', '5', '-...', '10', '» Next']);
- de = testFixture.debugElement.query(By.css('ul.pagination'));
- expect(de.nativeElement.classList.contains('pagination-sm')).toBeTruthy();
+
+
+ currentPagination.next(Object.assign(new PaginationComponentOptions(), pagination, {currentPage: 3}));
+ testFixture.detectChanges();
+
+ expectPages(testFixture, ['« Previous', '1', '2', '+3', '-» Next']);
+
+ currentPagination.next(Object.assign(new PaginationComponentOptions(), pagination, {currentPage: 2}));
+ testFixture.detectChanges();
+
+ expectPages(testFixture, ['« Previous', '1', '+2', '3', '» Next']);
+ });
+
+ it('should render and respond to collectionSize change', () => {
+
+ testComp.collectionSize = 30;
+ testFixture.detectChanges();
+ expectPages(testFixture, ['-« Previous', '+1', '2', '3', '» Next']);
+
+ testComp.collectionSize = 40;
+ testFixture.detectChanges();
+ expectPages(testFixture, ['-« Previous', '+1', '2', '3', '4', '» Next']);
+ });
+
+ it('should render and respond to pageSize change', () => {
+ const paginationComponent: PaginationComponent = testFixture.debugElement.query(By.css('ds-pagination')).references.p;
+
+ testComp.collectionSize = 30;
+ testFixture.detectChanges();
+ expectPages(testFixture, ['-« Previous', '+1', '2', '3', '» Next']);
+
+ currentPagination.next(Object.assign(new PaginationComponentOptions(), pagination, {pageSize: 5}));
+ testFixture.detectChanges();
+
+ expectPages(testFixture, ['-« Previous', '+1', '2', '3', '4', '5', '6', '» Next']);
+
+ currentPagination.next(Object.assign(new PaginationComponentOptions(), pagination, {pageSize: 10}));
+ testFixture.detectChanges();
+ expectPages(testFixture, ['-« Previous', '+1', '2', '3', '» Next']);
+
+ currentPagination.next(Object.assign(new PaginationComponentOptions(), pagination, {pageSize: 20}));
+ testFixture.detectChanges();
+ expectPages(testFixture, ['-« Previous', '+1', '2', '» Next']);
+ });
+
+ it('should emit pageSizeChange event with correct value', fakeAsync(() => {
+ const paginationComponent: PaginationComponent = testFixture.debugElement.query(By.css('ds-pagination')).references.p;
+
+ spyOn(testComp, 'pageSizeChanged');
+
+ testComp.pageSizeChanged(5);
+ tick();
+
+ expect(testComp.pageSizeChanged).toHaveBeenCalledWith(5);
+ }));
+
+ it('should call the updateRoute method on the paginationService with the correct params', fakeAsync(() => {
+ testComp.collectionSize = 60;
+
+ changePage(testFixture, 3);
+ tick();
+ expect(paginationService.updateRoute).toHaveBeenCalledWith('test', Object.assign({ page: '3'}), {}, false);
+
+ changePage(testFixture, 0);
+ tick();
+ expect(paginationService.updateRoute).toHaveBeenCalledWith('test', Object.assign({ page: '2'}), {}, false);
+ }));
+
+ it('should set correct pageSize route parameters', fakeAsync(() => {
+ routerStub = testFixture.debugElement.injector.get(Router) as any;
+
+ testComp.collectionSize = 60;
+
+ changePageSize(testFixture, '20');
+ tick();
+ expect(paginationService.updateRoute).toHaveBeenCalledWith('test', Object.assign({ pageId: 'test', page: 1, pageSize: 20}), {}, false);
+ }));
+
+ it('should respond to windows resize', () => {
+ const paginationComponent: PaginationComponent = testFixture.debugElement.query(By.css('ds-pagination')).references.p;
+ hostWindowServiceStub = testFixture.debugElement.injector.get(HostWindowService) as any;
+
+ hostWindowServiceStub.setWidth(400);
+
+ hostWindowServiceStub.isXs().subscribe((status) => {
+ paginationComponent.isXs = status;
+ testFixture.detectChanges();
+ expectPages(testFixture, ['-« Previous', '+1', '2', '3', '4', '5', '-...', '10', '» Next']);
+ de = testFixture.debugElement.query(By.css('ul.pagination'));
+ expect(de.nativeElement.classList.contains('pagination-sm')).toBeTruthy();
+ });
});
});
+
+ describe('when showPaginator is true', () => {
+ // synchronous beforeEach
+ beforeEach(() => {
+ html = `
+
+
+ `;
+ testFixture = createTestComponent(html, TestComponent) as ComponentFixture;
+ testComp = testFixture.componentInstance;
+ });
+
+ beforeEach(() => {
+ testComp.showPaginator = false;
+ testFixture.detectChanges();
+ });
+
+ describe('when clicking the previous arrow button', () => {
+ beforeEach(() => {
+ spyOn(testComp, 'goPrev');
+ testFixture.detectChanges();
+ });
+
+ it('should call goPrev method', () => {
+ const prev = testFixture.debugElement.query(By.css('#nav-prev'));
+ testFixture.detectChanges();
+ prev.triggerEventHandler('click', null);
+ expect(testComp.goPrev).toHaveBeenCalled();
+ });
+ });
+
+ describe('when clicking the next arrow button', () => {
+ beforeEach(() => {
+ spyOn(testComp, 'goNext');
+ testFixture.detectChanges();
+ });
+
+ it('should call goNext method', () => {
+ const next = testFixture.debugElement.query(By.css('#nav-next'));
+ testFixture.detectChanges();
+ next.triggerEventHandler('click', null);
+ expect(testComp.goNext).toHaveBeenCalled();
+ });
+ });
+
+ describe('check for prev and next button', () => {
+ it('shoud have a previous button', () => {
+ const prev = testFixture.debugElement.query(By.css('#nav-prev'));
+ testFixture.detectChanges();
+ expect(prev).toBeTruthy();
+ });
+
+ it('shoud have a next button', () => {
+ const next = testFixture.debugElement.query(By.css('#nav-next'));
+ testFixture.detectChanges();
+ expect(next).toBeTruthy();
+ });
+ });
+ });
+
});
// declare a test component
@@ -313,11 +387,19 @@ class TestComponent {
collectionSize: number;
paginationOptions = new PaginationComponentOptions();
sortOptions = new SortOptions('dc.title', SortDirection.ASC);
+ showPaginator: boolean;
+ objects = {
+ payload: {
+ currentPage: 2,
+ totalPages: 100
+ }
+ };
constructor() {
this.collection = Array.from(new Array(100), (x, i) => `item ${i + 1}`);
this.collectionSize = 100;
this.paginationOptions.id = 'test';
+ this.showPaginator = false;
}
pageChanged(page) {
@@ -327,4 +409,12 @@ class TestComponent {
pageSizeChanged(pageSize) {
this.paginationOptions.pageSize = pageSize;
}
+
+ goPrev() {
+ this.objects.payload.currentPage --;
+ }
+
+ goNext() {
+ this.objects.payload.currentPage ++;
+ }
}
diff --git a/src/app/shared/pagination/pagination.component.ts b/src/app/shared/pagination/pagination.component.ts
index 8f1c6bf26f..6da813cbc7 100644
--- a/src/app/shared/pagination/pagination.component.ts
+++ b/src/app/shared/pagination/pagination.component.ts
@@ -19,7 +19,11 @@ import { SortDirection, SortOptions } from '../../core/cache/models/sort-options
import { hasValue } from '../empty.util';
import { PageInfo } from '../../core/shared/page-info.model';
import { PaginationService } from '../../core/pagination/pagination.service';
-import { map } from 'rxjs/operators';
+import { map, take } from 'rxjs/operators';
+import { RemoteData } from '../../core/data/remote-data';
+import { PaginatedList } from '../../core/data/paginated-list.model';
+import { ListableObject } from '../object-collection/shared/listable-object.model';
+import { ViewMode } from '../../core/shared/view-mode.model';
/**
* The default pagination controls component.
@@ -33,6 +37,11 @@ import { map } from 'rxjs/operators';
encapsulation: ViewEncapsulation.Emulated
})
export class PaginationComponent implements OnDestroy, OnInit {
+ /**
+ * ViewMode that should be passed to {@link ListableObjectComponentLoaderComponent}.
+ */
+ viewMode: ViewMode = ViewMode.ListElement;
+
/**
* Number of items in collection.
*/
@@ -53,6 +62,26 @@ export class PaginationComponent implements OnDestroy, OnInit {
*/
@Input() sortOptions: SortOptions;
+ /**
+ * Whether or not the pagination should be rendered as simple previous and next buttons instead of the normal pagination
+ */
+ @Input() showPaginator = true;
+
+ /**
+ * The current pagination configuration
+ */
+ @Input() config?: PaginationComponentOptions;
+
+ /**
+ * The list of listable objects to render in this component
+ */
+ @Input() objects: RemoteData>;
+
+ /**
+ * The current sorting configuration
+ */
+ @Input() sortConfig: SortOptions;
+
/**
* An event fired when the page is changed.
* Event's payload equals to the newly selected page.
@@ -163,6 +192,15 @@ export class PaginationComponent implements OnDestroy, OnInit {
*/
private subs: Subscription[] = [];
+ /**
+ * If showPaginator is set to true, emit when the previous button is clicked
+ */
+ @Output() prev = new EventEmitter();
+
+ /**
+ * If showPaginator is set to true, emit when the next button is clicked
+ */
+ @Output() next = new EventEmitter();
/**
* Method provided by Angular. Invoked after the constructor.
*/
@@ -347,4 +385,31 @@ export class PaginationComponent implements OnDestroy, OnInit {
map((hasMultiplePages) => hasMultiplePages || !this.hidePagerWhenSinglePage)
);
}
+
+ /**
+ * Go to the previous page
+ */
+ goPrev() {
+ this.prev.emit(true);
+ this.updatePagination(-1);
+ }
+
+ /**
+ * Go to the next page
+ */
+ goNext() {
+ this.next.emit(true);
+ this.updatePagination(1);
+ }
+
+ /**
+ * Update page when next or prev button is clicked
+ * @param value
+ */
+ updatePagination(value: number) {
+ this.paginationService.getCurrentPagination(this.id, this.paginationOptions).pipe(take(1)).subscribe((currentPaginationOptions) => {
+ this.updateParams({page: (currentPaginationOptions.currentPage + value).toString()});
+ });
+ }
+
}
diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5
index 1be5ac448a..c3c68a6882 100644
--- a/src/assets/i18n/en.json5
+++ b/src/assets/i18n/en.json5
@@ -678,9 +678,9 @@
"browse.metadata.title.breadcrumbs": "Browse by Title",
- "browse.next.button": "Next",
+ "pagination.next.button": "Next",
- "browse.previous.button": "Previous",
+ "pagination.previous.button": "Previous",
"browse.startsWith.choose_start": "(Choose start)",