Merge pull request #1012 from Alfresco/dev-wabson-730

Display start forms in Start Process dialog
This commit is contained in:
Eugenio Romano 2016-11-08 14:17:53 +00:00 committed by GitHub
commit 7236bf1da9
19 changed files with 567 additions and 29 deletions

View File

@ -19,6 +19,7 @@ import { NgModule, ModuleWithProviders } from '@angular/core';
import { CoreModule } from 'ng2-alfresco-core';
import { ActivitiForm } from './src/components/activiti-form.component';
import { ActivitiStartForm } from './src/components/activiti-start-form.component';
import { FormService } from './src/services/form.service';
import { EcmModelService } from './src/services/ecm-model.service';
import { NodeService } from './src/services/node.service';
@ -28,6 +29,7 @@ import { HttpModule } from '@angular/http';
import { WIDGET_DIRECTIVES } from './src/components/widgets/index';
export * from './src/components/activiti-form.component';
export * from './src/components/activiti-start-form.component';
export * from './src/services/form.service';
export * from './src/components/widgets/index';
export * from './src/services/ecm-model.service';
@ -35,6 +37,7 @@ export * from './src/services/node.service';
export const ACTIVITI_FORM_DIRECTIVES: any[] = [
ActivitiForm,
ActivitiStartForm,
...WIDGET_DIRECTIVES
];

View File

@ -0,0 +1,28 @@
/*!
* @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 { Observable } from 'rxjs/Rx';
export class TranslationMock {
get(key: string|Array<string>, interpolateParams?: Object): Observable<string|any> {
return Observable.of(key);
}
addTranslationFolder() {
}
}

View File

@ -145,7 +145,7 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges {
debugMode: boolean = false;
constructor(private formService: FormService,
constructor(protected formService: FormService,
private visibilityService: WidgetVisibilityService,
private ecmModelService: EcmModelService,
private nodeService: NodeService) {

View File

@ -0,0 +1,35 @@
<div>
<div *ngIf="hasForm()">
<div class="mdl-card mdl-shadow--2dp activiti-form-container">
<div class="mdl-card__title">
<i class="material-icons">{{ form.isValid ? 'event_available' : 'event_busy' }}</i>
<h2 *ngIf="isTitleEnabled()" class="mdl-card__title-text">{{form.taskName}}</h2>
</div>
<div class="mdl-card__media">
<div *ngIf="form.hasTabs()">
<tabs-widget [tabs]="form.tabs" (formTabChanged)="checkVisibility($event);"></tabs-widget>
</div>
<div *ngIf="!form.hasTabs() && form.hasFields()">
<container-widget *ngFor="let field of form.fields" [content]="field" (formValueChanged)="checkVisibility($event);"></container-widget>
</div>
</div>
<div *ngIf="showOutcomeButtons && form.hasOutcomes()" class="mdl-card__actions mdl-card--border" #outcomesContainer>
<button *ngFor="let outcome of form.outcomes"
alfresco-mdl-button
[disabled]="!isOutcomeButtonEnabled(outcome)"
[class.mdl-button--colored]="!outcome.isSystem"
[class.activiti-form-hide-button]="!isOutcomeButtonVisible(outcome)"
(click)="onOutcomeClicked(outcome, $event)">
{{outcome.name}}
</button>
</div>
<div *ngIf="showRefreshButton" class="mdl-card__menu" >
<button (click)="onRefreshClicked()"
class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect">
<i class="material-icons">refresh</i>
</button>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,134 @@
/*!
* @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 { Observable } from 'rxjs/Rx';
import { ActivitiStartForm } from './activiti-start-form.component';
import { WIDGET_DIRECTIVES } from './widgets/index';
import { FormService } from './../services/form.service';
import { EcmModelService } from './../services/ecm-model.service';
import { WidgetVisibilityService } from './../services/widget-visibility.service';
import { AlfrescoTranslationService, CoreModule } from 'ng2-alfresco-core';
import { TranslationMock } from './../assets/translation.service.mock';
describe('ActivitiStartForm', () => {
let componentHandler: any;
let formService: FormService;
let component: ActivitiStartForm;
let fixture: ComponentFixture<ActivitiStartForm>;
let getStartFormSpy: jasmine.Spy;
const exampleId1 = 'my:process1';
const exampleId2 = 'my:process2';
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [ CoreModule ],
declarations: [
ActivitiStartForm,
...WIDGET_DIRECTIVES
],
providers: [
{ provide: AlfrescoTranslationService, useClass: TranslationMock },
EcmModelService,
FormService,
WidgetVisibilityService
]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ActivitiStartForm);
component = fixture.componentInstance;
formService = fixture.debugElement.injector.get(FormService);
getStartFormSpy = spyOn(formService, 'getStartFormDefinition').and.returnValue(Observable.of({
processDefinitionName: 'my:process'
}));
componentHandler = jasmine.createSpyObj('componentHandler', [
'upgradeAllRegistered',
'upgradeElement'
]);
window['componentHandler'] = componentHandler;
});
it('should load start form on init if processDefinitionId defined', () => {
component.processDefinitionId = exampleId1;
component.ngOnInit();
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)});
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)});
expect(formService.getStartFormDefinition).not.toHaveBeenCalled();
});
it('should consume errors encountered when loading start form', () => {
getStartFormSpy.and.returnValue(Observable.throw({}));
component.processDefinitionId = exampleId1;
component.ngOnInit();
});
it('should not show outcome buttons by default', () => {
getStartFormSpy.and.returnValue(Observable.of({
id: '1',
processDefinitionName: 'my:process',
outcomes: [{
id: 'approve',
name: 'Approve'
}]
}));
component.processDefinitionId = exampleId1;
component.ngOnInit();
fixture.detectChanges();
expect(component.outcomesContainer).not.toBeTruthy();
});
it('should show outcome buttons if showOutcomeButtons is true', () => {
getStartFormSpy.and.returnValue(Observable.of({
id: '1',
processDefinitionName: 'my:process',
outcomes: [{
id: 'approve',
name: 'Approve'
}]
}));
component.processDefinitionId = exampleId1;
component.showOutcomeButtons = true;
component.ngOnInit();
fixture.detectChanges();
expect(component.outcomesContainer).toBeTruthy();
});
});

View File

@ -0,0 +1,115 @@
/*!
* @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 {
Component,
OnInit, AfterViewChecked, OnChanges,
SimpleChanges,
Input,
ViewChild,
ElementRef
} from '@angular/core';
import { AlfrescoTranslationService } from 'ng2-alfresco-core';
import { ActivitiForm } from './activiti-form.component';
import { FormService } from './../services/form.service';
import { WidgetVisibilityService } from './../services/widget-visibility.service';
/**
* Displays the start form for a named process definition, which can be used to retrieve values to start a new process.
*
* After the form has been completed the form values are available from the attribute component.form.values and
* component.form.isValid (boolean) can be used to check the if the form is valid or not. Both of these properties are
* updated as the user types into the form.
*
* @Input
* {processDefinitionId} string: The process definition ID
* {showOutcomeButtons} boolean: Whether form outcome buttons should be shown, as yet these don't do anything so this
* is false by default
* @Output
* {formLoaded} EventEmitter - This event is fired when the form is loaded, it pass all the value in the form.
* {formSaved} EventEmitter - This event is fired when the form is saved, it pass all the value in the form.
* {formCompleted} EventEmitter - This event is fired when the form is completed, it pass all the value in the form.
*
* @returns {ActivitiForm} .
*/
@Component({
moduleId: module.id,
selector: 'activiti-start-form',
templateUrl: './activiti-start-form.component.html',
styleUrls: ['./activiti-form.component.css']
})
export class ActivitiStartForm extends ActivitiForm implements OnInit, AfterViewChecked, OnChanges {
@Input()
processDefinitionId: string;
@Input()
showOutcomeButtons: boolean = false;
@ViewChild('outcomesContainer', {})
outcomesContainer: ElementRef = null;
constructor(private translate: AlfrescoTranslationService,
formService: FormService,
visibilityService: WidgetVisibilityService) {
super(formService, visibilityService, null, null);
}
ngOnInit() {
this.loadForm();
if (this.translate) {
this.translate.addTranslationFolder('node_modules/ng2-activiti-form/src');
}
}
ngOnChanges(changes: SimpleChanges) {
let processId = changes['processDefinitionId'];
if (processId && processId.currentValue) {
this.getStartFormDefinition(processId.currentValue);
return;
}
}
loadForm() {
if (this.processDefinitionId) {
this.getStartFormDefinition(this.processDefinitionId);
return;
}
}
getStartFormDefinition(processId: string) {
this.formService
.getStartFormDefinition(processId)
.subscribe(
form => {
this.formName = form.processDefinitionName;
this.form = this.parseForm(form);
this.formLoaded.emit(this.form);
},
(error) => {
this.handleError(error);
}
);
}
saveTaskForm() {
}
completeTaskForm(outcome?: string) {
}
}

View File

@ -0,0 +1,7 @@
{
"FORM": {
"START_FORM": {
"TITLE": "Start Form"
}
}
}

View File

@ -30,7 +30,7 @@ declare let jasmine: any;
describe('FormService', () => {
let responseBody: any, service: FormService;
let responseBody: any, service: FormService, apiService: AlfrescoApiService;
beforeAll(() => {
TestBed.configureTestingModule({
@ -44,6 +44,7 @@ describe('FormService', () => {
]
});
service = TestBed.get(FormService);
apiService = TestBed.get(AlfrescoApiService);
});
beforeEach(() => {
@ -229,6 +230,22 @@ describe('FormService', () => {
});
});
it('should get start form definition by process definition id', (done) => {
let processApiSpy = jasmine.createSpyObj(['getProcessDefinitionStartForm']);
spyOn(apiService, 'getInstance').and.returnValue({
activiti: {
processApi: processApiSpy
}
});
processApiSpy.getProcessDefinitionStartForm.and.returnValue(Promise.resolve({ id: '1' }));
service.getStartFormDefinition('myprocess:1').subscribe(result => {
expect(processApiSpy.getProcessDefinitionStartForm).toHaveBeenCalledWith('myprocess:1');
done();
});
});
it('should not get form id from response', () => {
let response = new Response(new ResponseOptions({body: null}));
expect(service.getFormId(response)).toBeNull();

View File

@ -206,6 +206,18 @@ export class FormService {
.catch(this.handleError);
}
/**
* Get start form definition for a given process
* @param processId Process definition ID
* @returns {Observable<any>}
*/
getStartFormDefinition(processId: string): Observable<any> {
return Observable.fromPromise(
this.apiService.getInstance().activiti.processApi.getProcessDefinitionStartForm(processId))
.map(this.toJson)
.catch(this.handleError);
}
getRestFieldValues(taskId: string, field: string): Observable<any> {
let alfrescoApi = this.apiService.getInstance();
return Observable.fromPromise(alfrescoApi.activiti.taskApi.getRestFieldValues(taskId, field));

View File

@ -18,6 +18,7 @@
import { NgModule, ModuleWithProviders } from '@angular/core';
import { CoreModule } from 'ng2-alfresco-core';
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';
@ -54,6 +55,7 @@ export const ACTIVITI_PROCESSLIST_PROVIDERS: [any] = [
imports: [
CoreModule,
DataTableModule,
ActivitiFormModule,
ActivitiTaskListModule
],
declarations: [

View File

@ -54,6 +54,7 @@ var map = {
'ng2-translate': 'npm:ng2-translate',
'alfresco-js-api': 'npm:alfresco-js-api/dist',
'ng2-activiti-form': 'npm:ng2-activiti-form/dist',
'ng2-activiti-tasklist': 'npm:ng2-activiti-tasklist/dist',
'ng2-alfresco-core': 'npm:ng2-alfresco-core/dist',
'ng2-alfresco-datatable': 'npm:ng2-alfresco-datatable/dist'
@ -65,6 +66,7 @@ var packages = {
'ng2-translate': { defaultExtension: 'js' },
'alfresco-js-api': { main: './alfresco-js-api.js', defaultExtension: 'js'},
'ng2-activiti-form': { main: './index.js', defaultExtension: 'js'},
'ng2-activiti-tasklist': { main: './index.js', defaultExtension: 'js'},
'ng2-alfresco-core': { main: './index.js', defaultExtension: 'js'},
'ng2-alfresco-datatable': { main: './index.js', defaultExtension: 'js'}

View File

@ -46,7 +46,7 @@ module.exports = function (config) {
{ 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-activiti-tasklist/dist/**/*.js', included: false, served: true, watched: false },
{ pattern: 'node_modules/ng2-activiti-form/dist/**/*.js', 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
{pattern: 'src/**/*.ts', included: false, watched: false},

View File

@ -16,22 +16,13 @@
*/
import { Observable } from 'rxjs/Rx';
import { EventEmitter } from '@angular/core';
export interface LangChangeEvent {
lang: string;
translations: any;
}
export class TranslationMock {
public onLangChange: EventEmitter<LangChangeEvent> = new EventEmitter<LangChangeEvent>();
public get(key: string|Array<string>, interpolateParams?: Object): Observable<string|any> {
return Observable.of(key);
}
addTranslationFolder() {
}
}

View File

@ -9,3 +9,13 @@
.material-icons:hover {
color: rgb(255, 152, 0);
}
.mdl-dialog {
width: 400px;
}
.mdl-textfield.alf-mdl-selectfield label {
color: rgba(0,0,0,.54);
font-size: 12px;
top: 4px;
}

View File

@ -3,8 +3,9 @@
<dialog class="mdl-dialog" #dialog>
<h4 class="mdl-dialog__title">{{'START_PROCESS.DIALOG.TITLE'|translate}}</h4>
<div class="mdl-dialog__content">
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<select name="processDefinition" [(ngModel)]="processDefinition" id="processDefinition">
<div class="mdl-textfield mdl-js-textfield alf-mdl-selectfield">
<select name="processDefinition" [(ngModel)]="processDefinitionId" id="processDefinition">
<option value="" selected="selected">{{'START_PROCESS.DIALOG.TYPE_PLACEHOLDER'|translate}}</option>
<option *ngFor="let processDef of processDefinitions" [value]="processDef.id">
{{processDef.name}}
</option>
@ -15,9 +16,16 @@
<input class="mdl-textfield__input" type="text" [(ngModel)]="name" id="processName" />
<label class="mdl-textfield__label" for="processName">{{'START_PROCESS.DIALOG.LABEL.NAME'|translate}}</label>
</div>
<activiti-start-form *ngIf="hasStartForm()" [processDefinitionId]="processDefinitionId"
(formSaved)='onFormSaved($event)'
(formCompleted)='onFormCompleted($event)'
(formLoaded)='onFormLoaded($event)'
(onError)='onFormError($event)'
#startForm>
</activiti-start-form>
</div>
<div class="mdl-dialog__actions">
<button type="button" (click)="startProcess()" class="mdl-button">{{'START_PROCESS.DIALOG.ACTION.START'|translate}}</button>
<button type="button" [disabled]="!validateForm()" (click)="startProcess()" class="mdl-button">{{'START_PROCESS.DIALOG.ACTION.START'|translate}}</button>
<button type="button" (click)="cancel()" class="mdl-button close">{{'START_PROCESS.DIALOG.ACTION.CANCEL'|translate}}</button>
</div>
</dialog>

View File

@ -0,0 +1,143 @@
/*!
* @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 { DebugElement } from '@angular/core';
import { Observable } from 'rxjs/Rx';
import { ActivitiFormModule } from 'ng2-activiti-form';
import { AlfrescoTranslationService, CoreModule } from 'ng2-alfresco-core';
import { FormService } from 'ng2-activiti-form';
import { TranslationMock } from './../assets/translation.service.mock';
import { ActivitiStartProcessButton } from './activiti-start-process.component';
import { ActivitiProcessService } from '../services/activiti-process.service';
describe('ActivitiStartProcessButton', () => {
let componentHandler: any;
let component: ActivitiStartProcessButton;
let fixture: ComponentFixture<ActivitiStartProcessButton>;
let processService: ActivitiProcessService;
let formService: FormService;
let getDefinitionsSpy: jasmine.Spy;
let startProcessSpy: jasmine.Spy;
let debugElement: DebugElement;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [ CoreModule, ActivitiFormModule ],
declarations: [
ActivitiStartProcessButton
],
providers: [
{ provide: AlfrescoTranslationService, useClass: TranslationMock },
ActivitiProcessService,
FormService
]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ActivitiStartProcessButton);
component = fixture.componentInstance;
debugElement = fixture.debugElement;
processService = fixture.debugElement.injector.get(ActivitiProcessService);
formService = fixture.debugElement.injector.get(FormService);
getDefinitionsSpy = spyOn(processService, 'getProcessDefinitions').and.returnValue(Observable.of([{
id: 'my:process1',
name: 'My Process 1'
}, {
id: 'my:process2',
name: 'My Process 2'
}]));
startProcessSpy = spyOn(processService, 'startProcess').and.returnValue(Observable.of({
id: '32323',
name: 'Process'
}));
componentHandler = jasmine.createSpyObj('componentHandler', [
'upgradeAllRegistered',
'upgradeElement'
]);
window['componentHandler'] = componentHandler;
});
it('should display the correct number of processes in the select list', () => {
fixture.detectChanges();
let selectElement = debugElement.query(By.css('select'));
expect(selectElement.children.length).toBe(3);
});
it('should display the correct process def details', (done) => {
fixture.detectChanges();
fixture.whenStable().then(() => {
let optionEl: HTMLOptionElement = debugElement.queryAll(By.css('select option'))[1].nativeElement;
expect(optionEl.value).toBe('my:process1');
expect(optionEl.textContent.trim()).toBe('My Process 1');
done();
});
});
it('should call service to start process if required fields provided', (done) => {
component.name = 'My new process';
component.processDefinitionId = 'my:process1';
component.showDialog();
fixture.detectChanges();
component.startProcess();
fixture.whenStable().then(() => {
expect(startProcessSpy).toHaveBeenCalled();
done();
});
});
it('should avoid calling service to start process if required fields NOT provided', (done) => {
component.showDialog();
fixture.detectChanges();
component.startProcess();
fixture.whenStable().then(() => {
expect(startProcessSpy).not.toHaveBeenCalled();
done();
});
});
it('should call service to start process with the correct parameters', (done) => {
component.name = 'My new process';
component.processDefinitionId = 'my:process1';
component.showDialog();
fixture.detectChanges();
component.startProcess();
fixture.whenStable().then(() => {
expect(startProcessSpy).toHaveBeenCalledWith('my:process1', 'My new process', undefined);
done();
});
});
it('should indicate start form is missing when process does not have a start form', (done) => {
component.name = 'My new process';
component.processDefinitionId = 'my:process1';
component.showDialog();
fixture.detectChanges();
component.startProcess();
fixture.whenStable().then(() => {
expect(component.isStartFormMissingOrValid()).toBe(true);
done();
});
});
});

View File

@ -15,11 +15,13 @@
* limitations under the License.
*/
import { Component, Input, OnInit, ViewChild } from '@angular/core';
import { Component, Input, OnInit, ViewChild, DebugElement } from '@angular/core';
import { AlfrescoTranslationService } from 'ng2-alfresco-core';
import { ActivitiStartForm } from 'ng2-activiti-form';
import { ActivitiProcessService } from './../services/activiti-process.service';
declare let componentHandler: any;
declare let dialogPolyfill: any;
@Component({
selector: 'activiti-start-process-instance',
@ -33,12 +35,15 @@ export class ActivitiStartProcessButton implements OnInit {
appId: string;
@ViewChild('dialog')
dialog: any;
dialog: DebugElement;
@ViewChild('startForm')
startForm: ActivitiStartForm;
processDefinitions: any[] = [];
name: string;
processDefinition: string;
processDefinitionId: string;
constructor(private translate: AlfrescoTranslationService,
private activitiProcess: ActivitiProcessService) {
@ -64,15 +69,19 @@ export class ActivitiStartProcessButton implements OnInit {
}
public showDialog() {
if (this.dialog) {
this.dialog.nativeElement.showModal();
if (!this.dialog.nativeElement.showModal) {
dialogPolyfill.registerDialog(this.dialog.nativeElement);
}
this.dialog.nativeElement.showModal();
}
public startProcess() {
if (this.processDefinition && this.name) {
this.activitiProcess.startProcess(this.processDefinition, this.name).subscribe(
if (this.processDefinitionId && this.name) {
let formValues = this.startForm ? this.startForm.form.values : undefined;
this.activitiProcess.startProcess(this.processDefinitionId, this.name, formValues).subscribe(
(res: any) => {
this.name = '';
this.processDefinitionId = '';
this.cancel();
},
(err) => {
@ -83,8 +92,25 @@ export class ActivitiStartProcessButton implements OnInit {
}
public cancel() {
if (this.dialog) {
this.dialog.nativeElement.close();
}
this.dialog.nativeElement.close();
}
private getSelectedProcess(): any {
return this.processDefinitions.filter((processDefinition) => {
return processDefinition.id === this.processDefinitionId;
})[0];
}
hasStartForm() {
let selectedProcessDefinition = this.getSelectedProcess();
return selectedProcessDefinition && selectedProcessDefinition.hasStartForm;
}
isStartFormMissingOrValid() {
return !this.startForm || this.startForm.form.isValid;
}
validateForm() {
return this.processDefinitionId && this.name && this.isStartFormMissingOrValid();
}
}

View File

@ -45,6 +45,7 @@
"TYPE": "Type",
"NAME": "Name"
},
"TYPE_PLACEHOLDER": "Choose one...",
"ACTION": {
"START": "Start",
"CANCEL": "Cancel"

View File

@ -226,10 +226,14 @@ export class ActivitiProcessService {
.catch(this.handleError);
}
startProcess(processDefinitionId: string, name: string) {
let startRequest: any = {};
startRequest.name = name;
startRequest.processDefinitionId = processDefinitionId;
startProcess(processDefinitionId: string, name: string, startFormValues?: any) {
let startRequest: any = {
name: name,
processDefinitionId: processDefinitionId
};
if (startFormValues) {
startRequest.values = startFormValues;
}
return Observable.fromPromise(
this.authService.getAlfrescoApi().activiti.processApi.startNewProcessInstance(startRequest)
)