mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-31 17:38:48 +00:00
[ADF - 1114] Process comments - Share the same comment between Task and Process (#2105)
* changed process comment template and used task comment component * changed getTaskComment, getProcessInstanceComment, addTaskComment and addProcessInstanceComment to getComments and addComment * removed provider from task comment component * extended tasklist service and changed comment-list container css * changed process service methods and associated test cases * added error emitter and test cases for process-comments component * fixed process header component test case
This commit is contained in:
committed by
Eugenio Romano
parent
7fbdf4ed8a
commit
83a6f0d425
@@ -1,35 +1 @@
|
||||
<span class="activiti-label mdl-badge"
|
||||
[attr.data-badge]="comments?.length">{{ 'DETAILS.LABELS.COMMENTS' |translate }}</span>
|
||||
<div id="addComment" (click)="showDialog()" class="icon material-icons">add</div>
|
||||
<div class="mdl-tooltip" for="addComment">
|
||||
{{ 'DETAILS.COMMENTS.BUTTON.ADD' |translate }}
|
||||
</div>
|
||||
|
||||
<div class="menu-container" *ngIf="comments?.length > 0">
|
||||
<ul class='mdl-list'>
|
||||
<li class="mdl-list__item list-wrap" *ngFor="let comment of comments">
|
||||
<span class="mdl-list__item-primary-content hide-long-names">
|
||||
<i class="material-icons mdl-list__item-icon">comment</i>
|
||||
{{comment.message}}
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div *ngIf="comments?.length === 0" data-automation-id="comments-none">
|
||||
{{ 'DETAILS.COMMENTS.NONE' | translate }}
|
||||
</div>
|
||||
|
||||
|
||||
<dialog class="mdl-dialog" #dialog>
|
||||
<h4 class="mdl-dialog__title">{{ 'DETAILS.COMMENTS.ADD_DIALOG.TITLE' |translate }}</h4>
|
||||
<div class="mdl-dialog__content">
|
||||
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
|
||||
<textarea class="mdl-textfield__input" type="text" [(ngModel)]="message" rows="1" id="commentText"></textarea>
|
||||
<label class="mdl-textfield__label" for="commentText">{{ 'DETAILS.COMMENTS.ADD_DIALOG.LABEL.MESSAGE' |translate }}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mdl-dialog__actions">
|
||||
<button type="button" (click)="add()" class="mdl-button">{{ 'DETAILS.COMMENTS.ADD_DIALOG.BUTTON.ADD' |translate }}</button>
|
||||
<button type="button" (click)="cancel()" class="mdl-button close">{{ 'DETAILS.COMMENTS.ADD_DIALOG.BUTTON.CANCEL' |translate }}</button>
|
||||
</div>
|
||||
</dialog>
|
||||
<adf-comments [readOnly]="readOnly" [taskId]="processInstanceId" (error)="onError($event)" #activiticomments></adf-comments>
|
@@ -15,13 +15,18 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { SimpleChange } from '@angular/core';
|
||||
import { DatePipe } from '@angular/common';
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { MdInputModule } from '@angular/material';
|
||||
import { Observable } from 'rxjs/Rx';
|
||||
|
||||
import { ActivitiFormModule } from 'ng2-activiti-form';
|
||||
import {
|
||||
CommentListComponent,
|
||||
CommentsComponent,
|
||||
TaskListService
|
||||
} from 'ng2-activiti-tasklist';
|
||||
import { AlfrescoTranslationService, CoreModule } from 'ng2-alfresco-core';
|
||||
import { DataTableModule } from 'ng2-alfresco-datatable';
|
||||
|
||||
import { TranslationMock } from './../assets/translation.service.mock';
|
||||
import { ProcessService } from './../services/process.service';
|
||||
@@ -30,24 +35,27 @@ import { ProcessCommentsComponent } from './process-comments.component';
|
||||
describe('ActivitiProcessInstanceComments', () => {
|
||||
|
||||
let componentHandler: any;
|
||||
let service: ProcessService;
|
||||
let service: TaskListService;
|
||||
let component: ProcessCommentsComponent;
|
||||
let fixture: ComponentFixture<ProcessCommentsComponent>;
|
||||
let getCommentsSpy: jasmine.Spy;
|
||||
let addCommentSpy: jasmine.Spy;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
CoreModule,
|
||||
ActivitiFormModule
|
||||
DataTableModule,
|
||||
MdInputModule
|
||||
],
|
||||
declarations: [
|
||||
ProcessCommentsComponent
|
||||
ProcessCommentsComponent,
|
||||
CommentsComponent,
|
||||
CommentListComponent
|
||||
],
|
||||
providers: [
|
||||
{ provide: AlfrescoTranslationService, useClass: TranslationMock },
|
||||
ProcessService
|
||||
{ provide: TaskListService, useClass: ProcessService },
|
||||
DatePipe
|
||||
]
|
||||
}).compileComponents();
|
||||
}));
|
||||
@@ -56,16 +64,13 @@ describe('ActivitiProcessInstanceComments', () => {
|
||||
|
||||
fixture = TestBed.createComponent(ProcessCommentsComponent);
|
||||
component = fixture.componentInstance;
|
||||
service = fixture.debugElement.injector.get(ProcessService);
|
||||
service = fixture.debugElement.injector.get(TaskListService);
|
||||
|
||||
getCommentsSpy = spyOn(service, 'getProcessInstanceComments').and.returnValue(Observable.of([{
|
||||
message: 'Test1'
|
||||
}, {
|
||||
message: 'Test2'
|
||||
}, {
|
||||
message: 'Test3'
|
||||
}]));
|
||||
addCommentSpy = spyOn(service, 'addProcessInstanceComment').and.returnValue(Observable.of({id: 123, message: 'Test'}));
|
||||
getCommentsSpy = spyOn(service, 'getComments').and.returnValue(Observable.of([
|
||||
{ message: 'Test1', created: Date.now(), createdBy: {firstName: 'Admin', lastName: 'User'} },
|
||||
{ message: 'Test2', created: Date.now(), createdBy: {firstName: 'Admin', lastName: 'User'} },
|
||||
{ message: 'Test3', created: Date.now(), createdBy: {firstName: 'Admin', lastName: 'User'} }
|
||||
]));
|
||||
|
||||
componentHandler = jasmine.createSpyObj('componentHandler', [
|
||||
'upgradeAllRegistered',
|
||||
@@ -75,118 +80,75 @@ describe('ActivitiProcessInstanceComments', () => {
|
||||
});
|
||||
|
||||
it('should load comments when processInstanceId specified', () => {
|
||||
let change = new SimpleChange(null, '123', true);
|
||||
component.ngOnChanges({ 'processInstanceId': change });
|
||||
component.processInstanceId = '123';
|
||||
fixture.detectChanges();
|
||||
expect(getCommentsSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should emit an error when an error occurs loading comments', () => {
|
||||
let emitSpy = spyOn(component.error, 'emit');
|
||||
getCommentsSpy.and.returnValue(Observable.throw({}));
|
||||
let change = new SimpleChange(null, '123', true);
|
||||
component.ngOnChanges({ 'processInstanceId': change });
|
||||
component.processInstanceId = '123';
|
||||
fixture.detectChanges();
|
||||
expect(emitSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not comments when no processInstanceId is specified', () => {
|
||||
it('should not load comments when no processInstanceId is specified', () => {
|
||||
fixture.detectChanges();
|
||||
expect(getCommentsSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should display comments when the process has comments', async(() => {
|
||||
let change = new SimpleChange(null, '123', true);
|
||||
component.ngOnChanges({ 'processInstanceId': change });
|
||||
component.processInstanceId = '123';
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.nativeElement.querySelectorAll('#comment-message').length).toBe(3);
|
||||
expect(fixture.nativeElement.querySelector('#comment-message:empty')).toBeNull();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should display comments count when the process has comments', () => {
|
||||
component.processInstanceId = '123';
|
||||
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.queryAll(By.css('ul.mdl-list li')).length).toBe(3);
|
||||
let element = fixture.nativeElement.querySelector('#comment-header');
|
||||
expect(element.innerText).toContain('(3)');
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('should not display comments when the process has no comments', async(() => {
|
||||
component.processInstanceId = '123';
|
||||
getCommentsSpy.and.returnValue(Observable.of([]));
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.queryAll(By.css('ul.mdl-list li')).length).toBe(0);
|
||||
expect(fixture.nativeElement.querySelector('#comment-container')).toBeNull();
|
||||
});
|
||||
}));
|
||||
|
||||
describe('change detection', () => {
|
||||
|
||||
let change = new SimpleChange('123', '456', true);
|
||||
let nullChange = new SimpleChange('123', null, true);
|
||||
|
||||
beforeEach(async(() => {
|
||||
component.processInstanceId = '123';
|
||||
it('should not display comments input by default', async(() => {
|
||||
component.processInstanceId = '123';
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
getCommentsSpy.calls.reset();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should fetch new comments when processInstanceId changed', () => {
|
||||
component.ngOnChanges({ 'processInstanceId': change });
|
||||
expect(getCommentsSpy).toHaveBeenCalledWith('456');
|
||||
expect(fixture.nativeElement.querySelector('#comment-input')).toBeNull();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should NOT fetch new comments when empty changeset made', () => {
|
||||
component.ngOnChanges({});
|
||||
expect(getCommentsSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should NOT fetch new comments when processInstanceId changed to null', () => {
|
||||
component.ngOnChanges({ 'processInstanceId': nullChange });
|
||||
expect(getCommentsSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should set a placeholder message when processInstanceId changed to null', () => {
|
||||
component.ngOnChanges({ 'processInstanceId': nullChange });
|
||||
it('should not display comments input when the process is readonly', async(() => {
|
||||
component.readOnly = true;
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.query(By.css('[data-automation-id="comments-none"]'))).not.toBeNull();
|
||||
expect(fixture.nativeElement.querySelector('#comment-input')).toBeNull();
|
||||
});
|
||||
});
|
||||
}));
|
||||
|
||||
describe('Add comment', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
component.processInstanceId = '123';
|
||||
it('should display comments input when the process isn\'t readonly', async(() => {
|
||||
component.readOnly = false;
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable();
|
||||
}));
|
||||
|
||||
it('should display a dialog to the user when the Add button clicked', () => {
|
||||
let dialogEl = fixture.debugElement.query(By.css('.mdl-dialog')).nativeElement;
|
||||
let showSpy: jasmine.Spy = spyOn(dialogEl, 'showModal');
|
||||
component.showDialog();
|
||||
expect(showSpy).toHaveBeenCalled();
|
||||
expect(fixture.nativeElement.querySelector('#comment-input')).not.toBeNull();
|
||||
});
|
||||
|
||||
it('should call service to add a comment', () => {
|
||||
component.showDialog();
|
||||
component.message = 'Test comment';
|
||||
component.add();
|
||||
expect(addCommentSpy).toHaveBeenCalledWith('123', 'Test comment');
|
||||
});
|
||||
|
||||
it('should emit an error when an error occurs adding the comment', () => {
|
||||
let emitSpy = spyOn(component.error, 'emit');
|
||||
addCommentSpy.and.returnValue(Observable.throw({}));
|
||||
component.showDialog();
|
||||
component.message = 'Test comment';
|
||||
component.add();
|
||||
expect(emitSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should close add dialog when close button clicked', () => {
|
||||
let dialogEl = fixture.debugElement.query(By.css('.mdl-dialog')).nativeElement;
|
||||
let closeSpy: jasmine.Spy = spyOn(dialogEl, 'close');
|
||||
component.showDialog();
|
||||
component.cancel();
|
||||
expect(closeSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}));
|
||||
});
|
||||
|
@@ -15,117 +15,40 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges, ViewChild } from '@angular/core';
|
||||
import { Comment } from 'ng2-activiti-tasklist';
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { TaskListService } from 'ng2-activiti-tasklist';
|
||||
import { AlfrescoTranslationService } from 'ng2-alfresco-core';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { Observer } from 'rxjs/Observer';
|
||||
import { ProcessService } from './../services/process.service';
|
||||
|
||||
declare let componentHandler: any;
|
||||
declare let dialogPolyfill: any;
|
||||
|
||||
@Component({
|
||||
selector: 'adf-process-instance-comments, activiti-process-instance-comments',
|
||||
templateUrl: './process-comments.component.html',
|
||||
styleUrls: ['./process-comments.component.css'],
|
||||
providers: [ProcessService]
|
||||
providers: [{provide: TaskListService, useClass: ProcessService}]
|
||||
})
|
||||
export class ProcessCommentsComponent implements OnChanges {
|
||||
export class ProcessCommentsComponent {
|
||||
|
||||
@Input()
|
||||
processInstanceId: string;
|
||||
|
||||
@Input()
|
||||
readOnly: boolean = true;
|
||||
|
||||
@Output()
|
||||
error: EventEmitter<any> = new EventEmitter<any>();
|
||||
|
||||
@ViewChild('dialog')
|
||||
dialog: any;
|
||||
|
||||
comments: Comment [] = [];
|
||||
|
||||
commentObserver: Observer<Comment>;
|
||||
|
||||
comment$: Observable<Comment>;
|
||||
|
||||
message: string;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param translate Translation service
|
||||
* @param activitiProcess Process service
|
||||
*/
|
||||
constructor(private translate: AlfrescoTranslationService,
|
||||
private activitiProcess: ProcessService) {
|
||||
constructor(private translate: AlfrescoTranslationService) {
|
||||
|
||||
if (translate) {
|
||||
translate.addTranslationFolder('ng2-activiti-processlist', 'assets/ng2-activiti-processlist');
|
||||
}
|
||||
|
||||
this.comment$ = new Observable<Comment>(observer => this.commentObserver = observer).share();
|
||||
this.comment$.subscribe((comment: Comment) => {
|
||||
this.comments.push(comment);
|
||||
});
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
let processInstanceId = changes['processInstanceId'];
|
||||
if (processInstanceId) {
|
||||
if (processInstanceId.currentValue) {
|
||||
this.getProcessComments(processInstanceId.currentValue);
|
||||
} else {
|
||||
this.resetComments();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private getProcessComments(processInstanceId: string) {
|
||||
this.comments = [];
|
||||
if (processInstanceId) {
|
||||
this.activitiProcess.getProcessInstanceComments(processInstanceId).subscribe(
|
||||
(res: Comment[]) => {
|
||||
res.forEach((comment) => {
|
||||
this.commentObserver.next(comment);
|
||||
});
|
||||
},
|
||||
(err) => {
|
||||
this.error.emit(err);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
this.resetComments();
|
||||
}
|
||||
}
|
||||
|
||||
private resetComments() {
|
||||
this.comments = [];
|
||||
}
|
||||
|
||||
public showDialog() {
|
||||
if (!this.dialog.nativeElement.showModal) {
|
||||
dialogPolyfill.registerDialog(this.dialog.nativeElement);
|
||||
}
|
||||
if (this.dialog) {
|
||||
this.dialog.nativeElement.showModal();
|
||||
}
|
||||
}
|
||||
|
||||
public add() {
|
||||
this.activitiProcess.addProcessInstanceComment(this.processInstanceId, this.message).subscribe(
|
||||
(res: Comment) => {
|
||||
this.comments.push(res);
|
||||
this.message = '';
|
||||
},
|
||||
(err) => {
|
||||
this.error.emit(err);
|
||||
}
|
||||
);
|
||||
this.cancel();
|
||||
}
|
||||
|
||||
public cancel() {
|
||||
if (this.dialog) {
|
||||
this.dialog.nativeElement.close();
|
||||
}
|
||||
onError(error: any) {
|
||||
this.error.emit(error);
|
||||
}
|
||||
}
|
||||
|
@@ -22,7 +22,6 @@ import { Observable } from 'rxjs/Rx';
|
||||
import { ProcessInstance } from '../models/process-instance.model';
|
||||
import { exampleProcess } from './../assets/process.model.mock';
|
||||
import { ProcessService } from './../services/process.service';
|
||||
import { ProcessCommentsComponent } from './process-comments.component';
|
||||
import { ProcessInstanceHeaderComponent } from './process-instance-header.component';
|
||||
|
||||
describe('ProcessInstanceHeaderComponent', () => {
|
||||
@@ -38,8 +37,7 @@ describe('ProcessInstanceHeaderComponent', () => {
|
||||
CoreModule.forRoot()
|
||||
],
|
||||
declarations: [
|
||||
ProcessInstanceHeaderComponent,
|
||||
ProcessCommentsComponent
|
||||
ProcessInstanceHeaderComponent
|
||||
],
|
||||
providers: [
|
||||
ProcessService,
|
||||
|
@@ -430,13 +430,13 @@ describe('ProcessService', () => {
|
||||
});
|
||||
|
||||
it('should return the correct number of comments', async(() => {
|
||||
service.getProcessInstanceComments(processId).subscribe((tasks) => {
|
||||
service.getComments(processId).subscribe((tasks) => {
|
||||
expect(tasks.length).toBe(2);
|
||||
});
|
||||
}));
|
||||
|
||||
it('should return the correct comment data', async(() => {
|
||||
service.getProcessInstanceComments(processId).subscribe((comments) => {
|
||||
service.getComments(processId).subscribe((comments) => {
|
||||
let comment = comments[0];
|
||||
expect(comment.id).toBe(fakeComment.id);
|
||||
expect(comment.created).toBe(fakeComment.created);
|
||||
@@ -446,13 +446,13 @@ describe('ProcessService', () => {
|
||||
}));
|
||||
|
||||
it('should call service to fetch process instance comments', () => {
|
||||
service.getProcessInstanceComments(processId);
|
||||
service.getComments(processId);
|
||||
expect(getProcessInstanceComments).toHaveBeenCalledWith(processId);
|
||||
});
|
||||
|
||||
it('should pass on any error that is returned by the API', async(() => {
|
||||
getProcessInstanceComments = getProcessInstanceComments.and.returnValue(Promise.reject(fakeError));
|
||||
service.getProcessInstanceComments(processId).subscribe(
|
||||
service.getComments(processId).subscribe(
|
||||
() => {},
|
||||
(res) => {
|
||||
expect(res).toBe(fakeError);
|
||||
@@ -462,7 +462,7 @@ describe('ProcessService', () => {
|
||||
|
||||
it('should return a default error if no data is returned by the API', async(() => {
|
||||
getProcessInstanceComments = getProcessInstanceComments.and.returnValue(Promise.reject(null));
|
||||
service.getProcessInstanceComments(processId).subscribe(
|
||||
service.getComments(processId).subscribe(
|
||||
() => {},
|
||||
(res) => {
|
||||
expect(res).toBe('Server error');
|
||||
@@ -484,14 +484,14 @@ describe('ProcessService', () => {
|
||||
});
|
||||
|
||||
it('should call service to add comment', () => {
|
||||
service.addProcessInstanceComment(processId, message);
|
||||
service.addComment(processId, message);
|
||||
expect(addProcessInstanceComment).toHaveBeenCalledWith({
|
||||
message: message
|
||||
}, processId);
|
||||
});
|
||||
|
||||
it('should return the created comment', async(() => {
|
||||
service.addProcessInstanceComment(processId, message).subscribe((comment) => {
|
||||
service.addComment(processId, message).subscribe((comment) => {
|
||||
expect(comment.id).toBe(fakeComment.id);
|
||||
expect(comment.created).toBe(fakeComment.created);
|
||||
expect(comment.message).toBe(fakeComment.message);
|
||||
@@ -501,7 +501,7 @@ describe('ProcessService', () => {
|
||||
|
||||
it('should pass on any error that is returned by the API', async(() => {
|
||||
addProcessInstanceComment = addProcessInstanceComment.and.returnValue(Promise.reject(fakeError));
|
||||
service.addProcessInstanceComment(processId, message).subscribe(
|
||||
service.addComment(processId, message).subscribe(
|
||||
() => {},
|
||||
(res) => {
|
||||
expect(res).toBe(fakeError);
|
||||
@@ -511,7 +511,7 @@ describe('ProcessService', () => {
|
||||
|
||||
it('should return a default error if no data is returned by the API', async(() => {
|
||||
addProcessInstanceComment = addProcessInstanceComment.and.returnValue(Promise.reject(null));
|
||||
service.addProcessInstanceComment(processId, message).subscribe(
|
||||
service.addComment(processId, message).subscribe(
|
||||
() => {},
|
||||
(res) => {
|
||||
expect(res).toBe('Server error');
|
||||
@@ -638,7 +638,7 @@ describe('ProcessService', () => {
|
||||
}));
|
||||
|
||||
it('should return the default filters', (done) => {
|
||||
service.createDefaultFilters('1234').subscribe(
|
||||
service.createDefaultProcessFilters('1234').subscribe(
|
||||
(res: FilterProcessRepresentationModel []) => {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.length).toEqual(3);
|
||||
@@ -668,12 +668,12 @@ describe('ProcessService', () => {
|
||||
let filter = fakeFilters.data[0];
|
||||
|
||||
it('should call the API to create the filter', () => {
|
||||
service.addFilter(filter);
|
||||
service.addProcessFilter(filter);
|
||||
expect(createFilter).toHaveBeenCalledWith(filter);
|
||||
});
|
||||
|
||||
it('should return the created filter', async(() => {
|
||||
service.addFilter(filter).subscribe((createdFilter: FilterProcessRepresentationModel) => {
|
||||
service.addProcessFilter(filter).subscribe((createdFilter: FilterProcessRepresentationModel) => {
|
||||
expect(createdFilter).toBe(filter);
|
||||
});
|
||||
}));
|
||||
@@ -681,7 +681,7 @@ describe('ProcessService', () => {
|
||||
it('should pass on any error that is returned by the API', async(() => {
|
||||
createFilter = createFilter.and.returnValue(Promise.reject(fakeError));
|
||||
|
||||
service.addFilter(filter).subscribe(
|
||||
service.addProcessFilter(filter).subscribe(
|
||||
() => {},
|
||||
(res) => {
|
||||
expect(res).toBe(fakeError);
|
||||
@@ -691,7 +691,7 @@ describe('ProcessService', () => {
|
||||
|
||||
it('should return a default error if no data is returned by the API', async(() => {
|
||||
createFilter = createFilter.and.returnValue(Promise.reject(null));
|
||||
service.addFilter(filter).subscribe(
|
||||
service.addProcessFilter(filter).subscribe(
|
||||
() => {},
|
||||
(res) => {
|
||||
expect(res).toBe('Server error');
|
||||
|
@@ -17,7 +17,11 @@
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { RestVariable } from 'alfresco-js-api';
|
||||
import { AppDefinitionRepresentationModel, Comment, TaskDetailsModel, User } from 'ng2-activiti-tasklist';
|
||||
import {
|
||||
Comment,
|
||||
TaskDetailsModel,
|
||||
TaskListService,
|
||||
User } from 'ng2-activiti-tasklist';
|
||||
import { AlfrescoApiService, LogService } from 'ng2-alfresco-core';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { FilterProcessRepresentationModel } from '../models/filter-process.model';
|
||||
@@ -29,44 +33,22 @@ import { ProcessInstanceVariable } from './../models/process-instance-variable.m
|
||||
declare let moment: any;
|
||||
|
||||
@Injectable()
|
||||
export class ProcessService {
|
||||
export class ProcessService extends TaskListService {
|
||||
|
||||
constructor(private apiService: AlfrescoApiService,
|
||||
private logService: LogService) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all deployed apps
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
getDeployedApplications(name: string): Observable<AppDefinitionRepresentationModel> {
|
||||
return Observable.fromPromise(this.apiService.getInstance().activiti.appsApi.getAppDefinitions())
|
||||
.map((response: any) => response.data.find((app: AppDefinitionRepresentationModel) => app.name === name))
|
||||
.catch(err => this.handleError(err));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve deployed apps details by id
|
||||
* @param appId - number - optional - The id of app
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
getApplicationDetailsById(appId: number): Observable<any> {
|
||||
return Observable.fromPromise(this.apiService.getInstance().activiti.appsApi.getAppDefinitions())
|
||||
.map((response: any) => {
|
||||
return response.data.find(app => app.id === appId);
|
||||
})
|
||||
.catch(err => this.handleError(err));
|
||||
constructor(private alfrescoApiService: AlfrescoApiService,
|
||||
private processLogService: LogService) {
|
||||
super(alfrescoApiService, processLogService);
|
||||
}
|
||||
|
||||
getProcessInstances(requestNode: ProcessFilterRequestRepresentation): Observable<ProcessInstance[]> {
|
||||
return Observable.fromPromise(this.apiService.getInstance().activiti.processApi.getProcessInstances(requestNode))
|
||||
return Observable.fromPromise(this.alfrescoApiService.getInstance().activiti.processApi.getProcessInstances(requestNode))
|
||||
.map((res: any) => {
|
||||
if (requestNode.processDefinitionKey) {
|
||||
return res.data.filter(process => process.processDefinitionKey === requestNode.processDefinitionKey);
|
||||
} else {
|
||||
return res.data;
|
||||
}
|
||||
}).catch(err => this.handleError(err));
|
||||
}).catch(err => this.handleProcessError(err));
|
||||
}
|
||||
|
||||
getProcessFilters(appId: string): Observable<FilterProcessRepresentationModel[]> {
|
||||
@@ -79,7 +61,7 @@ export class ProcessService {
|
||||
});
|
||||
return filters;
|
||||
})
|
||||
.catch(err => this.handleError(err));
|
||||
.catch(err => this.handleProcessError(err));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,7 +74,7 @@ export class ProcessService {
|
||||
return Observable.fromPromise(this.callApiProcessFilters(appId))
|
||||
.map((response: any) => {
|
||||
return response.data.find(filter => filter.id === filterId);
|
||||
}).catch(err => this.handleError(err));
|
||||
}).catch(err => this.handleProcessError(err));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -105,7 +87,7 @@ export class ProcessService {
|
||||
return Observable.fromPromise(this.callApiProcessFilters(appId))
|
||||
.map((response: any) => {
|
||||
return response.data.find(filter => filter.name === filterName);
|
||||
}).catch(err => this.handleError(err));
|
||||
}).catch(err => this.handleProcessError(err));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,15 +95,15 @@ export class ProcessService {
|
||||
* @param appId
|
||||
* @returns {FilterProcessRepresentationModel[]}
|
||||
*/
|
||||
public createDefaultFilters(appId: string): Observable<FilterProcessRepresentationModel[]> {
|
||||
public createDefaultProcessFilters(appId: string): Observable<FilterProcessRepresentationModel[]> {
|
||||
let runnintFilter = this.getRunningFilterInstance(appId);
|
||||
let runnintObservable = this.addFilter(runnintFilter);
|
||||
let runnintObservable = this.addProcessFilter(runnintFilter);
|
||||
|
||||
let completedFilter = this.getCompletedFilterInstance(appId);
|
||||
let completedObservable = this.addFilter(completedFilter);
|
||||
let completedObservable = this.addProcessFilter(completedFilter);
|
||||
|
||||
let allFilter = this.getAllFilterInstance(appId);
|
||||
let allObservable = this.addFilter(allFilter);
|
||||
let allObservable = this.addProcessFilter(allFilter);
|
||||
|
||||
return Observable.create(observer => {
|
||||
Observable.forkJoin(
|
||||
@@ -144,7 +126,7 @@ export class ProcessService {
|
||||
observer.complete();
|
||||
},
|
||||
(err: any) => {
|
||||
this.logService.error(err);
|
||||
this.processLogService.error(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -194,17 +176,17 @@ export class ProcessService {
|
||||
* @param filter - FilterProcessRepresentationModel
|
||||
* @returns {FilterProcessRepresentationModel}
|
||||
*/
|
||||
addFilter(filter: FilterProcessRepresentationModel): Observable<FilterProcessRepresentationModel> {
|
||||
return Observable.fromPromise(this.callApiAddFilter(filter))
|
||||
addProcessFilter(filter: FilterProcessRepresentationModel): Observable<FilterProcessRepresentationModel> {
|
||||
return Observable.fromPromise(this.callApiAddProccessFilter(filter))
|
||||
.map(res => res)
|
||||
.map((response: FilterProcessRepresentationModel) => {
|
||||
return response;
|
||||
}).catch(err => this.handleError(err));
|
||||
}).catch(err => this.handleProcessError(err));
|
||||
}
|
||||
|
||||
getProcess(id: string): Observable<ProcessInstance> {
|
||||
return Observable.fromPromise(this.apiService.getInstance().activiti.processApi.getProcessInstance(id))
|
||||
.catch(err => this.handleError(err));
|
||||
return Observable.fromPromise(this.alfrescoApiService.getInstance().activiti.processApi.getProcessInstance(id))
|
||||
.catch(err => this.handleProcessError(err));
|
||||
}
|
||||
|
||||
getProcessTasks(id: string, state?: string): Observable<TaskDetailsModel[]> {
|
||||
@@ -214,13 +196,13 @@ export class ProcessService {
|
||||
} : {
|
||||
processInstanceId: id
|
||||
};
|
||||
return Observable.fromPromise(this.apiService.getInstance().activiti.taskApi.listTasks(taskOpts))
|
||||
return Observable.fromPromise(this.alfrescoApiService.getInstance().activiti.taskApi.listTasks(taskOpts))
|
||||
.map(this.extractData)
|
||||
.map(tasks => tasks.map((task: any) => {
|
||||
task.created = moment(task.created, 'YYYY-MM-DD').format();
|
||||
return task;
|
||||
}))
|
||||
.catch(err => this.handleError(err));
|
||||
.catch(err => this.handleProcessError(err));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -228,8 +210,8 @@ export class ProcessService {
|
||||
* @param id - process instance ID
|
||||
* @returns {<Comment[]>}
|
||||
*/
|
||||
getProcessInstanceComments(id: string): Observable<Comment[]> {
|
||||
return Observable.fromPromise(this.apiService.getInstance().activiti.commentsApi.getProcessInstanceComments(id))
|
||||
getComments(id: string): Observable<Comment[]> {
|
||||
return Observable.fromPromise(this.alfrescoApiService.getInstance().activiti.commentsApi.getProcessInstanceComments(id))
|
||||
.map(res => res)
|
||||
.map((response: any) => {
|
||||
let comments: Comment[] = [];
|
||||
@@ -243,7 +225,7 @@ export class ProcessService {
|
||||
comments.push(new Comment(comment.id, comment.message, comment.created, user));
|
||||
});
|
||||
return comments;
|
||||
}).catch(err => this.handleError(err));
|
||||
}).catch(err => this.handleProcessError(err));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -252,13 +234,13 @@ export class ProcessService {
|
||||
* @param message - content of the comment
|
||||
* @returns {Comment}
|
||||
*/
|
||||
addProcessInstanceComment(id: string, message: string): Observable<Comment> {
|
||||
addComment(id: string, message: string): Observable<Comment> {
|
||||
return Observable.fromPromise(
|
||||
this.apiService.getInstance().activiti.commentsApi.addProcessInstanceComment({ message: message }, id)
|
||||
this.alfrescoApiService.getInstance().activiti.commentsApi.addProcessInstanceComment({ message: message }, id)
|
||||
)
|
||||
.map((response: Comment) => {
|
||||
return new Comment(response.id, response.message, response.created, response.createdBy);
|
||||
}).catch(err => this.handleError(err));
|
||||
}).catch(err => this.handleProcessError(err));
|
||||
|
||||
}
|
||||
|
||||
@@ -270,11 +252,11 @@ export class ProcessService {
|
||||
latest: true
|
||||
};
|
||||
return Observable.fromPromise(
|
||||
this.apiService.getInstance().activiti.processApi.getProcessDefinitions(opts)
|
||||
this.alfrescoApiService.getInstance().activiti.processApi.getProcessDefinitions(opts)
|
||||
)
|
||||
.map(this.extractData)
|
||||
.map(processDefs => processDefs.map((pd) => new ProcessDefinitionRepresentation(pd)))
|
||||
.catch(err => this.handleError(err));
|
||||
.catch(err => this.handleProcessError(err));
|
||||
}
|
||||
|
||||
startProcess(processDefinitionId: string, name: string, outcome?: string, startFormValues?: any, variables?: RestVariable[]): Observable<ProcessInstance> {
|
||||
@@ -292,50 +274,50 @@ export class ProcessService {
|
||||
startRequest.variables = variables;
|
||||
}
|
||||
return Observable.fromPromise(
|
||||
this.apiService.getInstance().activiti.processApi.startNewProcessInstance(startRequest)
|
||||
this.alfrescoApiService.getInstance().activiti.processApi.startNewProcessInstance(startRequest)
|
||||
)
|
||||
.map((pd) => new ProcessInstance(pd))
|
||||
.catch(err => this.handleError(err));
|
||||
.catch(err => this.handleProcessError(err));
|
||||
}
|
||||
|
||||
cancelProcess(processInstanceId: string): Observable<void> {
|
||||
return Observable.fromPromise(
|
||||
this.apiService.getInstance().activiti.processApi.deleteProcessInstance(processInstanceId)
|
||||
this.alfrescoApiService.getInstance().activiti.processApi.deleteProcessInstance(processInstanceId)
|
||||
)
|
||||
.catch(err => this.handleError(err));
|
||||
.catch(err => this.handleProcessError(err));
|
||||
}
|
||||
|
||||
getProcessInstanceVariables(processDefinitionId: string): Observable<ProcessInstanceVariable[]> {
|
||||
return Observable.fromPromise(
|
||||
this.apiService.getInstance().activiti.processInstanceVariablesApi.getProcessInstanceVariables(processDefinitionId)
|
||||
this.alfrescoApiService.getInstance().activiti.processInstanceVariablesApi.getProcessInstanceVariables(processDefinitionId)
|
||||
)
|
||||
.map((processVars: any[]) => processVars.map((pd) => new ProcessInstanceVariable(pd)))
|
||||
.catch(err => this.handleError(err));
|
||||
.catch(err => this.handleProcessError(err));
|
||||
}
|
||||
|
||||
createOrUpdateProcessInstanceVariables(processDefinitionId: string, variables: ProcessInstanceVariable[]): Observable<ProcessInstanceVariable[]> {
|
||||
return Observable.fromPromise(
|
||||
this.apiService.getInstance().activiti.processInstanceVariablesApi.createOrUpdateProcessInstanceVariables(processDefinitionId, variables)
|
||||
this.alfrescoApiService.getInstance().activiti.processInstanceVariablesApi.createOrUpdateProcessInstanceVariables(processDefinitionId, variables)
|
||||
)
|
||||
.catch(err => this.handleError(err));
|
||||
.catch(err => this.handleProcessError(err));
|
||||
}
|
||||
|
||||
deleteProcessInstanceVariable(processDefinitionId: string, variableName: string): Observable<void> {
|
||||
return Observable.fromPromise(
|
||||
this.apiService.getInstance().activiti.processInstanceVariablesApi.deleteProcessInstanceVariable(processDefinitionId, variableName)
|
||||
this.alfrescoApiService.getInstance().activiti.processInstanceVariablesApi.deleteProcessInstanceVariable(processDefinitionId, variableName)
|
||||
)
|
||||
.catch(err => this.handleError(err));
|
||||
.catch(err => this.handleProcessError(err));
|
||||
}
|
||||
|
||||
private callApiAddFilter(filter: FilterProcessRepresentationModel) {
|
||||
return this.apiService.getInstance().activiti.userFiltersApi.createUserProcessInstanceFilter(filter);
|
||||
private callApiAddProccessFilter(filter: FilterProcessRepresentationModel) {
|
||||
return this.alfrescoApiService.getInstance().activiti.userFiltersApi.createUserProcessInstanceFilter(filter);
|
||||
}
|
||||
|
||||
callApiProcessFilters(appId?: string) {
|
||||
if (appId) {
|
||||
return this.apiService.getInstance().activiti.userFiltersApi.getUserProcessInstanceFilters({ appId: appId });
|
||||
return this.alfrescoApiService.getInstance().activiti.userFiltersApi.getUserProcessInstanceFilters({ appId: appId });
|
||||
} else {
|
||||
return this.apiService.getInstance().activiti.userFiltersApi.getUserProcessInstanceFilters();
|
||||
return this.alfrescoApiService.getInstance().activiti.userFiltersApi.getUserProcessInstanceFilters();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,7 +325,7 @@ export class ProcessService {
|
||||
return res.data || {};
|
||||
}
|
||||
|
||||
private handleError(error: any) {
|
||||
private handleProcessError(error: any) {
|
||||
return Observable.throw(error || 'Server error');
|
||||
}
|
||||
}
|
||||
|
@@ -23,3 +23,10 @@
|
||||
.adf-full-width {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
adf-comment-list {
|
||||
float: left;
|
||||
overflow: auto;
|
||||
height: calc(100% - 101px);
|
||||
width: 100%;
|
||||
}
|
@@ -66,12 +66,12 @@ describe('CommentsComponent', () => {
|
||||
component = fixture.componentInstance;
|
||||
service = fixture.debugElement.injector.get(TaskListService);
|
||||
|
||||
getCommentsSpy = spyOn(service, 'getTaskComments').and.returnValue(Observable.of([
|
||||
getCommentsSpy = spyOn(service, 'getComments').and.returnValue(Observable.of([
|
||||
{ message: 'Test1', created: Date.now(), createdBy: {firstName: 'Admin', lastName: 'User'} },
|
||||
{ message: 'Test2', created: Date.now(), createdBy: {firstName: 'Admin', lastName: 'User'} },
|
||||
{ message: 'Test3', created: Date.now(), createdBy: {firstName: 'Admin', lastName: 'User'} }
|
||||
]));
|
||||
addCommentSpy = spyOn(service, 'addTaskComment').and.returnValue(Observable.of({id: 123, message: 'Test Comment'}));
|
||||
addCommentSpy = spyOn(service, 'addComment').and.returnValue(Observable.of({id: 123, message: 'Test Comment'}));
|
||||
|
||||
componentHandler = jasmine.createSpyObj('componentHandler', [
|
||||
'upgradeAllRegistered',
|
||||
|
@@ -25,8 +25,7 @@ import { TaskListService } from '../services/tasklist.service';
|
||||
@Component({
|
||||
selector: 'adf-comments, activiti-comments',
|
||||
templateUrl: './comments.component.html',
|
||||
styleUrls: ['./comments.component.css'],
|
||||
providers: [TaskListService]
|
||||
styleUrls: ['./comments.component.css']
|
||||
})
|
||||
export class CommentsComponent implements OnChanges {
|
||||
|
||||
@@ -80,7 +79,7 @@ export class CommentsComponent implements OnChanges {
|
||||
private getTaskComments(taskId: string): void {
|
||||
this.resetComments();
|
||||
if (taskId) {
|
||||
this.activitiTaskList.getTaskComments(taskId).subscribe(
|
||||
this.activitiTaskList.getComments(taskId).subscribe(
|
||||
(res: Comment[]) => {
|
||||
res = res.sort((comment1: Comment, comment2: Comment) => {
|
||||
let date1 = new Date(comment1.created);
|
||||
@@ -106,7 +105,7 @@ export class CommentsComponent implements OnChanges {
|
||||
add(): void {
|
||||
if (this.message && this.message.trim() && !this.beingAdded) {
|
||||
this.beingAdded = true;
|
||||
this.activitiTaskList.addTaskComment(this.taskId, this.message).subscribe(
|
||||
this.activitiTaskList.addComment(this.taskId, this.message).subscribe(
|
||||
(res: Comment) => {
|
||||
this.comments.unshift(res);
|
||||
this.message = '';
|
||||
|
@@ -73,7 +73,7 @@ describe('TaskDetailsComponent', () => {
|
||||
getFormSpy = spyOn(formService, 'getTaskForm').and.returnValue(Observable.of(taskFormMock));
|
||||
getTasksSpy = spyOn(service, 'getTasks').and.returnValue(Observable.of(tasksMock));
|
||||
completeTaskSpy = spyOn(service, 'completeTask').and.returnValue(Observable.of({}));
|
||||
spyOn(service, 'getTaskComments').and.returnValue(Observable.of(noDataMock));
|
||||
spyOn(service, 'getComments').and.returnValue(Observable.of(noDataMock));
|
||||
spyOn(service, 'getTaskChecklist').and.returnValue(Observable.of(noDataMock));
|
||||
|
||||
componentHandler = jasmine.createSpyObj('componentHandler', [
|
||||
|
@@ -161,7 +161,7 @@ describe('Activiti TaskList Service', () => {
|
||||
});
|
||||
|
||||
it('should return the task list filtered', (done) => {
|
||||
service.getTasks(<TaskQueryRequestRepresentationModel>fakeFilter).subscribe(
|
||||
service.getTasks(<TaskQueryRequestRepresentationModel> fakeFilter).subscribe(
|
||||
res => {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.length).toEqual(1);
|
||||
@@ -181,7 +181,7 @@ describe('Activiti TaskList Service', () => {
|
||||
});
|
||||
|
||||
it('should return the task list filtered by processDefinitionKey', (done) => {
|
||||
service.getTasks(<TaskQueryRequestRepresentationModel>fakeFilterWithProcessDefinitionKey).subscribe(
|
||||
service.getTasks(<TaskQueryRequestRepresentationModel> fakeFilterWithProcessDefinitionKey).subscribe(
|
||||
res => {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.length).toEqual(1);
|
||||
@@ -202,7 +202,7 @@ describe('Activiti TaskList Service', () => {
|
||||
});
|
||||
|
||||
it('should throw an exception when the response is wrong', () => {
|
||||
service.getTasks(<TaskQueryRequestRepresentationModel>fakeFilter).subscribe(
|
||||
service.getTasks(<TaskQueryRequestRepresentationModel> fakeFilter).subscribe(
|
||||
(res) => {
|
||||
},
|
||||
(err: any) => {
|
||||
@@ -240,7 +240,7 @@ describe('Activiti TaskList Service', () => {
|
||||
});
|
||||
|
||||
it('should return the tasks comments ', (done) => {
|
||||
service.getTaskComments('999').subscribe(
|
||||
service.getComments('999').subscribe(
|
||||
(res: Comment[]) => {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.length).toEqual(2);
|
||||
@@ -327,7 +327,7 @@ describe('Activiti TaskList Service', () => {
|
||||
});
|
||||
|
||||
it('should add a comment task ', (done) => {
|
||||
service.addTaskComment('999', 'fake-comment-message').subscribe(
|
||||
service.addComment('999', 'fake-comment-message').subscribe(
|
||||
(res: Comment) => {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.id).not.toEqual('');
|
||||
@@ -367,7 +367,7 @@ describe('Activiti TaskList Service', () => {
|
||||
});
|
||||
|
||||
it('should return the total number of tasks', (done) => {
|
||||
service.getTotalTasks(<TaskQueryRequestRepresentationModel>fakeFilter).subscribe(
|
||||
service.getTotalTasks(<TaskQueryRequestRepresentationModel> fakeFilter).subscribe(
|
||||
res => {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.size).toEqual(1);
|
||||
|
@@ -178,7 +178,7 @@ export class TaskListService {
|
||||
* @param id - taskId
|
||||
* @returns {<Comment[]>}
|
||||
*/
|
||||
getTaskComments(id: string): Observable<Comment[]> {
|
||||
getComments(id: string): Observable<Comment[]> {
|
||||
return Observable.fromPromise(this.callApiTaskComments(id))
|
||||
.map(res => res)
|
||||
.map((response: any) => {
|
||||
@@ -321,7 +321,7 @@ export class TaskListService {
|
||||
* @param message - content of the comment
|
||||
* @returns {Comment}
|
||||
*/
|
||||
addTaskComment(id: string, message: string): Observable<Comment> {
|
||||
addComment(id: string, message: string): Observable<Comment> {
|
||||
return Observable.fromPromise(this.callApiAddTaskComment(id, message))
|
||||
.map(res => res)
|
||||
.map((response: Comment) => {
|
||||
|
Reference in New Issue
Block a user