Skip to content

Commit e68b07c

Browse files
committed
fix(restoreStateFile): add migration for v5 to 6 volview.zip json
1 parent b291137 commit e68b07c

5 files changed

Lines changed: 665 additions & 21 deletions

File tree

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

Lines changed: 116 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,12 +146,127 @@ const migrate210To300 = (inputManifest: any) => {
146146
return manifest;
147147
};
148148

149+
const migrate501To600 = (inputManifest: any) => {
150+
const manifest = JSON.parse(JSON.stringify(inputManifest));
151+
152+
// Convert views array to viewByID object
153+
if (manifest.views && Array.isArray(manifest.views)) {
154+
manifest.viewByID = {};
155+
manifest.views.forEach((view: any) => {
156+
const migratedView = { ...view };
157+
158+
// Add required 'name' field if missing
159+
if (!migratedView.name) {
160+
migratedView.name = migratedView.id;
161+
}
162+
163+
// Convert 'props' to 'options' if present
164+
if (migratedView.props) {
165+
// Convert any non-string values in props to strings for options
166+
migratedView.options = {};
167+
Object.entries(migratedView.props).forEach(([key, value]) => {
168+
if (typeof value === 'string') {
169+
migratedView.options[key] = value;
170+
} else {
171+
// Convert arrays and objects to JSON strings
172+
migratedView.options[key] = JSON.stringify(value);
173+
}
174+
});
175+
delete migratedView.props;
176+
}
177+
178+
// Add orientation for 2D views based on the view ID
179+
if (migratedView.type === '2D' && !migratedView.options) {
180+
migratedView.options = {};
181+
}
182+
if (migratedView.type === '2D') {
183+
// Set orientation based on view ID (Coronal, Sagittal, Axial)
184+
if (['Coronal', 'Sagittal', 'Axial'].includes(migratedView.id)) {
185+
migratedView.options.orientation = migratedView.id;
186+
}
187+
}
188+
189+
// Handle type conversion for Oblique views
190+
if (migratedView.type === 'Oblique3D') {
191+
migratedView.type = 'Oblique';
192+
}
193+
194+
// Set dataID based on whether the view has config with data
195+
// In 5.0.1, if a view has config entries, it means it's associated with that data
196+
if (migratedView.config && Object.keys(migratedView.config).length > 0) {
197+
// Use the first (and typically only) key from config as the dataID
198+
migratedView.dataID = Object.keys(migratedView.config)[0];
199+
} else {
200+
migratedView.dataID = null;
201+
}
202+
203+
manifest.viewByID[migratedView.id] = migratedView;
204+
});
205+
delete manifest.views;
206+
}
207+
208+
// Add missing fields with proper defaults
209+
if (manifest.isActiveViewMaximized === undefined) {
210+
manifest.isActiveViewMaximized = false;
211+
}
212+
213+
if (manifest.activeView === undefined) {
214+
manifest.activeView = null;
215+
}
216+
217+
// Convert layout to layoutSlots and update layout structure
218+
if (manifest.layout && !manifest.layoutSlots) {
219+
const slots: string[] = [];
220+
221+
// Extract all slot names and convert layout to new format
222+
const convertLayoutItem = (item: any): any => {
223+
if (typeof item === 'string') {
224+
// This is a view name like "Coronal", "3D", etc.
225+
const slotIndex = slots.length;
226+
slots.push(item);
227+
return {
228+
type: 'slot',
229+
slotIndex
230+
};
231+
}
232+
if (item.direction && item.items) {
233+
// This is a nested layout
234+
return {
235+
type: 'layout',
236+
direction: item.direction,
237+
items: item.items.map(convertLayoutItem)
238+
};
239+
}
240+
return item;
241+
};
242+
243+
// Convert the root layout
244+
if (manifest.layout.direction && manifest.layout.items) {
245+
manifest.layout = {
246+
direction: manifest.layout.direction,
247+
items: manifest.layout.items.map(convertLayoutItem)
248+
};
249+
}
250+
251+
manifest.layoutSlots = slots;
252+
}
253+
254+
// Ensure parentToLayers exists as an array
255+
if (!manifest.parentToLayers) {
256+
manifest.parentToLayers = [];
257+
}
258+
259+
manifest.version = '6.0.0';
260+
return manifest;
261+
};
262+
149263
const migrateManifest = (manifestString: string) => {
150264
const inputManifest = JSON.parse(manifestString);
151265
return pipe(
152266
inputManifest,
153267
migrateOrPass(['1.1.0', '1.0.0', '0.5.0'], migrateBefore210),
154-
migrateOrPass(['2.1.0'], migrate210To300)
268+
migrateOrPass(['2.1.0'], migrate210To300),
269+
migrateOrPass(['5.0.1'], migrate501To600)
155270
);
156271
};
157272

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { ARCHIVE_FILE_TYPES } from '@/src/io/mimeTypes';
1212
import { useViewConfigStore } from '@/src/store/view-configs';
1313

1414
export const MANIFEST = 'manifest.json';
15-
export const MANIFEST_VERSION = '5.0.1';
15+
export const MANIFEST_VERSION = '6.0.0';
1616

1717
export async function serialize() {
1818
const datasetStore = useDatasetStore();

0 commit comments

Comments
 (0)