[ADF-2500] fix trashcan bug plus refactoring documentlist (#3136)

* [ADF-2500] The full content of Trashcan is not displayed.

fix pagination problem and add tests

* refactor code

* custom resources services

* move custom resources in separate service part 2

* move custom resources in separate service part 3

* move isCustomResources in custom resources

* move getCorrispondinNodeIds in custom services

* reorganize code

* add pagination interface

* remove permissions check document list and use the common cs method
remove the merge option and move it in the paginator

* make infinte scrolling always use the target

* restore loading infinite page

* fix license header

* fix type problems

* breadcrumb test service

* fix test

* export CustomResourcesService

* fix test pagination

* fix content ndoe test

* remove timeout content node selector test

* fix after rebase

* ripristinate observalbe in search service

* fix wrong type return stub document list test

* fix search service

* fix test document list

* move handle error in common method

* restore observable in search control

* Update search-control.component.spec.ts

* fix after rebase

* add import switchmap

* core import in karma conf

* missing commas

* fix mocks

* fix mock searchquerybody

* search test fix
This commit is contained in:
Eugenio Romano
2018-04-09 10:31:43 +01:00
committed by Denys Vuika
parent 79789cb070
commit 07c247ca11
57 changed files with 1103 additions and 1088 deletions

View File

@@ -19,6 +19,7 @@ import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { async, TestBed } from '@angular/core/testing';
import { DataTableModule } from '@alfresco/adf-core';
import { DocumentListService } from '../../services/document-list.service';
import { CustomResourcesService } from '../../services/custom-resources.service';
import { ContentActionModel } from './../../models/content-action.model';
import { DocumentListComponent } from './../document-list.component';
import { ContentActionListComponent } from './content-action-list.component';
@@ -37,7 +38,8 @@ describe('ContentColumnList', () => {
DocumentListComponent
],
providers: [
DocumentListService
DocumentListService,
CustomResourcesService
],
schemas: [
CUSTOM_ELEMENTS_SCHEMA

View File

@@ -22,6 +22,7 @@ import { ContentService } from '@alfresco/adf-core';
import { DataTableModule } from '@alfresco/adf-core';
import { FileNode } from '../../../mock';
import { DocumentListService } from '../../services/document-list.service';
import { CustomResourcesService } from '../../services/custom-resources.service';
import { ContentActionHandler } from './../../models/content-action.model';
import { DocumentActionsService } from './../../services/document-actions.service';
import { FolderActionsService } from './../../services/folder-actions.service';
@@ -47,7 +48,8 @@ describe('ContentAction', () => {
DataTableModule
],
providers: [
DocumentListService
DocumentListService,
CustomResourcesService
],
declarations: [
DocumentListComponent

View File

@@ -21,6 +21,7 @@ import { DataColumn, DataTableModule } from '@alfresco/adf-core';
import { LogService } from '@alfresco/adf-core';
import { DocumentListService } from '../../services/document-list.service';
import { CustomResourcesService } from '../../services/custom-resources.service';
import { DocumentListComponent } from './../document-list.component';
import { ContentColumnListComponent } from './content-column-list.component';
@@ -39,8 +40,8 @@ describe('ContentColumnList', () => {
DocumentListComponent
],
providers: [
DocumentListService,
LogService
CustomResourcesService,
DocumentListService
],
schemas: [
CUSTOM_ELEMENTS_SCHEMA

View File

@@ -20,6 +20,7 @@ import { async, TestBed } from '@angular/core/testing';
import { LogService } from '@alfresco/adf-core';
import { DataTableModule } from '@alfresco/adf-core';
import { DocumentListService } from '../../services/document-list.service';
import { CustomResourcesService } from '../../services/custom-resources.service';
import { DocumentListComponent } from './../document-list.component';
import { ContentColumnListComponent } from './content-column-list.component';
import { ContentColumnComponent } from './content-column.component';
@@ -39,6 +40,7 @@ describe('ContentColumn', () => {
DocumentListComponent
],
providers: [
CustomResourcesService,
DocumentListService,
LogService
],

View File

@@ -24,7 +24,6 @@ import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import { FileNode, FolderNode } from '../../mock';
import {
fakeNodeAnswerWithEntries,
fakeNodeAnswerWithNOEntries,
fakeNodeWithCreatePermission,
fakeNodeWithNoPermission,
@@ -37,6 +36,7 @@ import { ImageResolver } from './../data/image-resolver.model';
import { RowFilter } from './../data/row-filter.model';
import { DocumentListService } from './../services/document-list.service';
import { CustomResourcesService } from './../services/custom-resources.service';
import { DocumentListComponent } from './document-list.component';
declare let jasmine: any;
@@ -46,6 +46,7 @@ describe('DocumentList', () => {
let documentList: DocumentListComponent;
let documentListService: DocumentListService;
let apiService: AlfrescoApiService;
let customResourcesService: CustomResourcesService;
let fixture: ComponentFixture<DocumentListComponent>;
let element: HTMLElement;
let eventMock: any;
@@ -62,6 +63,7 @@ describe('DocumentList', () => {
],
providers: [
DocumentListService,
CustomResourcesService,
{ provide: NgZone, useValue: zone }
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
@@ -85,6 +87,7 @@ describe('DocumentList', () => {
documentList = fixture.componentInstance;
documentListService = TestBed.get(DocumentListService);
apiService = TestBed.get(AlfrescoApiService);
customResourcesService = TestBed.get(CustomResourcesService);
fixture.detectChanges();
});
@@ -255,17 +258,10 @@ describe('DocumentList', () => {
expect(documentList.resetSelection).toHaveBeenCalled();
});
it('should reset selection on loading folder by node id', () => {
spyOn(documentList, 'resetSelection').and.callThrough();
documentList.loadFolderByNodeId('-trashcan-');
expect(documentList.resetSelection).toHaveBeenCalled();
});
it('should reset selection in the datatable also', () => {
it('should reset when a prameter changes', () => {
spyOn(documentList.dataTable, 'resetSelection').and.callThrough();
documentList.loadFolderByNodeId('-trashcan-');
documentList.ngOnChanges({});
expect(documentList.dataTable.resetSelection).toHaveBeenCalled();
});
@@ -390,7 +386,7 @@ describe('DocumentList', () => {
});
it('should not disable the action if there is no permission for the file and disableWithNoPermission false', () => {
it('should disable the action if there is no permission for the file and disableWithNoPermission false', () => {
let documentMenu = new ContentActionModel({
disableWithNoPermission: false,
permission: 'delete',
@@ -407,10 +403,10 @@ describe('DocumentList', () => {
let actions = documentList.getNodeActions(nodeFile);
expect(actions.length).toBe(1);
expect(actions[0].title).toEqual('FileAction');
expect(actions[0].disabled).toBeUndefined(true);
expect(actions[0].disabled).toBe(true);
});
it('should not disable the action if there is no permission for the folder and disableWithNoPermission false', () => {
it('should disable the action if there is no permission for the folder and disableWithNoPermission false', () => {
let documentMenu = new ContentActionModel({
disableWithNoPermission: false,
permission: 'delete',
@@ -427,7 +423,7 @@ describe('DocumentList', () => {
let actions = documentList.getNodeActions(nodeFile);
expect(actions.length).toBe(1);
expect(actions[0].title).toEqual('FolderAction');
expect(actions[0].disabled).toBeUndefined(true);
expect(actions[0].disabled).toBe(true);
});
it('should not disable the action if there is the right permission for the file', () => {
@@ -724,14 +720,6 @@ describe('DocumentList', () => {
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();
@@ -927,7 +915,7 @@ describe('DocumentList', () => {
it('should emit error when getFolderNode fails', (done) => {
const error = { message: '{ "error": { "statusCode": 501 } }' };
spyOn(documentListService, 'getFolderNode').and.returnValue(Promise.reject(error));
spyOn(documentListService, 'getFolderNode').and.returnValue(Observable.throw(error));
documentList.error.subscribe(val => {
expect(val).toBe(error);
@@ -939,7 +927,7 @@ describe('DocumentList', () => {
it('should emit error when loadFolderNodesByFolderNodeId fails', (done) => {
const error = { message: '{ "error": { "statusCode": 501 } }' };
spyOn(documentListService, 'getFolderNode').and.returnValue(Promise.resolve(fakeNodeWithCreatePermission));
spyOn(documentListService, 'getFolderNode').and.returnValue(Observable.of(fakeNodeWithCreatePermission));
spyOn(documentList, 'loadFolderNodesByFolderNodeId').and.returnValue(Promise.reject(error));
documentList.error.subscribe(val => {
@@ -952,7 +940,7 @@ describe('DocumentList', () => {
it('should set no permision when getFolderNode fails with 403', (done) => {
const error = { message: '{ "error": { "statusCode": 403 } }' };
spyOn(documentListService, 'getFolderNode').and.returnValue(Promise.reject(error));
spyOn(documentListService, 'getFolderNode').and.returnValue(Observable.throw(error));
documentList.error.subscribe(val => {
expect(val).toBe(error);
@@ -963,16 +951,6 @@ describe('DocumentList', () => {
documentList.loadFolderByNodeId('123');
});
it('should reset noPermission on loading folder by node id', () => {
documentList.noPermission = true;
fixture.detectChanges();
documentList.loadFolderByNodeId('-trashcan-');
fixture.detectChanges();
expect(documentList.noPermission).toBeFalsy();
});
it('should reset noPermission upon reload', () => {
documentList.noPermission = true;
fixture.detectChanges();
@@ -995,60 +973,15 @@ describe('DocumentList', () => {
expect(documentList.noPermission).toBeFalsy();
});
xit('should load previous page if there are no other elements in multi page table', (done) => {
it('should noPermission be true if navigate to a folder with no permission', (done) => {
const error = { message: '{ "error": { "statusCode": 403 } }' };
documentList.currentFolderId = '1d26e465-dea3-42f3-b415-faa8364b9692';
documentList.folderNode = new NodeMinimal();
documentList.folderNode.id = '1d26e465-dea3-42f3-b415-faa8364b9692';
documentList.reload();
fixture.detectChanges();
documentList.ready.subscribe(() => {
fixture.detectChanges();
let rowElement = element.querySelector('[data-automation-id="b_txt_file.rtf"]');
expect(rowElement).toBeDefined();
expect(rowElement).not.toBeNull();
done();
});
jasmine.Ajax.requests.at(0).respondWith({
status: 200,
contentType: 'application/json',
responseText: JSON.stringify(fakeNodeAnswerWithNOEntries)
});
jasmine.Ajax.requests.at(1).respondWith({
status: 200,
contentType: 'application/json',
responseText: JSON.stringify(fakeNodeAnswerWithEntries)
});
});
it('should return true if current folder node has create permission', (done) => {
documentList.currentFolderId = '1d26e465-dea3-42f3-b415-faa8364b9692';
documentList.folderNode = new NodeMinimal();
documentList.folderNode.id = '1d26e465-dea3-42f3-b415-faa8364b9692';
spyOn(documentListService, 'getFolderNode').and.returnValue(Promise.resolve(fakeNodeWithCreatePermission));
spyOn(documentListService, 'getFolder').and.returnValue(Promise.resolve(fakeNodeAnswerWithNOEntries));
let change = new SimpleChange(null, '1d26e465-dea3-42f3-b415-faa8364b9692', true);
documentList.ngOnChanges({ 'currentFolderId': change });
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
expect(documentList.hasCreatePermission()).toBeTruthy();
done();
});
});
it('should return false if navigate to a folder with no create permission', (done) => {
documentList.currentFolderId = '1d26e465-dea3-42f3-b415-faa8364b9692';
documentList.folderNode = new NodeMinimal();
documentList.folderNode.id = '1d26e465-dea3-42f3-b415-faa8364b9692';
spyOn(documentListService, 'getFolderNode').and.returnValue(Promise.resolve(fakeNodeWithNoPermission));
spyOn(documentListService, 'getFolder').and.returnValue(Promise.resolve(fakeNodeAnswerWithNOEntries));
spyOn(documentListService, 'getFolderNode').and.returnValue(Observable.of(fakeNodeWithNoPermission));
spyOn(documentListService, 'getFolder').and.returnValue(Observable.throw(error));
documentList.loadFolder();
let clickedFolderNode = new FolderNode('fake-folder-node');
@@ -1056,7 +989,7 @@ describe('DocumentList', () => {
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(documentList.hasCreatePermission()).toBeFalsy();
expect(documentList.noPermission).toBeTruthy();
done();
});
});
@@ -1249,10 +1182,8 @@ describe('DocumentList', () => {
documentList.loadFolderByNodeId('-recent-');
});
xit('should emit error when fetch recent fails on search call', (done) => {
const person = { entry: { id: 'person ' } };
spyOn(apiService.peopleApi, 'getPerson').and.returnValue(Promise.resolve(person));
spyOn(apiService.searchApi, 'search').and.returnValue(Promise.reject('error'));
it('should emit error when fetch recent fails on search call', (done) => {
spyOn(customResourcesService, 'loadFolderByNodeId').and.returnValue(Observable.throw('error'));
documentList.error.subscribe(val => {
expect(val).toBe('error');
@@ -1291,21 +1222,6 @@ describe('DocumentList', () => {
expect(documentList.currentFolderId).toBe('-mysites-');
});
it('should update pagination settings', () => {
spyOn(documentList, 'reload').and.stub();
documentList.maxItems = 0;
documentList.skipCount = 0;
documentList.updatePagination({
maxItems: 10,
skipCount: 10
});
expect(documentList.maxItems).toBe(10);
expect(documentList.skipCount).toBe(10);
});
it('should reload data upon changing pagination settings', () => {
spyOn(documentList, 'reload').and.stub();
@@ -1320,21 +1236,7 @@ describe('DocumentList', () => {
expect(documentList.reload).toHaveBeenCalled();
});
it('should not reload data if pagination settings are same', () => {
spyOn(documentList, 'reload').and.stub();
documentList.maxItems = 10;
documentList.skipCount = 10;
documentList.updatePagination({
maxItems: 10,
skipCount: 10
});
expect(documentList.reload).not.toHaveBeenCalled();
});
it('should NOT reload data on first call of onNgChanges', () => {
it('should NOT reload data on first call of ngOnChanges', () => {
spyOn(documentList, 'reload').and.stub();
const firstChange = true;
@@ -1343,16 +1245,7 @@ describe('DocumentList', () => {
expect(documentList.reload).not.toHaveBeenCalled();
});
it('should reload data on NON-first calls of onNgChanges', () => {
spyOn(documentList, 'reload').and.stub();
const firstChange = true;
documentList.ngOnChanges({ skipCount: new SimpleChange(undefined, 10, !firstChange) });
expect(documentList.reload).toHaveBeenCalled();
});
it('should NOT reload data on onNgChanges upon reset of skipCount to 0', () => {
it('should NOT reload data on ngOnChanges upon reset of skipCount to 0', () => {
spyOn(documentList, 'reload').and.stub();
documentList.maxItems = 10;
@@ -1378,23 +1271,6 @@ describe('DocumentList', () => {
expect(documentList.reload).toHaveBeenCalled();
});
it('should reset skipCount from pagination settings on loading folder by node id', () => {
spyOn(documentList, 'reload').and.stub();
const favoritesApi = apiService.getInstance().core.favoritesApi;
spyOn(favoritesApi, 'getFavorites').and.returnValue(Promise.resolve(null));
documentList.maxItems = 0;
documentList.skipCount = 0;
documentList.updatePagination({
maxItems: 10,
skipCount: 10
});
documentList.loadFolderByNodeId('-favorites-');
expect(documentList.skipCount).toBe(0, 'skipCount is reset');
});
it('should add includeFields in the server request when present', () => {
documentList.currentFolderId = 'fake-id';
documentList.includeFields = ['test-include'];

View File

@@ -15,50 +15,33 @@
* limitations under the License.
*/
import {
DataCellEvent,
DataColumn,
DataRowActionEvent,
DataSorting,
DataTableComponent,
DisplayMode,
ObjectDataColumn,
PaginatedComponent,
PaginationQueryParams,
PermissionsEnum,
ContentService
} from '@alfresco/adf-core';
import {
AlfrescoApiService,
AppConfigService,
DataColumnListComponent,
UserPreferencesService
} from '@alfresco/adf-core';
import {
AfterContentInit, Component, ContentChild, ElementRef, EventEmitter, HostListener, Input, NgZone,
OnChanges, OnDestroy, OnInit, Output, SimpleChanges, TemplateRef, ViewChild, ViewEncapsulation
} from '@angular/core';
import {
DeletedNodesPaging,
MinimalNodeEntity,
MinimalNodeEntryEntity,
NodePaging,
PersonEntry,
SitePaging,
Pagination
} from 'alfresco-js-api';
ContentService, DataCellEvent, DataColumn, DataRowActionEvent, DataSorting, DataTableComponent,
DisplayMode, ObjectDataColumn, PaginatedComponent, AppConfigService, DataColumnListComponent,
UserPreferencesService, PaginationModel
} from '@alfresco/adf-core';
import { MinimalNodeEntity, MinimalNodeEntryEntity, NodePaging } from 'alfresco-js-api';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { presetsDefaultModel } from '../models/preset.model';
import { Subscription } from 'rxjs/Subscription';
import { ShareDataRow } from './../data/share-data-row.model';
import { ShareDataTableAdapter } from './../data/share-datatable-adapter';
import { presetsDefaultModel } from '../models/preset.model';
import { ContentActionModel } from './../models/content-action.model';
import { PermissionStyleModel } from './../models/permissions-style.model';
import { DocumentListService } from './../services/document-list.service';
import { NodeEntityEvent, NodeEntryEvent } from './node.event';
import { Subscription } from 'rxjs/Subscription';
import { CustomResourcesService } from './../services/custom-resources.service';
export enum PaginationStrategy {
Finite,
@@ -77,7 +60,8 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
static DOUBLE_CLICK_NAVIGATION: string = 'dblclick';
static DEFAULT_PAGE_SIZE: number = 20;
@ContentChild(DataColumnListComponent) columnList: DataColumnListComponent;
@ContentChild(DataColumnListComponent)
columnList: DataColumnListComponent;
/** Include additional information about the node in the server request.for example: association, isLink, isLocked and others. */
@Input()
@@ -191,14 +175,16 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
@Input()
node: NodePaging = null;
/** Default value is stored into user preference settings */
/** Default value is stored into user preference settings use it only if you are not using the pagination */
@Input()
maxItems: number;
/** @deprecated 2.3.0 define it in pagination */
/** Number of elements to skip over for pagination purposes */
@Input()
skipCount: number = 0;
/** @deprecated 2.3.0 */
/** Set document list to work in infinite scrolling mode */
@Input()
enableInfiniteScrolling: boolean = false;
@@ -233,39 +219,26 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
@ViewChild('dataTable')
dataTable: DataTableComponent;
errorMessage;
actions: ContentActionModel[] = [];
emptyFolderTemplate: TemplateRef<any>;
noPermissionTemplate: TemplateRef<any>;
contextActionHandler: Subject<any> = new Subject();
data: ShareDataTableAdapter;
infiniteLoading: boolean = false;
noPermission: boolean = false;
selection = new Array<MinimalNodeEntity>();
pagination: BehaviorSubject<Pagination>;
private _pagination: BehaviorSubject<PaginationModel>;
private layoutPresets = {};
private currentNodeAllowableOperations: string[] = [];
private CREATE_PERMISSION = 'create';
private contextActionHandlerSubscription: Subscription;
constructor(private documentListService: DocumentListService,
private ngZone: NgZone,
private elementRef: ElementRef,
private apiService: AlfrescoApiService,
private appConfig: AppConfigService,
private preferences: UserPreferencesService,
private contentService?: ContentService) {
this.maxItems = this.preferences.paginationSize;
this.pagination = new BehaviorSubject<Pagination>(<Pagination> {
maxItems: this.preferences.paginationSize,
skipCount: 0,
totalItems: 0,
hasMoreItems: false
});
private customResourcesService: CustomResourcesService,
private contentService: ContentService) {
}
getContextActions(node: MinimalNodeEntity) {
@@ -284,16 +257,75 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
return null;
}
contextActionCallback(action) {
if (action) {
this.executeContentAction(action.node, action.model);
}
/** @deprecated 2.3.0 define it in pagination */
get supportedPageSizes(): number[] {
return this.preferences.getDefaultPageSizes();
}
get hasCustomLayout(): boolean {
return this.columnList && this.columnList.columns && this.columnList.columns.length > 0;
}
private getDefaultSorting(): DataSorting {
let defaultSorting: DataSorting;
if (this.sorting) {
const [key, direction] = this.sorting;
defaultSorting = new DataSorting(key, direction);
}
return defaultSorting;
}
private getLayoutPreset(name: string = 'default'): DataColumn[] {
return (this.layoutPresets[name] || this.layoutPresets['default']).map(col => new ObjectDataColumn(col));
}
get pagination(): BehaviorSubject<PaginationModel> {
let maxItems = this.preferences.paginationSize;
if (!this._pagination) {
if (this.maxItems) {
maxItems = this.maxItems;
}
let defaultPagination = <PaginationModel> {
maxItems: maxItems,
skipCount: 0,
totalItems: 0,
hasMoreItems: false
};
this._pagination = new BehaviorSubject<PaginationModel>(defaultPagination);
}
return this._pagination;
}
isEmptyTemplateDefined(): boolean {
if (this.dataTable) {
if (this.emptyFolderTemplate) {
return true;
}
}
return false;
}
isNoPermissionTemplateDefined(): boolean {
if (this.dataTable) {
if (this.noPermissionTemplate) {
return true;
}
}
return false;
}
isMobile(): boolean {
return !!/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
}
isEmpty() {
return !this.data || this.data.getRows().length === 0;
}
ngOnInit() {
this.loadLayoutPresets();
this.data = new ShareDataTableAdapter(this.documentListService, null, this.getDefaultSorting());
@@ -333,10 +365,8 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
}
ngOnChanges(changes: SimpleChanges) {
if (this.isSkipCountChanged(changes) ||
this.isMaxItemsChanged(changes)) {
this.reload(this.enableInfiniteScrolling);
}
this.resetSelection();
if (changes.folderNode && changes.folderNode.currentValue) {
this.loadFolder();
} else if (changes.currentFolderId && changes.currentFolderId.currentValue) {
@@ -346,17 +376,18 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
if (!this.hasCustomLayout) {
this.setupDefaultColumns(changes.currentFolderId.currentValue);
}
this.loading = true;
this.loadFolderByNodeId(changes.currentFolderId.currentValue);
} else if (this.data) {
if (changes.node && changes.node.currentValue) {
this.resetSelection();
this.data.loadPage(changes.node.currentValue);
this.pagination.next(changes.node.currentValue.list.pagination);
this.onDataReady(changes.node.currentValue);
} else if (changes.rowFilter) {
this.data.setFilter(changes.rowFilter.currentValue);
if (this.currentFolderId) {
this.loadFolderNodesByFolderNodeId(this.currentFolderId, this.maxItems, this.skipCount);
this.loadFolderNodesByFolderNodeId(this.currentFolderId, this.pagination.getValue()).catch(err => this.error.emit(err));
}
} else if (changes.imageResolver) {
this.data.setImageResolver(changes.imageResolver.currentValue);
@@ -364,14 +395,15 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
}
}
reload(merge: boolean = false) {
reload() {
this.ngZone.run(() => {
this.resetSelection();
if (this.folderNode) {
this.loadFolder(merge);
this.loadFolder();
} else if (this.currentFolderId) {
this.loadFolderByNodeId(this.currentFolderId, merge);
this.loading = true;
this.loadFolderByNodeId(this.currentFolderId);
} else if (this.node) {
this.data.loadPage(this.node);
this.onDataReady(this.node);
@@ -379,30 +411,10 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
});
}
isEmptyTemplateDefined(): boolean {
if (this.dataTable) {
if (this.emptyFolderTemplate) {
return true;
}
contextActionCallback(action) {
if (action) {
this.executeContentAction(action.node, action.model);
}
return false;
}
isNoPermissionTemplateDefined(): boolean {
if (this.dataTable) {
if (this.noPermissionTemplate) {
return true;
}
}
return false;
}
isMobile(): boolean {
return !!/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
}
isEmpty() {
return !this.data || this.data.getRows().length === 0;
}
getNodeActions(node: MinimalNodeEntity | any): ContentActionModel[] {
@@ -411,20 +423,17 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
if (node && node.entry) {
if (node.entry.isFile) {
target = 'document';
}
if (node.entry.isFolder) {
} else if (node.entry.isFolder) {
target = 'folder';
}
if (target) {
let ltarget = target.toLowerCase();
let actionsByTarget = this.actions.filter(entry => {
return entry.target.toLowerCase() === ltarget;
return entry.target.toLowerCase() === target;
}).map(action => new ContentActionModel(action));
actionsByTarget.forEach((action) => {
this.checkPermission(node, action);
this.disableActionsWithNoPermissions(node, action);
});
return actionsByTarget;
@@ -434,26 +443,10 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
return [];
}
checkPermission(node: any, action: ContentActionModel): ContentActionModel {
if (action.permission && !~[PermissionsEnum.COPY, PermissionsEnum.LOCK].indexOf(action.permission)) {
if (this.hasPermissions(node)) {
let permissions = node.entry.allowableOperations;
let findPermission = permissions.find(permission => permission === action.permission);
if (!findPermission && action.disableWithNoPermission === true) {
action.disabled = true;
}
}
disableActionsWithNoPermissions(node: MinimalNodeEntity, action: ContentActionModel) {
if (action.permission && node.entry.allowableOperations && !this.contentService.hasPermission(node.entry, action.permission)) {
action.disabled = true;
}
if (action.permission === PermissionsEnum.LOCK) {
action.disabled = !this.contentService.hasPermission(node.entry, PermissionsEnum.LOCK);
}
return action;
}
private hasPermissions(node: any): boolean {
return node.entry.allowableOperations ? true : false;
}
@HostListener('contextmenu', ['$event'])
@@ -472,7 +465,7 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
}
performCustomSourceNavigation(node: MinimalNodeEntity): boolean {
if (this.isCustomSource(this.currentFolderId)) {
if (this.customResourcesService.isCustomSource(this.currentFolderId)) {
this.updateFolderData(node);
return true;
}
@@ -482,18 +475,13 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
updateFolderData(node: MinimalNodeEntity): void {
this.currentFolderId = node.entry.id;
this.folderNode = node.entry;
this.skipCount = 0;
this.currentNodeAllowableOperations = node.entry['allowableOperations'] ? node.entry['allowableOperations'] : [];
this.loadFolder();
this.folderChange.emit(new NodeEntryEvent(node.entry));
}
updateCustomSourceData(nodeId: string, merge: boolean): void {
updateCustomSourceData(nodeId: string): void {
this.folderNode = null;
this.currentFolderId = nodeId;
if (!merge) {
this.skipCount = 0;
}
}
/**
@@ -519,10 +507,8 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
}
}
loadFolder(merge: boolean = false) {
if (merge) {
this.infiniteLoading = true;
} else {
loadFolder() {
if (!this.pagination.getValue().merge) {
this.loading = true;
}
@@ -532,70 +518,55 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
this.setupDefaultColumns(nodeId);
}
if (nodeId) {
this.loadFolderNodesByFolderNodeId(nodeId, this.maxItems, this.skipCount, merge).catch(err => this.error.emit(err));
this.loadFolderNodesByFolderNodeId(nodeId, this.pagination.getValue());
}
}
// gets folder node and its content
loadFolderByNodeId(nodeId: string, merge: boolean = false) {
this.loading = true;
this.resetSelection();
if (nodeId === '-trashcan-') {
this.loadTrashcan(merge);
} else if (nodeId === '-sharedlinks-') {
this.loadSharedLinks(merge);
} else if (nodeId === '-sites-') {
this.loadSites(merge);
} else if (nodeId === '-mysites-') {
this.loadMemberSites(merge);
} else if (nodeId === '-favorites-') {
this.loadFavorites(merge);
} else if (nodeId === '-recent-') {
this.loadRecent(merge);
loadFolderByNodeId(nodeId: string) {
if (this.customResourcesService.isCustomSource(nodeId)) {
this.updateCustomSourceData(nodeId);
this.customResourcesService.loadFolderByNodeId(nodeId, this.pagination.getValue(), this.includeFields)
.subscribe((page: NodePaging) => {
this.onPageLoaded(page);
}, err => {
this.error.emit(err);
});
} else {
this.documentListService
.getFolderNode(nodeId, this.includeFields)
.then(node => {
.subscribe((node: MinimalNodeEntryEntity) => {
this.folderNode = node;
this.currentFolderId = node.id;
this.skipCount = 0;
this.currentNodeAllowableOperations = node['allowableOperations'] ? node['allowableOperations'] : [];
return this.loadFolderNodesByFolderNodeId(node.id, this.maxItems, this.skipCount, merge);
})
.catch(err => {
if (JSON.parse(err.message).error.statusCode === 403) {
this.loading = false;
this.noPermission = true;
if (node.id) {
this.currentFolderId = node.id;
}
this.error.emit(err);
return this.loadFolderNodesByFolderNodeId(node.id, this.pagination.getValue())
.catch(err => this.handleError(err));
}, err => {
this.handleError(err);
});
}
}
loadFolderNodesByFolderNodeId(id: string, maxItems: number, skipCount: number, merge: boolean = false): Promise<any> {
loadFolderNodesByFolderNodeId(id: string, pagination: PaginationModel): Promise<any> {
return new Promise((resolve, reject) => {
this.resetSelection();
this.documentListService
.getFolder(null, {
maxItems: maxItems,
skipCount: skipCount,
maxItems: pagination.maxItems,
skipCount: pagination.skipCount,
rootFolderId: id
}, this.includeFields)
.subscribe(
val => {
this.data.loadPage(<NodePaging> val, merge);
nodePaging => {
this.data.loadPage(<NodePaging> nodePaging, this.pagination.getValue().merge);
this.loading = false;
this.infiniteLoading = false;
this.onDataReady(val);
this.onDataReady(nodePaging);
resolve(true);
},
error => {
reject(error);
}, err => {
this.handleError(err);
});
});
}
resetSelection() {
@@ -604,144 +575,11 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
this.noPermission = false;
}
private isSkipCountChanged(changePage: SimpleChanges) {
return changePage.skipCount &&
!changePage.skipCount.isFirstChange() &&
changePage.skipCount.currentValue &&
changePage.skipCount.currentValue !== changePage.skipCount.previousValue;
}
private isMaxItemsChanged(changePage: SimpleChanges) {
return changePage.maxItems &&
!changePage.maxItems.isFirstChange() &&
changePage.maxItems.currentValue &&
changePage.maxItems.currentValue !== changePage.maxItems.previousValue;
}
private loadTrashcan(merge: boolean = false): void {
this.updateCustomSourceData('-trashcan-', merge);
const options = {
include: ['path', 'properties'],
maxItems: this.maxItems,
skipCount: this.skipCount
};
this.apiService.nodesApi.getDeletedNodes(options)
.then((page: DeletedNodesPaging) => this.onPageLoaded(page, merge))
.catch(error => this.error.emit(error));
}
private loadSharedLinks(merge: boolean = false): void {
this.updateCustomSourceData('-sharedlinks-', merge);
const options = {
include: ['properties', 'allowableOperations', 'path'],
maxItems: this.maxItems,
skipCount: this.skipCount
};
this.apiService.sharedLinksApi.findSharedLinks(options)
.then((page: NodePaging) => this.onPageLoaded(page, merge))
.catch(error => this.error.emit(error));
}
private loadSites(merge: boolean = false): void {
this.updateCustomSourceData('-sites-', merge);
const options = {
include: ['properties'],
maxItems: this.maxItems,
skipCount: this.skipCount
};
this.apiService.sitesApi.getSites(options)
.then((page: NodePaging) => {
page.list.entries.map(
({ entry }: any) => {
entry.name = entry.name || entry.title;
return { entry };
}
);
this.onPageLoaded(page, merge);
})
.catch(error => this.error.emit(error));
}
private loadMemberSites(merge: boolean = false): void {
this.updateCustomSourceData('-mysites-', merge);
const options = {
include: ['properties'],
maxItems: this.maxItems,
skipCount: this.skipCount
};
this.apiService.peopleApi.getSiteMembership('-me-', options)
.then((result: SitePaging) => {
let page: NodePaging = {
list: {
entries: result.list.entries
.map(({ entry: { site } }: any) => {
site.allowableOperations = site.allowableOperations ? site.allowableOperations : [this.CREATE_PERMISSION];
site.name = site.name || site.title;
return {
entry: site
};
}),
pagination: result.list.pagination
}
};
this.onPageLoaded(page, merge);
})
.catch(error => this.error.emit(error));
}
private loadFavorites(merge: boolean = false): void {
this.updateCustomSourceData('-favorites-', merge);
const options = {
maxItems: this.maxItems,
skipCount: this.skipCount,
where: '(EXISTS(target/file) OR EXISTS(target/folder))',
include: ['properties', 'allowableOperations', 'path']
};
this.apiService.favoritesApi.getFavorites('-me-', options)
.then((result: NodePaging) => {
let page: NodePaging = {
list: {
entries: result.list.entries
.map(({ entry: { target } }: any) => ({
entry: target.file || target.folder
}))
.map(({ entry }: any) => {
entry.properties = {
'cm:title': entry.title,
'cm:description': entry.description
};
return { entry };
}),
pagination: result.list.pagination
}
};
this.onPageLoaded(page, merge);
})
.catch(error => this.error.emit(error));
}
private loadRecent(merge: boolean = false): void {
this.updateCustomSourceData('-recent-', merge);
this.getRecentFiles('-me-')
.then((page: NodePaging) => this.onPageLoaded(page, merge))
.catch(error => this.error.emit(error));
}
private onPageLoaded(page: NodePaging, merge: boolean = false) {
if (page) {
this.data.loadPage(page, merge);
private onPageLoaded(nodePaging: NodePaging) {
if (nodePaging) {
this.data.loadPage(nodePaging, this.pagination.getValue().merge);
this.loading = false;
this.onDataReady(page);
this.onDataReady(nodePaging);
}
}
@@ -876,48 +714,16 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
}
}
private getDefaultSorting(): DataSorting {
let defaultSorting: DataSorting;
if (this.sorting) {
const [key, direction] = this.sorting;
defaultSorting = new DataSorting(key, direction);
}
return defaultSorting;
}
canNavigateFolder(node: MinimalNodeEntity): boolean {
if (this.isCustomSource(this.currentFolderId)) {
return false;
let canNavigateFolder: boolean = false;
if (this.customResourcesService.isCustomSource(this.currentFolderId)) {
canNavigateFolder = false;
} else if (node && node.entry && node.entry.isFolder) {
canNavigateFolder = true;
}
if (node && node.entry && node.entry.isFolder) {
return true;
}
return false;
}
isCustomSource(folderId: string): boolean {
const sources = ['-trashcan-', '-sharedlinks-', '-sites-', '-mysites-', '-favorites-', '-recent-'];
if (sources.indexOf(folderId) > -1) {
return true;
}
return false;
}
hasCurrentNodePermission(permission: string): boolean {
let hasPermission: boolean = false;
if (this.currentNodeAllowableOperations.length > 0) {
let permFound = this.currentNodeAllowableOperations.find(element => element === permission);
hasPermission = permFound ? true : false;
}
return hasPermission;
}
hasCreatePermission() {
return this.hasCurrentNodePermission(this.CREATE_PERMISSION);
return canNavigateFolder;
}
private loadLayoutPresets(): void {
@@ -930,33 +736,30 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
}
}
private getLayoutPreset(name: string = 'default'): DataColumn[] {
return (this.layoutPresets[name] || this.layoutPresets['default']).map(col => new ObjectDataColumn(col));
private onDataReady(nodePaging: NodePaging) {
this.ready.emit(nodePaging);
this.pagination.next(nodePaging.list.pagination);
}
private onDataReady(page: NodePaging) {
this.ready.emit(page);
updatePagination(pagination: PaginationModel) {
this.reload();
}
if (page && page.list && page.list.pagination) {
this.pagination.next(page.list.pagination);
} else {
this.pagination.next(null);
// TODO: remove it from here
getCorrespondingNodeIds(nodeId: string): Observable<string[]> {
if (this.customResourcesService.isCustomSource(nodeId)) {
return this.customResourcesService.getCorrespondingNodeIds(nodeId, this.pagination.getValue());
} else if (nodeId) {
return new Observable(observer => {
this.documentListService.getFolderNode(nodeId, this.includeFields)
.subscribe((node: MinimalNodeEntryEntity) => {
observer.next([node.id]);
observer.complete();
});
});
}
}
updatePagination(params: PaginationQueryParams) {
const needsReload = this.maxItems !== params.maxItems || this.skipCount !== params.skipCount;
this.maxItems = params.maxItems;
this.skipCount = params.skipCount;
if (needsReload) {
this.reload(this.enableInfiniteScrolling);
}
}
get supportedPageSizes(): number[] {
return this.preferences.getDefaultPageSizes();
}
ngOnDestroy() {
@@ -966,67 +769,15 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
}
}
getCorrespondingNodeIds(nodeId: string): Promise<string[]> {
if (nodeId === '-trashcan-') {
return this.apiService.nodesApi.getDeletedNodes()
.then(result => result.list.entries.map(node => node.entry.id));
} else if (nodeId === '-sharedlinks-') {
return this.apiService.sharedLinksApi.findSharedLinks()
.then(result => result.list.entries.map(node => node.entry.nodeId));
} else if (nodeId === '-sites-') {
return this.apiService.sitesApi.getSites()
.then(result => result.list.entries.map(node => node.entry.guid));
} else if (nodeId === '-mysites-') {
return this.apiService.peopleApi.getSiteMembership('-me-')
.then(result => result.list.entries.map(node => node.entry.guid));
} else if (nodeId === '-favorites-') {
return this.apiService.favoritesApi.getFavorites('-me-')
.then(result => result.list.entries.map(node => node.entry.targetGuid));
} else if (nodeId === '-recent-') {
return this.getRecentFiles('-me-')
.then(result => result.list.entries.map(node => node.entry.id));
} else if (nodeId) {
return this.documentListService.getFolderNode(nodeId, this.includeFields)
.then(node => [node.id]);
private handleError(err: any) {
if (err.message) {
if (JSON.parse(err.message).error.statusCode === 403) {
this.loading = false;
this.noPermission = true;
}
}
this.error.emit(err);
return new Promise((resolve) => {
resolve([]);
});
}
getRecentFiles(personId: string): Promise<NodePaging> {
return this.apiService.peopleApi.getPerson(personId)
.then((person: PersonEntry) => {
const username = person.entry.id;
const query = {
query: {
query: '*',
language: 'afts'
},
filterQueries: [
{ query: `cm:modified:[NOW/DAY-30DAYS TO NOW/DAY+1DAY]` },
{ query: `cm:modifier:${username} OR cm:creator:${username}` },
{ query: `TYPE:"content" AND -TYPE:"app:filelink" AND -TYPE:"fm:post"` }
],
include: ['path', 'properties', 'allowableOperations'],
sort: [{
type: 'FIELD',
field: 'cm:modified',
ascending: false
}],
paging: {
maxItems: this.maxItems,
skipCount: this.skipCount
}
};
return this.apiService.searchApi.search(query);
});
}
}

View File

@@ -19,6 +19,7 @@ import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { async, TestBed } from '@angular/core/testing';
import { DataTableComponent, DataTableModule } from '@alfresco/adf-core';
import { DocumentListService } from '../../services/document-list.service';
import { CustomResourcesService } from '../../services/custom-resources.service';
import { DocumentListComponent } from './../document-list.component';
import { EmptyFolderContentDirective } from './empty-folder-content.directive';
@@ -37,7 +38,8 @@ describe('EmptyFolderContent', () => {
DocumentListComponent
],
providers: [
DocumentListService
DocumentListService,
CustomResourcesService
],
schemas: [
CUSTOM_ELEMENTS_SCHEMA

View File

@@ -19,6 +19,7 @@ import { async, TestBed } from '@angular/core/testing';
import { MatProgressSpinnerModule } from '@angular/material';
import { DataTableComponent, DataTableModule } from '@alfresco/adf-core';
import { DocumentListService } from '../../services/document-list.service';
import { CustomResourcesService } from '../../services/custom-resources.service';
import { DocumentListComponent } from './../document-list.component';
import { NoPermissionContentDirective } from './no-permission-content.directive';
@@ -38,7 +39,8 @@ describe('NoPermissionContentDirective', () => {
DocumentListComponent
],
providers: [
DocumentListService
DocumentListService,
CustomResourcesService
]
}).compileComponents();
}));

View File

@@ -37,6 +37,7 @@ import { DocumentActionsService } from './services/document-actions.service';
import { DocumentListService } from './services/document-list.service';
import { FolderActionsService } from './services/folder-actions.service';
import { NodeActionsService } from './services/node-actions.service';
import { CustomResourcesService } from './services/custom-resources.service';
@NgModule({
imports: [
@@ -62,7 +63,8 @@ import { NodeActionsService } from './services/node-actions.service';
DocumentListService,
FolderActionsService,
DocumentActionsService,
NodeActionsService
NodeActionsService,
CustomResourcesService
],
exports: [
DocumentListComponent,

View File

@@ -35,6 +35,7 @@ export * from './services/folder-actions.service';
export * from './services/document-actions.service';
export * from './services/document-list.service';
export * from './services/node-actions.service';
export * from './services/custom-resources.service';
// models
export * from './models/content-action.model';

View File

@@ -0,0 +1,285 @@
/*!
* @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 {
AlfrescoApiService,
LogService,
PaginationModel
} from '@alfresco/adf-core';
import {
NodePaging,
PersonEntry,
SitePaging,
DeletedNodesPaging
} from 'alfresco-js-api';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class CustomResourcesService {
private CREATE_PERMISSION = 'create';
constructor(private apiService: AlfrescoApiService,
private logService: LogService) {
}
getRecentFiles(personId: string, pagination: PaginationModel): Observable<NodePaging> {
return new Observable(observer => {
this.apiService.peopleApi.getPerson(personId)
.then((person: PersonEntry) => {
const username = person.entry.id;
const query = {
query: {
query: '*',
language: 'afts'
},
filterQueries: [
{ query: `cm:modified:[NOW/DAY-30DAYS TO NOW/DAY+1DAY]` },
{ query: `cm:modifier:${username} OR cm:creator:${username}` },
{ query: `TYPE:"content" AND -TYPE:"app:filelink" AND -TYPE:"fm:post"` }
],
include: ['path', 'properties', 'allowableOperations'],
sort: [{
type: 'FIELD',
field: 'cm:modified',
ascending: false
}],
paging: {
maxItems: pagination.maxItems,
skipCount: pagination.skipCount
}
};
return this.apiService.searchApi.search(query)
.then((serachResult) => {
observer.next(serachResult);
observer.complete();
},
(err) => {
observer.error(err);
observer.complete();
});
},
(err) => {
observer.error(err);
observer.complete();
});
}).catch(err => this.handleError(err));
}
loadFavorites(pagination: PaginationModel, includeFields: string[] = []): Observable<NodePaging> {
let includeFieldsRequest = this.getIncludesFields(includeFields);
const options = {
maxItems: pagination.maxItems,
skipCount: pagination.skipCount,
where: '(EXISTS(target/file) OR EXISTS(target/folder))',
include: includeFieldsRequest
};
return new Observable(observer => {
this.apiService.favoritesApi.getFavorites('-me-', options)
.then((result: NodePaging) => {
let page: NodePaging = {
list: {
entries: result.list.entries
.map(({ entry: { target } }: any) => ({
entry: target.file || target.folder
}))
.map(({ entry }: any) => {
entry.properties = {
'cm:title': entry.title,
'cm:description': entry.description
};
return { entry };
}),
pagination: result.list.pagination
}
};
observer.next(page);
observer.complete();
},
(err) => {
observer.error(err);
observer.complete();
});
}).catch(err => this.handleError(err));
}
loadMemberSites(pagination: PaginationModel): Observable<NodePaging> {
const options = {
include: ['properties'],
maxItems: pagination.maxItems,
skipCount: pagination.skipCount
};
return new Observable(observer => {
this.apiService.peopleApi.getSiteMembership('-me-', options)
.then((result: SitePaging) => {
let page: NodePaging = {
list: {
entries: result.list.entries
.map(({ entry: { site } }: any) => {
site.allowableOperations = site.allowableOperations ? site.allowableOperations : [this.CREATE_PERMISSION];
site.name = site.name || site.title;
return {
entry: site
};
}),
pagination: result.list.pagination
}
};
observer.next(page);
observer.complete();
},
(err) => {
observer.error(err);
observer.complete();
});
}).catch(err => this.handleError(err));
}
loadSites(pagination: PaginationModel): Observable<NodePaging> {
const options = {
include: ['properties'],
maxItems: pagination.maxItems,
skipCount: pagination.skipCount
};
return new Observable(observer => {
this.apiService.sitesApi.getSites(options)
.then((page: NodePaging) => {
page.list.entries.map(
({ entry }: any) => {
entry.name = entry.name || entry.title;
return { entry };
}
);
observer.next(page);
observer.complete();
},
(err) => {
observer.error(err);
observer.complete();
});
}).catch(err => this.handleError(err));
}
loadTrashcan(pagination: PaginationModel, includeFields: string[] = []): Observable<DeletedNodesPaging> {
let includeFieldsRequest = this.getIncludesFields(includeFields);
const options = {
include: includeFieldsRequest,
maxItems: pagination.maxItems,
skipCount: pagination.skipCount
};
return Observable.fromPromise(this.apiService.nodesApi.getDeletedNodes(options)).catch(err => this.handleError(err));
}
loadSharedLinks(pagination: PaginationModel, includeFields: string[] = []): Observable<NodePaging> {
let includeFieldsRequest = this.getIncludesFields(includeFields);
const options = {
include: includeFieldsRequest,
maxItems: pagination.maxItems,
skipCount: pagination.skipCount
};
return Observable.fromPromise(this.apiService.sharedLinksApi.findSharedLinks(options)).catch(err => this.handleError(err));
}
isCustomSource(folderId: string): boolean {
let isCustomSources = false;
const sources = ['-trashcan-', '-sharedlinks-', '-sites-', '-mysites-', '-favorites-', '-recent-'];
if (sources.indexOf(folderId) > -1) {
isCustomSources = true;
}
return isCustomSources;
}
loadFolderByNodeId(nodeId: string, pagination: PaginationModel, includeFields: string[]): Observable<NodePaging> {
if (nodeId === '-trashcan-') {
return this.loadTrashcan(pagination, includeFields);
} else if (nodeId === '-sharedlinks-') {
return this.loadSharedLinks(pagination, includeFields);
} else if (nodeId === '-sites-') {
return this.loadSites(pagination);
} else if (nodeId === '-mysites-') {
return this.loadMemberSites(pagination);
} else if (nodeId === '-favorites-') {
return this.loadFavorites(pagination, includeFields);
} else if (nodeId === '-recent-') {
return this.getRecentFiles('-me-', pagination);
}
}
// TODO: remove it from here
getCorrespondingNodeIds(nodeId: string, pagination: PaginationModel): Observable<string[]> {
if (nodeId === '-trashcan-') {
return Observable.fromPromise(this.apiService.nodesApi.getDeletedNodes()
.then(result => result.list.entries.map(node => node.entry.id)));
} else if (nodeId === '-sharedlinks-') {
return Observable.fromPromise(this.apiService.sharedLinksApi.findSharedLinks()
.then(result => result.list.entries.map(node => node.entry.nodeId)));
} else if (nodeId === '-sites-') {
return Observable.fromPromise(this.apiService.sitesApi.getSites()
.then(result => result.list.entries.map(node => node.entry.guid)));
} else if (nodeId === '-mysites-') {
return Observable.fromPromise(this.apiService.peopleApi.getSiteMembership('-me-')
.then(result => result.list.entries.map(node => node.entry.guid)));
} else if (nodeId === '-favorites-') {
return Observable.fromPromise(this.apiService.favoritesApi.getFavorites('-me-')
.then(result => result.list.entries.map(node => node.entry.targetGuid)));
} else if (nodeId === '-recent-') {
return new Observable(observer => {
this.getRecentFiles('-me-', pagination)
.subscribe((recentFiles) => {
let recentFilesIdS = recentFiles.list.entries.map(node => node.entry.id);
observer.next(recentFilesIdS);
observer.complete();
});
});
}
return Observable.of([]);
}
private getIncludesFields(includeFields: string[]): string[] {
return ['path', 'properties', 'allowableOperations', 'permissions', ...includeFields]
.filter((element, index, array) => index === array.indexOf(element));
}
private handleError(error: Response) {
// in a real world app, we may send the error to some remote logging infrastructure
// instead of just logging it to the console
this.logService.error(error);
return Observable.throw(error || 'Server error');
}
}

View File

@@ -15,12 +15,7 @@
* limitations under the License.
*/
import {
AlfrescoApiServiceMock,
AppConfigService,
StorageService,
ContentService
} from '@alfresco/adf-core';
import { AlfrescoApiServiceMock, AppConfigService, StorageService, ContentService } from '@alfresco/adf-core';
import { FileNode, FolderNode } from '../../mock';
import { ContentActionHandler } from '../models/content-action.model';
import { DocumentActionsService } from './document-actions.service';
@@ -37,6 +32,7 @@ describe('DocumentActionsService', () => {
beforeEach(() => {
let contentService = new ContentService(null, null, null, null);
let alfrescoApiService = new AlfrescoApiServiceMock(new AppConfigService(null), new StorageService());
documentListService = new DocumentListService(null, contentService, alfrescoApiService, null, null);
service = new DocumentActionsService(null, null, documentListService, contentService);

View File

@@ -15,7 +15,8 @@
* limitations under the License.
*/
import { AlfrescoApiServiceMock, AlfrescoApiService, AppConfigService, StorageService, ContentService } from '@alfresco/adf-core';
import { AlfrescoApiServiceMock, AlfrescoApiService,
AppConfigService, StorageService, ContentService } from '@alfresco/adf-core';
import { DocumentListService } from './document-list.service';
declare let jasmine: any;

View File

@@ -16,13 +16,10 @@
*/
import {
AlfrescoApiService,
AuthenticationService,
ContentService,
LogService,
PermissionsEnum,
ThumbnailService
AlfrescoApiService, AuthenticationService, ContentService, LogService,
PermissionsEnum, ThumbnailService
} from '@alfresco/adf-core';
import { Injectable } from '@angular/core';
import { Response } from '@angular/http';
import { MinimalNodeEntity, MinimalNodeEntryEntity, NodePaging } from 'alfresco-js-api';
@@ -135,7 +132,7 @@ export class DocumentListService {
* @param includeFields Extra information to include (available options are "aspectNames", "isLink" and "association")
* @returns Details of the folder
*/
getFolderNode(nodeId: string, includeFields: string[] = []): Promise<MinimalNodeEntryEntity> {
getFolderNode(nodeId: string, includeFields: string[] = []): Observable<MinimalNodeEntryEntity> {
let includeFieldsRequest = ['path', 'properties', 'allowableOperations', 'permissions', ...includeFields]
.filter((element, index, array) => index === array.indexOf(element));
@@ -145,8 +142,7 @@ export class DocumentListService {
include: includeFieldsRequest
};
let nodes: any = this.apiService.getInstance().nodes;
return nodes.getNodeInfo(nodeId, opts);
return Observable.fromPromise(this.apiService.getInstance().nodes.getNodeInfo(nodeId, opts));
}
/**
@@ -176,6 +172,7 @@ export class DocumentListService {
}
/**
* @Deprecated 2.3.0 use the one in the content service
* Checks if a node has the specified permission.
* @param node Target node
* @param permission Permission level to query

View File

@@ -44,7 +44,6 @@ describe('NodeActionsService', () => {
declarations: [
NodeLockDialogComponent
],
imports: [],
providers: [
NodeActionsService,
DocumentListService,