Persist Perspective viewer state including column formatting
Save/restore went through both viewer and plugin, where the explicit plugin.restore could stomp the column formatting the viewer had already applied. Capture via viewer.save() alone (it includes plugin_config) and restore via a single viewer.restore call with edit_mode merged in. Added a perspective-config-update listener so formatting, sort, and other in-place changes persist to the last-used cache without an explicit Save. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
a5e59f823a
commit
6a98c3f8fc
@ -234,9 +234,8 @@ export default function Forecast({ sourceId, versionId }) {
|
|||||||
const saved = localStorage.getItem(LAYOUT_KEY(vid))
|
const saved = localStorage.getItem(LAYOUT_KEY(vid))
|
||||||
if (saved) {
|
if (saved) {
|
||||||
const cfg = cleanLayout(JSON.parse(saved), validCols)
|
const cfg = cleanLayout(JSON.parse(saved), validCols)
|
||||||
|
cfg.plugin_config = { edit_mode: 'SELECT_REGION', ...(cfg.plugin_config || {}) }
|
||||||
await viewer.restore(cfg)
|
await viewer.restore(cfg)
|
||||||
const plugin = await viewer.getPlugin()
|
|
||||||
await plugin.restore({ edit_mode: 'SELECT_REGION', ...(cfg.plugin_config || {}) })
|
|
||||||
if (cfg.expand_depth != null) await applyDepth(cfg.expand_depth)
|
if (cfg.expand_depth != null) await applyDepth(cfg.expand_depth)
|
||||||
} else {
|
} else {
|
||||||
const dims = meta.filter(c => c.role === 'dimension').map(c => c.cname)
|
const dims = meta.filter(c => c.role === 'dimension').map(c => c.cname)
|
||||||
@ -245,10 +244,18 @@ export default function Forecast({ sourceId, versionId }) {
|
|||||||
if (dims.length) cfg.group_by = dims.slice(0, 2)
|
if (dims.length) cfg.group_by = dims.slice(0, 2)
|
||||||
if (dateCol) cfg.split_by = [dateCol]
|
if (dateCol) cfg.split_by = [dateCol]
|
||||||
await viewer.restore(cfg)
|
await viewer.restore(cfg)
|
||||||
const plugin = await viewer.getPlugin()
|
|
||||||
await plugin.restore({ edit_mode: 'SELECT_REGION' })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// auto-persist viewer state (formatting, columns, etc.) to the last-used cache
|
||||||
|
if (viewer._pspUpdate) viewer.removeEventListener('perspective-config-update', viewer._pspUpdate)
|
||||||
|
viewer._pspUpdate = async () => {
|
||||||
|
try {
|
||||||
|
const cfg = await captureConfig()
|
||||||
|
if (cfg) await persistLayout(vid, cfg)
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
viewer.addEventListener('perspective-config-update', viewer._pspUpdate)
|
||||||
|
|
||||||
// click → slice via event filters (Perspective encodes row position as [col,'==',val] triples)
|
// click → slice via event filters (Perspective encodes row position as [col,'==',val] triples)
|
||||||
if (viewer._pspClick) viewer.removeEventListener('perspective-click', viewer._pspClick)
|
if (viewer._pspClick) viewer.removeEventListener('perspective-click', viewer._pspClick)
|
||||||
viewer._pspClick = async (e) => {
|
viewer._pspClick = async (e) => {
|
||||||
@ -286,9 +293,8 @@ export default function Forecast({ sourceId, versionId }) {
|
|||||||
async function captureConfig() {
|
async function captureConfig() {
|
||||||
const viewer = viewerRef.current
|
const viewer = viewerRef.current
|
||||||
if (!viewer) return null
|
if (!viewer) return null
|
||||||
const plugin = await viewer.getPlugin()
|
const cfg = await viewer.save()
|
||||||
const [cfg, pluginCfg] = await Promise.all([viewer.save(), plugin.save()])
|
return { ...cfg, expand_depth: expandDepthRef.current }
|
||||||
return { ...cfg, plugin_config: pluginCfg, expand_depth: expandDepthRef.current }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function persistLayout(vid, cfg) {
|
async function persistLayout(vid, cfg) {
|
||||||
@ -328,11 +334,8 @@ export default function Forecast({ sourceId, versionId }) {
|
|||||||
if (!viewer) return
|
if (!viewer) return
|
||||||
const validCols = new Set(tableRef.current ? Object.keys(await tableRef.current.schema()) : [])
|
const validCols = new Set(tableRef.current ? Object.keys(await tableRef.current.schema()) : [])
|
||||||
const cfg = cleanLayout(layout.config, validCols)
|
const cfg = cleanLayout(layout.config, validCols)
|
||||||
|
cfg.plugin_config = { edit_mode: 'SELECT_REGION', ...(cfg.plugin_config || {}) }
|
||||||
await viewer.restore(cfg)
|
await viewer.restore(cfg)
|
||||||
if (cfg.plugin_config) {
|
|
||||||
const plugin = await viewer.getPlugin()
|
|
||||||
await plugin.restore(cfg.plugin_config)
|
|
||||||
}
|
|
||||||
if (cfg.expand_depth != null) await applyDepth(cfg.expand_depth)
|
if (cfg.expand_depth != null) await applyDepth(cfg.expand_depth)
|
||||||
setActiveLayoutId(layout.id)
|
setActiveLayoutId(layout.id)
|
||||||
await persistLayout(versionId, cfg)
|
await persistLayout(versionId, cfg)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user