Bug
In the app viewer, with multiple accordions stacked vertically, collapsing all of them still leaves the canvas at its original (fully-expanded) height — the page stays scrollable with a large empty white area below the collapsed accordions.
Root cause
updateCanvasBottomHeight in `frontend/src/AppBuilder/_stores/slices/appSlice.js` computed the scroll height as:
```js
const maxHeight = Math.max(maxPermanentHeight, temporaryLayoutsMaxHeight);
```
- `maxPermanentHeight` is derived from each component's static authored `layout.top + layout.height`.
- `temporaryLayoutsMaxHeight` is derived from the reflowed `temporaryLayouts`.
Collapsing an accordion triggers dynamic-height reflow (`useDynamicHeight` → `adjustComponentPositions` → `dynamicHeightReflow.js`), which shrinks the widget and shifts siblings up — but writes the new positions only to `temporaryLayouts`, never to the permanent `layouts`. So the temp max drops while the permanent max stays at the original expanded bottom, and `Math.max` keeps the canvas tall.
Fix
Unify into a single pass using the effective layout per component (`temporaryLayouts[id] ?? layouts[currentLayout]`) so a reflowed/collapsed widget correctly lowers the canvas bottom.
Note: only affects accordions/widgets with dynamic height enabled (otherwise siblings don't reflow on collapse by design).
Bug
In the app viewer, with multiple accordions stacked vertically, collapsing all of them still leaves the canvas at its original (fully-expanded) height — the page stays scrollable with a large empty white area below the collapsed accordions.
Root cause
updateCanvasBottomHeightin `frontend/src/AppBuilder/_stores/slices/appSlice.js` computed the scroll height as:```js
const maxHeight = Math.max(maxPermanentHeight, temporaryLayoutsMaxHeight);
```
Collapsing an accordion triggers dynamic-height reflow (`useDynamicHeight` → `adjustComponentPositions` → `dynamicHeightReflow.js`), which shrinks the widget and shifts siblings up — but writes the new positions only to `temporaryLayouts`, never to the permanent `layouts`. So the temp max drops while the permanent max stays at the original expanded bottom, and `Math.max` keeps the canvas tall.
Fix
Unify into a single pass using the effective layout per component (`temporaryLayouts[id] ?? layouts[currentLayout]`) so a reflowed/collapsed widget correctly lowers the canvas bottom.
Note: only affects accordions/widgets with dynamic height enabled (otherwise siblings don't reflow on collapse by design).