diff --git a/ng2-components/README.md b/ng2-components/README.md index 8dd0b1a5eb..9799c8130b 100644 --- a/ng2-components/README.md +++ b/ng2-components/README.md @@ -62,7 +62,7 @@ - [adf-dropdown-breadcrumb](ng2-alfresco-documentlist/README.md) - [adf-breadcrumb](ng2-alfresco-documentlist/README.md) - [adf-document-list](ng2-alfresco-documentlist/README.md) -- [adf-pagination](ng2-alfresco-datatable/README.md) +- [adf-pagination](ng2-alfresco-core/src/components/pagination/pagination.md) - [adf-empty-list](ng2-alfresco-datatable/README.md) - [adf-datatable](ng2-alfresco-datatable/README.md) - [adf-datatable-cell](ng2-alfresco-datatable/README.md) diff --git a/ng2-components/ng2-alfresco-core/docs/pagination/basic.png b/ng2-components/ng2-alfresco-core/docs/pagination/basic.png new file mode 100644 index 0000000000..9ceb4da7ab Binary files /dev/null and b/ng2-components/ng2-alfresco-core/docs/pagination/basic.png differ diff --git a/ng2-components/ng2-alfresco-core/index.ts b/ng2-components/ng2-alfresco-core/index.ts index 36ce9acf97..82b045a76a 100644 --- a/ng2-components/ng2-alfresco-core/index.ts +++ b/ng2-components/ng2-alfresco-core/index.ts @@ -24,6 +24,7 @@ import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; import { CollapsableModule } from './src/components/collapsable/collapsable.module'; import { ContextMenuModule } from './src/components/context-menu/context-menu.module'; +import { PaginationModule } from './src/components/pagination/pagination.module'; import { ToolbarModule } from './src/components/toolbar/toolbar.module'; import { CardViewModule } from './src/components/view/card-view.module'; import { MaterialModule } from './src/material.module'; @@ -209,6 +210,7 @@ export function createTranslateLoader(http: Http, logService: LogService) { }), MaterialModule, AppConfigModule, + PaginationModule, ToolbarModule, ContextMenuModule, CardViewModule, @@ -236,6 +238,7 @@ export function createTranslateLoader(http: Http, logService: LogService) { ContextMenuModule, CardViewModule, CollapsableModule, + PaginationModule, ToolbarModule, ...obsoleteMdlDirectives(), UploadDirective, diff --git a/ng2-components/ng2-alfresco-core/src/components/pagination/pagination-query-params.interface.ts b/ng2-components/ng2-alfresco-core/src/components/pagination/pagination-query-params.interface.ts new file mode 100644 index 0000000000..bc763d21ec --- /dev/null +++ b/ng2-components/ng2-alfresco-core/src/components/pagination/pagination-query-params.interface.ts @@ -0,0 +1,31 @@ +/*! + * @license + * Copyright 2016 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * PaginationQueryParams object is used to emit events regarding pagination having two + * properties from the Pagination interface found in AlfrescoJS API + * + * The two properties are "skipCount" and "maxItems" that are sent as query parameters + * to server to paginate results + * + * @TODO Contribute this to AlfrescoJS API + */ + +export interface PaginationQueryParams { + skipCount: number; + maxItems: number; +}; diff --git a/ng2-components/ng2-alfresco-core/src/components/pagination/pagination.component.html b/ng2-components/ng2-alfresco-core/src/components/pagination/pagination.component.html new file mode 100644 index 0000000000..86aa826a70 --- /dev/null +++ b/ng2-components/ng2-alfresco-core/src/components/pagination/pagination.component.html @@ -0,0 +1,64 @@ +
+ + {{ + 'CORE.PAGINATION.ITEMS_RANGE' | translate: { + range: range.join('-'), + total: pagination.totalItems + } + }} + +
+ +
+ {{ 'CORE.PAGINATION.ITEMS_PER_PAGE' | translate }} + {{ pagination.maxItems }} + + + + + +
+ +
+ {{ 'CORE.PAGINATION.CURRENT_PAGE' | translate }} {{ current }} + + + + + {{ 'CORE.PAGINATION.TOTAL_PAGES' | translate: { total: pages.length } }} + + + + + +
+ +
+ + + +
diff --git a/ng2-components/ng2-alfresco-core/src/components/pagination/pagination.component.scss b/ng2-components/ng2-alfresco-core/src/components/pagination/pagination.component.scss new file mode 100644 index 0000000000..6982250540 --- /dev/null +++ b/ng2-components/ng2-alfresco-core/src/components/pagination/pagination.component.scss @@ -0,0 +1,37 @@ +@import 'theming'; + +$adf-pagination--height: 48px; +$adf-pagination--icon-button-size: 32px; + +.adf-pagination { + display: flex; + border-top: 1px solid $alfresco-divider-color; + height: $adf-pagination--height; + line-height: $adf-pagination--height; + + &__block { + display: flex; + align-items: center; + padding: 0 12px; + border-right: 1px solid $alfresco-divider-color; + + &:first-child { + flex: 1 1 auto; + } + + &:last-child { + border-right-width: 0; + } + + span { + color: $alfresco-secondary-text-color; + margin: 0 5px; + } + } + + button[md-icon-button] { + width: $adf-pagination--icon-button-size; + height: $adf-pagination--icon-button-size; + line-height: $adf-pagination--icon-button-size; + } +} \ No newline at end of file diff --git a/ng2-components/ng2-alfresco-core/src/components/pagination/pagination.component.spec.ts b/ng2-components/ng2-alfresco-core/src/components/pagination/pagination.component.spec.ts new file mode 100644 index 0000000000..13772f3173 --- /dev/null +++ b/ng2-components/ng2-alfresco-core/src/components/pagination/pagination.component.spec.ts @@ -0,0 +1,276 @@ +/*! + * @license + * Copyright 2016 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, TestBed } from '@angular/core/testing'; +import { MaterialModule } from '@angular/material'; + +import { CoreModule } from 'ng2-alfresco-core'; + +import { PaginationComponent } from './pagination.component'; + +declare let jasmine: any; + +class FakePaginationInput { + count: string = 'Not applicable / not used'; + hasMoreItems: string = 'Not applicable / not used'; + totalItems: number = null; + skipCount: number = null; + maxItems: number = 25; + + constructor(pagesCount, currentPage, lastPageItems) { + this.totalItems = ((pagesCount - 1) * this.maxItems) + lastPageItems; + this.skipCount = (currentPage - 1) * this.maxItems; + } +} + +class TestConfig { + testBed: any = null; + + constructor() { + this.testBed = TestBed.configureTestingModule({ + imports: [ + CoreModule.forRoot(), + MaterialModule + ], + schemas: [ NO_ERRORS_SCHEMA ] + }); + } +} + +describe('PaginationComponent', () => { + beforeEach(() => { + jasmine.Ajax.install(); + }); + + afterEach(() => { + jasmine.Ajax.uninstall(); + }); + + beforeEach(async(() => { + const test = new TestConfig(); + + test.testBed + .compileComponents() + .then(() => { + const fixture = test.testBed.createComponent(PaginationComponent); + const component: PaginationComponent = fixture.componentInstance; + + ( component).ngAfterViewInit = jasmine + .createSpy('ngAfterViewInit').and + .callThrough(); + + spyOn(component.onChangePageNumber, 'emit'); + spyOn(component.onChangePageSize, 'emit'); + spyOn(component.onNextPage, 'emit'); + spyOn(component.onPrevPage, 'emit'); + + this.fixture = fixture; + this.component = component; + + fixture.detectChanges(); + }); + })); + + describe('Single page', () => { + beforeEach(() => { + this.component.pagination = new FakePaginationInput(1, 1, 10); + }); + + it('has a single page', () => { + expect(this.component.pages.length).toBe(1); + }); + + it('has current page 1', () => { + expect(this.component.current).toBe(1); + }); + + it('is first and last page', () => { + expect(this.component.isFirstPage).toBe(true); + expect(this.component.isLastPage).toBe(true); + }); + + it('has range', () => { + expect(this.component.range).toEqual([ 1, 10 ]); + }); + }); + + describe('Single full page', () => { + beforeEach(() => { + this.component.pagination = new FakePaginationInput(1, 1, 25); + }); + + it('has a single page', () => { + expect(this.component.pages.length).toBe(1); + }); + + it('has range', () => { + expect(this.component.range).toEqual([ 1, 25 ]); + }); + }); + + describe('Middle page', () => { + + // This test describes 6 pages being on the third page + // and last page has 5 items + + beforeEach(() => { + this.component.pagination = new FakePaginationInput(6, 3, 5); + }); + + it('has more pages', () => { + expect(this.component.pages.length).toBe(6); + }); + + it('has the last page', () => { + expect(this.component.lastPage).toBe(6); + }); + + it('is on the 3rd page', () => { + expect(this.component.current).toBe(3); + }); + + it('has previous and next page', () => { + expect(this.component.previous).toBe(2); + expect(this.component.next).toBe(4); + }); + + it('is not first, nor last', () => { + expect(this.component.isFirstPage).toBe(false); + expect(this.component.isLastPage).toBe(false); + }); + + it('has range', () => { + expect(this.component.range).toEqual([ 51, 75 ]); + }); + + it('goes next', () => { + const { component } = this; + + component.goNext(); + + const { emit: { calls } } = component.onNextPage; + const { skipCount } = calls.mostRecent().args[0]; + + expect(skipCount).toBe(75); + }); + + it('goes previous', () => { + const { component } = this; + + component.goPrevious(); + + const { emit: { calls } } = component.onPrevPage; + const { skipCount } = calls.mostRecent().args[0]; + + expect(skipCount).toBe(25); + }); + + it('changes page size', () => { + const { component } = this; + component.changePageSize(50); + + const { emit: { calls } } = component.onChangePageSize; + const { maxItems } = calls.mostRecent().args[0]; + + expect(maxItems).toBe(50); + }); + + it('changes page number', () => { + const { component } = this; + + component.changePageNumber(5); + + const { emit: { calls } } = component.onChangePageNumber; + const { skipCount } = calls.mostRecent().args[0]; + + expect(skipCount).toBe(100); + }); + }); + + describe('First page', () => { + + // This test describes 10 pages being on the first page + + beforeEach(() => { + this.component.pagination = new FakePaginationInput(10, 1, 5); + }); + + it('is on the first page', () => { + expect(this.component.current).toBe(1); + expect(this.component.isFirstPage).toBe(true); + }); + + it('has the same, previous page', () => { + expect(this.component.previous).toBe(1); + }); + + it('has next page', () => { + expect(this.component.next).toBe(2); + }); + + it('has range', () => { + expect(this.component.range).toEqual([ 1, 25 ]); + }); + }); + + describe('Last page', () => { + + // This test describes 10 pages being on the last page + + beforeEach(() => { + this.component.pagination = new FakePaginationInput(10, 10, 5); + }); + + it('is on the last page', () => { + expect(this.component.current).toBe(10); + expect(this.component.isLastPage).toBe(true); + }); + + it('has the same, next page', () => { + expect(this.component.next).toBe(10); + }); + + it('has previous page', () => { + expect(this.component.previous).toBe(9); + }); + + it('has range', () => { + expect(this.component.range).toEqual([ 226, 230 ]); + }); + }); + + describe('Without pagination input', () => { + it('has defaults', () => { + const { + current, lastPage, isFirstPage, isLastPage, + next, previous, range, pages + } = this.component; + + expect(lastPage).toBe(1, 'lastPage'); + expect(previous).toBe(1, 'previous'); + expect(current).toBe(1, 'current'); + expect(next).toBe(1, 'next'); + + expect(isFirstPage).toBe(true, 'isFirstPage'); + expect(isLastPage).toBe(true, 'isLastPage'); + + expect(range).toEqual([ 0, 0 ], 'range'); + expect(pages).toEqual([ 1 ], 'pages'); + }); + }); +}); diff --git a/ng2-components/ng2-alfresco-core/src/components/pagination/pagination.component.ts b/ng2-components/ng2-alfresco-core/src/components/pagination/pagination.component.ts new file mode 100644 index 0000000000..c5e2eee8ab --- /dev/null +++ b/ng2-components/ng2-alfresco-core/src/components/pagination/pagination.component.ts @@ -0,0 +1,206 @@ +/*! + * @license + * Copyright 2016 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + ChangeDetectionStrategy, + Component, + EventEmitter, + Input, + OnInit, + Output, + ViewEncapsulation +} from '@angular/core'; + +import { Pagination } from 'alfresco-js-api'; +import { PaginationQueryParams } from './pagination-query-params.interface'; + +@Component({ + selector: 'adf-pagination, alfresco-pagination', + host: { 'class': 'adf-pagination' }, + templateUrl: './pagination.component.html', + styleUrls: [ './pagination.component.scss' ], + changeDetection: ChangeDetectionStrategy.OnPush, + encapsulation: ViewEncapsulation.None +}) +export class PaginationComponent implements OnInit { + + static DEFAULT_PAGE_SIZE: number = 25; + + static ACTIONS = { + NEXT_PAGE: 'NEXT_PAGE', + PREV_PAGE: 'PREV_PAGE', + CHANGE_PAGE_SIZE: 'CHANGE_PAGE_SIZE', + CHANGE_PAGE_NUMBER: 'CHANGE_PAGE_NUMBER' + }; + + @Input() + supportedPageSizes: number[] = [ 25, 50, 100 ]; + + /** @deprecated */ + /** "pagination" object already has "maxItems" */ + @Input() + maxItems: number = PaginationComponent.DEFAULT_PAGE_SIZE; + + @Input() + pagination: Pagination; + + @Output('change') + onChange: EventEmitter = new EventEmitter(); + + @Output('changePageNumber') + onChangePageNumber: EventEmitter = new EventEmitter(); + + @Output('changePageSize') + onChangePageSize: EventEmitter = new EventEmitter(); + + @Output('nextPage') + onNextPage: EventEmitter = new EventEmitter(); + + @Output('prevPage') + onPrevPage: EventEmitter = new EventEmitter(); + + ngOnInit() { + this.pagination = { + skipCount: 0, + maxItems: PaginationComponent.DEFAULT_PAGE_SIZE, + totalItems: 0 + }; + } + + get lastPage(): number { + const { maxItems, totalItems } = this.pagination; + + return (totalItems && maxItems) + ? Math.ceil(totalItems / maxItems) + : 1; + } + + get current(): number { + const { maxItems, skipCount } = this.pagination; + + return (skipCount && maxItems) + ? Math.floor(skipCount / maxItems) + 1 + : 1; + } + + get isLastPage(): boolean { + const { current, lastPage } = this; + return current === lastPage; + } + + get isFirstPage(): boolean { + return this.current === 1; + } + + get next(): number { + const { isLastPage, current } = this; + return isLastPage ? current : current + 1; + } + + get previous(): number { + const { isFirstPage, current } = this; + return isFirstPage ? 1 : current - 1; + } + + get range(): number[] { + const { skipCount, maxItems, totalItems } = this.pagination; + const { isLastPage } = this; + + const start = totalItems ? skipCount + 1 : 0; + const end = isLastPage ? totalItems : skipCount + maxItems; + + return [ start, end ]; + } + + get pages(): number[] { + return Array(this.lastPage) + .fill('n') + .map((item, index) => (index + 1)); + } + + goNext() { + const { next, pagination: { maxItems } } = this; + + this.handlePaginationEvent(PaginationComponent.ACTIONS.NEXT_PAGE, { + skipCount: (next - 1) * maxItems, + maxItems + }); + } + + goPrevious() { + const { previous, pagination: { maxItems } } = this; + + this.handlePaginationEvent(PaginationComponent.ACTIONS.PREV_PAGE, { + skipCount: (previous - 1) * maxItems, + maxItems + }); + } + + changePageNumber(pageNumber: number) { + const { pagination: { maxItems } } = this; + + this.handlePaginationEvent(PaginationComponent.ACTIONS.CHANGE_PAGE_NUMBER, { + skipCount: (pageNumber - 1) * maxItems, + maxItems + }); + } + + changePageSize(maxItems: number) { + this.handlePaginationEvent(PaginationComponent.ACTIONS.CHANGE_PAGE_SIZE, { + skipCount: 0, + maxItems + }); + } + + handlePaginationEvent(action: string, params: PaginationQueryParams) { + const { + NEXT_PAGE, + PREV_PAGE, + CHANGE_PAGE_NUMBER, + CHANGE_PAGE_SIZE + } = PaginationComponent.ACTIONS; + + const { + onChange, + onChangePageNumber, + onChangePageSize, + onNextPage, + onPrevPage, + pagination + } = this; + + const data = Object.assign({}, pagination, params); + + if (action === NEXT_PAGE) { + onNextPage.emit(data); + } + + if (action === PREV_PAGE) { + onPrevPage.emit(data); + } + + if (action === CHANGE_PAGE_NUMBER) { + onChangePageNumber.emit(data); + } + + if (action === CHANGE_PAGE_SIZE) { + onChangePageSize.emit(data); + } + + onChange.emit(params); + } +} diff --git a/ng2-components/ng2-alfresco-core/src/components/pagination/pagination.md b/ng2-components/ng2-alfresco-core/src/components/pagination/pagination.md new file mode 100644 index 0000000000..39a64cc603 --- /dev/null +++ b/ng2-components/ng2-alfresco-core/src/components/pagination/pagination.md @@ -0,0 +1,37 @@ +# Pagination Component + +## Basic example + +```html + + +``` + +Depending on the pagination data, you should see result similar to the following one: + +![](../../../docs/pagination/basic.png) + +## Properties + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| pagination | Pagination | | Pagination object | +| supportedPageSizes | Array<number> | [ 25, 50, 100 ] | An array of page sizes | +| change | EventEmitter<PaginationQueryParams> | | Triggered for any action in pagination | +| nextPage | EventEmitter<Pagination> | | Triggered on next page action | +| prevPage | EventEmitter<Pagination> | | Triggered on previous page action | +| changePageSize | EventEmitter<Pagination> | | Triggered on page size change action | +| changePageNumber | EventEmitter<Pagination> | | Triggered on page change action | + +Each event helps to detect the certain action that user have made using the component. + +For `change` event, a [PaginationQueryParams](https://github.com/Alfresco/alfresco-ng2-components/tree/master/ng2-components/ng2-alfresco-core/src/components/pagination/pagination-query-params.ts) (including the query params supported by the REST API, `skipCount` and `maxItems`) is returned. + +For all other events, other than `change`, a new [Pagination object](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-core-rest-api/docs/Pagination.md) is returned as in the folowing example, with updated properties to be used to query further. diff --git a/ng2-components/ng2-alfresco-core/src/components/pagination/pagination.module.ts b/ng2-components/ng2-alfresco-core/src/components/pagination/pagination.module.ts new file mode 100644 index 0000000000..7e4c7b11e6 --- /dev/null +++ b/ng2-components/ng2-alfresco-core/src/components/pagination/pagination.module.ts @@ -0,0 +1,39 @@ +/*! + * @license + * Copyright 2016 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { MaterialModule } from '@angular/material'; + +import { TranslateModule } from '@ngx-translate/core'; + +import { PaginationComponent } from './pagination.component'; + +@NgModule({ + imports: [ + CommonModule, + TranslateModule, + MaterialModule + ], + declarations: [ + PaginationComponent + ], + exports: [ + PaginationComponent + ] +}) +export class PaginationModule {} diff --git a/ng2-components/ng2-alfresco-core/src/i18n/en.json b/ng2-components/ng2-alfresco-core/src/i18n/en.json index 0db3279e44..2c8da2442e 100644 --- a/ng2-components/ng2-alfresco-core/src/i18n/en.json +++ b/ng2-components/ng2-alfresco-core/src/i18n/en.json @@ -1,3 +1,10 @@ { - + "CORE": { + "PAGINATION": { + "ITEMS_RANGE": "Showing {{ range }} of {{ total }}", + "ITEMS_PER_PAGE": "Items per page", + "CURRENT_PAGE": "Page", + "TOTAL_PAGES": "of {{ total }}" + } + } } diff --git a/ng2-components/ng2-alfresco-datatable/index.ts b/ng2-components/ng2-alfresco-datatable/index.ts index e612b72ab6..43842fe5a4 100644 --- a/ng2-components/ng2-alfresco-datatable/index.ts +++ b/ng2-components/ng2-alfresco-datatable/index.ts @@ -24,14 +24,12 @@ export * from './src/data/index'; export { DataTableCellComponent } from './src/components/datatable/datatable-cell.component'; export { DataTableComponent } from './src/components/datatable/datatable.component'; export { EmptyListComponent } from './src/components/datatable/empty-list.component'; -export { PaginationComponent } from './src/components/pagination/pagination.component'; export { DataCellEvent, DataCellEventModel } from './src/components/datatable/data-cell.event'; export { DataRowActionEvent, DataRowActionModel } from './src/components/datatable/data-row-action.event'; import { DataTableCellComponent } from './src/components/datatable/datatable-cell.component'; import { DataTableComponent } from './src/components/datatable/datatable.component'; import { EmptyListComponent } from './src/components/datatable/empty-list.component'; -import { PaginationComponent } from './src/components/pagination/pagination.component'; import { LoadingContentTemplateDirective } from './src/directives/loading-template.directive'; import { NoContentTemplateDirective } from './src/directives/no-content-template.directive'; @@ -41,8 +39,7 @@ export function directives() { EmptyListComponent, DataTableCellComponent, NoContentTemplateDirective, - LoadingContentTemplateDirective, - PaginationComponent + LoadingContentTemplateDirective ]; } diff --git a/ng2-components/ng2-alfresco-datatable/src/components/pagination/pagination.component.css b/ng2-components/ng2-alfresco-datatable/src/components/pagination/pagination.component.css deleted file mode 100644 index faed4d0dbf..0000000000 --- a/ng2-components/ng2-alfresco-datatable/src/components/pagination/pagination.component.css +++ /dev/null @@ -1,63 +0,0 @@ -.mdl-paging { - color: rgba(0, 0, 0, 0.54); - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - height: 56px; - -webkit-flex-flow: row wrap; - -ms-flex-flow: row wrap; - flex-flow: row wrap; -} - -.mdl-paging > * { - -webkit-flex: none; - -ms-flex: none; - flex: none; -} - -.mdl-list + .mdl-paging { - margin: 0; -} - -.mdl-paging__per-page { - position: relative; -} - -.mdl-paging__per-page-label { - margin-right: 40px; -} - -.mdl-paging__per-page-value { - right: 36px; - top: 6px; -} - -.mdl-paging__per-page + .mdl-paging__count { - margin-left: 24px; -} - -.mdl-paging .mdl-menu { - min-width: 64px; -} - -.mdl-paging__prev:last-child { - margin-right: 44px; -} - -.mdl-paging__count + .mdl-paging__prev { - margin-left: 24px; -} - -.mdl-paging__prev + .mdl-paging__next { - margin-left: 12px; -} - -.mdl-paging__count + .mdl-paging__next { - margin-left: 68px; -} diff --git a/ng2-components/ng2-alfresco-datatable/src/components/pagination/pagination.component.html b/ng2-components/ng2-alfresco-datatable/src/components/pagination/pagination.component.html deleted file mode 100644 index 3fe519bcd6..0000000000 --- a/ng2-components/ng2-alfresco-datatable/src/components/pagination/pagination.component.html +++ /dev/null @@ -1,27 +0,0 @@ -
- - Rows per page: - {{pagination.maxItems}} - - -
- {{size}} -
-
- -
- {{summary}} - - -
diff --git a/ng2-components/ng2-alfresco-datatable/src/components/pagination/pagination.component.spec.ts b/ng2-components/ng2-alfresco-datatable/src/components/pagination/pagination.component.spec.ts deleted file mode 100644 index 1d5856cee5..0000000000 --- a/ng2-components/ng2-alfresco-datatable/src/components/pagination/pagination.component.spec.ts +++ /dev/null @@ -1,108 +0,0 @@ -/*! - * @license - * Copyright 2016 Alfresco Software, Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Injector, SimpleChange } from '@angular/core'; -import { getTestBed, TestBed } from '@angular/core/testing'; -import { PaginationData } from '../../models/pagination.data'; -import { PaginationComponent } from '../pagination/pagination.component'; - -describe('PaginationComponent', () => { - let injector: Injector; - let paginationComponent: PaginationComponent; - - beforeEach(() => { - TestBed.configureTestingModule({ - providers: [ - PaginationComponent - ] - }); - injector = getTestBed(); - paginationComponent = injector.get(PaginationComponent); - paginationComponent.pagination = new PaginationData(0, 0, 0, 20, true); - }); - - it('should create Pagination object on init if no object pagination is passed', () => { - paginationComponent.pagination = null; - paginationComponent.ngOnInit(); - expect(paginationComponent.pagination).not.toBe(null); - }); - - it('is defined', () => { - expect(paginationComponent).toBeDefined(); - }); - - it('page size', () => { - expect(paginationComponent.pagination.maxItems).toBe(20); - }); - - it('set page size', () => { - paginationComponent.pagination.maxItems = 100; - expect(paginationComponent.pagination.maxItems).toBe(100); - }); - - it('prevPageAvail dafault false', () => { - expect(paginationComponent.prevPageAvail()).toBe(false); - }); - - it('nextPageAvail default true', () => { - expect(paginationComponent.nextPageAvail()).toBe(true); - }); - - it('showNextPage', () => { - expect(paginationComponent.pagination.skipCount).toBe(0); - paginationComponent.showNextPage(); - expect(paginationComponent.pagination.skipCount).toBe(20); - }); - - it('showPrevPage', () => { - paginationComponent.pagination.skipCount = 100; - paginationComponent.showPrevPage(); - expect(paginationComponent.pagination.skipCount).toBe(80); - }); - - it('should update the summary on nextpage click', () => { - spyOn(paginationComponent, 'updateSummary'); - - paginationComponent.showNextPage(); - - expect(paginationComponent.updateSummary).toHaveBeenCalled(); - }); - - it('should update the summary on prevpage click', () => { - spyOn(paginationComponent, 'updateSummary'); - - paginationComponent.showPrevPage(); - - expect(paginationComponent.updateSummary).toHaveBeenCalled(); - }); - - it('should update the summary on chage page size click', () => { - spyOn(paginationComponent, 'updateSummary'); - - paginationComponent.setPageSize(100); - - expect(paginationComponent.updateSummary).toHaveBeenCalled(); - }); - - it('should update the summary on input pagination parameter change', () => { - spyOn(paginationComponent, 'updateSummary'); - - paginationComponent.ngOnChanges({pagination: new SimpleChange(null, new PaginationData(0, 0, 0, 20, true), true)}); - - expect(paginationComponent.updateSummary).toHaveBeenCalled(); - }); -}); diff --git a/ng2-components/ng2-alfresco-datatable/src/components/pagination/pagination.component.ts b/ng2-components/ng2-alfresco-datatable/src/components/pagination/pagination.component.ts deleted file mode 100644 index c21cf021ff..0000000000 --- a/ng2-components/ng2-alfresco-datatable/src/components/pagination/pagination.component.ts +++ /dev/null @@ -1,104 +0,0 @@ -/*! - * @license - * Copyright 2016 Alfresco Software, Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core'; -import { Pagination } from 'alfresco-js-api'; -import { PaginationData } from '../../models/pagination.data'; - -@Component({ - selector: 'adf-pagination, alfresco-pagination', - templateUrl: './pagination.component.html', - styleUrls: ['./pagination.component.css'] -}) -export class PaginationComponent implements OnInit, OnChanges { - - static DEFAULT_PAGE_SIZE: number = 20; - - summary: string = ''; - - @Input() - supportedPageSizes: number[] = [5, 10, 20, 50, 100]; - - @Input() - maxItems: number = PaginationComponent.DEFAULT_PAGE_SIZE; - - @Input() - pagination: Pagination; - - @Output() - changePageSize: EventEmitter = new EventEmitter(); - - @Output() - nextPage: EventEmitter = new EventEmitter(); - - @Output() - prevPage: EventEmitter = new EventEmitter(); - - constructor() { - } - - ngOnInit() { - if (!this.pagination) { - this.pagination = new PaginationData(0, 0, 0, this.maxItems, true); - } - } - - ngOnChanges(changes: SimpleChanges) { - if (changes['pagination']) { - if (changes['pagination'].currentValue) { - this.pagination = changes['pagination'].currentValue; - this.updateSummary(); - } - } - } - - setPageSize(value: number) { - this.pagination.maxItems = value; - this.updateSummary(); - this.changePageSize.emit(this.pagination); - } - - nextPageAvail(): boolean { - return this.pagination.hasMoreItems; - } - - prevPageAvail(): boolean { - return this.pagination.skipCount > 0; - } - - showNextPage() { - this.pagination.skipCount += this.pagination.maxItems; - this.updateSummary(); - this.nextPage.emit(this.pagination); - } - - showPrevPage() { - this.pagination.skipCount -= this.pagination.maxItems; - this.updateSummary(); - this.prevPage.emit(this.pagination); - } - - updateSummary() { - let from = this.pagination.skipCount; - if (from === 0) { - from = 1; - } - let to = this.pagination.skipCount + this.pagination.count; - let of = this.pagination.totalItems; - this.summary = `${from}-${to} of ${of}`; - } -} diff --git a/ng2-components/ng2-alfresco-datatable/src/models/pagination.data.ts b/ng2-components/ng2-alfresco-datatable/src/models/pagination.data.ts deleted file mode 100644 index 94fbe0d19e..0000000000 --- a/ng2-components/ng2-alfresco-datatable/src/models/pagination.data.ts +++ /dev/null @@ -1,57 +0,0 @@ -/*! - * @license - * Copyright 2016 Alfresco Software, Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Pagination } from 'alfresco-js-api'; - -export class PaginationData implements Pagination { - - /** - * The number of objects in the collection. - */ - count: number; - - /** - * A boolean value which is true if there are more entities in the collection beyond those in this response. - * A true value means a request with a larger value for the skipCount or the maxItems parameter will return more entities. - */ - hasMoreItems: boolean; - - /** - * An integer describing the total number of entities in the collection. - * The API might not be able to determine this value, in which case this property will not be present. - */ - totalItems: number; - - /** - * An integer describing how many entities exist in the collection before those included in this list. - */ - skipCount: number; - - /** - * The value of the maxItems parameter used to generate this list, - * or if there was no maxItems parameter the default value is 100. - */ - maxItems: number; - - constructor(count: number, totalItems: number, skipCount: number, maxItems: number, hasMoreItems: boolean) { - this.count = count; - this.hasMoreItems = hasMoreItems; - this.totalItems = totalItems; - this.skipCount = skipCount; - this.maxItems = maxItems; - } -} diff --git a/ng2-components/ng2-alfresco-documentlist/src/components/document-list.component.html b/ng2-components/ng2-alfresco-documentlist/src/components/document-list.component.html index 4c4b76b02d..43235a77c2 100644 --- a/ng2-components/ng2-alfresco-documentlist/src/components/document-list.component.html +++ b/ng2-components/ng2-alfresco-documentlist/src/components/document-list.component.html @@ -5,6 +5,7 @@ (error)="onActionMenuError($event)" (permissionErrorEvent)="onPermissionError($event)"> + +
@@ -33,24 +35,28 @@
+
- +
- + + diff --git a/ng2-components/ng2-alfresco-search/src/components/search.component.html b/ng2-components/ng2-alfresco-search/src/components/search.component.html index 4882f862b6..da814fe06f 100644 --- a/ng2-components/ng2-alfresco-search/src/components/search.component.html +++ b/ng2-components/ng2-alfresco-search/src/components/search.component.html @@ -68,6 +68,7 @@ + { let result = { list: { + pagination: { + hasMoreItems: false, + maxItems: 25, + skipCount: 0, + totalItems: 1 + }, entries: [ { entry: { @@ -55,6 +61,12 @@ describe('SearchComponent', () => { let folderResult = { list: { + pagination: { + hasMoreItems: false, + maxItems: 25, + skipCount: 0, + totalItems: 1 + }, entries: [ { entry: { @@ -76,6 +88,12 @@ describe('SearchComponent', () => { let noResult = { list: { + pagination: { + hasMoreItems: false, + maxItems: 25, + skipCount: 0, + totalItems: 0 + }, entries: [] } };