mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-31 17:38:48 +00:00
@@ -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
|
||||
|
@@ -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)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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 || {};
|
||||
|
Reference in New Issue
Block a user