mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-31 17:38:48 +00:00
@@ -1,123 +0,0 @@
|
|||||||
/*!
|
|
||||||
* @license
|
|
||||||
* Copyright 2016 Alfresco Software, Ltd.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { DatePipe } from '@angular/common';
|
|
||||||
import {
|
|
||||||
DataTableAdapter, ObjectDataTableAdapter, ObjectDataColumn,
|
|
||||||
DataRow, DataColumn, DataSorting
|
|
||||||
} from 'ng2-alfresco-datatable';
|
|
||||||
|
|
||||||
export class ProcessListDataTableAdapter extends ObjectDataTableAdapter implements DataTableAdapter {
|
|
||||||
|
|
||||||
ERR_ROW_NOT_FOUND: string = 'Row not found';
|
|
||||||
ERR_COL_NOT_FOUND: string = 'Column not found';
|
|
||||||
|
|
||||||
DEFAULT_DATE_FORMAT: string = 'medium';
|
|
||||||
|
|
||||||
private sorting: DataSorting;
|
|
||||||
private rows: DataRow[];
|
|
||||||
private columns: DataColumn[];
|
|
||||||
|
|
||||||
constructor(rows: any, schema: DataColumn[]) {
|
|
||||||
super(rows, schema);
|
|
||||||
this.rows = rows;
|
|
||||||
this.columns = schema || [];
|
|
||||||
}
|
|
||||||
|
|
||||||
getRows(): Array<DataRow> {
|
|
||||||
return this.rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: disable this api
|
|
||||||
setRows(rows: Array<DataRow>) {
|
|
||||||
this.rows = rows || [];
|
|
||||||
this.sort();
|
|
||||||
}
|
|
||||||
|
|
||||||
getColumns(): Array<DataColumn> {
|
|
||||||
return this.columns;
|
|
||||||
}
|
|
||||||
|
|
||||||
setColumns(columns: Array<DataColumn>) {
|
|
||||||
this.columns = columns || [];
|
|
||||||
}
|
|
||||||
|
|
||||||
getValue(row: DataRow, col: DataColumn): any {
|
|
||||||
if (!row) {
|
|
||||||
throw new Error(this.ERR_ROW_NOT_FOUND);
|
|
||||||
}
|
|
||||||
if (!col) {
|
|
||||||
throw new Error(this.ERR_COL_NOT_FOUND);
|
|
||||||
}
|
|
||||||
let value = row.getValue(col.key);
|
|
||||||
|
|
||||||
if (col.type === 'date') {
|
|
||||||
let datePipe = new DatePipe('en-US');
|
|
||||||
let format = (<ActivitiDataColumn>(col)).format || this.DEFAULT_DATE_FORMAT;
|
|
||||||
try {
|
|
||||||
return datePipe.transform(value, format);
|
|
||||||
} catch (err) {
|
|
||||||
console.error(`Error parsing date ${value} to format ${format}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
getSorting(): DataSorting {
|
|
||||||
return this.sorting;
|
|
||||||
}
|
|
||||||
|
|
||||||
setSorting(sorting: DataSorting): void {
|
|
||||||
this.sorting = sorting;
|
|
||||||
|
|
||||||
if (sorting && sorting.key && this.rows && this.rows.length > 0) {
|
|
||||||
this.rows.sort((a: DataRow, b: DataRow) => {
|
|
||||||
let left = a.getValue(sorting.key);
|
|
||||||
if (left) {
|
|
||||||
left = (left instanceof Date) ? left.valueOf().toString() : left.toString();
|
|
||||||
} else {
|
|
||||||
left = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
let right = b.getValue(sorting.key);
|
|
||||||
if (right) {
|
|
||||||
right = (right instanceof Date) ? right.valueOf().toString() : right.toString();
|
|
||||||
} else {
|
|
||||||
right = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
return sorting.direction === 'asc'
|
|
||||||
? left.localeCompare(right)
|
|
||||||
: right.localeCompare(left);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sort(key?: string, direction?: string): void {
|
|
||||||
let sorting = this.sorting || new DataSorting();
|
|
||||||
if (key) {
|
|
||||||
sorting.key = key;
|
|
||||||
sorting.direction = direction || 'asc';
|
|
||||||
}
|
|
||||||
this.setSorting(sorting);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class ActivitiDataColumn extends ObjectDataColumn {
|
|
||||||
format: string;
|
|
||||||
}
|
|
@@ -45,7 +45,7 @@ module.exports = function (config) {
|
|||||||
// ng2-components
|
// ng2-components
|
||||||
{ pattern: 'node_modules/ng2-alfresco-core/dist/**/*.*', included: false, served: true, watched: false },
|
{ pattern: 'node_modules/ng2-alfresco-core/dist/**/*.*', included: false, served: true, watched: false },
|
||||||
{ pattern: 'node_modules/ng2-alfresco-datatable/dist/**/*.*', included: false, served: true, watched: false },
|
{ pattern: 'node_modules/ng2-alfresco-datatable/dist/**/*.*', included: false, served: true, watched: false },
|
||||||
{ pattern: 'node_modules/ng2-activiti-tasklist/dist/**/*.js', included: false, served: true, watched: false },
|
{ pattern: 'node_modules/ng2-activiti-tasklist/dist/**/*.*', included: false, served: true, watched: false },
|
||||||
{ pattern: 'node_modules/ng2-activiti-form/dist/**/*.*', included: false, served: true, watched: false },
|
{ pattern: 'node_modules/ng2-activiti-form/dist/**/*.*', included: false, served: true, watched: false },
|
||||||
|
|
||||||
// paths to support debugging with source maps in dev tools
|
// paths to support debugging with source maps in dev tools
|
||||||
|
@@ -31,9 +31,22 @@ export class ProcessList {
|
|||||||
|
|
||||||
export class SingleProcessList extends ProcessList {
|
export class SingleProcessList extends ProcessList {
|
||||||
constructor(name?: string) {
|
constructor(name?: string) {
|
||||||
let instance = new ProcessInstance();
|
let instance = new ProcessInstance({
|
||||||
instance.id = '123';
|
id: '123',
|
||||||
instance.name = name;
|
name: name
|
||||||
|
});
|
||||||
super([instance]);
|
super([instance]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export var exampleProcess = new ProcessInstance({
|
||||||
|
id: '123',
|
||||||
|
name: 'Process 123',
|
||||||
|
started: '2016-11-10T03:37:30.010+0000',
|
||||||
|
startedBy: {
|
||||||
|
id: 1001,
|
||||||
|
firstName: 'Bob',
|
||||||
|
lastName: 'Jones',
|
||||||
|
email: 'bob@app.activiti.com'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
@@ -0,0 +1,192 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2016 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export var taskDetailsMock = {
|
||||||
|
'id': '91',
|
||||||
|
'name': 'Request translation',
|
||||||
|
'description': null,
|
||||||
|
'category': null,
|
||||||
|
'assignee': {'id': 1001, 'firstName': 'Wilbur', 'lastName': 'Adams', 'email': 'wilbur@app.activiti.com'},
|
||||||
|
'created': '2016-11-03T15:25:42.749+0000',
|
||||||
|
'dueDate': null,
|
||||||
|
'endDate': null,
|
||||||
|
'duration': null,
|
||||||
|
'priority': 50,
|
||||||
|
'parentTaskId': null,
|
||||||
|
'parentTaskName': null,
|
||||||
|
'processInstanceId': '86',
|
||||||
|
'processInstanceName': null,
|
||||||
|
'processDefinitionId': 'TranslationProcess:2:8',
|
||||||
|
'processDefinitionName': 'Translation Process',
|
||||||
|
'processDefinitionDescription': null,
|
||||||
|
'processDefinitionKey': 'TranslationProcess',
|
||||||
|
'processDefinitionCategory': 'http://www.activiti.org/processdef',
|
||||||
|
'processDefinitionVersion': 2,
|
||||||
|
'processDefinitionDeploymentId': '5',
|
||||||
|
'formKey': '4',
|
||||||
|
'processInstanceStartUserId': '1001',
|
||||||
|
'initiatorCanCompleteTask': false,
|
||||||
|
'adhocTaskCanBeReassigned': false,
|
||||||
|
'taskDefinitionKey': 'sid-DDECD9E4-0299-433F-9193-C3D905C3EEBE',
|
||||||
|
'executionId': '86',
|
||||||
|
'involvedPeople': [],
|
||||||
|
'memberOfCandidateUsers': false,
|
||||||
|
'managerOfCandidateGroup': false,
|
||||||
|
'memberOfCandidateGroup': false
|
||||||
|
};
|
||||||
|
|
||||||
|
export var taskFormMock = {
|
||||||
|
'id': 4,
|
||||||
|
'name': 'Translation request',
|
||||||
|
'processDefinitionId': 'TranslationProcess:2:8',
|
||||||
|
'processDefinitionName': 'Translation Process',
|
||||||
|
'processDefinitionKey': 'TranslationProcess',
|
||||||
|
'taskId': '91',
|
||||||
|
'taskName': 'Request translation',
|
||||||
|
'taskDefinitionKey': 'sid-DDECD9E4-0299-433F-9193-C3D905C3EEBE',
|
||||||
|
'tabs': [],
|
||||||
|
'fields': [{
|
||||||
|
'fieldType': 'ContainerRepresentation',
|
||||||
|
'id': '1478093984155',
|
||||||
|
'name': 'Label',
|
||||||
|
'type': 'container',
|
||||||
|
'value': null,
|
||||||
|
'required': false,
|
||||||
|
'readOnly': false,
|
||||||
|
'overrideId': false,
|
||||||
|
'colspan': 1,
|
||||||
|
'placeholder': null,
|
||||||
|
'minLength': 0,
|
||||||
|
'maxLength': 0,
|
||||||
|
'minValue': null,
|
||||||
|
'maxValue': null,
|
||||||
|
'regexPattern': null,
|
||||||
|
'optionType': null,
|
||||||
|
'hasEmptyValue': null,
|
||||||
|
'options': null,
|
||||||
|
'restUrl': null,
|
||||||
|
'restResponsePath': null,
|
||||||
|
'restIdProperty': null,
|
||||||
|
'restLabelProperty': null,
|
||||||
|
'tab': null,
|
||||||
|
'className': null,
|
||||||
|
'dateDisplayFormat': null,
|
||||||
|
'layout': null,
|
||||||
|
'sizeX': 2,
|
||||||
|
'sizeY': 1,
|
||||||
|
'row': -1,
|
||||||
|
'col': -1,
|
||||||
|
'visibilityCondition': null,
|
||||||
|
'numberOfColumns': 2,
|
||||||
|
'fields': {
|
||||||
|
'1': [{
|
||||||
|
'fieldType': 'AttachFileFieldRepresentation',
|
||||||
|
'id': 'originalcontent',
|
||||||
|
'name': 'Original content',
|
||||||
|
'type': 'upload',
|
||||||
|
'value': [],
|
||||||
|
'required': true,
|
||||||
|
'readOnly': false,
|
||||||
|
'overrideId': false,
|
||||||
|
'colspan': 1,
|
||||||
|
'placeholder': null,
|
||||||
|
'minLength': 0,
|
||||||
|
'maxLength': 0,
|
||||||
|
'minValue': null,
|
||||||
|
'maxValue': null,
|
||||||
|
'regexPattern': null,
|
||||||
|
'optionType': null,
|
||||||
|
'hasEmptyValue': null,
|
||||||
|
'options': null,
|
||||||
|
'restUrl': null,
|
||||||
|
'restResponsePath': null,
|
||||||
|
'restIdProperty': null,
|
||||||
|
'restLabelProperty': null,
|
||||||
|
'tab': null,
|
||||||
|
'className': null,
|
||||||
|
'params': {
|
||||||
|
},
|
||||||
|
'dateDisplayFormat': null,
|
||||||
|
'layout': {'row': -1, 'column': -1, 'colspan': 1},
|
||||||
|
'sizeX': 1,
|
||||||
|
'sizeY': 1,
|
||||||
|
'row': -1,
|
||||||
|
'col': -1,
|
||||||
|
'visibilityCondition': null,
|
||||||
|
'metaDataColumnDefinitions': []
|
||||||
|
}],
|
||||||
|
'2': [{
|
||||||
|
'fieldType': 'RestFieldRepresentation',
|
||||||
|
'id': 'language',
|
||||||
|
'name': 'Language',
|
||||||
|
'type': 'dropdown',
|
||||||
|
'value': 'Choose one...',
|
||||||
|
'required': true,
|
||||||
|
'readOnly': false,
|
||||||
|
'overrideId': false,
|
||||||
|
'colspan': 1,
|
||||||
|
'placeholder': null,
|
||||||
|
'minLength': 0,
|
||||||
|
'maxLength': 0,
|
||||||
|
'minValue': null,
|
||||||
|
'maxValue': null,
|
||||||
|
'regexPattern': null,
|
||||||
|
'optionType': null,
|
||||||
|
'hasEmptyValue': true,
|
||||||
|
'options': [{'id': 'empty', 'name': 'Choose one...'}, {'id': 'fr', 'name': 'French'}, {
|
||||||
|
'id': 'de',
|
||||||
|
'name': 'German'
|
||||||
|
}, {'id': 'es', 'name': 'Spanish'}],
|
||||||
|
'restUrl': null,
|
||||||
|
'restResponsePath': null,
|
||||||
|
'restIdProperty': null,
|
||||||
|
'restLabelProperty': null,
|
||||||
|
'tab': null,
|
||||||
|
'className': null,
|
||||||
|
'params': {'existingColspan': 1, 'maxColspan': 1},
|
||||||
|
'dateDisplayFormat': null,
|
||||||
|
'layout': {'row': -1, 'column': -1, 'colspan': 1},
|
||||||
|
'sizeX': 1,
|
||||||
|
'sizeY': 1,
|
||||||
|
'row': -1,
|
||||||
|
'col': -1,
|
||||||
|
'visibilityCondition': null,
|
||||||
|
'endpoint': null,
|
||||||
|
'requestHeaders': null
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
'outcomes': [],
|
||||||
|
'javascriptEvents': [],
|
||||||
|
'className': '',
|
||||||
|
'style': '',
|
||||||
|
'customFieldTemplates': {},
|
||||||
|
'metadata': {},
|
||||||
|
'variables': [],
|
||||||
|
'gridsterForm': false,
|
||||||
|
'globalDateFormat': 'D-M-YYYY'
|
||||||
|
};
|
||||||
|
|
||||||
|
export var tasksMock = {
|
||||||
|
data: [
|
||||||
|
taskDetailsMock
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
export var noDataMock = {
|
||||||
|
data: []
|
||||||
|
};
|
@@ -15,7 +15,7 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="comments?.length === 0">
|
<div *ngIf="comments?.length === 0" data-automation-id="comments-none">
|
||||||
{{ 'DETAILS.COMMENTS.NONE' | translate }}
|
{{ 'DETAILS.COMMENTS.NONE' | translate }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@@ -0,0 +1,191 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2016 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { SimpleChange } from '@angular/core';
|
||||||
|
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
|
import { Observable } from 'rxjs/Rx';
|
||||||
|
|
||||||
|
import { AlfrescoTranslationService, CoreModule } from 'ng2-alfresco-core';
|
||||||
|
import { ActivitiFormModule } from 'ng2-activiti-form';
|
||||||
|
|
||||||
|
import { ActivitiComments } from './activiti-comments.component';
|
||||||
|
import { ActivitiProcessService } from './../services/activiti-process.service';
|
||||||
|
import { TranslationMock } from './../assets/translation.service.mock';
|
||||||
|
|
||||||
|
describe('ActivitiProcessInstanceComments', () => {
|
||||||
|
|
||||||
|
let componentHandler: any;
|
||||||
|
let service: ActivitiProcessService;
|
||||||
|
let component: ActivitiComments;
|
||||||
|
let fixture: ComponentFixture<ActivitiComments>;
|
||||||
|
let getCommentsSpy: jasmine.Spy;
|
||||||
|
let addCommentSpy: jasmine.Spy;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [
|
||||||
|
CoreModule,
|
||||||
|
ActivitiFormModule
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
ActivitiComments
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
{ provide: AlfrescoTranslationService, useClass: TranslationMock },
|
||||||
|
ActivitiProcessService
|
||||||
|
]
|
||||||
|
}).compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(ActivitiComments);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
service = fixture.debugElement.injector.get(ActivitiProcessService);
|
||||||
|
|
||||||
|
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'}));
|
||||||
|
|
||||||
|
componentHandler = jasmine.createSpyObj('componentHandler', [
|
||||||
|
'upgradeAllRegistered',
|
||||||
|
'upgradeElement'
|
||||||
|
]);
|
||||||
|
window['componentHandler'] = componentHandler;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should load comments when processInstanceId specified', () => {
|
||||||
|
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({}));
|
||||||
|
component.processInstanceId = '123';
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(emitSpy).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not comments when no processInstanceId is specified', () => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(getCommentsSpy).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display comments when the process has comments', async(() => {
|
||||||
|
component.processInstanceId = '123';
|
||||||
|
fixture.detectChanges();
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(fixture.debugElement.queryAll(By.css('ul.mdl-list li')).length).toBe(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);
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('change detection', () => {
|
||||||
|
|
||||||
|
let change = new SimpleChange('123', '456');
|
||||||
|
let nullChange = new SimpleChange('123', null);
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
component.processInstanceId = '123';
|
||||||
|
fixture.detectChanges();
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
getCommentsSpy.calls.reset();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should fetch new comments when processInstanceId changed', () => {
|
||||||
|
component.ngOnChanges({ 'processInstanceId': change });
|
||||||
|
expect(getCommentsSpy).toHaveBeenCalledWith('456');
|
||||||
|
});
|
||||||
|
|
||||||
|
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 });
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(fixture.debugElement.query(By.css('[data-automation-id="comments-none"]'))).not.toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Add comment', () => {
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
component.processInstanceId = '123';
|
||||||
|
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();
|
||||||
|
});
|
||||||
|
|
||||||
|
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,7 +15,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Component, Input, OnInit, ViewChild, OnChanges, SimpleChanges } from '@angular/core';
|
import { Component, EventEmitter, Input, Output, OnInit, ViewChild, OnChanges, SimpleChanges } from '@angular/core';
|
||||||
import { AlfrescoTranslationService } from 'ng2-alfresco-core';
|
import { AlfrescoTranslationService } from 'ng2-alfresco-core';
|
||||||
import { ActivitiProcessService } from './../services/activiti-process.service';
|
import { ActivitiProcessService } from './../services/activiti-process.service';
|
||||||
import { Comment } from 'ng2-activiti-tasklist';
|
import { Comment } from 'ng2-activiti-tasklist';
|
||||||
@@ -23,6 +23,7 @@ import { Observer } from 'rxjs/Observer';
|
|||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
|
|
||||||
declare let componentHandler: any;
|
declare let componentHandler: any;
|
||||||
|
declare let dialogPolyfill: any;
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'activiti-process-instance-comments',
|
selector: 'activiti-process-instance-comments',
|
||||||
@@ -36,6 +37,9 @@ export class ActivitiComments implements OnInit, OnChanges {
|
|||||||
@Input()
|
@Input()
|
||||||
processInstanceId: string;
|
processInstanceId: string;
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
error: EventEmitter<any> = new EventEmitter<any>();
|
||||||
|
|
||||||
@ViewChild('dialog')
|
@ViewChild('dialog')
|
||||||
dialog: any;
|
dialog: any;
|
||||||
|
|
||||||
@@ -48,8 +52,8 @@ export class ActivitiComments implements OnInit, OnChanges {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* @param auth
|
* @param translate Translation service
|
||||||
* @param translate
|
* @param activitiProcess Process service
|
||||||
*/
|
*/
|
||||||
constructor(private translate: AlfrescoTranslationService,
|
constructor(private translate: AlfrescoTranslationService,
|
||||||
private activitiProcess: ActivitiProcessService) {
|
private activitiProcess: ActivitiProcessService) {
|
||||||
@@ -66,17 +70,24 @@ export class ActivitiComments implements OnInit, OnChanges {
|
|||||||
this.comment$.subscribe((comment: Comment) => {
|
this.comment$.subscribe((comment: Comment) => {
|
||||||
this.comments.push(comment);
|
this.comments.push(comment);
|
||||||
});
|
});
|
||||||
}
|
if (this.processInstanceId) {
|
||||||
|
this.getProcessComments(this.processInstanceId);
|
||||||
ngOnChanges(changes: SimpleChanges) {
|
|
||||||
let processInstanceId = changes['processInstanceId'];
|
|
||||||
if (processInstanceId && processInstanceId.currentValue) {
|
|
||||||
this.getProcessComments(processInstanceId.currentValue);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public getProcessComments(processInstanceId: string) {
|
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 = [];
|
this.comments = [];
|
||||||
if (processInstanceId) {
|
if (processInstanceId) {
|
||||||
this.activitiProcess.getProcessInstanceComments(processInstanceId).subscribe(
|
this.activitiProcess.getProcessInstanceComments(processInstanceId).subscribe(
|
||||||
@@ -86,15 +97,22 @@ export class ActivitiComments implements OnInit, OnChanges {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
(err) => {
|
(err) => {
|
||||||
console.log(err);
|
this.error.emit(err);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
this.comments = [];
|
this.resetComments();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private resetComments() {
|
||||||
|
this.comments = [];
|
||||||
|
}
|
||||||
|
|
||||||
public showDialog() {
|
public showDialog() {
|
||||||
|
if (!this.dialog.nativeElement.showModal) {
|
||||||
|
dialogPolyfill.registerDialog(this.dialog.nativeElement);
|
||||||
|
}
|
||||||
if (this.dialog) {
|
if (this.dialog) {
|
||||||
this.dialog.nativeElement.showModal();
|
this.dialog.nativeElement.showModal();
|
||||||
}
|
}
|
||||||
@@ -107,7 +125,7 @@ export class ActivitiComments implements OnInit, OnChanges {
|
|||||||
this.message = '';
|
this.message = '';
|
||||||
},
|
},
|
||||||
(err) => {
|
(err) => {
|
||||||
console.log(err);
|
this.error.emit(err);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
this.cancel();
|
this.cancel();
|
||||||
|
@@ -0,0 +1,160 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2016 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { SimpleChange } from '@angular/core';
|
||||||
|
import { ActivitiProcessFilters } from './activiti-filters.component';
|
||||||
|
import { ActivitiProcessService } from '../services/activiti-process.service';
|
||||||
|
import { Observable } from 'rxjs/Rx';
|
||||||
|
import { FilterRepresentationModel } from 'ng2-activiti-tasklist';
|
||||||
|
|
||||||
|
describe('ActivitiFilters', () => {
|
||||||
|
|
||||||
|
let filterList: ActivitiProcessFilters;
|
||||||
|
let activitiService: ActivitiProcessService;
|
||||||
|
|
||||||
|
let fakeGlobalFilter = [];
|
||||||
|
fakeGlobalFilter.push(new FilterRepresentationModel({name: 'FakeInvolvedTasks', filter: { state: 'open', assignment: 'fake-involved'}}));
|
||||||
|
fakeGlobalFilter.push(new FilterRepresentationModel({name: 'FakeMyTasks', filter: { state: 'open', assignment: 'fake-assignee'}}));
|
||||||
|
|
||||||
|
let fakeGlobalFilterPromise = new Promise(function (resolve, reject) {
|
||||||
|
resolve(fakeGlobalFilter);
|
||||||
|
});
|
||||||
|
|
||||||
|
let fakeErrorFilterList = {
|
||||||
|
error: 'wrong request'
|
||||||
|
};
|
||||||
|
|
||||||
|
let fakeErrorFilterPromise = new Promise(function (resolve, reject) {
|
||||||
|
reject(fakeErrorFilterList);
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
activitiService = new ActivitiProcessService(null);
|
||||||
|
filterList = new ActivitiProcessFilters(null, activitiService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the filter task list', (done) => {
|
||||||
|
spyOn(activitiService, 'getProcessFilters').and.returnValue(Observable.fromPromise(fakeGlobalFilterPromise));
|
||||||
|
|
||||||
|
filterList.onSuccess.subscribe((res) => {
|
||||||
|
expect(res).toBeDefined();
|
||||||
|
expect(filterList.filters).toBeDefined();
|
||||||
|
expect(filterList.filters.length).toEqual(2);
|
||||||
|
expect(filterList.filters[0].name).toEqual('FakeInvolvedTasks');
|
||||||
|
expect(filterList.filters[1].name).toEqual('FakeMyTasks');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
filterList.ngOnInit();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the filter task list, filtered By Name', (done) => {
|
||||||
|
|
||||||
|
let fakeDeployedApplicationsPromise = new Promise(function (resolve, reject) {
|
||||||
|
resolve({});
|
||||||
|
});
|
||||||
|
|
||||||
|
spyOn(activitiService, 'getDeployedApplications').and.returnValue(Observable.fromPromise(fakeDeployedApplicationsPromise));
|
||||||
|
spyOn(activitiService, 'getProcessFilters').and.returnValue(Observable.fromPromise(fakeGlobalFilterPromise));
|
||||||
|
|
||||||
|
filterList.appName = 'test';
|
||||||
|
|
||||||
|
filterList.onSuccess.subscribe((res) => {
|
||||||
|
let deployApp: any = activitiService.getDeployedApplications;
|
||||||
|
expect(deployApp.calls.count()).toEqual(1);
|
||||||
|
expect(res).toBeDefined();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
filterList.ngOnInit();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should emit an error with a bad response', (done) => {
|
||||||
|
filterList.appId = '1';
|
||||||
|
spyOn(activitiService, 'getProcessFilters').and.returnValue(Observable.fromPromise(fakeErrorFilterPromise));
|
||||||
|
|
||||||
|
filterList.onError.subscribe((err) => {
|
||||||
|
expect(err).toBeDefined();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
filterList.ngOnInit();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should emit an error with a bad response', (done) => {
|
||||||
|
filterList.appName = 'fake-app';
|
||||||
|
spyOn(activitiService, 'getDeployedApplications').and.returnValue(Observable.fromPromise(fakeErrorFilterPromise));
|
||||||
|
|
||||||
|
filterList.onError.subscribe((err) => {
|
||||||
|
expect(err).toBeDefined();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
filterList.ngOnInit();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should emit an event when a filter is selected', (done) => {
|
||||||
|
let currentFilter = new FilterRepresentationModel({filter: { state: 'open', assignment: 'fake-involved'}});
|
||||||
|
|
||||||
|
filterList.filterClick.subscribe((filter: FilterRepresentationModel) => {
|
||||||
|
expect(filter).toBeDefined();
|
||||||
|
expect(filter).toEqual(currentFilter);
|
||||||
|
expect(filterList.currentFilter).toEqual(currentFilter);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
filterList.selectFilter(currentFilter);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should reload filters by appId on binding changes', () => {
|
||||||
|
spyOn(filterList, 'getFiltersByAppId').and.stub();
|
||||||
|
const appId = '1';
|
||||||
|
|
||||||
|
let change = new SimpleChange(null, appId);
|
||||||
|
filterList.ngOnChanges({ 'appId': change });
|
||||||
|
|
||||||
|
expect(filterList.getFiltersByAppId).toHaveBeenCalledWith(appId);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should reload filters by appId null on binding changes', () => {
|
||||||
|
spyOn(filterList, 'getFiltersByAppId').and.stub();
|
||||||
|
const appId = null;
|
||||||
|
|
||||||
|
let change = new SimpleChange(null, appId);
|
||||||
|
filterList.ngOnChanges({ 'appId': change });
|
||||||
|
|
||||||
|
expect(filterList.getFiltersByAppId).toHaveBeenCalledWith(appId);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should reload filters by app name on binding changes', () => {
|
||||||
|
spyOn(filterList, 'getFiltersByAppName').and.stub();
|
||||||
|
const appName = 'fake-app-name';
|
||||||
|
|
||||||
|
let change = new SimpleChange(null, appName);
|
||||||
|
filterList.ngOnChanges({ 'appName': change });
|
||||||
|
|
||||||
|
expect(filterList.getFiltersByAppName).toHaveBeenCalledWith(appName);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the current filter after one is selected', () => {
|
||||||
|
let filter = new FilterRepresentationModel({name: 'FakeMyTasks', filter: { state: 'open', assignment: 'fake-assignee'}});
|
||||||
|
expect(filterList.currentFilter).toBeUndefined();
|
||||||
|
filterList.selectFilter(filter);
|
||||||
|
expect(filterList.getCurrentFilter()).toBe(filter);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@@ -4,7 +4,11 @@
|
|||||||
<activiti-process-instance-header [processInstance]="processInstanceDetails" (processCancelled)="bubbleProcessCancelled()" #activitiprocessheader></activiti-process-instance-header>
|
<activiti-process-instance-header [processInstance]="processInstanceDetails" (processCancelled)="bubbleProcessCancelled()" #activitiprocessheader></activiti-process-instance-header>
|
||||||
<div class="mdl-grid">
|
<div class="mdl-grid">
|
||||||
<div class="mdl-cell mdl-cell--8-col">
|
<div class="mdl-cell mdl-cell--8-col">
|
||||||
|
<<<<<<< HEAD
|
||||||
<activiti-process-instance-tasks [processInstanceDetails]="processInstanceDetails" (taskFormCompleted)="bubbleTaskFormCompleted()" #activitiprocesstasks></activiti-process-instance-tasks>
|
<activiti-process-instance-tasks [processInstanceDetails]="processInstanceDetails" (taskFormCompleted)="bubbleTaskFormCompleted()" #activitiprocesstasks></activiti-process-instance-tasks>
|
||||||
|
=======
|
||||||
|
<activiti-process-instance-tasks [processInstanceId]="processInstanceDetails.id" (taskFormCompleted)="onTaskFormCompleted()" #activitiprocesstasks></activiti-process-instance-tasks>
|
||||||
|
>>>>>>> New tests for processlist components
|
||||||
</div>
|
</div>
|
||||||
<div class="mdl-cell mdl-cell--4-col">
|
<div class="mdl-cell mdl-cell--4-col">
|
||||||
<activiti-process-instance-comments [processInstanceId]="processInstanceDetails.id" #activitiprocesscomments></activiti-process-instance-comments>
|
<activiti-process-instance-comments [processInstanceId]="processInstanceDetails.id" #activitiprocesscomments></activiti-process-instance-comments>
|
||||||
|
@@ -0,0 +1,165 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2016 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { NO_ERRORS_SCHEMA, DebugElement, SimpleChange } from '@angular/core';
|
||||||
|
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
|
import { Observable } from 'rxjs/Rx';
|
||||||
|
|
||||||
|
import { AlfrescoTranslationService, CoreModule } from 'ng2-alfresco-core';
|
||||||
|
import { ActivitiFormModule, FormModel, FormOutcomeEvent, FormOutcomeModel, FormService } from 'ng2-activiti-form';
|
||||||
|
import { ActivitiTaskListModule } from 'ng2-activiti-tasklist';
|
||||||
|
|
||||||
|
import { ActivitiProcessInstanceDetails } from './activiti-process-instance-details.component';
|
||||||
|
import { ActivitiProcessService } from './../services/activiti-process.service';
|
||||||
|
import { TranslationMock } from './../assets/translation.service.mock';
|
||||||
|
import { exampleProcess } from './../assets/activiti-process.model.mock';
|
||||||
|
|
||||||
|
describe('ActivitiProcessInstanceDetails', () => {
|
||||||
|
|
||||||
|
let componentHandler: any;
|
||||||
|
let service: ActivitiProcessService;
|
||||||
|
let formService: FormService;
|
||||||
|
let component: ActivitiProcessInstanceDetails;
|
||||||
|
let fixture: ComponentFixture<ActivitiProcessInstanceDetails>;
|
||||||
|
let getProcessSpy: jasmine.Spy;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [
|
||||||
|
CoreModule,
|
||||||
|
ActivitiFormModule,
|
||||||
|
ActivitiTaskListModule
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
ActivitiProcessInstanceDetails
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
{ provide: AlfrescoTranslationService, useClass: TranslationMock },
|
||||||
|
ActivitiProcessService
|
||||||
|
],
|
||||||
|
schemas: [ NO_ERRORS_SCHEMA ]
|
||||||
|
}).compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(ActivitiProcessInstanceDetails);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
service = fixture.debugElement.injector.get(ActivitiProcessService);
|
||||||
|
formService = fixture.debugElement.injector.get(FormService);
|
||||||
|
|
||||||
|
getProcessSpy = spyOn(service, 'getProcess').and.returnValue(Observable.of(exampleProcess));
|
||||||
|
|
||||||
|
componentHandler = jasmine.createSpyObj('componentHandler', [
|
||||||
|
'upgradeAllRegistered',
|
||||||
|
'upgradeElement'
|
||||||
|
]);
|
||||||
|
window['componentHandler'] = componentHandler;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should load task details when processInstanceId specified', () => {
|
||||||
|
component.processInstanceId = '123';
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(getProcessSpy).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not load task details when no processInstanceId is specified', () => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(getProcessSpy).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set a placeholder message when processInstanceId not initialised', () => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(fixture.nativeElement.innerText).toBe('DETAILS.MESSAGES.NONE');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display a header when the processInstanceId is provided', async(() => {
|
||||||
|
component.processInstanceId = '123';
|
||||||
|
fixture.detectChanges();
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
let headerEl: DebugElement = fixture.debugElement.query(By.css('h2'));
|
||||||
|
expect(headerEl).not.toBeNull();
|
||||||
|
expect(headerEl.nativeElement.innerText).toBe('Process 123');
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('change detection', () => {
|
||||||
|
|
||||||
|
let change = new SimpleChange('123', '456');
|
||||||
|
let nullChange = new SimpleChange('123', null);
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
component.processInstanceId = '123';
|
||||||
|
fixture.detectChanges();
|
||||||
|
component.tasksList = jasmine.createSpyObj('tasksList', ['load']);
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
getProcessSpy.calls.reset();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should fetch new process details when processInstanceId changed', () => {
|
||||||
|
component.ngOnChanges({ 'processInstanceId': change });
|
||||||
|
expect(getProcessSpy).toHaveBeenCalledWith('456');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should reload tasks list when processInstanceId changed', () => {
|
||||||
|
component.ngOnChanges({ 'processInstanceId': change });
|
||||||
|
expect(component.tasksList.load).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should NOT fetch new process details when empty changeset made', () => {
|
||||||
|
component.ngOnChanges({});
|
||||||
|
expect(getProcessSpy).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should NOT fetch new process details when processInstanceId changed to null', () => {
|
||||||
|
component.ngOnChanges({ 'processInstanceId': nullChange });
|
||||||
|
expect(getProcessSpy).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set a placeholder message when processInstanceId changed to null', () => {
|
||||||
|
component.ngOnChanges({ 'processInstanceId': nullChange });
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(fixture.nativeElement.innerText).toBe('DETAILS.MESSAGES.NONE');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('events', () => {
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
component.processInstanceId = '123';
|
||||||
|
fixture.detectChanges();
|
||||||
|
fixture.whenStable();
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should emit a task form completed event when task form completed', () => {
|
||||||
|
let emitSpy: jasmine.Spy = spyOn(component.taskFormCompleted, 'emit');
|
||||||
|
component.bubbleTaskFormCompleted(new FormModel());
|
||||||
|
expect(emitSpy).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should emit a outcome execution event when task form outcome executed', () => {
|
||||||
|
let emitSpy: jasmine.Spy = spyOn(component.processCancelled, 'emit');
|
||||||
|
component.bubbleProcessCancelled(new FormOutcomeEvent(new FormOutcomeModel(new FormModel())));
|
||||||
|
expect(emitSpy).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@@ -61,9 +61,8 @@ export class ActivitiProcessInstanceDetails implements OnInit, OnChanges {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* @param auth
|
* @param translate Translation service
|
||||||
* @param translate
|
* @param activitiProcess Process service
|
||||||
* @param activitiProcess
|
|
||||||
*/
|
*/
|
||||||
constructor(private translate: AlfrescoTranslationService,
|
constructor(private translate: AlfrescoTranslationService,
|
||||||
private activitiProcess: ActivitiProcessService) {
|
private activitiProcess: ActivitiProcessService) {
|
||||||
|
@@ -1,15 +1,19 @@
|
|||||||
<div *ngIf="processInstance">
|
<div *ngIf="processInstance">
|
||||||
<div class="mdl-grid">
|
<div class="mdl-grid">
|
||||||
<div class="mdl-cell mdl-cell--4-col">
|
<div class="mdl-cell mdl-cell--4-col" data-automation-id="header-started-by">
|
||||||
<span class="activiti-label">{{ 'DETAILS.LABELS.STARTED_BY' | translate }}</span>:
|
<span class="activiti-label">{{ 'DETAILS.LABELS.STARTED_BY' | translate }}</span>:
|
||||||
{{getStartedByFullName()}}
|
<span class="activiti-process-header__value">{{getStartedByFullName()}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="mdl-cell mdl-cell--4-col">
|
<div class="mdl-cell mdl-cell--4-col" data-automation-id="header-started">
|
||||||
<span class="activiti-label">{{ 'DETAILS.LABELS.STARTED' | translate }}</span>:
|
<span class="activiti-label">{{ 'DETAILS.LABELS.STARTED' | translate }}</span>:
|
||||||
{{getFormatDate(processInstance.started, 'medium')}}
|
<span class="activiti-process-header__value">{{getFormatDate(processInstance.started, 'medium')}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="mdl-cell mdl-cell--4-col">
|
<div class="mdl-cell mdl-cell--4-col" data-automation-id="header-status" *ngIf="isRunning()">
|
||||||
<button type="button" (click)="cancelProcess()" class="mdl-button">{{ 'DETAILS.BUTTON.CANCEL' | translate }}</button>
|
<button type="button" (click)="cancelProcess()" class="mdl-button">{{ 'DETAILS.BUTTON.CANCEL' | translate }}</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mdl-cell mdl-cell--4-col" data-automation-id="header-status" *ngIf="!isRunning()">
|
||||||
|
<span class="activiti-label">{{ 'DETAILS.LABELS.ENDED' | translate }}</span>:
|
||||||
|
<span class="activiti-process-header__value">{{getFormatDate(processInstance.ended, 'medium')}}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -0,0 +1,108 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2016 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
|
|
||||||
|
import { AlfrescoTranslationService, CoreModule } from 'ng2-alfresco-core';
|
||||||
|
|
||||||
|
import { ActivitiProcessInstanceHeader } from './activiti-process-instance-header.component';
|
||||||
|
import { TranslationMock } from './../assets/translation.service.mock';
|
||||||
|
import { exampleProcess } from './../assets/activiti-process.model.mock';
|
||||||
|
import { ProcessInstance } from './../models/process-instance';
|
||||||
|
import { ActivitiProcessService } from './../services/activiti-process.service';
|
||||||
|
|
||||||
|
describe('ActivitiProcessInstanceHeader', () => {
|
||||||
|
|
||||||
|
let componentHandler: any;
|
||||||
|
let component: ActivitiProcessInstanceHeader;
|
||||||
|
let fixture: ComponentFixture<ActivitiProcessInstanceHeader>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [
|
||||||
|
CoreModule
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
ActivitiProcessInstanceHeader
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
{ provide: AlfrescoTranslationService, useClass: TranslationMock },
|
||||||
|
ActivitiProcessService
|
||||||
|
]
|
||||||
|
}).compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(ActivitiProcessInstanceHeader);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
|
||||||
|
component.processInstance = new ProcessInstance(exampleProcess);
|
||||||
|
|
||||||
|
componentHandler = jasmine.createSpyObj('componentHandler', [
|
||||||
|
'upgradeAllRegistered',
|
||||||
|
'upgradeElement'
|
||||||
|
]);
|
||||||
|
window['componentHandler'] = componentHandler;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render empty component if no form details provided', () => {
|
||||||
|
component.processInstance = undefined;
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(fixture.debugElement.children.length).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display started by user', () => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
let formValueEl = fixture.debugElement.query(By.css('[data-automation-id="header-started-by"] .activiti-process-header__value'));
|
||||||
|
expect(formValueEl).not.toBeNull();
|
||||||
|
expect(formValueEl.nativeElement.innerText).toBe('Bob Jones');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display empty started by user if user unknown', () => {
|
||||||
|
component.processInstance.startedBy = null;
|
||||||
|
fixture.detectChanges();
|
||||||
|
let formValueEl = fixture.debugElement.query(By.css('[data-automation-id="header-started-by"] .activiti-process-header__value'));
|
||||||
|
expect(formValueEl).not.toBeNull();
|
||||||
|
expect(formValueEl.nativeElement.innerText).toBe('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display process start date', () => {
|
||||||
|
component.processInstance.started = '2016-11-10T03:37:30.010+0000';
|
||||||
|
fixture.detectChanges();
|
||||||
|
let formValueEl = fixture.debugElement.query(By.css('[data-automation-id="header-started"] .activiti-process-header__value'));
|
||||||
|
expect(formValueEl).not.toBeNull();
|
||||||
|
expect(formValueEl.nativeElement.innerText).toBe('Nov 10, 2016, 3:37:30 AM');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display cancel button if process is running', () => {
|
||||||
|
component.processInstance.ended = null;
|
||||||
|
fixture.detectChanges();
|
||||||
|
let buttonEl = fixture.debugElement.query(By.css('[data-automation-id="header-status"] button'));
|
||||||
|
expect(buttonEl).not.toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display ended date if process is ended', () => {
|
||||||
|
component.processInstance.ended = '2016-11-10T03:37:30.010+0000';
|
||||||
|
fixture.detectChanges();
|
||||||
|
let formValueEl = fixture.debugElement.query(By.css('[data-automation-id="header-status"] .activiti-process-header__value'));
|
||||||
|
expect(formValueEl).not.toBeNull();
|
||||||
|
expect(formValueEl.nativeElement.innerText).toBe('Nov 10, 2016, 3:37:30 AM');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@@ -48,7 +48,7 @@ export class ActivitiProcessInstanceHeader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getStartedByFullName() {
|
getStartedByFullName(): string {
|
||||||
if (this.processInstance && this.processInstance.startedBy) {
|
if (this.processInstance && this.processInstance.startedBy) {
|
||||||
return (this.processInstance.startedBy.firstName && this.processInstance.startedBy.firstName !== 'null'
|
return (this.processInstance.startedBy.firstName && this.processInstance.startedBy.firstName !== 'null'
|
||||||
? this.processInstance.startedBy.firstName + ' ' : '') +
|
? this.processInstance.startedBy.firstName + ' ' : '') +
|
||||||
@@ -66,6 +66,10 @@ export class ActivitiProcessInstanceHeader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isRunning(): boolean {
|
||||||
|
return this.processInstance && !this.processInstance.ended;
|
||||||
|
}
|
||||||
|
|
||||||
cancelProcess() {
|
cancelProcess() {
|
||||||
this.activitiProcess.cancelProcess(this.processInstance.id).subscribe(
|
this.activitiProcess.cancelProcess(this.processInstance.id).subscribe(
|
||||||
(res) => {
|
(res) => {
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
<span class="activiti-label mdl-badge"
|
<span class="activiti-label mdl-badge"
|
||||||
[attr.data-badge]="activeTasks?.length">{{ 'DETAILS.LABELS.TASKS_ACTIVE'|translate }}</span>
|
[attr.data-badge]="activeTasks?.length">{{ 'DETAILS.LABELS.TASKS_ACTIVE'|translate }}</span>
|
||||||
|
|
||||||
<div class="menu-container" *ngIf="activeTasks?.length > 0">
|
<div class="menu-container" *ngIf="activeTasks?.length > 0" data-automation-id="active-tasks">
|
||||||
<ul class='mdl-list'>
|
<ul class='mdl-list'>
|
||||||
<li class="mdl-list__item mdl-list__item--two-line" *ngFor="let task of activeTasks">
|
<li class="mdl-list__item mdl-list__item--two-line" *ngFor="let task of activeTasks">
|
||||||
<span class="mdl-list__item-primary-content" (click)="clickTask($event, task)">
|
<span class="mdl-list__item-primary-content" (click)="clickTask($event, task)">
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
<!-- START FORM -->
|
<!-- START FORM -->
|
||||||
|
|
||||||
<div *ngIf="activeTasks?.length === 0">
|
<div *ngIf="activeTasks?.length === 0" data-automation-id="active-tasks-none">
|
||||||
{{ 'DETAILS.TASKS.NO_ACTIVE' | translate }}
|
{{ 'DETAILS.TASKS.NO_ACTIVE' | translate }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
<span class="activiti-label mdl-badge"
|
<span class="activiti-label mdl-badge"
|
||||||
[attr.data-badge]="completedTasks?.length">{{ 'DETAILS.LABELS.TASKS_COMPLETED'|translate }}</span>
|
[attr.data-badge]="completedTasks?.length">{{ 'DETAILS.LABELS.TASKS_COMPLETED'|translate }}</span>
|
||||||
|
|
||||||
<div class="menu-container" *ngIf="completedTasks?.length > 0">
|
<div class="menu-container" *ngIf="completedTasks?.length > 0" data-automation-id="completed-tasks">
|
||||||
<ul class='mdl-list'>
|
<ul class='mdl-list'>
|
||||||
<li class="mdl-list__item mdl-list__item--two-line" *ngFor="let task of completedTasks">
|
<li class="mdl-list__item mdl-list__item--two-line" *ngFor="let task of completedTasks">
|
||||||
<span class="mdl-list__item-primary-content" (click)="clickTask($event, task)">
|
<span class="mdl-list__item-primary-content" (click)="clickTask($event, task)">
|
||||||
@@ -64,7 +64,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngIf="completedTasks?.length === 0">
|
<div *ngIf="completedTasks?.length === 0" data-automation-id="completed-tasks-none">
|
||||||
{{ 'DETAILS.TASKS.NO_COMPLETED' | translate }}
|
{{ 'DETAILS.TASKS.NO_COMPLETED' | translate }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@@ -0,0 +1,206 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2016 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
|
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
|
import { Observable } from 'rxjs/Rx';
|
||||||
|
|
||||||
|
import { AlfrescoTranslationService, CoreModule } from 'ng2-alfresco-core';
|
||||||
|
import { TaskDetailsModel } from 'ng2-activiti-tasklist';
|
||||||
|
|
||||||
|
import { ActivitiProcessInstanceTasks } from './activiti-process-instance-tasks.component';
|
||||||
|
import { TranslationMock } from './../assets/translation.service.mock';
|
||||||
|
import { taskDetailsMock } from './../assets/task-details.mock';
|
||||||
|
import { ProcessInstance } from './../models/process-instance';
|
||||||
|
import { ActivitiProcessService } from './../services/activiti-process.service';
|
||||||
|
|
||||||
|
describe('ActivitiProcessInstanceTasks', () => {
|
||||||
|
|
||||||
|
let componentHandler: any;
|
||||||
|
let component: ActivitiProcessInstanceTasks;
|
||||||
|
let fixture: ComponentFixture<ActivitiProcessInstanceTasks>;
|
||||||
|
let service: ActivitiProcessService;
|
||||||
|
let getProcessTasksSpy: jasmine.Spy;
|
||||||
|
|
||||||
|
let exampleProcessInstance = new ProcessInstance({ id: '123' });
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [
|
||||||
|
CoreModule
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
ActivitiProcessInstanceTasks
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
{ provide: AlfrescoTranslationService, useClass: TranslationMock },
|
||||||
|
ActivitiProcessService
|
||||||
|
],
|
||||||
|
schemas: [ NO_ERRORS_SCHEMA ]
|
||||||
|
}).compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(ActivitiProcessInstanceTasks);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
service = fixture.debugElement.injector.get(ActivitiProcessService);
|
||||||
|
getProcessTasksSpy = spyOn(service, 'getProcessTasks').and.returnValue(Observable.of([new TaskDetailsModel(taskDetailsMock)]));
|
||||||
|
|
||||||
|
componentHandler = jasmine.createSpyObj('componentHandler', [
|
||||||
|
'upgradeAllRegistered',
|
||||||
|
'upgradeElement'
|
||||||
|
]);
|
||||||
|
window['componentHandler'] = componentHandler;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should initially render message about no active tasks if no process instance ID provided', async(() => {
|
||||||
|
component.processInstanceDetails = undefined;
|
||||||
|
fixture.detectChanges();
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
let msgEl = fixture.debugElement.query(By.css('[data-automation-id="active-tasks-none"]'));
|
||||||
|
expect(msgEl).not.toBeNull();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should initially render message about no completed tasks if no process instance ID provided', async(() => {
|
||||||
|
component.processInstanceDetails = undefined;
|
||||||
|
fixture.detectChanges();
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
let msgEl = fixture.debugElement.query(By.css('[data-automation-id="completed-tasks-none"]'));
|
||||||
|
expect(msgEl).not.toBeNull();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should not render active tasks list if no process instance ID provided', () => {
|
||||||
|
component.processInstanceDetails = undefined;
|
||||||
|
fixture.detectChanges();
|
||||||
|
let listEl = fixture.debugElement.query(By.css('[data-automation-id="active-tasks"]'));
|
||||||
|
expect(listEl).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not render completed tasks list if no process instance ID provided', () => {
|
||||||
|
component.processInstanceDetails = undefined;
|
||||||
|
fixture.detectChanges();
|
||||||
|
let listEl = fixture.debugElement.query(By.css('[data-automation-id="completed-tasks"]'));
|
||||||
|
expect(listEl).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call service to get tasks on init', () => {
|
||||||
|
component.processInstanceDetails = exampleProcessInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(getProcessTasksSpy).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display active tasks', () => {
|
||||||
|
component.processInstanceDetails = exampleProcessInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
let listEl = fixture.debugElement.query(By.css('[data-automation-id="active-tasks"]'));
|
||||||
|
expect(listEl).not.toBeNull();
|
||||||
|
expect(listEl.queryAll(By.css('li')).length).toBe(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display completed tasks', () => {
|
||||||
|
component.processInstanceDetails = exampleProcessInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
let listEl = fixture.debugElement.query(By.css('[data-automation-id="completed-tasks"]'));
|
||||||
|
expect(listEl).not.toBeNull();
|
||||||
|
expect(listEl.queryAll(By.css('li')).length).toBe(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('task reloading', () => {
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
component.processInstanceDetails = exampleProcessInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
fixture.whenStable();
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should render a refresh button by default', () => {
|
||||||
|
expect(fixture.debugElement.query(By.css('.process-tasks-refresh'))).not.toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render a refresh button if configured to', () => {
|
||||||
|
component.showRefreshButton = true;
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(fixture.debugElement.query(By.css('.process-tasks-refresh'))).not.toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should NOT render a refresh button if configured not to', () => {
|
||||||
|
component.showRefreshButton = false;
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(fixture.debugElement.query(By.css('.process-tasks-refresh'))).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call service to get tasks when reload button clicked', () => {
|
||||||
|
getProcessTasksSpy.calls.reset();
|
||||||
|
component.onRefreshClicked();
|
||||||
|
expect(getProcessTasksSpy).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('task details', () => {
|
||||||
|
|
||||||
|
let closeSpy;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
closeSpy = spyOn(component.dialog.nativeElement, 'close');
|
||||||
|
component.processInstanceDetails = exampleProcessInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
fixture.whenStable();
|
||||||
|
component.taskdetails = jasmine.createSpyObj('taskdetails', [
|
||||||
|
'loadDetails'
|
||||||
|
]);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should display task details dialog when task clicked', () => {
|
||||||
|
let showModalSpy = spyOn(component.dialog.nativeElement, 'showModal');
|
||||||
|
component.clickTask({}, new TaskDetailsModel(taskDetailsMock));
|
||||||
|
expect(showModalSpy).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should close the task details dialog when close button clicked', () => {
|
||||||
|
component.clickTask({}, new TaskDetailsModel(taskDetailsMock));
|
||||||
|
fixture.detectChanges();
|
||||||
|
component.cancelDialog();
|
||||||
|
expect(closeSpy).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should output event when task form completed', async(() => {
|
||||||
|
let emitSpy = spyOn(component.taskFormCompleted, 'emit');
|
||||||
|
fixture.detectChanges();
|
||||||
|
component.clickTask({}, new TaskDetailsModel(taskDetailsMock));
|
||||||
|
fixture.detectChanges();
|
||||||
|
component.onTaskFormCompleted();
|
||||||
|
expect(emitSpy).toHaveBeenCalled();
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should close dialog when task form completed', async(() => {
|
||||||
|
component.clickTask({}, new TaskDetailsModel(taskDetailsMock));
|
||||||
|
fixture.detectChanges();
|
||||||
|
component.onTaskFormCompleted();
|
||||||
|
expect(closeSpy).toHaveBeenCalled();
|
||||||
|
}));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@@ -41,7 +41,7 @@ export class ActivitiProcessInstanceTasks implements OnInit {
|
|||||||
showRefreshButton: boolean = true;
|
showRefreshButton: boolean = true;
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
taskFormCompletedEmitter = new EventEmitter();
|
taskFormCompleted = new EventEmitter();
|
||||||
|
|
||||||
activeTasks: TaskDetailsModel[] = [];
|
activeTasks: TaskDetailsModel[] = [];
|
||||||
completedTasks: TaskDetailsModel[] = [];
|
completedTasks: TaskDetailsModel[] = [];
|
||||||
@@ -191,10 +191,10 @@ export class ActivitiProcessInstanceTasks implements OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public taskFormCompleted() {
|
public onTaskFormCompleted() {
|
||||||
this.closeDialog();
|
this.closeDialog();
|
||||||
this.load(this.processInstanceDetails.id);
|
this.load(this.processInstanceDetails.id);
|
||||||
this.taskFormCompletedEmitter.emit(this.processInstanceDetails.id);
|
this.taskFormCompleted.emit(this.processInstanceDetails.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public onRefreshClicked() {
|
public onRefreshClicked() {
|
||||||
|
@@ -20,6 +20,7 @@ import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
|||||||
import { Observable } from 'rxjs/Rx';
|
import { Observable } from 'rxjs/Rx';
|
||||||
import { ActivitiProcessInstanceListComponent } from './activiti-processlist.component';
|
import { ActivitiProcessInstanceListComponent } from './activiti-processlist.component';
|
||||||
import { TranslationMock } from './../assets/translation.service.mock';
|
import { TranslationMock } from './../assets/translation.service.mock';
|
||||||
|
import { ObjectDataTableAdapter } from 'ng2-alfresco-datatable';
|
||||||
import { FilterRepresentationModel } from 'ng2-activiti-tasklist';
|
import { FilterRepresentationModel } from 'ng2-activiti-tasklist';
|
||||||
import { ActivitiProcessService } from '../services/activiti-process.service';
|
import { ActivitiProcessService } from '../services/activiti-process.service';
|
||||||
import { AlfrescoTranslationService, CoreModule } from 'ng2-alfresco-core';
|
import { AlfrescoTranslationService, CoreModule } from 'ng2-alfresco-core';
|
||||||
@@ -60,8 +61,23 @@ describe('ActivitiProcessInstanceListComponent', () => {
|
|||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should initialise data table', () => {
|
it('should use the default schemaColumn as default', () => {
|
||||||
fixture.detectChanges();
|
component.ngOnInit();
|
||||||
|
expect(component.data.getColumns()).toBeDefined();
|
||||||
|
expect(component.data.getColumns().length).toEqual(4);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should use the schemaColumn passed in input', () => {
|
||||||
|
component.data = new ObjectDataTableAdapter(
|
||||||
|
[],
|
||||||
|
[
|
||||||
|
{type: 'text', key: 'fake-id', title: 'Name'}
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
component.ngOnInit();
|
||||||
|
expect(component.data.getColumns()).toBeDefined();
|
||||||
|
expect(component.data.getColumns().length).toEqual(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fetch process instances when a filter is provided', () => {
|
it('should fetch process instances when a filter is provided', () => {
|
||||||
|
@@ -1,22 +0,0 @@
|
|||||||
/*!
|
|
||||||
* @license
|
|
||||||
* Copyright 2016 Alfresco Software, Ltd.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
describe('Placeholder', () => {
|
|
||||||
it('test placeholder', () => {
|
|
||||||
expect(true).toBe(true);
|
|
||||||
});
|
|
||||||
});
|
|
@@ -16,6 +16,7 @@
|
|||||||
"LABELS": {
|
"LABELS": {
|
||||||
"STARTED_BY": "Started by",
|
"STARTED_BY": "Started by",
|
||||||
"STARTED": "Started",
|
"STARTED": "Started",
|
||||||
|
"ENDED": "Ended",
|
||||||
"COMMENTS": "Comments",
|
"COMMENTS": "Comments",
|
||||||
"START_FORM": "Start Form",
|
"START_FORM": "Start Form",
|
||||||
"TASKS_ACTIVE": "Active Tasks",
|
"TASKS_ACTIVE": "Active Tasks",
|
||||||
|
@@ -36,4 +36,25 @@ export class ProcessInstance {
|
|||||||
public tenantId: string;
|
public tenantId: string;
|
||||||
public variables: any;
|
public variables: any;
|
||||||
|
|
||||||
|
constructor(data?: any) {
|
||||||
|
this.businessKey = data && data.businessKey !== undefined ? data.businessKey : null;
|
||||||
|
this.ended = data && data.ended !== undefined ? data.ended : null;
|
||||||
|
this.graphicalNotationDefined = data && data.graphicalNotationDefined !== undefined ? data.graphicalNotationDefined : null;
|
||||||
|
this.id = data && data.id !== undefined ? data.id : null;
|
||||||
|
this.name = data && data.name !== undefined ? data.name : null;
|
||||||
|
this.processDefinitionCategory = data && data.processDefinitionCategory !== undefined ? data.processDefinitionCategory : null;
|
||||||
|
this.processDefinitionDeploymentId = data && data.processDefinitionDeploymentId !== undefined ? data.processDefinitionDeploymentId : null;
|
||||||
|
this.processDefinitionDescription = data && data.processDefinitionDescription !== undefined ? data.processDefinitionDescription : null;
|
||||||
|
this.processDefinitionId = data && data.processDefinitionId !== undefined ? data.processDefinitionId : null;
|
||||||
|
this.processDefinitionKey = data && data.processDefinitionKey !== undefined ? data.processDefinitionKey : null;
|
||||||
|
this.processDefinitionName = data && data.processDefinitionName !== undefined ? data.processDefinitionName : null;
|
||||||
|
this.processDefinitionVersion = data && data.processDefinitionVersion !== undefined ? data.processDefinitionVersion : null;
|
||||||
|
this.startFormDefined = data && data.startFormDefined !== undefined ? data.startFormDefined : null;
|
||||||
|
this.started = data && data.started !== undefined ? data.started : null;
|
||||||
|
this.startedBy = data && data.startedBy !== undefined ? data.startedBy : null;
|
||||||
|
this.suspended = data && data.suspended !== undefined ? data.suspended : null;
|
||||||
|
this.tenantId = data && data.tenantId !== undefined ? data.tenantId : null;
|
||||||
|
this.variables = data && data.variables !== undefined ? data.variables : null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user