diff --git a/packages/core/src/data_sources/model/conditional_variables/ComponentDataCondition.ts b/packages/core/src/data_sources/model/conditional_variables/ComponentDataCondition.ts index d153f61a0..131ac859f 100644 --- a/packages/core/src/data_sources/model/conditional_variables/ComponentDataCondition.ts +++ b/packages/core/src/data_sources/model/conditional_variables/ComponentDataCondition.ts @@ -2,6 +2,7 @@ import Component from '../../../dom_components/model/Component'; import { ComponentDefinition, ComponentOptions } from '../../../dom_components/model/types'; import { toLowerCase } from '../../../utils/mixins'; import { DataCondition, DataConditionProps, DataConditionType } from './DataCondition'; +import { ConditionProps } from './DataConditionEvaluator'; export default class ComponentDataCondition extends Component { dataResolver: DataCondition; @@ -21,6 +22,18 @@ export default class ComponentDataCondition extends Component { this.dataResolver.onValueChange = this.handleConditionChange.bind(this); } + getCondition() { + return this.dataResolver.getCondition(); + } + + getIfTrue() { + return this.dataResolver.getIfTrue(); + } + + getIfFalse() { + return this.dataResolver.getIfFalse(); + } + private handleConditionChange() { this.components(this.dataResolver.getDataValue()); } @@ -29,6 +42,18 @@ export default class ComponentDataCondition extends Component { return toLowerCase(el.tagName) === DataConditionType; } + setCondition(newCondition: ConditionProps) { + this.dataResolver.setCondition(newCondition); + } + + setIfTrue(newIfTrue: any) { + this.dataResolver.setIfTrue(newIfTrue); + } + + setIfFalse(newIfFalse: any) { + this.dataResolver.setIfFalse(newIfFalse); + } + toJSON(): ComponentDefinition { return this.dataResolver.toJSON(); } diff --git a/packages/core/src/data_sources/model/conditional_variables/DataCondition.ts b/packages/core/src/data_sources/model/conditional_variables/DataCondition.ts index 427a30a87..fc72ef2f0 100644 --- a/packages/core/src/data_sources/model/conditional_variables/DataCondition.ts +++ b/packages/core/src/data_sources/model/conditional_variables/DataCondition.ts @@ -68,25 +68,29 @@ export class DataCondition extends Model { }); } - get condition() { + private get conditionEvaluator() { return this.get('condition')!; } - get ifTrue() { + getCondition(): ConditionProps { + return this.get('condition')?.get('condition')!; + } + + getIfTrue() { return this.get('ifTrue')!; } - get ifFalse() { + getIfFalse() { return this.get('ifFalse')!; } isTrue(): boolean { - return this.condition.evaluate(); + return this.conditionEvaluator.evaluate(); } getDataValue(skipDynamicValueResolution: boolean = false): any { - const ifTrue = this.ifTrue; - const ifFalse = this.ifFalse; + const ifTrue = this.get('ifTrue'); + const ifFalse = this.get('ifFalse'); const isConditionTrue = this.isTrue(); if (skipDynamicValueResolution) { @@ -136,7 +140,7 @@ export class DataCondition extends Model { } getDependentDataVariables() { - const dataVariables: DataVariableProps[] = this.condition.getDependentDataVariables(); + const dataVariables: DataVariableProps[] = this.conditionEvaluator.getDependentDataVariables(); const ifTrue = this.get('ifTrue'); const ifFalse = this.get('ifFalse'); if (isDataVariable(ifTrue)) dataVariables.push(ifTrue); @@ -156,7 +160,7 @@ export class DataCondition extends Model { return { type: DataConditionType, - condition: this.condition, + condition: this.conditionEvaluator, ifTrue, ifFalse, }; diff --git a/packages/core/test/specs/data_sources/model/conditional_variables/ComponentDataCondition.setters.ts b/packages/core/test/specs/data_sources/model/conditional_variables/ComponentDataCondition.setters.ts new file mode 100644 index 000000000..96eab39ff --- /dev/null +++ b/packages/core/test/specs/data_sources/model/conditional_variables/ComponentDataCondition.setters.ts @@ -0,0 +1,156 @@ +import { Component, DataSourceManager, Editor } from '../../../../../src'; +import { DataVariableType } from '../../../../../src/data_sources/model/DataVariable'; +import ComponentDataCondition from '../../../../../src/data_sources/model/conditional_variables/ComponentDataCondition'; +import { DataConditionType } from '../../../../../src/data_sources/model/conditional_variables/DataCondition'; +import { AnyTypeOperation } from '../../../../../src/data_sources/model/conditional_variables/operators/AnyTypeOperator'; +import { NumberOperation } from '../../../../../src/data_sources/model/conditional_variables/operators/NumberOperator'; +import ComponentDataConditionView from '../../../../../src/data_sources/view/ComponentDataConditionView'; +import ComponentWrapper from '../../../../../src/dom_components/model/ComponentWrapper'; +import EditorModel from '../../../../../src/editor/model/Editor'; +import { setupTestEditor } from '../../../../common'; + +describe('ComponentDataCondition Setters', () => { + let editor: Editor; + let em: EditorModel; + let dsm: DataSourceManager; + let cmpRoot: ComponentWrapper; + + beforeEach(() => { + ({ editor, em, dsm, cmpRoot } = setupTestEditor()); + }); + + afterEach(() => { + em.destroy(); + }); + + it('should update the condition using setCondition', () => { + const component = cmpRoot.append({ + type: DataConditionType, + condition: { + left: 0, + operator: NumberOperation.greaterThan, + right: -1, + }, + ifTrue: '

some text

', + ifFalse: '

false text

', + })[0] as ComponentDataCondition; + + const newCondition = { + left: 1, + operator: NumberOperation.lessThan, + right: 0, + }; + + component.setCondition(newCondition); + expect(component.getCondition()).toEqual(newCondition); + expect(component.getInnerHTML()).toBe('

false text

'); + }); + + it('should update the ifTrue value using setIfTrue', () => { + const component = cmpRoot.append({ + type: DataConditionType, + condition: { + left: 0, + operator: NumberOperation.greaterThan, + right: -1, + }, + ifTrue: '

some text

', + ifFalse: '

false text

', + })[0] as ComponentDataCondition; + + const newIfTrue = '

new true text

'; + component.setIfTrue(newIfTrue); + expect(component.getIfTrue()).toEqual(newIfTrue); + expect(component.getInnerHTML()).toBe(newIfTrue); + }); + + it('should update the ifFalse value using setIfFalse', () => { + const component = cmpRoot.append({ + type: DataConditionType, + condition: { + left: 0, + operator: NumberOperation.greaterThan, + right: -1, + }, + ifTrue: '

some text

', + ifFalse: '

false text

', + })[0] as ComponentDataCondition; + + const newIfFalse = '

new false text

'; + component.setIfFalse(newIfFalse); + expect(component.getIfFalse()).toEqual(newIfFalse); + + component.setCondition({ + left: 0, + operator: NumberOperation.lessThan, + right: -1, + }); + expect(component.getInnerHTML()).toBe(newIfFalse); + }); + + it('should update the data sources and re-evaluate the condition', () => { + const dataSource = { + id: 'ds1', + records: [ + { id: 'left_id', left: 'Name1' }, + { id: 'right_id', right: 'Name1' }, + ], + }; + dsm.add(dataSource); + + const component = cmpRoot.append({ + type: DataConditionType, + condition: { + left: { + type: DataVariableType, + path: 'ds1.left_id.left', + }, + operator: AnyTypeOperation.equals, + right: { + type: DataVariableType, + path: 'ds1.right_id.right', + }, + }, + ifTrue: '

True value

', + ifFalse: '

False value

', + })[0] as ComponentDataCondition; + + expect(component.getInnerHTML()).toBe('

True value

'); + + changeDataSourceValue(dsm, 'Different value'); + expect(component.getInnerHTML()).toBe('

False value

'); + + changeDataSourceValue(dsm, 'Name1'); + expect(component.getInnerHTML()).toBe('

True value

'); + }); + + it('should re-render the component when condition, ifTrue, or ifFalse changes', () => { + const component = cmpRoot.append({ + type: DataConditionType, + condition: { + left: 0, + operator: NumberOperation.greaterThan, + right: -1, + }, + ifTrue: '

some text

', + ifFalse: '

false text

', + })[0] as ComponentDataCondition; + + const componentView = component.getView() as ComponentDataConditionView; + + component.setIfTrue('

new true text

'); + expect(componentView.el.innerHTML).toContain('new true text'); + + component.setIfFalse('

new false text

'); + component.setCondition({ + left: 0, + operator: NumberOperation.lessThan, + right: -1, + }); + expect(componentView.el.innerHTML).toContain('new false text'); + }); +}); + +function changeDataSourceValue(dsm: DataSourceManager, newValue: string) { + dsm.get('ds1').getRecord('left_id')?.set('left', newValue); +} diff --git a/packages/core/test/specs/data_sources/model/conditional_variables/ComponentConditionalVariable.ts b/packages/core/test/specs/data_sources/model/conditional_variables/ComponentDataCondition.ts similarity index 97% rename from packages/core/test/specs/data_sources/model/conditional_variables/ComponentConditionalVariable.ts rename to packages/core/test/specs/data_sources/model/conditional_variables/ComponentDataCondition.ts index 33af1c63c..222e1bcd7 100644 --- a/packages/core/test/specs/data_sources/model/conditional_variables/ComponentConditionalVariable.ts +++ b/packages/core/test/specs/data_sources/model/conditional_variables/ComponentDataCondition.ts @@ -10,7 +10,7 @@ import ComponentTextView from '../../../../../src/dom_components/view/ComponentT import EditorModel from '../../../../../src/editor/model/Editor'; import { setupTestEditor } from '../../../../common'; -describe('ComponentConditionalVariable', () => { +describe('ComponentDataCondition', () => { let editor: Editor; let em: EditorModel; let dsm: DataSourceManager; @@ -121,10 +121,10 @@ describe('ComponentConditionalVariable', () => { expect(childComponent.getInnerHTML()).toBe('Some value'); /* Test changing datasources */ - updatedsmLeftValue(dsm, 'Diffirent value'); + changeDataSourceValue(dsm, 'Diffirent value'); expect(getFirstChild(component).getInnerHTML()).toBe('False value'); expect(getFirstChildView(component)?.el.innerHTML).toBe('False value'); - updatedsmLeftValue(dsm, 'Name1'); + changeDataSourceValue(dsm, 'Name1'); expect(getFirstChild(component).getInnerHTML()).toBe('Some value'); expect(getFirstChildView(component)?.el.innerHTML).toBe('Some value'); }); @@ -212,7 +212,7 @@ describe('ComponentConditionalVariable', () => { }); }); -function updatedsmLeftValue(dsm: DataSourceManager, newValue: string) { +function changeDataSourceValue(dsm: DataSourceManager, newValue: string) { dsm.get('ds1').getRecord('left_id')?.set('left', newValue); }