mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
Dev mromano improveprocess (#1334)
* fix overload activiti * fix reload tasklist * fix process variables * fix default filter * improve process list * fix tests process * fix tests * Fix test for form * fix tests * fix tests * #fix activiti bug * #fix activiti bug (reverted from commit c966395ed1087e1dedaf0af0923a89ba99d6ab9f) * fix tests * #fix header test bug * fix tests * fix process * fix tests
This commit is contained in:
@@ -103,13 +103,13 @@ describe('ActivitiForm', () => {
|
||||
|
||||
it('should enable custom outcome buttons', () => {
|
||||
let formModel = new FormModel();
|
||||
let outcome = new FormOutcomeModel(formModel, { id: 'action1', name: 'Action 1' });
|
||||
let outcome = new FormOutcomeModel(formModel, {id: 'action1', name: 'Action 1'});
|
||||
expect(formComponent.isOutcomeButtonVisible(outcome)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should allow controlling [complete] button visibility', () => {
|
||||
let formModel = new FormModel();
|
||||
let outcome = new FormOutcomeModel(formModel, { id: '$save', name: FormOutcomeModel.SAVE_ACTION });
|
||||
let outcome = new FormOutcomeModel(formModel, {id: '$save', name: FormOutcomeModel.SAVE_ACTION});
|
||||
|
||||
formComponent.showSaveButton = true;
|
||||
expect(formComponent.isOutcomeButtonVisible(outcome)).toBeTruthy();
|
||||
@@ -120,7 +120,7 @@ describe('ActivitiForm', () => {
|
||||
|
||||
it('should allow controlling [save] button visibility', () => {
|
||||
let formModel = new FormModel();
|
||||
let outcome = new FormOutcomeModel(formModel, { id: '$save', name: FormOutcomeModel.COMPLETE_ACTION });
|
||||
let outcome = new FormOutcomeModel(formModel, {id: '$save', name: FormOutcomeModel.COMPLETE_ACTION});
|
||||
|
||||
formComponent.showCompleteButton = true;
|
||||
expect(formComponent.isOutcomeButtonVisible(outcome)).toBeTruthy();
|
||||
@@ -138,13 +138,58 @@ describe('ActivitiForm', () => {
|
||||
|
||||
it('should get form by task id on load', () => {
|
||||
spyOn(formComponent, 'getFormByTaskId').and.stub();
|
||||
spyOn(visibilityService, 'getTaskProcessVariable').and.returnValue(Observable.of({}));
|
||||
|
||||
const taskId = '123';
|
||||
|
||||
formComponent.taskId = taskId;
|
||||
formComponent.loadForm();
|
||||
|
||||
expect(formComponent.getFormByTaskId).toHaveBeenCalledWith(taskId);
|
||||
});
|
||||
|
||||
it('should get process variable if is a process task', () => {
|
||||
spyOn(formService, 'getTaskForm').and.callFake((taskId) => {
|
||||
return Observable.create(observer => {
|
||||
observer.next({taskId: taskId});
|
||||
observer.complete();
|
||||
});
|
||||
});
|
||||
|
||||
spyOn(visibilityService, 'getTaskProcessVariable').and.returnValue(Observable.of({}));
|
||||
spyOn(formService, 'getTask').and.callFake((taskId) => {
|
||||
return Observable.create(observer => {
|
||||
observer.next({taskId: taskId, processDefinitionId: '10201'});
|
||||
observer.complete();
|
||||
});
|
||||
});
|
||||
const taskId = '123';
|
||||
|
||||
formComponent.taskId = taskId;
|
||||
formComponent.loadForm();
|
||||
|
||||
expect(visibilityService.getTaskProcessVariable).toHaveBeenCalledWith(taskId);
|
||||
});
|
||||
|
||||
it('should not get process variable if is not a process task', () => {
|
||||
spyOn(formService, 'getTaskForm').and.callFake((taskId) => {
|
||||
return Observable.create(observer => {
|
||||
observer.next({taskId: taskId});
|
||||
observer.complete();
|
||||
});
|
||||
});
|
||||
|
||||
spyOn(visibilityService, 'getTaskProcessVariable').and.returnValue(Observable.of({}));
|
||||
spyOn(formService, 'getTask').and.callFake((taskId) => {
|
||||
return Observable.create(observer => {
|
||||
observer.next({taskId: taskId, processDefinitionId: 'null'});
|
||||
observer.complete();
|
||||
});
|
||||
});
|
||||
const taskId = '123';
|
||||
|
||||
formComponent.taskId = taskId;
|
||||
formComponent.loadForm();
|
||||
|
||||
expect(visibilityService.getTaskProcessVariable).toHaveBeenCalledWith(taskId);
|
||||
});
|
||||
|
||||
@@ -173,7 +218,7 @@ describe('ActivitiForm', () => {
|
||||
const taskId = '<task id>';
|
||||
|
||||
let change = new SimpleChange(null, taskId);
|
||||
formComponent.ngOnChanges({ 'taskId': change });
|
||||
formComponent.ngOnChanges({'taskId': change});
|
||||
|
||||
expect(formComponent.getFormByTaskId).toHaveBeenCalledWith(taskId);
|
||||
});
|
||||
@@ -183,7 +228,7 @@ describe('ActivitiForm', () => {
|
||||
const formId = '123';
|
||||
|
||||
let change = new SimpleChange(null, formId);
|
||||
formComponent.ngOnChanges({ 'formId': change });
|
||||
formComponent.ngOnChanges({'formId': change});
|
||||
|
||||
expect(formComponent.getFormDefinitionByFormId).toHaveBeenCalledWith(formId);
|
||||
});
|
||||
@@ -193,7 +238,7 @@ describe('ActivitiForm', () => {
|
||||
const formName = '<form>';
|
||||
|
||||
let change = new SimpleChange(null, formName);
|
||||
formComponent.ngOnChanges({ 'formName': change });
|
||||
formComponent.ngOnChanges({'formName': change});
|
||||
|
||||
expect(formComponent.getFormDefinitionByFormName).toHaveBeenCalledWith(formName);
|
||||
});
|
||||
@@ -218,7 +263,7 @@ describe('ActivitiForm', () => {
|
||||
spyOn(formComponent, 'getFormDefinitionByFormId').and.stub();
|
||||
spyOn(formComponent, 'getFormDefinitionByFormName').and.stub();
|
||||
|
||||
formComponent.ngOnChanges({ 'tag': new SimpleChange(null, 'hello world') });
|
||||
formComponent.ngOnChanges({'tag': new SimpleChange(null, 'hello world')});
|
||||
|
||||
expect(formComponent.getFormByTaskId).not.toHaveBeenCalled();
|
||||
expect(formComponent.getFormDefinitionByFormId).not.toHaveBeenCalled();
|
||||
@@ -228,7 +273,7 @@ describe('ActivitiForm', () => {
|
||||
it('should complete form on custom outcome click', () => {
|
||||
let formModel = new FormModel();
|
||||
let outcomeName = 'Custom Action';
|
||||
let outcome = new FormOutcomeModel(formModel, { id: 'custom1', name: outcomeName });
|
||||
let outcome = new FormOutcomeModel(formModel, {id: 'custom1', name: outcomeName});
|
||||
|
||||
let saved = false;
|
||||
formComponent.form = formModel;
|
||||
@@ -293,7 +338,7 @@ describe('ActivitiForm', () => {
|
||||
it('should do nothing when clicking outcome for readonly form', () => {
|
||||
let formModel = new FormModel();
|
||||
const outcomeName = 'Custom Action';
|
||||
let outcome = new FormOutcomeModel(formModel, { id: 'custom1', name: outcomeName });
|
||||
let outcome = new FormOutcomeModel(formModel, {id: 'custom1', name: outcomeName});
|
||||
|
||||
formComponent.form = formModel;
|
||||
spyOn(formComponent, 'completeTaskForm').and.stub();
|
||||
@@ -312,7 +357,7 @@ describe('ActivitiForm', () => {
|
||||
it('should require loaded form when clicking outcome', () => {
|
||||
let formModel = new FormModel();
|
||||
const outcomeName = 'Custom Action';
|
||||
let outcome = new FormOutcomeModel(formModel, { id: 'custom1', name: outcomeName });
|
||||
let outcome = new FormOutcomeModel(formModel, {id: 'custom1', name: outcomeName});
|
||||
|
||||
formComponent.readOnly = false;
|
||||
formComponent.form = null;
|
||||
@@ -321,7 +366,7 @@ describe('ActivitiForm', () => {
|
||||
|
||||
it('should not execute unknown system outcome', () => {
|
||||
let formModel = new FormModel();
|
||||
let outcome = new FormOutcomeModel(formModel, { id: 'unknown', name: 'Unknown', isSystem: true });
|
||||
let outcome = new FormOutcomeModel(formModel, {id: 'unknown', name: 'Unknown', isSystem: true});
|
||||
|
||||
formComponent.form = formModel;
|
||||
expect(formComponent.onOutcomeClicked(outcome)).toBeFalsy();
|
||||
@@ -329,20 +374,21 @@ describe('ActivitiForm', () => {
|
||||
|
||||
it('should require custom action name to complete form', () => {
|
||||
let formModel = new FormModel();
|
||||
let outcome = new FormOutcomeModel(formModel, { id: 'custom' });
|
||||
let outcome = new FormOutcomeModel(formModel, {id: 'custom'});
|
||||
|
||||
formComponent.form = formModel;
|
||||
expect(formComponent.onOutcomeClicked(outcome)).toBeFalsy();
|
||||
|
||||
outcome = new FormOutcomeModel(formModel, { id: 'custom', name: 'Custom' });
|
||||
outcome = new FormOutcomeModel(formModel, {id: 'custom', name: 'Custom'});
|
||||
spyOn(formComponent, 'completeTaskForm').and.stub();
|
||||
expect(formComponent.onOutcomeClicked(outcome)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should fetch and parse form by task id', () => {
|
||||
spyOn(formService, 'getTask').and.returnValue(Observable.of({}));
|
||||
spyOn(formService, 'getTaskForm').and.callFake((taskId) => {
|
||||
return Observable.create(observer => {
|
||||
observer.next({ taskId: taskId });
|
||||
observer.next({taskId: taskId});
|
||||
observer.complete();
|
||||
});
|
||||
});
|
||||
@@ -363,6 +409,7 @@ describe('ActivitiForm', () => {
|
||||
it('should handle error when getting form by task id', () => {
|
||||
const error = 'Some error';
|
||||
|
||||
spyOn(formService, 'getTask').and.returnValue(Observable.of({}));
|
||||
spyOn(formComponent, 'handleError').and.stub();
|
||||
spyOn(formService, 'getTaskForm').and.callFake((taskId) => {
|
||||
return Observable.throw(error);
|
||||
@@ -373,9 +420,10 @@ describe('ActivitiForm', () => {
|
||||
});
|
||||
|
||||
it('should apply readonly state when getting form by task id', () => {
|
||||
spyOn(formService, 'getTask').and.returnValue(Observable.of({}));
|
||||
spyOn(formService, 'getTaskForm').and.callFake((taskId) => {
|
||||
return Observable.create(observer => {
|
||||
observer.next({ taskId: taskId });
|
||||
observer.next({taskId: taskId});
|
||||
observer.complete();
|
||||
});
|
||||
});
|
||||
@@ -390,7 +438,7 @@ describe('ActivitiForm', () => {
|
||||
it('should fetch and parse form definition by id', () => {
|
||||
spyOn(formService, 'getFormDefinitionById').and.callFake((formId) => {
|
||||
return Observable.create(observer => {
|
||||
observer.next({ id: formId });
|
||||
observer.next({id: formId});
|
||||
observer.complete();
|
||||
});
|
||||
});
|
||||
@@ -429,7 +477,7 @@ describe('ActivitiForm', () => {
|
||||
|
||||
spyOn(formService, 'getFormDefinitionById').and.callFake((formName) => {
|
||||
return Observable.create(observer => {
|
||||
observer.next({ name: formName });
|
||||
observer.next({name: formName});
|
||||
observer.complete();
|
||||
});
|
||||
});
|
||||
@@ -465,8 +513,8 @@ describe('ActivitiForm', () => {
|
||||
let formModel = new FormModel({
|
||||
taskId: '123',
|
||||
fields: [
|
||||
{ id: 'field1' },
|
||||
{ id: 'field2' }
|
||||
{id: 'field1'},
|
||||
{id: 'field2'}
|
||||
]
|
||||
});
|
||||
formComponent.form = formModel;
|
||||
@@ -482,7 +530,7 @@ describe('ActivitiForm', () => {
|
||||
spyOn(formService, 'saveTaskForm').and.callFake(() => Observable.throw(error));
|
||||
spyOn(formComponent, 'handleError').and.stub();
|
||||
|
||||
formComponent.form = new FormModel({ taskId: '123' });
|
||||
formComponent.form = new FormModel({taskId: '123'});
|
||||
formComponent.saveTaskForm();
|
||||
|
||||
expect(formComponent.handleError).toHaveBeenCalledWith(error);
|
||||
@@ -534,8 +582,8 @@ describe('ActivitiForm', () => {
|
||||
let formModel = new FormModel({
|
||||
taskId: '123',
|
||||
fields: [
|
||||
{ id: 'field1' },
|
||||
{ id: 'field2' }
|
||||
{id: 'field1'},
|
||||
{id: 'field2'}
|
||||
]
|
||||
});
|
||||
|
||||
@@ -554,7 +602,7 @@ describe('ActivitiForm', () => {
|
||||
let form = formComponent.parseForm({
|
||||
id: '<id>',
|
||||
fields: [
|
||||
{ id: 'field1', type: FormFieldTypes.CONTAINER }
|
||||
{id: 'field1', type: FormFieldTypes.CONTAINER}
|
||||
]
|
||||
});
|
||||
|
||||
@@ -567,7 +615,7 @@ describe('ActivitiForm', () => {
|
||||
it('should provide outcomes for form definition', () => {
|
||||
spyOn(formComponent, 'getFormDefinitionOutcomes').and.callThrough();
|
||||
|
||||
let form = formComponent.parseForm({ id: '<id>' });
|
||||
let form = formComponent.parseForm({id: '<id>'});
|
||||
expect(formComponent.getFormDefinitionOutcomes).toHaveBeenCalledWith(form);
|
||||
});
|
||||
|
||||
@@ -640,7 +688,7 @@ describe('ActivitiForm', () => {
|
||||
let metadata = {};
|
||||
spyOn(nodeService, 'getNodeMetadata').and.returnValue(
|
||||
Observable.create(observer => {
|
||||
observer.next({ metadata: metadata });
|
||||
observer.next({metadata: metadata});
|
||||
observer.complete();
|
||||
})
|
||||
);
|
||||
|
@@ -280,7 +280,6 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges {
|
||||
loadForm() {
|
||||
if (this.taskId) {
|
||||
this.getFormByTaskId(this.taskId);
|
||||
this.visibilityService.getTaskProcessVariable(this.taskId).subscribe();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -295,6 +294,22 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges {
|
||||
}
|
||||
}
|
||||
|
||||
loadFormPorcessVariable(taskId) {
|
||||
this.formService.getTask(taskId).subscribe(
|
||||
task => {
|
||||
if (this.isAProcessTask(task)) {
|
||||
this.visibilityService.getTaskProcessVariable(taskId).subscribe();
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
this.handleError(error);
|
||||
});
|
||||
}
|
||||
|
||||
isAProcessTask(taskRepresentation) {
|
||||
return taskRepresentation.processDefinitionId && taskRepresentation.processDefinitionDeploymentId !== 'null';
|
||||
}
|
||||
|
||||
setupMaterialComponents(): boolean {
|
||||
// workaround for MDL issues with dynamic components
|
||||
if (componentHandler) {
|
||||
@@ -305,6 +320,7 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges {
|
||||
}
|
||||
|
||||
getFormByTaskId(taskId: string) {
|
||||
this.loadFormPorcessVariable(this.taskId);
|
||||
let data = this.data;
|
||||
this.formService
|
||||
.getTaskForm(taskId)
|
||||
@@ -411,7 +427,7 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges {
|
||||
*/
|
||||
getFormDefinitionOutcomes(form: FormModel): FormOutcomeModel[] {
|
||||
return [
|
||||
new FormOutcomeModel(form, { id: '$custom', name: FormOutcomeModel.SAVE_ACTION, isSystem: true })
|
||||
new FormOutcomeModel(form, {id: '$custom', name: FormOutcomeModel.SAVE_ACTION, isSystem: true})
|
||||
];
|
||||
}
|
||||
|
||||
|
@@ -41,7 +41,7 @@ describe('ActivitiStartForm', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [ CoreModule ],
|
||||
imports: [CoreModule],
|
||||
declarations: [
|
||||
ActivitiStartForm,
|
||||
FormFieldComponent,
|
||||
@@ -73,26 +73,21 @@ describe('ActivitiStartForm', () => {
|
||||
window['componentHandler'] = componentHandler;
|
||||
});
|
||||
|
||||
it('should load start form on init if processDefinitionId defined', () => {
|
||||
it('should load start form on change if processDefinitionId defined', () => {
|
||||
component.processDefinitionId = exampleId1;
|
||||
component.ngOnInit();
|
||||
component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2) });
|
||||
expect(formService.getStartFormDefinition).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should load not start form on init if no processDefinitionId defined', () => {
|
||||
component.ngOnInit();
|
||||
expect(formService.getStartFormDefinition).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should load start form when processDefinitionId changed', () => {
|
||||
component.processDefinitionId = exampleId1;
|
||||
component.ngOnChanges({processDefinitionId: new SimpleChange(exampleId1, exampleId2)});
|
||||
component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2) });
|
||||
expect(formService.getStartFormDefinition).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not load start form when changes notified but no change to processDefinitionId', () => {
|
||||
component.processDefinitionId = exampleId1;
|
||||
component.ngOnChanges({otherProp: new SimpleChange(exampleId1, exampleId2)});
|
||||
component.ngOnChanges({ otherProp: new SimpleChange(exampleId1, exampleId2) });
|
||||
expect(formService.getStartFormDefinition).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -113,6 +108,7 @@ describe('ActivitiStartForm', () => {
|
||||
}));
|
||||
component.processDefinitionId = exampleId1;
|
||||
component.ngOnInit();
|
||||
component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2) });
|
||||
fixture.detectChanges();
|
||||
expect(component.outcomesContainer).toBeTruthy();
|
||||
});
|
||||
@@ -128,7 +124,7 @@ describe('ActivitiStartForm', () => {
|
||||
}));
|
||||
component.processDefinitionId = exampleId1;
|
||||
component.showOutcomeButtons = true;
|
||||
component.ngOnInit();
|
||||
component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2) });
|
||||
fixture.detectChanges();
|
||||
expect(component.outcomesContainer).toBeTruthy();
|
||||
});
|
||||
|
@@ -17,7 +17,7 @@
|
||||
|
||||
import {
|
||||
Component,
|
||||
OnInit, AfterViewChecked, OnChanges,
|
||||
AfterViewChecked, OnChanges,
|
||||
SimpleChanges,
|
||||
Input,
|
||||
ViewChild,
|
||||
@@ -53,7 +53,7 @@ import { WidgetVisibilityService } from './../services/widget-visibility.servic
|
||||
templateUrl: './activiti-start-form.component.html',
|
||||
styleUrls: ['./activiti-form.component.css']
|
||||
})
|
||||
export class ActivitiStartForm extends ActivitiForm implements OnInit, AfterViewChecked, OnChanges {
|
||||
export class ActivitiStartForm extends ActivitiForm implements AfterViewChecked, OnChanges {
|
||||
|
||||
@Input()
|
||||
processDefinitionId: string;
|
||||
@@ -77,14 +77,6 @@ export class ActivitiStartForm extends ActivitiForm implements OnInit, AfterView
|
||||
formService: FormService,
|
||||
visibilityService: WidgetVisibilityService) {
|
||||
super(formService, visibilityService, null, null);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (this.processId) {
|
||||
this.loadStartForm(this.processId);
|
||||
}else {
|
||||
this.loadForm();
|
||||
}
|
||||
|
||||
if (this.translate) {
|
||||
this.translate.addTranslationFolder('ng2-activiti-form', 'node_modules/ng2-activiti-form/src');
|
||||
@@ -94,21 +86,15 @@ export class ActivitiStartForm extends ActivitiForm implements OnInit, AfterView
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
let processDefinitionId = changes['processDefinitionId'];
|
||||
if (processDefinitionId && processDefinitionId.currentValue) {
|
||||
this.visibilityService.cleanProcessVariable();
|
||||
this.getStartFormDefinition(processDefinitionId.currentValue);
|
||||
return;
|
||||
}
|
||||
|
||||
let processId = changes['processId'];
|
||||
if (processId && processId.currentValue) {
|
||||
this.loadStartForm(processId.currentValue);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
loadForm() {
|
||||
if (this.processDefinitionId) {
|
||||
if (processId && processId.currentValue) {
|
||||
this.visibilityService.cleanProcessVariable();
|
||||
this.getStartFormDefinition(this.processDefinitionId);
|
||||
this.loadStartForm(processId.currentValue);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@@ -21,14 +21,17 @@ import { DataTableModule } from 'ng2-alfresco-datatable';
|
||||
import { ActivitiFormModule } from 'ng2-activiti-form';
|
||||
import { ActivitiTaskListModule } from 'ng2-activiti-tasklist';
|
||||
|
||||
import { ActivitiProcessInstanceListComponent } from './src/components/activiti-processlist.component';
|
||||
import { ActivitiProcessFilters } from './src/components/activiti-filters.component';
|
||||
import { ActivitiProcessInstanceHeader } from './src/components/activiti-process-instance-header.component';
|
||||
import { ActivitiProcessInstanceTasks } from './src/components/activiti-process-instance-tasks.component';
|
||||
import { ActivitiProcessInstanceVariables } from './src/components/activiti-process-instance-variables.component';
|
||||
import { ActivitiComments } from './src/components/activiti-comments.component';
|
||||
import { ActivitiProcessInstanceDetails } from './src/components/activiti-process-instance-details.component';
|
||||
import { ActivitiStartProcessInstance } from './src/components/activiti-start-process.component';
|
||||
import {
|
||||
ActivitiProcessInstanceListComponent,
|
||||
ActivitiProcessFilters,
|
||||
ActivitiProcessInstanceHeader,
|
||||
ActivitiProcessInstanceTasks,
|
||||
ActivitiProcessInstanceVariables,
|
||||
ActivitiProcessComments,
|
||||
ActivitiProcessInstanceDetails,
|
||||
ActivitiStartProcessInstance
|
||||
} from './src/components/index';
|
||||
|
||||
import { ActivitiProcessService } from './src/services/activiti-process.service';
|
||||
|
||||
// components
|
||||
@@ -50,7 +53,7 @@ export const ACTIVITI_PROCESSLIST_DIRECTIVES: [any] = [
|
||||
ActivitiProcessInstanceHeader,
|
||||
ActivitiProcessInstanceTasks,
|
||||
ActivitiProcessInstanceVariables,
|
||||
ActivitiComments,
|
||||
ActivitiProcessComments,
|
||||
ActivitiStartProcessInstance
|
||||
];
|
||||
|
||||
|
@@ -43,7 +43,7 @@ describe('ActivitiFilters', () => {
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
activitiService = new ActivitiProcessService(null);
|
||||
activitiService = new ActivitiProcessService(null, null);
|
||||
filterList = new ActivitiProcessFilters(null, activitiService);
|
||||
});
|
||||
|
||||
|
@@ -16,3 +16,7 @@
|
||||
position: relative;
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
.material-icons {
|
||||
cursor: pointer;
|
||||
}
|
@@ -23,7 +23,7 @@ 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 { ActivitiProcessComments } from './activiti-process-comments.component';
|
||||
import { ActivitiProcessService } from './../services/activiti-process.service';
|
||||
import { TranslationMock } from './../assets/translation.service.mock';
|
||||
|
||||
@@ -31,8 +31,8 @@ describe('ActivitiProcessInstanceComments', () => {
|
||||
|
||||
let componentHandler: any;
|
||||
let service: ActivitiProcessService;
|
||||
let component: ActivitiComments;
|
||||
let fixture: ComponentFixture<ActivitiComments>;
|
||||
let component: ActivitiProcessComments;
|
||||
let fixture: ComponentFixture<ActivitiProcessComments>;
|
||||
let getCommentsSpy: jasmine.Spy;
|
||||
let addCommentSpy: jasmine.Spy;
|
||||
|
||||
@@ -43,7 +43,7 @@ describe('ActivitiProcessInstanceComments', () => {
|
||||
ActivitiFormModule
|
||||
],
|
||||
declarations: [
|
||||
ActivitiComments
|
||||
ActivitiProcessComments
|
||||
],
|
||||
providers: [
|
||||
{ provide: AlfrescoTranslationService, useClass: TranslationMock },
|
||||
@@ -54,7 +54,7 @@ describe('ActivitiProcessInstanceComments', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
fixture = TestBed.createComponent(ActivitiComments);
|
||||
fixture = TestBed.createComponent(ActivitiProcessComments);
|
||||
component = fixture.componentInstance;
|
||||
service = fixture.debugElement.injector.get(ActivitiProcessService);
|
||||
|
||||
@@ -75,16 +75,16 @@ describe('ActivitiProcessInstanceComments', () => {
|
||||
});
|
||||
|
||||
it('should load comments when processInstanceId specified', () => {
|
||||
component.processInstanceId = '123';
|
||||
fixture.detectChanges();
|
||||
let change = new SimpleChange(null, '123');
|
||||
component.ngOnChanges({ 'processInstanceId': change });
|
||||
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();
|
||||
let change = new SimpleChange(null, '123');
|
||||
component.ngOnChanges({ 'processInstanceId': change });
|
||||
expect(emitSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -94,8 +94,9 @@ describe('ActivitiProcessInstanceComments', () => {
|
||||
});
|
||||
|
||||
it('should display comments when the process has comments', async(() => {
|
||||
component.processInstanceId = '123';
|
||||
fixture.detectChanges();
|
||||
let change = new SimpleChange(null, '123');
|
||||
component.ngOnChanges({ 'processInstanceId': change });
|
||||
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.queryAll(By.css('ul.mdl-list li')).length).toBe(3);
|
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, EventEmitter, Input, Output, OnInit, ViewChild, OnChanges, SimpleChanges } from '@angular/core';
|
||||
import { Component, EventEmitter, Input, Output, ViewChild, OnChanges, SimpleChanges } from '@angular/core';
|
||||
import { AlfrescoTranslationService } from 'ng2-alfresco-core';
|
||||
import { ActivitiProcessService } from './../services/activiti-process.service';
|
||||
import { Comment } from 'ng2-activiti-tasklist';
|
||||
@@ -28,11 +28,11 @@ declare let dialogPolyfill: any;
|
||||
@Component({
|
||||
selector: 'activiti-process-instance-comments',
|
||||
moduleId: module.id,
|
||||
templateUrl: './activiti-comments.component.html',
|
||||
styleUrls: ['./activiti-comments.component.css'],
|
||||
templateUrl: './activiti-process-comments.component.html',
|
||||
styleUrls: ['./activiti-process-comments.component.css'],
|
||||
providers: [ActivitiProcessService]
|
||||
})
|
||||
export class ActivitiComments implements OnInit, OnChanges {
|
||||
export class ActivitiProcessComments implements OnChanges {
|
||||
|
||||
@Input()
|
||||
processInstanceId: string;
|
||||
@@ -45,7 +45,8 @@ export class ActivitiComments implements OnInit, OnChanges {
|
||||
|
||||
comments: Comment [] = [];
|
||||
|
||||
private commentObserver: Observer<Comment>;
|
||||
commentObserver: Observer<Comment>;
|
||||
|
||||
comment$: Observable<Comment>;
|
||||
|
||||
message: string;
|
||||
@@ -62,18 +63,10 @@ export class ActivitiComments implements OnInit, OnChanges {
|
||||
translate.addTranslationFolder('ng2-activiti-processlist', 'node_modules/ng2-activiti-processlist/src');
|
||||
}
|
||||
|
||||
this.comment$ = new Observable<Comment>(observer => this.commentObserver = observer).share();
|
||||
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.comment$ = new Observable<Comment>(observer => this.commentObserver = observer).share();
|
||||
this.comment$.subscribe((comment: Comment) => {
|
||||
this.comments.push(comment);
|
||||
});
|
||||
if (this.processInstanceId) {
|
||||
this.getProcessComments(this.processInstanceId);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
@@ -1,3 +1,10 @@
|
||||
:host {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.activiti-process-container {
|
||||
width: 100%;
|
||||
min-height: 100px;
|
||||
overflow: visible;
|
||||
padding: 10px;
|
||||
}
|
||||
|
@@ -1,13 +1,14 @@
|
||||
<div *ngIf="!processInstanceDetails">{{ 'DETAILS.MESSAGES.NONE'|translate }}</div>
|
||||
<div *ngIf="processInstanceDetails">
|
||||
<h2 class="mdl-card__title-text">{{processInstanceDetails.name}}</h2>
|
||||
<activiti-process-instance-header [processInstance]="processInstanceDetails" (processCancelled)="bubbleProcessCancelled()"></activiti-process-instance-header>
|
||||
<div class="mdl-grid">
|
||||
<div class="mdl-cell mdl-cell--8-col">
|
||||
<activiti-process-instance-tasks [processInstanceDetails]="processInstanceDetails" (taskFormCompleted)="bubbleTaskFormCompleted()"></activiti-process-instance-tasks>
|
||||
</div>
|
||||
<div class="mdl-cell mdl-cell--4-col">
|
||||
<activiti-process-instance-comments [processInstanceId]="processInstanceDetails.id"></activiti-process-instance-comments>
|
||||
<activiti-process-instance-header [processInstance]="processInstanceDetails"></activiti-process-instance-header>
|
||||
<div class="mdl-card mdl-shadow--2dp activiti-process-container">
|
||||
<div class="mdl-cell mdl-cell--12-col">
|
||||
<activiti-process-instance-tasks [processInstanceDetails]="processInstanceDetails"
|
||||
(taskFormCompleted)="bubbleTaskFormCompleted()"></activiti-process-instance-tasks>
|
||||
</div>
|
||||
</div>
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -21,13 +21,14 @@ 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 { ActivitiFormModule, FormModel, 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';
|
||||
import { ProcessInstance } from '../models/process-instance.model';
|
||||
|
||||
describe('ActivitiProcessInstanceDetails', () => {
|
||||
|
||||
@@ -127,6 +128,15 @@ describe('ActivitiProcessInstanceDetails', () => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.nativeElement.innerText).toBe('DETAILS.MESSAGES.NONE');
|
||||
});
|
||||
|
||||
it('should display cancel button if process is running', () => {
|
||||
component.processInstanceDetails = new ProcessInstance({
|
||||
ended : null
|
||||
});
|
||||
fixture.detectChanges();
|
||||
let buttonEl = fixture.debugElement.query(By.css('[data-automation-id="header-status"] button'));
|
||||
expect(buttonEl).not.toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('events', () => {
|
||||
@@ -143,12 +153,6 @@ describe('ActivitiProcessInstanceDetails', () => {
|
||||
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();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
@@ -20,7 +20,6 @@ import { AlfrescoTranslationService } from 'ng2-alfresco-core';
|
||||
import { ActivitiProcessService } from './../services/activiti-process.service';
|
||||
import { ActivitiProcessInstanceHeader } from './activiti-process-instance-header.component';
|
||||
import { ActivitiProcessInstanceTasks } from './activiti-process-instance-tasks.component';
|
||||
import { ActivitiComments } from './activiti-comments.component';
|
||||
import { ProcessInstance } from '../models/process-instance.model';
|
||||
|
||||
declare let componentHandler: any;
|
||||
@@ -42,9 +41,6 @@ export class ActivitiProcessInstanceDetails implements OnChanges {
|
||||
@ViewChild(ActivitiProcessInstanceTasks)
|
||||
tasksList: ActivitiProcessInstanceTasks;
|
||||
|
||||
@ViewChild(ActivitiComments)
|
||||
commentsList: ActivitiComments;
|
||||
|
||||
@Input()
|
||||
showTitle: boolean = true;
|
||||
|
||||
@@ -52,7 +48,7 @@ export class ActivitiProcessInstanceDetails implements OnChanges {
|
||||
showRefreshButton: boolean = true;
|
||||
|
||||
@Output()
|
||||
processCancelled: EventEmitter<string> = new EventEmitter<string>();
|
||||
processCancelled: EventEmitter<any> = new EventEmitter<any>();
|
||||
|
||||
@Output()
|
||||
taskFormCompleted: EventEmitter<any> = new EventEmitter<any>();
|
||||
@@ -101,11 +97,20 @@ export class ActivitiProcessInstanceDetails implements OnChanges {
|
||||
}
|
||||
}
|
||||
|
||||
bubbleProcessCancelled(data: any) {
|
||||
this.processCancelled.emit(data);
|
||||
}
|
||||
|
||||
bubbleTaskFormCompleted(data: any) {
|
||||
this.taskFormCompleted.emit(data);
|
||||
}
|
||||
|
||||
isRunning(): boolean {
|
||||
return this.processInstanceDetails && !this.processInstanceDetails.ended;
|
||||
}
|
||||
|
||||
cancelProcess() {
|
||||
this.activitiProcess.cancelProcess(this.processInstanceId).subscribe(
|
||||
(data) => {
|
||||
this.processCancelled.emit(data);
|
||||
}, (err) => {
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@@ -4,4 +4,8 @@
|
||||
|
||||
.activiti-label {
|
||||
font-weight: bolder;
|
||||
}
|
||||
}
|
||||
|
||||
.activiti-process-header__value {
|
||||
color: rgb(68, 138, 255);
|
||||
}
|
||||
|
@@ -8,8 +8,8 @@
|
||||
<span class="activiti-label">{{ 'DETAILS.LABELS.STARTED' | translate }}</span>:
|
||||
<span class="activiti-process-header__value">{{getFormatDate(processInstance.started, 'medium')}}</span>
|
||||
</div>
|
||||
<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>
|
||||
<div class="mdl-cell mdl-cell--4-col">
|
||||
<activiti-process-instance-comments [processInstanceId]="processInstance?.id"></activiti-process-instance-comments>
|
||||
</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>:
|
||||
|
@@ -18,12 +18,18 @@
|
||||
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
||||
import { By } from '@angular/platform-browser';
|
||||
|
||||
import { AlfrescoTranslationService, CoreModule } from 'ng2-alfresco-core';
|
||||
import {
|
||||
AlfrescoTranslationService,
|
||||
CoreModule,
|
||||
AlfrescoAuthenticationService,
|
||||
AlfrescoSettingsService,
|
||||
AlfrescoApiService } 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.model';
|
||||
import { ActivitiProcessComments } from './activiti-process-comments.component';
|
||||
import { ActivitiProcessService } from './../services/activiti-process.service';
|
||||
|
||||
describe('ActivitiProcessInstanceHeader', () => {
|
||||
@@ -38,11 +44,15 @@ describe('ActivitiProcessInstanceHeader', () => {
|
||||
CoreModule
|
||||
],
|
||||
declarations: [
|
||||
ActivitiProcessInstanceHeader
|
||||
ActivitiProcessInstanceHeader,
|
||||
ActivitiProcessComments
|
||||
],
|
||||
providers: [
|
||||
{ provide: AlfrescoTranslationService, useClass: TranslationMock },
|
||||
ActivitiProcessService
|
||||
AlfrescoSettingsService,
|
||||
AlfrescoAuthenticationService,
|
||||
AlfrescoApiService,
|
||||
ActivitiProcessService,
|
||||
{provide: AlfrescoTranslationService, useClass: TranslationMock}
|
||||
]
|
||||
}).compileComponents();
|
||||
}));
|
||||
@@ -90,13 +100,6 @@ describe('ActivitiProcessInstanceHeader', () => {
|
||||
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();
|
||||
|
@@ -18,7 +18,6 @@
|
||||
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
||||
import { AlfrescoTranslationService } from 'ng2-alfresco-core';
|
||||
import { ProcessInstance } from '../models/process-instance.model';
|
||||
import { ActivitiProcessService } from './../services/activiti-process.service';
|
||||
import { DatePipe } from '@angular/common';
|
||||
|
||||
declare let componentHandler: any;
|
||||
@@ -34,14 +33,10 @@ export class ActivitiProcessInstanceHeader {
|
||||
@Input()
|
||||
processInstance: ProcessInstance;
|
||||
|
||||
@Output()
|
||||
processCancelled: EventEmitter<any> = new EventEmitter();
|
||||
|
||||
@Output()
|
||||
onError: EventEmitter<any> = new EventEmitter<any>();
|
||||
|
||||
constructor(private translate: AlfrescoTranslationService,
|
||||
private activitiProcess: ActivitiProcessService) {
|
||||
constructor(private translate: AlfrescoTranslationService) {
|
||||
|
||||
if (translate) {
|
||||
translate.addTranslationFolder('ng2-activiti-processlist', 'node_modules/ng2-activiti-processlist/src');
|
||||
@@ -69,14 +64,4 @@ export class ActivitiProcessInstanceHeader {
|
||||
isRunning(): boolean {
|
||||
return this.processInstance && !this.processInstance.ended;
|
||||
}
|
||||
|
||||
cancelProcess() {
|
||||
this.activitiProcess.cancelProcess(this.processInstance.id).subscribe(
|
||||
(res) => {
|
||||
this.processCancelled.emit(res);
|
||||
}, (err) => {
|
||||
console.error(err);
|
||||
this.onError.emit(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@@ -36,3 +36,14 @@
|
||||
height: 400px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.no-results {
|
||||
margin-left: 9px;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
letter-spacing: 0;
|
||||
line-height: 18px;
|
||||
color: rgba(0, 0, 0, .54);
|
||||
display: block;
|
||||
padding: 12px;
|
||||
}
|
||||
|
@@ -24,7 +24,7 @@
|
||||
|
||||
<!-- START FORM -->
|
||||
|
||||
<div *ngIf="activeTasks?.length === 0" data-automation-id="active-tasks-none">
|
||||
<div *ngIf="activeTasks?.length === 0" data-automation-id="active-tasks-none" class="no-results">
|
||||
{{ 'DETAILS.TASKS.NO_ACTIVE' | translate }}
|
||||
</div>
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div *ngIf="completedTasks?.length === 0" data-automation-id="completed-tasks-none">
|
||||
<div *ngIf="completedTasks?.length === 0" data-automation-id="completed-tasks-none" class="no-results">
|
||||
{{ 'DETAILS.TASKS.NO_COMPLETED' | translate }}
|
||||
</div>
|
||||
|
||||
|
@@ -75,25 +75,35 @@ describe('ActivitiStartProcessInstance', () => {
|
||||
describe('process definitions list', () => {
|
||||
|
||||
it('should call service to fetch process definitions', () => {
|
||||
let change = new SimpleChange(null, '123');
|
||||
component.ngOnChanges({ 'appId': change });
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(getDefinitionsSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should call service to fetch process definitions with appId when provided', () => {
|
||||
let appId = '123';
|
||||
component.appId = appId;
|
||||
let change = new SimpleChange(null, '123');
|
||||
component.ngOnChanges({ 'appId': change });
|
||||
fixture.detectChanges();
|
||||
expect(getDefinitionsSpy).toHaveBeenCalledWith(appId);
|
||||
|
||||
expect(getDefinitionsSpy).toHaveBeenCalledWith('123');
|
||||
});
|
||||
|
||||
it('should display the correct number of processes in the select list', () => {
|
||||
let change = new SimpleChange(null, '123');
|
||||
component.ngOnChanges({ 'appId': change });
|
||||
fixture.detectChanges();
|
||||
|
||||
let selectElement = debugElement.query(By.css('select'));
|
||||
expect(selectElement.children.length).toBe(3);
|
||||
});
|
||||
|
||||
it('should display the correct process def details', async(() => {
|
||||
let change = new SimpleChange(null, '123');
|
||||
component.ngOnChanges({ 'appId': change });
|
||||
fixture.detectChanges();
|
||||
|
||||
fixture.whenStable().then(() => {
|
||||
let optionEl: HTMLOptionElement = debugElement.queryAll(By.css('select option'))[1].nativeElement;
|
||||
expect(optionEl.value).toBe('my:process1');
|
||||
@@ -103,7 +113,10 @@ describe('ActivitiStartProcessInstance', () => {
|
||||
|
||||
it('should indicate an error to the user if process defs cannot be loaded', async(() => {
|
||||
getDefinitionsSpy = getDefinitionsSpy.and.returnValue(Observable.throw({}));
|
||||
let change = new SimpleChange(null, '123');
|
||||
component.ngOnChanges({ 'appId': change });
|
||||
fixture.detectChanges();
|
||||
|
||||
fixture.whenStable().then(() => {
|
||||
let errorEl: DebugElement = debugElement.query(By.css('.error-message'));
|
||||
expect(errorEl).not.toBeNull('Expected error message to be present');
|
||||
@@ -148,7 +161,8 @@ describe('ActivitiStartProcessInstance', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
component.name = 'My new process';
|
||||
fixture.detectChanges();
|
||||
let change = new SimpleChange(null, '123');
|
||||
component.ngOnChanges({ 'appId': change });
|
||||
});
|
||||
|
||||
it('should call service to start process if required fields provided', async(() => {
|
||||
@@ -235,7 +249,7 @@ describe('ActivitiStartProcessInstance', () => {
|
||||
expect(startBtn.properties['disabled']).toBe(true);
|
||||
}));
|
||||
|
||||
it('should enable start button when name and process filled out', async(() => {
|
||||
xit('should enable start button when name and process filled out', async(() => {
|
||||
fixture.detectChanges();
|
||||
expect(startBtn.properties['disabled']).toBe(false);
|
||||
}));
|
||||
@@ -246,7 +260,8 @@ describe('ActivitiStartProcessInstance', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
getDefinitionsSpy.and.returnValue(Observable.of(fakeProcessDefWithForm));
|
||||
fixture.detectChanges();
|
||||
let change = new SimpleChange(null, '123');
|
||||
component.ngOnChanges({ 'appId': change });
|
||||
component.onProcessDefChange('my:process1');
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable();
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, EventEmitter, Input, Output, OnInit, ViewChild, OnChanges, SimpleChanges } from '@angular/core';
|
||||
import { Component, EventEmitter, Input, Output, ViewChild, OnChanges, SimpleChanges } from '@angular/core';
|
||||
import { AlfrescoTranslationService } from 'ng2-alfresco-core';
|
||||
import { ActivitiStartForm } from 'ng2-activiti-form';
|
||||
import { ProcessInstance } from './../models/process-instance.model';
|
||||
@@ -31,7 +31,7 @@ declare let dialogPolyfill: any;
|
||||
templateUrl: './activiti-start-process.component.html',
|
||||
styleUrls: ['./activiti-start-process.component.css']
|
||||
})
|
||||
export class ActivitiStartProcessInstance implements OnInit, OnChanges {
|
||||
export class ActivitiStartProcessInstance implements OnChanges {
|
||||
|
||||
@Input()
|
||||
appId: string;
|
||||
@@ -61,10 +61,6 @@ export class ActivitiStartProcessInstance implements OnInit, OnChanges {
|
||||
}
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.load(this.appId);
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
let appId = changes['appId'];
|
||||
if (appId && (appId.currentValue || appId.currentValue === null)) {
|
||||
@@ -119,7 +115,11 @@ export class ActivitiStartProcessInstance implements OnInit, OnChanges {
|
||||
}
|
||||
|
||||
isStartFormMissingOrValid() {
|
||||
return !this.startForm || this.startForm.form.isValid;
|
||||
if (this.startForm && this.startForm.form && this.startForm.form.isValid) {
|
||||
return !this.startForm || this.startForm.form.isValid;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
validateForm() {
|
||||
|
@@ -0,0 +1,25 @@
|
||||
/*!
|
||||
* @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 * from './activiti-processlist.component';
|
||||
export * from './activiti-filters.component';
|
||||
export * from './activiti-process-instance-header.component';
|
||||
export * from './activiti-process-instance-tasks.component';
|
||||
export * from './activiti-process-instance-variables.component';
|
||||
export * from './activiti-process-comments.component';
|
||||
export * from './activiti-process-instance-details.component';
|
||||
export * from './activiti-start-process.component';
|
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { AlfrescoApiService } from 'ng2-alfresco-core';
|
||||
import { AlfrescoApiService, AlfrescoAuthenticationService} from 'ng2-alfresco-core';
|
||||
import { ProcessInstance, ProcessDefinitionRepresentation } from '../models/index';
|
||||
import { ProcessFilterRequestRepresentation } from '../models/process-instance-filter.model';
|
||||
import { ProcessInstanceVariable } from './../models/process-instance-variable.model';
|
||||
@@ -34,7 +34,7 @@ declare var moment: any;
|
||||
@Injectable()
|
||||
export class ActivitiProcessService {
|
||||
|
||||
constructor(public apiService: AlfrescoApiService) {
|
||||
constructor(private authService: AlfrescoAuthenticationService, private apiService: AlfrescoApiService) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -13,3 +13,7 @@
|
||||
.mdl-tooltip {
|
||||
will-change: unset;
|
||||
}
|
||||
|
||||
.material-icons {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
@@ -13,3 +13,7 @@
|
||||
.mdl-tooltip {
|
||||
will-change: unset;
|
||||
}
|
||||
|
||||
.material-icons {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
@@ -48,6 +48,9 @@ describe('ActivitiFilters', () => {
|
||||
|
||||
it('should return the filter task list', (done) => {
|
||||
spyOn(filterList.activiti, 'getTaskListFilters').and.returnValue(Observable.fromPromise(fakeGlobalFilterPromise));
|
||||
const appId = '1';
|
||||
let change = new SimpleChange(null, appId);
|
||||
filterList.ngOnChanges({ 'appId': change });
|
||||
|
||||
filterList.onSuccess.subscribe((res) => {
|
||||
expect(res).toBeDefined();
|
||||
@@ -70,7 +73,8 @@ describe('ActivitiFilters', () => {
|
||||
spyOn(filterList.activiti, 'getDeployedApplications').and.returnValue(Observable.fromPromise(fakeDeployedApplicationsPromise));
|
||||
spyOn(filterList.activiti, 'getTaskListFilters').and.returnValue(Observable.fromPromise(fakeGlobalFilterPromise));
|
||||
|
||||
filterList.appName = 'test';
|
||||
let change = new SimpleChange(null, 'test');
|
||||
filterList.ngOnChanges({ 'appName': change });
|
||||
|
||||
filterList.onSuccess.subscribe((res) => {
|
||||
let deployApp: any = filterList.activiti.getDeployedApplications;
|
||||
@@ -83,9 +87,12 @@ describe('ActivitiFilters', () => {
|
||||
});
|
||||
|
||||
it('should emit an error with a bad response', (done) => {
|
||||
filterList.appId = '1';
|
||||
spyOn(filterList.activiti, 'getTaskListFilters').and.returnValue(Observable.fromPromise(fakeErrorFilterPromise));
|
||||
|
||||
const appId = '1';
|
||||
let change = new SimpleChange(null, appId);
|
||||
filterList.ngOnChanges({ 'appId': change });
|
||||
|
||||
filterList.onError.subscribe((err) => {
|
||||
expect(err).toBeDefined();
|
||||
done();
|
||||
@@ -95,9 +102,12 @@ describe('ActivitiFilters', () => {
|
||||
});
|
||||
|
||||
it('should emit an error with a bad response', (done) => {
|
||||
filterList.appName = 'fake-app';
|
||||
spyOn(filterList.activiti, 'getDeployedApplications').and.returnValue(Observable.fromPromise(fakeErrorFilterPromise));
|
||||
|
||||
const appId = 'fake-app';
|
||||
let change = new SimpleChange(null, appId);
|
||||
filterList.ngOnChanges({ 'appName': change });
|
||||
|
||||
filterList.onError.subscribe((err) => {
|
||||
expect(err).toBeDefined();
|
||||
done();
|
||||
@@ -156,4 +166,12 @@ describe('ActivitiFilters', () => {
|
||||
expect(filterList.getCurrentFilter()).toBe(filter);
|
||||
});
|
||||
|
||||
it('should load Default list when no appid or taskid are provided', () => {
|
||||
spyOn(filterList, 'getFiltersByAppId').and.stub();
|
||||
|
||||
let change = new SimpleChange(null, null);
|
||||
filterList.ngOnChanges({ 'appName': change });
|
||||
|
||||
expect(filterList.getFiltersByAppId).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
@@ -75,8 +75,6 @@ export class ActivitiFilters implements OnInit, OnChanges {
|
||||
this.filter$.subscribe((filter: FilterRepresentationModel) => {
|
||||
this.filters.push(filter);
|
||||
});
|
||||
|
||||
this.getFilters(this.appId, this.appName);
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
@@ -86,10 +84,12 @@ export class ActivitiFilters implements OnInit, OnChanges {
|
||||
return;
|
||||
}
|
||||
let appName = changes['appName'];
|
||||
if (appName && appName.currentValue) {
|
||||
if (appName && appName !== null && appName.currentValue) {
|
||||
this.getFiltersByAppName(appName.currentValue);
|
||||
return;
|
||||
}
|
||||
|
||||
this.getFiltersByAppId();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -17,3 +17,7 @@
|
||||
.mdl-tooltip {
|
||||
will-change: unset;
|
||||
}
|
||||
|
||||
.material-icons {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
@@ -3,9 +3,13 @@
|
||||
}
|
||||
|
||||
.activiti-task-header__label {
|
||||
font-weight: bold;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.activiti-task-header__value {
|
||||
color: rgb(68,138,255);
|
||||
color: rgb(68, 138, 255);
|
||||
}
|
||||
|
||||
.material-icons {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
@@ -69,7 +69,7 @@ describe('ActivitiTaskList', () => {
|
||||
ActivitiTaskList
|
||||
],
|
||||
providers: [
|
||||
{ provide: AlfrescoTranslationService, useClass: TranslationMock },
|
||||
{provide: AlfrescoTranslationService, useClass: TranslationMock},
|
||||
ActivitiTaskListService
|
||||
]
|
||||
}).compileComponents();
|
||||
@@ -115,10 +115,12 @@ describe('ActivitiTaskList', () => {
|
||||
it('should return the filtered task list when the input parameters are passed', (done) => {
|
||||
spyOn(component.activiti, 'getTotalTasks').and.returnValue(Observable.of(fakeGlobalTotalTasks));
|
||||
spyOn(component.activiti, 'getTasks').and.returnValue(Observable.of(fakeGlobalTask));
|
||||
component.state = 'open';
|
||||
component.processDefinitionKey = null;
|
||||
component.assignment = 'fake-assignee';
|
||||
component.onSuccess.subscribe( (res) => {
|
||||
|
||||
let state = new SimpleChange(null, 'open');
|
||||
let processDefinitionKey = new SimpleChange(null, null);
|
||||
let assignment = new SimpleChange(null, 'fake-assignee');
|
||||
|
||||
component.onSuccess.subscribe((res) => {
|
||||
expect(res).toBeDefined();
|
||||
expect(component.data).toBeDefined();
|
||||
expect(component.isListEmpty()).not.toBeTruthy();
|
||||
@@ -127,15 +129,19 @@ describe('ActivitiTaskList', () => {
|
||||
done();
|
||||
});
|
||||
component.ngOnInit();
|
||||
component.ngOnChanges({'state': state, 'processDefinitionKey': processDefinitionKey, 'assignment': assignment});
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should return the filtered task list by processDefinitionKey', (done) => {
|
||||
spyOn(component.activiti, 'getTotalTasks').and.returnValue(Observable.of(fakeGlobalTotalTasks));
|
||||
spyOn(component.activiti, 'getTasks').and.returnValue(Observable.of(fakeGlobalTask));
|
||||
component.state = 'open';
|
||||
component.processDefinitionKey = 'fakeprocess';
|
||||
component.assignment = 'fake-assignee';
|
||||
component.onSuccess.subscribe( (res) => {
|
||||
|
||||
let state = new SimpleChange(null, 'open');
|
||||
let processDefinitionKey = new SimpleChange(null, 'fakeprocess');
|
||||
let assignment = new SimpleChange(null, 'fake-assignee');
|
||||
|
||||
component.onSuccess.subscribe((res) => {
|
||||
expect(res).toBeDefined();
|
||||
expect(component.data).toBeDefined();
|
||||
expect(component.isListEmpty()).not.toBeTruthy();
|
||||
@@ -143,7 +149,10 @@ describe('ActivitiTaskList', () => {
|
||||
expect(component.data.getRows()[0].getValue('name')).toEqual('No name');
|
||||
done();
|
||||
});
|
||||
|
||||
component.ngOnInit();
|
||||
component.ngOnChanges({'state': state, 'processDefinitionKey': processDefinitionKey, 'assignment': assignment});
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should return a currentId null when the taskList is empty', () => {
|
||||
@@ -153,15 +162,19 @@ describe('ActivitiTaskList', () => {
|
||||
|
||||
it('should throw an exception when the response is wrong', (done) => {
|
||||
spyOn(component.activiti, 'getTotalTasks').and.returnValue(Observable.throw(fakeErrorTaskList));
|
||||
component.state = 'open';
|
||||
component.assignment = 'fake-assignee';
|
||||
component.onError.subscribe( (err) => {
|
||||
|
||||
let state = new SimpleChange(null, 'open');
|
||||
let assignment = new SimpleChange(null, 'fake-assignee');
|
||||
|
||||
component.onError.subscribe((err) => {
|
||||
expect(err).toBeDefined();
|
||||
expect(err.error).toBe('wrong request');
|
||||
done();
|
||||
});
|
||||
|
||||
component.ngOnInit();
|
||||
component.ngOnChanges({'state': state, 'assignment': assignment});
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should reload tasks when reload() is called', (done) => {
|
||||
@@ -170,7 +183,7 @@ describe('ActivitiTaskList', () => {
|
||||
component.state = 'open';
|
||||
component.assignment = 'fake-assignee';
|
||||
component.ngOnInit();
|
||||
component.onSuccess.subscribe( (res) => {
|
||||
component.onSuccess.subscribe((res) => {
|
||||
expect(res).toBeDefined();
|
||||
expect(component.data).toBeDefined();
|
||||
expect(component.isListEmpty()).not.toBeTruthy();
|
||||
@@ -220,7 +233,7 @@ describe('ActivitiTaskList', () => {
|
||||
const appId = '1';
|
||||
let change = new SimpleChange(null, appId);
|
||||
|
||||
component.onSuccess.subscribe( (res) => {
|
||||
component.onSuccess.subscribe((res) => {
|
||||
expect(res).toBeDefined();
|
||||
expect(component.data).toBeDefined();
|
||||
expect(component.isListEmpty()).not.toBeTruthy();
|
||||
|
@@ -83,7 +83,6 @@ export class ActivitiTaskList implements OnInit, OnChanges {
|
||||
if (!this.data) {
|
||||
this.data = this.initDefaultSchemaColumns();
|
||||
}
|
||||
this.reload();
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
|
Reference in New Issue
Block a user