Skip to content

Commit 243f82a

Browse files
committed
fix(views): keep active view selected after data binding
Tools and rendering panels resolve currentImageID through activeView and viewByID. Select the first startup view directly, then enforce a visible active view when data binds. Session restore reuses that binding path when manifest data IDs are rebound. Added store coverage for startup, normal data load, and session rebinding. Verified with focused Vitest, lint, and full Chrome e2e.
1 parent 4795212 commit 243f82a

2 files changed

Lines changed: 70 additions & 6 deletions

File tree

src/store/__tests__/views.spec.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { describe, it, beforeEach, expect } from 'vitest';
2+
import { setActivePinia, createPinia } from 'pinia';
3+
import { useViewStore } from '@/src/store/views';
4+
import type { Manifest } from '@/src/io/state-file/schema';
5+
6+
describe('View store', () => {
7+
beforeEach(() => {
8+
setActivePinia(createPinia());
9+
});
10+
11+
it('selects the first initial visible view', () => {
12+
const store = useViewStore();
13+
14+
expect(store.activeView).toBe(store.visibleViews[0].id);
15+
});
16+
17+
it('selects a visible view when data is attached to the default layout', () => {
18+
const store = useViewStore();
19+
20+
store.setActiveView(null);
21+
store.setDataForAllViews('image-1');
22+
23+
expect(store.activeView).toBe(store.visibleViews[0].id);
24+
});
25+
26+
it('selects a visible view when session data IDs are rebound', () => {
27+
const store = useViewStore();
28+
const manifest: Manifest = {
29+
version: '6.1.0',
30+
dataSources: [],
31+
activeView: null,
32+
layout: {
33+
direction: 'column',
34+
items: [{ type: 'slot', slotIndex: 0 }],
35+
},
36+
layoutSlots: ['view-1'],
37+
viewByID: {
38+
'view-1': {
39+
id: 'view-1',
40+
type: '2D',
41+
dataID: 'state-image',
42+
name: 'Axial',
43+
options: {
44+
orientation: 'Axial',
45+
},
46+
},
47+
},
48+
};
49+
50+
store.deserializeLayout(manifest);
51+
expect(store.activeView).toBeNull();
52+
53+
store.bindViewsToData('state-image', 'loaded-image', manifest);
54+
55+
expect(store.activeView).toBe('view-1');
56+
expect(store.viewByID['view-1'].dataID).toBe('loaded-image');
57+
});
58+
});

src/store/views.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -147,13 +147,14 @@ export const useViewStore = defineStore('view', () => {
147147
}
148148

149149
function ensureActiveViewIsVisible() {
150-
if (!visibleViews.value.length) {
150+
const views = visibleViews.value;
151+
if (!views.length) {
151152
setActiveView(null);
152153
return;
153154
}
154155

155-
if (!visibleViews.value.find((view) => view.id === activeView.value)) {
156-
setActiveView(visibleViews.value[0].id);
156+
if (!views.find((view) => view.id === activeView.value)) {
157+
setActiveView(views[0].id);
157158
}
158159
}
159160

@@ -263,6 +264,8 @@ export const useViewStore = defineStore('view', () => {
263264
if (!(viewID in viewByID)) return;
264265
viewByID[viewID].dataID = dataID;
265266
ViewDataChangeEvent.trigger(viewID, dataID);
267+
// Global tools resolve their image through activeView.
268+
ensureActiveViewIsVisible();
266269
}
267270

268271
function setDataForActiveView(dataID: Maybe<string>) {
@@ -342,16 +345,19 @@ export const useViewStore = defineStore('view', () => {
342345

343346
Object.entries(manifest.viewByID).forEach(([id, view]) => {
344347
if (view.dataID === stateID && viewByID[id]) {
345-
viewByID[id].dataID = storeID;
346-
ViewDataChangeEvent.trigger(id, storeID);
348+
setDataForView(id, storeID);
347349
}
348350
});
349351
}
350352

351353
// initialization
352354

353355
firstLayout.views.forEach((viewInit) => {
354-
layoutSlots.value.push(addView(viewInit));
356+
const viewId = addView(viewInit);
357+
layoutSlots.value.push(viewId);
358+
if (!activeView.value) {
359+
setActiveView(viewId);
360+
}
355361
});
356362

357363
watch(disabledViewTypes, () => {

0 commit comments

Comments
 (0)