diff --git a/.travis.yml b/.travis.yml index 5be48fb0ff..e15bf35b9c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -38,14 +38,21 @@ before_script: (cd ng2-components/ng2-alfresco-datatable; npm link ng2-alfresco-core; if [ ! -d "bundles" ]; then npm link; fi); fi - if ([ "$MODULE" == "ng2-activiti-tasklist" ] || [ "$MODULE" == "ng2-activiti-processlist" ]); then + (cd ng2-components/ng2-alfresco-datatable; npm link ng2-alfresco-core; if [ ! -d "bundles" ]; then npm link; fi); (cd ng2-components/ng2-activiti-form; npm link ng2-alfresco-core; if [ ! -d "bundles" ]; then npm link; fi); fi - if ([ "$MODULE" == "ng2-activiti-processlist" ]); then + (cd ng2-components/ng2-alfresco-datatable; npm link ng2-alfresco-core; if [ ! -d "bundles" ]; then npm link; fi); + (cd ng2-components/ng2-activiti-form; npm link ng2-alfresco-core; if [ ! -d "bundles" ]; then npm link; fi); (cd ng2-components/ng2-activiti-tasklist; npm link ng2-alfresco-core; npm link ng2-alfresco-datatable; npm link ng2-activiti-form; if [ ! -d "bundles" ]; then npm link; fi); fi - if ([ "$MODULE" == "ng2-activiti-analytics" ]); then (cd ng2-components/ng2-activiti-diagrams; npm link ng2-alfresco-core; if [ ! -d "bundles" ]; then npm link; fi); fi + - if ([ "$MODULE" == "ng2-alfresco-search" ]); then + (cd ng2-components/ng2-alfresco-datatable; npm link ng2-alfresco-core; if [ ! -d "bundles" ]; then npm link; fi); + (cd ng2-components/ng2-alfresco-documentlist; npm link ng2-alfresco-core; npm link ng2-alfresco-datatable; if [ ! -d "bundles" ]; then npm link; fi); + fi - cd ng2-components/$MODULE; - npm run travis; #npm insall run install, build and tests diff --git a/appveyor.yml b/appveyor.yml index ef6eab1287..e333bfdeee 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -30,22 +30,19 @@ install: # Get the latest stable version of Node.js or io.js - ps: Install-Product node $env:nodejs_version # install module - - IF %COMPONENT_NAME% NEQ ng2-alfresco-core (cd ng2-components/ng2-alfresco-core && npm install && npm link && cd ../../) - - IF %COMPONENT_NAME% EQU ng2-alfresco-documentlist (cd ng2-components/ng2-alfresco-datatable && npm link ng2-alfresco-core && npm install && npm link && cd ../../) - - IF %COMPONENT_NAME% EQU ng2-activiti-processlist (cd ng2-components/ng2-alfresco-datatable && npm link ng2-alfresco-core && npm install && npm link && cd ../../) - - IF %COMPONENT_NAME% EQU ng2-activiti-processlist (cd ng2-components/ng2-activiti-form && npm link ng2-alfresco-core && npm install && npm link && cd ../../) - - IF %COMPONENT_NAME% EQU ng2-activiti-processlist (cd ng2-components/ng2-activiti-tasklist && npm link ng2-alfresco-core && npm link ng2-alfresco-datatable && npm link ng2-activiti-form && npm install && npm link && cd ../../) - - IF %COMPONENT_NAME% EQU ng2-activiti-tasklist (cd ng2-components/ng2-alfresco-datatable && npm link ng2-alfresco-core && npm install && npm link && cd ../../) - - IF %COMPONENT_NAME% EQU ng2-activiti-tasklist (cd ng2-components/ng2-activiti-form && npm link ng2-alfresco-core && npm install && npm link && cd ../../) - - IF %COMPONENT_NAME% EQU ng2-alfresco-webscript (cd ng2-components/ng2-alfresco-datatable && npm link ng2-alfresco-core && npm install && npm link && cd ../../) - - IF %COMPONENT_NAME% EQU ng2-activiti-analytics (cd ng2-components/ng2-activiti-diagrams && npm link link ng2-alfresco-core && npm install && npm link && cd ../../) + - IF %COMPONENT_NAME% NEQ ng2-alfresco-core (cd ng2-components/ng2-alfresco-core && npm link && cd ../../) + - IF %COMPONENT_NAME% EQU ng2-alfresco-documentlist (cd ng2-components/ng2-alfresco-datatable && npm link ng2-alfresco-core && npm link && cd ../../) + - IF %COMPONENT_NAME% EQU ng2-alfresco-search (cd ng2-components/ng2-alfresco-datatable && npm link ng2-alfresco-core && npm link && cd ../../) + - IF %COMPONENT_NAME% EQU ng2-alfresco-search (cd ng2-components/ng2-alfresco-documentlist && npm link ng2-alfresco-core && npm link ng2-alfresco-datatable && npm link && cd ../../) + - IF %COMPONENT_NAME% EQU ng2-activiti-processlist (cd ng2-components/ng2-alfresco-datatable && npm link ng2-alfresco-core && npm link && cd ../../) + - IF %COMPONENT_NAME% EQU ng2-activiti-processlist (cd ng2-components/ng2-activiti-form && npm link ng2-alfresco-core && npm link && cd ../../) + - IF %COMPONENT_NAME% EQU ng2-activiti-processlist (cd ng2-components/ng2-activiti-tasklist && npm link ng2-alfresco-core && npm link ng2-alfresco-datatable && npm link ng2-activiti-form && npm link && cd ../../) + - IF %COMPONENT_NAME% EQU ng2-activiti-tasklist (cd ng2-components/ng2-alfresco-datatable && npm link ng2-alfresco-core && npm link && cd ../../) + - IF %COMPONENT_NAME% EQU ng2-activiti-tasklist (cd ng2-components/ng2-activiti-form && npm link ng2-alfresco-core && npm link && cd ../../) + - IF %COMPONENT_NAME% EQU ng2-alfresco-webscript (cd ng2-components/ng2-alfresco-datatable && npm link ng2-alfresco-core && npm link && cd ../../) + - IF %COMPONENT_NAME% EQU ng2-activiti-analytics (cd ng2-components/ng2-activiti-diagrams && npm link link ng2-alfresco-core && npm link && cd ../../) - cd ng2-components/%COMPONENT_NAME% - - IF %COMPONENT_NAME% NEQ ng2-alfresco-core (npm link ng2-alfresco-core) - - IF %COMPONENT_NAME% EQU ng2-alfresco-documentlist (npm link ng2-alfresco-datatable) - - IF %COMPONENT_NAME% EQU ng2-activiti-processlist (npm link ng2-alfresco-datatable && npm link ng2-activiti-form && npm link ng2-activiti-tasklist) - - IF %COMPONENT_NAME% EQU ng2-activiti-tasklist (npm link ng2-alfresco-datatable && npm link ng2-activiti-form) - - IF %COMPONENT_NAME% EQU ng2-alfresco-webscript (npm link ng2-alfresco-datatable) - - IF %COMPONENT_NAME% EQU ng2-activiti-analytics (npm link ng2-activiti-diagrams) + - npm run travis # Post-install test scripts. test_script: diff --git a/demo-shell-ng2/app/components/files/files.component.html b/demo-shell-ng2/app/components/files/files.component.html index 9c03991ed6..f8b6e7e7ab 100644 --- a/demo-shell-ng2/app/components/files/files.component.html +++ b/demo-shell-ng2/app/components/files/files.component.html @@ -96,10 +96,6 @@ - - diff --git a/demo-shell-ng2/app/components/search/search.component.html b/demo-shell-ng2/app/components/search/search.component.html index 8e5f7d755c..bdd4757b17 100644 --- a/demo-shell-ng2/app/components/search/search.component.html +++ b/demo-shell-ng2/app/components/search/search.component.html @@ -1,8 +1,12 @@

Search results

- +
- -
-
+
+ +
+
+
diff --git a/demo-shell-ng2/app/components/search/search.component.ts b/demo-shell-ng2/app/components/search/search.component.ts index 6351a0b5b2..9882609249 100644 --- a/demo-shell-ng2/app/components/search/search.component.ts +++ b/demo-shell-ng2/app/components/search/search.component.ts @@ -47,18 +47,18 @@ import { MinimalNodeEntity } from 'alfresco-js-api'; }) export class SearchComponent { - fileShowed: boolean = false; fileNodeId: string; + fileShowed: boolean = false; constructor(public router: Router) { } - onNavigateItem(event: MinimalNodeEntity) { - if (event.entry.isFile) { - this.fileNodeId = event.entry.id; + showFile(event) { + if (event.value.entry.isFile) { + this.fileNodeId = event.value.entry.id; this.fileShowed = true; - } else if (event.entry.isFolder) { - this.router.navigate(['/files', event.entry.id]); + } else { + this.fileShowed = false; } } } diff --git a/ng2-components/ng2-activiti-analytics/karma-test-shim.js b/ng2-components/ng2-activiti-analytics/karma-test-shim.js index d346348361..50673b05cb 100644 --- a/ng2-components/ng2-activiti-analytics/karma-test-shim.js +++ b/ng2-components/ng2-activiti-analytics/karma-test-shim.js @@ -1,7 +1,14 @@ // Tun on full stack traces in errors to help debugging Error.stackTraceLimit = Infinity; -// jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; +jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000; + +window.componentHandler = { + upgradeAllRegistered: function () { + }, + upgradeElement: function () { + } +}; __karma__.loaded = function() {}; diff --git a/ng2-components/ng2-activiti-diagrams/karma-test-shim.js b/ng2-components/ng2-activiti-diagrams/karma-test-shim.js index 04a45e501c..085bf02f56 100644 --- a/ng2-components/ng2-activiti-diagrams/karma-test-shim.js +++ b/ng2-components/ng2-activiti-diagrams/karma-test-shim.js @@ -1,7 +1,14 @@ // Tun on full stack traces in errors to help debugging Error.stackTraceLimit = Infinity; -// jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; +jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000; + +window.componentHandler = { + upgradeAllRegistered: function () { + }, + upgradeElement: function () { + } +}; __karma__.loaded = function() {}; diff --git a/ng2-components/ng2-activiti-form/karma-test-shim.js b/ng2-components/ng2-activiti-form/karma-test-shim.js index ac2dd6fcfb..1751adb04e 100644 --- a/ng2-components/ng2-activiti-form/karma-test-shim.js +++ b/ng2-components/ng2-activiti-form/karma-test-shim.js @@ -1,7 +1,14 @@ // Tun on full stack traces in errors to help debugging Error.stackTraceLimit = Infinity; -// jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; +jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000; + +window.componentHandler = { + upgradeAllRegistered: function () { + }, + upgradeElement: function () { + } +}; __karma__.loaded = function() {}; diff --git a/ng2-components/ng2-activiti-processlist/karma-test-shim.js b/ng2-components/ng2-activiti-processlist/karma-test-shim.js index 8ab8026459..b3f275d74f 100644 --- a/ng2-components/ng2-activiti-processlist/karma-test-shim.js +++ b/ng2-components/ng2-activiti-processlist/karma-test-shim.js @@ -1,7 +1,14 @@ // Tun on full stack traces in errors to help debugging Error.stackTraceLimit = Infinity; -// jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; +jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000; + +window.componentHandler = { + upgradeAllRegistered: function () { + }, + upgradeElement: function () { + } +}; __karma__.loaded = function() {}; diff --git a/ng2-components/ng2-activiti-tasklist/karma-test-shim.js b/ng2-components/ng2-activiti-tasklist/karma-test-shim.js index a66c8eb6a9..9f594e357b 100644 --- a/ng2-components/ng2-activiti-tasklist/karma-test-shim.js +++ b/ng2-components/ng2-activiti-tasklist/karma-test-shim.js @@ -1,7 +1,14 @@ // Tun on full stack traces in errors to help debugging Error.stackTraceLimit = Infinity; -// jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; +jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000; + +window.componentHandler = { + upgradeAllRegistered: function () { + }, + upgradeElement: function () { + } +}; __karma__.loaded = function() {}; diff --git a/ng2-components/ng2-alfresco-core/karma-test-shim.js b/ng2-components/ng2-alfresco-core/karma-test-shim.js index c6de4c47e5..23ec0d86d4 100644 --- a/ng2-components/ng2-alfresco-core/karma-test-shim.js +++ b/ng2-components/ng2-alfresco-core/karma-test-shim.js @@ -1,7 +1,14 @@ // Tun on full stack traces in errors to help debugging Error.stackTraceLimit = Infinity; -// jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; +jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000; + +window.componentHandler = { + upgradeAllRegistered: function () { + }, + upgradeElement: function () { + } +}; __karma__.loaded = function() {}; diff --git a/ng2-components/ng2-alfresco-datatable/README.md b/ng2-components/ng2-alfresco-datatable/README.md index 4ae455c08d..733717418b 100644 --- a/ng2-components/ng2-alfresco-datatable/README.md +++ b/ng2-components/ng2-alfresco-datatable/README.md @@ -441,6 +441,31 @@ let schema = ObjectDataTableAdapter.generateSchema(data); ``` +# Pagination Component + +The pagination object is a generic component to paginate component. The Alfresco API are paginated and returns a Pagination object. You can use the pagination object to feed the pagination component and then listen to the event which return the current pagination and query again the API with the options choose by the user. + +![DataTable demo](docs/assets/pagination-demo.png) + + +### Properties + +| Name | Type | Default | Description +| --- | --- | --- | --- | +| `supportedPageSizes` | numer[] | [5, 10, 20, 50, 100] | This array describe the set of options showed in the pick list | +| `maxItems` | boolean | false | Max number of element showed per page. If you pick another size from the pick list this option will be overwritten | +| `pagination` | Pagination | {count: 0, totalItems: 0, skipCount: 0, maxItems: 20 , hasMoreItems: true} | The Alfresco Api return a pagination object, you can use it to feed the pagination component, or create your own. | + +### Events + +| Name | Description +| --- | --- | +| `changePageSize` | Emitted when user picks one of the options from the pick list | +| `nextPage` | Emitted when user clicks next page button | +| `prevPage` | Emitted when user clicks prev page button | + +All the events carry with them the current pagination object. + ## Build from sources Alternatively you can build component from sources with the following commands: diff --git a/ng2-components/ng2-alfresco-datatable/docs/assets/pagination-demo.png b/ng2-components/ng2-alfresco-datatable/docs/assets/pagination-demo.png new file mode 100644 index 0000000000..bd78a01440 Binary files /dev/null and b/ng2-components/ng2-alfresco-datatable/docs/assets/pagination-demo.png differ diff --git a/ng2-components/ng2-alfresco-datatable/karma-test-shim.js b/ng2-components/ng2-alfresco-datatable/karma-test-shim.js index b922a90bce..6aa9dd62c7 100644 --- a/ng2-components/ng2-alfresco-datatable/karma-test-shim.js +++ b/ng2-components/ng2-alfresco-datatable/karma-test-shim.js @@ -1,7 +1,14 @@ // Tun on full stack traces in errors to help debugging Error.stackTraceLimit = Infinity; -// jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; +jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000; + +window.componentHandler = { + upgradeAllRegistered: function () { + }, + upgradeElement: function () { + } +}; __karma__.loaded = function() {}; diff --git a/ng2-components/ng2-alfresco-datatable/src/components/pagination/index.ts b/ng2-components/ng2-alfresco-datatable/src/components/pagination/index.ts index 1b1e7e47b6..4f9699a18c 100644 --- a/ng2-components/ng2-alfresco-datatable/src/components/pagination/index.ts +++ b/ng2-components/ng2-alfresco-datatable/src/components/pagination/index.ts @@ -15,5 +15,4 @@ * limitations under the License. */ -export * from './paginationProvider.interface'; export * from './pagination.component'; 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 index 297974de9a..5598cc3b73 100644 --- a/ng2-components/ng2-alfresco-datatable/src/components/pagination/pagination.component.html +++ b/ng2-components/ng2-alfresco-datatable/src/components/pagination/pagination.component.html @@ -1,7 +1,7 @@ -
+
Rows per page: - {{pageSize}} + {{pagination.maxItems}} @@ -15,12 +15,12 @@ {{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 index 6266faa761..e69a226dcd 100644 --- 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 @@ -16,17 +16,9 @@ */ import { PaginationComponent } from '../pagination/pagination.component'; -import { PaginationProvider, DataLoadedEventEmitter} from '../pagination/paginationProvider.interface'; -import { Injector } from '@angular/core'; -import { getTestBed, TestBed} from '@angular/core/testing'; - -class CustomPaginationProvider implements PaginationProvider { - skipCount: number = 0; - dataLoaded: DataLoadedEventEmitter; - count: number = 200; - hasMoreItems: boolean = false; - maxItems: number = 20; -} +import { PaginationData } from '../../models/pagination.data'; +import { Injector, SimpleChange } from '@angular/core'; +import { getTestBed, TestBed } from '@angular/core/testing'; describe('PaginationComponent', () => { let injector: Injector; @@ -40,7 +32,13 @@ describe('PaginationComponent', () => { }); injector = getTestBed(); paginationComponent = injector.get(PaginationComponent); - paginationComponent.provider = new CustomPaginationProvider(); + 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', () => { @@ -48,35 +46,63 @@ describe('PaginationComponent', () => { }); it('page size', () => { - expect(paginationComponent.pageSize).toBe(20); + expect(paginationComponent.pagination.maxItems).toBe(20); }); it('set page size', () => { - paginationComponent.pageSize = 100; - expect(paginationComponent.pageSize).toBe(100); + paginationComponent.pagination.maxItems = 100; + expect(paginationComponent.pagination.maxItems).toBe(100); }); - it('prevPageAvail', () => { - expect(paginationComponent.prevPageAvail).toBe(false); + it('prevPageAvail dafault false', () => { + expect(paginationComponent.prevPageAvail()).toBe(false); }); - it('nextPageAvail', () => { - expect(paginationComponent.nextPageAvail).toBe(false); + it('nextPageAvail default true', () => { + expect(paginationComponent.nextPageAvail()).toBe(true); }); it('showNextPage', () => { - expect(paginationComponent.provider.skipCount).toBe(0); + expect(paginationComponent.pagination.skipCount).toBe(0); paginationComponent.showNextPage(); - expect(paginationComponent.provider.skipCount).toBe(20); + expect(paginationComponent.pagination.skipCount).toBe(20); }); it('showPrevPage', () => { - paginationComponent.provider.skipCount = 100; + paginationComponent.pagination.skipCount = 100; paginationComponent.showPrevPage(); - expect(paginationComponent.provider.skipCount).toBe(80); + expect(paginationComponent.pagination.skipCount).toBe(80); }); - it('PaginationProvider', () => { - expect(paginationComponent.provider instanceof CustomPaginationProvider).toBeTruthy(); + 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))}); + + 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 index fdc0d233c6..c689de3ae9 100644 --- a/ng2-components/ng2-alfresco-datatable/src/components/pagination/pagination.component.ts +++ b/ng2-components/ng2-alfresco-datatable/src/components/pagination/pagination.component.ts @@ -15,8 +15,9 @@ * limitations under the License. */ -import { Component, Input, OnInit } from '@angular/core'; -import { PaginationProvider } from './paginationProvider.interface'; +import { SimpleChanges, OnChanges, EventEmitter, Output, Component, Input, OnInit } from '@angular/core'; +import { PaginationData } from '../../models/pagination.data'; +import { Pagination } from 'alfresco-js-api'; @Component({ moduleId: module.id, @@ -24,68 +25,81 @@ import { PaginationProvider } from './paginationProvider.interface'; templateUrl: './pagination.component.html', styleUrls: ['./pagination.component.css'] }) -export class PaginationComponent implements OnInit { +export class PaginationComponent implements OnInit, OnChanges { - DEFAULT_PAGE_SIZE: number = 20; + static DEFAULT_PAGE_SIZE: number = 20; - private _summary: string = ''; + private summary: string = ''; @Input() supportedPageSizes: number[] = [5, 10, 20, 50, 100]; @Input() - provider: PaginationProvider; + maxItems: number = PaginationComponent.DEFAULT_PAGE_SIZE; - get pageSize(): number { - if (this.provider) { - return this.provider.maxItems; - } - return this.DEFAULT_PAGE_SIZE; + @Input() + pagination: Pagination; + + @Output() + changePageSize: EventEmitter = new EventEmitter(); + + @Output() + nextPage: EventEmitter = new EventEmitter(); + + @Output() + prevPage: EventEmitter = new EventEmitter(); + + constructor() { } - set pageSize(value: number) { - if (this.provider) { - this.provider.maxItems = value; + 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.pageSize = value; + this.pagination.maxItems = value; + this.updateSummary(); + this.changePageSize.emit(this.pagination); } - get summary(): string { - return this._summary; + nextPageAvail(): boolean { + return this.pagination.hasMoreItems; } - get nextPageAvail(): boolean { - return this.provider.hasMoreItems; - } - - get prevPageAvail(): boolean { - return this.provider.skipCount > 0; + prevPageAvail(): boolean { + return this.pagination.skipCount > 0; } showNextPage() { - this.provider.skipCount += this.provider.maxItems; + this.pagination.skipCount += this.pagination.maxItems; + this.updateSummary(); + this.nextPage.emit(this.pagination); } showPrevPage() { - this.provider.skipCount -= this.provider.maxItems; + this.pagination.skipCount -= this.pagination.maxItems; + this.updateSummary(); + this.prevPage.emit(this.pagination); } - ngOnInit() { - this.provider.dataLoaded.subscribe(() => { - this.updateSummary(); - }); - } - - private updateSummary() { - let from = this.provider.skipCount; + updateSummary() { + let from = this.pagination.skipCount; if (from === 0) { from = 1; } - let to = this.provider.skipCount + this.provider.count; - let of = this.provider.totalItems; - this._summary = `${from}-${to} of ${of}`; + 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/components/pagination/paginationProvider.interface.ts b/ng2-components/ng2-alfresco-datatable/src/models/pagination.data.ts similarity index 78% rename from ng2-components/ng2-alfresco-datatable/src/components/pagination/paginationProvider.interface.ts rename to ng2-components/ng2-alfresco-datatable/src/models/pagination.data.ts index fb445a0364..94fbe0d19e 100644 --- a/ng2-components/ng2-alfresco-datatable/src/components/pagination/paginationProvider.interface.ts +++ b/ng2-components/ng2-alfresco-datatable/src/models/pagination.data.ts @@ -15,9 +15,9 @@ * limitations under the License. */ -import { Subject } from 'rxjs/Rx'; +import { Pagination } from 'alfresco-js-api'; -export interface PaginationProvider { +export class PaginationData implements Pagination { /** * The number of objects in the collection. @@ -34,7 +34,7 @@ export interface PaginationProvider { * 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; + totalItems: number; /** * An integer describing how many entities exist in the collection before those included in this list. @@ -47,18 +47,11 @@ export interface PaginationProvider { */ maxItems: number; - /** - * An event that is emitted every time data is loaded. - */ - dataLoaded: DataLoadedEventEmitter; -} - -export class DataLoadedEventEmitter extends Subject { - constructor() { - super(); - } - - emit(value) { - super.next(value); + 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/README.md b/ng2-components/ng2-alfresco-documentlist/README.md index 2df200747f..ea4be1c6d1 100644 --- a/ng2-components/ng2-alfresco-documentlist/README.md +++ b/ng2-components/ng2-alfresco-documentlist/README.md @@ -168,10 +168,13 @@ platformBrowserDynamic().bootstrapModule(AppModule); ### Properties +The properties currentFolderId, folderNode and node are the entry initialization properties of the document list. They can not be used together, choose the one that suites more your use case. + | Name | Type | Default | Description | | --- | --- | --- | --- | | `currentFolderId` | string | null | Initial node ID of displayed folder. Can be `-root-`, `-shared-`, `-my-`, or a fixed node ID | | `folderNode` | `MinimalNodeEntryEntity` | null | Currently displayed folder node | +| `node` | `NodePaging` | null | Document list will show all the node contained in the NodePaging entity | | `navigate` | boolean | true | Toggles navigation to folder content or file preview | | `navigationMode` | string (click\|dblclick) | dblclick | User interaction for folder navigation or file preview | | `thumbnails` | boolean | false | Show document thumbnails rather than icons | @@ -179,6 +182,7 @@ platformBrowserDynamic().bootstrapModule(AppModule); | `multiselect` | boolean | false | Toggles multiselect mode | | `contentActions` | boolean | false | Toggles content actions for each row | | `contextMenuActions` | boolean | false | Toggles context menus for each row | +| `enablePagination` | boolean | true | Shows pagination | | `creationMenuActions` | boolean | true | Toggles the creation menu actions| | `rowFilter` | `RowFilter` | | Custom row filter, [see more](#custom-row-filter). | `imageResolver` | `ImageResolver` | | Custom image resolver, [see more](#custom-image-resolver). diff --git a/ng2-components/ng2-alfresco-documentlist/karma-test-shim.js b/ng2-components/ng2-alfresco-documentlist/karma-test-shim.js index dcfa63a5ae..53e4408aa1 100644 --- a/ng2-components/ng2-alfresco-documentlist/karma-test-shim.js +++ b/ng2-components/ng2-alfresco-documentlist/karma-test-shim.js @@ -1,7 +1,14 @@ // Tun on full stack traces in errors to help debugging Error.stackTraceLimit = Infinity; -// jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; +jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000; + +window.componentHandler = { + upgradeAllRegistered: function () { + }, + upgradeElement: function () { + } +}; __karma__.loaded = function() {}; 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 2d582847bb..bb164fbc3c 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 @@ -27,4 +27,11 @@
+ + diff --git a/ng2-components/ng2-alfresco-documentlist/src/components/document-list.component.spec.ts b/ng2-components/ng2-alfresco-documentlist/src/components/document-list.component.spec.ts index c2cc0459cb..80fc2da6e1 100644 --- a/ng2-components/ng2-alfresco-documentlist/src/components/document-list.component.spec.ts +++ b/ng2-components/ng2-alfresco-documentlist/src/components/document-list.component.spec.ts @@ -22,7 +22,7 @@ import { DocumentListComponent } from './document-list.component'; import { DocumentListServiceMock } from './../assets/document-list.service.mock'; import { ContentActionModel } from '../models/content-action.model'; import { FileNode, FolderNode } from '../assets/document-library.model.mock'; -import { NodeMinimalEntry } from '../models/document-library.model'; +import { NodeMinimalEntry, NodeMinimal, NodePaging } from '../models/document-library.model'; import { ShareDataRow, RowFilter, ImageResolver } from './../data/share-datatable-adapter'; describe('DocumentList', () => { @@ -291,10 +291,10 @@ describe('DocumentList', () => { }); /* - it('should not get node path for null node', () => { - expect(documentList.getNodePath(null)).toBeNull(); - }); - */ + it('should not get node path for null node', () => { + expect(documentList.getNodePath(null)).toBeNull(); + }); + */ it('should require valid node for file preview', () => { let file = new FileNode(); @@ -326,12 +326,30 @@ describe('DocumentList', () => { expect(documentList.performNavigation).not.toHaveBeenCalled(); }); - it('should display folder content on reload', () => { + it('should display folder content from loadFolder on reload if folderNode defined', () => { + documentList.folderNode = new NodeMinimal(); + spyOn(documentList, 'loadFolder').and.callThrough(); documentList.reload(); expect(documentList.loadFolder).toHaveBeenCalled(); }); + it('should display folder content from loadFolderByNodeId on reload if currentFolderId defined', () => { + documentList.currentFolderId = 'id-folder'; + spyOn(documentListService, 'getFolderNode').and.returnValue(Promise.reject(false)); + spyOn(documentList, 'loadFolderByNodeId').and.callThrough(); + documentList.reload(); + expect(documentList.loadFolderByNodeId).toHaveBeenCalled(); + }); + + it('should display folder content from loadFolderByNodeId on reload if node defined', () => { + documentList.node = new NodePaging(); + + spyOn(documentList.data, 'loadPage').and.callThrough(); + documentList.reload(); + expect(documentList.data.loadPage).toHaveBeenCalled(); + }); + it('should require node to resolve context menu actions', () => { expect(documentList.getContextActions(null)).toBeNull(); @@ -428,6 +446,7 @@ describe('DocumentList', () => { it('should set row filter for underlying adapter', () => { let filter = {}; + documentList.currentFolderId = 'id'; spyOn(documentList.data, 'setFilter').and.callThrough(); documentList.rowFilter = filter; @@ -445,7 +464,7 @@ describe('DocumentList', () => { it('should emit [nodeClick] event on row click', () => { let node = new NodeMinimalEntry(); let row = new ShareDataRow(node); - let event = { value: row }; + let event = {value: row}; spyOn(documentList, 'onNodeClick').and.callThrough(); documentList.onRowClick(event); @@ -455,7 +474,7 @@ describe('DocumentList', () => { it('should emit [nodeDblClick] event on row double-click', () => { let node = new NodeMinimalEntry(); let row = new ShareDataRow(node); - let event = { value: row }; + let event = {value: row}; spyOn(documentList, 'onNodeDblClick').and.callThrough(); documentList.onRowDblClick(event); @@ -464,8 +483,8 @@ describe('DocumentList', () => { it('should load folder by ID on init', () => { documentList.currentFolderId = '1d26e465-dea3-42f3-b415-faa8364b9692'; - spyOn(documentList.data, 'loadById').and.returnValue(Promise.resolve()); - documentList.ngOnInit(); - expect(documentList.data.loadById).toHaveBeenCalled(); + spyOn(documentList, 'loadFolderNodesByFolderNodeId').and.returnValue(Promise.resolve()); + documentList.ngOnChanges({folderNode: new SimpleChange(null, documentList.currentFolderId)}); + expect(documentList.loadFolderNodesByFolderNodeId).toHaveBeenCalled(); }); }); diff --git a/ng2-components/ng2-alfresco-documentlist/src/components/document-list.component.ts b/ng2-components/ng2-alfresco-documentlist/src/components/document-list.component.ts index 13c863d15e..f2a7ebb66d 100644 --- a/ng2-components/ng2-alfresco-documentlist/src/components/document-list.component.ts +++ b/ng2-components/ng2-alfresco-documentlist/src/components/document-list.component.ts @@ -15,9 +15,22 @@ * limitations under the License. */ -import { Component, OnInit, Input, OnChanges, Output, SimpleChanges, EventEmitter, AfterContentInit, TemplateRef, NgZone, ViewChild, HostListener } from '@angular/core'; +import { + Component, + OnInit, + Input, + OnChanges, + Output, + SimpleChanges, + EventEmitter, + AfterContentInit, + TemplateRef, + NgZone, + ViewChild, + HostListener +} from '@angular/core'; import { Subject } from 'rxjs/Rx'; -import { MinimalNodeEntity, MinimalNodeEntryEntity } from 'alfresco-js-api'; +import { MinimalNodeEntity, MinimalNodeEntryEntity, NodePaging, Pagination } from 'alfresco-js-api'; import { AlfrescoTranslationService } from 'ng2-alfresco-core'; import { DataRowEvent, DataTableComponent, ObjectDataColumn } from 'ng2-alfresco-datatable'; import { DocumentListService } from './../services/document-list.service'; @@ -55,6 +68,9 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni @Input() multiselect: boolean = false; + @Input() + enablePagination: boolean = true; + @Input() contentActions: boolean = false; @@ -67,10 +83,15 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni @Input() pageSize: number = DocumentListComponent.DEFAULT_PAGE_SIZE; + skipCount: number = 0; + + pagination: Pagination; + @Input() set rowFilter(value: RowFilter) { - if (this.data) { + if (this.data && value && this.currentFolderId) { this.data.setFilter(value); + this.loadFolderNodesByFolderNodeId(this.currentFolderId, this.pageSize, this.skipCount); } }; @@ -81,6 +102,16 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni } } + // The identifier of a node. You can also use one of these well-known aliases: -my- | -shared- | -root- + @Input() + currentFolderId: string = null; + + @Input() + folderNode: MinimalNodeEntryEntity = null; + + @Input() + node: NodePaging = null; + @Output() nodeClick: EventEmitter = new EventEmitter(); @@ -102,25 +133,17 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni @ViewChild(DataTableComponent) dataTable: DataTableComponent; - // The identifier of a node. You can also use one of these well-known aliases: -my- | -shared- | -root- - @Input() - currentFolderId: string = null; - - @Input() - folderNode: MinimalNodeEntryEntity = null; - errorMessage; actions: ContentActionModel[] = []; emptyFolderTemplate: TemplateRef; contextActionHandler: Subject = new Subject(); data: ShareDataTableAdapter; - constructor( - private documentListService: DocumentListService, - private ngZone: NgZone, - private translateService: AlfrescoTranslationService) { + constructor(private documentListService: DocumentListService, + private ngZone: NgZone, + private translateService: AlfrescoTranslationService) { - this.data = new ShareDataTableAdapter(this.documentListService, './', []); + this.data = new ShareDataTableAdapter(this.documentListService, this.baseComponentPath, []); if (translateService) { translateService.addTranslationFolder('ng2-alfresco-documentlist', 'node_modules/ng2-alfresco-documentlist/src'); @@ -151,15 +174,15 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni ngOnInit() { this.data.thumbnails = this.thumbnails; - this.data.maxItems = this.pageSize; this.contextActionHandler.subscribe(val => this.contextActionCallback(val)); - // Automatically enforce single-click navigation for mobile browsers + this.enforceSingleClickNavigationForMobile(); + } + + private enforceSingleClickNavigationForMobile(): void { if (this.isMobile()) { this.navigationMode = DocumentListComponent.SINGLE_CLICK_NAVIGATION; } - - this.loadFolder(); } ngAfterContentInit() { @@ -172,9 +195,37 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni ngOnChanges(changes: SimpleChanges) { if (changes['folderNode'] && changes['folderNode'].currentValue) { this.loadFolder(); - } else if (changes['currentFolderId'] && changes['currentFolderId'].currentValue) { - this.loadFolderByNodeId(changes['currentFolderId'].currentValue); + return; } + + if (changes['currentFolderId'] && changes['currentFolderId'].currentValue) { + this.loadFolderByNodeId(changes['currentFolderId'].currentValue); + return; + } + + if (changes['node'] && changes['node'].currentValue) { + this.data.loadPage(changes['node'].currentValue); + return; + } + } + + reload() { + this.ngZone.run(() => { + if (this.folderNode) { + this.loadFolder(); + return; + } + + if (this.currentFolderId) { + this.loadFolderByNodeId(this.currentFolderId); + return; + } + + if (this.node) { + this.data.loadPage(this.node); + return; + } + }); } isEmptyTemplateDefined() { @@ -229,7 +280,7 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni this.folderNode = node.entry; this.loadFolder(); - this.folderChange.emit({ node: node.entry }); + this.folderChange.emit({node: node.entry}); return true; } return false; @@ -246,21 +297,10 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni } } - loadFolderById(id: string): Promise { - return this.data.loadById(id); - } - - reload() { - this.ngZone.run(() => { - this.loadFolder(); - }); - } - loadFolder() { let nodeId = this.folderNode ? this.folderNode.id : this.currentFolderId; if (nodeId) { - this.loadFolderById(nodeId) - .catch(err => this.error.emit(err)); + this.loadFolderNodesByFolderNodeId(nodeId, this.pageSize, this.skipCount).catch(err => this.error.emit(err)); } } @@ -269,9 +309,33 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni this.documentListService.getFolderNode(nodeId).then(node => { this.folderNode = node; this.currentFolderId = node.id; - this.data.loadById(node.id).catch(err => this.error.emit(err)); + this.loadFolderNodesByFolderNodeId(node.id, this.pageSize, this.skipCount).catch(err => this.error.emit(err)); }) - .catch(err => this.error.emit(err)); + .catch(err => this.error.emit(err)); + } + + loadFolderNodesByFolderNodeId(id: string, maxItems: number, skipCount: number): Promise { + return new Promise((resolve, reject) => { + if (id && this.documentListService) { + this.documentListService + .getFolder(null, { + maxItems: maxItems, + skipCount: skipCount, + rootFolderId: id + }) + .subscribe(val => { + this.data.loadPage(val); + this.pagination = val.list.pagination; + resolve(true); + }, + error => { + reject(error); + }); + } else { + resolve(false); + } + }); + } /** @@ -387,4 +451,19 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni this.reload(); this.success.emit(event); } + + public onChangePageSize(event: Pagination): void { + this.pageSize = event.maxItems; + this.reload(); + } + + public onNextPage(event: Pagination): void { + this.skipCount = event.skipCount; + this.reload(); + } + + public onPrevPage(event: Pagination): void { + this.skipCount = event.skipCount; + this.reload(); + } } diff --git a/ng2-components/ng2-alfresco-documentlist/src/data/share-datatable-adapter.ts b/ng2-components/ng2-alfresco-documentlist/src/data/share-datatable-adapter.ts index ab112fc0bb..23fd57f915 100644 --- a/ng2-components/ng2-alfresco-documentlist/src/data/share-datatable-adapter.ts +++ b/ng2-components/ng2-alfresco-documentlist/src/data/share-datatable-adapter.ts @@ -17,80 +17,34 @@ import { DatePipe } from '@angular/common'; import { ObjectUtils } from 'ng2-alfresco-core'; -import { PaginationProvider, DataLoadedEventEmitter, DataTableAdapter, DataRow, DataColumn, DataSorting } from 'ng2-alfresco-datatable'; +import { DataTableAdapter, DataRow, DataColumn, DataSorting } from 'ng2-alfresco-datatable'; import { NodePaging, NodeMinimalEntry } from './../models/document-library.model'; import { DocumentListService } from './../services/document-list.service'; -export class ShareDataTableAdapter implements DataTableAdapter, PaginationProvider { +export class ShareDataTableAdapter implements DataTableAdapter { ERR_ROW_NOT_FOUND: string = 'Row not found'; ERR_COL_NOT_FOUND: string = 'Column not found'; DEFAULT_DATE_FORMAT: string = 'medium'; - DEFAULT_PAGE_SIZE: number = 20; - MIN_PAGE_SIZE: number = 5; private sorting: DataSorting; private rows: DataRow[]; private columns: DataColumn[]; private page: NodePaging; - private folderNodeId: string; private filter: RowFilter; private imageResolver: ImageResolver; - private _count: number = 0; - private _hasMoreItems: boolean = false; - private _totalItems: number = 0; - private _skipCount: number = 0; - private _maxItems: number = this.DEFAULT_PAGE_SIZE; - thumbnails: boolean = false; - dataLoaded: DataLoadedEventEmitter; selectedRow: DataRow; constructor(private documentListService: DocumentListService, private basePath: string, schema: DataColumn[]) { - this.dataLoaded = new DataLoadedEventEmitter(); this.rows = []; this.columns = schema || []; - this.resetPagination(); - } - - get count(): number { - return this._count; - } - - get hasMoreItems(): boolean { - return this._hasMoreItems; - } - - get totalItems(): number { - return this._totalItems; - } - - get skipCount(): number { - return this._skipCount; - } - - set skipCount(value: number) { - if (value !== this._skipCount) { - this._skipCount = value > 0 ? value : 0; - this.loadById(this.folderNodeId); - } - } - - get maxItems(): number { - return this._maxItems; - } - - set maxItems(value: number) { - if (value !== this._maxItems) { - this._maxItems = value > this.MIN_PAGE_SIZE ? value : this.MIN_PAGE_SIZE; - this.loadById(this.folderNodeId); - } } getRows(): Array { @@ -198,37 +152,8 @@ export class ShareDataTableAdapter implements DataTableAdapter, PaginationProvid this.setSorting(sorting); } - loadById(id: string): Promise { - return new Promise((resolve, reject) => { - if (id && this.documentListService) { - this.documentListService - .getFolder(null, { - maxItems: this._maxItems, - skipCount: this._skipCount, - rootFolderId: id - }) - .subscribe(val => { - this.folderNodeId = id; - this.loadPage(val); - this.dataLoaded.emit(null); - resolve(true); - }, - error => { - reject(error); - }); - } else { - resolve(false); - } - }); - - } - setFilter(filter: RowFilter) { this.filter = filter; - - if (this.filter && this.folderNodeId) { - this.loadById(this.folderNodeId); - } } setImageResolver(resolver: ImageResolver) { @@ -263,9 +188,8 @@ export class ShareDataTableAdapter implements DataTableAdapter, PaginationProvid } } - private loadPage(page: NodePaging) { + public loadPage(page: NodePaging) { this.page = page; - this.resetPagination(); let rows = []; @@ -293,15 +217,6 @@ export class ShareDataTableAdapter implements DataTableAdapter, PaginationProvid } } } - - let pagination = page.list.pagination; - if (pagination) { - this._count = pagination.count; - this._hasMoreItems = pagination.hasMoreItems; - this._maxItems = pagination.maxItems; - this._skipCount = pagination.skipCount; - this._totalItems = pagination.totalItems; - } } this.rows = rows; @@ -310,14 +225,6 @@ export class ShareDataTableAdapter implements DataTableAdapter, PaginationProvid getImagePath(id: string): any { return `${this.basePath}/assets/images/${id}`; } - - private resetPagination() { - this._count = 0; - this._hasMoreItems = false; - this._totalItems = 0; - this._skipCount = 0; - this._maxItems = this.DEFAULT_PAGE_SIZE; - } } export class ShareDataRow implements DataRow { diff --git a/ng2-components/ng2-alfresco-documentlist/src/services/document-list.service.ts b/ng2-components/ng2-alfresco-documentlist/src/services/document-list.service.ts index f2b4254184..04841f8345 100644 --- a/ng2-components/ng2-alfresco-documentlist/src/services/document-list.service.ts +++ b/ng2-components/ng2-alfresco-documentlist/src/services/document-list.service.ts @@ -124,7 +124,6 @@ export class DocumentListService { include: ['path', 'properties'] }; - // see https://github.com/Alfresco/alfresco-js-api/issues/140 let nodes: any = this.apiService.getInstance().nodes; return nodes.getNodeInfo(nodeId, opts); } diff --git a/ng2-components/ng2-alfresco-login/karma-test-shim.js b/ng2-components/ng2-alfresco-login/karma-test-shim.js index b922a90bce..6aa9dd62c7 100644 --- a/ng2-components/ng2-alfresco-login/karma-test-shim.js +++ b/ng2-components/ng2-alfresco-login/karma-test-shim.js @@ -1,7 +1,14 @@ // Tun on full stack traces in errors to help debugging Error.stackTraceLimit = Infinity; -// jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; +jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000; + +window.componentHandler = { + upgradeAllRegistered: function () { + }, + upgradeElement: function () { + } +}; __karma__.loaded = function() {}; diff --git a/ng2-components/ng2-alfresco-search/README.md b/ng2-components/ng2-alfresco-search/README.md index b35fec0c29..7023fc91c0 100644 --- a/ng2-components/ng2-alfresco-search/README.md +++ b/ng2-components/ng2-alfresco-search/README.md @@ -89,6 +89,7 @@ Follow the 3 steps below: - ng2-alfresco-core - alfresco-js-api - ng2-alfresco-search + - ng2-alfresco-documentlist Please refer to the following example file: [systemjs.config.js](demo/systemjs .config.js) . @@ -165,7 +166,7 @@ platformBrowserDynamic().bootstrapModule(AppModule); | `searchTerm` | {string} | (optional) | "" | Search term to pre-populate the field with | | `inputType` | {string} | (optional) | "text" | Type of the input field to render, e.g. "search" or "text" (default) | | `expandable` | {boolean} | (optional) | true | Whether to use an expanding search control, if false then a regular input is used. | -| `autocomplet` | {boolean} | (optional) | true | Whether the browser should offer field auto-completion for the input field to the user. | +| `autocomplete` | {boolean} | (optional) | true | Whether the browser should offer field auto-completion for the input field to the user. | | `liveSearchEnabled` | {boolean} | (optional) | true | Whether find-as-you-type suggestions should be offered for matching content items. Set to false to disable. | | `liveSearchRoot` | {boolean} | (optional) | "-root-" | NodeRef or node name where the search should start. | | `liveSearchResultType` | {boolean} | (optional) | (none) | Node type to filter live search results by, e.g. 'cm:content'. | @@ -228,7 +229,7 @@ platformBrowserDynamic().bootstrapModule(AppModule); | Name | Description | | --- | --- | -| `navigate` | Emitted when a search result is clicked or double-clicked | +| `preview` | emitted when user acts upon files with either single or double click (depends on `navigation-mode`), recommended for Viewer components integration | | `resultsLoad` | Emitted when search results have fully loaded | #### Options diff --git a/ng2-components/ng2-alfresco-search/demo/i18n/en.json b/ng2-components/ng2-alfresco-search/demo/i18n/en.json deleted file mode 100644 index ff2576b3d3..0000000000 --- a/ng2-components/ng2-alfresco-search/demo/i18n/en.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "SEARCH": { - } -} diff --git a/ng2-components/ng2-alfresco-search/demo/package.json b/ng2-components/ng2-alfresco-search/demo/package.json index 8ceb942c6a..833d2a7347 100644 --- a/ng2-components/ng2-alfresco-search/demo/package.json +++ b/ng2-components/ng2-alfresco-search/demo/package.json @@ -70,6 +70,8 @@ "ng2-translate": "2.5.0", "alfresco-js-api": "^1.0.0", "ng2-alfresco-core": "1.0.0", + "ng2-alfresco-datatable": "1.0.0", + "ng2-alfresco-documentlist": "1.0.0", "ng2-alfresco-search": "^1.0.0" }, "devDependencies": { diff --git a/ng2-components/ng2-alfresco-search/demo/systemjs.config.js b/ng2-components/ng2-alfresco-search/demo/systemjs.config.js index a5ad11779e..13871f886d 100644 --- a/ng2-components/ng2-alfresco-search/demo/systemjs.config.js +++ b/ng2-components/ng2-alfresco-search/demo/systemjs.config.js @@ -26,6 +26,8 @@ 'ng2-translate': 'npm:ng2-translate', 'alfresco-js-api': 'npm:alfresco-js-api/dist', 'ng2-alfresco-core': 'npm:ng2-alfresco-core', + 'ng2-alfresco-documentlist': 'npm:ng2-alfresco-documentlist', + 'ng2-alfresco-datatable': 'npm:ng2-alfresco-datatable', 'ng2-alfresco-search': 'npm:ng2-alfresco-search' }, // packages tells the System loader how to load when no filename and/or no extension @@ -40,6 +42,8 @@ 'ng2-translate': { defaultExtension: 'js' }, 'alfresco-js-api': { main: './alfresco-js-api.js', defaultExtension: 'js'}, 'ng2-alfresco-core': { main: './index.js', defaultExtension: 'js'}, + 'ng2-alfresco-documentlist': { main: './index.js', defaultExtension: 'js'}, + 'ng2-alfresco-datatable': { main: './index.js', defaultExtension: 'js'}, 'ng2-alfresco-search': { main: './index.js', defaultExtension: 'js'} } }); diff --git a/ng2-components/ng2-alfresco-search/index.ts b/ng2-components/ng2-alfresco-search/index.ts index c2ce45856f..6ac815eb1d 100644 --- a/ng2-components/ng2-alfresco-search/index.ts +++ b/ng2-components/ng2-alfresco-search/index.ts @@ -18,12 +18,12 @@ import { NgModule, ModuleWithProviders } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { CoreModule } from 'ng2-alfresco-core'; - import { AlfrescoSearchService } from './src/services/alfresco-search.service'; import { AlfrescoThumbnailService } from './src/services/alfresco-thumbnail.service'; import { AlfrescoSearchComponent } from './src/components/alfresco-search.component'; import { AlfrescoSearchControlComponent } from './src/components/alfresco-search-control.component'; import { AlfrescoSearchAutocompleteComponent } from './src/components/alfresco-search-autocomplete.component'; +import { DocumentListModule } from 'ng2-alfresco-documentlist'; // services export * from './src/services/alfresco-search.service'; @@ -45,6 +45,7 @@ export const ALFRESCO_SEARCH_PROVIDERS: [any] = [ @NgModule({ imports: [ + DocumentListModule.forRoot(), CoreModule, FormsModule, ReactiveFormsModule diff --git a/ng2-components/ng2-alfresco-search/karma-test-shim.js b/ng2-components/ng2-alfresco-search/karma-test-shim.js index b922a90bce..b48288e490 100644 --- a/ng2-components/ng2-alfresco-search/karma-test-shim.js +++ b/ng2-components/ng2-alfresco-search/karma-test-shim.js @@ -1,7 +1,14 @@ // Tun on full stack traces in errors to help debugging Error.stackTraceLimit = Infinity; -// jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; +jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000; + +window.componentHandler = { + upgradeAllRegistered: function () { + }, + upgradeElement: function () { + } +}; __karma__.loaded = function() {}; @@ -56,7 +63,9 @@ var map = { 'ng2-translate': 'npm:ng2-translate', 'alfresco-js-api': 'npm:alfresco-js-api/dist', - 'ng2-alfresco-core': 'npm:ng2-alfresco-core' + 'ng2-alfresco-core': 'npm:ng2-alfresco-core', + 'ng2-alfresco-datatable': 'npm:ng2-alfresco-datatable', + 'ng2-alfresco-documentlist': 'npm:ng2-alfresco-documentlist' }; var packages = { @@ -65,7 +74,9 @@ var packages = { 'ng2-translate': { defaultExtension: 'js' }, 'alfresco-js-api': { main: './alfresco-js-api.js', defaultExtension: 'js'}, - 'ng2-alfresco-core': { main: './index.js', defaultExtension: 'js'} + 'ng2-alfresco-core': { main: './index.js', defaultExtension: 'js'}, + 'ng2-alfresco-datatable': { main: './index.js', defaultExtension: 'js'}, + 'ng2-alfresco-documentlist': { main: './index.js', defaultExtension: 'js'} }; var config = { diff --git a/ng2-components/ng2-alfresco-search/karma.conf.js b/ng2-components/ng2-alfresco-search/karma.conf.js index 02c4b6c5d0..68345649f6 100644 --- a/ng2-components/ng2-alfresco-search/karma.conf.js +++ b/ng2-components/ng2-alfresco-search/karma.conf.js @@ -50,6 +50,12 @@ module.exports = function (config) { { pattern: 'node_modules/ng2-alfresco-core/src/**/*.js', included: false, served: true, watched: false }, { pattern: 'node_modules/ng2-alfresco-core/index.js', included: false, served: true, watched: false }, + { pattern: 'node_modules/ng2-alfresco-datatable/src/**/*.js', included: false, served: true, watched: false }, + { pattern: 'node_modules/ng2-alfresco-datatable/index.js', included: false, served: true, watched: false }, + + { pattern: 'node_modules/ng2-alfresco-documentlist/src/**/*.js', included: false, served: true, watched: false }, + { pattern: 'node_modules/ng2-alfresco-documentlist/index.js', included: false, served: true, watched: false }, + // paths to support debugging with source maps in dev tools {pattern: 'src/**/*.ts', included: false, watched: false}, {pattern: 'src/**/*.js.map', included: false, watched: false} diff --git a/ng2-components/ng2-alfresco-search/package.json b/ng2-components/ng2-alfresco-search/package.json index 30bdac0c8b..af3f60daa0 100644 --- a/ng2-components/ng2-alfresco-search/package.json +++ b/ng2-components/ng2-alfresco-search/package.json @@ -17,7 +17,7 @@ "posttest": "remap-istanbul -i coverage/report/coverage-final.json -o coverage/report -t html && remap-istanbul -i coverage/report/coverage-final.json -o coverage/report/coverage-final.json", "coverage": "npm run test && wsrv -o -p 9875 ./coverage/report", "prepublish": "npm run test", - "travis": "npm link ng2-alfresco-core", + "travis": "npm link ng2-alfresco-core ng2-alfresco-datatable ng2-alfresco-documentlist", "gulp": "gulp", "build.umd": "gulp build.prod --color --env-config prod --build-type prod", "reinstall": "npm cache clean && npm install" @@ -70,7 +70,9 @@ "zone.js": "^0.6.23", "ng2-translate": "2.5.0", "alfresco-js-api": "^1.0.0", - "ng2-alfresco-core": "1.0.0" + "ng2-alfresco-core": "1.0.0", + "ng2-alfresco-datatable": "1.0.0", + "ng2-alfresco-documentlist": "1.0.0" }, "devDependencies": { "@types/jasmine": "^2.2.33", diff --git a/ng2-components/ng2-alfresco-search/src/assets/images/document-list.empty-folder.png b/ng2-components/ng2-alfresco-search/src/assets/images/document-list.empty-folder.png deleted file mode 100644 index 7a23727b20..0000000000 Binary files a/ng2-components/ng2-alfresco-search/src/assets/images/document-list.empty-folder.png and /dev/null differ diff --git a/ng2-components/ng2-alfresco-search/src/assets/images/empty_doc_lib.svg b/ng2-components/ng2-alfresco-search/src/assets/images/empty_doc_lib.svg new file mode 100644 index 0000000000..866acd527b --- /dev/null +++ b/ng2-components/ng2-alfresco-search/src/assets/images/empty_doc_lib.svg @@ -0,0 +1,208 @@ + + + + empty_doc_lib + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ng2-components/ng2-alfresco-search/src/components/alfresco-search-autocomplete.component.ts b/ng2-components/ng2-alfresco-search/src/components/alfresco-search-autocomplete.component.ts index f4b5e50e13..f3a066f4ba 100644 --- a/ng2-components/ng2-alfresco-search/src/components/alfresco-search-autocomplete.component.ts +++ b/ng2-components/ng2-alfresco-search/src/components/alfresco-search-autocomplete.component.ts @@ -68,7 +68,7 @@ export class AlfrescoSearchAutocompleteComponent implements OnInit, OnChanges { @ViewChild('resultsTableBody', {}) resultsTableBody: ElementRef; - baseComponentPath: string = module.id.replace('/components/alfresco-search.component.js', ''); + baseComponentPath: string = module.id.replace('/components/alfresco-search-autocomplete.component.js', ''); constructor(private searchService: AlfrescoSearchService, private translateService: AlfrescoTranslationService, @@ -128,13 +128,14 @@ export class AlfrescoSearchAutocompleteComponent implements OnInit, OnChanges { if (node.entry.content && node.entry.content.mimeType) { let icon = this.thumbnailService.getMimeTypeIcon(node.entry.content.mimeType); return this.resolveIconPath(icon); - } else if (node.entry.isFolder) { - return `${this.baseComponentPath}/../assets/images/ft_ic_folder.svg`; + } + if (node.entry.isFolder) { + return `${this.baseComponentPath}/assets/images/ft_ic_folder.svg`; } } resolveIconPath(icon: string): string { - return `${this.baseComponentPath}/../assets/images/${icon}`; + return `${this.baseComponentPath}/assets/images/${icon}`; } /** diff --git a/ng2-components/ng2-alfresco-search/src/components/alfresco-search.component.css b/ng2-components/ng2-alfresco-search/src/components/alfresco-search.component.css index 5f087e32c3..46d9a98066 100644 --- a/ng2-components/ng2-alfresco-search/src/components/alfresco-search.component.css +++ b/ng2-components/ng2-alfresco-search/src/components/alfresco-search.component.css @@ -13,3 +13,25 @@ overflow: hidden; text-overflow: ellipsis; } +.no-result-message { + height: 32px; + opacity: 0.26; + font-family: Muli, Helvetica, Arial, sans-serif; + font-size: 24px; + line-height: 1.33; + letter-spacing: -1px; + color: #000000; +} + +.no-result__empty_doc_lib { + width: 565px; + height: 161px; + object-fit: contain; + margin-top: 17px; +} + +.empty_template { + text-align: center; + margin-top: 20px; + margin-bottom: 20px; +} diff --git a/ng2-components/ng2-alfresco-search/src/components/alfresco-search.component.html b/ng2-components/ng2-alfresco-search/src/components/alfresco-search.component.html index 4b023fbfbe..a38feaaf40 100644 --- a/ng2-components/ng2-alfresco-search/src/components/alfresco-search.component.html +++ b/ng2-components/ng2-alfresco-search/src/components/alfresco-search.component.html @@ -1,38 +1,79 @@ - - - - - - - - - - - +
+

{{ 'SEARCH.RESULTS.ERROR' | translate:{errorMessage: errorMessage} }}

+
+ + + + + -
- - - - - + + + + + + + + + - -
{{ 'SEARCH.RESULTS.SUMMARY' | translate:{numResults: results.length, searchTerm: searchTerm} }}
- {{'SEARCH.RESULTS.COLUMNS.NAME' | translate}} - - {{'SEARCH.RESULTS.COLUMNS.MODIFIED_BY' | translate}} - - {{'SEARCH.RESULTS.COLUMNS.MODIFIED_AT' | translate}} -
{{getMimeTypeKey(result)|translate}}{{result.entry.name}}{{result.entry.modifiedByUser.displayName}}{{result.entry.modifiedAt | date}}
- - - - - - -
{{ 'SEARCH.RESULTS.NONE' | translate:{searchTerm: searchTerm} }}
-

{{ 'SEARCH.RESULTS.ERROR' | translate:{errorMessage: errorMessage} }}

+ + + + + + + + + + + + + +
+ diff --git a/ng2-components/ng2-alfresco-search/src/components/alfresco-search.component.spec.ts b/ng2-components/ng2-alfresco-search/src/components/alfresco-search.component.spec.ts index 61186eda3d..b14a95d503 100644 --- a/ng2-components/ng2-alfresco-search/src/components/alfresco-search.component.spec.ts +++ b/ng2-components/ng2-alfresco-search/src/components/alfresco-search.component.spec.ts @@ -16,12 +16,10 @@ */ import { DebugElement, ReflectiveInjector, SimpleChange } from '@angular/core'; -import { By } from '@angular/platform-browser'; import { ComponentFixture, TestBed, async } from '@angular/core/testing'; import { ActivatedRoute } from '@angular/router'; import { Observable } from 'rxjs/Rx'; import { AlfrescoSearchComponent } from './alfresco-search.component'; -import { AlfrescoThumbnailService } from './../services/alfresco-thumbnail.service'; import { TranslationMock } from './../assets/translation.service.mock'; import { AlfrescoSearchService } from '../services/alfresco-search.service'; import { @@ -33,6 +31,7 @@ import { StorageService, LogService } from 'ng2-alfresco-core'; +import { DocumentListModule } from 'ng2-alfresco-documentlist'; describe('AlfrescoSearchComponent', () => { @@ -69,8 +68,8 @@ describe('AlfrescoSearchComponent', () => { entry: { id: '123', name: 'MyFolder', - isFile : false, - isFolder : true, + isFile: false, + isFolder: true, createdByUser: { displayName: 'John Doe' }, @@ -102,13 +101,13 @@ describe('AlfrescoSearchComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ - CoreModule.forRoot() + CoreModule.forRoot(), + DocumentListModule.forRoot() ], - declarations: [ AlfrescoSearchComponent ], // declare the test component + declarations: [AlfrescoSearchComponent], // declare the test component providers: [ AlfrescoSearchService, - {provide: AlfrescoTranslationService, useClass: TranslationMock}, - AlfrescoThumbnailService + {provide: AlfrescoTranslationService, useClass: TranslationMock} ] }).compileComponents().then(() => { fixture = TestBed.createComponent(AlfrescoSearchComponent); @@ -123,9 +122,9 @@ describe('AlfrescoSearchComponent', () => { it('should take the provided search term from query param provided via RouteParams', () => { let injector = ReflectiveInjector.resolveAndCreate([ - { provide: ActivatedRoute, useValue: { params: Observable.from([{ q: 'exampleTerm692' }]) } } + {provide: ActivatedRoute, useValue: {params: Observable.from([{q: 'exampleTerm692'}])}} ]); - let search = new AlfrescoSearchComponent(null, null, null, injector.get(ActivatedRoute)); + let search = new AlfrescoSearchComponent(null, null, injector.get(ActivatedRoute)); search.ngOnInit(); expect(search.searchTerm).toBe('exampleTerm692'); }); @@ -138,9 +137,9 @@ describe('AlfrescoSearchComponent', () => { AlfrescoApiService, StorageService, LogService, - { provide: ActivatedRoute, useValue: { params: Observable.from([{}]) } } + {provide: ActivatedRoute, useValue: {params: Observable.from([{}])}} ]); - let search = new AlfrescoSearchComponent(injector.get(AlfrescoSearchService), null, null, injector.get(ActivatedRoute)); + let search = new AlfrescoSearchComponent(injector.get(AlfrescoSearchService), null, injector.get(ActivatedRoute)); search.ngOnInit(); expect(search.searchTerm).toBeNull(); }); @@ -157,6 +156,7 @@ describe('AlfrescoSearchComponent', () => { it('should call search service with the correct parameters', (done) => { let searchTerm = 'searchTerm63688', options = { include: ['path'], + skipCount: 0, rootNodeId: '-my-', nodeType: 'my:type', maxItems: 20, @@ -186,9 +186,9 @@ describe('AlfrescoSearchComponent', () => { component.resultsLoad.subscribe(() => { fixture.detectChanges(); expect(searchService.getQueryNodesPromise).toHaveBeenCalled(); - expect(element.querySelector('#result_user_0')).not.toBeNull(); - expect(element.querySelector('#result_user_0').innerHTML).toBe('John Doe'); - expect(element.querySelector('#result_name_0').innerHTML).toBe('MyDoc'); + let resultsEl = element.querySelector('[data-automation-id="text_MyDoc"]'); + expect(resultsEl).not.toBeNull(); + expect(resultsEl.innerHTML.trim()).toBe('MyDoc'); done(); }); @@ -204,7 +204,7 @@ describe('AlfrescoSearchComponent', () => { component.resultsLoad.subscribe(() => { fixture.detectChanges(); - expect(element.querySelector('#search_no_result')).not.toBeNull(); + expect(element.querySelector('.no-result-message')).not.toBeNull(); done(); }); @@ -218,11 +218,10 @@ describe('AlfrescoSearchComponent', () => { spyOn(searchService, 'getQueryNodesPromise') .and.returnValue(Promise.reject(errorJson)); - component.resultsLoad.subscribe(() => {}, () => { + component.resultsLoad.subscribe(() => { + }, () => { fixture.detectChanges(); - let resultsEl = element.querySelector('[data-automation-id="search_result_table"]'); let errorEl = element.querySelector('[data-automation-id="search_error_message"]'); - expect(resultsEl).toBeNull(); expect(errorEl).not.toBeNull(); expect((errorEl).innerText).toBe('SEARCH.RESULTS.ERROR'); done(); @@ -240,10 +239,10 @@ describe('AlfrescoSearchComponent', () => { component.resultsLoad.subscribe(() => { fixture.detectChanges(); - expect(searchService.getQueryNodesPromise.calls.mostRecent().args[0]).toBe('searchTerm2'); - expect(element.querySelector('#result_user_0')).not.toBeNull(); - expect(element.querySelector('#result_user_0').innerHTML).toBe('John Doe'); - expect(element.querySelector('#result_name_0').innerHTML).toBe('MyDoc'); + expect(searchService.getQueryNodesPromise).toHaveBeenCalled(); + let resultsEl = element.querySelector('[data-automation-id="text_MyDoc"]'); + expect(resultsEl).not.toBeNull(); + expect(resultsEl.innerHTML.trim()).toBe('MyDoc'); done(); }); @@ -257,13 +256,12 @@ describe('AlfrescoSearchComponent', () => { let searchService: AlfrescoSearchService; let querySpy: jasmine.Spy; let emitSpy: jasmine.Spy; - const rowSelector = '[data-automation-id="search_result_table"] tbody tr'; beforeEach(() => { debugElement = fixture.debugElement; searchService = fixture.debugElement.injector.get(AlfrescoSearchService); querySpy = spyOn(searchService, 'getQueryNodesPromise').and.returnValue(Promise.resolve(result)); - emitSpy = spyOn(component.navigate, 'emit'); + emitSpy = spyOn(component.preview, 'emit'); }); describe('click results', () => { @@ -272,12 +270,14 @@ describe('AlfrescoSearchComponent', () => { component.navigationMode = AlfrescoSearchComponent.SINGLE_CLICK_NAVIGATION; }); - it('should emit navigation event when file item clicked', (done) => { + it('should emit preview event when file item clicked', (done) => { component.resultsLoad.subscribe(() => { fixture.detectChanges(); - debugElement.query(By.css(rowSelector)).triggerEventHandler('click', {}); - expect(emitSpy).toHaveBeenCalled(); + + let resultsEl = element.querySelector('[data-automation-id="text_MyDoc"]'); + resultsEl.dispatchEvent(new Event('click')); + done(); }); @@ -285,14 +285,16 @@ describe('AlfrescoSearchComponent', () => { component.ngOnInit(); }); - it('should emit navigation event when non-file item is clicked', (done) => { + it('should emit preview event when non-file item is clicked', (done) => { querySpy.and.returnValue(Promise.resolve(folderResult)); component.resultsLoad.subscribe(() => { fixture.detectChanges(); - debugElement.query(By.css(rowSelector)).triggerEventHandler('click', {}); - expect(emitSpy).toHaveBeenCalled(); + + let resultsEl = element.querySelector('[data-automation-id="text_MyFolder"]'); + resultsEl.dispatchEvent(new Event('click')); + done(); }); @@ -307,12 +309,14 @@ describe('AlfrescoSearchComponent', () => { component.navigationMode = AlfrescoSearchComponent.DOUBLE_CLICK_NAVIGATION; }); - it('should emit navigation event when file item clicked', (done) => { + it('should emit preview event when file item clicked', (done) => { component.resultsLoad.subscribe(() => { fixture.detectChanges(); - debugElement.query(By.css(rowSelector)).triggerEventHandler('dblclick', {}); - expect(emitSpy).toHaveBeenCalled(); + + let resultsEl = element.querySelector('[data-automation-id="text_MyDoc"]'); + resultsEl.dispatchEvent(new Event('dblclick')); + done(); }); @@ -320,14 +324,16 @@ describe('AlfrescoSearchComponent', () => { component.ngOnInit(); }); - it('should emit navigation event when non-file item is clicked', (done) => { + it('should emit preview event when non-file item is clicked', (done) => { querySpy.and.returnValue(Promise.resolve(folderResult)); component.resultsLoad.subscribe(() => { fixture.detectChanges(); - debugElement.query(By.css(rowSelector)).triggerEventHandler('dblclick', {}); - expect(emitSpy).toHaveBeenCalled(); + + let resultsEl = element.querySelector('[data-automation-id="text_MyFolder"]'); + resultsEl.dispatchEvent(new Event('dblclick')); + done(); }); diff --git a/ng2-components/ng2-alfresco-search/src/components/alfresco-search.component.ts b/ng2-components/ng2-alfresco-search/src/components/alfresco-search.component.ts index 711f057d03..0a6cbc00b9 100644 --- a/ng2-components/ng2-alfresco-search/src/components/alfresco-search.component.ts +++ b/ng2-components/ng2-alfresco-search/src/components/alfresco-search.component.ts @@ -18,9 +18,8 @@ import { Component, EventEmitter, Input, Output, Optional, OnChanges, SimpleChanges, OnInit } from '@angular/core'; import { ActivatedRoute, Params } from '@angular/router'; import { AlfrescoSearchService, SearchOptions } from './../services/alfresco-search.service'; -import { AlfrescoThumbnailService } from './../services/alfresco-thumbnail.service'; import { AlfrescoTranslationService } from 'ng2-alfresco-core'; -import { MinimalNodeEntity } from 'alfresco-js-api'; +import { NodePaging, Pagination } from 'alfresco-js-api'; @Component({ moduleId: module.id, @@ -51,23 +50,28 @@ export class AlfrescoSearchComponent implements OnChanges, OnInit { @Input() navigationMode: string = AlfrescoSearchComponent.DOUBLE_CLICK_NAVIGATION; // click|dblclick - @Output() - navigate: EventEmitter = new EventEmitter(); - @Output() resultsLoad = new EventEmitter(); + @Output() + preview: EventEmitter = new EventEmitter(); + results: any = null; + pagination: Pagination; + errorMessage; queryParamName = 'q'; + skipCount: number = 0; + + nodeResults: NodePaging; + baseComponentPath: string = module.id.replace('/components/alfresco-search.component.js', ''); constructor(private searchService: AlfrescoSearchService, private translateService: AlfrescoTranslationService, - private thumbnailService: AlfrescoThumbnailService, @Optional() private route: ActivatedRoute) { } @@ -75,6 +79,7 @@ export class AlfrescoSearchComponent implements OnChanges, OnInit { if (this.translateService !== null) { this.translateService.addTranslationFolder('ng2-alfresco-search', 'node_modules/ng2-alfresco-search/src'); } + if (this.route) { this.route.params.forEach((params: Params) => { this.searchTerm = params.hasOwnProperty(this.queryParamName) ? params[this.queryParamName] : null; @@ -88,38 +93,16 @@ export class AlfrescoSearchComponent implements OnChanges, OnInit { ngOnChanges(changes: SimpleChanges) { if (changes['searchTerm']) { this.searchTerm = changes['searchTerm'].currentValue; + this.skipCount = 0; this.displaySearchResults(this.searchTerm); } } - /** - * Gets thumbnail URL for the given document node. - * @param node Node to get URL for. - * @returns {string} URL address. - */ - getMimeTypeIcon(node: any): string { - if (node.entry.content && node.entry.content.mimeType) { - let icon = this.thumbnailService.getMimeTypeIcon(node.entry.content.mimeType); - return this.resolveIconPath(icon); - } else if (node.entry.isFolder) { - return `${this.baseComponentPath}/../assets/images/ft_ic_folder.svg`; - } - } - - private resolveIconPath(icon: string): string { - return `${this.baseComponentPath}/../assets/images/${icon}`; - } - - /** - * Gets thumbnail message key for the given document node, which can be used to look up alt text - * @param node Node to get URL for. - * @returns {string} URL address. - */ - getMimeTypeKey(node: any): string { - if (node.entry.content && node.entry.content.mimeType) { - return 'SEARCH.ICONS.' + this.thumbnailService.getMimeTypeKey(node.entry.content.mimeType); - } else { - return ''; + onPreviewFile(event: any) { + if (event.value) { + this.preview.emit({ + value: event.value + }); } } @@ -131,6 +114,7 @@ export class AlfrescoSearchComponent implements OnChanges, OnInit { if (searchTerm && this.searchService) { let searchOpts: SearchOptions = { include: ['path'], + skipCount: this.skipCount, rootNodeId: this.rootNodeId, nodeType: this.resultType, maxItems: this.maxResults, @@ -140,33 +124,35 @@ export class AlfrescoSearchComponent implements OnChanges, OnInit { .getNodeQueryResults(searchTerm, searchOpts) .subscribe( results => { + this.nodeResults = results; this.results = results.list.entries; + this.pagination = results.list.pagination; this.resultsLoad.emit(this.results); this.errorMessage = null; }, error => { - this.results = null; - this.errorMessage = error; - this.resultsLoad.error(error); + if (error.status !== 400) { + this.results = null; + this.errorMessage = error; + this.resultsLoad.error(error); + } } ); } } - onItemClick(node, event?: Event) { - if (this.navigate && this.navigationMode === AlfrescoSearchComponent.SINGLE_CLICK_NAVIGATION) { - if (node && node.entry) { - this.navigate.emit(node); - } - } + public onChangePageSize(event: Pagination): void { + this.maxResults = event.maxItems; + this.displaySearchResults(this.searchTerm); } - onItemDblClick(node: MinimalNodeEntity) { - if (this.navigate && this.navigationMode === AlfrescoSearchComponent.DOUBLE_CLICK_NAVIGATION) { - if (node && node.entry) { - this.navigate.emit(node); - } - } + public onNextPage(event: Pagination): void { + this.skipCount = event.skipCount; + this.displaySearchResults(this.searchTerm); } + public onPrevPage(event: Pagination): void { + this.skipCount = event.skipCount; + this.displaySearchResults(this.searchTerm); + } } diff --git a/ng2-components/ng2-alfresco-search/src/i18n/en.json b/ng2-components/ng2-alfresco-search/src/i18n/en.json index 8f8042c28b..bfee68b4c5 100644 --- a/ng2-components/ng2-alfresco-search/src/i18n/en.json +++ b/ng2-components/ng2-alfresco-search/src/i18n/en.json @@ -5,7 +5,7 @@ }, "RESULTS": { "SUMMARY": "Found {{numResults}} results for {{searchTerm}}", - "NONE": "No results found for {{searchTerm}}", + "NONE": "No results found searching for {{searchTerm}}", "ERROR": "An error occurred while running the search", "COLUMNS": { "NAME": "Display name", @@ -25,6 +25,22 @@ "ft_ic_archive": "Acrchive file", "ft_ic_presentation": "Presentation file", "ft_ic_spreadsheet": "Spreadsheet file" + }, + "DOCUMENT_LIST": { + "COLUMNS": { + "DISPLAY_NAME": "Display name", + "CREATED_BY": "Created by", + "CREATED_ON": "Created on" + }, + "ACTIONS": { + "FOLDER": { + "DELETE": "Delete" + }, + "DOCUMENT": { + "DOWNLOAD": "Download", + "DELETE": "Delete" + } + } } } } diff --git a/ng2-components/ng2-alfresco-search/src/services/alfresco-search.service.ts b/ng2-components/ng2-alfresco-search/src/services/alfresco-search.service.ts index 7de189c7da..f9fc563d48 100644 --- a/ng2-components/ng2-alfresco-search/src/services/alfresco-search.service.ts +++ b/ng2-components/ng2-alfresco-search/src/services/alfresco-search.service.ts @@ -18,6 +18,7 @@ import { Injectable } from '@angular/core'; import { Observable } from 'rxjs/Rx'; import { AlfrescoAuthenticationService, AlfrescoApiService } from 'ng2-alfresco-core'; +import { NodePaging } from 'alfresco-js-api'; /** * Internal service used by Document List component. @@ -36,13 +37,13 @@ export class AlfrescoSearchService { * @param options Additional options passed to the search * @returns {Observable} Search results */ - public getNodeQueryResults(term: string, options?: SearchOptions): Observable { + public getNodeQueryResults(term: string, options?: SearchOptions): Observable { return Observable.fromPromise(this.getQueryNodesPromise(term, options)) - .map(res => res) + .map(res => res) .catch(err => this.handleError(err)); } - private getQueryNodesPromise(term: string, opts: SearchOptions) { + private getQueryNodesPromise(term: string, opts: SearchOptions): Promise { return this.apiService.getInstance().core.queriesApi.findNodes(term, opts); } diff --git a/ng2-components/ng2-alfresco-tag/karma-test-shim.js b/ng2-components/ng2-alfresco-tag/karma-test-shim.js index b922a90bce..6aa9dd62c7 100644 --- a/ng2-components/ng2-alfresco-tag/karma-test-shim.js +++ b/ng2-components/ng2-alfresco-tag/karma-test-shim.js @@ -1,7 +1,14 @@ // Tun on full stack traces in errors to help debugging Error.stackTraceLimit = Infinity; -// jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; +jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000; + +window.componentHandler = { + upgradeAllRegistered: function () { + }, + upgradeElement: function () { + } +}; __karma__.loaded = function() {}; diff --git a/ng2-components/ng2-alfresco-upload/karma-test-shim.js b/ng2-components/ng2-alfresco-upload/karma-test-shim.js index b922a90bce..6aa9dd62c7 100644 --- a/ng2-components/ng2-alfresco-upload/karma-test-shim.js +++ b/ng2-components/ng2-alfresco-upload/karma-test-shim.js @@ -1,7 +1,14 @@ // Tun on full stack traces in errors to help debugging Error.stackTraceLimit = Infinity; -// jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; +jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000; + +window.componentHandler = { + upgradeAllRegistered: function () { + }, + upgradeElement: function () { + } +}; __karma__.loaded = function() {}; diff --git a/ng2-components/ng2-alfresco-userinfo/karma-test-shim.js b/ng2-components/ng2-alfresco-userinfo/karma-test-shim.js index b922a90bce..6aa9dd62c7 100644 --- a/ng2-components/ng2-alfresco-userinfo/karma-test-shim.js +++ b/ng2-components/ng2-alfresco-userinfo/karma-test-shim.js @@ -1,7 +1,14 @@ // Tun on full stack traces in errors to help debugging Error.stackTraceLimit = Infinity; -// jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; +jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000; + +window.componentHandler = { + upgradeAllRegistered: function () { + }, + upgradeElement: function () { + } +}; __karma__.loaded = function() {}; diff --git a/ng2-components/ng2-alfresco-viewer/karma-test-shim.js b/ng2-components/ng2-alfresco-viewer/karma-test-shim.js index b922a90bce..6aa9dd62c7 100644 --- a/ng2-components/ng2-alfresco-viewer/karma-test-shim.js +++ b/ng2-components/ng2-alfresco-viewer/karma-test-shim.js @@ -1,7 +1,14 @@ // Tun on full stack traces in errors to help debugging Error.stackTraceLimit = Infinity; -// jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; +jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000; + +window.componentHandler = { + upgradeAllRegistered: function () { + }, + upgradeElement: function () { + } +}; __karma__.loaded = function() {}; diff --git a/ng2-components/ng2-alfresco-webscript/karma-test-shim.js b/ng2-components/ng2-alfresco-webscript/karma-test-shim.js index dcfa63a5ae..53e4408aa1 100644 --- a/ng2-components/ng2-alfresco-webscript/karma-test-shim.js +++ b/ng2-components/ng2-alfresco-webscript/karma-test-shim.js @@ -1,7 +1,14 @@ // Tun on full stack traces in errors to help debugging Error.stackTraceLimit = Infinity; -// jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; +jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000; + +window.componentHandler = { + upgradeAllRegistered: function () { + }, + upgradeElement: function () { + } +}; __karma__.loaded = function() {}; diff --git a/scripts/npm-build-bundle-all.sh b/scripts/npm-build-bundle-all.sh index 5433de9890..bb67f0931a 100755 --- a/scripts/npm-build-bundle-all.sh +++ b/scripts/npm-build-bundle-all.sh @@ -72,10 +72,18 @@ npm link ng2-activiti-diagrams npm link npm run build +#LINK SEARCH +echo "====== linking component: ng2-alfresco-search =====" +cd "$DIR/../ng2-components/ng2-alfresco-search" +npm link ng2-alfresco-core +npm link ng2-alfresco-datatable +npm link ng2-alfresco-documentlist +npm link +npm run build + #LINK ALL THE OTHERS COMPONENTS for PACKAGE in \ ng2-alfresco-login \ - ng2-alfresco-search \ ng2-alfresco-userinfo \ ng2-alfresco-upload \ ng2-alfresco-tag \ diff --git a/scripts/npm-link-all-components-demo.sh b/scripts/npm-link-all-components-demo.sh index 7d2ee6a75e..bd09e0c988 100755 --- a/scripts/npm-link-all-components-demo.sh +++ b/scripts/npm-link-all-components-demo.sh @@ -71,10 +71,19 @@ npm link ng2-alfresco-core npm link ng2-activiti-diagrams npm install +#LINK SEARCH +echo "====== linking component: ng2-alfresco-search =====" +cd "$DIR/../ng2-components/ng2-alfresco-search/demo" +npm link ng2-alfresco-core +npm link ng2-alfresco-datatable +npm link ng2-alfresco-documentlist +npm link ng2-alfresco-search +npm link +npm run build + #LINK ALL THE OTHERS COMPONENTS for PACKAGE in \ ng2-alfresco-login \ - ng2-alfresco-search \ ng2-alfresco-userinfo \ ng2-alfresco-upload \ ng2-alfresco-tag \ diff --git a/scripts/npm-link-demo-shell.sh b/scripts/npm-link-demo-shell.sh index 5433de9890..bb67f0931a 100755 --- a/scripts/npm-link-demo-shell.sh +++ b/scripts/npm-link-demo-shell.sh @@ -72,10 +72,18 @@ npm link ng2-activiti-diagrams npm link npm run build +#LINK SEARCH +echo "====== linking component: ng2-alfresco-search =====" +cd "$DIR/../ng2-components/ng2-alfresco-search" +npm link ng2-alfresco-core +npm link ng2-alfresco-datatable +npm link ng2-alfresco-documentlist +npm link +npm run build + #LINK ALL THE OTHERS COMPONENTS for PACKAGE in \ ng2-alfresco-login \ - ng2-alfresco-search \ ng2-alfresco-userinfo \ ng2-alfresco-upload \ ng2-alfresco-tag \