Skip to content

Commit b221dd8

Browse files
committed
fix(state): restore view configurations and fix dataID mapping
- Add deserializeAll method to restore view configs from state files - Fix view dataID mapping to use correct field (was incorrectly using view.id) - Preserve windowing defaults when applying configuration patches - Include view config in state file schema
1 parent 65454cb commit b221dd8

6 files changed

Lines changed: 30 additions & 6 deletions

File tree

‎src/io/import/processors/restoreStateFile.ts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import handleDicomStream from '@/src/io/import/processors/handleDicomStream';
3030
import downloadStream from '@/src/io/import/processors/downloadStream';
3131
import { FileEntry } from '@/src/io/types';
3232
import { useViewStore } from '@/src/store/views';
33+
import { useViewConfigStore } from '@/src/store/view-configs';
3334

3435
const LABELMAP_PALETTE_2_1_0 = {
3536
'1': {
@@ -378,6 +379,9 @@ const restoreStateFile: ImportHandler = async (dataSource, context) => {
378379
// Restore the views
379380
useViewStore().deserialize(manifest, stateIDToStoreID);
380381

382+
// Restore view configs
383+
useViewConfigStore().deserializeAll(manifest, stateIDToStoreID);
384+
381385
// Restore the labelmaps
382386
const segmentGroupIDMap = await useSegmentGroupStore().deserialize(
383387
manifest,

‎src/io/state-file/schema.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ const View = z.object({
281281
type: z.union([z.literal('2D'), z.literal('3D'), z.literal('Oblique')]),
282282
dataID: z.string().optional().nullable(),
283283
options: z.record(z.string()).optional(),
284+
config: z.record(ViewConfig).optional(),
284285
});
285286

286287
export type View = z.infer<typeof View>;

‎src/store/view-configs.ts‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,22 @@ export const useViewConfigStore = defineStore('viewConfig', () => {
6161
volumeColoringStore.deserialize(viewID, updatedConfig);
6262
};
6363

64+
const deserializeAll = (
65+
manifest: StateFile['manifest'],
66+
dataIDMap: Record<string, string>
67+
) => {
68+
Object.entries(manifest.viewByID).forEach(([viewID, view]) => {
69+
if (view.config) {
70+
deserialize(viewID, view.config, dataIDMap);
71+
}
72+
});
73+
};
74+
6475
return {
6576
removeView,
6677
removeData,
6778
serialize,
6879
deserialize,
80+
deserializeAll,
6981
};
7082
});

‎src/store/view-configs/common.ts‎

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,18 @@ const serializeViewConfig = <
1313
viewConfigStateKey: K
1414
) => {
1515
const dataIDs = stateFile.manifest.datasets.map((dataset) => dataset.id);
16-
const { views } = stateFile.manifest;
16+
const views = Object.values(stateFile.manifest.viewByID);
1717

1818
views.forEach((view) => {
1919
dataIDs.forEach((dataID) => {
20-
const { config } = view;
21-
2220
const viewConfig = viewConfigs[view.id]?.[dataID];
2321
if (viewConfig !== undefined) {
24-
const configForData = ensureDefault(dataID, config, {} as ViewConfig);
25-
22+
// Initialize config if it doesn't exist
23+
if (!view.config) {
24+
// eslint-disable-next-line no-param-reassign
25+
view.config = {};
26+
}
27+
const configForData = ensureDefault(dataID, view.config, {} as ViewConfig);
2628
configForData[viewConfigStateKey] = viewConfig as ViewConfig[K];
2729
}
2830
});

‎src/store/view-configs/windowing.ts‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,14 @@ export const useWindowingStore = defineStore('windowing', () => {
131131
}
132132
}
133133

134+
// Ensure we always have required fields from defaults
135+
const baseConfig = currentInternalConfig || defaults;
136+
134137
const newInternalConfig = {
138+
...baseConfig,
135139
...widthLevelPatchOnSwitchingFromAuto,
136140
...patch,
141+
auto: patch.auto ?? currentInternalConfig?.auto ?? defaults.auto,
137142
useAuto: effectiveUseAuto,
138143
// one way from false to true
139144
userTriggered:

‎src/store/views.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ export const useViewStore = defineStore('view', () => {
213213
Object.entries(manifest.viewByID).forEach(([id, view]) => {
214214
viewByID[id] = {
215215
...view,
216-
dataID: view.id ? dataIDMap[view.id] : null,
216+
dataID: view.dataID ? dataIDMap[view.dataID] : null,
217217
} as unknown as ViewInfo;
218218
});
219219
}

0 commit comments

Comments
 (0)