-
Notifications
You must be signed in to change notification settings - Fork 27
Description
Describe the Bug
Steps to Reproduce
I had config of a section (this is my properties of "Message Intermediate Catch Event", where I am adding a custom ListGroup to standard "message" group):
Group "message"
|-- ListGroup "localCorrelationKeys" (my custom group)
I experienced bad UX:
- User expands the "message" group
- User expands the "localCorrelationKeys" nested ListGroup
- BAM - the system collapses all groups
This occurs just one time after diagram open. After that - it works normally.
It took hours to debug and I found the reason.
I removed all my customizations, but still found the bug in more simple scenario:
- Open diagram
- Select any element with Input and Output parameters
Group "input"
Group "output"
Those are Camunda properties - not mine, so, by removing my customizations, at least I eliminated that I did something wrong in my code by that.
- Expand "input"
- Expand "output"
- BAM - the system collapses all groups
And again - this happens just one time. After that it works normally.
Expected Behavior
Expected behavior is clearly, that system not do any unwanted collapsing of sections. Or at the very least do them somehow consistently.
Investigation results
All debugging efforts led me to the setLayoutForKey function: https://github.com/bpmn-io/properties-panel/blob/main/src/PropertiesPanel.js#L156
const setLayoutForKey = (key, config) => {
const newLayout = assign({}, layout);
set(newLayout, key, config);
setLayout(newLayout);
};
At the very least, here we have the shallow copy, the min-dash assign function just redirect it to Object.assign:
https://github.com/bpmn-io/min-dash/blob/main/lib/object.js#L20
So, this is a shallow copy, while using set function from min-dash creates deep objects, like {group: {message: {open: true}}}
So the first thing - I tried replaced it to the following line:
// commented out original line, because it creates a shallow copy
// const newLayout = assign({}, layout);
const newLayout = JSON.parse(JSON.stringify(currentLayout));
It changed behavior, but not in the way I wanted: it made behavior consistent - now every expand collapsed all other sections, every time, not just the first one.
I am not sure, guys, how do you prefer to create a deep copy of object, I did not find anything in min-dash, so came up with good old JSON.parse(JSON.stringify(...)).
Next thing I tried is instead of calling setLayout(newLayout), call it with a function like that:
const setLayoutForKey = (key, config) => {
setLayout(currentLayout => {
const newLayout = JSON.parse(JSON.stringify(currentLayout));
set(newLayout, key, config);
return newLayout;
});
};
And this resolved the problem. Now, layout is updated as expected, first time and any subsequent expand of collapse action as expected.
I am still trying to understand, why this fixed issue. Probably the instance of currentLayout, which the setLayoutForKey possessed was obsolete for some reason, and using the callback is always updates the actual current value...