mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-31 17:38:48 +00:00
[ADF-907] - Form reacts to data added in input (#2016)
* [ADF-907] Enable activiti form to react on value data changes * [ADF-907] - Form reacts to data added in input] * [ADF - 907] added mock json for form * [ADF-907] added new event of the form to the event list * [ADF - 907] Added return column to README * [ADF - 907] Added return column to README
This commit is contained in:
@@ -2,14 +2,14 @@
|
|||||||
* @license
|
* @license
|
||||||
* Copyright 2016 Alfresco Software, Ltd.
|
* Copyright 2016 Alfresco Software, Ltd.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
@@ -17,6 +17,343 @@
|
|||||||
|
|
||||||
export class DemoForm {
|
export class DemoForm {
|
||||||
|
|
||||||
|
static getEasyForm(): any {
|
||||||
|
return {
|
||||||
|
'id': 1001,
|
||||||
|
'name': 'ISSUE_FORM',
|
||||||
|
'processDefinitionId': 'ISSUE_APP:1:2504',
|
||||||
|
'processDefinitionName': 'ISSUE_APP',
|
||||||
|
'processDefinitionKey': 'ISSUE_APP',
|
||||||
|
'taskId': '2510',
|
||||||
|
'taskDefinitionKey': 'sid-F67A2996-1684-4774-855A-4591490081FD',
|
||||||
|
'tabs': [],
|
||||||
|
'fields': [
|
||||||
|
{
|
||||||
|
'fieldType': 'ContainerRepresentation',
|
||||||
|
'id': '1498212398417',
|
||||||
|
'name': 'Label',
|
||||||
|
'type': 'container',
|
||||||
|
'value': null,
|
||||||
|
'required': false,
|
||||||
|
'readOnly': false,
|
||||||
|
'overrideId': false,
|
||||||
|
'colspan': 1,
|
||||||
|
'placeholder': null,
|
||||||
|
'minLength': 0,
|
||||||
|
'maxLength': 0,
|
||||||
|
'minValue': null,
|
||||||
|
'maxValue': null,
|
||||||
|
'regexPattern': null,
|
||||||
|
'optionType': null,
|
||||||
|
'hasEmptyValue': false,
|
||||||
|
'options': null,
|
||||||
|
'restUrl': null,
|
||||||
|
'restResponsePath': null,
|
||||||
|
'restIdProperty': null,
|
||||||
|
'restLabelProperty': null,
|
||||||
|
'tab': null,
|
||||||
|
'className': null,
|
||||||
|
'dateDisplayFormat': null,
|
||||||
|
'sizeX': 2,
|
||||||
|
'sizeY': 1,
|
||||||
|
'row': -1,
|
||||||
|
'col': -1,
|
||||||
|
'numberOfColumns': 2,
|
||||||
|
'fields': {
|
||||||
|
'1': [
|
||||||
|
{
|
||||||
|
'fieldType': 'RestFieldRepresentation',
|
||||||
|
'id': 'label',
|
||||||
|
'name': 'Label',
|
||||||
|
'type': 'dropdown',
|
||||||
|
'value': 'Choose one...',
|
||||||
|
'required': false,
|
||||||
|
'readOnly': false,
|
||||||
|
'overrideId': false,
|
||||||
|
'colspan': 1,
|
||||||
|
'placeholder': null,
|
||||||
|
'minLength': 0,
|
||||||
|
'maxLength': 0,
|
||||||
|
'minValue': null,
|
||||||
|
'maxValue': null,
|
||||||
|
'regexPattern': null,
|
||||||
|
'optionType': null,
|
||||||
|
'hasEmptyValue': true,
|
||||||
|
'options': [
|
||||||
|
{
|
||||||
|
'id': 'empty',
|
||||||
|
'name': 'Choose one...'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'id': 'option_1',
|
||||||
|
'name': 'test1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'id': 'option_2',
|
||||||
|
'name': 'test2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'id': 'option_3',
|
||||||
|
'name': 'test3'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'restUrl': null,
|
||||||
|
'restResponsePath': null,
|
||||||
|
'restIdProperty': null,
|
||||||
|
'restLabelProperty': null,
|
||||||
|
'tab': null,
|
||||||
|
'className': null,
|
||||||
|
'params': {
|
||||||
|
'existingColspan': 1,
|
||||||
|
'maxColspan': 2
|
||||||
|
},
|
||||||
|
'dateDisplayFormat': null,
|
||||||
|
'layout': {
|
||||||
|
'row': -1,
|
||||||
|
'column': -1,
|
||||||
|
'colspan': 1
|
||||||
|
},
|
||||||
|
'sizeX': 1,
|
||||||
|
'sizeY': 1,
|
||||||
|
'row': -1,
|
||||||
|
'col': -1,
|
||||||
|
'visibilityCondition': null,
|
||||||
|
'endpoint': null,
|
||||||
|
'requestHeaders': null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'fieldType': 'FormFieldRepresentation',
|
||||||
|
'id': 'Date',
|
||||||
|
'name': 'Date',
|
||||||
|
'type': 'date',
|
||||||
|
'value': null,
|
||||||
|
'required': false,
|
||||||
|
'readOnly': false,
|
||||||
|
'overrideId': false,
|
||||||
|
'colspan': 1,
|
||||||
|
'placeholder': null,
|
||||||
|
'minLength': 0,
|
||||||
|
'maxLength': 0,
|
||||||
|
'minValue': null,
|
||||||
|
'maxValue': null,
|
||||||
|
'regexPattern': null,
|
||||||
|
'optionType': null,
|
||||||
|
'hasEmptyValue': null,
|
||||||
|
'options': null,
|
||||||
|
'restUrl': null,
|
||||||
|
'restResponsePath': null,
|
||||||
|
'restIdProperty': null,
|
||||||
|
'restLabelProperty': null,
|
||||||
|
'tab': 'tab1',
|
||||||
|
'className': null,
|
||||||
|
'params': {
|
||||||
|
'existingColspan': 1,
|
||||||
|
'maxColspan': 2
|
||||||
|
},
|
||||||
|
'dateDisplayFormat': null,
|
||||||
|
'layout': {
|
||||||
|
'row': -1,
|
||||||
|
'column': -1,
|
||||||
|
'colspan': 1
|
||||||
|
},
|
||||||
|
'sizeX': 1,
|
||||||
|
'sizeY': 1,
|
||||||
|
'row': -1,
|
||||||
|
'col': -1,
|
||||||
|
'visibilityCondition': null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'fieldType': 'FormFieldRepresentation',
|
||||||
|
'id': 'label5',
|
||||||
|
'name': 'Label5',
|
||||||
|
'type': 'boolean',
|
||||||
|
'value': null,
|
||||||
|
'required': false,
|
||||||
|
'readOnly': false,
|
||||||
|
'overrideId': false,
|
||||||
|
'colspan': 1,
|
||||||
|
'placeholder': null,
|
||||||
|
'minLength': 0,
|
||||||
|
'maxLength': 0,
|
||||||
|
'minValue': null,
|
||||||
|
'maxValue': null,
|
||||||
|
'regexPattern': null,
|
||||||
|
'optionType': null,
|
||||||
|
'hasEmptyValue': null,
|
||||||
|
'options': null,
|
||||||
|
'restUrl': null,
|
||||||
|
'restResponsePath': null,
|
||||||
|
'restIdProperty': null,
|
||||||
|
'restLabelProperty': null,
|
||||||
|
'tab': 'tab1',
|
||||||
|
'className': null,
|
||||||
|
'params': {
|
||||||
|
'existingColspan': 1,
|
||||||
|
'maxColspan': 1
|
||||||
|
},
|
||||||
|
'dateDisplayFormat': null,
|
||||||
|
'layout': {
|
||||||
|
'row': -1,
|
||||||
|
'column': -1,
|
||||||
|
'colspan': 1
|
||||||
|
},
|
||||||
|
'sizeX': 1,
|
||||||
|
'sizeY': 1,
|
||||||
|
'row': -1,
|
||||||
|
'col': -1,
|
||||||
|
'visibilityCondition': null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'fieldType': 'FormFieldRepresentation',
|
||||||
|
'id': 'label6',
|
||||||
|
'name': 'Label6',
|
||||||
|
'type': 'boolean',
|
||||||
|
'value': null,
|
||||||
|
'required': false,
|
||||||
|
'readOnly': false,
|
||||||
|
'overrideId': false,
|
||||||
|
'colspan': 1,
|
||||||
|
'placeholder': null,
|
||||||
|
'minLength': 0,
|
||||||
|
'maxLength': 0,
|
||||||
|
'minValue': null,
|
||||||
|
'maxValue': null,
|
||||||
|
'regexPattern': null,
|
||||||
|
'optionType': null,
|
||||||
|
'hasEmptyValue': null,
|
||||||
|
'options': null,
|
||||||
|
'restUrl': null,
|
||||||
|
'restResponsePath': null,
|
||||||
|
'restIdProperty': null,
|
||||||
|
'restLabelProperty': null,
|
||||||
|
'tab': 'tab1',
|
||||||
|
'className': null,
|
||||||
|
'params': {
|
||||||
|
'existingColspan': 1,
|
||||||
|
'maxColspan': 1
|
||||||
|
},
|
||||||
|
'dateDisplayFormat': null,
|
||||||
|
'layout': {
|
||||||
|
'row': -1,
|
||||||
|
'column': -1,
|
||||||
|
'colspan': 1
|
||||||
|
},
|
||||||
|
'sizeX': 1,
|
||||||
|
'sizeY': 1,
|
||||||
|
'row': -1,
|
||||||
|
'col': -1,
|
||||||
|
'visibilityCondition': null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'fieldType': 'FormFieldRepresentation',
|
||||||
|
'id': 'label4',
|
||||||
|
'name': 'Label4',
|
||||||
|
'type': 'integer',
|
||||||
|
'value': null,
|
||||||
|
'required': false,
|
||||||
|
'readOnly': false,
|
||||||
|
'overrideId': false,
|
||||||
|
'colspan': 1,
|
||||||
|
'placeholder': null,
|
||||||
|
'minLength': 0,
|
||||||
|
'maxLength': 0,
|
||||||
|
'minValue': null,
|
||||||
|
'maxValue': null,
|
||||||
|
'regexPattern': null,
|
||||||
|
'optionType': null,
|
||||||
|
'hasEmptyValue': null,
|
||||||
|
'options': null,
|
||||||
|
'restUrl': null,
|
||||||
|
'restResponsePath': null,
|
||||||
|
'restIdProperty': null,
|
||||||
|
'restLabelProperty': null,
|
||||||
|
'tab': 'tab1',
|
||||||
|
'className': null,
|
||||||
|
'params': {
|
||||||
|
'existingColspan': 1,
|
||||||
|
'maxColspan': 2
|
||||||
|
},
|
||||||
|
'dateDisplayFormat': null,
|
||||||
|
'layout': {
|
||||||
|
'row': -1,
|
||||||
|
'column': -1,
|
||||||
|
'colspan': 1
|
||||||
|
},
|
||||||
|
'sizeX': 1,
|
||||||
|
'sizeY': 1,
|
||||||
|
'row': -1,
|
||||||
|
'col': -1,
|
||||||
|
'visibilityCondition': null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'fieldType': 'RestFieldRepresentation',
|
||||||
|
'id': 'label12',
|
||||||
|
'name': 'Label12',
|
||||||
|
'type': 'radio-buttons',
|
||||||
|
'value': null,
|
||||||
|
'required': false,
|
||||||
|
'readOnly': false,
|
||||||
|
'overrideId': false,
|
||||||
|
'colspan': 1,
|
||||||
|
'placeholder': null,
|
||||||
|
'minLength': 0,
|
||||||
|
'maxLength': 0,
|
||||||
|
'minValue': null,
|
||||||
|
'maxValue': null,
|
||||||
|
'regexPatt§12212ern': null,
|
||||||
|
'optionType': null,
|
||||||
|
'hasEmptyValue': null,
|
||||||
|
'options': [
|
||||||
|
{
|
||||||
|
'id': 'option_1',
|
||||||
|
'name': 'Option 1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'id': 'option_2',
|
||||||
|
'name': 'Option 2'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'restUrl': null,
|
||||||
|
'restResponsePath': null,
|
||||||
|
'restIdProperty': null,
|
||||||
|
'restLabelProperty': null,
|
||||||
|
'tab': 'tab1',
|
||||||
|
'className': null,
|
||||||
|
'params': {
|
||||||
|
'existingColspan': 1,
|
||||||
|
'maxColspan': 2
|
||||||
|
},
|
||||||
|
'dateDisplayFormat': null,
|
||||||
|
'layout': {
|
||||||
|
'row': -1,
|
||||||
|
'column': -1,
|
||||||
|
'colspan': 1
|
||||||
|
},
|
||||||
|
'sizeX': 1,
|
||||||
|
'sizeY': 1,
|
||||||
|
'row': -1,
|
||||||
|
'col': -1,
|
||||||
|
'visibilityCondition': null,
|
||||||
|
'endpoint': null,
|
||||||
|
'requestHeaders': null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'outcomes': [],
|
||||||
|
'javascriptEvents': [],
|
||||||
|
'className': '',
|
||||||
|
'style': '',
|
||||||
|
'customFieldTemplates': {},
|
||||||
|
'metadata': {},
|
||||||
|
'variables': [],
|
||||||
|
'customFieldsValueInfo': {},
|
||||||
|
'gridsterForm': false,
|
||||||
|
'globalDateFormat': 'D-M-YYYY'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
static getDefinition(): any {
|
static getDefinition(): any {
|
||||||
return {
|
return {
|
||||||
'id': 3003,
|
'id': 3003,
|
||||||
|
@@ -1,3 +1,8 @@
|
|||||||
.form-container {
|
.form-container {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.store-form-container{
|
||||||
|
width: 80%;
|
||||||
|
height: 80%;
|
||||||
|
}
|
||||||
|
@@ -1,4 +1,32 @@
|
|||||||
<div class="form-container">
|
<div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">
|
||||||
|
<header class="mdl-layout__header">
|
||||||
|
<div class="mdl-layout__tab-bar mdl-js-ripple-effect">
|
||||||
|
<a id="demo-form" href="#demo" class="mdl-layout__tab" [class.is-active]="activeTab === 'demo'" (click)="changeToDemoForm()">DEMO</a>
|
||||||
|
<a id="store-form" href="#store" class="mdl-layout__tab" [class.is-active]="activeTab === 'processes'" (click)="changeToStoreForm()">STORE</a>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<main class="mdl-layout__content activiti">
|
||||||
|
<section class="mdl-layout__tab-panel" [class.is-active]="activeTab === 'demo'" id="demo">
|
||||||
|
<div class="form-container">
|
||||||
<activiti-form [form]="form">
|
<activiti-form [form]="form">
|
||||||
</activiti-form>
|
</activiti-form>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="mdl-layout__tab-panel" [class.is-active]="activeTab === 'store'" id="store">
|
||||||
|
<span>FORM NAME TO VISUALIZE</span>
|
||||||
|
<input [(ngModel)]="formToLoadName" class="mdl-textfield__input" type="text" (ngModelChange)="loadForm()">
|
||||||
|
<div *ngIf="formToLoadName && formToLoadName !== '' " class="store-form-container">
|
||||||
|
<activiti-form [form]="form" [data]="restoredData" #storeForm>
|
||||||
|
</activiti-form>
|
||||||
|
<button class="mdl-button mdl-js-button" (click)="store()">STORE</button>
|
||||||
|
<button class="mdl-button mdl-js-button" (click)="restore()">RESTORE</button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span> Please create in APS the form with the name you entered</span>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="showError">
|
||||||
|
<span> Form Name not valid or form not present</span>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -15,9 +15,12 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core';
|
||||||
import { FormModel, FormService } from 'ng2-activiti-form';
|
import { FormModel, FormService } from 'ng2-activiti-form';
|
||||||
import { DemoForm } from './demo-form';
|
import { DemoForm } from './demo-form';
|
||||||
|
import { ActivitiForm } from 'ng2-activiti-form';
|
||||||
|
|
||||||
|
declare var componentHandler;
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'form-demo',
|
selector: 'form-demo',
|
||||||
@@ -26,9 +29,17 @@ import { DemoForm } from './demo-form';
|
|||||||
'form-demo.component.css'
|
'form-demo.component.css'
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class FormDemoComponent implements OnInit {
|
export class FormDemoComponent implements OnInit, AfterViewInit {
|
||||||
|
|
||||||
|
@ViewChild(ActivitiForm)
|
||||||
|
activitiForm: ActivitiForm;
|
||||||
|
|
||||||
form: FormModel;
|
form: FormModel;
|
||||||
|
activeTab: string = 'demo';
|
||||||
|
storedData: any = {};
|
||||||
|
restoredData: any = {};
|
||||||
|
formToLoadName: string = null;
|
||||||
|
showError: boolean = false;
|
||||||
|
|
||||||
constructor(private formService: FormService) {
|
constructor(private formService: FormService) {
|
||||||
formService.executeOutcome.subscribe(e => {
|
formService.executeOutcome.subscribe(e => {
|
||||||
@@ -43,4 +54,69 @@ export class FormDemoComponent implements OnInit {
|
|||||||
console.log(form);
|
console.log(form);
|
||||||
this.form = form;
|
this.form = form;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngAfterViewInit() {
|
||||||
|
// workaround for MDL issues with dynamic components
|
||||||
|
if (componentHandler) {
|
||||||
|
componentHandler.upgradeAllRegistered();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
changeToStoreForm() {
|
||||||
|
this.activeTab = 'store';
|
||||||
|
this.showError = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
changeToDemoForm() {
|
||||||
|
this.activeTab = 'demo';
|
||||||
|
let formDefinitionJSON: any = DemoForm.getDefinition();
|
||||||
|
let demoForm = this.formService.parseForm(formDefinitionJSON);
|
||||||
|
this.form = demoForm;
|
||||||
|
}
|
||||||
|
|
||||||
|
store() {
|
||||||
|
this.clone(this.activitiForm.form.values, this.storedData);
|
||||||
|
console.log('DATA SAVED');
|
||||||
|
console.log(this.storedData);
|
||||||
|
console.log('DATA SAVED');
|
||||||
|
this.restoredData = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
restore() {
|
||||||
|
this.restoredData = this.storedData;
|
||||||
|
this.storedData = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
clone(objToCopyFrom, objToCopyTo) {
|
||||||
|
for (let attribute in objToCopyFrom) {
|
||||||
|
if (objToCopyFrom.hasOwnProperty(attribute)) {
|
||||||
|
objToCopyTo[attribute] = objToCopyFrom[attribute];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return objToCopyTo;
|
||||||
|
}
|
||||||
|
|
||||||
|
loadForm() {
|
||||||
|
if (this.formToLoadName) {
|
||||||
|
this.showError = false;
|
||||||
|
this.formService
|
||||||
|
.getFormDefinitionByName(this.formToLoadName)
|
||||||
|
.debounceTime(7000)
|
||||||
|
.subscribe(
|
||||||
|
id => {
|
||||||
|
this.formService.getFormDefinitionById(id).subscribe(
|
||||||
|
form => {
|
||||||
|
this.form = this.formService.parseForm((form);
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
this.showError = true;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
this.showError = true;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -174,13 +174,14 @@ The recommended set of properties can be found in the following table:
|
|||||||
|
|
||||||
### Events
|
### Events
|
||||||
|
|
||||||
| Name | Description |
|
| Name | Return Type | Description |
|
||||||
| --- | --- |
|
| --- | --- | --- |
|
||||||
| formLoaded | Invoked when form is loaded or reloaded. |
|
| formLoaded | [FormModel](https://github.com/Alfresco/alfresco-ng2-components/blob/master/ng2-components/ng2-activiti-form/src/components/widgets/core/form.model.ts) | Invoked when form is loaded or reloaded. |
|
||||||
| formSaved | Invoked when form is submitted with `Save` or custom outcomes. |
|
| formSaved | [FormModel](https://github.com/Alfresco/alfresco-ng2-components/blob/master/ng2-components/ng2-activiti-form/src/components/widgets/core/form.model.ts) | Invoked when form is submitted with `Save` or custom outcomes. |
|
||||||
| formCompleted | Invoked when form is submitted with `Complete` outcome. |
|
| formCompleted | [FormModel](https://github.com/Alfresco/alfresco-ng2-components/blob/master/ng2-components/ng2-activiti-form/src/components/widgets/core/form.model.ts) | Invoked when form is submitted with `Complete` outcome. |
|
||||||
| executeOutcome | Invoked when any outcome is executed, default behaviour can be prevented via `event.preventDefault()` |
|
| formDataRefreshed | [FormModel](https://github.com/Alfresco/alfresco-ng2-components/blob/master/ng2-components/ng2-activiti-form/src/components/widgets/core/form.model.ts) | Invoked when form values are refreshed due a data property change |
|
||||||
| onError | Invoked at any error |
|
| executeOutcome | [FormOutcomeEvent](https://github.com/Alfresco/alfresco-ng2-components/blob/master/ng2-components/ng2-activiti-form/src/components/widgets/core/form-outcome-event.model.ts) | Invoked when any outcome is executed, default behaviour can be prevented via `event.preventDefault()` |
|
||||||
|
| onError | any | Invoked at any error |
|
||||||
|
|
||||||
All `form*` events receive an instance of the `FormModel` as event argument for ease of development:
|
All `form*` events receive an instance of the `FormModel` as event argument for ease of development:
|
||||||
|
|
||||||
|
@@ -0,0 +1,275 @@
|
|||||||
|
/*!
|
||||||
|
* @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 let fakeForm = {
|
||||||
|
id: 1001,
|
||||||
|
name: 'ISSUE_FORM',
|
||||||
|
processDefinitionId: 'ISSUE_APP:1:2504',
|
||||||
|
processDefinitionName: 'ISSUE_APP',
|
||||||
|
processDefinitionKey: 'ISSUE_APP',
|
||||||
|
taskId: '7506',
|
||||||
|
taskDefinitionKey: 'sid-F67A2996-1684-4774-855A-4591490081FD',
|
||||||
|
tabs: [],
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
fieldType: 'ContainerRepresentation',
|
||||||
|
id: '1498212398417',
|
||||||
|
name: 'Label',
|
||||||
|
type: 'container',
|
||||||
|
value: null,
|
||||||
|
required: false,
|
||||||
|
readOnly: false,
|
||||||
|
overrideId: false,
|
||||||
|
colspan: 1,
|
||||||
|
placeholder: null,
|
||||||
|
minLength: 0,
|
||||||
|
maxLength: 0,
|
||||||
|
minValue: null,
|
||||||
|
maxValue: null,
|
||||||
|
regexPattern: null,
|
||||||
|
optionType: null,
|
||||||
|
hasEmptyValue: null,
|
||||||
|
options: null,
|
||||||
|
restUrl: null,
|
||||||
|
restResponsePath: null,
|
||||||
|
restIdProperty: null,
|
||||||
|
restLabelProperty: null,
|
||||||
|
tab: null,
|
||||||
|
className: null,
|
||||||
|
dateDisplayFormat: null,
|
||||||
|
layout: null,
|
||||||
|
sizeX: 2,
|
||||||
|
sizeY: 1,
|
||||||
|
row: -1,
|
||||||
|
col: -1,
|
||||||
|
visibilityCondition: null,
|
||||||
|
numberOfColumns: 2,
|
||||||
|
fields: {
|
||||||
|
1: [
|
||||||
|
{
|
||||||
|
fieldType: 'RestFieldRepresentation',
|
||||||
|
id: 'label',
|
||||||
|
name: 'Label',
|
||||||
|
type: 'dropdown',
|
||||||
|
value: 'Choose one...',
|
||||||
|
required: false,
|
||||||
|
readOnly: false,
|
||||||
|
overrideId: false,
|
||||||
|
colspan: 1,
|
||||||
|
placeholder: null,
|
||||||
|
minLength: 0,
|
||||||
|
maxLength: 0,
|
||||||
|
minValue: null,
|
||||||
|
maxValue: null,
|
||||||
|
regexPattern: null,
|
||||||
|
optionType: null,
|
||||||
|
hasEmptyValue: true,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
id: 'empty',
|
||||||
|
name: 'Choose one...'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'option_1',
|
||||||
|
name: 'test1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'option_2',
|
||||||
|
name: 'test2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'option_3',
|
||||||
|
name: 'test3'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
restUrl: null,
|
||||||
|
restResponsePath: null,
|
||||||
|
restIdProperty: null,
|
||||||
|
restLabelProperty: null,
|
||||||
|
tab: null,
|
||||||
|
className: null,
|
||||||
|
params: {
|
||||||
|
existingColspan: 1,
|
||||||
|
maxColspan: 2
|
||||||
|
},
|
||||||
|
dateDisplayFormat: null,
|
||||||
|
layout: {
|
||||||
|
row: -1,
|
||||||
|
column: -1,
|
||||||
|
colspan: 1
|
||||||
|
},
|
||||||
|
sizeX: 1,
|
||||||
|
sizeY: 1,
|
||||||
|
row: -1,
|
||||||
|
col: -1,
|
||||||
|
visibilityCondition: null,
|
||||||
|
endpoint: null,
|
||||||
|
requestHeaders: null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
2: [
|
||||||
|
{
|
||||||
|
fieldType: 'RestFieldRepresentation',
|
||||||
|
id: 'raduio',
|
||||||
|
name: 'raduio',
|
||||||
|
type: 'radio-buttons',
|
||||||
|
value: null,
|
||||||
|
required: false,
|
||||||
|
readOnly: false,
|
||||||
|
overrideId: false,
|
||||||
|
colspan: 1,
|
||||||
|
placeholder: null,
|
||||||
|
minLength: 0,
|
||||||
|
maxLength: 0,
|
||||||
|
minValue: null,
|
||||||
|
maxValue: null,
|
||||||
|
regexPattern: null,
|
||||||
|
optionType: null,
|
||||||
|
hasEmptyValue: null,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
id: 'option_1',
|
||||||
|
name: 'Option 1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'option_2',
|
||||||
|
name: 'Option 2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'option_3',
|
||||||
|
name: 'Option 3'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
restUrl: null,
|
||||||
|
restResponsePath: null,
|
||||||
|
restIdProperty: null,
|
||||||
|
restLabelProperty: null,
|
||||||
|
tab: null,
|
||||||
|
className: null,
|
||||||
|
params: {
|
||||||
|
existingColspan: 1,
|
||||||
|
maxColspan: 1
|
||||||
|
},
|
||||||
|
dateDisplayFormat: null,
|
||||||
|
layout: {
|
||||||
|
row: -1,
|
||||||
|
column: -1,
|
||||||
|
colspan: 1
|
||||||
|
},
|
||||||
|
sizeX: 1,
|
||||||
|
sizeY: 2,
|
||||||
|
row: -1,
|
||||||
|
col: -1,
|
||||||
|
visibilityCondition: null,
|
||||||
|
endpoint: null,
|
||||||
|
requestHeaders: null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldType: 'ContainerRepresentation',
|
||||||
|
id: '1498212413062',
|
||||||
|
name: 'Label',
|
||||||
|
type: 'container',
|
||||||
|
value: null,
|
||||||
|
required: false,
|
||||||
|
readOnly: false,
|
||||||
|
overrideId: false,
|
||||||
|
colspan: 1,
|
||||||
|
placeholder: null,
|
||||||
|
minLength: 0,
|
||||||
|
maxLength: 0,
|
||||||
|
minValue: null,
|
||||||
|
maxValue: null,
|
||||||
|
regexPattern: null,
|
||||||
|
optionType: null,
|
||||||
|
hasEmptyValue: null,
|
||||||
|
options: null,
|
||||||
|
restUrl: null,
|
||||||
|
restResponsePath: null,
|
||||||
|
restIdProperty: null,
|
||||||
|
restLabelProperty: null,
|
||||||
|
tab: null,
|
||||||
|
className: null,
|
||||||
|
dateDisplayFormat: null,
|
||||||
|
layout: null,
|
||||||
|
sizeX: 2,
|
||||||
|
sizeY: 1,
|
||||||
|
row: -1,
|
||||||
|
col: -1,
|
||||||
|
visibilityCondition: null,
|
||||||
|
numberOfColumns: 2,
|
||||||
|
fields: {
|
||||||
|
1: [
|
||||||
|
{
|
||||||
|
fieldType: 'FormFieldRepresentation',
|
||||||
|
id: 'date',
|
||||||
|
name: 'date',
|
||||||
|
type: 'date',
|
||||||
|
value: null,
|
||||||
|
required: false,
|
||||||
|
readOnly: false,
|
||||||
|
overrideId: false,
|
||||||
|
colspan: 1,
|
||||||
|
placeholder: null,
|
||||||
|
minLength: 0,
|
||||||
|
maxLength: 0,
|
||||||
|
minValue: null,
|
||||||
|
maxValue: null,
|
||||||
|
regexPattern: null,
|
||||||
|
optionType: null,
|
||||||
|
hasEmptyValue: null,
|
||||||
|
options: null,
|
||||||
|
restUrl: null,
|
||||||
|
restResponsePath: null,
|
||||||
|
restIdProperty: null,
|
||||||
|
restLabelProperty: null,
|
||||||
|
tab: null,
|
||||||
|
className: null,
|
||||||
|
params: {
|
||||||
|
existingColspan: 1,
|
||||||
|
maxColspan: 2
|
||||||
|
},
|
||||||
|
dateDisplayFormat: null,
|
||||||
|
layout: {
|
||||||
|
row: -1,
|
||||||
|
column: -1,
|
||||||
|
colspan: 1
|
||||||
|
},
|
||||||
|
sizeX: 1,
|
||||||
|
sizeY: 1,
|
||||||
|
row: -1,
|
||||||
|
col: -1,
|
||||||
|
visibilityCondition: null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
2: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
outcomes: [],
|
||||||
|
javascriptEvents: [],
|
||||||
|
className: '',
|
||||||
|
style: '',
|
||||||
|
customFieldTemplates: {},
|
||||||
|
metadata: {},
|
||||||
|
variables: [],
|
||||||
|
customFieldsValueInfo: {},
|
||||||
|
gridsterForm: false,
|
||||||
|
globalDateFormat: 'D-M-YYYY'
|
||||||
|
};
|
@@ -23,6 +23,7 @@ import { FormModel, FormOutcomeModel, FormFieldModel, FormOutcomeEvent, FormFiel
|
|||||||
import { FormService } from './../services/form.service';
|
import { FormService } from './../services/form.service';
|
||||||
import { WidgetVisibilityService } from './../services/widget-visibility.service';
|
import { WidgetVisibilityService } from './../services/widget-visibility.service';
|
||||||
import { NodeService } from './../services/node.service';
|
import { NodeService } from './../services/node.service';
|
||||||
|
import { fakeForm } from '../assets/activiti-form.component.mock';
|
||||||
|
|
||||||
describe('ActivitiForm', () => {
|
describe('ActivitiForm', () => {
|
||||||
|
|
||||||
@@ -107,14 +108,14 @@ describe('ActivitiForm', () => {
|
|||||||
it('should enable custom outcome buttons', () => {
|
it('should enable custom outcome buttons', () => {
|
||||||
let formModel = new FormModel();
|
let formModel = new FormModel();
|
||||||
formComponent.form = formModel;
|
formComponent.form = 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, formComponent.form.readOnly)).toBeTruthy();
|
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow controlling [complete] button visibility', () => {
|
it('should allow controlling [complete] button visibility', () => {
|
||||||
let formModel = new FormModel();
|
let formModel = new FormModel();
|
||||||
formComponent.form = formModel;
|
formComponent.form = 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;
|
formComponent.showSaveButton = true;
|
||||||
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeTruthy();
|
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeTruthy();
|
||||||
@@ -127,7 +128,7 @@ describe('ActivitiForm', () => {
|
|||||||
let formModel = new FormModel();
|
let formModel = new FormModel();
|
||||||
formModel.readOnly = true;
|
formModel.readOnly = true;
|
||||||
formComponent.form = formModel;
|
formComponent.form = formModel;
|
||||||
let outcome = new FormOutcomeModel(formModel, {id: '$complete', name: FormOutcomeModel.COMPLETE_ACTION});
|
let outcome = new FormOutcomeModel(formModel, { id: '$complete', name: FormOutcomeModel.COMPLETE_ACTION });
|
||||||
|
|
||||||
formComponent.showCompleteButton = true;
|
formComponent.showCompleteButton = true;
|
||||||
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeTruthy();
|
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeTruthy();
|
||||||
@@ -137,23 +138,23 @@ describe('ActivitiForm', () => {
|
|||||||
let formModel = new FormModel();
|
let formModel = new FormModel();
|
||||||
formModel.readOnly = true;
|
formModel.readOnly = true;
|
||||||
formComponent.form = formModel;
|
formComponent.form = 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;
|
formComponent.showSaveButton = true;
|
||||||
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeFalsy();
|
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should show [custom-outcome] button with readOnly form and selected custom-outcome', () => {
|
it('should show [custom-outcome] button with readOnly form and selected custom-outcome', () => {
|
||||||
let formModel = new FormModel({selectedOutcome: 'custom-outcome'});
|
let formModel = new FormModel({ selectedOutcome: 'custom-outcome' });
|
||||||
formModel.readOnly = true;
|
formModel.readOnly = true;
|
||||||
formComponent.form = formModel;
|
formComponent.form = formModel;
|
||||||
let outcome = new FormOutcomeModel(formModel, {id: '$customoutome', name: 'custom-outcome'});
|
let outcome = new FormOutcomeModel(formModel, { id: '$customoutome', name: 'custom-outcome' });
|
||||||
|
|
||||||
formComponent.showCompleteButton = true;
|
formComponent.showCompleteButton = true;
|
||||||
formComponent.showSaveButton = true;
|
formComponent.showSaveButton = true;
|
||||||
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeTruthy();
|
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeTruthy();
|
||||||
|
|
||||||
outcome = new FormOutcomeModel(formModel, {id: '$customoutome2', name: 'custom-outcome2'});
|
outcome = new FormOutcomeModel(formModel, { id: '$customoutome2', name: 'custom-outcome2' });
|
||||||
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeFalsy();
|
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -161,7 +162,7 @@ describe('ActivitiForm', () => {
|
|||||||
let formModel = new FormModel();
|
let formModel = new FormModel();
|
||||||
formModel.readOnly = false;
|
formModel.readOnly = false;
|
||||||
formComponent.form = formModel;
|
formComponent.form = 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;
|
formComponent.showCompleteButton = true;
|
||||||
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeTruthy();
|
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeTruthy();
|
||||||
@@ -191,7 +192,7 @@ describe('ActivitiForm', () => {
|
|||||||
it('should get process variable if is a process task', () => {
|
it('should get process variable if is a process task', () => {
|
||||||
spyOn(formService, 'getTaskForm').and.callFake((taskId) => {
|
spyOn(formService, 'getTaskForm').and.callFake((taskId) => {
|
||||||
return Observable.create(observer => {
|
return Observable.create(observer => {
|
||||||
observer.next({taskId: taskId});
|
observer.next({ taskId: taskId });
|
||||||
observer.complete();
|
observer.complete();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -199,7 +200,7 @@ describe('ActivitiForm', () => {
|
|||||||
spyOn(visibilityService, 'getTaskProcessVariable').and.returnValue(Observable.of({}));
|
spyOn(visibilityService, 'getTaskProcessVariable').and.returnValue(Observable.of({}));
|
||||||
spyOn(formService, 'getTask').and.callFake((taskId) => {
|
spyOn(formService, 'getTask').and.callFake((taskId) => {
|
||||||
return Observable.create(observer => {
|
return Observable.create(observer => {
|
||||||
observer.next({taskId: taskId, processDefinitionId: '10201'});
|
observer.next({ taskId: taskId, processDefinitionId: '10201' });
|
||||||
observer.complete();
|
observer.complete();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -214,7 +215,7 @@ describe('ActivitiForm', () => {
|
|||||||
it('should not get process variable if is not a process task', () => {
|
it('should not get process variable if is not a process task', () => {
|
||||||
spyOn(formService, 'getTaskForm').and.callFake((taskId) => {
|
spyOn(formService, 'getTaskForm').and.callFake((taskId) => {
|
||||||
return Observable.create(observer => {
|
return Observable.create(observer => {
|
||||||
observer.next({taskId: taskId});
|
observer.next({ taskId: taskId });
|
||||||
observer.complete();
|
observer.complete();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -222,7 +223,7 @@ describe('ActivitiForm', () => {
|
|||||||
spyOn(visibilityService, 'getTaskProcessVariable').and.returnValue(Observable.of({}));
|
spyOn(visibilityService, 'getTaskProcessVariable').and.returnValue(Observable.of({}));
|
||||||
spyOn(formService, 'getTask').and.callFake((taskId) => {
|
spyOn(formService, 'getTask').and.callFake((taskId) => {
|
||||||
return Observable.create(observer => {
|
return Observable.create(observer => {
|
||||||
observer.next({taskId: taskId, processDefinitionId: 'null'});
|
observer.next({ taskId: taskId, processDefinitionId: 'null' });
|
||||||
observer.complete();
|
observer.complete();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -259,7 +260,7 @@ describe('ActivitiForm', () => {
|
|||||||
const taskId = '<task id>';
|
const taskId = '<task id>';
|
||||||
|
|
||||||
let change = new SimpleChange(null, taskId, true);
|
let change = new SimpleChange(null, taskId, true);
|
||||||
formComponent.ngOnChanges({'taskId': change});
|
formComponent.ngOnChanges({ 'taskId': change });
|
||||||
|
|
||||||
expect(formComponent.getFormByTaskId).toHaveBeenCalledWith(taskId);
|
expect(formComponent.getFormByTaskId).toHaveBeenCalledWith(taskId);
|
||||||
});
|
});
|
||||||
@@ -269,7 +270,7 @@ describe('ActivitiForm', () => {
|
|||||||
const formId = '123';
|
const formId = '123';
|
||||||
|
|
||||||
let change = new SimpleChange(null, formId, true);
|
let change = new SimpleChange(null, formId, true);
|
||||||
formComponent.ngOnChanges({'formId': change});
|
formComponent.ngOnChanges({ 'formId': change });
|
||||||
|
|
||||||
expect(formComponent.getFormDefinitionByFormId).toHaveBeenCalledWith(formId);
|
expect(formComponent.getFormDefinitionByFormId).toHaveBeenCalledWith(formId);
|
||||||
});
|
});
|
||||||
@@ -279,7 +280,7 @@ describe('ActivitiForm', () => {
|
|||||||
const formName = '<form>';
|
const formName = '<form>';
|
||||||
|
|
||||||
let change = new SimpleChange(null, formName, true);
|
let change = new SimpleChange(null, formName, true);
|
||||||
formComponent.ngOnChanges({'formName': change});
|
formComponent.ngOnChanges({ 'formName': change });
|
||||||
|
|
||||||
expect(formComponent.getFormDefinitionByFormName).toHaveBeenCalledWith(formName);
|
expect(formComponent.getFormDefinitionByFormName).toHaveBeenCalledWith(formName);
|
||||||
});
|
});
|
||||||
@@ -304,7 +305,7 @@ describe('ActivitiForm', () => {
|
|||||||
spyOn(formComponent, 'getFormDefinitionByFormId').and.stub();
|
spyOn(formComponent, 'getFormDefinitionByFormId').and.stub();
|
||||||
spyOn(formComponent, 'getFormDefinitionByFormName').and.stub();
|
spyOn(formComponent, 'getFormDefinitionByFormName').and.stub();
|
||||||
|
|
||||||
formComponent.ngOnChanges({'tag': new SimpleChange(null, 'hello world', true)});
|
formComponent.ngOnChanges({ 'tag': new SimpleChange(null, 'hello world', true) });
|
||||||
|
|
||||||
expect(formComponent.getFormByTaskId).not.toHaveBeenCalled();
|
expect(formComponent.getFormByTaskId).not.toHaveBeenCalled();
|
||||||
expect(formComponent.getFormDefinitionByFormId).not.toHaveBeenCalled();
|
expect(formComponent.getFormDefinitionByFormId).not.toHaveBeenCalled();
|
||||||
@@ -314,7 +315,7 @@ describe('ActivitiForm', () => {
|
|||||||
it('should complete form on custom outcome click', () => {
|
it('should complete form on custom outcome click', () => {
|
||||||
let formModel = new FormModel();
|
let formModel = new FormModel();
|
||||||
let outcomeName = 'Custom Action';
|
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;
|
let saved = false;
|
||||||
formComponent.form = formModel;
|
formComponent.form = formModel;
|
||||||
@@ -379,7 +380,7 @@ describe('ActivitiForm', () => {
|
|||||||
it('should do nothing when clicking outcome for readonly form', () => {
|
it('should do nothing when clicking outcome for readonly form', () => {
|
||||||
let formModel = new FormModel();
|
let formModel = new FormModel();
|
||||||
const outcomeName = 'Custom Action';
|
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;
|
formComponent.form = formModel;
|
||||||
spyOn(formComponent, 'completeTaskForm').and.stub();
|
spyOn(formComponent, 'completeTaskForm').and.stub();
|
||||||
@@ -398,7 +399,7 @@ describe('ActivitiForm', () => {
|
|||||||
it('should require loaded form when clicking outcome', () => {
|
it('should require loaded form when clicking outcome', () => {
|
||||||
let formModel = new FormModel();
|
let formModel = new FormModel();
|
||||||
const outcomeName = 'Custom Action';
|
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.readOnly = false;
|
||||||
formComponent.form = null;
|
formComponent.form = null;
|
||||||
@@ -407,7 +408,7 @@ describe('ActivitiForm', () => {
|
|||||||
|
|
||||||
it('should not execute unknown system outcome', () => {
|
it('should not execute unknown system outcome', () => {
|
||||||
let formModel = new FormModel();
|
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;
|
formComponent.form = formModel;
|
||||||
expect(formComponent.onOutcomeClicked(outcome)).toBeFalsy();
|
expect(formComponent.onOutcomeClicked(outcome)).toBeFalsy();
|
||||||
@@ -415,12 +416,12 @@ describe('ActivitiForm', () => {
|
|||||||
|
|
||||||
it('should require custom action name to complete form', () => {
|
it('should require custom action name to complete form', () => {
|
||||||
let formModel = new FormModel();
|
let formModel = new FormModel();
|
||||||
let outcome = new FormOutcomeModel(formModel, {id: 'custom'});
|
let outcome = new FormOutcomeModel(formModel, { id: 'custom' });
|
||||||
|
|
||||||
formComponent.form = formModel;
|
formComponent.form = formModel;
|
||||||
expect(formComponent.onOutcomeClicked(outcome)).toBeFalsy();
|
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();
|
spyOn(formComponent, 'completeTaskForm').and.stub();
|
||||||
expect(formComponent.onOutcomeClicked(outcome)).toBeTruthy();
|
expect(formComponent.onOutcomeClicked(outcome)).toBeTruthy();
|
||||||
});
|
});
|
||||||
@@ -429,7 +430,7 @@ describe('ActivitiForm', () => {
|
|||||||
spyOn(formService, 'getTask').and.returnValue(Observable.of({}));
|
spyOn(formService, 'getTask').and.returnValue(Observable.of({}));
|
||||||
spyOn(formService, 'getTaskForm').and.callFake((taskId) => {
|
spyOn(formService, 'getTaskForm').and.callFake((taskId) => {
|
||||||
return Observable.create(observer => {
|
return Observable.create(observer => {
|
||||||
observer.next({taskId: taskId});
|
observer.next({ taskId: taskId });
|
||||||
observer.complete();
|
observer.complete();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -465,7 +466,7 @@ describe('ActivitiForm', () => {
|
|||||||
spyOn(formService, 'getTask').and.returnValue(Observable.of({}));
|
spyOn(formService, 'getTask').and.returnValue(Observable.of({}));
|
||||||
spyOn(formService, 'getTaskForm').and.callFake((taskId) => {
|
spyOn(formService, 'getTaskForm').and.callFake((taskId) => {
|
||||||
return Observable.create(observer => {
|
return Observable.create(observer => {
|
||||||
observer.next({taskId: taskId});
|
observer.next({ taskId: taskId });
|
||||||
observer.complete();
|
observer.complete();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -481,7 +482,7 @@ describe('ActivitiForm', () => {
|
|||||||
it('should fetch and parse form definition by id', () => {
|
it('should fetch and parse form definition by id', () => {
|
||||||
spyOn(formService, 'getFormDefinitionById').and.callFake((formId) => {
|
spyOn(formService, 'getFormDefinitionById').and.callFake((formId) => {
|
||||||
return Observable.create(observer => {
|
return Observable.create(observer => {
|
||||||
observer.next({id: formId});
|
observer.next({ id: formId });
|
||||||
observer.complete();
|
observer.complete();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -520,7 +521,7 @@ describe('ActivitiForm', () => {
|
|||||||
|
|
||||||
spyOn(formService, 'getFormDefinitionById').and.callFake((formName) => {
|
spyOn(formService, 'getFormDefinitionById').and.callFake((formName) => {
|
||||||
return Observable.create(observer => {
|
return Observable.create(observer => {
|
||||||
observer.next({name: formName});
|
observer.next({ name: formName });
|
||||||
observer.complete();
|
observer.complete();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -556,8 +557,8 @@ describe('ActivitiForm', () => {
|
|||||||
let formModel = new FormModel({
|
let formModel = new FormModel({
|
||||||
taskId: '123',
|
taskId: '123',
|
||||||
fields: [
|
fields: [
|
||||||
{id: 'field1'},
|
{ id: 'field1' },
|
||||||
{id: 'field2'}
|
{ id: 'field2' }
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
formComponent.form = formModel;
|
formComponent.form = formModel;
|
||||||
@@ -573,7 +574,7 @@ describe('ActivitiForm', () => {
|
|||||||
spyOn(formService, 'saveTaskForm').and.callFake(() => Observable.throw(error));
|
spyOn(formService, 'saveTaskForm').and.callFake(() => Observable.throw(error));
|
||||||
spyOn(formComponent, 'handleError').and.stub();
|
spyOn(formComponent, 'handleError').and.stub();
|
||||||
|
|
||||||
formComponent.form = new FormModel({taskId: '123'});
|
formComponent.form = new FormModel({ taskId: '123' });
|
||||||
formComponent.saveTaskForm();
|
formComponent.saveTaskForm();
|
||||||
|
|
||||||
expect(formComponent.handleError).toHaveBeenCalledWith(error);
|
expect(formComponent.handleError).toHaveBeenCalledWith(error);
|
||||||
@@ -618,8 +619,8 @@ describe('ActivitiForm', () => {
|
|||||||
let formModel = new FormModel({
|
let formModel = new FormModel({
|
||||||
taskId: '123',
|
taskId: '123',
|
||||||
fields: [
|
fields: [
|
||||||
{id: 'field1'},
|
{ id: 'field1' },
|
||||||
{id: 'field2'}
|
{ id: 'field2' }
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -638,7 +639,7 @@ describe('ActivitiForm', () => {
|
|||||||
let form = formComponent.parseForm({
|
let form = formComponent.parseForm({
|
||||||
id: '<id>',
|
id: '<id>',
|
||||||
fields: [
|
fields: [
|
||||||
{id: 'field1', type: FormFieldTypes.CONTAINER}
|
{ id: 'field1', type: FormFieldTypes.CONTAINER }
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -651,7 +652,7 @@ describe('ActivitiForm', () => {
|
|||||||
it('should provide outcomes for form definition', () => {
|
it('should provide outcomes for form definition', () => {
|
||||||
spyOn(formComponent, 'getFormDefinitionOutcomes').and.callThrough();
|
spyOn(formComponent, 'getFormDefinitionOutcomes').and.callThrough();
|
||||||
|
|
||||||
let form = formComponent.parseForm({id: '<id>'});
|
let form = formComponent.parseForm({ id: '<id>' });
|
||||||
expect(formComponent.getFormDefinitionOutcomes).toHaveBeenCalledWith(form);
|
expect(formComponent.getFormDefinitionOutcomes).toHaveBeenCalledWith(form);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -724,7 +725,7 @@ describe('ActivitiForm', () => {
|
|||||||
let metadata = {};
|
let metadata = {};
|
||||||
spyOn(nodeService, 'getNodeMetadata').and.returnValue(
|
spyOn(nodeService, 'getNodeMetadata').and.returnValue(
|
||||||
Observable.create(observer => {
|
Observable.create(observer => {
|
||||||
observer.next({metadata: metadata});
|
observer.next({ metadata: metadata });
|
||||||
observer.complete();
|
observer.complete();
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -814,4 +815,30 @@ describe('ActivitiForm', () => {
|
|||||||
formComponent.onOutcomeClicked(outcome);
|
formComponent.onOutcomeClicked(outcome);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should refresh form values when data is changed', () => {
|
||||||
|
formComponent.form = new FormModel(fakeForm);
|
||||||
|
let formFields = formComponent.form.getFormFields();
|
||||||
|
|
||||||
|
let labelField = formFields.find(field => field.id === 'label');
|
||||||
|
let radioField = formFields.find(field => field.id === 'raduio');
|
||||||
|
expect(labelField.value).toBe('empty');
|
||||||
|
expect(radioField.value).toBeNull();
|
||||||
|
|
||||||
|
let formValues: any = {};
|
||||||
|
formValues.label = {
|
||||||
|
id: 'option_1',
|
||||||
|
name: 'test1'
|
||||||
|
};
|
||||||
|
formValues.raduio = { id: 'option_1', name: 'Option 1' };
|
||||||
|
let change = new SimpleChange(null, formValues, false);
|
||||||
|
formComponent.data = formValues;
|
||||||
|
formComponent.ngOnChanges({ 'data': change });
|
||||||
|
|
||||||
|
formFields = formComponent.form.getFormFields();
|
||||||
|
labelField = formFields.find(field => field.id === 'label');
|
||||||
|
radioField = formFields.find(field => field.id === 'raduio');
|
||||||
|
expect(labelField.value).toBe('option_1');
|
||||||
|
expect(radioField.value).toBe('option_1');
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@@ -100,6 +100,9 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges {
|
|||||||
@Output()
|
@Output()
|
||||||
formLoaded: EventEmitter<FormModel> = new EventEmitter<FormModel>();
|
formLoaded: EventEmitter<FormModel> = new EventEmitter<FormModel>();
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
formDataRefreshed: EventEmitter<FormModel> = new EventEmitter<FormModel>();
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
executeOutcome: EventEmitter<FormOutcomeEvent> = new EventEmitter<FormOutcomeEvent>();
|
executeOutcome: EventEmitter<FormOutcomeEvent> = new EventEmitter<FormOutcomeEvent>();
|
||||||
|
|
||||||
@@ -202,6 +205,12 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges {
|
|||||||
this.loadFormForEcmNode();
|
this.loadFormForEcmNode();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let data = changes['data'];
|
||||||
|
if (data && data.currentValue) {
|
||||||
|
this.refreshFormData();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -424,6 +433,12 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private refreshFormData() {
|
||||||
|
this.form = new FormModel(this.form.json, this.data, this.readOnly, this.formService);
|
||||||
|
this.onFormLoaded(this.form);
|
||||||
|
this.onFormDataRefreshed(this.form);
|
||||||
|
}
|
||||||
|
|
||||||
private loadFormForEcmNode(): void {
|
private loadFormForEcmNode(): void {
|
||||||
this.nodeService.getNodeMetadata(this.nodeId).subscribe(data => {
|
this.nodeService.getNodeMetadata(this.nodeId).subscribe(data => {
|
||||||
this.data = data.metadata;
|
this.data = data.metadata;
|
||||||
@@ -471,6 +486,11 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges {
|
|||||||
this.formService.formLoaded.next(new FormEvent(form));
|
this.formService.formLoaded.next(new FormEvent(form));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected onFormDataRefreshed(form: FormModel) {
|
||||||
|
this.formDataRefreshed.emit(form);
|
||||||
|
this.formService.formDataRefreshed.next(new FormEvent(form));
|
||||||
|
}
|
||||||
|
|
||||||
protected onTaskSaved(form: FormModel) {
|
protected onTaskSaved(form: FormModel) {
|
||||||
this.formSaved.emit(form);
|
this.formSaved.emit(form);
|
||||||
this.formService.taskSaved.next(new FormEvent(form));
|
this.formService.taskSaved.next(new FormEvent(form));
|
||||||
|
@@ -109,7 +109,7 @@ export class FormModel {
|
|||||||
}
|
}
|
||||||
if (json.fields) {
|
if (json.fields) {
|
||||||
let saveOutcome = new FormOutcomeModel(this, { id: FormModel.SAVE_OUTCOME, name: 'Save', isSystem: true });
|
let saveOutcome = new FormOutcomeModel(this, { id: FormModel.SAVE_OUTCOME, name: 'Save', isSystem: true });
|
||||||
let completeOutcome = new FormOutcomeModel(this, {id: FormModel.COMPLETE_OUTCOME, name: 'Complete', isSystem: true });
|
let completeOutcome = new FormOutcomeModel(this, { id: FormModel.COMPLETE_OUTCOME, name: 'Complete', isSystem: true });
|
||||||
let startProcessOutcome = new FormOutcomeModel(this, { id: FormModel.START_PROCESS_OUTCOME, name: 'Start Process', isSystem: true });
|
let startProcessOutcome = new FormOutcomeModel(this, { id: FormModel.START_PROCESS_OUTCOME, name: 'Start Process', isSystem: true });
|
||||||
|
|
||||||
let customOutcomes = (json.outcomes || []).map(obj => new FormOutcomeModel(this, obj));
|
let customOutcomes = (json.outcomes || []).map(obj => new FormOutcomeModel(this, obj));
|
||||||
@@ -137,7 +137,7 @@ export class FormModel {
|
|||||||
let field = this.fields[i];
|
let field = this.fields[i];
|
||||||
|
|
||||||
if (field instanceof ContainerModel) {
|
if (field instanceof ContainerModel) {
|
||||||
let container = <ContainerModel> field;
|
let container = <ContainerModel>field;
|
||||||
result.push(container.field);
|
result.push(container.field);
|
||||||
result.push(...container.field.fields);
|
result.push(...container.field.fields);
|
||||||
}
|
}
|
||||||
@@ -203,7 +203,11 @@ export class FormModel {
|
|||||||
for (let field of this.getFormFields()) {
|
for (let field of this.getFormFields()) {
|
||||||
if (data[field.id]) {
|
if (data[field.id]) {
|
||||||
field.json.value = data[field.id];
|
field.json.value = data[field.id];
|
||||||
field.value = data[field.id];
|
field.value = field.parseValue(field.json);
|
||||||
|
if (field.type === FormFieldTypes.DROPDOWN ||
|
||||||
|
field.type === FormFieldTypes.RADIO_BUTTONS) {
|
||||||
|
field.value = data[field.id].id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -33,6 +33,7 @@ export class FormService {
|
|||||||
static GENERIC_ERROR_MESSAGE: string = 'Server error';
|
static GENERIC_ERROR_MESSAGE: string = 'Server error';
|
||||||
|
|
||||||
formLoaded: Subject<FormEvent> = new Subject<FormEvent>();
|
formLoaded: Subject<FormEvent> = new Subject<FormEvent>();
|
||||||
|
formDataRefreshed: Subject<FormEvent> = new Subject<FormEvent>();
|
||||||
formFieldValueChanged: Subject<FormFieldEvent> = new Subject<FormFieldEvent>();
|
formFieldValueChanged: Subject<FormFieldEvent> = new Subject<FormFieldEvent>();
|
||||||
formEvents: Subject<Event> = new Subject<Event>();
|
formEvents: Subject<Event> = new Subject<Event>();
|
||||||
taskCompleted: Subject<FormEvent> = new Subject<FormEvent>();
|
taskCompleted: Subject<FormEvent> = new Subject<FormEvent>();
|
||||||
|
Reference in New Issue
Block a user