-
Notifications
You must be signed in to change notification settings - Fork 4
ISSUE-139957: fixing Achmea issues #105
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
59c0595
6a1c312
146d46f
c74bef9
062b4ba
e7f01bb
ac9d3b9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,34 +30,22 @@ export class ComponentsManager { | |
|
|
||
| /** | ||
| * Creates a component. | ||
| * | ||
| * Warning: We cannot init() component here because it may cause infinite loop. | ||
| * If we init() child before adding it to parent the following flow may occur: | ||
| * 1. Parent creates child (but does not add it to its children list yet) | ||
| * 2. Child init() is called | ||
| * 3. Parent is updated (because of redux store update) | ||
| * 4. Parent creates child again because its children list is empty. | ||
| * 5. Child init() is called again - and loops occurs. | ||
| * | ||
| * @param type - type of component to create | ||
| * @param args - arguments to pass to the component's constructor | ||
| * @param init - if true, calls the component's init() method after creation | ||
|
||
| * @returns the created component | ||
| */ | ||
| create(type, args = [], init = true) { | ||
| create(type, args = []) { | ||
| const ComponentClass = getComponentFromMap(type); | ||
| const component = new ComponentClass(this, ...args); | ||
| if (init) { | ||
| component.init(); | ||
| } | ||
| return component; | ||
| } | ||
|
|
||
| /** | ||
| * Creates or updates a component. | ||
| * @param component - component to update, or null/undefined to create a new one | ||
| * @param type - type of component to create | ||
| * @param args - arguments to pass to the component's constructor | ||
| * @param init - if true, calls the component's init() method after creation | ||
| * @returns created or updated component | ||
| */ | ||
| upsert(component, type, args = [], init = true) { | ||
| if (component) { | ||
| component.update(...args); | ||
| return component; | ||
| } else { | ||
| return this.create(type, args, init); | ||
| } | ||
| return new ComponentClass(this, ...args); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -99,7 +99,14 @@ export class FieldGroupTemplateComponent extends BaseComponent { | |
| lookForChildInConfig, | ||
| evaluateAllowRowAction(allowRowEdit, item) | ||
| ).getPConnect(); | ||
| const newComponent = this.componentsManager.upsert(oldComponent, newPConn.meta.type, [newPConn]); | ||
| let newComponent; | ||
| if (oldComponent) { | ||
| oldComponent.update(newPConn) | ||
|
||
| newComponent = oldComponent; | ||
| } else { | ||
| newComponent = this.componentsManager.create(newPConn.meta.type, [newPConn]); | ||
| newComponent.init(); | ||
| } | ||
| updatedItems.push({ | ||
| id: index, | ||
| name: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -116,14 +116,30 @@ export class ViewComponent extends ContainerBaseComponent { | |
| this.destroyChildren(); | ||
| } | ||
|
|
||
| this.childrenComponents[0] = this.componentsManager.upsert(this.childrenComponents[0], template, [this.pConn]); | ||
| if (this.childrenComponents[0]) { | ||
| this.childrenComponents[0].update(this.pConn); | ||
| } else { | ||
| this.childrenComponents[0] = this.componentsManager.create(template, [this.pConn]); | ||
| this.childrenComponents[0].init(); | ||
| } | ||
| } | ||
|
|
||
| #evaluateVisibility(pConn, referenceContext) { | ||
| const visibilityExpression = pConn.meta.config.visibility; | ||
| if (!visibilityExpression || visibilityExpression.length === 0) return true; | ||
| const contextName = pConn.getContextName(); | ||
| if (visibilityExpression.startsWith("@E ")) { | ||
| return this.#evaluateExpressionVisibility(contextName, referenceContext, visibilityExpression); | ||
| } else if(visibilityExpression.startsWith("@W ")) { | ||
| return this.#evaluateWhenVisibility(contextName, visibilityExpression); | ||
| } else { | ||
| console.warn(TAG, `Unsupported visibility expression: ${visibilityExpression}. Defaulting to visible.`); | ||
| return true; | ||
| } | ||
| } | ||
|
|
||
| let dataPage = this.#getDataPage(pConn.getContextName(), referenceContext); | ||
| #evaluateExpressionVisibility(contextName, referenceContext, visibilityExpression) { | ||
| let dataPage = this.#getDataPage(contextName, referenceContext); | ||
| if (!dataPage) return false; | ||
|
|
||
| const visibilityConditions = visibilityExpression.replace("@E ", ""); | ||
|
|
@@ -136,6 +152,38 @@ export class ViewComponent extends ContainerBaseComponent { | |
| }); | ||
| } | ||
|
|
||
| #evaluateWhenVisibility(contextName, visibilityExpression) { | ||
| let bVisibility = true; | ||
| // e.g. "@E .EmbeddedData_SelectedTestName == 'Readonly' && .EmbeddedData_SelectedSubCategory == 'Mode'" | ||
|
||
| const aVisibility = visibilityExpression.split('&&'); | ||
|
||
| // e.g. ["EmbeddedData_SelectedTestName": "Readonly", "EmbeddedData_SelectedSubCategory": "Mode"] | ||
| // Reading values from the Store to evaluate the visibility expressions | ||
| const storeData = PCore.getStore().getState()?.data[contextName].caseInfo.content; | ||
|
|
||
| const initialVal = {}; | ||
| const oProperties = aVisibility.reduce((properties, property) => { | ||
| const keyStartIndex = property.indexOf('.'); | ||
| const keyEndIndex = property.indexOf('=') - 1; | ||
| const valueStartIndex = property.indexOf("'"); | ||
| const valueEndIndex = property.lastIndexOf("'") - 1; | ||
| return { | ||
| ...properties, | ||
| [property.substr(keyStartIndex + 1, keyEndIndex - keyStartIndex - 1)]: property.substr(valueStartIndex + 1, valueEndIndex - valueStartIndex) | ||
|
||
| }; | ||
| }, initialVal); | ||
|
|
||
| const propertyKeys = Object.keys(oProperties); | ||
| const propertyValues = Object.values(oProperties); | ||
|
|
||
| for (let propertyIndex = 0; propertyIndex < propertyKeys.length; propertyIndex++) { | ||
| if (storeData[propertyKeys[propertyIndex]] !== propertyValues[propertyIndex]) { | ||
| bVisibility = false; | ||
| } | ||
| } | ||
|
|
||
| return bVisibility; | ||
| } | ||
|
|
||
| #getDataPage(context, referenceContext) { | ||
| let pageReferenceKeys = referenceContext.replace("caseInfo.content.", "").split("."); | ||
| let page = PCore.getStore().getState()?.data[context].caseInfo.content; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw, you should be able to create & init components in all places where you are operating on local variables.