mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2026-09-09 18:03:21 +00:00
AAE-40078 Fix visibility condition not working (#11389)
* AAE-40078 Fix visibility condition not working * AAE-40078 Fix test * AAE-40078 Improve handlers
This commit is contained in:
@@ -815,7 +815,7 @@ describe('Form Renderer Component', () => {
|
|||||||
params: {
|
params: {
|
||||||
initialNumberOfRows: 2,
|
initialNumberOfRows: 2,
|
||||||
allowInitialRowsDelete: true,
|
allowInitialRowsDelete: true,
|
||||||
newRowsLimit: 1
|
maxNumberOfRows: 3
|
||||||
},
|
},
|
||||||
numberOfColumns: 2,
|
numberOfColumns: 2,
|
||||||
fields: {
|
fields: {
|
||||||
|
|||||||
@@ -2332,7 +2332,7 @@ export const mockRepeatableSectionForm01 = {
|
|||||||
params: {
|
params: {
|
||||||
initialNumberOfRows: 2,
|
initialNumberOfRows: 2,
|
||||||
allowInitialRowsDelete: true,
|
allowInitialRowsDelete: true,
|
||||||
newRowsLimit: 3
|
maxNumberOfRows: 5
|
||||||
},
|
},
|
||||||
numberOfColumns: 2,
|
numberOfColumns: 2,
|
||||||
fields: {
|
fields: {
|
||||||
@@ -2403,7 +2403,7 @@ export const mockRepeatableSectionForm02 = {
|
|||||||
params: {
|
params: {
|
||||||
initialNumberOfRows: 2,
|
initialNumberOfRows: 2,
|
||||||
allowInitialRowsDelete: false,
|
allowInitialRowsDelete: false,
|
||||||
newRowsLimit: 3
|
maxNumberOfRows: 5
|
||||||
},
|
},
|
||||||
numberOfColumns: 2,
|
numberOfColumns: 2,
|
||||||
fields: {
|
fields: {
|
||||||
|
|||||||
@@ -1492,6 +1492,16 @@ describe('FormFieldModel', () => {
|
|||||||
field.addRow(field.fields, form);
|
field.addRow(field.fields, form);
|
||||||
expect(field.rows.length).toBe(5);
|
expect(field.rows.length).toBe(5);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should call onRepeatableSectionChanged', () => {
|
||||||
|
spyOn(field.form, 'onRepeatableSectionChanged').and.callThrough();
|
||||||
|
|
||||||
|
expect(field.form.onRepeatableSectionChanged).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
field.addRow(field.fields, form);
|
||||||
|
|
||||||
|
expect(field.form.onRepeatableSectionChanged).toHaveBeenCalled();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('remove row', () => {
|
describe('remove row', () => {
|
||||||
@@ -1560,6 +1570,16 @@ describe('FormFieldModel', () => {
|
|||||||
|
|
||||||
expect(field.form.onFormFieldChanged).not.toHaveBeenCalled();
|
expect(field.form.onFormFieldChanged).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should call onRepeatableSectionChanged', () => {
|
||||||
|
spyOn(field.form, 'onRepeatableSectionChanged').and.callThrough();
|
||||||
|
|
||||||
|
expect(field.form.onRepeatableSectionChanged).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
field.removeRow(1);
|
||||||
|
|
||||||
|
expect(field.form.onRepeatableSectionChanged).toHaveBeenCalled();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('disabled state', () => {
|
describe('disabled state', () => {
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import { isValid as isValidDate } from 'date-fns';
|
|||||||
import { ContainerRowModel } from './container-row.model';
|
import { ContainerRowModel } from './container-row.model';
|
||||||
import { RepeatableSectionModel, ROW_ID_PREFIX } from './repeatable-section.model';
|
import { RepeatableSectionModel, ROW_ID_PREFIX } from './repeatable-section.model';
|
||||||
import { formFieldRuleHandler } from './handlers/form-field-rule.handler';
|
import { formFieldRuleHandler } from './handlers/form-field-rule.handler';
|
||||||
|
import { formFieldVisibilityConditionHandler } from './handlers/form-field-visibility-condition.handler';
|
||||||
|
|
||||||
export type FieldOptionType = 'rest' | 'manual' | 'variable';
|
export type FieldOptionType = 'rest' | 'manual' | 'variable';
|
||||||
export type FieldSelectionType = 'single' | 'multiple';
|
export type FieldSelectionType = 'single' | 'multiple';
|
||||||
@@ -217,7 +218,7 @@ export class FormFieldModel extends FormWidgetModel {
|
|||||||
this.params = json.params || {};
|
this.params = json.params || {};
|
||||||
this.hyperlinkUrl = json.hyperlinkUrl;
|
this.hyperlinkUrl = json.hyperlinkUrl;
|
||||||
this.displayText = json.displayText;
|
this.displayText = json.displayText;
|
||||||
this.visibilityCondition = json.visibilityCondition ? new WidgetVisibilityModel(json.visibilityCondition) : undefined;
|
this.visibilityCondition = formFieldVisibilityConditionHandler.getVisibilityCondition(this.id, json.visibilityCondition, parent);
|
||||||
this.enableFractions = json.enableFractions;
|
this.enableFractions = json.enableFractions;
|
||||||
this.currency = json.currency;
|
this.currency = json.currency;
|
||||||
this.dateDisplayFormat = json.dateDisplayFormat || this.getDefaultDateFormat(json);
|
this.dateDisplayFormat = json.dateDisplayFormat || this.getDefaultDateFormat(json);
|
||||||
@@ -354,7 +355,7 @@ export class FormFieldModel extends FormWidgetModel {
|
|||||||
this.columns = this.rows[0].columns;
|
this.columns = this.rows[0].columns;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getNumberOfRows(initialNrRows: number = 1, maxNrRows?: number, value?: any) {
|
private getNumberOfRows(initialNrRows: number = 1, maxNrRows: number | null = null, value?: any) {
|
||||||
return value?.length ? (maxNrRows ? Math.min(value.length, maxNrRows) : value.length) : initialNrRows;
|
return value?.length ? (maxNrRows ? Math.min(value.length, maxNrRows) : value.length) : initialNrRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -469,6 +470,7 @@ export class FormFieldModel extends FormWidgetModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.rows.push(this.createRow(fields, form, this.rows.length));
|
this.rows.push(this.createRow(fields, form, this.rows.length));
|
||||||
|
this.form.onRepeatableSectionChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
private shouldAddRow(): boolean {
|
private shouldAddRow(): boolean {
|
||||||
@@ -482,6 +484,7 @@ export class FormFieldModel extends FormWidgetModel {
|
|||||||
|
|
||||||
this.rows.splice(index, 1);
|
this.rows.splice(index, 1);
|
||||||
this.updateChildrenFieldsRowIndex();
|
this.updateChildrenFieldsRowIndex();
|
||||||
|
this.form.onRepeatableSectionChanged();
|
||||||
|
|
||||||
if (!this.form.values[this.id]) {
|
if (!this.form.values[this.id]) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -147,6 +147,10 @@ export class FormModel implements ProcessFormModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onRepeatableSectionChanged() {
|
||||||
|
this.fieldsCache = this.getFormFields([], true);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates entire form and all form fields.
|
* Validates entire form and all form fields.
|
||||||
*/
|
*/
|
||||||
@@ -343,8 +347,8 @@ export class FormModel implements ProcessFormModel {
|
|||||||
return this.fieldsCache.find((field) => field.id === fieldId);
|
return this.fieldsCache.find((field) => field.id === fieldId);
|
||||||
}
|
}
|
||||||
|
|
||||||
getFormFields(filterTypes?: string[]): FormFieldModel[] {
|
getFormFields(filterTypes?: string[], isDynamic: boolean = false): FormFieldModel[] {
|
||||||
if (this.fieldsCache?.length) {
|
if (this.fieldsCache?.length && !isDynamic) {
|
||||||
return this.filterFieldsByType(this.fieldsCache, filterTypes);
|
return this.filterFieldsByType(this.fieldsCache, filterTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,7 +359,9 @@ export class FormModel implements ProcessFormModel {
|
|||||||
|
|
||||||
private processFields(fields: (ContainerModel | FormFieldModel)[], formFieldModel: FormFieldModel[]): void {
|
private processFields(fields: (ContainerModel | FormFieldModel)[], formFieldModel: FormFieldModel[]): void {
|
||||||
fields.forEach((field) => {
|
fields.forEach((field) => {
|
||||||
if (this.isContainerField(field)) {
|
if (this.isRepeatableSectionField(field)) {
|
||||||
|
this.handleRepeatableSectionField(field, formFieldModel);
|
||||||
|
} else if (this.isContainerField(field)) {
|
||||||
this.handleContainerField(field, formFieldModel);
|
this.handleContainerField(field, formFieldModel);
|
||||||
} else if (this.isSectionField(field)) {
|
} else if (this.isSectionField(field)) {
|
||||||
this.handleSectionField(field, formFieldModel);
|
this.handleSectionField(field, formFieldModel);
|
||||||
@@ -377,6 +383,10 @@ export class FormModel implements ProcessFormModel {
|
|||||||
return field.type === FormFieldTypes.SECTION;
|
return field.type === FormFieldTypes.SECTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private isRepeatableSectionField(field: ContainerModel | FormFieldModel): field is ContainerModel {
|
||||||
|
return field.type === FormFieldTypes.REPEATABLE_SECTION;
|
||||||
|
}
|
||||||
|
|
||||||
private handleSectionField(section: FormFieldModel, formFieldModel: FormFieldModel[]): void {
|
private handleSectionField(section: FormFieldModel, formFieldModel: FormFieldModel[]): void {
|
||||||
formFieldModel.push(section);
|
formFieldModel.push(section);
|
||||||
section.columns.forEach((column) => {
|
section.columns.forEach((column) => {
|
||||||
@@ -384,6 +394,15 @@ export class FormModel implements ProcessFormModel {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private handleRepeatableSectionField(repeatableSection: ContainerModel, formFieldModel: FormFieldModel[]): void {
|
||||||
|
formFieldModel.push(repeatableSection.field);
|
||||||
|
for (const row of repeatableSection.field.rows) {
|
||||||
|
for (const column of row.columns) {
|
||||||
|
this.processFields(column.fields, formFieldModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private handleContainerField(container: ContainerModel, formFieldModel: FormFieldModel[]): void {
|
private handleContainerField(container: ContainerModel, formFieldModel: FormFieldModel[]): void {
|
||||||
formFieldModel.push(container.field);
|
formFieldModel.push(container.field);
|
||||||
container.field.columns.forEach((column) => {
|
container.field.columns.forEach((column) => {
|
||||||
|
|||||||
+2
-7
@@ -17,13 +17,8 @@
|
|||||||
|
|
||||||
import { formFieldRuleHandler } from './form-field-rule.handler';
|
import { formFieldRuleHandler } from './form-field-rule.handler';
|
||||||
import { FormFieldRule } from '../form-field-rule';
|
import { FormFieldRule } from '../form-field-rule';
|
||||||
import {
|
import { mockParentRule, mockRule } from '../mocks/form-field-rule.handler.mock';
|
||||||
mockParentRule,
|
import { mockParentWithoutFields, mockParentWithFields, mockParentWithSectionFields } from '../mocks/repeatable-section-model.mock';
|
||||||
mockParentWithFields,
|
|
||||||
mockParentWithoutFields,
|
|
||||||
mockParentWithSectionFields,
|
|
||||||
mockRule
|
|
||||||
} from '../mocks/form-field-rule.handler.mock';
|
|
||||||
|
|
||||||
describe('formFieldRuleHandler', () => {
|
describe('formFieldRuleHandler', () => {
|
||||||
it('should return null if provided rule is null', () => {
|
it('should return null if provided rule is null', () => {
|
||||||
|
|||||||
@@ -31,13 +31,7 @@ const getRuleOn = (id: string, ruleOn: string, fields: any): string => {
|
|||||||
for (const column of Object.values(fields)) {
|
for (const column of Object.values(fields)) {
|
||||||
for (const field of column as any) {
|
for (const field of column as any) {
|
||||||
if (field.type === FormFieldTypes.SECTION) {
|
if (field.type === FormFieldTypes.SECTION) {
|
||||||
for (const sectionColumn of Object.values(field.fields)) {
|
return getRuleOn(id, ruleOn, field.fields);
|
||||||
for (const sectionField of sectionColumn as any) {
|
|
||||||
if (sectionField.id === ruleOn) {
|
|
||||||
return getRepeatableSectionChildRuleOn(id, ruleOn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field.id === ruleOn) {
|
if (field.id === ruleOn) {
|
||||||
|
|||||||
+238
@@ -0,0 +1,238 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { formFieldVisibilityConditionHandler } from './form-field-visibility-condition.handler';
|
||||||
|
import { mockParentWithoutFields, mockParentWithFields, mockParentWithSectionFields } from '../mocks/repeatable-section-model.mock';
|
||||||
|
import {
|
||||||
|
mockParentVisibilityCondition,
|
||||||
|
mockParentVisibilityConditionWithLeftValue,
|
||||||
|
mockParentVisibilityConditionWithRightValue,
|
||||||
|
mockVisibilityCondition,
|
||||||
|
mockVisibilityConditionLeftValue,
|
||||||
|
mockVisibilityConditionRightValue
|
||||||
|
} from '../mocks/form-field-visibility-condition.handler.mock';
|
||||||
|
import { WidgetVisibilityModel } from '../../../../models/widget-visibility.model';
|
||||||
|
|
||||||
|
describe('formFieldVisibilityConditionHandler', () => {
|
||||||
|
it('should return undefined if provided visibility condition json is null', () => {
|
||||||
|
expect(formFieldVisibilityConditionHandler.getVisibilityCondition('mock-id', null)).toBe(undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return undefined if provided visibility condition json is undefined', () => {
|
||||||
|
expect(formFieldVisibilityConditionHandler.getVisibilityCondition('mock-id', undefined)).toBe(undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return provided visibility condition if json is provided and no parent is provided', () => {
|
||||||
|
const expectedVisibilityCondition = new WidgetVisibilityModel({
|
||||||
|
leftType: 'field',
|
||||||
|
leftValue: 'mock-left-value',
|
||||||
|
rightType: 'field',
|
||||||
|
rightValue: 'mock-right-value'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(formFieldVisibilityConditionHandler.getVisibilityCondition('mock-id', mockVisibilityCondition)).toEqual(expectedVisibilityCondition);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('rule and parent provided', () => {
|
||||||
|
describe('leftValue provided', () => {
|
||||||
|
it('should return provided visibility condition if parent has no fields', () => {
|
||||||
|
const expectedVisibilityCondition = new WidgetVisibilityModel({
|
||||||
|
leftType: 'field',
|
||||||
|
leftValue: 'mock-left-value'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(
|
||||||
|
formFieldVisibilityConditionHandler.getVisibilityCondition(
|
||||||
|
'mock-id-Row123456789',
|
||||||
|
mockVisibilityConditionLeftValue,
|
||||||
|
mockParentWithoutFields
|
||||||
|
)
|
||||||
|
).toEqual(expectedVisibilityCondition);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return provided visibility condition if leftValue does not belong to parent fields', () => {
|
||||||
|
const expectedVisibilityCondition = new WidgetVisibilityModel({
|
||||||
|
leftType: 'field',
|
||||||
|
leftValue: 'mock-left-value'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(
|
||||||
|
formFieldVisibilityConditionHandler.getVisibilityCondition(
|
||||||
|
'mock-id-Row123456789',
|
||||||
|
mockVisibilityConditionLeftValue,
|
||||||
|
mockParentWithFields
|
||||||
|
)
|
||||||
|
).toEqual(expectedVisibilityCondition);
|
||||||
|
});
|
||||||
|
it('should return visibility condition with parent leftValue property if leftValue belongs to parent fields', () => {
|
||||||
|
const expectedVisibilityCondition = new WidgetVisibilityModel({
|
||||||
|
leftType: 'field',
|
||||||
|
leftValue: 'Text0c0ydk-Row123456789'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(
|
||||||
|
formFieldVisibilityConditionHandler.getVisibilityCondition(
|
||||||
|
'mock-id-Row123456789',
|
||||||
|
mockParentVisibilityConditionWithLeftValue,
|
||||||
|
mockParentWithFields
|
||||||
|
)
|
||||||
|
).toEqual(expectedVisibilityCondition);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return visibility condition with parent leftValue property if leftValue belongs to parent fields and sections are present', () => {
|
||||||
|
const expectedVisibilityCondition = new WidgetVisibilityModel({
|
||||||
|
leftType: 'field',
|
||||||
|
leftValue: 'Text0c0ydk-Row123456789'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(
|
||||||
|
formFieldVisibilityConditionHandler.getVisibilityCondition(
|
||||||
|
'mock-id-Row123456789',
|
||||||
|
mockParentVisibilityConditionWithLeftValue,
|
||||||
|
mockParentWithSectionFields
|
||||||
|
)
|
||||||
|
).toEqual(expectedVisibilityCondition);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('rightValue provided', () => {
|
||||||
|
it('should return provided visibility condition if parent has no fields', () => {
|
||||||
|
const expectedVisibilityCondition = new WidgetVisibilityModel({
|
||||||
|
rightType: 'field',
|
||||||
|
rightValue: 'mock-right-value'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(
|
||||||
|
formFieldVisibilityConditionHandler.getVisibilityCondition(
|
||||||
|
'mock-id-Row123456789',
|
||||||
|
mockVisibilityConditionRightValue,
|
||||||
|
mockParentWithoutFields
|
||||||
|
)
|
||||||
|
).toEqual(expectedVisibilityCondition);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return provided visibility condition if rightValue does not belong to parent fields', () => {
|
||||||
|
const expectedVisibilityCondition = new WidgetVisibilityModel({
|
||||||
|
rightType: 'field',
|
||||||
|
rightValue: 'mock-right-value'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(
|
||||||
|
formFieldVisibilityConditionHandler.getVisibilityCondition(
|
||||||
|
'mock-id-Row123456789',
|
||||||
|
mockVisibilityConditionRightValue,
|
||||||
|
mockParentWithFields
|
||||||
|
)
|
||||||
|
).toEqual(expectedVisibilityCondition);
|
||||||
|
});
|
||||||
|
it('should return visibility condition with parent rightValue property if rightValue belongs to parent fields', () => {
|
||||||
|
const expectedVisibilityCondition = new WidgetVisibilityModel({
|
||||||
|
rightType: 'field',
|
||||||
|
rightValue: 'Text0c0ydk-Row123456789'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(
|
||||||
|
formFieldVisibilityConditionHandler.getVisibilityCondition(
|
||||||
|
'mock-id-Row123456789',
|
||||||
|
mockParentVisibilityConditionWithRightValue,
|
||||||
|
mockParentWithFields
|
||||||
|
)
|
||||||
|
).toEqual(expectedVisibilityCondition);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return visibility condition with parent rightValue property if rightValue belongs to parent fields and sections are present', () => {
|
||||||
|
const expectedVisibilityCondition = new WidgetVisibilityModel({
|
||||||
|
rightType: 'field',
|
||||||
|
rightValue: 'Text0c0ydk-Row123456789'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(
|
||||||
|
formFieldVisibilityConditionHandler.getVisibilityCondition(
|
||||||
|
'mock-id-Row123456789',
|
||||||
|
mockParentVisibilityConditionWithRightValue,
|
||||||
|
mockParentWithSectionFields
|
||||||
|
)
|
||||||
|
).toEqual(expectedVisibilityCondition);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('leftValue and rightValue provided', () => {
|
||||||
|
it('should return provided visibility condition if parent has no fields', () => {
|
||||||
|
const expectedVisibilityCondition = new WidgetVisibilityModel({
|
||||||
|
leftType: 'field',
|
||||||
|
leftValue: 'mock-left-value',
|
||||||
|
rightType: 'field',
|
||||||
|
rightValue: 'mock-right-value'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(
|
||||||
|
formFieldVisibilityConditionHandler.getVisibilityCondition(
|
||||||
|
'mock-id-Row123456789',
|
||||||
|
mockVisibilityCondition,
|
||||||
|
mockParentWithoutFields
|
||||||
|
)
|
||||||
|
).toEqual(expectedVisibilityCondition);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return provided visibility condition if leftValue and rightValue do not belong to parent fields', () => {
|
||||||
|
const expectedVisibilityCondition = new WidgetVisibilityModel({
|
||||||
|
leftType: 'field',
|
||||||
|
leftValue: 'mock-left-value',
|
||||||
|
rightType: 'field',
|
||||||
|
rightValue: 'mock-right-value'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(
|
||||||
|
formFieldVisibilityConditionHandler.getVisibilityCondition('mock-id-Row123456789', mockVisibilityCondition, mockParentWithFields)
|
||||||
|
).toEqual(expectedVisibilityCondition);
|
||||||
|
});
|
||||||
|
it('should return visibility condition with parent leftValue and rightValue property if values belong to parent fields', () => {
|
||||||
|
const expectedVisibilityCondition = new WidgetVisibilityModel({
|
||||||
|
leftType: 'field',
|
||||||
|
leftValue: 'Text0c0ydk-Row123456789',
|
||||||
|
rightType: 'field',
|
||||||
|
rightValue: 'Text0c26k4-Row123456789'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(
|
||||||
|
formFieldVisibilityConditionHandler.getVisibilityCondition(
|
||||||
|
'mock-id-Row123456789',
|
||||||
|
mockParentVisibilityCondition,
|
||||||
|
mockParentWithFields
|
||||||
|
)
|
||||||
|
).toEqual(expectedVisibilityCondition);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return visibility condition with parent leftValue and rightValue property if values belong to parent fields and sections are present', () => {
|
||||||
|
const expectedVisibilityCondition = new WidgetVisibilityModel({
|
||||||
|
leftType: 'field',
|
||||||
|
leftValue: 'Text0c0ydk-Row123456789',
|
||||||
|
rightType: 'field',
|
||||||
|
rightValue: 'Text0c26k4-Row123456789'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(
|
||||||
|
formFieldVisibilityConditionHandler.getVisibilityCondition(
|
||||||
|
'mock-id-Row123456789',
|
||||||
|
mockParentVisibilityCondition,
|
||||||
|
mockParentWithSectionFields
|
||||||
|
)
|
||||||
|
).toEqual(expectedVisibilityCondition);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
+70
@@ -0,0 +1,70 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { RepeatableSectionModel, ROW_ID_PREFIX } from '../repeatable-section.model';
|
||||||
|
import { WidgetTypeEnum, WidgetVisibilityModel } from '../../../../models/widget-visibility.model';
|
||||||
|
import { FormFieldTypes } from '../form-field-types';
|
||||||
|
|
||||||
|
const getVisibilityCondition = (id: string, json?: any, parent?: RepeatableSectionModel): WidgetVisibilityModel | undefined => {
|
||||||
|
if (!json) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new WidgetVisibilityModel(
|
||||||
|
parent?.fields
|
||||||
|
? {
|
||||||
|
...json,
|
||||||
|
...(shouldUpdateValue(json.leftType, json.leftValue) && {
|
||||||
|
leftValue: getValue(id, json.leftValue, parent.fields)
|
||||||
|
}),
|
||||||
|
...(shouldUpdateValue(json.rightType, json.rightValue) && {
|
||||||
|
rightValue: getValue(id, json.rightValue, parent.fields)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
: json
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const shouldUpdateValue = (type: WidgetTypeEnum, value: string): boolean => type === WidgetTypeEnum.field && !!value;
|
||||||
|
|
||||||
|
const getValue = (id: string, value: string, fields: any): string => {
|
||||||
|
for (const column of Object.values(fields)) {
|
||||||
|
for (const field of column as any) {
|
||||||
|
if (field.type === FormFieldTypes.SECTION) {
|
||||||
|
return getValue(id, value, field.fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (field.id === value) {
|
||||||
|
return getRepeatableSectionChildValue(id, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getRepeatableSectionChildValue = (id: string, value: string): string => value + ROW_ID_PREFIX + getRowId(id);
|
||||||
|
|
||||||
|
const getRowId = (id: string) => {
|
||||||
|
const split = id.split(ROW_ID_PREFIX);
|
||||||
|
|
||||||
|
return split.length > 1 ? split[1] : '';
|
||||||
|
};
|
||||||
|
|
||||||
|
export const formFieldVisibilityConditionHandler = {
|
||||||
|
getVisibilityCondition
|
||||||
|
};
|
||||||
@@ -48,3 +48,4 @@ export * from './widget-schema.model';
|
|||||||
export * from './theme.model';
|
export * from './theme.model';
|
||||||
export * from './predefined-theme';
|
export * from './predefined-theme';
|
||||||
export * from './displayable-cm-properties.model';
|
export * from './displayable-cm-properties.model';
|
||||||
|
export * from './repeatable-section.model';
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { FormFieldRule } from '../form-field-rule';
|
import { FormFieldRule } from '../form-field-rule';
|
||||||
import { RepeatableSectionModel } from '../repeatable-section.model';
|
|
||||||
|
|
||||||
export const mockRule: FormFieldRule = {
|
export const mockRule: FormFieldRule = {
|
||||||
ruleOn: 'mock-rule-on',
|
ruleOn: 'mock-rule-on',
|
||||||
@@ -27,135 +26,3 @@ export const mockParentRule: FormFieldRule = {
|
|||||||
ruleOn: 'Text0c0ydk',
|
ruleOn: 'Text0c0ydk',
|
||||||
entries: []
|
entries: []
|
||||||
};
|
};
|
||||||
|
|
||||||
export const mockParentWithoutFields: RepeatableSectionModel = {
|
|
||||||
id: 'mock-parent-id',
|
|
||||||
uid: 'mock-id-Row123456789',
|
|
||||||
fields: {},
|
|
||||||
rowIndex: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
export const mockParentWithFields: RepeatableSectionModel = {
|
|
||||||
id: 'mock-parent-id',
|
|
||||||
uid: 'mock-id-Row123456789',
|
|
||||||
fields: {
|
|
||||||
'1': [
|
|
||||||
{
|
|
||||||
id: 'Text0c0ydk',
|
|
||||||
name: 'Text',
|
|
||||||
type: 'text',
|
|
||||||
readOnly: false,
|
|
||||||
required: false,
|
|
||||||
colspan: 1,
|
|
||||||
rowspan: 1,
|
|
||||||
placeholder: null,
|
|
||||||
minLength: 0,
|
|
||||||
maxLength: 0,
|
|
||||||
regexPattern: null,
|
|
||||||
visibilityCondition: null,
|
|
||||||
params: {
|
|
||||||
existingColspan: 1,
|
|
||||||
maxColspan: 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
'2': [
|
|
||||||
{
|
|
||||||
id: 'Text0c26k4',
|
|
||||||
name: 'Text',
|
|
||||||
type: 'text',
|
|
||||||
readOnly: false,
|
|
||||||
required: false,
|
|
||||||
colspan: 1,
|
|
||||||
rowspan: 1,
|
|
||||||
placeholder: null,
|
|
||||||
minLength: 0,
|
|
||||||
maxLength: 0,
|
|
||||||
regexPattern: null,
|
|
||||||
visibilityCondition: null,
|
|
||||||
params: {
|
|
||||||
existingColspan: 1,
|
|
||||||
maxColspan: 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
rowIndex: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
export const mockParentWithSectionFields: RepeatableSectionModel = {
|
|
||||||
id: 'mock-parent-id',
|
|
||||||
uid: 'mock-id-Row123456789',
|
|
||||||
fields: {
|
|
||||||
'1': [
|
|
||||||
{
|
|
||||||
id: 'd376200a-7d22-4b36-bbcd-b5f11a462b3e',
|
|
||||||
name: 'Section',
|
|
||||||
type: 'section',
|
|
||||||
numberOfColumns: 2,
|
|
||||||
fields: {
|
|
||||||
'1': [
|
|
||||||
{
|
|
||||||
id: 'Text0c0ydk',
|
|
||||||
name: 'Text',
|
|
||||||
type: 'text',
|
|
||||||
readOnly: false,
|
|
||||||
required: false,
|
|
||||||
colspan: 1,
|
|
||||||
rowspan: 1,
|
|
||||||
placeholder: null,
|
|
||||||
minLength: 0,
|
|
||||||
maxLength: 0,
|
|
||||||
regexPattern: null,
|
|
||||||
visibilityCondition: null,
|
|
||||||
params: {
|
|
||||||
existingColspan: 1,
|
|
||||||
maxColspan: 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
'2': [
|
|
||||||
{
|
|
||||||
id: 'Text0c26k4',
|
|
||||||
name: 'Text',
|
|
||||||
type: 'text',
|
|
||||||
readOnly: false,
|
|
||||||
required: false,
|
|
||||||
colspan: 1,
|
|
||||||
rowspan: 1,
|
|
||||||
placeholder: null,
|
|
||||||
minLength: 0,
|
|
||||||
maxLength: 0,
|
|
||||||
regexPattern: null,
|
|
||||||
visibilityCondition: null,
|
|
||||||
params: {
|
|
||||||
existingColspan: 1,
|
|
||||||
maxColspan: 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
colspan: 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'Text08wpzg',
|
|
||||||
name: 'Text',
|
|
||||||
type: 'text',
|
|
||||||
readOnly: false,
|
|
||||||
required: false,
|
|
||||||
colspan: 1,
|
|
||||||
rowspan: 1,
|
|
||||||
placeholder: null,
|
|
||||||
minLength: 0,
|
|
||||||
maxLength: 0,
|
|
||||||
regexPattern: null,
|
|
||||||
visibilityCondition: null,
|
|
||||||
params: {
|
|
||||||
existingColspan: 1,
|
|
||||||
maxColspan: 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
rowIndex: 0
|
|
||||||
};
|
|
||||||
|
|||||||
+50
@@ -0,0 +1,50 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||||
|
*
|
||||||
|
* 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 const mockVisibilityCondition = {
|
||||||
|
leftType: 'field',
|
||||||
|
leftValue: 'mock-left-value',
|
||||||
|
rightType: 'field',
|
||||||
|
rightValue: 'mock-right-value'
|
||||||
|
};
|
||||||
|
|
||||||
|
export const mockVisibilityConditionLeftValue = {
|
||||||
|
leftType: 'field',
|
||||||
|
leftValue: 'mock-left-value'
|
||||||
|
};
|
||||||
|
|
||||||
|
export const mockVisibilityConditionRightValue = {
|
||||||
|
rightType: 'field',
|
||||||
|
rightValue: 'mock-right-value'
|
||||||
|
};
|
||||||
|
|
||||||
|
export const mockParentVisibilityConditionWithLeftValue = {
|
||||||
|
leftType: 'field',
|
||||||
|
leftValue: 'Text0c0ydk'
|
||||||
|
};
|
||||||
|
|
||||||
|
export const mockParentVisibilityConditionWithRightValue = {
|
||||||
|
rightType: 'field',
|
||||||
|
rightValue: 'Text0c0ydk'
|
||||||
|
};
|
||||||
|
|
||||||
|
export const mockParentVisibilityCondition = {
|
||||||
|
leftType: 'field',
|
||||||
|
leftValue: 'Text0c0ydk',
|
||||||
|
rightType: 'field',
|
||||||
|
rightValue: 'Text0c26k4'
|
||||||
|
};
|
||||||
@@ -0,0 +1,150 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { RepeatableSectionModel } from '../repeatable-section.model';
|
||||||
|
|
||||||
|
export const mockParentWithoutFields: RepeatableSectionModel = {
|
||||||
|
id: 'mock-parent-id',
|
||||||
|
uid: 'mock-id-Row123456789',
|
||||||
|
fields: {},
|
||||||
|
rowIndex: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
export const mockParentWithFields: RepeatableSectionModel = {
|
||||||
|
id: 'mock-parent-id',
|
||||||
|
uid: 'mock-id-Row123456789',
|
||||||
|
fields: {
|
||||||
|
'1': [
|
||||||
|
{
|
||||||
|
id: 'Text0c0ydk',
|
||||||
|
name: 'Text',
|
||||||
|
type: 'text',
|
||||||
|
readOnly: false,
|
||||||
|
required: false,
|
||||||
|
colspan: 1,
|
||||||
|
rowspan: 1,
|
||||||
|
placeholder: null,
|
||||||
|
minLength: 0,
|
||||||
|
maxLength: 0,
|
||||||
|
regexPattern: null,
|
||||||
|
visibilityCondition: null,
|
||||||
|
params: {
|
||||||
|
existingColspan: 1,
|
||||||
|
maxColspan: 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'2': [
|
||||||
|
{
|
||||||
|
id: 'Text0c26k4',
|
||||||
|
name: 'Text',
|
||||||
|
type: 'text',
|
||||||
|
readOnly: false,
|
||||||
|
required: false,
|
||||||
|
colspan: 1,
|
||||||
|
rowspan: 1,
|
||||||
|
placeholder: null,
|
||||||
|
minLength: 0,
|
||||||
|
maxLength: 0,
|
||||||
|
regexPattern: null,
|
||||||
|
visibilityCondition: null,
|
||||||
|
params: {
|
||||||
|
existingColspan: 1,
|
||||||
|
maxColspan: 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
rowIndex: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
export const mockParentWithSectionFields: RepeatableSectionModel = {
|
||||||
|
id: 'mock-parent-id',
|
||||||
|
uid: 'mock-id-Row123456789',
|
||||||
|
fields: {
|
||||||
|
'1': [
|
||||||
|
{
|
||||||
|
id: 'd376200a-7d22-4b36-bbcd-b5f11a462b3e',
|
||||||
|
name: 'Section',
|
||||||
|
type: 'section',
|
||||||
|
numberOfColumns: 2,
|
||||||
|
fields: {
|
||||||
|
'1': [
|
||||||
|
{
|
||||||
|
id: 'Text0c0ydk',
|
||||||
|
name: 'Text',
|
||||||
|
type: 'text',
|
||||||
|
readOnly: false,
|
||||||
|
required: false,
|
||||||
|
colspan: 1,
|
||||||
|
rowspan: 1,
|
||||||
|
placeholder: null,
|
||||||
|
minLength: 0,
|
||||||
|
maxLength: 0,
|
||||||
|
regexPattern: null,
|
||||||
|
visibilityCondition: null,
|
||||||
|
params: {
|
||||||
|
existingColspan: 1,
|
||||||
|
maxColspan: 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'2': [
|
||||||
|
{
|
||||||
|
id: 'Text0c26k4',
|
||||||
|
name: 'Text',
|
||||||
|
type: 'text',
|
||||||
|
readOnly: false,
|
||||||
|
required: false,
|
||||||
|
colspan: 1,
|
||||||
|
rowspan: 1,
|
||||||
|
placeholder: null,
|
||||||
|
minLength: 0,
|
||||||
|
maxLength: 0,
|
||||||
|
regexPattern: null,
|
||||||
|
visibilityCondition: null,
|
||||||
|
params: {
|
||||||
|
existingColspan: 1,
|
||||||
|
maxColspan: 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
colspan: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'Text08wpzg',
|
||||||
|
name: 'Text',
|
||||||
|
type: 'text',
|
||||||
|
readOnly: false,
|
||||||
|
required: false,
|
||||||
|
colspan: 1,
|
||||||
|
rowspan: 1,
|
||||||
|
placeholder: null,
|
||||||
|
minLength: 0,
|
||||||
|
maxLength: 0,
|
||||||
|
regexPattern: null,
|
||||||
|
visibilityCondition: null,
|
||||||
|
params: {
|
||||||
|
existingColspan: 1,
|
||||||
|
maxColspan: 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
rowIndex: 0
|
||||||
|
};
|
||||||
@@ -34,7 +34,7 @@ describe('RepeatWidgetComponent', () => {
|
|||||||
* @param allowInitialRowsDelete should allow deleting rows
|
* @param allowInitialRowsDelete should allow deleting rows
|
||||||
* @returns repeatable section json based on params
|
* @returns repeatable section json based on params
|
||||||
*/
|
*/
|
||||||
function getFormFieldJson(initialNumberOfRows: number = 2, maxNumberOfRows?: number, allowInitialRowsDelete: boolean = true) {
|
function getFormFieldJson(initialNumberOfRows: number = 2, maxNumberOfRows: number | null = null, allowInitialRowsDelete: boolean = true) {
|
||||||
return {
|
return {
|
||||||
id: 'RepeatableSection0tbw2y',
|
id: 'RepeatableSection0tbw2y',
|
||||||
name: 'Repeatable Section',
|
name: 'Repeatable Section',
|
||||||
|
|||||||
@@ -1836,3 +1836,129 @@ export const tabInvalidFormVisibility: any = {
|
|||||||
variables: []
|
variables: []
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const repeatableSectionFormVisibility: any = {
|
||||||
|
id: 'orm-875b6fe8-a84d-475b-a7e1-a3647955a0a6',
|
||||||
|
name: 'repeatable-section',
|
||||||
|
description: '',
|
||||||
|
version: 0,
|
||||||
|
tabs: [],
|
||||||
|
formDefinition: {
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
id: 'RepeatableSection0009v6',
|
||||||
|
name: 'Repeatable Section',
|
||||||
|
type: 'repeatable-section',
|
||||||
|
tab: null,
|
||||||
|
params: {
|
||||||
|
initialNumberOfRows: 1,
|
||||||
|
allowInitialRowsDelete: true,
|
||||||
|
maxNumberOfRows: null
|
||||||
|
},
|
||||||
|
numberOfColumns: 2,
|
||||||
|
fields: {
|
||||||
|
'1': [
|
||||||
|
{
|
||||||
|
id: 'text1',
|
||||||
|
name: 'Text',
|
||||||
|
type: 'text',
|
||||||
|
readOnly: false,
|
||||||
|
required: false,
|
||||||
|
colspan: 1,
|
||||||
|
rowspan: 1,
|
||||||
|
placeholder: null,
|
||||||
|
minLength: 0,
|
||||||
|
maxLength: 0,
|
||||||
|
regexPattern: null,
|
||||||
|
visibilityCondition: null,
|
||||||
|
params: {
|
||||||
|
existingColspan: 1,
|
||||||
|
maxColspan: 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'2': [
|
||||||
|
{
|
||||||
|
id: 'text2',
|
||||||
|
name: 'Text',
|
||||||
|
type: 'text',
|
||||||
|
readOnly: false,
|
||||||
|
required: false,
|
||||||
|
colspan: 1,
|
||||||
|
rowspan: 1,
|
||||||
|
placeholder: null,
|
||||||
|
minLength: 0,
|
||||||
|
maxLength: 0,
|
||||||
|
regexPattern: null,
|
||||||
|
visibilityCondition: {
|
||||||
|
leftType: 'field',
|
||||||
|
leftValue: 'text4',
|
||||||
|
operator: '!empty',
|
||||||
|
rightValue: null,
|
||||||
|
rightType: null,
|
||||||
|
nextConditionOperator: '',
|
||||||
|
nextCondition: null
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
existingColspan: 1,
|
||||||
|
maxColspan: 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '5a3474a8-22e1-4408-8a43-2eb1fc8300ac',
|
||||||
|
name: 'Section',
|
||||||
|
tab: null,
|
||||||
|
type: 'section',
|
||||||
|
numberOfColumns: 2,
|
||||||
|
fields: {
|
||||||
|
'1': [
|
||||||
|
{
|
||||||
|
id: 'text3',
|
||||||
|
name: 'Text',
|
||||||
|
type: 'text',
|
||||||
|
readOnly: false,
|
||||||
|
required: false,
|
||||||
|
colspan: 1,
|
||||||
|
rowspan: 1,
|
||||||
|
placeholder: null,
|
||||||
|
minLength: 0,
|
||||||
|
maxLength: 0,
|
||||||
|
regexPattern: null,
|
||||||
|
visibilityCondition: null,
|
||||||
|
params: {
|
||||||
|
existingColspan: 1,
|
||||||
|
maxColspan: 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'2': [
|
||||||
|
{
|
||||||
|
id: 'text4',
|
||||||
|
name: 'Text',
|
||||||
|
type: 'text',
|
||||||
|
readOnly: false,
|
||||||
|
required: false,
|
||||||
|
colspan: 1,
|
||||||
|
rowspan: 1,
|
||||||
|
placeholder: null,
|
||||||
|
minLength: 0,
|
||||||
|
maxLength: 0,
|
||||||
|
regexPattern: null,
|
||||||
|
visibilityCondition: null,
|
||||||
|
params: {
|
||||||
|
existingColspan: 1,
|
||||||
|
maxColspan: 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
outcomes: [],
|
||||||
|
metadata: {},
|
||||||
|
variables: []
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user