diff --git a/demo-shell/src/app/components/app-layout/cloud/form-demo/cloud-form-demo.component.ts b/demo-shell/src/app/components/app-layout/cloud/form-demo/cloud-form-demo.component.ts index d9a1c0b778..d875699933 100644 --- a/demo-shell/src/app/components/app-layout/cloud/form-demo/cloud-form-demo.component.ts +++ b/demo-shell/src/app/components/app-layout/cloud/form-demo/cloud-form-demo.component.ts @@ -54,8 +54,7 @@ export class FormCloudDemoComponent implements OnInit, OnDestroy { } ngOnInit() { - const formDefinitionJSON = this.automationService.forms.getFormCloudDefinition(); - this.formConfig = JSON.stringify(formDefinitionJSON); + this.formConfig = JSON.stringify(this.automationService.forms.getFormCloudDefinition()); this.parseForm(); } diff --git a/demo-shell/src/app/components/form/form.component.ts b/demo-shell/src/app/components/form/form.component.ts index e8a459aedc..33ba5fec89 100644 --- a/demo-shell/src/app/components/form/form.component.ts +++ b/demo-shell/src/app/components/form/form.component.ts @@ -62,8 +62,7 @@ export class FormComponent implements OnInit, OnDestroy { } ngOnInit() { - const formDefinitionJSON: any = this.automationService.forms.getFormDefinition(); - this.formConfig = JSON.stringify(formDefinitionJSON); + this.formConfig = JSON.stringify(this.automationService.forms.getFormDefinition()); this.parseForm(); } diff --git a/lib/core/form/components/form-base.model.ts b/lib/core/form/components/form-base.model.ts index 73731d988d..aefe3ee232 100644 --- a/lib/core/form/components/form-base.model.ts +++ b/lib/core/form/components/form-base.model.ts @@ -30,7 +30,6 @@ export abstract class FormBaseModel { static START_PROCESS_OUTCOME: string = '$startProcess'; json: any; - isValid: boolean; values: FormValues = {}; tabs: TabModel[] = []; @@ -41,6 +40,8 @@ export abstract class FormBaseModel { readOnly: boolean = false; taskName; + isValid: boolean = true; + hasTabs(): boolean { return this.tabs && this.tabs.length > 0; } @@ -77,8 +78,11 @@ export abstract class FormBaseModel { return formFieldModel; } + markAsInvalid() { + this.isValid = false; + } + abstract validateForm(); abstract validateField(field: FormFieldModel); abstract onFormFieldChanged(field: FormFieldModel); - abstract markAsInvalid(); } diff --git a/lib/core/form/components/widgets/core/form-field.model.ts b/lib/core/form/components/widgets/core/form-field.model.ts index 9ade572e7a..11020cbd71 100644 --- a/lib/core/form/components/widgets/core/form-field.model.ts +++ b/lib/core/form/components/widgets/core/form-field.model.ts @@ -68,7 +68,7 @@ export class FormFieldModel extends FormWidgetModel { visibilityCondition: WidgetVisibilityModel = null; enableFractions: boolean = false; currency: string = null; - dateDisplayFormat: string = this.dateDisplayFormat || this.defaultDateFormat; + dateDisplayFormat: string = this.defaultDateFormat; // container model members numberOfColumns: number = 1; diff --git a/lib/core/form/components/widgets/core/form.model.spec.ts b/lib/core/form/components/widgets/core/form.model.spec.ts index 5ada0ac272..5e099e09ad 100644 --- a/lib/core/form/components/widgets/core/form.model.spec.ts +++ b/lib/core/form/components/widgets/core/form.model.spec.ts @@ -35,7 +35,10 @@ describe('FormModel', () => { }); it('should store original json', () => { - const json = {}; + const json = { + id: '', + name: '' + }; const form = new FormModel(json); expect(form.json).toBe(json); }); diff --git a/lib/core/form/components/widgets/core/form.model.ts b/lib/core/form/components/widgets/core/form.model.ts index b2bd10ac23..9cec695ac3 100644 --- a/lib/core/form/components/widgets/core/form.model.ts +++ b/lib/core/form/components/widgets/core/form.model.ts @@ -43,11 +43,6 @@ export class FormModel extends FormBaseModel { readonly taskId: string; readonly taskName: string = FormModel.UNSET_TASK_NAME; processDefinitionId: string; - private _isValid: boolean = true; - - get isValid(): boolean { - return this._isValid; - } customFieldTemplates: FormFieldTemplates = {}; fieldValidators: FormFieldValidator[] = [...FORM_FIELD_VALIDATORS]; @@ -55,33 +50,33 @@ export class FormModel extends FormBaseModel { processVariables: any; - constructor(json?: any, formValues?: FormValues, readOnly: boolean = false, protected formService?: FormService) { + constructor(formRepresentationJSON?: any, formValues?: FormValues, readOnly: boolean = false, protected formService?: FormService) { super(); this.readOnly = readOnly; - if (json) { - this.json = json; + if (formRepresentationJSON) { + this.json = formRepresentationJSON; - this.id = json.id; - this.name = json.name; - this.taskId = json.taskId; - this.taskName = json.taskName || json.name || FormModel.UNSET_TASK_NAME; - this.processDefinitionId = json.processDefinitionId; - this.customFieldTemplates = json.customFieldTemplates || {}; - this.selectedOutcome = json.selectedOutcome || {}; - this.className = json.className || ''; + this.id = formRepresentationJSON.id; + this.name = formRepresentationJSON.name; + this.taskId = formRepresentationJSON.taskId; + this.taskName = formRepresentationJSON.taskName || formRepresentationJSON.name || FormModel.UNSET_TASK_NAME; + this.processDefinitionId = formRepresentationJSON.processDefinitionId; + this.customFieldTemplates = formRepresentationJSON.customFieldTemplates || {}; + this.selectedOutcome = formRepresentationJSON.selectedOutcome || {}; + this.className = formRepresentationJSON.className || ''; const tabCache: FormWidgetModelCache = {}; - this.processVariables = json.processVariables; + this.processVariables = formRepresentationJSON.processVariables; - this.tabs = (json.tabs || []).map((t) => { + this.tabs = (formRepresentationJSON.tabs || []).map((t) => { const model = new TabModel(this, t); tabCache[model.id] = model; return model; }); - this.fields = this.parseRootFields(json); + this.fields = this.parseRootFields(formRepresentationJSON); if (formValues) { this.loadData(formValues); @@ -97,7 +92,7 @@ export class FormModel extends FormBaseModel { } } - if (json.fields) { + if (formRepresentationJSON.fields) { const saveOutcome = new FormOutcomeModel(this, { id: FormModel.SAVE_OUTCOME, name: 'SAVE', @@ -114,7 +109,7 @@ export class FormModel extends FormBaseModel { isSystem: true }); - const customOutcomes = (json.outcomes || []).map((obj) => new FormOutcomeModel(this, obj)); + const customOutcomes = (formRepresentationJSON.outcomes || []).map((obj) => new FormOutcomeModel(this, obj)); this.outcomes = [saveOutcome].concat( customOutcomes.length > 0 ? customOutcomes : [completeOutcome, startProcessOutcome] @@ -132,10 +127,6 @@ export class FormModel extends FormBaseModel { } } - markAsInvalid() { - this._isValid = false; - } - /** * Validates entire form and all form fields. * @@ -153,10 +144,10 @@ export class FormModel extends FormBaseModel { } } - this._isValid = errorsField.length > 0 ? false : true; + this.isValid = errorsField.length > 0 ? false : true; if (this.formService) { - validateFormEvent.isValid = this._isValid; + validateFormEvent.isValid = this.isValid; validateFormEvent.errorsField = errorsField; this.formService.validateForm.next(validateFormEvent); } @@ -181,7 +172,7 @@ export class FormModel extends FormBaseModel { } if (!validateFieldEvent.isValid) { - this._isValid = false; + this.markAsInvalid(); return; } @@ -190,7 +181,7 @@ export class FormModel extends FormBaseModel { } if (!field.validate()) { - this._isValid = false; + this.markAsInvalid(); } this.validateForm(); diff --git a/lib/core/form/public-api.ts b/lib/core/form/public-api.ts index c977566a48..f7052e2255 100644 --- a/lib/core/form/public-api.ts +++ b/lib/core/form/public-api.ts @@ -16,6 +16,7 @@ */ export * from './components/form-base.component'; +export * from './components/form-base.model'; export * from './components/form-list.component'; export * from './components/widgets/content/content.widget'; export * from './components/form-renderer.component'; diff --git a/lib/core/form/services/widget-visibility.service.ts b/lib/core/form/services/widget-visibility.service.ts index 48773eb8f2..e2bd2d29bb 100644 --- a/lib/core/form/services/widget-visibility.service.ts +++ b/lib/core/form/services/widget-visibility.service.ts @@ -215,14 +215,7 @@ export class WidgetVisibilityService { } private getFormVariables(form: FormModel): any[] { - let variables; - if (form.json.formRepresentation) { - variables = form.json.formRepresentation.formDefinition.variables; - } else { - variables = form.json.variables; - } - - return variables; + return form.json.variables; } private getProcessVariableValue(name: string, processVarList: TaskProcessVariableModel[]): string { diff --git a/lib/core/mock/form/demo-form.mock.ts b/lib/core/mock/form/demo-form.mock.ts index e5ec2ae579..573428587b 100644 --- a/lib/core/mock/form/demo-form.mock.ts +++ b/lib/core/mock/form/demo-form.mock.ts @@ -32,7 +32,7 @@ * limitations under the License. */ -export class DemoForms { +export class DemoForm { easyForm = { 'id': 1001, diff --git a/lib/core/services/automation.service.ts b/lib/core/services/automation.service.ts index ca9b51ccdb..09ca039828 100644 --- a/lib/core/services/automation.service.ts +++ b/lib/core/services/automation.service.ts @@ -20,13 +20,14 @@ import { AppConfigService } from '../app-config/app-config.service'; import { AlfrescoApiService } from '../services/alfresco-api.service'; import { StorageService } from './storage.service'; import { UserPreferencesService } from './user-preferences.service'; -import { DemoForms } from '../mock/form/demo-form.mock'; +import { DemoForm } from '../mock/form/demo-form.mock'; @Injectable({ providedIn: 'root' }) export class CoreAutomationService { - forms = new DemoForms(); + + public forms = new DemoForm(); constructor(private appConfigService: AppConfigService, private alfrescoApiService: AlfrescoApiService, diff --git a/lib/process-services-cloud/src/lib/form/components/form-cloud.component.spec.ts b/lib/process-services-cloud/src/lib/form/components/form-cloud.component.spec.ts index 34b7437c27..7143d41a35 100644 --- a/lib/process-services-cloud/src/lib/form/components/form-cloud.component.spec.ts +++ b/lib/process-services-cloud/src/lib/form/components/form-cloud.component.spec.ts @@ -19,13 +19,16 @@ import { SimpleChange, DebugElement, CUSTOM_ELEMENTS_SCHEMA, Component } from '@ import { By } from '@angular/platform-browser'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { Observable, of, throwError } from 'rxjs'; -import { FormFieldModel, FormFieldTypes, FormService, FormOutcomeEvent, FormOutcomeModel, LogService, WidgetVisibilityService, - setupTestBed, AppConfigService, FormRenderingService } from '@alfresco/adf-core'; +import { + FormFieldModel, FormFieldTypes, FormService, FormOutcomeEvent, FormOutcomeModel, LogService, WidgetVisibilityService, + setupTestBed, AppConfigService, FormRenderingService +} from '@alfresco/adf-core'; import { ProcessServiceCloudTestingModule } from '../../testing/process-service-cloud.testing.module'; import { FormCloudService } from '../services/form-cloud.service'; import { FormCloudComponent } from './form-cloud.component'; import { FormCloud } from '../models/form-cloud.model'; import { cloudFormMock } from '../mocks/cloud-form.mock'; +import { FormCloudRepresentation } from '../models/form-cloud-representation.model'; describe('FormCloudComponent', () => { @@ -120,7 +123,7 @@ describe('FormCloudComponent', () => { }); it('should show [custom-outcome] button with readOnly form and selected custom-outcome', () => { - const formModel = new FormCloud({formRepresentation: {formDefinition: {selectedOutcome: 'custom-outcome'}}}); + const formModel = new FormCloud({ selectedOutcome: 'custom-outcome' }); formModel.readOnly = true; formComponent.form = formModel; let outcome = new FormOutcomeModel( formModel, { id: '$customoutome', name: 'custom-outcome' }); @@ -156,7 +159,7 @@ describe('FormCloudComponent', () => { it('should get task variables if a task form is rendered', () => { spyOn(formCloudService, 'getTaskForm').and.callFake((currentTaskId) => { return new Observable((observer) => { - observer.next({ formRepresentation: { taskId: currentTaskId }}); + observer.next({ formRepresentation: { taskId: currentTaskId } }); observer.complete(); }); }); @@ -164,7 +167,7 @@ describe('FormCloudComponent', () => { spyOn(formCloudService, 'getTaskVariables').and.returnValue(of({})); spyOn(formCloudService, 'getTask').and.callFake((currentTaskId) => { return new Observable((observer) => { - observer.next({ formRepresentation: { taskId: currentTaskId }}); + observer.next({ formRepresentation: { taskId: currentTaskId } }); observer.complete(); }); }); @@ -210,7 +213,7 @@ describe('FormCloudComponent', () => { }); it('should refresh visibility when the form is loaded', () => { - spyOn(formCloudService, 'getForm').and.returnValue(of({formRepresentation: {formDefinition: {}}})); + spyOn(formCloudService, 'getForm').and.returnValue(of({ formRepresentation: {} })); const formId = '123'; const appName = 'test-app'; @@ -388,7 +391,7 @@ describe('FormCloudComponent', () => { spyOn(formCloudService, 'getTask').and.returnValue(of({})); spyOn(formCloudService, 'getTaskVariables').and.returnValue(of({})); - spyOn(formCloudService, 'getTaskForm').and.returnValue(of({formRepresentation: {taskId: taskId, formDefinition: {selectedOutcome: 'custom-outcome'}}})); + spyOn(formCloudService, 'getTaskForm').and.returnValue(of({ taskId: taskId, selectedOutcome: 'custom-outcome' })); formComponent.formLoaded.subscribe(() => { expect(formCloudService.getTaskForm).toHaveBeenCalledWith(appName, taskId); @@ -421,7 +424,7 @@ describe('FormCloudComponent', () => { it('should fetch and parse form definition by id', (done) => { spyOn(formCloudService, 'getForm').and.callFake((currentAppName, currentFormId) => { return new Observable((observer) => { - observer.next({ formRepresentation: {id: currentFormId, formDefinition: {}}}); + observer.next({ id: currentFormId }); observer.complete(); }); }); @@ -469,16 +472,12 @@ describe('FormCloudComponent', () => { const processInstanceId = '333-444'; const formModel = new FormCloud({ - formRepresentation: { - id: '23', - taskId: taskId, - formDefinition: { - fields: [ - { id: 'field1' }, - { id: 'field2' } - ] - } - } + id: '23', + taskId: taskId, + fields: [ + { id: 'field1' }, + { id: 'field2' } + ] }); formComponent.form = formModel; formComponent.taskId = taskId; @@ -500,16 +499,12 @@ describe('FormCloudComponent', () => { const taskId = '123-223'; const appName = 'test-app'; const formModel = new FormCloud({ - formRepresentation: { - id: '23', - taskId: taskId, - formDefinition: { - fields: [ - { id: 'field1' }, - { id: 'field2' } - ] - } - } + id: '23', + taskId: taskId, + fields: [ + { id: 'field1' }, + { id: 'field2' } + ] }); formComponent.form = formModel; formComponent.taskId = taskId; @@ -572,16 +567,12 @@ describe('FormCloudComponent', () => { const processInstanceId = '333-444'; const formModel = new FormCloud({ - formRepresentation: { - id: '23', - taskId: taskId, - formDefinition: { - fields: [ - { id: 'field1' }, - { id: 'field2' } - ] - } - } + id: '23', + taskId: taskId, + fields: [ + { id: 'field1' }, + { id: 'field2' } + ] }); formComponent.form = formModel; @@ -600,14 +591,10 @@ describe('FormCloudComponent', () => { it('should parse form from json', () => { const form = formComponent.parseForm({ - formRepresentation: { - id: '1', - formDefinition: { - fields: [ - { id: 'field1', type: FormFieldTypes.CONTAINER } - ] - } - } + id: '1', + fields: [ + { id: 'field1', type: FormFieldTypes.CONTAINER } + ] }); expect(form).toBeDefined(); @@ -619,7 +606,7 @@ describe('FormCloudComponent', () => { it('should provide outcomes for form definition', () => { spyOn(formComponent, 'getFormDefinitionOutcomes').and.callThrough(); - const form = formComponent.parseForm({ formRepresentation: { id: 1, formDefinition: {}}}); + const form = formComponent.parseForm({ id: '1' }); expect(formComponent.getFormDefinitionOutcomes).toHaveBeenCalledWith(form); }); @@ -754,6 +741,7 @@ describe('FormCloudComponent', () => { it('should refresh form values when data is changed', (done) => { formComponent.form = new FormCloud(JSON.parse(JSON.stringify(cloudFormMock))); + formComponent.formCloudRepresentationJSON = new FormCloudRepresentation(JSON.parse(JSON.stringify(cloudFormMock))); let formFields = formComponent.form.getFormFields(); let labelField = formFields.find((field) => field.id === 'text1'); @@ -761,12 +749,12 @@ describe('FormCloudComponent', () => { expect(labelField.value).toBeNull(); expect(radioField.value).toBeUndefined(); - const formValues: any[] = [{name: 'text1', value: 'test'}, {name: 'number1', value: 99}]; + const formValues: any[] = [{ name: 'text1', value: 'test' }, { name: 'number1', value: 99 }]; const change = new SimpleChange(null, formValues, false); formComponent.data = formValues; - formComponent.formLoaded.subscribe( (form) => { + formComponent.formLoaded.subscribe((form) => { formFields = form.getFormFields(); labelField = formFields.find((field) => field.id === 'text1'); radioField = formFields.find((field) => field.id === 'number1'); @@ -782,10 +770,11 @@ describe('FormCloudComponent', () => { it('should refresh radio buttons value when id is given to data', () => { formComponent.form = new FormCloud(JSON.parse(JSON.stringify(cloudFormMock))); + formComponent.formCloudRepresentationJSON = new FormCloudRepresentation(JSON.parse(JSON.stringify(cloudFormMock))); let formFields = formComponent.form.getFormFields(); let radioFieldById = formFields.find((field) => field.id === 'radiobuttons1'); - const formValues: any[] = [{name: 'radiobuttons1', value: 'option_2'}]; + const formValues: any[] = [{ name: 'radiobuttons1', value: 'option_2' }]; const change = new SimpleChange(null, formValues, false); formComponent.data = formValues; formComponent.ngOnChanges({ 'data': change }); @@ -797,7 +786,7 @@ describe('FormCloudComponent', () => { }); @Component({ - selector: 'adf-form-cloud-with-custom-outcomes', + selector: 'adf-cloud-form-with-custom-outcomes', template: ` @@ -813,7 +802,7 @@ describe('FormCloudComponent', () => { class FormCloudWithCustomOutComesComponent { - onButtonClick() {} + onButtonClick() { } } describe('FormCloudWithCustomOutComesComponent', () => { diff --git a/lib/process-services-cloud/src/lib/form/components/form-cloud.component.ts b/lib/process-services-cloud/src/lib/form/components/form-cloud.component.ts index 4a164cddeb..febbbea62c 100644 --- a/lib/process-services-cloud/src/lib/form/components/form-cloud.component.ts +++ b/lib/process-services-cloud/src/lib/form/components/form-cloud.component.ts @@ -92,6 +92,7 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges, protected subscriptions: Subscription[] = []; nodeId: string; + formCloudRepresentationJSON: any; protected onDestroy$ = new Subject(); @@ -181,7 +182,8 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges, .subscribe( (data) => { this.data = data[1]; - const parsedForm = this.parseForm(data[0]); + this.formCloudRepresentationJSON = data[0]; + const parsedForm = this.parseForm(this.formCloudRepresentationJSON); this.visibilityService.refreshVisibility( parsedForm); parsedForm.validateForm(); this.form = parsedForm; @@ -268,10 +270,10 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges, } } - parseForm(json: any): FormCloud { - if (json) { - const form = new FormCloud(json, this.data, this.readOnly, this.formCloudService); - if (!json.formRepresentation.formDefinition || !json.formRepresentation.formDefinition.fields) { + parseForm(formCloudRepresentationJSON: any): FormCloud { + if (formCloudRepresentationJSON) { + const form = new FormCloud(formCloudRepresentationJSON, this.data, this.readOnly, this.formCloudService); + if (!form || !form.fields.length) { form.outcomes = this.getFormDefinitionOutcomes(form); } if (this.fieldValidators && this.fieldValidators.length > 0) { @@ -299,7 +301,7 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges, } private refreshFormData() { - this.form = this.parseForm(this.form.json); + this.form = this.parseForm(this.formCloudRepresentationJSON); this.onFormLoaded(this.form); this.onFormDataRefreshed(this.form); } diff --git a/lib/process-services-cloud/src/lib/form/mocks/cloud-form.mock.ts b/lib/process-services-cloud/src/lib/form/mocks/cloud-form.mock.ts index 988c7954f4..ca50cf819b 100644 --- a/lib/process-services-cloud/src/lib/form/mocks/cloud-form.mock.ts +++ b/lib/process-services-cloud/src/lib/form/mocks/cloud-form.mock.ts @@ -16,671 +16,662 @@ */ export const cloudFormMock = { - 'formRepresentation': { - 'id': 'form-b661635a-dc3e-4557-914a-3498ed47189c', - 'name': 'form-with-all-fields', - 'description': '', - 'version': 0, - 'formDefinition': { - 'tabs': [], - 'fields': [ - { - 'fieldType': 'ContainerRepresentation', - 'id': '26b10e64-0403-4686-a75b-0d45279ce3a8', - 'name': 'Label', - 'type': 'container', - 'tab': null, - 'numberOfColumns': 2, - 'fields': { - '1': [ + 'id': 'form-b661635a-dc3e-4557-914a-3498ed47189c', + 'name': 'form-with-all-fields', + 'description': '', + 'version': 0, + 'tabs': [], + 'fields': [ + { + 'fieldType': 'ContainerRepresentation', + 'id': '26b10e64-0403-4686-a75b-0d45279ce3a8', + 'name': 'Label', + 'type': 'container', + 'tab': null, + 'numberOfColumns': 2, + 'fields': { + '1': [ + { + 'fieldType': 'FormFieldRepresentation', + 'id': 'text1', + 'name': 'Text1', + 'type': 'text', + 'value': null, + 'required': false, + 'readOnly': true, + 'overrideId': false, + 'colspan': 1, + 'placeholder': null, + 'minLength': 0, + 'maxLength': 0, + 'minValue': null, + 'maxValue': null, + 'regexPattern': null, + 'visibilityCondition': null, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2 + } + } + ], + '2': [ + { + 'fieldType': 'FormFieldRepresentation', + 'id': 'text2', + 'name': 'Text2', + 'type': 'text', + 'value': null, + 'required': false, + 'readOnly': true, + 'overrideId': false, + 'colspan': 1, + 'placeholder': null, + 'minLength': 0, + 'maxLength': 0, + 'minValue': null, + 'maxValue': null, + 'regexPattern': null, + 'visibilityCondition': null, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2 + } + } + ] + } + }, + { + 'fieldType': 'ContainerRepresentation', + 'id': '69c1390a-8d8d-423c-8efb-8e43401efa42', + 'name': 'Label', + 'type': 'container', + 'tab': null, + 'numberOfColumns': 2, + 'fields': { + '1': [ + { + 'fieldType': 'FormFieldRepresentation', + 'id': 'multilinetext1', + 'name': 'Multiline text1', + 'type': 'multi-line-text', + 'overrideId': false, + 'colspan': 1, + 'placeholder': null, + 'minLength': 0, + 'maxLength': 0, + 'regexPattern': null, + 'required': false, + 'readOnly': true, + 'visibilityCondition': null, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2 + } + } + ], + '2': [ + { + 'fieldType': 'FormFieldRepresentation', + 'id': 'multilinetext2', + 'name': 'Multiline text2', + 'type': 'multi-line-text', + 'overrideId': false, + 'colspan': 1, + 'placeholder': null, + 'minLength': 0, + 'maxLength': 0, + 'regexPattern': null, + 'required': false, + 'readOnly': true, + 'visibilityCondition': null, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2 + } + } + ] + } + }, + { + 'fieldType': 'ContainerRepresentation', + 'id': 'df046463-2d65-4388-9ee1-0e1517985215', + 'name': 'Label', + 'type': 'container', + 'tab': null, + 'numberOfColumns': 2, + 'fields': { + '1': [ + { + 'fieldType': 'FormFieldRepresentation', + 'id': 'number1', + 'overrideId': false, + 'name': 'Number1', + 'type': 'integer', + 'colspan': 1, + 'placeholder': null, + 'readOnly': true, + 'minValue': null, + 'maxValue': null, + 'required': false, + 'visibilityCondition': null, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2 + } + } + ], + '2': [ + { + 'fieldType': 'FormFieldRepresentation', + 'id': 'number2', + 'overrideId': false, + 'name': 'Number2', + 'type': 'integer', + 'colspan': 1, + 'placeholder': null, + 'readOnly': true, + 'minValue': null, + 'maxValue': null, + 'required': false, + 'visibilityCondition': null, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2 + } + } + ] + } + }, + { + 'fieldType': 'ContainerRepresentation', + 'id': '9672cc7b-1959-49c9-96be-3816e57bdfc1', + 'name': 'Label', + 'type': 'container', + 'tab': null, + 'numberOfColumns': 2, + 'fields': { + '1': [ + { + 'fieldType': 'FormFieldRepresentation', + 'id': 'checkbox1', + 'name': 'Checkbox1', + 'type': 'boolean', + 'required': false, + 'readOnly': true, + 'colspan': 1, + 'overrideId': false, + 'visibilityCondition': null, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2 + } + } + ], + '2': [ + { + 'fieldType': 'FormFieldRepresentation', + 'id': 'checkbox2', + 'name': 'Checkbox2', + 'type': 'boolean', + 'required': false, + 'readOnly': true, + 'colspan': 1, + 'overrideId': false, + 'visibilityCondition': null, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2 + } + } + ] + } + }, + { + 'fieldType': 'ContainerRepresentation', + 'id': '054d193e-a899-4494-9a3e-b489315b7d57', + 'name': 'Label', + 'type': 'container', + 'tab': null, + 'numberOfColumns': 2, + 'fields': { + '1': [ + { + 'fieldType': 'FormFieldRepresentation', + 'id': 'dropdown1', + 'name': 'Dropdown1', + 'type': 'dropdown', + 'value': null, + 'required': false, + 'readOnly': true, + 'overrideId': false, + 'colspan': 1, + 'placeholder': null, + 'optionType': 'manual', + 'options': [], + 'endpoint': null, + 'requestHeaders': null, + 'restUrl': null, + 'restResponsePath': null, + 'restIdProperty': null, + 'restLabelProperty': null, + 'visibilityCondition': null, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2 + } + } + ], + '2': [ + { + 'fieldType': 'FormFieldRepresentation', + 'id': 'dropdown2', + 'name': 'Dropdown2', + 'type': 'dropdown', + 'value': null, + 'required': false, + 'readOnly': true, + 'overrideId': false, + 'colspan': 1, + 'placeholder': null, + 'optionType': 'manual', + 'options': [], + 'endpoint': null, + 'requestHeaders': null, + 'restUrl': null, + 'restResponsePath': null, + 'restIdProperty': null, + 'restLabelProperty': null, + 'visibilityCondition': null, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2 + } + } + ] + } + }, + { + 'fieldType': 'ContainerRepresentation', + 'id': '1f8f0b66-e022-4667-91b4-bbbf2ddc36fb', + 'name': 'Label', + 'type': 'container', + 'tab': null, + 'numberOfColumns': 2, + 'fields': { + '1': [ + { + 'fieldType': 'FormFieldRepresentation', + 'id': 'amount1', + 'name': 'Amount1', + 'type': 'amount', + 'value': null, + 'required': false, + 'readOnly': true, + 'overrideId': false, + 'colspan': 1, + 'placeholder': '123', + 'minValue': null, + 'maxValue': null, + 'visibilityCondition': null, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2 + }, + 'enableFractions': false, + 'currency': '$' + } + ], + '2': [ + { + 'fieldType': 'FormFieldRepresentation', + 'id': 'amount2', + 'name': 'Amount2', + 'type': 'amount', + 'value': null, + 'required': false, + 'readOnly': true, + 'overrideId': false, + 'colspan': 1, + 'placeholder': '123', + 'minValue': null, + 'maxValue': null, + 'visibilityCondition': null, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2 + }, + 'enableFractions': false, + 'currency': '$' + } + ] + } + }, + { + 'fieldType': 'ContainerRepresentation', + 'id': '541a368b-67ee-4a7c-ae7e-232c050b9e24', + 'name': 'Label', + 'type': 'container', + 'tab': null, + 'numberOfColumns': 2, + 'fields': { + '1': [ + { + 'fieldType': 'FormFieldRepresentation', + 'id': 'date1', + 'name': 'Date1', + 'type': 'date', + 'overrideId': false, + 'required': false, + 'readOnly': true, + 'colspan': 1, + 'placeholder': null, + 'minValue': null, + 'maxValue': null, + 'visibilityCondition': null, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2 + }, + 'dateDisplayFormat': 'D-M-YYYY' + } + ], + '2': [ + { + 'fieldType': 'FormFieldRepresentation', + 'id': 'date2', + 'name': 'Date2', + 'type': 'date', + 'overrideId': false, + 'required': false, + 'readOnly': true, + 'colspan': 1, + 'placeholder': null, + 'minValue': null, + 'maxValue': null, + 'visibilityCondition': null, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2 + }, + 'dateDisplayFormat': 'D-M-YYYY' + } + ] + } + }, + { + 'fieldType': 'ContainerRepresentation', + 'id': 'e79cb7e2-3dc1-4c79-8158-28662c28a9f3', + 'name': 'Label', + 'type': 'container', + 'tab': null, + 'numberOfColumns': 2, + 'fields': { + '1': [ + { + 'fieldType': 'FormFieldRepresentation', + 'id': 'radiobuttons1', + 'name': 'Radio buttons1', + 'type': 'radio-buttons', + 'value': null, + 'required': false, + 'readOnly': true, + 'overrideId': false, + 'colspan': 1, + 'placeholder': null, + 'optionType': 'manual', + 'options': [ { - 'fieldType': 'FormFieldRepresentation', - 'id': 'text1', - 'name': 'Text1', + 'id': 'option_1', + 'name': 'Option 1' + }, + { + 'id': 'option_2', + 'name': 'Option 2' + } + ], + 'endpoint': null, + 'requestHeaders': null, + 'restUrl': null, + 'restResponsePath': null, + 'restIdProperty': null, + 'restLabelProperty': null, + 'visibilityCondition': null, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2 + } + } + ], + '2': [ + { + 'fieldType': 'FormFieldRepresentation', + 'id': 'radiobuttons2', + 'name': 'Radio buttons2', + 'type': 'radio-buttons', + 'value': null, + 'required': false, + 'readOnly': true, + 'overrideId': false, + 'colspan': 1, + 'placeholder': null, + 'optionType': 'manual', + 'options': [ + { + 'id': 'option_1', + 'name': 'Option 1' + }, + { + 'id': 'option_2', + 'name': 'Option 2' + } + ], + 'endpoint': null, + 'requestHeaders': null, + 'restUrl': null, + 'restResponsePath': null, + 'restIdProperty': null, + 'restLabelProperty': null, + 'visibilityCondition': null, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2 + } + } + ] + } + }, + { + 'fieldType': 'ContainerRepresentation', + 'id': '7c01ed35-be86-4be7-9c28-ed640a5a2ae1', + 'name': 'Label', + 'type': 'container', + 'tab': null, + 'numberOfColumns': 2, + 'fields': { + '1': [ + { + 'fieldType': 'AttachFileFieldRepresentation', + 'id': 'attachfile1', + 'name': 'Attach file1', + 'type': 'upload', + 'value': null, + 'required': false, + 'readOnly': true, + 'overrideId': false, + 'colspan': 1, + 'placeholder': null, + 'visibilityCondition': null, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2, + 'fileSource': { + 'serviceId': 'all-file-sources', + 'name': 'All file sources' + }, + 'multiple': false, + 'link': false + } + } + ], + '2': [ + { + 'fieldType': 'AttachFileFieldRepresentation', + 'id': 'attachfile2', + 'name': 'Attach file2', + 'type': 'upload', + 'value': null, + 'required': false, + 'readOnly': true, + 'overrideId': false, + 'colspan': 1, + 'placeholder': null, + 'visibilityCondition': null, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2, + 'fileSource': { + 'serviceId': 'all-file-sources', + 'name': 'All file sources' + }, + 'multiple': false, + 'link': false + } + } + ] + } + }, + { + 'fieldType': 'ContainerRepresentation', + 'id': '07b13b96-d469-4a1e-8a9a-9bb957c68869', + 'name': 'Label', + 'type': 'container', + 'tab': null, + 'numberOfColumns': 2, + 'fields': { + '1': [ + { + 'fieldType': 'FormFieldRepresentation', + 'id': 'displayvalue1', + 'name': 'Display value1', + 'type': 'readonly', + 'value': 'No field selected', + 'readOnly': true, + 'required': false, + 'overrideId': false, + 'colspan': 1, + 'visibilityCondition': null, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2, + 'field': { + 'id': 'displayvalue', + 'name': 'Display value', 'type': 'text', - 'value': null, - 'required': false, - 'readOnly': true, - 'overrideId': false, - 'colspan': 1, - 'placeholder': null, - 'minLength': 0, - 'maxLength': 0, - 'minValue': null, - 'maxValue': null, - 'regexPattern': null, - 'visibilityCondition': null, - 'params': { - 'existingColspan': 1, - 'maxColspan': 2 - } + 'responseVariable': true } - ], - '2': [ - { - 'fieldType': 'FormFieldRepresentation', - 'id': 'text2', - 'name': 'Text2', + } + } + ], + '2': [ + { + 'fieldType': 'FormFieldRepresentation', + 'id': 'displayvalue2', + 'name': 'Display value2', + 'type': 'readonly', + 'value': 'No field selected', + 'readOnly': true, + 'required': false, + 'overrideId': false, + 'colspan': 1, + 'visibilityCondition': null, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2, + 'field': { + 'id': 'displayvalue', + 'name': 'Display value', 'type': 'text', - 'value': null, - 'required': false, - 'readOnly': true, - 'overrideId': false, - 'colspan': 1, - 'placeholder': null, - 'minLength': 0, - 'maxLength': 0, - 'minValue': null, - 'maxValue': null, - 'regexPattern': null, - 'visibilityCondition': null, - 'params': { - 'existingColspan': 1, - 'maxColspan': 2 - } + 'responseVariable': true } - ] + } } - }, - { - 'fieldType': 'ContainerRepresentation', - 'id': '69c1390a-8d8d-423c-8efb-8e43401efa42', - 'name': 'Label', - 'type': 'container', - 'tab': null, - 'numberOfColumns': 2, - 'fields': { - '1': [ - { - 'fieldType': 'FormFieldRepresentation', - 'id': 'multilinetext1', - 'name': 'Multiline text1', - 'type': 'multi-line-text', - 'overrideId': false, - 'colspan': 1, - 'placeholder': null, - 'minLength': 0, - 'maxLength': 0, - 'regexPattern': null, - 'required': false, - 'readOnly': true, - 'visibilityCondition': null, - 'params': { - 'existingColspan': 1, - 'maxColspan': 2 - } - } - ], - '2': [ - { - 'fieldType': 'FormFieldRepresentation', - 'id': 'multilinetext2', - 'name': 'Multiline text2', - 'type': 'multi-line-text', - 'overrideId': false, - 'colspan': 1, - 'placeholder': null, - 'minLength': 0, - 'maxLength': 0, - 'regexPattern': null, - 'required': false, - 'readOnly': true, - 'visibilityCondition': null, - 'params': { - 'existingColspan': 1, - 'maxColspan': 2 - } - } - ] + ] + } + }, + { + 'fieldType': 'ContainerRepresentation', + 'id': '1576ef25-c842-494c-ab84-265a1e3bf68d', + 'name': 'Label', + 'type': 'container', + 'tab': null, + 'numberOfColumns': 2, + 'fields': { + '1': [ + { + 'fieldType': 'FormFieldRepresentation', + 'id': 'displaytext1', + 'name': 'Display text1', + 'type': 'readonly-text', + 'value': 'Display text as part of the form', + 'readOnly': true, + 'required': false, + 'overrideId': false, + 'colspan': 1, + 'visibilityCondition': null, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2 + } } - }, - { - 'fieldType': 'ContainerRepresentation', - 'id': 'df046463-2d65-4388-9ee1-0e1517985215', - 'name': 'Label', - 'type': 'container', - 'tab': null, - 'numberOfColumns': 2, - 'fields': { - '1': [ - { - 'fieldType': 'FormFieldRepresentation', - 'id': 'number1', - 'overrideId': false, - 'name': 'Number1', - 'type': 'integer', - 'colspan': 1, - 'placeholder': null, - 'readOnly': true, - 'minValue': null, - 'maxValue': null, - 'required': false, - 'visibilityCondition': null, - 'params': { - 'existingColspan': 1, - 'maxColspan': 2 - } - } - ], - '2': [ - { - 'fieldType': 'FormFieldRepresentation', - 'id': 'number2', - 'overrideId': false, - 'name': 'Number2', - 'type': 'integer', - 'colspan': 1, - 'placeholder': null, - 'readOnly': true, - 'minValue': null, - 'maxValue': null, - 'required': false, - 'visibilityCondition': null, - 'params': { - 'existingColspan': 1, - 'maxColspan': 2 - } - } - ] + ], + '2': [ + { + 'fieldType': 'FormFieldRepresentation', + 'id': 'displaytext2', + 'name': 'Display text2', + 'type': 'readonly-text', + 'value': 'Display text as part of the form', + 'readOnly': true, + 'required': false, + 'overrideId': false, + 'colspan': 1, + 'visibilityCondition': null, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2 + } } - }, - { - 'fieldType': 'ContainerRepresentation', - 'id': '9672cc7b-1959-49c9-96be-3816e57bdfc1', - 'name': 'Label', - 'type': 'container', - 'tab': null, - 'numberOfColumns': 2, - 'fields': { - '1': [ - { - 'fieldType': 'FormFieldRepresentation', - 'id': 'checkbox1', - 'name': 'Checkbox1', - 'type': 'boolean', - 'required': false, - 'readOnly': true, - 'colspan': 1, - 'overrideId': false, - 'visibilityCondition': null, - 'params': { - 'existingColspan': 1, - 'maxColspan': 2 - } - } - ], - '2': [ - { - 'fieldType': 'FormFieldRepresentation', - 'id': 'checkbox2', - 'name': 'Checkbox2', - 'type': 'boolean', - 'required': false, - 'readOnly': true, - 'colspan': 1, - 'overrideId': false, - 'visibilityCondition': null, - 'params': { - 'existingColspan': 1, - 'maxColspan': 2 - } - } - ] - } - }, - { - 'fieldType': 'ContainerRepresentation', - 'id': '054d193e-a899-4494-9a3e-b489315b7d57', - 'name': 'Label', - 'type': 'container', - 'tab': null, - 'numberOfColumns': 2, - 'fields': { - '1': [ - { - 'fieldType': 'FormFieldRepresentation', - 'id': 'dropdown1', - 'name': 'Dropdown1', - 'type': 'dropdown', - 'value': null, - 'required': false, - 'readOnly': true, - 'overrideId': false, - 'colspan': 1, - 'placeholder': null, - 'optionType': 'manual', - 'options': [], - 'endpoint': null, - 'requestHeaders': null, - 'restUrl': null, - 'restResponsePath': null, - 'restIdProperty': null, - 'restLabelProperty': null, - 'visibilityCondition': null, - 'params': { - 'existingColspan': 1, - 'maxColspan': 2 - } - } - ], - '2': [ - { - 'fieldType': 'FormFieldRepresentation', - 'id': 'dropdown2', - 'name': 'Dropdown2', - 'type': 'dropdown', - 'value': null, - 'required': false, - 'readOnly': true, - 'overrideId': false, - 'colspan': 1, - 'placeholder': null, - 'optionType': 'manual', - 'options': [], - 'endpoint': null, - 'requestHeaders': null, - 'restUrl': null, - 'restResponsePath': null, - 'restIdProperty': null, - 'restLabelProperty': null, - 'visibilityCondition': null, - 'params': { - 'existingColspan': 1, - 'maxColspan': 2 - } - } - ] - } - }, - { - 'fieldType': 'ContainerRepresentation', - 'id': '1f8f0b66-e022-4667-91b4-bbbf2ddc36fb', - 'name': 'Label', - 'type': 'container', - 'tab': null, - 'numberOfColumns': 2, - 'fields': { - '1': [ - { - 'fieldType': 'FormFieldRepresentation', - 'id': 'amount1', - 'name': 'Amount1', - 'type': 'amount', - 'value': null, - 'required': false, - 'readOnly': true, - 'overrideId': false, - 'colspan': 1, - 'placeholder': '123', - 'minValue': null, - 'maxValue': null, - 'visibilityCondition': null, - 'params': { - 'existingColspan': 1, - 'maxColspan': 2 - }, - 'enableFractions': false, - 'currency': '$' - } - ], - '2': [ - { - 'fieldType': 'FormFieldRepresentation', - 'id': 'amount2', - 'name': 'Amount2', - 'type': 'amount', - 'value': null, - 'required': false, - 'readOnly': true, - 'overrideId': false, - 'colspan': 1, - 'placeholder': '123', - 'minValue': null, - 'maxValue': null, - 'visibilityCondition': null, - 'params': { - 'existingColspan': 1, - 'maxColspan': 2 - }, - 'enableFractions': false, - 'currency': '$' - } - ] - } - }, - { - 'fieldType': 'ContainerRepresentation', - 'id': '541a368b-67ee-4a7c-ae7e-232c050b9e24', - 'name': 'Label', - 'type': 'container', - 'tab': null, - 'numberOfColumns': 2, - 'fields': { - '1': [ - { - 'fieldType': 'FormFieldRepresentation', - 'id': 'date1', - 'name': 'Date1', - 'type': 'date', - 'overrideId': false, - 'required': false, - 'readOnly': true, - 'colspan': 1, - 'placeholder': null, - 'minValue': null, - 'maxValue': null, - 'visibilityCondition': null, - 'params': { - 'existingColspan': 1, - 'maxColspan': 2 - }, - 'dateDisplayFormat': 'D-M-YYYY' - } - ], - '2': [ - { - 'fieldType': 'FormFieldRepresentation', - 'id': 'date2', - 'name': 'Date2', - 'type': 'date', - 'overrideId': false, - 'required': false, - 'readOnly': true, - 'colspan': 1, - 'placeholder': null, - 'minValue': null, - 'maxValue': null, - 'visibilityCondition': null, - 'params': { - 'existingColspan': 1, - 'maxColspan': 2 - }, - 'dateDisplayFormat': 'D-M-YYYY' - } - ] - } - }, - { - 'fieldType': 'ContainerRepresentation', - 'id': 'e79cb7e2-3dc1-4c79-8158-28662c28a9f3', - 'name': 'Label', - 'type': 'container', - 'tab': null, - 'numberOfColumns': 2, - 'fields': { - '1': [ - { - 'fieldType': 'FormFieldRepresentation', - 'id': 'radiobuttons1', - 'name': 'Radio buttons1', - 'type': 'radio-buttons', - 'value': null, - 'required': false, - 'readOnly': true, - 'overrideId': false, - 'colspan': 1, - 'placeholder': null, - 'optionType': 'manual', - 'options': [ - { - 'id': 'option_1', - 'name': 'Option 1' - }, - { - 'id': 'option_2', - 'name': 'Option 2' - } - ], - 'endpoint': null, - 'requestHeaders': null, - 'restUrl': null, - 'restResponsePath': null, - 'restIdProperty': null, - 'restLabelProperty': null, - 'visibilityCondition': null, - 'params': { - 'existingColspan': 1, - 'maxColspan': 2 - } - } - ], - '2': [ - { - 'fieldType': 'FormFieldRepresentation', - 'id': 'radiobuttons2', - 'name': 'Radio buttons2', - 'type': 'radio-buttons', - 'value': null, - 'required': false, - 'readOnly': true, - 'overrideId': false, - 'colspan': 1, - 'placeholder': null, - 'optionType': 'manual', - 'options': [ - { - 'id': 'option_1', - 'name': 'Option 1' - }, - { - 'id': 'option_2', - 'name': 'Option 2' - } - ], - 'endpoint': null, - 'requestHeaders': null, - 'restUrl': null, - 'restResponsePath': null, - 'restIdProperty': null, - 'restLabelProperty': null, - 'visibilityCondition': null, - 'params': { - 'existingColspan': 1, - 'maxColspan': 2 - } - } - ] - } - }, - { - 'fieldType': 'ContainerRepresentation', - 'id': '7c01ed35-be86-4be7-9c28-ed640a5a2ae1', - 'name': 'Label', - 'type': 'container', - 'tab': null, - 'numberOfColumns': 2, - 'fields': { - '1': [ - { - 'fieldType': 'AttachFileFieldRepresentation', - 'id': 'attachfile1', - 'name': 'Attach file1', - 'type': 'upload', - 'value': null, - 'required': false, - 'readOnly': true, - 'overrideId': false, - 'colspan': 1, - 'placeholder': null, - 'visibilityCondition': null, - 'params': { - 'existingColspan': 1, - 'maxColspan': 2, - 'fileSource': { - 'serviceId': 'all-file-sources', - 'name': 'All file sources' - }, - 'multiple': false, - 'link': false - } - } - ], - '2': [ - { - 'fieldType': 'AttachFileFieldRepresentation', - 'id': 'attachfile2', - 'name': 'Attach file2', - 'type': 'upload', - 'value': null, - 'required': false, - 'readOnly': true, - 'overrideId': false, - 'colspan': 1, - 'placeholder': null, - 'visibilityCondition': null, - 'params': { - 'existingColspan': 1, - 'maxColspan': 2, - 'fileSource': { - 'serviceId': 'all-file-sources', - 'name': 'All file sources' - }, - 'multiple': false, - 'link': false - } - } - ] - } - }, - { - 'fieldType': 'ContainerRepresentation', - 'id': '07b13b96-d469-4a1e-8a9a-9bb957c68869', - 'name': 'Label', - 'type': 'container', - 'tab': null, - 'numberOfColumns': 2, - 'fields': { - '1': [ - { - 'fieldType': 'FormFieldRepresentation', - 'id': 'displayvalue1', - 'name': 'Display value1', - 'type': 'readonly', - 'value': 'No field selected', - 'readOnly': true, - 'required': false, - 'overrideId': false, - 'colspan': 1, - 'visibilityCondition': null, - 'params': { - 'existingColspan': 1, - 'maxColspan': 2, - 'field': { - 'id': 'displayvalue', - 'name': 'Display value', - 'type': 'text' - } - } - } - ], - '2': [ - { - 'fieldType': 'FormFieldRepresentation', - 'id': 'displayvalue2', - 'name': 'Display value2', - 'type': 'readonly', - 'value': 'No field selected', - 'readOnly': true, - 'required': false, - 'overrideId': false, - 'colspan': 1, - 'visibilityCondition': null, - 'params': { - 'existingColspan': 1, - 'maxColspan': 2, - 'field': { - 'id': 'displayvalue', - 'name': 'Display value', - 'type': 'text' - } - } - } - ] - } - }, - { - 'fieldType': 'ContainerRepresentation', - 'id': '1576ef25-c842-494c-ab84-265a1e3bf68d', - 'name': 'Label', - 'type': 'container', - 'tab': null, - 'numberOfColumns': 2, - 'fields': { - '1': [ - { - 'fieldType': 'FormFieldRepresentation', - 'id': 'displaytext1', - 'name': 'Display text1', - 'type': 'readonly-text', - 'value': 'Display text as part of the form', - 'readOnly': true, - 'required': false, - 'overrideId': false, - 'colspan': 1, - 'visibilityCondition': null, - 'params': { - 'existingColspan': 1, - 'maxColspan': 2 - } - } - ], - '2': [ - { - 'fieldType': 'FormFieldRepresentation', - 'id': 'displaytext2', - 'name': 'Display text2', - 'type': 'readonly-text', - 'value': 'Display text as part of the form', - 'readOnly': true, - 'required': false, - 'overrideId': false, - 'colspan': 1, - 'visibilityCondition': null, - 'params': { - 'existingColspan': 1, - 'maxColspan': 2 - } - } - ] - } - } - ], - 'outcomes': [], - 'javascriptEvents': [], - 'className': '', - 'style': '', - 'customFieldTemplates': {}, - 'metadata': {}, - 'variables': [ - { - 'name': 'FormVarStr', - 'type': 'string', - 'value': '' - }, - { - 'name': 'FormVarInt', - 'type': 'integer', - 'value': '' - }, - { - 'name': 'FormVarBool', - 'type': 'boolean', - 'value': '' - }, - { - 'name': 'FormVarDate', - 'type': 'date', - 'value': '' - }, - { - 'name': 'NewVar', - 'type': 'string', - 'value': '' - } - ], - 'customFieldsValueInfo': {}, - 'gridsterForm': false + ] + } } - }, - 'processScopeIdentifiers': [] + ], + 'outcomes': [], + 'metadata': {}, + 'variables': [ + { + 'name': 'FormVarStr', + 'type': 'string', + 'value': '' + }, + { + 'name': 'FormVarInt', + 'type': 'integer', + 'value': '' + }, + { + 'name': 'FormVarBool', + 'type': 'boolean', + 'value': '' + }, + { + 'name': 'FormVarDate', + 'type': 'date', + 'value': '' + }, + { + 'name': 'NewVar', + 'type': 'string', + 'value': '' + } + ] }; diff --git a/lib/process-services-cloud/src/lib/form/models/form-cloud-representation.model.ts b/lib/process-services-cloud/src/lib/form/models/form-cloud-representation.model.ts new file mode 100644 index 0000000000..ef17b12f0c --- /dev/null +++ b/lib/process-services-cloud/src/lib/form/models/form-cloud-representation.model.ts @@ -0,0 +1,51 @@ +/*! + * @license + * Copyright 2019 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 class FormCloudRepresentation { + + id?: string; + name?: string; + description?: string; + version?: number; + tabs?: any[]; + fields?: any[]; + outcomes?: any[]; + metadata?: any; + variables?: any[]; + taskId?: string; + taskName?: string; + processDefinitionId?: string; + processInstanceId?: string; + selectedOutcome?: string; + + constructor(obj?: any) { + this.id = obj.id || null; + this.name = obj.name || null; + this.description = obj.description || null; + this.version = obj.version || null; + this.tabs = obj.tabs || null; + this.fields = obj.fields || null; + this.outcomes = obj.outcomes || null; + this.metadata = obj.metadata || null; + this.variables = obj.variables || null; + this.taskId = obj.taskId || null; + this.taskName = obj.taskName || null; + this.processDefinitionId = obj.processDefinitionId || null; + this.processInstanceId = obj.processInstanceId || null; + this.selectedOutcome = obj.selectedOutcome || null; + } +} diff --git a/lib/process-services-cloud/src/lib/form/models/form-cloud.model.spec.ts b/lib/process-services-cloud/src/lib/form/models/form-cloud.model.spec.ts index 672d34d846..c2836b686e 100644 --- a/lib/process-services-cloud/src/lib/form/models/form-cloud.model.spec.ts +++ b/lib/process-services-cloud/src/lib/form/models/form-cloud.model.spec.ts @@ -18,6 +18,7 @@ import { FormCloudService } from '../services/form-cloud.service'; import { FormCloud } from './form-cloud.model'; import { TabModel, FormFieldModel, ContainerModel, FormOutcomeModel, FormFieldTypes, AppConfigService } from '@alfresco/adf-core'; +import { FormCloudRepresentation } from './form-cloud-representation.model'; describe('FormCloud', () => { @@ -28,33 +29,33 @@ describe('FormCloud', () => { }); it('should store original json', () => { - const json = {formRepresentation: {formDefinition: {}}}; - const form = new FormCloud(json); - expect(form.json).toBe(json); + const formRepresentation = {fields: []}; + const form = new FormCloud(formRepresentation); + expect(form.json).toEqual(formRepresentation); }); it('should setup properties with json', () => { - const json = {formRepresentation: { + const formRepresentation: FormCloudRepresentation = { id: '', name: '', taskId: '', taskName: '' - }}; - const form = new FormCloud(json); + }; + const form = new FormCloud(formRepresentation); - Object.keys(json).forEach((key) => { + Object.keys(formRepresentation).forEach((key) => { expect(form[key]).toEqual(form[key]); }); }); it('should take form name when task name is missing', () => { - const json = {formRepresentation: { + const formRepresentation = { id: '', name: '', formDefinition: {} - }}; - const form = new FormCloud(json); - expect(form.taskName).toBe(json.formRepresentation.name); + }; + const form = new FormCloud(formRepresentation); + expect(form.taskName).toBe(formRepresentation.name); }); it('should set readonly state from params', () => { @@ -103,21 +104,21 @@ describe('FormCloud', () => { }); it('should parse tabs', () => { - const json = {formRepresentation: {formDefinition: { + const formRepresentation = { tabs: [ { id: 'tab1' }, { id: 'tab2' } ] - }}}; + }; - const form = new FormCloud(json); + const form = new FormCloud(formRepresentation); expect(form.tabs.length).toBe(2); expect(form.tabs[0].id).toBe('tab1'); expect(form.tabs[1].id).toBe('tab2'); }); it('should parse fields', () => { - const json = {formRepresentation: {formDefinition: { + const formRepresentation = { fields: [ { id: 'field1', @@ -128,26 +129,26 @@ describe('FormCloud', () => { type: FormFieldTypes.CONTAINER } ] - }}}; + }; - const form = new FormCloud(json); + const form = new FormCloud(formRepresentation); expect(form.fields.length).toBe(2); expect(form.fields[0].id).toBe('field1'); expect(form.fields[1].id).toBe('field2'); }); it('should convert missing fields to empty collection', () => { - const json = {formRepresentation: {formDefinition: { + const formRepresentation = { fields: null - }}}; + }; - const form = new FormCloud(json); + const form = new FormCloud(formRepresentation); expect(form.fields).toBeDefined(); expect(form.fields.length).toBe(0); }); it('should put fields into corresponding tabs', () => { - const json = {formRepresentation: {formDefinition: { + const formRepresentation = { tabs: [ { id: 'tab1' }, { id: 'tab2' } @@ -158,9 +159,9 @@ describe('FormCloud', () => { { id: 'field3', tab: 'tab1', type: FormFieldTypes.DYNAMIC_TABLE }, { id: 'field4', tab: 'missing-tab', type: FormFieldTypes.DYNAMIC_TABLE } ] - }}}; + }; - const form = new FormCloud(json); + const form = new FormCloud(formRepresentation); expect(form.tabs.length).toBe(2); expect(form.fields.length).toBe(4); @@ -175,13 +176,13 @@ describe('FormCloud', () => { }); it('should create standard form outcomes', () => { - const json = {formRepresentation: {formDefinition: { + const formRepresentation = { fields: [ { id: 'container1' } ] - }}}; + }; - const form = new FormCloud(json); + const form = new FormCloud(formRepresentation); expect(form.outcomes.length).toBe(3); expect(form.outcomes[0].id).toBe(FormCloud.SAVE_OUTCOME); @@ -195,24 +196,24 @@ describe('FormCloud', () => { }); it('should create outcomes only when fields available', () => { - const json = {formRepresentation: {formDefinition: { + const formRepresentation = { fields: null - }}}; - const form = new FormCloud(json); + }; + const form = new FormCloud(formRepresentation); expect(form.outcomes.length).toBe(0); }); it('should use custom form outcomes', () => { - const json = {formRepresentation: {formDefinition: { + const formRepresentation = { fields: [ { id: 'container1' } - ]}, + ], outcomes: [ { id: 'custom-1', name: 'custom 1' } ] - }}; + }; - const form = new FormCloud(json); + const form = new FormCloud(formRepresentation); expect(form.outcomes.length).toBe(2); expect(form.outcomes[0].id).toBe(FormCloud.SAVE_OUTCOME); diff --git a/lib/process-services-cloud/src/lib/form/models/form-cloud.model.ts b/lib/process-services-cloud/src/lib/form/models/form-cloud.model.ts index a742402b9a..70b7936eb9 100644 --- a/lib/process-services-cloud/src/lib/form/models/form-cloud.model.ts +++ b/lib/process-services-cloud/src/lib/form/models/form-cloud.model.ts @@ -18,11 +18,11 @@ import { TabModel, FormWidgetModel, FormOutcomeModel, FormValues, FormWidgetModelCache, FormFieldModel, ContainerModel, FormFieldTypes, - ValidateFormFieldEvent, FormFieldValidator, FormFieldTemplates } from '@alfresco/adf-core'; + ValidateFormFieldEvent, FormFieldValidator, FormFieldTemplates, FormBaseModel } from '@alfresco/adf-core'; import { FormCloudService } from '../services/form-cloud.service'; import { TaskVariableCloud } from './task-variable-cloud.model'; -export class FormCloud { +export class FormCloud extends FormBaseModel { static SAVE_OUTCOME: string = '$save'; static COMPLETE_OUTCOME: string = '$complete'; @@ -34,14 +34,8 @@ export class FormCloud { readonly name: string; readonly taskId: string; readonly taskName: string; - private _isValid: boolean = true; - - get isValid(): boolean { - return this._isValid; - } readonly selectedOutcome: string; - readonly json: any; readOnly: boolean; processDefinitionId: any; @@ -54,29 +48,28 @@ export class FormCloud { customFieldTemplates: FormFieldTemplates = {}; fieldValidators: FormFieldValidator[] = []; - constructor(json?: any, formData?: TaskVariableCloud[], readOnly: boolean = false, protected formService?: FormCloudService) { + constructor(formCloudRepresentationJSON?: any, formData?: TaskVariableCloud[], readOnly: boolean = false, protected formService?: FormCloudService) { + super(); this.readOnly = readOnly; - if (json && json.formRepresentation && json.formRepresentation.formDefinition) { - this.json = json; - this.id = json.formRepresentation.id; - this.name = json.formRepresentation.name; - this.taskId = json.formRepresentation.taskId; - this.taskName = json.formRepresentation.taskName || json.formRepresentation.name; - this.processDefinitionId = json.formRepresentation.processDefinitionId; - this.customFieldTemplates = json.formRepresentation.formDefinition.customFieldTemplates || {}; - this.selectedOutcome = json.formRepresentation.formDefinition.selectedOutcome || {}; - this.className = json.formRepresentation.formDefinition.className || ''; + if (formCloudRepresentationJSON) { + this.json = formCloudRepresentationJSON; + this.id = formCloudRepresentationJSON.id; + this.name = formCloudRepresentationJSON.name; + this.taskId = formCloudRepresentationJSON.taskId; + this.taskName = formCloudRepresentationJSON.taskName || formCloudRepresentationJSON.name; + this.processDefinitionId = formCloudRepresentationJSON.processDefinitionId; + this.selectedOutcome = formCloudRepresentationJSON.selectedOutcome || ''; const tabCache: FormWidgetModelCache = {}; - this.tabs = (json.formRepresentation.formDefinition.tabs || []).map((t) => { + this.tabs = (formCloudRepresentationJSON.tabs || []).map((t) => { const model = new TabModel( this, t); tabCache[model.id] = model; return model; }); - this.fields = this.parseRootFields(json); + this.fields = this.parseRootFields(formCloudRepresentationJSON); if (formData && formData.length > 0) { this.loadData(formData); @@ -93,7 +86,7 @@ export class FormCloud { } } - if (json.formRepresentation.formDefinition.fields) { + if (formCloudRepresentationJSON.fields) { const saveOutcome = new FormOutcomeModel( this, { id: FormCloud.SAVE_OUTCOME, name: 'SAVE', @@ -110,7 +103,7 @@ export class FormCloud { isSystem: true }); - const customOutcomes = (json.formRepresentation.outcomes || []).map((obj) => new FormOutcomeModel( this, obj)); + const customOutcomes = (formCloudRepresentationJSON.outcomes || []).map((obj) => new FormOutcomeModel( this, obj)); this.outcomes = [saveOutcome].concat( customOutcomes.length > 0 ? customOutcomes : [completeOutcome, startProcessOutcome] @@ -142,37 +135,10 @@ export class FormCloud { return this.outcomes && this.outcomes.length > 0; } - getFieldById(fieldId: string): FormFieldModel { - return this.getFormFields().find((field) => field.id === fieldId); - } - onFormFieldChanged(field: FormFieldModel) { this.validateField(field); } - getFormFields(): FormFieldModel[] { - const formFields: FormFieldModel[] = []; - - for (let i = 0; i < this.fields.length; i++) { - const field = this.fields[i]; - - if (field instanceof ContainerModel) { - const container = field; - formFields.push(container.field); - - container.field.columns.forEach((column) => { - formFields.push(...column.fields); - }); - } - } - - return formFields; - } - - markAsInvalid() { - this._isValid = false; - } - validateForm() { const errorsField: FormFieldModel[] = []; @@ -183,7 +149,7 @@ export class FormCloud { } } - this._isValid = errorsField.length > 0 ? false : true; + this.isValid = errorsField.length > 0 ? false : true; } /** @@ -200,7 +166,7 @@ export class FormCloud { const validateFieldEvent = new ValidateFormFieldEvent( this, field); if (!validateFieldEvent.isValid) { - this._isValid = false; + this.isValid = false; return; } @@ -209,7 +175,7 @@ export class FormCloud { } if (!field.validate()) { - this._isValid = false; + this.isValid = false; } this.validateForm(); @@ -219,10 +185,8 @@ export class FormCloud { private parseRootFields(json: any): FormWidgetModel[] { let fields = []; - if (json.formRepresentation.fields) { - fields = json.formRepresentation.fields; - } else if (json.formRepresentation.formDefinition && json.formRepresentation.formDefinition.fields) { - fields = json.formRepresentation.formDefinition.fields; + if (json.fields) { + fields = json.fields; } const formWidgetModel: FormWidgetModel[] = []; diff --git a/lib/process-services-cloud/src/lib/form/services/form-cloud.service.spec.ts b/lib/process-services-cloud/src/lib/form/services/form-cloud.service.spec.ts index 494d7375a8..1c47eea24b 100644 --- a/lib/process-services-cloud/src/lib/form/services/form-cloud.service.spec.ts +++ b/lib/process-services-cloud/src/lib/form/services/form-cloud.service.spec.ts @@ -150,15 +150,17 @@ describe('Form Cloud service', () => { }); - it('should fetch task form', (done) => { + it('should fetch task form flattened', (done) => { spyOn(service, 'getTask').and.returnValue(of(responseBody.entry)); - spyOn(service, 'getForm').and.returnValue(of({ formRepresentation: { name: 'task-form' } })); + spyOn(service, 'getForm').and.returnValue(of({ + formRepresentation: {name: 'task-form', formDefinition: {} } + })); service.getTaskForm(appName, taskId).subscribe((result) => { expect(result).toBeDefined(); - expect(result.formRepresentation.name).toBe('task-form'); - expect(result.formRepresentation.taskId).toBe(responseBody.entry.id); - expect(result.formRepresentation.taskName).toBe(responseBody.entry.name); + expect(result.name).toBe('task-form'); + expect(result.taskId).toBe(responseBody.entry.id); + expect(result.taskName).toBe(responseBody.entry.name); done(); }); diff --git a/lib/process-services-cloud/src/lib/form/services/form-cloud.service.ts b/lib/process-services-cloud/src/lib/form/services/form-cloud.service.ts index 6150a114a3..5f8d457800 100644 --- a/lib/process-services-cloud/src/lib/form/services/form-cloud.service.ts +++ b/lib/process-services-cloud/src/lib/form/services/form-cloud.service.ts @@ -55,11 +55,13 @@ export class FormCloudService extends BaseCloudService { switchMap((task: TaskDetailsCloudModel) => { return this.getForm(appName, task.formKey).pipe( map((form: any) => { - form.formRepresentation.taskId = task.id; - form.formRepresentation.taskName = task.name; - form.formRepresentation.processDefinitionId = task.processDefinitionId; - form.formRepresentation.processInstanceId = task.processInstanceId; - return form; + const flattenForm = {...form.formRepresentation, ...form.formRepresentation.formDefinition}; + delete flattenForm.formDefinition; + flattenForm.taskId = task.id; + flattenForm.taskName = task.name; + flattenForm.processDefinitionId = task.processDefinitionId; + flattenForm.processInstanceId = task.processInstanceId; + return flattenForm; }) ); }) @@ -258,7 +260,10 @@ export class FormCloudService extends BaseCloudService { */ parseForm(json: any, data?: TaskVariableCloud[], readOnly: boolean = false): FormCloud { if (json) { - const form = new FormCloud(json, data, readOnly, this); + const flattenForm = {...json.formRepresentation, ...json.formRepresentation.formDefinition}; + delete flattenForm.formDefinition; + + const form = new FormCloud(flattenForm, data, readOnly, this); if (!json.fields) { form.outcomes = [ new FormOutcomeModel( form, { diff --git a/lib/process-services-cloud/src/lib/process/start-process/mock/start-process.component.mock.ts b/lib/process-services-cloud/src/lib/process/start-process/mock/start-process.component.mock.ts index 7840d8138d..13e7d03f55 100755 --- a/lib/process-services-cloud/src/lib/process/start-process/mock/start-process.component.mock.ts +++ b/lib/process-services-cloud/src/lib/process/start-process/mock/start-process.component.mock.ts @@ -81,65 +81,61 @@ export let fakeProcessPayload = new ProcessPayloadCloud({ }); export let fakeStartForm = { - 'formRepresentation': { - 'id': 'form-a5d50817-5183-4850-802d-17af54b2632f', - 'name': 'simpleform', - 'description': '', - 'version': 0, - 'formDefinition': { - 'tabs': [], - 'fields': [ - { + 'id': 'form-a5d50817-5183-4850-802d-17af54b2632f', + 'name': 'simpleform', + 'description': '', + 'version': 0, + 'tabs': [], + 'fields': [ + { 'type': 'container', 'id': '5a6b24c1-db2b-45e9-9aff-142395433d23', 'name': 'Label', 'tab': null, 'fields': { - '1': [ - { - 'type': 'text', - 'id': 'firstName', - 'name': 'firstName', - 'colspan': 1, - 'params': { - 'existingColspan': 1, - 'maxColspan': 2 - }, - 'visibilityCondition': null, - 'placeholder': null, - 'value': null, - 'required': false, - 'minLength': 0, - 'maxLength': 0, - 'regexPattern': null - } - ], - '2': [ - { - 'type': 'text', - 'id': 'lastName', - 'name': 'lastName', - 'colspan': 1, - 'params': { - 'existingColspan': 1, - 'maxColspan': 2 - }, - 'visibilityCondition': null, - 'placeholder': null, - 'value': null, - 'required': false, - 'minLength': 0, - 'maxLength': 0, - 'regexPattern': null - } - ] + '1': [ + { + 'type': 'text', + 'id': 'firstName', + 'name': 'firstName', + 'colspan': 1, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2 + }, + 'visibilityCondition': null, + 'placeholder': null, + 'value': null, + 'required': false, + 'minLength': 0, + 'maxLength': 0, + 'regexPattern': null + } + ], + '2': [ + { + 'type': 'text', + 'id': 'lastName', + 'name': 'lastName', + 'colspan': 1, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2 + }, + 'visibilityCondition': null, + 'placeholder': null, + 'value': null, + 'required': false, + 'minLength': 0, + 'maxLength': 0, + 'regexPattern': null + } + ] }, 'numberOfColumns': 2 - } - ], - 'outcomes': [], - 'metadata': {}, - 'variables': [] - } - } - }; + } + ], + 'outcomes': [], + 'metadata': {}, + 'variables': [] +}; diff --git a/lib/process-services/form/form.component.ts b/lib/process-services/form/form.component.ts index d117f11e0c..8b391fdfb0 100644 --- a/lib/process-services/form/form.component.ts +++ b/lib/process-services/form/form.component.ts @@ -282,10 +282,10 @@ export class FormComponent extends FormBaseComponent implements OnInit, OnDestro this.error.emit(err); } - parseForm(json: any): FormModel { - if (json) { - const form = new FormModel(json, this.data, this.readOnly, this.formService); - if (!json.fields) { + parseForm(formRepresentationJSON: any): FormModel { + if (formRepresentationJSON) { + const form = new FormModel(formRepresentationJSON, this.data, this.readOnly, this.formService); + if (!formRepresentationJSON.fields) { form.outcomes = this.getFormDefinitionOutcomes(form); } if (this.fieldValidators && this.fieldValidators.length > 0) {