AAE-39988 Dropdown conditional not working for repeatable section (#11360)

* AAE-39988 Conditional dropdown working for repeatable sections

* AAE-39988 Update test
This commit is contained in:
Diogo Bastos
2025-11-25 12:37:54 +00:00
committed by GitHub
parent e87c33dcae
commit 3031ec1f66
4 changed files with 229 additions and 34 deletions

View File

@@ -17,7 +17,13 @@
import { formFieldRuleHandler } from './form-field-rule.handler';
import { FormFieldRule } from '../form-field-rule';
import { RepeatableSectionModel } from '../repeatable-section.model';
import {
mockParentRule,
mockParentWithFields,
mockParentWithoutFields,
mockParentWithSectionFields,
mockRule
} from '../mocks/form-field-rule.handler.mock';
describe('formFieldRuleHandler', () => {
it('should return null if provided rule is null', () => {
@@ -28,42 +34,49 @@ describe('formFieldRuleHandler', () => {
expect(formFieldRuleHandler.getRule('mock-id', undefined)).toBe(undefined);
});
it('should return provided rule if rule is provided', () => {
const rule: FormFieldRule = {
ruleOn: 'mock-rule-on',
entries: []
};
expect(formFieldRuleHandler.getRule('mock-id', rule)).toEqual(rule);
});
it('should return provided rule if rule is provided and no parent is provided', () => {
const rule: FormFieldRule = {
const expectedRule: FormFieldRule = {
ruleOn: 'mock-rule-on',
entries: []
};
expect(formFieldRuleHandler.getRule('mock-id', rule)).toEqual(rule);
expect(formFieldRuleHandler.getRule('mock-id', mockRule)).toEqual(expectedRule);
});
it('should return rule with parent ruleOn property if rule and parent are provided', () => {
const rule: FormFieldRule = {
ruleOn: 'mock-rule-on',
entries: []
};
describe('rule and parent provided', () => {
it('should return provided rule if parent has no fields', () => {
const expectedRule: FormFieldRule = {
ruleOn: 'mock-rule-on',
entries: []
};
const parent: RepeatableSectionModel = {
id: 'mock-parent-id',
uid: 'mock-id-Row123456789',
fields: [],
rowIndex: 0
};
expect(formFieldRuleHandler.getRule('mock-id-Row123456789', mockRule, mockParentWithoutFields)).toEqual(expectedRule);
});
it('should return provided rule if ruleOn does not belong to parent fields', () => {
const expectedRule: FormFieldRule = {
ruleOn: 'mock-rule-on',
entries: []
};
const expectedRule: FormFieldRule = {
ruleOn: 'mock-rule-on-Row123456789',
entries: []
};
expect(formFieldRuleHandler.getRule('mock-id-Row123456789', mockRule, mockParentWithFields)).toEqual(expectedRule);
});
expect(formFieldRuleHandler.getRule('mock-id-Row123456789', rule, parent)).toEqual(expectedRule);
it('should return rule with parent ruleOn property if ruleOn belongs to parent fields', () => {
const expectedRule: FormFieldRule = {
ruleOn: 'Text0c0ydk-Row123456789',
entries: []
};
expect(formFieldRuleHandler.getRule('mock-id-Row123456789', mockParentRule, mockParentWithFields)).toEqual(expectedRule);
});
it('should return rule with parent ruleOn property if ruleOn belongs to parent fields and sections are present', () => {
const expectedRule: FormFieldRule = {
ruleOn: 'Text0c0ydk-Row123456789',
entries: []
};
expect(formFieldRuleHandler.getRule('mock-id-Row123456789', mockParentRule, mockParentWithSectionFields)).toEqual(expectedRule);
});
});
});

View File

@@ -16,19 +16,42 @@
*/
import { FormFieldRule } from '../form-field-rule';
import { FormFieldTypes } from '../form-field-types';
import { RepeatableSectionModel, ROW_ID_PREFIX } from '../repeatable-section.model';
const getRule = (id: string, rule?: FormFieldRule, parent?: RepeatableSectionModel): FormFieldRule =>
rule && parent
rule?.ruleOn && parent?.fields
? ({
...rule,
ruleOn: getRepeatableSectionChildRuleOn(id, rule.ruleOn ?? '')
ruleOn: getRuleOn(id, rule.ruleOn, parent.fields)
} as FormFieldRule)
: rule;
const getRuleOn = (id: string, ruleOn: string, fields: any): string => {
for (const column of Object.values(fields)) {
for (const field of column as any) {
if (field.type === FormFieldTypes.SECTION) {
for (const sectionColumn of Object.values(field.fields)) {
for (const sectionField of sectionColumn as any) {
if (sectionField.id === ruleOn) {
return getRepeatableSectionChildRuleOn(id, ruleOn);
}
}
}
}
if (field.id === ruleOn) {
return getRepeatableSectionChildRuleOn(id, ruleOn);
}
}
}
return ruleOn;
};
const getRepeatableSectionChildRuleOn = (id: string, ruleOn: string): string => ruleOn + ROW_ID_PREFIX + getRowId(id);
const getRowId = (id: string) => {
const getRowId = (id: string): string => {
const split = id.split(ROW_ID_PREFIX);
return split.length > 1 ? split[1] : '';

View File

@@ -0,0 +1,161 @@
/*!
* @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 { FormFieldRule } from '../form-field-rule';
import { RepeatableSectionModel } from '../repeatable-section.model';
export const mockRule: FormFieldRule = {
ruleOn: 'mock-rule-on',
entries: []
};
export const mockParentRule: FormFieldRule = {
ruleOn: 'Text0c0ydk',
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
};

View File

@@ -15,14 +15,12 @@
* limitations under the License.
*/
import { FormFieldModel } from './form-field.model';
export const ROW_ID_PREFIX = '-Row';
export interface RepeatableSectionModel {
id: string;
uid: string;
fields: FormFieldModel[];
fields: any;
rowIndex: number;
value?: any;
}