This commit is contained in:
Mario Romano
2016-08-12 12:09:03 +01:00
parent dccaa74253
commit 2f941c95a5
31 changed files with 2460 additions and 26 deletions

View File

@@ -1,11 +1,10 @@
<div>
<div *ngIf="!hasForm()">
<h3 style="text-align: center">Please select a Task</h3>
<h3 style="text-align: center">Please select a Visit</h3>
</div>
<div *ngIf="hasForm()">
<div class="mdl-card mdl-shadow--2dp activiti-form-container">
<div *ngIf="form.taskName" class="mdl-card__title">
<div *ngIf="isTitleEnabled()" class="mdl-card__title">
<h2 class="mdl-card__title-text">{{form.taskName}}</h2>
</div>
<div class="mdl-card__media">
@@ -25,7 +24,7 @@
{{outcome.name}}
</button>
</div>
<div class="mdl-card__menu">
<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>
@@ -34,7 +33,6 @@
</div>
</div>
</div>
<!--
For debugging and data visualisation purposes,
will be removed during future revisions

View File

@@ -19,7 +19,9 @@ import {
Component,
OnInit, AfterViewChecked, OnChanges,
SimpleChange,
Input
Input,
Output,
EventEmitter
} from '@angular/core';
import { MATERIAL_DESIGN_DIRECTIVES } from 'ng2-alfresco-core';
@@ -32,6 +34,32 @@ import { ContainerWidget } from './widgets/container/container.widget';
declare let __moduleName: string;
declare var componentHandler;
/**
* @Input
* ActivitiForm can show 3 forms searching by 3 type of params:
* 1) Form attached to a task passing the {taskId}.
* 2) Form that are only defined with the {formId} (in this case you receive only the form definition and the form will not be
* attached to any process, usefull in case you want to use Activitiform as form designer), in this case you can pass also other 2
* parameters:
* - {saveOption} as parameter to tell what is the function to call on the save action.
* - {data} to fill the form field with some data, the id of the form must to match the name of the field of the provided data object.
* 3) Form that are only defined with the {formName} (in this case you receive only the form definition and the form will not be
* attached to any process, usefull in case you want to use Activitiform as form designer),
* in this case you can pass also other 2 parameters:
* - {saveOption} as parameter to tell what is the function to call on the save action.
* - {data} to fill the form field with some data, the id of the form must to match the name of the field of the provided data object.
*
* {showTitle} boolean - to hide the title of the form pass false, default true;
*
* {showRefreshButton} boolean - to hide the refresh button of the form pass false, default true;
*
* @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: __moduleName,
selector: 'activiti-form',
@@ -45,19 +73,57 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges {
@Input()
taskId: string;
@Input()
formId: string;
@Input()
formName: string;
@Input()
data: any;
@Input()
showTitle: boolean = true;
@Input()
readOnly: boolean = false;
@Input()
showRefreshButton: boolean = true;
@Output()
formsaved = new EventEmitter();
@Output()
formCompleted = new EventEmitter();
@Output()
formLoaded = new EventEmitter();
form: FormModel;
debugMode: boolean = false;
hasForm(): boolean {
return this.form ? true : false;
}
isTitleEnabled(): boolean {
return this.form.taskName && this.showTitle;
}
constructor(private formService: FormService) {}
ngOnInit() {
if (this.taskId) {
this.loadForm(this.taskId);
}
if (this.formId) {
this.getFormDefinitionById();
}
if (this.formName) {
this.getFormDefinitionByName();
}
}
ngAfterViewChecked() {
@@ -72,11 +138,21 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges {
if (taskId && taskId.currentValue) {
this.loadForm(taskId.currentValue);
}
let formId = changes['formId'];
if (formId && formId.currentValue) {
this.getFormDefinitionById();
}
let formName = changes['formName'];
if (formName && formName.currentValue) {
this.getFormDefinitionByName();
}
}
onOutcomeClicked(outcome: FormOutcomeModel, event?: Event) {
if (outcome) {
if (!this.readOnly && outcome) {
if (outcome.isSystem) {
if (outcome.id === '$save') {
return this.saveTaskForm();
@@ -86,9 +162,13 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges {
return this.completeTaskForm();
}
if (outcome.id === '$custom') {
this.formsaved.emit(this.form.values);
}
} else {
// Note: Activiti is using NAME field rather than ID for outcomes
if (outcome.name) {
this.formsaved.emit(this.form.values);
return this.completeTaskForm(outcome.name);
}
}
@@ -99,13 +179,54 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges {
if (this.taskId) {
this.loadForm(this.taskId);
}
if (this.formId) {
this.getFormDefinitionById();
}
if (this.formName) {
this.getFormDefinitionByName();
}
}
private loadForm(taskId: string) {
let data = this.data;
this.formService
.getTaskForm(taskId)
.subscribe(
form => this.form = new FormModel(form),
form => {
this.form = new FormModel(form, data, null, this.readOnly);
this.formLoaded.emit(this.form.values);
},
err => console.log(err)
);
}
private getFormDefinitionById() {
this.formService
.getFormDefinitionById(this.formId)
.subscribe(
form => {
console.log('Get Form By definition Id', form);
this.form = new FormModel(form, this.data, this.formsaved, this.readOnly);
this.formLoaded.emit(this.form.values);
},
err => console.log(err)
);
}
private getFormDefinitionByName() {
this.formService
.getFormDefinitionByName(this.formName)
.subscribe(
id => {
this.formService.getFormDefinitionById(id).subscribe(
form => {
console.log('Get Form By Form definition Name', form);
this.form = new FormModel(form, this.data, this.formsaved, this.readOnly);
this.formLoaded.emit(this.form.values);
},
err => console.log(err)
);
},
err => console.log(err)
);
}
@@ -113,10 +234,10 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges {
private saveTaskForm() {
this.formService.saveTaskForm(this.form.taskId, this.form.values).subscribe(
(response) => {
console.log(response);
alert('Saved');
console.log('Saved task', response);
this.formsaved.emit(this.form.values);
},
(err) => window.alert(err)
(err) => console.log(err)
);
}
@@ -125,11 +246,10 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges {
.completeTaskForm(this.form.taskId, this.form.values, outcome)
.subscribe(
(response) => {
console.log(response);
alert('Saved');
console.log('Completed task', response);
this.formCompleted.emit(this.form.values);
},
(err) => window.alert(err)
(err) => console.log(err)
);
}
}

View File

@@ -376,14 +376,14 @@ export class FormModel {
return this.outcomes && this.outcomes.length > 0;
}
constructor(json?: any) {
constructor(json?: any, data?: any, saveOption?: any, readOnly: boolean = false) {
if (json) {
this._json = json;
this._id = json.id;
this._name = json.name;
this._taskId = json.taskId;
this._taskName = json.taskName || this.UNSET_TASK_NAME;
this._taskName = json.taskName || json.name || this.UNSET_TASK_NAME;
let tabCache: WidgetModelCache<TabModel> = {};
@@ -394,7 +394,12 @@ export class FormModel {
return model;
});
this.fields = (json.fields || []).map(obj => new ContainerModel(this, obj));
this.fields = (json.fields || json.formDefinition.fields || []).map(obj => new ContainerModel(this, obj));
if (data) {
this.updateFormValueWithProvaidedDataModel(data);
}
for (let i = 0; i < this.fields.length; i++) {
let field = this.fields[i];
if (field.tab) {
@@ -404,18 +409,55 @@ export class FormModel {
}
}
}
if (this.isATaskForm()) {
let saveOutcome = new FormOutcomeModel(this, {id: '$save', name: 'Save'});
saveOutcome.isSystem = true;
let saveOutcome = new FormOutcomeModel(this, {id: '$save', name: 'Save'});
saveOutcome.isSystem = true;
let completeOutcome = new FormOutcomeModel(this, {id: '$complete', name: 'Complete'});
completeOutcome.isSystem = true;
let completeOutcome = new FormOutcomeModel(this, {id: '$complete', name: 'Complete'});
completeOutcome.isSystem = true;
let customOutcomes = (json.outcomes || []).map(obj => new FormOutcomeModel(this, obj));
let customOutcomes = (json.outcomes || []).map(obj => new FormOutcomeModel(this, obj));
this.outcomes = [saveOutcome].concat(
customOutcomes.length > 0 ? customOutcomes : [completeOutcome]
);
} else {
if (saveOption && saveOption.observers.length > 0) {
let saveOutcome = new FormOutcomeModel(this, {id: '$custom', name: 'Save'});
saveOutcome.isSystem = true;
this.outcomes = [saveOutcome].concat(
customOutcomes.length > 0 ? customOutcomes : [completeOutcome]
);
this.outcomes = [saveOutcome];
}
}
}
}
private updateFormValueWithProvaidedDataModel(data: any) {
for (let i = 0; i < this.fields.length; i++) {
let containerModel = this.fields[i];
if (containerModel) {
for (let i = 0; i < containerModel.columns.length; i++) {
let containerModelColumn = containerModel.columns[i];
if (containerModelColumn) {
for (let i = 0; i < containerModelColumn.fields.length; i++) {
let formField = containerModelColumn.fields[i];
if (data[formField.id]) {
formField.value = data[formField.id];
formField.json.value = data[formField.id];
}
}
}
}
}
}
}
/**
* Check if the form is associated to a task or if is only the form definition
* @returns {boolean}
*/
private isATaskForm(): boolean {
return this._json.fields ? true : false;
}
}

View File

@@ -96,6 +96,27 @@ export class FormService {
.catch(this.handleError);
}
getFormDefinitionById(id: string): Observable<any> {
let url = `${this.alfrescoSettingsService.bpmHost}/activiti-app/app/rest/form-models/${id}`;
let options = this.getRequestOptions();
return this.http
.get(url, options)
.map(this.toJson)
.catch(this.handleError);
}
getFormDefinitionByName(name: string): Observable<any> {
let url = `${this.alfrescoSettingsService.bpmHost}` +
`/activiti-app/app/rest/models?filter=myReusableForms&filterText=${name}&modelType=2`;
let options = this.getRequestOptions();
return this.http
.get(url, options)
.map(this.getFormId)
.catch(this.handleError);
}
private getHeaders(): Headers {
return new Headers({
'Accept': 'application/json',
@@ -109,6 +130,11 @@ export class FormService {
return new RequestOptions({headers: headers});
}
private getFormId(res: Response) {
let body = res.json();
return body.data[0].id || {};
}
private toJson(res: Response) {
let body = res.json();
return body || {};