Stop the pivot snapping when its settings sidebar is opened
Two causes, both mine, both triggered by adjusting the layout. A zero size was being treated as the viewer going away, and opening Perspective's settings sidebar collapses the datagrid for a frame. The return then re-applied the stored row depth over whatever had been expanded by hand. Only lost intersection counts as a departure now; a zero size is a transient of layout, not an absence. And perspective-config-update fires for anything in the config, the settings flag included -- not only for split_by. While collapsed the live split_by is a truncation of the full hierarchy, so adopting it recorded the truncation as the hierarchy and put the deeper levels out of reach. A genuine rearrangement is not a prefix of what we already hold, which is the difference the handler now tests. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7cfd0068e7
commit
8aa0ae2ece
@ -346,14 +346,14 @@ export default function Forecast({ sources = [], sourceId, versions = [], versio
|
||||
let settle = null
|
||||
const onObserved = (ev) => {
|
||||
const d = ev.detail || {}
|
||||
// Losing intersection, or collapsing to zero size, is the element going
|
||||
// away: record it, because that is when the view gets discarded.
|
||||
const leaving = d.entries?.some(e =>
|
||||
e.isIntersecting === false || (e.width === 0 && e.height === 0))
|
||||
// Only intersection counts as going away. A zero size is a transient of
|
||||
// layout -- opening Perspective's own settings sidebar collapses the
|
||||
// datagrid for a frame -- and treating it as a departure meant the return
|
||||
// re-applied depth, so adjusting the layout snapped the tree back.
|
||||
const leaving = d.entries?.some(e => e.isIntersecting === false)
|
||||
if (leaving) { wentAwayRef.current = true; return dbg(`observer ${d.kind} -> viewer went away`) }
|
||||
|
||||
// A resize with a non-zero size is an ordinary reflow. It is not a
|
||||
// restoration, so it must not re-apply anything.
|
||||
// Everything else is a reflow. Not a restoration, so it restores nothing.
|
||||
if (!wentAwayRef.current) return
|
||||
|
||||
clearTimeout(settle)
|
||||
@ -875,7 +875,17 @@ export default function Forecast({ sources = [], sourceId, versions = [], versio
|
||||
// it redefines the hierarchy. Ours is a collapse, and must not overwrite it.
|
||||
if (!collapsingRef.current) {
|
||||
const live = await viewer.save()
|
||||
adoptSplit(live.split_by || [], (live.split_by || []).length)
|
||||
const next = live.split_by || []
|
||||
const full = splitFullRef.current || []
|
||||
// This event fires for anything in the config -- opening the settings
|
||||
// sidebar included -- not only for split_by. While collapsed, the live
|
||||
// split_by is a prefix of the full hierarchy, and adopting it would
|
||||
// record the truncation as the hierarchy and make the deeper levels
|
||||
// unreachable. A genuine rearrangement is not a prefix of what we hold.
|
||||
const isCollapsedPrefix =
|
||||
next.length < full.length && next.every((c, i) => c === full[i])
|
||||
if (!isCollapsedPrefix) adoptSplit(next, next.length)
|
||||
else dbg(`config-update: split_by is our collapse (${next.length}/${full.length}), keeping the full hierarchy`)
|
||||
}
|
||||
const cfg = await captureConfig()
|
||||
if (cfg) await persistLayout(vid, cfg)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user