content api service (#455)

* introduce content-api service

* upgrade files component

* upgrade directives

* upgrade directives

* update directives

* fix profile resolver call ordering issue

* fix reducer

* update services

* extra apis

* update about page

* update preview component

* code updates
This commit is contained in:
Denys Vuika
2018-06-25 08:37:21 +01:00
committed by Cilibiu Bogdan
parent ac6e96530f
commit af547aac31
36 changed files with 551 additions and 392 deletions

View File

@@ -79,6 +79,7 @@ import { PaginationDirective } from './directives/pagination.directive';
import { DocumentListDirective } from './directives/document-list.directive'; import { DocumentListDirective } from './directives/document-list.directive';
import { MaterialModule } from './material.module'; import { MaterialModule } from './material.module';
import { ExperimentalDirective } from './directives/experimental.directive'; import { ExperimentalDirective } from './directives/experimental.directive';
import { ContentApiService } from './services/content-api.service';
@NgModule({ @NgModule({
imports: [ imports: [
@@ -149,7 +150,8 @@ import { ExperimentalDirective } from './directives/experimental.directive';
ContentManagementService, ContentManagementService,
NodeActionsService, NodeActionsService,
NodePermissionService, NodePermissionService,
ProfileResolver ProfileResolver,
ContentApiService
], ],
entryComponents: [ entryComponents: [
NodeVersionsDialogComponent NodeVersionsDialogComponent

View File

@@ -27,10 +27,11 @@ import { Component, DebugElement } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { Observable } from 'rxjs/Rx'; import { Observable } from 'rxjs/Rx';
import { NodesApiService, NotificationService } from '@alfresco/adf-core'; import { NotificationService } from '@alfresco/adf-core';
import { NodeActionsService } from '../services/node-actions.service'; import { NodeActionsService } from '../services/node-actions.service';
import { NodeCopyDirective } from './node-copy.directive'; import { NodeCopyDirective } from './node-copy.directive';
import { AppTestingModule } from '../../testing/app-testing.module'; import { AppTestingModule } from '../../testing/app-testing.module';
import { ContentApiService } from '../../services/content-api.service';
@Component({ @Component({
template: '<div [acaCopyNode]="selection"></div>' template: '<div [acaCopyNode]="selection"></div>'
@@ -44,8 +45,8 @@ describe('NodeCopyDirective', () => {
let component: TestComponent; let component: TestComponent;
let element: DebugElement; let element: DebugElement;
let notificationService: NotificationService; let notificationService: NotificationService;
let nodesApiService: NodesApiService;
let service: NodeActionsService; let service: NodeActionsService;
let contentApi: ContentApiService;
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
@@ -56,11 +57,12 @@ describe('NodeCopyDirective', () => {
] ]
}); });
contentApi = TestBed.get(ContentApiService);
fixture = TestBed.createComponent(TestComponent); fixture = TestBed.createComponent(TestComponent);
component = fixture.componentInstance; component = fixture.componentInstance;
element = fixture.debugElement.query(By.directive(NodeCopyDirective)); element = fixture.debugElement.query(By.directive(NodeCopyDirective));
notificationService = TestBed.get(NotificationService); notificationService = TestBed.get(NotificationService);
nodesApiService = TestBed.get(NodesApiService);
service = TestBed.get(NodeActionsService); service = TestBed.get(NodeActionsService);
}); });
@@ -233,7 +235,7 @@ describe('NodeCopyDirective', () => {
}); });
it('should delete the newly created node on Undo action', () => { it('should delete the newly created node on Undo action', () => {
spyOn(nodesApiService, 'deleteNode').and.returnValue(Observable.of(null)); spyOn(contentApi, 'deleteNode').and.returnValue(Observable.of(null));
component.selection = [{ entry: { id: 'node-to-copy-id', name: 'name' } }]; component.selection = [{ entry: { id: 'node-to-copy-id', name: 'name' } }];
const createdItems = [{ entry: { id: 'copy-id', name: 'name' } }]; const createdItems = [{ entry: { id: 'copy-id', name: 'name' } }];
@@ -247,11 +249,11 @@ describe('NodeCopyDirective', () => {
'APP.MESSAGES.INFO.NODE_COPY.SINGULAR', 'APP.ACTIONS.UNDO', 10000 'APP.MESSAGES.INFO.NODE_COPY.SINGULAR', 'APP.ACTIONS.UNDO', 10000
); );
expect(nodesApiService.deleteNode).toHaveBeenCalledWith(createdItems[0].entry.id, { permanent: true }); expect(contentApi.deleteNode).toHaveBeenCalledWith(createdItems[0].entry.id, { permanent: true });
}); });
it('should delete also the node created inside an already existing folder from destination', () => { it('should delete also the node created inside an already existing folder from destination', () => {
const spyOnDeleteNode = spyOn(nodesApiService, 'deleteNode').and.returnValue(Observable.of(null)); const spyOnDeleteNode = spyOn(contentApi, 'deleteNode').and.returnValue(Observable.of(null));
component.selection = [ component.selection = [
{ entry: { id: 'node-to-copy-1', name: 'name1' } }, { entry: { id: 'node-to-copy-1', name: 'name1' } },
@@ -277,7 +279,7 @@ describe('NodeCopyDirective', () => {
}); });
it('notifies when error occurs on Undo action', () => { it('notifies when error occurs on Undo action', () => {
spyOn(nodesApiService, 'deleteNode').and.returnValue(Observable.throw(null)); spyOn(contentApi, 'deleteNode').and.returnValue(Observable.throw(null));
component.selection = [{ entry: { id: 'node-to-copy-id', name: 'name' } }]; component.selection = [{ entry: { id: 'node-to-copy-id', name: 'name' } }];
const createdItems = [{ entry: { id: 'copy-id', name: 'name' } }]; const createdItems = [{ entry: { id: 'copy-id', name: 'name' } }];
@@ -287,14 +289,14 @@ describe('NodeCopyDirective', () => {
service.contentCopied.next(<any>createdItems); service.contentCopied.next(<any>createdItems);
expect(service.copyNodes).toHaveBeenCalled(); expect(service.copyNodes).toHaveBeenCalled();
expect(nodesApiService.deleteNode).toHaveBeenCalled(); expect(contentApi.deleteNode).toHaveBeenCalled();
expect(notificationService.openSnackMessageAction['calls'].allArgs()) expect(notificationService.openSnackMessageAction['calls'].allArgs())
.toEqual([['APP.MESSAGES.INFO.NODE_COPY.SINGULAR', 'APP.ACTIONS.UNDO', 10000], .toEqual([['APP.MESSAGES.INFO.NODE_COPY.SINGULAR', 'APP.ACTIONS.UNDO', 10000],
['APP.MESSAGES.ERRORS.GENERIC', '', 3000]]); ['APP.MESSAGES.ERRORS.GENERIC', '', 3000]]);
}); });
it('notifies when some error of type Error occurs on Undo action', () => { it('notifies when some error of type Error occurs on Undo action', () => {
spyOn(nodesApiService, 'deleteNode').and.returnValue(Observable.throw(new Error('oops!'))); spyOn(contentApi, 'deleteNode').and.returnValue(Observable.throw(new Error('oops!')));
component.selection = [{ entry: { id: 'node-to-copy-id', name: 'name' } }]; component.selection = [{ entry: { id: 'node-to-copy-id', name: 'name' } }];
const createdItems = [{ entry: { id: 'copy-id', name: 'name' } }]; const createdItems = [{ entry: { id: 'copy-id', name: 'name' } }];
@@ -304,14 +306,14 @@ describe('NodeCopyDirective', () => {
service.contentCopied.next(<any>createdItems); service.contentCopied.next(<any>createdItems);
expect(service.copyNodes).toHaveBeenCalled(); expect(service.copyNodes).toHaveBeenCalled();
expect(nodesApiService.deleteNode).toHaveBeenCalled(); expect(contentApi.deleteNode).toHaveBeenCalled();
expect(notificationService.openSnackMessageAction['calls'].allArgs()) expect(notificationService.openSnackMessageAction['calls'].allArgs())
.toEqual([['APP.MESSAGES.INFO.NODE_COPY.SINGULAR', 'APP.ACTIONS.UNDO', 10000], .toEqual([['APP.MESSAGES.INFO.NODE_COPY.SINGULAR', 'APP.ACTIONS.UNDO', 10000],
['APP.MESSAGES.ERRORS.GENERIC', '', 3000]]); ['APP.MESSAGES.ERRORS.GENERIC', '', 3000]]);
}); });
it('notifies permission error when it occurs on Undo action', () => { it('notifies permission error when it occurs on Undo action', () => {
spyOn(nodesApiService, 'deleteNode').and.returnValue(Observable.throw(new Error(JSON.stringify({error: {statusCode: 403}})))); spyOn(contentApi, 'deleteNode').and.returnValue(Observable.throw(new Error(JSON.stringify({error: {statusCode: 403}}))));
component.selection = [{ entry: { id: 'node-to-copy-id', name: 'name' } }]; component.selection = [{ entry: { id: 'node-to-copy-id', name: 'name' } }];
const createdItems = [{ entry: { id: 'copy-id', name: 'name' } }]; const createdItems = [{ entry: { id: 'copy-id', name: 'name' } }];
@@ -321,7 +323,7 @@ describe('NodeCopyDirective', () => {
service.contentCopied.next(<any>createdItems); service.contentCopied.next(<any>createdItems);
expect(service.copyNodes).toHaveBeenCalled(); expect(service.copyNodes).toHaveBeenCalled();
expect(nodesApiService.deleteNode).toHaveBeenCalled(); expect(contentApi.deleteNode).toHaveBeenCalled();
expect(notificationService.openSnackMessageAction['calls'].allArgs()) expect(notificationService.openSnackMessageAction['calls'].allArgs())
.toEqual([['APP.MESSAGES.INFO.NODE_COPY.SINGULAR', 'APP.ACTIONS.UNDO', 10000], .toEqual([['APP.MESSAGES.INFO.NODE_COPY.SINGULAR', 'APP.ACTIONS.UNDO', 10000],
['APP.MESSAGES.ERRORS.PERMISSION', '', 3000]]); ['APP.MESSAGES.ERRORS.PERMISSION', '', 3000]]);

View File

@@ -26,10 +26,11 @@
import { Directive, HostListener, Input } from '@angular/core'; import { Directive, HostListener, Input } from '@angular/core';
import { Observable } from 'rxjs/Rx'; import { Observable } from 'rxjs/Rx';
import { TranslationService, NodesApiService, NotificationService } from '@alfresco/adf-core'; import { TranslationService, NotificationService } from '@alfresco/adf-core';
import { MinimalNodeEntity } from 'alfresco-js-api'; import { MinimalNodeEntity } from 'alfresco-js-api';
import { NodeActionsService } from '../services/node-actions.service'; import { NodeActionsService } from '../services/node-actions.service';
import { ContentManagementService } from '../services/content-management.service'; import { ContentManagementService } from '../services/content-management.service';
import { ContentApiService } from '../../services/content-api.service';
@Directive({ @Directive({
selector: '[acaCopyNode]' selector: '[acaCopyNode]'
@@ -47,9 +48,9 @@ export class NodeCopyDirective {
constructor( constructor(
private content: ContentManagementService, private content: ContentManagementService,
private contentApi: ContentApiService,
private notification: NotificationService, private notification: NotificationService,
private nodeActionsService: NodeActionsService, private nodeActionsService: NodeActionsService,
private nodesApi: NodesApiService,
private translation: TranslationService private translation: TranslationService
) {} ) {}
@@ -117,7 +118,7 @@ export class NodeCopyDirective {
private deleteCopy(nodes: MinimalNodeEntity[]) { private deleteCopy(nodes: MinimalNodeEntity[]) {
const batch = this.nodeActionsService.flatten(nodes) const batch = this.nodeActionsService.flatten(nodes)
.filter(item => item.entry) .filter(item => item.entry)
.map(item => this.nodesApi.deleteNode(item.entry.id, { permanent: true })); .map(item => this.contentApi.deleteNode(item.entry.id, { permanent: true }));
Observable.forkJoin(...batch) Observable.forkJoin(...batch)
.subscribe( .subscribe(

View File

@@ -25,7 +25,6 @@
import { TestBed, ComponentFixture, fakeAsync, tick } from '@angular/core/testing'; import { TestBed, ComponentFixture, fakeAsync, tick } from '@angular/core/testing';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { AlfrescoApiService } from '@alfresco/adf-core';
import { Component, DebugElement } from '@angular/core'; import { Component, DebugElement } from '@angular/core';
import { NodeDeleteDirective } from './node-delete.directive'; import { NodeDeleteDirective } from './node-delete.directive';
@@ -37,6 +36,8 @@ import {
} from '../../store/actions'; } from '../../store/actions';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { AppTestingModule } from '../../testing/app-testing.module'; import { AppTestingModule } from '../../testing/app-testing.module';
import { ContentApiService } from '../../services/content-api.service';
import { Observable } from 'rxjs/Rx';
@Component({ @Component({
template: '<div [acaDeleteNode]="selection"></div>' template: '<div [acaDeleteNode]="selection"></div>'
@@ -49,8 +50,8 @@ describe('NodeDeleteDirective', () => {
let component: TestComponent; let component: TestComponent;
let fixture: ComponentFixture<TestComponent>; let fixture: ComponentFixture<TestComponent>;
let element: DebugElement; let element: DebugElement;
let alfrescoApiService: AlfrescoApiService;
let actions$: Actions; let actions$: Actions;
let contentApi: ContentApiService;
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
@@ -64,9 +65,7 @@ describe('NodeDeleteDirective', () => {
] ]
}); });
alfrescoApiService = TestBed.get(AlfrescoApiService); contentApi = TestBed.get(ContentApiService);
alfrescoApiService.reset();
actions$ = TestBed.get(Actions); actions$ = TestBed.get(Actions);
fixture = TestBed.createComponent(TestComponent); fixture = TestBed.createComponent(TestComponent);
@@ -76,7 +75,7 @@ describe('NodeDeleteDirective', () => {
describe('Delete action', () => { describe('Delete action', () => {
it('should raise info message on successful single file deletion', fakeAsync(done => { it('should raise info message on successful single file deletion', fakeAsync(done => {
spyOn(alfrescoApiService.nodesApi, 'deleteNode').and.returnValue(Promise.resolve(null)); spyOn(contentApi, 'deleteNode').and.returnValue(Observable.of(null));
actions$.pipe( actions$.pipe(
ofType<SnackbarInfoAction>(SNACKBAR_INFO), ofType<SnackbarInfoAction>(SNACKBAR_INFO),
@@ -94,7 +93,7 @@ describe('NodeDeleteDirective', () => {
})); }));
it('should raise error message on failed single file deletion', fakeAsync(done => { it('should raise error message on failed single file deletion', fakeAsync(done => {
spyOn(alfrescoApiService.nodesApi, 'deleteNode').and.returnValue(Promise.reject(null)); spyOn(contentApi, 'deleteNode').and.returnValue(Observable.throw(null));
actions$.pipe( actions$.pipe(
ofType<SnackbarErrorAction>(SNACKBAR_ERROR), ofType<SnackbarErrorAction>(SNACKBAR_ERROR),
@@ -112,7 +111,7 @@ describe('NodeDeleteDirective', () => {
})); }));
it('should raise info message on successful multiple files deletion', fakeAsync(done => { it('should raise info message on successful multiple files deletion', fakeAsync(done => {
spyOn(alfrescoApiService.nodesApi, 'deleteNode').and.returnValue(Promise.resolve(null)); spyOn(contentApi, 'deleteNode').and.returnValue(Observable.of(null));
actions$.pipe( actions$.pipe(
ofType<SnackbarInfoAction>(SNACKBAR_INFO), ofType<SnackbarInfoAction>(SNACKBAR_INFO),
@@ -133,7 +132,7 @@ describe('NodeDeleteDirective', () => {
})); }));
it('should raise error message failed multiple files deletion', fakeAsync(done => { it('should raise error message failed multiple files deletion', fakeAsync(done => {
spyOn(alfrescoApiService.nodesApi, 'deleteNode').and.returnValue(Promise.reject(null)); spyOn(contentApi, 'deleteNode').and.returnValue(Observable.throw(null));
actions$.pipe( actions$.pipe(
ofType<SnackbarErrorAction>(SNACKBAR_ERROR), ofType<SnackbarErrorAction>(SNACKBAR_ERROR),
@@ -154,11 +153,11 @@ describe('NodeDeleteDirective', () => {
})); }));
it('should raise warning message when only one file is successful', fakeAsync(done => { it('should raise warning message when only one file is successful', fakeAsync(done => {
spyOn(alfrescoApiService.nodesApi, 'deleteNode').and.callFake((id) => { spyOn(contentApi, 'deleteNode').and.callFake((id) => {
if (id === '1') { if (id === '1') {
return Promise.reject(null); return Observable.throw(null);
} else { } else {
return Promise.resolve(null); return Observable.of(null);
} }
}); });
@@ -181,17 +180,17 @@ describe('NodeDeleteDirective', () => {
})); }));
it('should raise warning message when some files are successfully deleted', fakeAsync(done => { it('should raise warning message when some files are successfully deleted', fakeAsync(done => {
spyOn(alfrescoApiService.nodesApi, 'deleteNode').and.callFake((id) => { spyOn(contentApi, 'deleteNode').and.callFake((id) => {
if (id === '1') { if (id === '1') {
return Promise.reject(null); return Observable.throw(null);
} }
if (id === '2') { if (id === '2') {
return Promise.resolve(null); return Observable.of(null);
} }
if (id === '3') { if (id === '3') {
return Promise.resolve(null); return Observable.of(null);
} }
}); });

View File

@@ -27,7 +27,7 @@ import { Component, DebugElement } from '@angular/core';
import { ComponentFixture, TestBed, fakeAsync } from '@angular/core/testing'; import { ComponentFixture, TestBed, fakeAsync } from '@angular/core/testing';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { Observable } from 'rxjs/Rx'; import { Observable } from 'rxjs/Rx';
import { NodesApiService, NotificationService, TranslationService } from '@alfresco/adf-core'; import { NotificationService, TranslationService } from '@alfresco/adf-core';
import { NodeActionsService } from '../services/node-actions.service'; import { NodeActionsService } from '../services/node-actions.service';
import { NodeMoveDirective } from './node-move.directive'; import { NodeMoveDirective } from './node-move.directive';
import { EffectsModule, Actions, ofType } from '@ngrx/effects'; import { EffectsModule, Actions, ofType } from '@ngrx/effects';
@@ -35,6 +35,7 @@ import { NodeEffects } from '../../store/effects/node.effects';
import { SnackbarErrorAction, SNACKBAR_ERROR } from '../../store/actions'; import { SnackbarErrorAction, SNACKBAR_ERROR } from '../../store/actions';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { AppTestingModule } from '../../testing/app-testing.module'; import { AppTestingModule } from '../../testing/app-testing.module';
import { ContentApiService } from '../../services/content-api.service';
@Component({ @Component({
template: '<div [acaMoveNode]="selection"></div>' template: '<div [acaMoveNode]="selection"></div>'
@@ -48,10 +49,10 @@ describe('NodeMoveDirective', () => {
let component: TestComponent; let component: TestComponent;
let element: DebugElement; let element: DebugElement;
let notificationService: NotificationService; let notificationService: NotificationService;
let nodesApiService: NodesApiService;
let service: NodeActionsService; let service: NodeActionsService;
let actions$: Actions; let actions$: Actions;
let translationService: TranslationService; let translationService: TranslationService;
let contentApi: ContentApiService;
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
@@ -65,6 +66,7 @@ describe('NodeMoveDirective', () => {
] ]
}); });
contentApi = TestBed.get(ContentApiService);
translationService = TestBed.get(TranslationService); translationService = TestBed.get(TranslationService);
actions$ = TestBed.get(Actions); actions$ = TestBed.get(Actions);
@@ -72,7 +74,6 @@ describe('NodeMoveDirective', () => {
component = fixture.componentInstance; component = fixture.componentInstance;
element = fixture.debugElement.query(By.directive(NodeMoveDirective)); element = fixture.debugElement.query(By.directive(NodeMoveDirective));
notificationService = TestBed.get(NotificationService); notificationService = TestBed.get(NotificationService);
nodesApiService = TestBed.get(NodesApiService);
service = TestBed.get(NodeActionsService); service = TestBed.get(NodeActionsService);
}); });
@@ -382,7 +383,7 @@ describe('NodeMoveDirective', () => {
it('should restore deleted folder back to initial parent, after succeeded moving all its files', () => { it('should restore deleted folder back to initial parent, after succeeded moving all its files', () => {
// when folder was deleted after all its children were moved to a folder with the same name from destination // when folder was deleted after all its children were moved to a folder with the same name from destination
spyOn(nodesApiService, 'restoreNode').and.returnValue(Observable.of(null)); spyOn(contentApi, 'restoreNode').and.returnValue(Observable.of(null));
const initialParent = 'parent-id-0'; const initialParent = 'parent-id-0';
const node = { entry: { id: 'folder-to-move-id', name: 'conflicting-name', parentId: initialParent, isFolder: true } }; const node = { entry: { id: 'folder-to-move-id', name: 'conflicting-name', parentId: initialParent, isFolder: true } };
@@ -401,13 +402,13 @@ describe('NodeMoveDirective', () => {
element.triggerEventHandler('click', null); element.triggerEventHandler('click', null);
service.contentMoved.next(<any>movedItems); service.contentMoved.next(<any>movedItems);
expect(nodesApiService.restoreNode).toHaveBeenCalled(); expect(contentApi.restoreNode).toHaveBeenCalled();
expect(notificationService.openSnackMessageAction) expect(notificationService.openSnackMessageAction)
.toHaveBeenCalledWith('APP.MESSAGES.INFO.NODE_MOVE.SINGULAR', 'APP.ACTIONS.UNDO', 10000); .toHaveBeenCalledWith('APP.MESSAGES.INFO.NODE_MOVE.SINGULAR', 'APP.ACTIONS.UNDO', 10000);
}); });
it('should notify when error occurs on Undo Move action', fakeAsync(done => { it('should notify when error occurs on Undo Move action', fakeAsync(done => {
spyOn(nodesApiService, 'restoreNode').and.returnValue(Observable.throw(null)); spyOn(contentApi, 'restoreNode').and.returnValue(Observable.throw(null));
actions$.pipe( actions$.pipe(
ofType<SnackbarErrorAction>(SNACKBAR_ERROR), ofType<SnackbarErrorAction>(SNACKBAR_ERROR),
@@ -432,11 +433,11 @@ describe('NodeMoveDirective', () => {
element.triggerEventHandler('click', null); element.triggerEventHandler('click', null);
service.contentMoved.next(<any>movedItems); service.contentMoved.next(<any>movedItems);
expect(nodesApiService.restoreNode).toHaveBeenCalled(); expect(contentApi.restoreNode).toHaveBeenCalled();
})); }));
it('should notify when some error of type Error occurs on Undo Move action', fakeAsync(done => { it('should notify when some error of type Error occurs on Undo Move action', fakeAsync(done => {
spyOn(nodesApiService, 'restoreNode').and.returnValue(Observable.throw(new Error('oops!'))); spyOn(contentApi, 'restoreNode').and.returnValue(Observable.throw(new Error('oops!')));
actions$.pipe( actions$.pipe(
ofType<SnackbarErrorAction>(SNACKBAR_ERROR), ofType<SnackbarErrorAction>(SNACKBAR_ERROR),
@@ -460,11 +461,11 @@ describe('NodeMoveDirective', () => {
element.triggerEventHandler('click', null); element.triggerEventHandler('click', null);
service.contentMoved.next(<any>movedItems); service.contentMoved.next(<any>movedItems);
expect(nodesApiService.restoreNode).toHaveBeenCalled(); expect(contentApi.restoreNode).toHaveBeenCalled();
})); }));
it('should notify permission error when it occurs on Undo Move action', fakeAsync(done => { it('should notify permission error when it occurs on Undo Move action', fakeAsync(done => {
spyOn(nodesApiService, 'restoreNode').and.returnValue(Observable.throw(new Error(JSON.stringify({error: {statusCode: 403}})))); spyOn(contentApi, 'restoreNode').and.returnValue(Observable.throw(new Error(JSON.stringify({error: {statusCode: 403}}))));
actions$.pipe( actions$.pipe(
ofType<SnackbarErrorAction>(SNACKBAR_ERROR), ofType<SnackbarErrorAction>(SNACKBAR_ERROR),
@@ -489,7 +490,7 @@ describe('NodeMoveDirective', () => {
service.contentMoved.next(<any>movedItems); service.contentMoved.next(<any>movedItems);
expect(service.moveNodes).toHaveBeenCalled(); expect(service.moveNodes).toHaveBeenCalled();
expect(nodesApiService.restoreNode).toHaveBeenCalled(); expect(contentApi.restoreNode).toHaveBeenCalled();
})); }));
}); });

View File

@@ -25,7 +25,7 @@
import { Directive, HostListener, Input } from '@angular/core'; import { Directive, HostListener, Input } from '@angular/core';
import { TranslationService, NodesApiService, NotificationService } from '@alfresco/adf-core'; import { TranslationService, NotificationService } from '@alfresco/adf-core';
import { MinimalNodeEntity } from 'alfresco-js-api'; import { MinimalNodeEntity } from 'alfresco-js-api';
import { ContentManagementService } from '../services/content-management.service'; import { ContentManagementService } from '../services/content-management.service';
@@ -34,6 +34,7 @@ import { Observable } from 'rxjs/Rx';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AppStore } from '../../store/states/app.state'; import { AppStore } from '../../store/states/app.state';
import { SnackbarErrorAction } from '../../store/actions'; import { SnackbarErrorAction } from '../../store/actions';
import { ContentApiService } from '../../services/content-api.service';
@Directive({ @Directive({
selector: '[acaMoveNode]' selector: '[acaMoveNode]'
@@ -51,10 +52,10 @@ export class NodeMoveDirective {
constructor( constructor(
private store: Store<AppStore>, private store: Store<AppStore>,
private contentApi: ContentApiService,
private content: ContentManagementService, private content: ContentManagementService,
private notification: NotificationService, private notification: NotificationService,
private nodeActionsService: NodeActionsService, private nodeActionsService: NodeActionsService,
private nodesApi: NodesApiService,
private translation: TranslationService private translation: TranslationService
) {} ) {}
@@ -173,7 +174,9 @@ export class NodeMoveDirective {
const restoreDeletedNodesBatch = this.nodeActionsService.moveDeletedEntries const restoreDeletedNodesBatch = this.nodeActionsService.moveDeletedEntries
.map((folderEntry) => { .map((folderEntry) => {
return this.nodesApi.restoreNode(folderEntry.nodeId || folderEntry.id); return this.contentApi
.restoreNode(folderEntry.nodeId || folderEntry.id)
.map(node => node.entry);
}); });
Observable.zip(...restoreDeletedNodesBatch, Observable.of(null)) Observable.zip(...restoreDeletedNodesBatch, Observable.of(null))

View File

@@ -27,7 +27,6 @@ import { Component, DebugElement } from '@angular/core';
import { TestBed, ComponentFixture, fakeAsync, tick } from '@angular/core/testing'; import { TestBed, ComponentFixture, fakeAsync, tick } from '@angular/core/testing';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { Observable } from 'rxjs/Rx'; import { Observable } from 'rxjs/Rx';
import { AlfrescoApiService } from '@alfresco/adf-core';
import { NodePermanentDeleteDirective } from './node-permanent-delete.directive'; import { NodePermanentDeleteDirective } from './node-permanent-delete.directive';
import { MatDialog } from '@angular/material'; import { MatDialog } from '@angular/material';
@@ -39,6 +38,7 @@ import {
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { NodeEffects } from '../../store/effects/node.effects'; import { NodeEffects } from '../../store/effects/node.effects';
import { AppTestingModule } from '../../testing/app-testing.module'; import { AppTestingModule } from '../../testing/app-testing.module';
import { ContentApiService } from '../../services/content-api.service';
@Component({ @Component({
template: `<div [acaPermanentDelete]="selection"></div>` template: `<div [acaPermanentDelete]="selection"></div>`
@@ -51,9 +51,9 @@ describe('NodePermanentDeleteDirective', () => {
let fixture: ComponentFixture<TestComponent>; let fixture: ComponentFixture<TestComponent>;
let element: DebugElement; let element: DebugElement;
let component: TestComponent; let component: TestComponent;
let alfrescoApiService: AlfrescoApiService;
let dialog: MatDialog; let dialog: MatDialog;
let actions$: Actions; let actions$: Actions;
let contentApi: ContentApiService;
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
@@ -67,9 +67,7 @@ describe('NodePermanentDeleteDirective', () => {
] ]
}); });
alfrescoApiService = TestBed.get(AlfrescoApiService); contentApi = TestBed.get(ContentApiService);
alfrescoApiService.reset();
actions$ = TestBed.get(Actions); actions$ = TestBed.get(Actions);
fixture = TestBed.createComponent(TestComponent); fixture = TestBed.createComponent(TestComponent);
@@ -85,18 +83,18 @@ describe('NodePermanentDeleteDirective', () => {
}); });
it('does not purge nodes if no selection', () => { it('does not purge nodes if no selection', () => {
spyOn(alfrescoApiService.nodesApi, 'purgeDeletedNode'); spyOn(contentApi, 'purgeDeletedNode');
component.selection = []; component.selection = [];
fixture.detectChanges(); fixture.detectChanges();
element.triggerEventHandler('click', null); element.triggerEventHandler('click', null);
expect(alfrescoApiService.nodesApi.purgeDeletedNode).not.toHaveBeenCalled(); expect(contentApi.purgeDeletedNode).not.toHaveBeenCalled();
}); });
it('call purge nodes if selection is not empty', fakeAsync(() => { it('call purge nodes if selection is not empty', fakeAsync(() => {
spyOn(alfrescoApiService.nodesApi, 'purgeDeletedNode').and.returnValue(Promise.resolve()); spyOn(contentApi, 'purgeDeletedNode').and.returnValue(Observable.of({}));
component.selection = [ { entry: { id: '1' } } ]; component.selection = [ { entry: { id: '1' } } ];
@@ -104,7 +102,7 @@ describe('NodePermanentDeleteDirective', () => {
element.triggerEventHandler('click', null); element.triggerEventHandler('click', null);
tick(); tick();
expect(alfrescoApiService.nodesApi.purgeDeletedNode).toHaveBeenCalled(); expect(contentApi.purgeDeletedNode).toHaveBeenCalled();
})); }));
describe('notification', () => { describe('notification', () => {
@@ -116,17 +114,17 @@ describe('NodePermanentDeleteDirective', () => {
}) })
); );
spyOn(alfrescoApiService.nodesApi, 'purgeDeletedNode').and.callFake((id) => { spyOn(contentApi, 'purgeDeletedNode').and.callFake((id) => {
if (id === '1') { if (id === '1') {
return Promise.resolve(); return Observable.of({});
} }
if (id === '2') { if (id === '2') {
return Promise.reject({}); return Observable.throw({});
} }
if (id === '3') { if (id === '3') {
return Promise.reject({}); return Observable.throw({});
} }
}); });
@@ -149,21 +147,21 @@ describe('NodePermanentDeleteDirective', () => {
}) })
); );
spyOn(alfrescoApiService.nodesApi, 'purgeDeletedNode').and.callFake((id) => { spyOn(contentApi, 'purgeDeletedNode').and.callFake((id) => {
if (id === '1') { if (id === '1') {
return Promise.resolve(); return Observable.of({});
} }
if (id === '2') { if (id === '2') {
return Promise.reject({}); return Observable.throw({});
} }
if (id === '3') { if (id === '3') {
return Promise.reject({}); return Observable.throw({});
} }
if (id === '4') { if (id === '4') {
return Promise.resolve(); return Observable.of({});
} }
}); });
@@ -187,7 +185,7 @@ describe('NodePermanentDeleteDirective', () => {
}) })
); );
spyOn(alfrescoApiService.nodesApi, 'purgeDeletedNode').and.returnValue(Promise.resolve()); spyOn(contentApi, 'purgeDeletedNode').and.returnValue(Observable.of({}));
component.selection = [ component.selection = [
{ entry: { id: '1', name: 'name1' } } { entry: { id: '1', name: 'name1' } }
@@ -206,7 +204,7 @@ describe('NodePermanentDeleteDirective', () => {
}) })
); );
spyOn(alfrescoApiService.nodesApi, 'purgeDeletedNode').and.returnValue(Promise.reject({})); spyOn(contentApi, 'purgeDeletedNode').and.returnValue(Observable.throw({}));
component.selection = [ component.selection = [
{ entry: { id: '1', name: 'name1' } } { entry: { id: '1', name: 'name1' } }
@@ -224,13 +222,13 @@ describe('NodePermanentDeleteDirective', () => {
done(); done();
}) })
); );
spyOn(alfrescoApiService.nodesApi, 'purgeDeletedNode').and.callFake((id) => { spyOn(contentApi, 'purgeDeletedNode').and.callFake((id) => {
if (id === '1') { if (id === '1') {
return Promise.resolve(); return Observable.of({});
} }
if (id === '2') { if (id === '2') {
return Promise.resolve(); return Observable.of({});
} }
}); });
@@ -251,13 +249,13 @@ describe('NodePermanentDeleteDirective', () => {
done(); done();
}) })
); );
spyOn(alfrescoApiService.nodesApi, 'purgeDeletedNode').and.callFake((id) => { spyOn(contentApi, 'purgeDeletedNode').and.callFake((id) => {
if (id === '1') { if (id === '1') {
return Promise.reject({}); return Observable.throw({});
} }
if (id === '2') { if (id === '2') {
return Promise.reject({}); return Observable.throw({});
} }
}); });

View File

@@ -26,7 +26,6 @@
import { Component, DebugElement } from '@angular/core'; import { Component, DebugElement } from '@angular/core';
import { TestBed, ComponentFixture, fakeAsync, tick } from '@angular/core/testing'; import { TestBed, ComponentFixture, fakeAsync, tick } from '@angular/core/testing';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { AlfrescoApiService } from '@alfresco/adf-core';
import { NodeRestoreDirective } from './node-restore.directive'; import { NodeRestoreDirective } from './node-restore.directive';
import { ContentManagementService } from '../services/content-management.service'; import { ContentManagementService } from '../services/content-management.service';
import { Actions, ofType } from '@ngrx/effects'; import { Actions, ofType } from '@ngrx/effects';
@@ -35,6 +34,8 @@ import { SnackbarErrorAction,
NavigateRouteAction, NAVIGATE_ROUTE } from '../../store/actions'; NavigateRouteAction, NAVIGATE_ROUTE } from '../../store/actions';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { AppTestingModule } from '../../testing/app-testing.module'; import { AppTestingModule } from '../../testing/app-testing.module';
import { ContentApiService } from '../../services/content-api.service';
import { Observable } from 'rxjs/Rx';
@Component({ @Component({
template: `<div [acaRestoreNode]="selection"></div>` template: `<div [acaRestoreNode]="selection"></div>`
@@ -47,10 +48,10 @@ describe('NodeRestoreDirective', () => {
let fixture: ComponentFixture<TestComponent>; let fixture: ComponentFixture<TestComponent>;
let element: DebugElement; let element: DebugElement;
let component: TestComponent; let component: TestComponent;
let alfrescoService: AlfrescoApiService;
let directiveInstance: NodeRestoreDirective; let directiveInstance: NodeRestoreDirective;
let contentManagementService: ContentManagementService; let contentManagementService: ContentManagementService;
let actions$: Actions; let actions$: Actions;
let contentApi: ContentApiService;
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
@@ -63,43 +64,41 @@ describe('NodeRestoreDirective', () => {
actions$ = TestBed.get(Actions); actions$ = TestBed.get(Actions);
alfrescoService = TestBed.get(AlfrescoApiService);
alfrescoService.reset();
fixture = TestBed.createComponent(TestComponent); fixture = TestBed.createComponent(TestComponent);
component = fixture.componentInstance; component = fixture.componentInstance;
element = fixture.debugElement.query(By.directive(NodeRestoreDirective)); element = fixture.debugElement.query(By.directive(NodeRestoreDirective));
directiveInstance = element.injector.get(NodeRestoreDirective); directiveInstance = element.injector.get(NodeRestoreDirective);
contentManagementService = TestBed.get(ContentManagementService); contentManagementService = TestBed.get(ContentManagementService);
contentApi = TestBed.get(ContentApiService);
}); });
it('does not restore nodes if no selection', () => { it('does not restore nodes if no selection', () => {
spyOn(alfrescoService.nodesApi, 'restoreNode'); spyOn(contentApi, 'restoreNode');
component.selection = []; component.selection = [];
fixture.detectChanges(); fixture.detectChanges();
element.triggerEventHandler('click', null); element.triggerEventHandler('click', null);
expect(alfrescoService.nodesApi.restoreNode).not.toHaveBeenCalled(); expect(contentApi.restoreNode).not.toHaveBeenCalled();
}); });
it('does not restore nodes if selection has nodes without path', () => { it('does not restore nodes if selection has nodes without path', () => {
spyOn(alfrescoService.nodesApi, 'restoreNode'); spyOn(contentApi, 'restoreNode');
component.selection = [ { entry: { id: '1' } } ]; component.selection = [ { entry: { id: '1' } } ];
fixture.detectChanges(); fixture.detectChanges();
element.triggerEventHandler('click', null); element.triggerEventHandler('click', null);
expect(alfrescoService.nodesApi.restoreNode).not.toHaveBeenCalled(); expect(contentApi.restoreNode).not.toHaveBeenCalled();
}); });
it('call restore nodes if selection has nodes with path', fakeAsync(() => { it('call restore nodes if selection has nodes with path', fakeAsync(() => {
spyOn(directiveInstance, 'restoreNotification').and.callFake(() => null); spyOn(directiveInstance, 'restoreNotification').and.callFake(() => null);
spyOn(alfrescoService.nodesApi, 'restoreNode').and.returnValue(Promise.resolve()); spyOn(contentApi, 'restoreNode').and.returnValue(Observable.of({}));
spyOn(alfrescoService.nodesApi, 'getDeletedNodes').and.returnValue(Promise.resolve({ spyOn(contentApi, 'getDeletedNodes').and.returnValue(Observable.of({
list: { entries: [] } list: { entries: [] }
})); }));
@@ -109,14 +108,14 @@ describe('NodeRestoreDirective', () => {
element.triggerEventHandler('click', null); element.triggerEventHandler('click', null);
tick(); tick();
expect(alfrescoService.nodesApi.restoreNode).toHaveBeenCalled(); expect(contentApi.restoreNode).toHaveBeenCalled();
})); }));
describe('refresh()', () => { describe('refresh()', () => {
it('dispatch event on finish', fakeAsync(done => { it('dispatch event on finish', fakeAsync(done => {
spyOn(directiveInstance, 'restoreNotification').and.callFake(() => null); spyOn(directiveInstance, 'restoreNotification').and.callFake(() => null);
spyOn(alfrescoService.nodesApi, 'restoreNode').and.returnValue(Promise.resolve()); spyOn(contentApi, 'restoreNode').and.returnValue(Observable.of({}));
spyOn(alfrescoService.nodesApi, 'getDeletedNodes').and.returnValue(Promise.resolve({ spyOn(contentApi, 'getDeletedNodes').and.returnValue(Observable.of({
list: { entries: [] } list: { entries: [] }
})); }));
@@ -132,7 +131,7 @@ describe('NodeRestoreDirective', () => {
describe('notification', () => { describe('notification', () => {
beforeEach(() => { beforeEach(() => {
spyOn(alfrescoService.nodesApi, 'getDeletedNodes').and.returnValue(Promise.resolve({ spyOn(contentApi, 'getDeletedNodes').and.returnValue(Observable.of({
list: { entries: [] } list: { entries: [] }
})); }));
}); });
@@ -145,17 +144,17 @@ describe('NodeRestoreDirective', () => {
map(action => done()) map(action => done())
); );
spyOn(alfrescoService.nodesApi, 'restoreNode').and.callFake((id) => { spyOn(contentApi, 'restoreNode').and.callFake((id) => {
if (id === '1') { if (id === '1') {
return Promise.resolve(); return Observable.of({});
} }
if (id === '2') { if (id === '2') {
return Promise.reject(error); return Observable.throw(error);
} }
if (id === '3') { if (id === '3') {
return Promise.reject(error); return Observable.throw(error);
} }
}); });
@@ -172,7 +171,7 @@ describe('NodeRestoreDirective', () => {
it('should raise error message when restored node exist, error 409', fakeAsync(done => { it('should raise error message when restored node exist, error 409', fakeAsync(done => {
const error = { message: '{ "error": { "statusCode": 409 } }' }; const error = { message: '{ "error": { "statusCode": 409 } }' };
spyOn(alfrescoService.nodesApi, 'restoreNode').and.returnValue(Promise.reject(error)); spyOn(contentApi, 'restoreNode').and.returnValue(Observable.throw(error));
actions$.pipe( actions$.pipe(
ofType<SnackbarErrorAction>(SNACKBAR_ERROR), ofType<SnackbarErrorAction>(SNACKBAR_ERROR),
@@ -191,7 +190,7 @@ describe('NodeRestoreDirective', () => {
it('should raise error message when restored node returns different statusCode', fakeAsync(done => { it('should raise error message when restored node returns different statusCode', fakeAsync(done => {
const error = { message: '{ "error": { "statusCode": 404 } }' }; const error = { message: '{ "error": { "statusCode": 404 } }' };
spyOn(alfrescoService.nodesApi, 'restoreNode').and.returnValue(Promise.reject(error)); spyOn(contentApi, 'restoreNode').and.returnValue(Observable.throw(error));
actions$.pipe( actions$.pipe(
ofType<SnackbarErrorAction>(SNACKBAR_ERROR), ofType<SnackbarErrorAction>(SNACKBAR_ERROR),
@@ -210,7 +209,7 @@ describe('NodeRestoreDirective', () => {
it('should raise error message when restored node location is missing', fakeAsync(done => { it('should raise error message when restored node location is missing', fakeAsync(done => {
const error = { message: '{ "error": { } }' }; const error = { message: '{ "error": { } }' };
spyOn(alfrescoService.nodesApi, 'restoreNode').and.returnValue(Promise.reject(error)); spyOn(contentApi, 'restoreNode').and.returnValue(Observable.throw(error));
actions$.pipe( actions$.pipe(
ofType<SnackbarErrorAction>(SNACKBAR_ERROR), ofType<SnackbarErrorAction>(SNACKBAR_ERROR),
@@ -227,13 +226,13 @@ describe('NodeRestoreDirective', () => {
})); }));
it('should raise info message when restore multiple nodes', fakeAsync(done => { it('should raise info message when restore multiple nodes', fakeAsync(done => {
spyOn(alfrescoService.nodesApi, 'restoreNode').and.callFake((id) => { spyOn(contentApi, 'restoreNode').and.callFake((id) => {
if (id === '1') { if (id === '1') {
return Promise.resolve(); return Observable.of({});
} }
if (id === '2') { if (id === '2') {
return Promise.resolve(); return Observable.of({});
} }
}); });
@@ -253,7 +252,7 @@ describe('NodeRestoreDirective', () => {
})); }));
xit('should raise info message when restore selected node', fakeAsync(done => { xit('should raise info message when restore selected node', fakeAsync(done => {
spyOn(alfrescoService.nodesApi, 'restoreNode').and.returnValue(Promise.resolve()); spyOn(contentApi, 'restoreNode').and.returnValue(Observable.of({}));
actions$.pipe( actions$.pipe(
ofType<SnackbarInfoAction>(SNACKBAR_INFO), ofType<SnackbarInfoAction>(SNACKBAR_INFO),
@@ -270,7 +269,7 @@ describe('NodeRestoreDirective', () => {
})); }));
it('navigate to restore selected node location onAction', fakeAsync(done => { it('navigate to restore selected node location onAction', fakeAsync(done => {
spyOn(alfrescoService.nodesApi, 'restoreNode').and.returnValue(Promise.resolve()); spyOn(contentApi, 'restoreNode').and.returnValue(Observable.of({}));
actions$.pipe( actions$.pipe(
ofType<NavigateRouteAction>(NAVIGATE_ROUTE), ofType<NavigateRouteAction>(NAVIGATE_ROUTE),

View File

@@ -25,8 +25,6 @@
import { Directive, HostListener, Input } from '@angular/core'; import { Directive, HostListener, Input } from '@angular/core';
import { Observable } from 'rxjs/Rx'; import { Observable } from 'rxjs/Rx';
import { AlfrescoApiService } from '@alfresco/adf-core';
import { import {
MinimalNodeEntity, MinimalNodeEntity,
MinimalNodeEntryEntity, MinimalNodeEntryEntity,
@@ -44,6 +42,7 @@ import {
SnackbarInfoAction, SnackbarInfoAction,
SnackbarUserAction SnackbarUserAction
} from '../../store/actions'; } from '../../store/actions';
import { ContentApiService } from '../../services/content-api.service';
@Directive({ @Directive({
selector: '[acaRestoreNode]' selector: '[acaRestoreNode]'
@@ -59,7 +58,7 @@ export class NodeRestoreDirective {
constructor( constructor(
private store: Store<AppStore>, private store: Store<AppStore>,
private alfrescoApiService: AlfrescoApiService, private contentApi: ContentApiService,
private contentManagementService: ContentManagementService private contentManagementService: ContentManagementService
) {} ) {}
@@ -84,7 +83,7 @@ export class NodeRestoreDirective {
.do(restoredNodes => { .do(restoredNodes => {
status = this.processStatus(restoredNodes); status = this.processStatus(restoredNodes);
}) })
.flatMap(() => this.getDeletedNodes()) .flatMap(() => this.contentApi.getDeletedNodes())
.subscribe((nodes: DeletedNodesPaging) => { .subscribe((nodes: DeletedNodesPaging) => {
const selectedNodes = this.diff(status.fail, selection, false); const selectedNodes = this.diff(status.fail, selection, false);
const remainingNodes = this.diff( const remainingNodes = this.diff(
@@ -101,20 +100,10 @@ export class NodeRestoreDirective {
}); });
} }
private getDeletedNodes(): Observable<DeletedNodesPaging> {
return Observable.from(
this.alfrescoApiService.nodesApi.getDeletedNodes({
include: ['path']
})
);
}
private restoreNode(node: MinimalNodeEntity): Observable<any> { private restoreNode(node: MinimalNodeEntity): Observable<any> {
const { entry } = node; const { entry } = node;
return Observable.from( return this.contentApi.restoreNode(entry.id)
this.alfrescoApiService.nodesApi.restoreNode(entry.id)
)
.map(() => ({ .map(() => ({
status: 1, status: 1,
entry entry

View File

@@ -23,9 +23,10 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/ */
import { Directive, HostListener, Input, ElementRef } from '@angular/core'; import { Directive, HostListener, Input } from '@angular/core';
import { AlfrescoApiService } from '@alfresco/adf-core';
import { MinimalNodeEntity } from 'alfresco-js-api'; import { MinimalNodeEntity } from 'alfresco-js-api';
import { ContentManagementService } from '../services/content-management.service';
import { ContentApiService } from '../../services/content-api.service';
@Directive({ @Directive({
selector: '[acaUnshareNode]' selector: '[acaUnshareNode]'
@@ -37,8 +38,8 @@ export class NodeUnshareDirective {
selection: MinimalNodeEntity[]; selection: MinimalNodeEntity[];
constructor( constructor(
private apiService: AlfrescoApiService, private contentApi: ContentApiService,
private el: ElementRef) { private contentManagement: ContentManagementService) {
} }
@HostListener('click') @HostListener('click')
@@ -49,14 +50,8 @@ export class NodeUnshareDirective {
} }
private async unshareLinks(links: MinimalNodeEntity[]) { private async unshareLinks(links: MinimalNodeEntity[]) {
const promises = links.map(link => this.apiService.sharedLinksApi.deleteSharedLink(link.entry.id)); const promises = links.map(link => this.contentApi.deleteSharedLink(link.entry.id).toPromise());
await Promise.all(promises); await Promise.all(promises);
this.emitDone(); this.contentManagement.linksUnshared.next();
} }
private emitDone() {
const e = new CustomEvent('links-unshared', { bubbles: true });
this.el.nativeElement.dispatchEvent(e);
}
} }

View File

@@ -24,15 +24,13 @@
*/ */
import { Directive, HostListener, Input } from '@angular/core'; import { Directive, HostListener, Input } from '@angular/core';
import { AlfrescoApiService } from '@alfresco/adf-core';
import { MinimalNodeEntity, MinimalNodeEntryEntity } from 'alfresco-js-api'; import { MinimalNodeEntity, MinimalNodeEntryEntity } from 'alfresco-js-api';
import { NodeVersionsDialogComponent } from '../../dialogs/node-versions/node-versions.dialog'; import { NodeVersionsDialogComponent } from '../../dialogs/node-versions/node-versions.dialog';
import { MatDialog } from '@angular/material'; import { MatDialog } from '@angular/material';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AppStore } from '../../store/states/app.state'; import { AppStore } from '../../store/states/app.state';
import { SnackbarErrorAction } from '../../store/actions'; import { SnackbarErrorAction } from '../../store/actions';
import { ContentApiService } from '../../services/content-api.service';
@Directive({ @Directive({
selector: '[acaNodeVersions]' selector: '[acaNodeVersions]'
@@ -48,7 +46,7 @@ export class NodeVersionsDirective {
constructor( constructor(
private store: Store<AppStore>, private store: Store<AppStore>,
private apiService: AlfrescoApiService, private contentApi: ContentApiService,
private dialog: MatDialog private dialog: MatDialog
) {} ) {}
@@ -57,10 +55,9 @@ export class NodeVersionsDirective {
let entry = this.node.entry; let entry = this.node.entry;
if (entry.nodeId || (<any>entry).guid) { if (entry.nodeId || (<any>entry).guid) {
entry = await this.apiService.nodesApi.getNodeInfo( entry = await this.contentApi.getNodeInfo(
entry.nodeId || (<any>entry).id, entry.nodeId || (<any>entry).id
{ include: ['allowableOperations'] } ).toPromise();
);
this.openVersionManagerDialog(entry); this.openVersionManagerDialog(entry);
} else { } else {
this.openVersionManagerDialog(entry); this.openVersionManagerDialog(entry);

View File

@@ -35,4 +35,5 @@ export class ContentManagementService {
folderEdited = new Subject<any>(); folderEdited = new Subject<any>();
folderCreated = new Subject<any>(); folderCreated = new Subject<any>();
siteDeleted = new Subject<string>(); siteDeleted = new Subject<string>();
linksUnshared = new Subject<any>();
} }

View File

@@ -24,21 +24,14 @@
*/ */
import { TestBed, async } from '@angular/core/testing'; import { TestBed, async } from '@angular/core/testing';
import { MatDialog, MatDialogModule, MatIconModule } from '@angular/material'; import { MatDialog } from '@angular/material';
import { OverlayModule } from '@angular/cdk/overlay';
import { Observable } from 'rxjs/Rx'; import { Observable } from 'rxjs/Rx';
import { import { AlfrescoApiService, TranslationService } from '@alfresco/adf-core';
TranslationMock, AlfrescoApiService, NodesApiService,
TranslationService, ContentService, AuthenticationService,
UserPreferencesService, AppConfigService, StorageService,
CookieService, LogService, ThumbnailService
} from '@alfresco/adf-core';
import { DocumentListService } from '@alfresco/adf-content-services'; import { DocumentListService } from '@alfresco/adf-content-services';
import { NodeActionsService } from './node-actions.service'; import { NodeActionsService } from './node-actions.service';
import { MinimalNodeEntryEntity } from 'alfresco-js-api'; import { MinimalNodeEntryEntity } from 'alfresco-js-api';
import { TranslateModule } from '@ngx-translate/core'; import { AppTestingModule } from '../../testing/app-testing.module';
import { HttpClientModule } from '@angular/common/http'; import { ContentApiService } from '../../services/content-api.service';
class TestNode { class TestNode {
entry?: MinimalNodeEntryEntity; entry?: MinimalNodeEntryEntity;
@@ -67,10 +60,10 @@ describe('NodeActionsService', () => {
const emptyChildrenList = {list: {entries: []}}; const emptyChildrenList = {list: {entries: []}};
let service: NodeActionsService; let service: NodeActionsService;
let apiService: AlfrescoApiService; let apiService: AlfrescoApiService;
let nodesApiService: NodesApiService;
let nodesApi; let nodesApi;
const spyOnSuccess = jasmine.createSpy('spyOnSuccess'); const spyOnSuccess = jasmine.createSpy('spyOnSuccess');
const spyOnError = jasmine.createSpy('spyOnError'); const spyOnError = jasmine.createSpy('spyOnError');
let contentApi: ContentApiService;
const helper = { const helper = {
fakeCopyNode: (isForbidden: boolean = false, nameExistingOnDestination?: string) => { fakeCopyNode: (isForbidden: boolean = false, nameExistingOnDestination?: string) => {
@@ -110,33 +103,16 @@ describe('NodeActionsService', () => {
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ imports: [
MatDialogModule, AppTestingModule
MatIconModule,
HttpClientModule,
TranslateModule.forRoot(),
OverlayModule
],
providers: [
AlfrescoApiService,
NodesApiService,
{ provide: TranslationService, useClass: TranslationMock },
AuthenticationService,
UserPreferencesService,
AppConfigService,
CookieService,
LogService,
ThumbnailService,
StorageService,
ContentService,
DocumentListService,
NodeActionsService
] ]
}); });
contentApi = TestBed.get(ContentApiService);
service = TestBed.get(NodeActionsService); service = TestBed.get(NodeActionsService);
apiService = TestBed.get(AlfrescoApiService); apiService = TestBed.get(AlfrescoApiService);
apiService.reset(); apiService.reset();
nodesApiService = TestBed.get(NodesApiService);
nodesApi = apiService.getInstance().nodes; nodesApi = apiService.getInstance().nodes;
}); });
@@ -884,7 +860,7 @@ describe('NodeActionsService', () => {
beforeEach(() => { beforeEach(() => {
parentFolderToMove = new TestNode('parent-folder', !isFile, 'conflicting-name'); parentFolderToMove = new TestNode('parent-folder', !isFile, 'conflicting-name');
spyOnDelete = spyOn(nodesApiService, 'deleteNode').and.returnValue(Observable.of(null)); spyOnDelete = spyOn(contentApi, 'deleteNode').and.returnValue(Observable.of(null));
}); });
afterEach(() => { afterEach(() => {

View File

@@ -27,9 +27,10 @@ import { Injectable } from '@angular/core';
import { MatDialog } from '@angular/material'; import { MatDialog } from '@angular/material';
import { Observable, Subject } from 'rxjs/Rx'; import { Observable, Subject } from 'rxjs/Rx';
import { AlfrescoApiService, ContentService, NodesApiService, DataColumn, TranslationService } from '@alfresco/adf-core'; import { AlfrescoApiService, ContentService, DataColumn, TranslationService } from '@alfresco/adf-core';
import { DocumentListService, ContentNodeSelectorComponent, ContentNodeSelectorComponentData } from '@alfresco/adf-content-services'; import { DocumentListService, ContentNodeSelectorComponent, ContentNodeSelectorComponentData } from '@alfresco/adf-content-services';
import { MinimalNodeEntity, MinimalNodeEntryEntity, SitePaging } from 'alfresco-js-api'; import { MinimalNodeEntity, MinimalNodeEntryEntity, SitePaging } from 'alfresco-js-api';
import { ContentApiService } from '../../services/content-api.service';
@Injectable() @Injectable()
export class NodeActionsService { export class NodeActionsService {
@@ -42,10 +43,10 @@ export class NodeActionsService {
isSitesDestinationAvailable = false; isSitesDestinationAvailable = false;
constructor(private contentService: ContentService, constructor(private contentService: ContentService,
private contentApi: ContentApiService,
private dialog: MatDialog, private dialog: MatDialog,
private documentListService: DocumentListService, private documentListService: DocumentListService,
private apiService: AlfrescoApiService, private apiService: AlfrescoApiService,
private nodesApi: NodesApiService,
private translation: TranslationService) {} private translation: TranslationService) {}
/** /**
@@ -422,7 +423,7 @@ export class NodeActionsService {
// Check if there's nodeId for Shared Files // Check if there's nodeId for Shared Files
const nodeEntryId = nodeEntry.nodeId || nodeEntry.id; const nodeEntryId = nodeEntry.nodeId || nodeEntry.id;
// delete it from location // delete it from location
return this.nodesApi.deleteNode(nodeEntryId) return this.contentApi.deleteNode(nodeEntryId)
.flatMap(() => { .flatMap(() => {
this.moveDeletedEntries.push(nodeEntry); this.moveDeletedEntries.push(nodeEntry);
return Observable.of(newContent); return Observable.of(newContent);

View File

@@ -26,31 +26,26 @@
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Resolve } from '@angular/router'; import { Resolve } from '@angular/router';
import { Person } from 'alfresco-js-api';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs/Observable';
import { AppStore } from '../../store/states/app.state'; import { AppStore } from '../../store/states/app.state';
import { SetUserAction } from '../../store/actions/user.actions'; import { SetUserAction } from '../../store/actions/user.actions';
import { selectUser } from '../../store/selectors/app.selectors'; import { ContentApiService } from '../../services/content-api.service';
import { PeopleContentService } from '@alfresco/adf-core';
@Injectable() @Injectable()
export class ProfileResolver implements Resolve<any> { export class ProfileResolver implements Resolve<Person> {
constructor(private store: Store<AppStore>, private peopleApi: PeopleContentService) { } constructor(
private store: Store<AppStore>,
private contentApi: ContentApiService
) {}
resolve(): Observable<any> { resolve(): Observable<Person> {
return new Observable(observer => {
this.init(); this.contentApi.getPerson('-me-').subscribe(person => {
return this.profileLoaded();
}
profileLoaded(): Observable<any> {
return this.store.select(selectUser).take(1);
}
init(): void {
this.peopleApi.getCurrentPerson().subscribe((person: any) => {
this.store.dispatch(new SetUserAction(person.entry)); this.store.dispatch(new SetUserAction(person.entry));
observer.next(person.entry);
observer.complete();
});
}); });
} }
} }

View File

@@ -1,9 +1,9 @@
<div class="inner-layout inner-layout--scroll"> <div class="inner-layout inner-layout--scroll">
<div class="inner-layout__content"> <div class="inner-layout__content">
<div class="inner-layout__panel content--scroll"> <div class="inner-layout__panel content--scroll">
<article *ngIf="ecmVersion" class="padding"> <article *ngIf="repository" class="padding">
<header class="header padding-left">Alfresco Content Services</header> <header class="header padding-left">Alfresco Content Services</header>
<p class="padding-left"> version: {{ ecmVersion.edition }} {{ ecmVersion.version.display }} </p> <p class="padding-left"> version: {{ repository.edition }} {{ repository.version.display }} </p>
</article> </article>
<article class="padding-top-bottom"> <article class="padding-top-bottom">

View File

@@ -25,15 +25,16 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { Http } from '@angular/http'; import { Http } from '@angular/http';
import { DiscoveryApiService } from '@alfresco/adf-core'; import { ObjectDataTableAdapter } from '@alfresco/adf-core';
import { EcmProductVersionModel, ObjectDataTableAdapter } from '@alfresco/adf-core'; import { ContentApiService } from '../../services/content-api.service';
import { RepositoryInfo } from 'alfresco-js-api';
@Component({ @Component({
selector: 'app-about', selector: 'app-about',
templateUrl: './about.component.html' templateUrl: './about.component.html'
}) })
export class AboutComponent implements OnInit { export class AboutComponent implements OnInit {
ecmVersion: EcmProductVersionModel = null; repository: RepositoryInfo;
data: ObjectDataTableAdapter; data: ObjectDataTableAdapter;
status: ObjectDataTableAdapter; status: ObjectDataTableAdapter;
license: ObjectDataTableAdapter; license: ObjectDataTableAdapter;
@@ -42,15 +43,17 @@ export class AboutComponent implements OnInit {
releaseVersion = ''; releaseVersion = '';
constructor( constructor(
private discovery: DiscoveryApiService, private contentApi: ContentApiService,
private http: Http private http: Http
) {} ) {}
ngOnInit() { ngOnInit() {
this.discovery.getEcmProductInfo().subscribe((ecmVers) => { this.contentApi.getRepositoryInformation()
this.ecmVersion = ecmVers; .map(node => node.entry.repository)
.subscribe(repository => {
this.repository = repository;
this.modules = new ObjectDataTableAdapter(this.ecmVersion.modules, [ this.modules = new ObjectDataTableAdapter(repository.modules, [
{type: 'text', key: 'id', title: 'ID', sortable: true}, {type: 'text', key: 'id', title: 'ID', sortable: true},
{type: 'text', key: 'title', title: 'Title', sortable: true}, {type: 'text', key: 'title', title: 'Title', sortable: true},
{type: 'text', key: 'version', title: 'Description', sortable: true}, {type: 'text', key: 'version', title: 'Description', sortable: true},
@@ -60,14 +63,14 @@ export class AboutComponent implements OnInit {
{type: 'text', key: 'versionMax', title: 'Version Max', sortable: true} {type: 'text', key: 'versionMax', title: 'Version Max', sortable: true}
]); ]);
this.status = new ObjectDataTableAdapter([this.ecmVersion.status], [ this.status = new ObjectDataTableAdapter([repository.status], [
{type: 'text', key: 'isReadOnly', title: 'Read Only', sortable: true}, {type: 'text', key: 'isReadOnly', title: 'Read Only', sortable: true},
{type: 'text', key: 'isAuditEnabled', title: 'Audit Enable', sortable: true}, {type: 'text', key: 'isAuditEnabled', title: 'Audit Enable', sortable: true},
{type: 'text', key: 'isQuickShareEnabled', title: 'Quick Shared Enable', sortable: true}, {type: 'text', key: 'isQuickShareEnabled', title: 'Quick Shared Enable', sortable: true},
{type: 'text', key: 'isThumbnailGenerationEnabled', title: 'Thumbnail Generation', sortable: true} {type: 'text', key: 'isThumbnailGenerationEnabled', title: 'Thumbnail Generation', sortable: true}
]); ]);
this.license = new ObjectDataTableAdapter([this.ecmVersion.license], [ this.license = new ObjectDataTableAdapter([repository.license], [
{type: 'date', key: 'issuedAt', title: 'Issued At', sortable: true}, {type: 'date', key: 'issuedAt', title: 'Issued At', sortable: true},
{type: 'date', key: 'expiresAt', title: 'Expires At', sortable: true}, {type: 'date', key: 'expiresAt', title: 'Expires At', sortable: true},
{type: 'text', key: 'remainingDays', title: 'Remaining Days', sortable: true}, {type: 'text', key: 'remainingDays', title: 'Remaining Days', sortable: true},

View File

@@ -28,7 +28,6 @@ import { NO_ERRORS_SCHEMA } from '@angular/core';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { TestBed, ComponentFixture } from '@angular/core/testing'; import { TestBed, ComponentFixture } from '@angular/core/testing';
import { import {
NodesApiService,
AlfrescoApiService, AlfrescoApiService,
TimeAgoPipe, NodeNameTooltipPipe, TimeAgoPipe, NodeNameTooltipPipe,
NodeFavoriteDirective, DataTableComponent, AppConfigPipe NodeFavoriteDirective, DataTableComponent, AppConfigPipe
@@ -38,13 +37,14 @@ import { ContentManagementService } from '../../common/services/content-manageme
import { FavoritesComponent } from './favorites.component'; import { FavoritesComponent } from './favorites.component';
import { AppTestingModule } from '../../testing/app-testing.module'; import { AppTestingModule } from '../../testing/app-testing.module';
import { ContentApiService } from '../../services/content-api.service';
describe('FavoritesComponent', () => { describe('FavoritesComponent', () => {
let fixture: ComponentFixture<FavoritesComponent>; let fixture: ComponentFixture<FavoritesComponent>;
let component: FavoritesComponent; let component: FavoritesComponent;
let nodesApi: NodesApiService;
let alfrescoApi: AlfrescoApiService; let alfrescoApi: AlfrescoApiService;
let contentService: ContentManagementService; let contentService: ContentManagementService;
let contentApi: ContentApiService;
let router: Router; let router: Router;
let page; let page;
let node; let node;
@@ -93,11 +93,12 @@ describe('FavoritesComponent', () => {
fixture = TestBed.createComponent(FavoritesComponent); fixture = TestBed.createComponent(FavoritesComponent);
component = fixture.componentInstance; component = fixture.componentInstance;
nodesApi = TestBed.get(NodesApiService);
alfrescoApi = TestBed.get(AlfrescoApiService); alfrescoApi = TestBed.get(AlfrescoApiService);
alfrescoApi.reset(); alfrescoApi.reset();
spyOn(alfrescoApi.favoritesApi, 'getFavorites').and.returnValue(Promise.resolve(page)); spyOn(alfrescoApi.favoritesApi, 'getFavorites').and.returnValue(Promise.resolve(page));
contentApi = TestBed.get(ContentApiService);
contentService = TestBed.get(ContentManagementService); contentService = TestBed.get(ContentManagementService);
router = TestBed.get(Router); router = TestBed.get(Router);
}); });
@@ -135,7 +136,7 @@ describe('FavoritesComponent', () => {
describe('Node navigation', () => { describe('Node navigation', () => {
beforeEach(() => { beforeEach(() => {
spyOn(nodesApi, 'getNode').and.returnValue(Observable.of(node)); spyOn(contentApi, 'getNode').and.returnValue(Observable.of({ entry: node}));
spyOn(router, 'navigate'); spyOn(router, 'navigate');
fixture.detectChanges(); fixture.detectChanges();
}); });

View File

@@ -23,7 +23,6 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/ */
import { NodesApiService } from '@alfresco/adf-core';
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
@@ -37,6 +36,7 @@ import { ContentManagementService } from '../../common/services/content-manageme
import { NodePermissionService } from '../../common/services/node-permission.service'; import { NodePermissionService } from '../../common/services/node-permission.service';
import { AppStore } from '../../store/states/app.state'; import { AppStore } from '../../store/states/app.state';
import { PageComponent } from '../page.component'; import { PageComponent } from '../page.component';
import { ContentApiService } from '../../services/content-api.service';
@Component({ @Component({
templateUrl: './favorites.component.html' templateUrl: './favorites.component.html'
@@ -45,7 +45,7 @@ export class FavoritesComponent extends PageComponent implements OnInit {
constructor( constructor(
private router: Router, private router: Router,
store: Store<AppStore>, store: Store<AppStore>,
private nodesApi: NodesApiService, private contentApi: ContentApiService,
private content: ContentManagementService, private content: ContentManagementService,
public permission: NodePermissionService public permission: NodePermissionService
) { ) {
@@ -74,8 +74,9 @@ export class FavoritesComponent extends PageComponent implements OnInit {
}; };
if (isFolder) { if (isFolder) {
this.nodesApi this.contentApi
.getNode(id) .getNode(id)
.map(node => node.entry)
.subscribe(({ path }: MinimalNodeEntryEntity) => { .subscribe(({ path }: MinimalNodeEntryEntity) => {
const routeUrl = isSitePath(path) const routeUrl = isSitePath(path)
? '/libraries' ? '/libraries'

View File

@@ -28,7 +28,6 @@ import { TestBed, fakeAsync, tick, ComponentFixture } from '@angular/core/testin
import { NO_ERRORS_SCHEMA } from '@angular/core'; import { NO_ERRORS_SCHEMA } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router'; import { Router, ActivatedRoute } from '@angular/router';
import { import {
NodesApiService,
TimeAgoPipe, NodeNameTooltipPipe, FileSizePipe, NodeFavoriteDirective, TimeAgoPipe, NodeNameTooltipPipe, FileSizePipe, NodeFavoriteDirective,
DataTableComponent, UploadService, AppConfigPipe DataTableComponent, UploadService, AppConfigPipe
} from '@alfresco/adf-core'; } from '@alfresco/adf-core';
@@ -38,6 +37,7 @@ import { BrowsingFilesService } from '../../common/services/browsing-files.servi
import { NodeActionsService } from '../../common/services/node-actions.service'; import { NodeActionsService } from '../../common/services/node-actions.service';
import { FilesComponent } from './files.component'; import { FilesComponent } from './files.component';
import { AppTestingModule } from '../../testing/app-testing.module'; import { AppTestingModule } from '../../testing/app-testing.module';
import { ContentApiService } from '../../services/content-api.service';
describe('FilesComponent', () => { describe('FilesComponent', () => {
let node; let node;
@@ -46,10 +46,10 @@ describe('FilesComponent', () => {
let component: FilesComponent; let component: FilesComponent;
let contentManagementService: ContentManagementService; let contentManagementService: ContentManagementService;
let uploadService: UploadService; let uploadService: UploadService;
let nodesApi: NodesApiService;
let router: Router; let router: Router;
let browsingFilesService: BrowsingFilesService; let browsingFilesService: BrowsingFilesService;
let nodeActionsService: NodeActionsService; let nodeActionsService: NodeActionsService;
let contentApi: ContentApiService;
beforeAll(() => { beforeAll(() => {
// testing only functional-wise not time-wise // testing only functional-wise not time-wise
@@ -83,10 +83,10 @@ describe('FilesComponent', () => {
contentManagementService = TestBed.get(ContentManagementService); contentManagementService = TestBed.get(ContentManagementService);
uploadService = TestBed.get(UploadService); uploadService = TestBed.get(UploadService);
nodesApi = TestBed.get(NodesApiService);
router = TestBed.get(Router); router = TestBed.get(Router);
browsingFilesService = TestBed.get(BrowsingFilesService); browsingFilesService = TestBed.get(BrowsingFilesService);
nodeActionsService = TestBed.get(NodeActionsService); nodeActionsService = TestBed.get(NodeActionsService);
contentApi = TestBed.get(ContentApiService);
}); });
beforeEach(() => { beforeEach(() => {
@@ -103,7 +103,7 @@ describe('FilesComponent', () => {
describe('Current page is valid', () => { describe('Current page is valid', () => {
it('should be a valid current page', fakeAsync(() => { it('should be a valid current page', fakeAsync(() => {
spyOn(component, 'fetchNode').and.returnValue(Observable.of(node)); spyOn(contentApi, 'getNode').and.returnValue(Observable.of({ entry: node }));
spyOn(component, 'fetchNodes').and.returnValue(Observable.throw(null)); spyOn(component, 'fetchNodes').and.returnValue(Observable.throw(null));
component.ngOnInit(); component.ngOnInit();
@@ -114,7 +114,7 @@ describe('FilesComponent', () => {
})); }));
it('should set current page as invalid path', fakeAsync(() => { it('should set current page as invalid path', fakeAsync(() => {
spyOn(component, 'fetchNode').and.returnValue(Observable.of(node)); spyOn(contentApi, 'getNode').and.returnValue(Observable.of({ entry: node }));
spyOn(component, 'fetchNodes').and.returnValue(Observable.of(page)); spyOn(component, 'fetchNodes').and.returnValue(Observable.of(page));
component.ngOnInit(); component.ngOnInit();
@@ -127,7 +127,7 @@ describe('FilesComponent', () => {
describe('OnInit', () => { describe('OnInit', () => {
it('should set current node', () => { it('should set current node', () => {
spyOn(component, 'fetchNode').and.returnValue(Observable.of(node)); spyOn(contentApi, 'getNode').and.returnValue(Observable.of({ entry: node }));
spyOn(component, 'fetchNodes').and.returnValue(Observable.of(page)); spyOn(component, 'fetchNodes').and.returnValue(Observable.of(page));
fixture.detectChanges(); fixture.detectChanges();
@@ -136,7 +136,7 @@ describe('FilesComponent', () => {
}); });
it('should get current node children', () => { it('should get current node children', () => {
spyOn(component, 'fetchNode').and.returnValue(Observable.of(node)); spyOn(contentApi, 'getNode').and.returnValue(Observable.of({ entry: node }));
spyOn(component, 'fetchNodes').and.returnValue(Observable.of(page)); spyOn(component, 'fetchNodes').and.returnValue(Observable.of(page));
fixture.detectChanges(); fixture.detectChanges();
@@ -145,7 +145,7 @@ describe('FilesComponent', () => {
}); });
it('emits onChangeParent event', () => { it('emits onChangeParent event', () => {
spyOn(component, 'fetchNode').and.returnValue(Observable.of(node)); spyOn(contentApi, 'getNode').and.returnValue(Observable.of({ entry: node }));
spyOn(component, 'fetchNodes').and.returnValue(Observable.of(page)); spyOn(component, 'fetchNodes').and.returnValue(Observable.of(page));
spyOn(browsingFilesService.onChangeParent, 'next').and.callFake((val) => val); spyOn(browsingFilesService.onChangeParent, 'next').and.callFake((val) => val);
@@ -158,7 +158,7 @@ describe('FilesComponent', () => {
it('if should navigate to parent if node is not a folder', () => { it('if should navigate to parent if node is not a folder', () => {
node.isFolder = false; node.isFolder = false;
node.parentId = 'parent-id'; node.parentId = 'parent-id';
spyOn(component, 'fetchNode').and.returnValue(Observable.of(node)); spyOn(contentApi, 'getNode').and.returnValue(Observable.of({ entry: node }));
spyOn(router, 'navigate'); spyOn(router, 'navigate');
fixture.detectChanges(); fixture.detectChanges();
@@ -169,7 +169,7 @@ describe('FilesComponent', () => {
describe('refresh on events', () => { describe('refresh on events', () => {
beforeEach(() => { beforeEach(() => {
spyOn(component, 'fetchNode').and.returnValue(Observable.of(node)); spyOn(contentApi, 'getNode').and.returnValue(Observable.of(node));
spyOn(component, 'fetchNodes').and.returnValue(Observable.of(page)); spyOn(component, 'fetchNodes').and.returnValue(Observable.of(page));
spyOn(component.documentList, 'reload'); spyOn(component.documentList, 'reload');
@@ -269,25 +269,10 @@ describe('FilesComponent', () => {
}); });
}); });
describe('fetchNode()', () => {
beforeEach(() => {
spyOn(component, 'fetchNodes').and.returnValue(Observable.of(page));
spyOn(nodesApi, 'getNode').and.returnValue(Observable.of(node));
fixture.detectChanges();
});
it('should call getNode api with node id', () => {
component.fetchNode('nodeId');
expect(nodesApi.getNode).toHaveBeenCalledWith('nodeId');
});
});
describe('fetchNodes()', () => { describe('fetchNodes()', () => {
beforeEach(() => { beforeEach(() => {
spyOn(component, 'fetchNode').and.returnValue(Observable.of(node)); spyOn(contentApi, 'getNode').and.returnValue(Observable.of(node));
spyOn(nodesApi, 'getNodeChildren').and.returnValue(Observable.of(page)); spyOn(contentApi, 'getNodeChildren').and.returnValue(Observable.of(page));
fixture.detectChanges(); fixture.detectChanges();
}); });
@@ -295,13 +280,13 @@ describe('FilesComponent', () => {
it('should call getNode api with node id', () => { it('should call getNode api with node id', () => {
component.fetchNodes('nodeId'); component.fetchNodes('nodeId');
expect(nodesApi.getNodeChildren).toHaveBeenCalledWith('nodeId', jasmine.any(Object)); expect(contentApi.getNodeChildren).toHaveBeenCalledWith('nodeId');
}); });
}); });
describe('onBreadcrumbNavigate()', () => { describe('onBreadcrumbNavigate()', () => {
beforeEach(() => { beforeEach(() => {
spyOn(component, 'fetchNode').and.returnValue(Observable.of(node)); spyOn(contentApi, 'getNode').and.returnValue(Observable.of(node));
spyOn(component, 'fetchNodes').and.returnValue(Observable.of(page)); spyOn(component, 'fetchNodes').and.returnValue(Observable.of(page));
fixture.detectChanges(); fixture.detectChanges();
@@ -319,7 +304,7 @@ describe('FilesComponent', () => {
describe('Node navigation', () => { describe('Node navigation', () => {
beforeEach(() => { beforeEach(() => {
spyOn(component, 'fetchNode').and.returnValue(Observable.of(node)); spyOn(contentApi, 'getNode').and.returnValue(Observable.of(node));
spyOn(component, 'fetchNodes').and.returnValue(Observable.of(page)); spyOn(component, 'fetchNodes').and.returnValue(Observable.of(page));
spyOn(router, 'navigate'); spyOn(router, 'navigate');

View File

@@ -23,7 +23,7 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/ */
import { AlfrescoApiService, FileUploadEvent, NodesApiService, UploadService } from '@alfresco/adf-core'; import { FileUploadEvent, UploadService } from '@alfresco/adf-core';
import { Component, OnDestroy, OnInit } from '@angular/core'; import { Component, OnDestroy, OnInit } from '@angular/core';
import { ActivatedRoute, Params, Router } from '@angular/router'; import { ActivatedRoute, Params, Router } from '@angular/router';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
@@ -35,6 +35,7 @@ import { NodeActionsService } from '../../common/services/node-actions.service';
import { NodePermissionService } from '../../common/services/node-permission.service'; import { NodePermissionService } from '../../common/services/node-permission.service';
import { AppStore } from '../../store/states/app.state'; import { AppStore } from '../../store/states/app.state';
import { PageComponent } from '../page.component'; import { PageComponent } from '../page.component';
import { ContentApiService } from '../../services/content-api.service';
@Component({ @Component({
templateUrl: './files.component.html' templateUrl: './files.component.html'
@@ -47,13 +48,12 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
constructor(private router: Router, constructor(private router: Router,
private route: ActivatedRoute, private route: ActivatedRoute,
private contentApi: ContentApiService,
store: Store<AppStore>, store: Store<AppStore>,
private nodesApi: NodesApiService,
private nodeActionsService: NodeActionsService, private nodeActionsService: NodeActionsService,
private uploadService: UploadService, private uploadService: UploadService,
private contentManagementService: ContentManagementService, private contentManagementService: ContentManagementService,
private browsingFilesService: BrowsingFilesService, private browsingFilesService: BrowsingFilesService,
private apiService: AlfrescoApiService,
public permission: NodePermissionService) { public permission: NodePermissionService) {
super(store); super(store);
} }
@@ -69,8 +69,9 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
route.params.subscribe(({ folderId }: Params) => { route.params.subscribe(({ folderId }: Params) => {
const nodeId = folderId || data.defaultNodeId; const nodeId = folderId || data.defaultNodeId;
this.fetchNode(nodeId) this.contentApi.getNode(nodeId)
.do((node) => { .map(node => node.entry)
.do(node => {
if (node.isFolder) { if (node.isFolder) {
this.updateCurrentNode(node); this.updateCurrentNode(node);
} else { } else {
@@ -78,14 +79,10 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
} }
}) })
.skipWhile(node => !node.isFolder) .skipWhile(node => !node.isFolder)
.flatMap((node) => this.fetchNodes(node.id)) .flatMap(node => this.fetchNodes(node.id))
.subscribe( .subscribe(
(page) => { () => this.isValidPath = true,
this.isValidPath = true; () => this.isValidPath = false
},
error => {
this.isValidPath = false;
}
); );
}); });
@@ -107,18 +104,8 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
this.browsingFilesService.onChangeParent.next(null); this.browsingFilesService.onChangeParent.next(null);
} }
fetchNode(nodeId: string): Observable<MinimalNodeEntryEntity> { fetchNodes(parentNodeId?: string): Observable<NodePaging> {
return this.nodesApi.getNode(nodeId); return this.contentApi.getNodeChildren(parentNodeId);
}
fetchNodes(parentNodeId?: string, options: { maxItems?: number, skipCount?: number } = {}): Observable<NodePaging> {
const defaults = {
include: [ 'isLocked', 'path', 'properties', 'allowableOperations' ]
};
const queryOptions = Object.assign({}, defaults, options);
return this.nodesApi.getNodeChildren(parentNodeId, queryOptions);
} }
navigate(nodeId: string = null) { navigate(nodeId: string = null) {
@@ -246,7 +233,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
if (this.isSiteContainer(node)) { if (this.isSiteContainer(node)) {
// rename 'documentLibrary' entry to the target site display name // rename 'documentLibrary' entry to the target site display name
// clicking on the breadcrumb entry loads the site content // clicking on the breadcrumb entry loads the site content
const parentNode = await this.apiService.nodesApi.getNodeInfo(node.parentId); const parentNode = await this.contentApi.getNodeInfo(node.parentId).toPromise();
node.name = parentNode.properties['cm:title'] || parentNode.name; node.name = parentNode.properties['cm:title'] || parentNode.name;
// remove the site entry // remove the site entry
@@ -256,7 +243,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
const docLib = elements.findIndex(el => el.name === 'documentLibrary'); const docLib = elements.findIndex(el => el.name === 'documentLibrary');
if (docLib > -1) { if (docLib > -1) {
const siteFragment = elements[docLib - 1]; const siteFragment = elements[docLib - 1];
const siteNode = await this.apiService.nodesApi.getNodeInfo(siteFragment.id); const siteNode = await this.contentApi.getNodeInfo(siteFragment.id).toPromise();
// apply Site Name to the parent fragment // apply Site Name to the parent fragment
siteFragment.name = siteNode.properties['cm:title'] || siteNode.name; siteFragment.name = siteNode.properties['cm:title'] || siteNode.name;

View File

@@ -26,7 +26,7 @@
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core'; import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
import { MinimalNodeEntity, MinimalNodeEntryEntity } from 'alfresco-js-api'; import { MinimalNodeEntity, MinimalNodeEntryEntity } from 'alfresco-js-api';
import { NodePermissionService } from '../../common/services/node-permission.service'; import { NodePermissionService } from '../../common/services/node-permission.service';
import { AlfrescoApiService } from '@alfresco/adf-core'; import { ContentApiService } from '../../services/content-api.service';
@Component({ @Component({
selector: 'aca-info-drawer', selector: 'aca-info-drawer',
@@ -67,7 +67,7 @@ export class InfoDrawerComponent implements OnChanges {
constructor( constructor(
public permission: NodePermissionService, public permission: NodePermissionService,
private apiService: AlfrescoApiService private contentApi: ContentApiService
) {} ) {}
ngOnChanges(changes: SimpleChanges) { ngOnChanges(changes: SimpleChanges) {
@@ -88,15 +88,13 @@ export class InfoDrawerComponent implements OnChanges {
if (nodeId) { if (nodeId) {
this.isLoading = true; this.isLoading = true;
this.apiService.nodesApi this.contentApi.getNodeInfo(nodeId).subscribe(
.getNodeInfo(nodeId, { include: ['allowableOperations'] }) entity => {
.then((entity: MinimalNodeEntryEntity) => {
this.displayNode = entity; this.displayNode = entity;
this.isLoading = false; this.isLoading = false;
}) },
.catch(() => { () => this.isLoading = false
this.isLoading = false; );
});
} }
} }
} }

View File

@@ -28,7 +28,7 @@ import { Observable } from 'rxjs/Rx';
import { NO_ERRORS_SCHEMA } from '@angular/core'; import { NO_ERRORS_SCHEMA } from '@angular/core';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { import {
NodesApiService, AlfrescoApiService, AlfrescoApiService,
TimeAgoPipe, NodeNameTooltipPipe, NodeFavoriteDirective, DataTableComponent, AppConfigPipe TimeAgoPipe, NodeNameTooltipPipe, NodeFavoriteDirective, DataTableComponent, AppConfigPipe
} from '@alfresco/adf-core'; } from '@alfresco/adf-core';
import { DocumentListComponent } from '@alfresco/adf-content-services'; import { DocumentListComponent } from '@alfresco/adf-content-services';
@@ -36,11 +36,12 @@ import { ShareDataTableAdapter } from '@alfresco/adf-content-services';
import { LibrariesComponent } from './libraries.component'; import { LibrariesComponent } from './libraries.component';
import { ExperimentalDirective } from '../../directives/experimental.directive'; import { ExperimentalDirective } from '../../directives/experimental.directive';
import { AppTestingModule } from '../../testing/app-testing.module'; import { AppTestingModule } from '../../testing/app-testing.module';
import { ContentApiService } from '../../services/content-api.service';
describe('LibrariesComponent', () => { describe('LibrariesComponent', () => {
let fixture: ComponentFixture<LibrariesComponent>; let fixture: ComponentFixture<LibrariesComponent>;
let component: LibrariesComponent; let component: LibrariesComponent;
let nodesApi: NodesApiService; let contentApi: ContentApiService;
let alfrescoApi: AlfrescoApiService; let alfrescoApi: AlfrescoApiService;
let router: Router; let router: Router;
let page; let page;
@@ -81,13 +82,14 @@ describe('LibrariesComponent', () => {
fixture = TestBed.createComponent(LibrariesComponent); fixture = TestBed.createComponent(LibrariesComponent);
component = fixture.componentInstance; component = fixture.componentInstance;
nodesApi = TestBed.get(NodesApiService);
alfrescoApi = TestBed.get(AlfrescoApiService); alfrescoApi = TestBed.get(AlfrescoApiService);
alfrescoApi.reset(); alfrescoApi.reset();
router = TestBed.get(Router); router = TestBed.get(Router);
spyOn(alfrescoApi.sitesApi, 'getSites').and.returnValue((Promise.resolve(page))); spyOn(alfrescoApi.sitesApi, 'getSites').and.returnValue((Promise.resolve(page)));
spyOn(alfrescoApi.peopleApi, 'getSiteMembership').and.returnValue((Promise.resolve({}))); spyOn(alfrescoApi.peopleApi, 'getSiteMembership').and.returnValue((Promise.resolve({})));
contentApi = TestBed.get(ContentApiService);
}); });
describe('makeLibraryTooltip()', () => { describe('makeLibraryTooltip()', () => {
@@ -153,7 +155,7 @@ describe('LibrariesComponent', () => {
it('navigates to node id', () => { it('navigates to node id', () => {
const document = { id: 'documentId' }; const document = { id: 'documentId' };
spyOn(nodesApi, 'getNode').and.returnValue(Observable.of(document)); spyOn(contentApi, 'getNode').and.returnValue(Observable.of({ entry: document }));
component.navigate(node.id); component.navigate(node.id);

View File

@@ -25,7 +25,6 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router'; import { Router, ActivatedRoute } from '@angular/router';
import { NodesApiService } from '@alfresco/adf-core';
import { ShareDataRow } from '@alfresco/adf-content-services'; import { ShareDataRow } from '@alfresco/adf-content-services';
import { PageComponent } from '../page.component'; import { PageComponent } from '../page.component';
@@ -34,15 +33,16 @@ import { AppStore } from '../../store/states/app.state';
import { DeleteLibraryAction } from '../../store/actions'; import { DeleteLibraryAction } from '../../store/actions';
import { SiteEntry } from 'alfresco-js-api'; import { SiteEntry } from 'alfresco-js-api';
import { ContentManagementService } from '../../common/services/content-management.service'; import { ContentManagementService } from '../../common/services/content-management.service';
import { ContentApiService } from '../../services/content-api.service';
@Component({ @Component({
templateUrl: './libraries.component.html' templateUrl: './libraries.component.html'
}) })
export class LibrariesComponent extends PageComponent implements OnInit { export class LibrariesComponent extends PageComponent implements OnInit {
constructor(private nodesApi: NodesApiService, constructor(private route: ActivatedRoute,
private route: ActivatedRoute,
private content: ContentManagementService, private content: ContentManagementService,
private contentApi: ContentApiService,
store: Store<AppStore>, store: Store<AppStore>,
private router: Router) { private router: Router) {
super(store); super(store);
@@ -89,8 +89,9 @@ export class LibrariesComponent extends PageComponent implements OnInit {
navigate(libraryId: string) { navigate(libraryId: string) {
if (libraryId) { if (libraryId) {
this.nodesApi this.contentApi
.getNode(libraryId, { relativePath: '/documentLibrary' }) .getNode(libraryId, { relativePath: '/documentLibrary' })
.map(node => node.entry)
.subscribe(documentLibrary => { .subscribe(documentLibrary => {
this.router.navigate([ './', documentLibrary.id ], { relativeTo: this.route }); this.router.navigate([ './', documentLibrary.id ], { relativeTo: this.route });
}); });

View File

@@ -24,13 +24,14 @@
*/ */
import { Component, Input, ChangeDetectionStrategy, OnInit, ViewEncapsulation } from '@angular/core'; import { Component, Input, ChangeDetectionStrategy, OnInit, ViewEncapsulation } from '@angular/core';
import { AlfrescoApiService, DataColumn, DataRow, DataTableAdapter } from '@alfresco/adf-core'; import { DataColumn, DataRow, DataTableAdapter } from '@alfresco/adf-core';
import { PathInfoEntity, MinimalNodeEntity } from 'alfresco-js-api'; import { PathInfoEntity, MinimalNodeEntity } from 'alfresco-js-api';
import { Observable } from 'rxjs/Rx'; import { Observable } from 'rxjs/Rx';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AppStore } from '../../store/states/app.state'; import { AppStore } from '../../store/states/app.state';
import { NavigateToParentFolder } from '../../store/actions'; import { NavigateToParentFolder } from '../../store/actions';
import { ContentApiService } from '../../services/content-api.service';
@Component({ @Component({
selector: 'app-location-link', selector: 'app-location-link',
@@ -59,7 +60,7 @@ export class LocationLinkComponent implements OnInit {
constructor( constructor(
private store: Store<AppStore>, private store: Store<AppStore>,
private apiService: AlfrescoApiService) { private contentApi: ContentApiService) {
} }
goToLocation() { goToLocation() {
@@ -104,12 +105,12 @@ export class LocationLinkComponent implements OnInit {
const fragment = path.elements[path.elements.length - 2]; const fragment = path.elements[path.elements.length - 2];
return new Observable<string>(observer => { return new Observable<string>(observer => {
this.apiService.nodesApi.getNodeInfo(fragment.id).then( this.contentApi.getNodeInfo(fragment.id).subscribe(
(node) => { node => {
observer.next(node.properties['cm:title'] || node.name || fragment.name); observer.next(node.properties['cm:title'] || node.name || fragment.name);
observer.complete(); observer.complete();
}, },
(err) => { () => {
observer.next(fragment.name); observer.next(fragment.name);
observer.complete(); observer.complete();
} }
@@ -132,8 +133,8 @@ export class LocationLinkComponent implements OnInit {
const fragment = elements[2]; const fragment = elements[2];
return new Observable<string>(observer => { return new Observable<string>(observer => {
this.apiService.nodesApi.getNodeInfo(fragment.id).then( this.contentApi.getNodeInfo(fragment.id).subscribe(
(node) => { node => {
elements.splice(0, 2); elements.splice(0, 2);
elements[0].name = node.properties['cm:title'] || node.name || fragment.name; elements[0].name = node.properties['cm:title'] || node.name || fragment.name;
elements.splice(1, 1); elements.splice(1, 1);
@@ -142,7 +143,7 @@ export class LocationLinkComponent implements OnInit {
observer.next(elements.map(e => e.name).join('/')); observer.next(elements.map(e => e.name).join('/'));
observer.complete(); observer.complete();
}, },
(err) => { () => {
elements.splice(0, 2); elements.splice(0, 2);
elements.unshift({ id: null, name: 'File Libraries' }); elements.unshift({ id: null, name: 'File Libraries' });
elements.splice(2, 1); elements.splice(2, 1);

View File

@@ -25,13 +25,14 @@
import { NO_ERRORS_SCHEMA } from '@angular/core'; import { NO_ERRORS_SCHEMA } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router'; import { Router, ActivatedRoute } from '@angular/router';
import { TestBed, async, ComponentFixture } from '@angular/core/testing'; import { TestBed, ComponentFixture } from '@angular/core/testing';
import { AlfrescoApiService, UserPreferencesService, AppConfigPipe, NodeFavoriteDirective } from '@alfresco/adf-core'; import { UserPreferencesService, AppConfigPipe, NodeFavoriteDirective } from '@alfresco/adf-core';
import { PreviewComponent } from './preview.component'; import { PreviewComponent } from './preview.component';
import { Observable } from 'rxjs/Rx'; import { Observable } from 'rxjs/Rx';
import { EffectsModule } from '@ngrx/effects'; import { EffectsModule } from '@ngrx/effects';
import { NodeEffects } from '../../store/effects/node.effects'; import { NodeEffects } from '../../store/effects/node.effects';
import { AppTestingModule } from '../../testing/app-testing.module'; import { AppTestingModule } from '../../testing/app-testing.module';
import { ContentApiService } from '../../services/content-api.service';
describe('PreviewComponent', () => { describe('PreviewComponent', () => {
@@ -39,10 +40,10 @@ describe('PreviewComponent', () => {
let component: PreviewComponent; let component: PreviewComponent;
let router: Router; let router: Router;
let route: ActivatedRoute; let route: ActivatedRoute;
let alfrescoApi: AlfrescoApiService;
let preferences: UserPreferencesService; let preferences: UserPreferencesService;
let contentApi: ContentApiService;
beforeEach(async(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ imports: [
AppTestingModule, AppTestingModule,
@@ -54,18 +55,16 @@ describe('PreviewComponent', () => {
NodeFavoriteDirective NodeFavoriteDirective
], ],
schemas: [ NO_ERRORS_SCHEMA ] schemas: [ NO_ERRORS_SCHEMA ]
}) });
.compileComponents().then(() => {
fixture = TestBed.createComponent(PreviewComponent); fixture = TestBed.createComponent(PreviewComponent);
component = fixture.componentInstance; component = fixture.componentInstance;
router = TestBed.get(Router); router = TestBed.get(Router);
route = TestBed.get(ActivatedRoute); route = TestBed.get(ActivatedRoute);
alfrescoApi = TestBed.get(AlfrescoApiService);
alfrescoApi.reset();
preferences = TestBed.get(UserPreferencesService); preferences = TestBed.get(UserPreferencesService);
contentApi = TestBed.get(ContentApiService);
}); });
}));
it('should extract the property path root', () => { it('should extract the property path root', () => {
expect(component.getRootField('some.property.path')).toBe('some'); expect(component.getRootField('some.property.path')).toBe('some');
@@ -339,35 +338,33 @@ describe('PreviewComponent', () => {
it('should not display node when id is missing', async () => { it('should not display node when id is missing', async () => {
spyOn(router, 'navigate').and.stub(); spyOn(router, 'navigate').and.stub();
spyOn(alfrescoApi.nodesApi, 'getNodeInfo').and.returnValue( spyOn(contentApi, 'getNodeInfo').and.returnValue(
Promise.resolve(null) Observable.of(null)
); );
await component.displayNode(null); await component.displayNode(null);
expect(alfrescoApi.nodesApi.getNodeInfo).not.toHaveBeenCalled(); expect(contentApi.getNodeInfo).not.toHaveBeenCalled();
expect(router.navigate).not.toHaveBeenCalled(); expect(router.navigate).not.toHaveBeenCalled();
}); });
it('should navigate to original location if node not found', async () => { it('should navigate to original location if node not found', async () => {
spyOn(router, 'navigate').and.stub(); spyOn(router, 'navigate').and.stub();
spyOn(alfrescoApi.nodesApi, 'getNodeInfo').and.returnValue( spyOn(contentApi, 'getNodeInfo').and.returnValue(
Promise.resolve(null) Observable.of(null)
); );
component.previewLocation = 'personal-files'; component.previewLocation = 'personal-files';
await component.displayNode('folder1'); await component.displayNode('folder1');
expect(alfrescoApi.nodesApi.getNodeInfo).toHaveBeenCalledWith( expect(contentApi.getNodeInfo).toHaveBeenCalledWith('folder1');
'folder1', { include: [ 'allowableOperations' ] }
);
expect(router.navigate).toHaveBeenCalledWith(['personal-files', 'folder1']); expect(router.navigate).toHaveBeenCalledWith(['personal-files', 'folder1']);
}); });
it('should navigate to original location if node is not a File', async () => { it('should navigate to original location if node is not a File', async () => {
spyOn(router, 'navigate').and.stub(); spyOn(router, 'navigate').and.stub();
spyOn(alfrescoApi.nodesApi, 'getNodeInfo').and.returnValue( spyOn(contentApi, 'getNodeInfo').and.returnValue(
Promise.resolve({ Observable.of({
isFile: false isFile: false
}) })
); );
@@ -375,31 +372,27 @@ describe('PreviewComponent', () => {
component.previewLocation = 'personal-files'; component.previewLocation = 'personal-files';
await component.displayNode('folder1'); await component.displayNode('folder1');
expect(alfrescoApi.nodesApi.getNodeInfo).toHaveBeenCalledWith( expect(contentApi.getNodeInfo).toHaveBeenCalledWith('folder1');
'folder1', { include: [ 'allowableOperations' ] }
);
expect(router.navigate).toHaveBeenCalledWith(['personal-files', 'folder1']); expect(router.navigate).toHaveBeenCalledWith(['personal-files', 'folder1']);
}); });
it('should navigate to original location in case of Alfresco API errors', async () => { it('should navigate to original location in case of Alfresco API errors', async () => {
spyOn(router, 'navigate').and.stub(); spyOn(router, 'navigate').and.stub();
spyOn(alfrescoApi.nodesApi, 'getNodeInfo').and.returnValue( spyOn(contentApi, 'getNodeInfo').and.returnValue(
Promise.reject('error') Observable.throw('error')
); );
component.previewLocation = 'personal-files'; component.previewLocation = 'personal-files';
await component.displayNode('folder1'); await component.displayNode('folder1');
expect(alfrescoApi.nodesApi.getNodeInfo).toHaveBeenCalledWith( expect(contentApi.getNodeInfo).toHaveBeenCalledWith('folder1');
'folder1', { include: [ 'allowableOperations' ] }
);
expect(router.navigate).toHaveBeenCalledWith(['personal-files', 'folder1']); expect(router.navigate).toHaveBeenCalledWith(['personal-files', 'folder1']);
}); });
it('should navigate to original location in case of internal errors', async () => { it('should navigate to original location in case of internal errors', async () => {
spyOn(router, 'navigate').and.stub(); spyOn(router, 'navigate').and.stub();
spyOn(alfrescoApi.nodesApi, 'getNodeInfo').and.returnValue( spyOn(contentApi, 'getNodeInfo').and.returnValue(
Promise.resolve({ Observable.of({
isFile: true isFile: true
}) })
); );
@@ -410,17 +403,15 @@ describe('PreviewComponent', () => {
component.previewLocation = 'personal-files'; component.previewLocation = 'personal-files';
await component.displayNode('folder1'); await component.displayNode('folder1');
expect(alfrescoApi.nodesApi.getNodeInfo).toHaveBeenCalledWith( expect(contentApi.getNodeInfo).toHaveBeenCalledWith('folder1');
'folder1', { include: [ 'allowableOperations' ] }
);
expect(router.navigate).toHaveBeenCalledWith(['personal-files', 'folder1']); expect(router.navigate).toHaveBeenCalledWith(['personal-files', 'folder1']);
}); });
it('should setup node for displaying', async () => { it('should setup node for displaying', async () => {
spyOn(router, 'navigate').and.stub(); spyOn(router, 'navigate').and.stub();
spyOn(component, 'getNearestNodes').and.returnValue({ left: 'node1', right: 'node3' }); spyOn(component, 'getNearestNodes').and.returnValue({ left: 'node1', right: 'node3' });
spyOn(alfrescoApi.nodesApi, 'getNodeInfo').and.returnValue( spyOn(contentApi, 'getNodeInfo').and.returnValue(
Promise.resolve({ Observable.of({
id: 'node2', id: 'node2',
parentId: 'parent1', parentId: 'parent1',
isFile: true isFile: true
@@ -439,8 +430,8 @@ describe('PreviewComponent', () => {
preferences.set('personal-files.sorting.key', 'name'); preferences.set('personal-files.sorting.key', 'name');
preferences.set('personal-files.sorting.direction', 'desc'); preferences.set('personal-files.sorting.direction', 'desc');
spyOn(alfrescoApi.nodesApi, 'getNodeChildren').and.returnValue( spyOn(contentApi, 'getNodeChildren').and.returnValue(
Promise.resolve({ Observable.of({
list: { list: {
entries: [ entries: [
{ entry: { id: 'node1', name: 'node 1' } }, { entry: { id: 'node1', name: 'node 1' } },
@@ -458,8 +449,8 @@ describe('PreviewComponent', () => {
preferences.set('personal-files.sorting.key', 'missing'); preferences.set('personal-files.sorting.key', 'missing');
preferences.set('personal-files.sorting.direction', 'desc'); preferences.set('personal-files.sorting.direction', 'desc');
spyOn(alfrescoApi.nodesApi, 'getNodeChildren').and.returnValue( spyOn(contentApi, 'getNodeChildren').and.returnValue(
Promise.resolve({ Observable.of({
list: { list: {
entries: [ entries: [
{ entry: { id: 'node1', name: 'node 1' } }, { entry: { id: 'node1', name: 'node 1' } },
@@ -481,8 +472,8 @@ describe('PreviewComponent', () => {
it('should sort file ids for personal-files with [modifiedAt desc]', async () => { it('should sort file ids for personal-files with [modifiedAt desc]', async () => {
spyOn(preferences, 'get').and.returnValue(null); spyOn(preferences, 'get').and.returnValue(null);
spyOn(alfrescoApi.nodesApi, 'getNodeChildren').and.returnValue( spyOn(contentApi, 'getNodeChildren').and.returnValue(
Promise.resolve({ Observable.of({
list: { list: {
entries: [ entries: [
{ entry: { id: 'node1', name: 'node 1', modifiedAt: 1 } }, { entry: { id: 'node1', name: 'node 1', modifiedAt: 1 } },
@@ -500,8 +491,8 @@ describe('PreviewComponent', () => {
preferences.set('personal-files.sorting.key', 'name'); preferences.set('personal-files.sorting.key', 'name');
preferences.set('personal-files.sorting.direction', 'desc'); preferences.set('personal-files.sorting.direction', 'desc');
spyOn(alfrescoApi.nodesApi, 'getNodeChildren').and.returnValue( spyOn(contentApi, 'getNodeChildren').and.returnValue(
Promise.resolve({ Observable.of({
list: { list: {
entries: [ entries: [
{ entry: { id: 'node1', name: 'node 1' } }, { entry: { id: 'node1', name: 'node 1' } },
@@ -523,8 +514,8 @@ describe('PreviewComponent', () => {
it('should sort file ids for libraries with [modifiedAt desc]', async () => { it('should sort file ids for libraries with [modifiedAt desc]', async () => {
spyOn(preferences, 'get').and.returnValue(null); spyOn(preferences, 'get').and.returnValue(null);
spyOn(alfrescoApi.nodesApi, 'getNodeChildren').and.returnValue( spyOn(contentApi, 'getNodeChildren').and.returnValue(
Promise.resolve({ Observable.of({
list: { list: {
entries: [ entries: [
{ entry: { id: 'node1', name: 'node 1', modifiedAt: new Date(1) } }, { entry: { id: 'node1', name: 'node 1', modifiedAt: new Date(1) } },
@@ -542,8 +533,8 @@ describe('PreviewComponent', () => {
preferences.set('favorites.sorting.key', 'name'); preferences.set('favorites.sorting.key', 'name');
preferences.set('favorites.sorting.direction', 'desc'); preferences.set('favorites.sorting.direction', 'desc');
spyOn(alfrescoApi.favoritesApi, 'getFavorites').and.returnValue( spyOn(contentApi, 'getFavorites').and.returnValue(
Promise.resolve({ Observable.of({
list: { list: {
entries: [ entries: [
{ entry: { target: { file: { id: 'file3', name: 'file 3' } } } }, { entry: { target: { file: { id: 'file3', name: 'file 3' } } } },
@@ -561,8 +552,8 @@ describe('PreviewComponent', () => {
it('should sort file ids for favorites with [modifiedAt desc]', async () => { it('should sort file ids for favorites with [modifiedAt desc]', async () => {
spyOn(preferences, 'get').and.returnValue(null); spyOn(preferences, 'get').and.returnValue(null);
spyOn(alfrescoApi.favoritesApi, 'getFavorites').and.returnValue( spyOn(contentApi, 'getFavorites').and.returnValue(
Promise.resolve({ Observable.of({
list: { list: {
entries: [ entries: [
{ entry: { target: { file: { id: 'file3', modifiedAt: new Date(3) } } } }, { entry: { target: { file: { id: 'file3', modifiedAt: new Date(3) } } } },
@@ -581,8 +572,8 @@ describe('PreviewComponent', () => {
preferences.set('shared.sorting.key', 'name'); preferences.set('shared.sorting.key', 'name');
preferences.set('shared.sorting.direction', 'asc'); preferences.set('shared.sorting.direction', 'asc');
spyOn(alfrescoApi.sharedLinksApi, 'findSharedLinks').and.returnValue( spyOn(contentApi, 'findSharedLinks').and.returnValue(
Promise.resolve({ Observable.of({
list: { list: {
entries: [ entries: [
{ entry: { nodeId: 'node2', name: 'node 2', modifiedAt: new Date(2) } }, { entry: { nodeId: 'node2', name: 'node 2', modifiedAt: new Date(2) } },
@@ -599,8 +590,8 @@ describe('PreviewComponent', () => {
it('should sort file ids for favorites with [modifiedAt desc]', async () => { it('should sort file ids for favorites with [modifiedAt desc]', async () => {
spyOn(preferences, 'get').and.returnValue(null); spyOn(preferences, 'get').and.returnValue(null);
spyOn(alfrescoApi.sharedLinksApi, 'findSharedLinks').and.returnValue( spyOn(contentApi, 'findSharedLinks').and.returnValue(
Promise.resolve({ Observable.of({
list: { list: {
entries: [ entries: [
{ entry: { nodeId: 'node2', name: 'node 2', modifiedAt: new Date(2) } }, { entry: { nodeId: 'node2', name: 'node 2', modifiedAt: new Date(2) } },
@@ -618,14 +609,14 @@ describe('PreviewComponent', () => {
preferences.set('recent-files.sorting.key', 'name'); preferences.set('recent-files.sorting.key', 'name');
preferences.set('recent-files.sorting.direction', 'asc'); preferences.set('recent-files.sorting.direction', 'asc');
spyOn(alfrescoApi.peopleApi, 'getPerson').and.returnValue( spyOn(contentApi, 'getPerson').and.returnValue(
Promise.resolve({ Observable.of({
entry: { id: 'user' } entry: { id: 'user' }
}) })
); );
spyOn(alfrescoApi.searchApi, 'search').and.returnValue( spyOn(contentApi, 'search').and.returnValue(
Promise.resolve({ Observable.of({
list: { list: {
entries: [ entries: [
{ entry: { id: 'node2', name: 'node 2', modifiedAt: new Date(2) } }, { entry: { id: 'node2', name: 'node 2', modifiedAt: new Date(2) } },
@@ -642,14 +633,14 @@ describe('PreviewComponent', () => {
it('should sort file ids for favorites with [modifiedAt desc]', async () => { it('should sort file ids for favorites with [modifiedAt desc]', async () => {
spyOn(preferences, 'get').and.returnValue(null); spyOn(preferences, 'get').and.returnValue(null);
spyOn(alfrescoApi.peopleApi, 'getPerson').and.returnValue( spyOn(contentApi, 'getPerson').and.returnValue(
Promise.resolve({ Observable.of({
entry: { id: 'user' } entry: { id: 'user' }
}) })
); );
spyOn(alfrescoApi.searchApi, 'search').and.returnValue( spyOn(contentApi, 'search').and.returnValue(
Promise.resolve({ Observable.of({
list: { list: {
entries: [ entries: [
{ entry: { id: 'node2', name: 'node 2', modifiedAt: new Date(2) } }, { entry: { id: 'node2', name: 'node 2', modifiedAt: new Date(2) } },

View File

@@ -25,13 +25,14 @@
import { Component, OnInit, ViewEncapsulation } from '@angular/core'; import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { ActivatedRoute, Router, UrlTree, UrlSegmentGroup, UrlSegment, PRIMARY_OUTLET } from '@angular/router'; import { ActivatedRoute, Router, UrlTree, UrlSegmentGroup, UrlSegment, PRIMARY_OUTLET } from '@angular/router';
import { AlfrescoApiService, UserPreferencesService, ObjectUtils, UploadService } from '@alfresco/adf-core'; import { UserPreferencesService, ObjectUtils, UploadService } from '@alfresco/adf-core';
import { Node, MinimalNodeEntity } from 'alfresco-js-api'; import { Node, MinimalNodeEntity } from 'alfresco-js-api';
import { NodePermissionService } from '../../common/services/node-permission.service'; import { NodePermissionService } from '../../common/services/node-permission.service';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AppStore } from '../../store/states/app.state'; import { AppStore } from '../../store/states/app.state';
import { DeleteNodesAction } from '../../store/actions'; import { DeleteNodesAction } from '../../store/actions';
import { PageComponent } from '../page.component'; import { PageComponent } from '../page.component';
import { ContentApiService } from '../../services/content-api.service';
@Component({ @Component({
selector: 'app-preview', selector: 'app-preview',
templateUrl: 'preview.component.html', templateUrl: 'preview.component.html',
@@ -56,8 +57,8 @@ export class PreviewComponent extends PageComponent implements OnInit {
selectedEntities: MinimalNodeEntity[] = []; selectedEntities: MinimalNodeEntity[] = [];
constructor( constructor(
private contentApi: ContentApiService,
private uploadService: UploadService, private uploadService: UploadService,
private apiService: AlfrescoApiService,
private preferences: UserPreferencesService, private preferences: UserPreferencesService,
private route: ActivatedRoute, private route: ActivatedRoute,
private router: Router, private router: Router,
@@ -105,9 +106,7 @@ export class PreviewComponent extends PageComponent implements OnInit {
async displayNode(id: string) { async displayNode(id: string) {
if (id) { if (id) {
try { try {
this.node = await this.apiService.nodesApi.getNodeInfo(id, { this.node = await this.contentApi.getNodeInfo(id).toPromise();
include: ['allowableOperations']
});
this.selectedEntities = [{ entry: this.node }]; this.selectedEntities = [{ entry: this.node }];
if (this.node && this.node.isFile) { if (this.node && this.node.isFile) {
@@ -222,11 +221,11 @@ export class PreviewComponent extends PageComponent implements OnInit {
if ((source === 'personal-files' || source === 'libraries') && folderId) { if ((source === 'personal-files' || source === 'libraries') && folderId) {
const sortKey = this.preferences.get('personal-files.sorting.key') || 'modifiedAt'; const sortKey = this.preferences.get('personal-files.sorting.key') || 'modifiedAt';
const sortDirection = this.preferences.get('personal-files.sorting.direction') || 'desc'; const sortDirection = this.preferences.get('personal-files.sorting.direction') || 'desc';
const nodes = await this.apiService.nodesApi.getNodeChildren(folderId, { const nodes = await this.contentApi.getNodeChildren(folderId, {
// orderBy: `${sortKey} ${sortDirection}`, // orderBy: `${sortKey} ${sortDirection}`,
fields: ['id', this.getRootField(sortKey)], fields: ['id', this.getRootField(sortKey)],
where: '(isFile=true)' where: '(isFile=true)'
}); }).toPromise();
const entries = nodes.list.entries.map(obj => obj.entry); const entries = nodes.list.entries.map(obj => obj.entry);
this.sort(entries, sortKey, sortDirection); this.sort(entries, sortKey, sortDirection);
@@ -235,10 +234,10 @@ export class PreviewComponent extends PageComponent implements OnInit {
} }
if (source === 'favorites') { if (source === 'favorites') {
const nodes = await this.apiService.favoritesApi.getFavorites('-me-', { const nodes = await this.contentApi.getFavorites('-me-', {
where: '(EXISTS(target/file))', where: '(EXISTS(target/file))',
fields: ['target'] fields: ['target']
}); }).toPromise();
const sortKey = this.preferences.get('favorites.sorting.key') || 'modifiedAt'; const sortKey = this.preferences.get('favorites.sorting.key') || 'modifiedAt';
const sortDirection = this.preferences.get('favorites.sorting.direction') || 'desc'; const sortDirection = this.preferences.get('favorites.sorting.direction') || 'desc';
@@ -252,9 +251,9 @@ export class PreviewComponent extends PageComponent implements OnInit {
const sortingKey = this.preferences.get('shared.sorting.key') || 'modifiedAt'; const sortingKey = this.preferences.get('shared.sorting.key') || 'modifiedAt';
const sortingDirection = this.preferences.get('shared.sorting.direction') || 'desc'; const sortingDirection = this.preferences.get('shared.sorting.direction') || 'desc';
const nodes = await this.apiService.sharedLinksApi.findSharedLinks({ const nodes = await this.contentApi.findSharedLinks({
fields: ['nodeId', this.getRootField(sortingKey)] fields: ['nodeId', this.getRootField(sortingKey)]
}); }).toPromise();
const entries = nodes.list.entries.map(obj => obj.entry); const entries = nodes.list.entries.map(obj => obj.entry);
this.sort(entries, sortingKey, sortingDirection); this.sort(entries, sortingKey, sortingDirection);
@@ -263,12 +262,12 @@ export class PreviewComponent extends PageComponent implements OnInit {
} }
if (source === 'recent-files') { if (source === 'recent-files') {
const person = await this.apiService.peopleApi.getPerson('-me-'); const person = await this.contentApi.getPerson('-me-').toPromise();
const username = person.entry.id; const username = person.entry.id;
const sortingKey = this.preferences.get('recent-files.sorting.key') || 'modifiedAt'; const sortingKey = this.preferences.get('recent-files.sorting.key') || 'modifiedAt';
const sortingDirection = this.preferences.get('recent-files.sorting.direction') || 'desc'; const sortingDirection = this.preferences.get('recent-files.sorting.direction') || 'desc';
const nodes = await this.apiService.searchApi.search({ const nodes = await this.contentApi.search({
query: { query: {
query: '*', query: '*',
language: 'afts' language: 'afts'
@@ -284,7 +283,7 @@ export class PreviewComponent extends PageComponent implements OnInit {
field: 'cm:modified', field: 'cm:modified',
ascending: false ascending: false
}] }]
}); }).toPromise();
const entries = nodes.list.entries.map(obj => obj.entry); const entries = nodes.list.entries.map(obj => obj.entry);
this.sort(entries, sortingKey, sortingDirection); this.sort(entries, sortingKey, sortingDirection);

View File

@@ -65,8 +65,7 @@
<button <button
mat-menu-item mat-menu-item
*ngIf="permission.check(selection.nodes, ['delete'])" *ngIf="permission.check(selection.nodes, ['delete'])"
[acaUnshareNode]="selection.nodes" [acaUnshareNode]="selection.nodes">
(links-unshared)="reload()">
<mat-icon>stop_screen_share</mat-icon> <mat-icon>stop_screen_share</mat-icon>
<span>{{ 'APP.ACTIONS.UNSHARE' | translate }}</span> <span>{{ 'APP.ACTIONS.UNSHARE' | translate }}</span>
</button> </button>

View File

@@ -51,6 +51,7 @@ export class SharedFilesComponent extends PageComponent implements OnInit {
this.content.nodesDeleted.subscribe(() => this.reload()), this.content.nodesDeleted.subscribe(() => this.reload()),
this.content.nodesMoved.subscribe(() => this.reload()), this.content.nodesMoved.subscribe(() => this.reload()),
this.content.nodesRestored.subscribe(() => this.reload()), this.content.nodesRestored.subscribe(() => this.reload()),
this.content.linksUnshared.subscribe(() => this.reload()),
this.uploadService.fileUploadError.subscribe((error) => this.onFileUploadedError(error)) this.uploadService.fileUploadError.subscribe((error) => this.onFileUploadedError(error))
]); ]);
} }

View File

@@ -0,0 +1,229 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2018 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { Injectable } from '@angular/core';
import { AlfrescoApiService, UserPreferencesService } from '@alfresco/adf-core';
import { Observable } from 'rxjs/Observable';
import {
MinimalNodeEntity,
NodePaging,
Node,
DeletedNodesPaging,
PersonEntry,
NodeEntry,
DiscoveryEntry,
FavoritePaging,
SharedLinkPaging,
SearchRequest,
ResultSetPaging
} from 'alfresco-js-api';
@Injectable()
export class ContentApiService {
constructor(
private api: AlfrescoApiService,
private preferences: UserPreferencesService
) {}
/**
* Moves a node to the trashcan.
* @param nodeId ID of the target node
* @param options Optional parameters supported by JS-API
* @returns Empty result that notifies when the deletion is complete
*/
deleteNode(
nodeId: string,
options: { permanent?: boolean } = {}
): Observable<void> {
return Observable.fromPromise(
this.api.nodesApi.deleteNode(nodeId, options)
);
}
/**
* Gets the stored information about a node.
* @param nodeId ID of the target node
* @param options Optional parameters supported by JS-API
* @returns Node information
*/
getNode(nodeId: string, options: any = {}): Observable<MinimalNodeEntity> {
const defaults = {
include: [
'path',
'properties',
'allowableOperations',
'permissions'
]
};
const queryOptions = Object.assign(defaults, options);
return Observable.fromPromise(
this.api.nodesApi.getNode(nodeId, queryOptions)
);
}
getNodeInfo(nodeId: string, options: any = {}): Observable<Node> {
const defaults = {
include: ['allowableOperations']
};
const queryOptions = Object.assign(defaults, options);
return Observable.fromPromise(
this.api.nodesApi.getNodeInfo(nodeId, queryOptions)
);
}
/**
* Gets the items contained in a folder node.
* @param nodeId ID of the target node
* @param options Optional parameters supported by JS-API
* @returns List of child items from the folder
*/
getNodeChildren(nodeId: string, options: any = {}): Observable<NodePaging> {
const defaults = {
maxItems: this.preferences.paginationSize,
skipCount: 0,
include: [
'isLocked',
'path',
'properties',
'allowableOperations',
'permissions'
]
};
const queryOptions = Object.assign(defaults, options);
return Observable.fromPromise(
this.api.nodesApi.getNodeChildren(nodeId, queryOptions)
);
}
deleteSharedLink(linkId: string): Observable<any> {
return Observable.fromPromise(
this.api.sharedLinksApi.deleteSharedLink(linkId)
);
}
getDeletedNodes(options: any = {}): Observable<DeletedNodesPaging> {
const defaults = {
include: ['path']
};
const queryOptions = Object.assign(defaults, options);
return Observable.fromPromise(
this.api.nodesApi.getDeletedNodes(queryOptions)
);
}
restoreNode(nodeId: string): Observable<MinimalNodeEntity> {
return Observable.fromPromise(this.api.nodesApi.restoreNode(nodeId));
}
purgeDeletedNode(nodeId: string): Observable<any> {
return Observable.fromPromise(
this.api.nodesApi.purgeDeletedNode(nodeId)
);
}
/**
* Gets information about a user identified by their username.
* @param personId ID of the target user
* @returns User information
*/
getPerson(
personId: string,
options?: { fields?: Array<string> }
): Observable<PersonEntry> {
return Observable.fromPromise(
this.api.peopleApi.getPerson(personId, options)
);
}
/**
* Copy a node to destination node
*
* @param nodeId The id of the node to be copied
* @param targetParentId The id of the folder-node where the node have to be copied to
* @param name The new name for the copy that would be added on the destination folder
*/
copyNode(
nodeId: string,
targetParentId: string,
name?: string,
opts?: { include?: Array<string>; fields?: Array<string> }
): Observable<NodeEntry> {
return Observable.fromPromise(
this.api.nodesApi.copyNode(nodeId, { targetParentId, name }, opts)
);
}
/**
* Gets product information for Content Services.
* @returns ProductVersionModel containing product details
*/
getRepositoryInformation(): Observable<DiscoveryEntry> {
return Observable.fromPromise(
this.api
.getInstance()
.discovery.discoveryApi.getRepositoryInformation()
);
}
getFavorites(
personId: string,
opts?: {
skipCount?: number;
maxItems?: number;
where?: string;
fields?: Array<string>;
}
): Observable<FavoritePaging> {
return Observable.fromPromise(
this.api.favoritesApi.getFavorites(personId, opts)
);
}
findSharedLinks(opts?: any): Observable<SharedLinkPaging> {
return Observable.fromPromise(
this.api.sharedLinksApi.findSharedLinks(opts)
);
}
search(request: SearchRequest): Observable<ResultSetPaging> {
return Observable.fromPromise(
this.api.searchApi.search(request)
);
}
getContentUrl(nodeId: string, attachment?: boolean): string {
return this.api.contentApi.getContentUrl(nodeId, attachment);
}
deleteSite(siteId?: string, opts?: { permanent?: boolean }): Observable<any> {
return Observable.fromPromise(
this.api.sitesApi.deleteSite(siteId, opts)
);
}
}

View File

@@ -24,10 +24,11 @@
*/ */
import { Action } from '@ngrx/store'; import { Action } from '@ngrx/store';
import { Person } from 'alfresco-js-api';
export const SET_USER = 'SET_USER'; export const SET_USER = 'SET_USER';
export class SetUserAction implements Action { export class SetUserAction implements Action {
readonly type = SET_USER; readonly type = SET_USER;
constructor(public payload: any) { } constructor(public payload: Person) { }
} }

View File

@@ -24,19 +24,19 @@
*/ */
import { DownloadZipDialogComponent } from '@alfresco/adf-content-services'; import { DownloadZipDialogComponent } from '@alfresco/adf-content-services';
import { AlfrescoApiService } from '@alfresco/adf-core';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { MatDialog } from '@angular/material'; import { MatDialog } from '@angular/material';
import { Actions, Effect, ofType } from '@ngrx/effects'; import { Actions, Effect, ofType } from '@ngrx/effects';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { DownloadNodesAction, DOWNLOAD_NODES } from '../actions'; import { DownloadNodesAction, DOWNLOAD_NODES } from '../actions';
import { NodeInfo } from '../models'; import { NodeInfo } from '../models';
import { ContentApiService } from '../../services/content-api.service';
@Injectable() @Injectable()
export class DownloadEffects { export class DownloadEffects {
constructor( constructor(
private actions$: Actions, private actions$: Actions,
private apiService: AlfrescoApiService, private contentApi: ContentApiService,
private dialog: MatDialog private dialog: MatDialog
) {} ) {}
@@ -75,7 +75,7 @@ export class DownloadEffects {
private downloadFile(node: NodeInfo) { private downloadFile(node: NodeInfo) {
if (node) { if (node) {
this.download( this.download(
this.apiService.contentApi.getContentUrl(node.id, true), this.contentApi.getContentUrl(node.id, true),
node.name node.name
); );
} }

View File

@@ -27,7 +27,6 @@ import { Effect, Actions, ofType } from '@ngrx/effects';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { DeleteLibraryAction, DELETE_LIBRARY } from '../actions'; import { DeleteLibraryAction, DELETE_LIBRARY } from '../actions';
import { AlfrescoApiService } from '@alfresco/adf-core';
import { import {
SnackbarInfoAction, SnackbarInfoAction,
SnackbarErrorAction SnackbarErrorAction
@@ -35,13 +34,14 @@ import {
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AppStore } from '../states/app.state'; import { AppStore } from '../states/app.state';
import { ContentManagementService } from '../../common/services/content-management.service'; import { ContentManagementService } from '../../common/services/content-management.service';
import { ContentApiService } from '../../services/content-api.service';
@Injectable() @Injectable()
export class SiteEffects { export class SiteEffects {
constructor( constructor(
private actions$: Actions, private actions$: Actions,
private store: Store<AppStore>, private store: Store<AppStore>,
private apiService: AlfrescoApiService, private contentApi: ContentApiService,
private content: ContentManagementService private content: ContentManagementService
) {} ) {}
@@ -49,7 +49,7 @@ export class SiteEffects {
deleteLibrary$ = this.actions$.pipe( deleteLibrary$ = this.actions$.pipe(
ofType<DeleteLibraryAction>(DELETE_LIBRARY), ofType<DeleteLibraryAction>(DELETE_LIBRARY),
map(action => { map(action => {
this.apiService.sitesApi.deleteSite(action.payload).then( this.contentApi.deleteSite(action.payload).subscribe(
() => { () => {
this.content.siteDeleted.next(action.payload); this.content.siteDeleted.next(action.payload);
this.store.dispatch( this.store.dispatch(
@@ -58,7 +58,7 @@ export class SiteEffects {
) )
); );
}, },
err => { () => {
this.store.dispatch( this.store.dispatch(
new SnackbarErrorAction( new SnackbarErrorAction(
'APP.MESSAGES.ERRORS.DELETE_LIBRARY_FAILED' 'APP.MESSAGES.ERRORS.DELETE_LIBRARY_FAILED'

View File

@@ -43,8 +43,8 @@ import {
} from '../actions'; } from '../actions';
import { ContentManagementService } from '../../common/services/content-management.service'; import { ContentManagementService } from '../../common/services/content-management.service';
import { Observable } from 'rxjs/Rx'; import { Observable } from 'rxjs/Rx';
import { AlfrescoApiService } from '@alfresco/adf-core';
import { NodeInfo, DeleteStatus, DeletedNodeInfo } from '../models'; import { NodeInfo, DeleteStatus, DeletedNodeInfo } from '../models';
import { ContentApiService } from '../../services/content-api.service';
@Injectable() @Injectable()
export class NodeEffects { export class NodeEffects {
@@ -52,7 +52,7 @@ export class NodeEffects {
private store: Store<AppStore>, private store: Store<AppStore>,
private actions$: Actions, private actions$: Actions,
private contentManagementService: ContentManagementService, private contentManagementService: ContentManagementService,
private alfrescoApiService: AlfrescoApiService private contentApi: ContentApiService
) {} ) {}
@Effect({ dispatch: false }) @Effect({ dispatch: false })
@@ -113,9 +113,7 @@ export class NodeEffects {
private deleteNode(node: NodeInfo): Observable<DeletedNodeInfo> { private deleteNode(node: NodeInfo): Observable<DeletedNodeInfo> {
const { id, name } = node; const { id, name } = node;
return Observable.fromPromise( return this.contentApi.deleteNode(id)
this.alfrescoApiService.nodesApi.deleteNode(id)
)
.map(() => { .map(() => {
return { return {
id, id,
@@ -208,9 +206,7 @@ export class NodeEffects {
private undoDeleteNode(item: DeletedNodeInfo): Observable<DeletedNodeInfo> { private undoDeleteNode(item: DeletedNodeInfo): Observable<DeletedNodeInfo> {
const { id, name } = item; const { id, name } = item;
return Observable.fromPromise( return this.contentApi.restoreNode(id)
this.alfrescoApiService.nodesApi.restoreNode(id)
)
.map(() => { .map(() => {
return { return {
id, id,
@@ -266,9 +262,8 @@ export class NodeEffects {
private purgeDeletedNode(node: NodeInfo): Observable<DeletedNodeInfo> { private purgeDeletedNode(node: NodeInfo): Observable<DeletedNodeInfo> {
const { id, name } = node; const { id, name } = node;
const promise = this.alfrescoApiService.nodesApi.purgeDeletedNode(id);
return Observable.from(promise) return this.contentApi.purgeDeletedNode(id)
.map(() => ({ .map(() => ({
status: 1, status: 1,
id, id,

View File

@@ -117,7 +117,9 @@ function updateUser(state: AppState, action: SetUserAction): AppState {
const lastName = user.lastName || ''; const lastName = user.lastName || '';
const userName = `${firstName} ${lastName}`; const userName = `${firstName} ${lastName}`;
const initials = [firstName[0], lastName[0]].join(''); const initials = [firstName[0], lastName[0]].join('');
const isAdmin = user.capabilities ? user.capabilities.isAdmin : true;
const capabilities = (<any>user).capabilities;
const isAdmin = capabilities ? capabilities.isAdmin : true;
newState.user = { newState.user = {
firstName, firstName,

View File

@@ -42,7 +42,8 @@ import {
ContentService, ContentService,
ThumbnailService, ThumbnailService,
UploadService, UploadService,
PeopleContentService PeopleContentService,
AlfrescoApiMock
} from '@alfresco/adf-core'; } from '@alfresco/adf-core';
import { HttpClientModule } from '@angular/common/http'; import { HttpClientModule } from '@angular/common/http';
import { TranslateServiceMock } from './translation.service'; import { TranslateServiceMock } from './translation.service';
@@ -60,6 +61,7 @@ import { ContentManagementService } from '../common/services/content-management.
import { NodeActionsService } from '../common/services/node-actions.service'; import { NodeActionsService } from '../common/services/node-actions.service';
import { NodePermissionService } from '../common/services/node-permission.service'; import { NodePermissionService } from '../common/services/node-permission.service';
import { BrowsingFilesService } from '../common/services/browsing-files.service'; import { BrowsingFilesService } from '../common/services/browsing-files.service';
import { ContentApiService } from '../services/content-api.service';
@NgModule({ @NgModule({
imports: [ imports: [
@@ -76,6 +78,7 @@ import { BrowsingFilesService } from '../common/services/browsing-files.service'
declarations: [TranslatePipeMock], declarations: [TranslatePipeMock],
exports: [TranslatePipeMock, RouterTestingModule, MaterialModule], exports: [TranslatePipeMock, RouterTestingModule, MaterialModule],
providers: [ providers: [
{ provide: AlfrescoApiService, useClass: AlfrescoApiMock },
{ provide: TranslationService, useClass: TranslationMock }, { provide: TranslationService, useClass: TranslationMock },
{ provide: TranslateService, useClass: TranslateServiceMock }, { provide: TranslateService, useClass: TranslateServiceMock },
{ provide: TranslatePipe, useClass: TranslatePipeMock }, { provide: TranslatePipe, useClass: TranslatePipeMock },
@@ -108,7 +111,8 @@ import { BrowsingFilesService } from '../common/services/browsing-files.service'
ContentManagementService, ContentManagementService,
NodeActionsService, NodeActionsService,
NodePermissionService, NodePermissionService,
BrowsingFilesService BrowsingFilesService,
ContentApiService
] ]
}) })
export class AppTestingModule {} export class AppTestingModule {}