Skip to content

Commit 7ec44aa

Browse files
authored
View Definition Auto Migration (#1504)
* UI view definition migration support * Add and update unit tests * Support ConstraintViolationsPanel -> ConstraintsPanel update * Remove deprecated ActivityLayer.activityHeight from schema and migrate old views * Bubble up migration error when uploading view that needs migration * Add migration toast message * Restrict view upload to JSON files
1 parent 8b0bd84 commit 7ec44aa

File tree

20 files changed

+3590
-60
lines changed

20 files changed

+3590
-60
lines changed

e2e-tests/data/valid-view.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,6 @@
315315
"layers": [
316316
{
317317
"activityColor": "#283593",
318-
"activityHeight": 20,
319318
"chartType": "activity",
320319
"filter": {
321320
"activity": {

e2e-tests/fixtures/View.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export class View {
1212
navButtonViewSaveAsMenuButton: Locator;
1313
navButtonViewSavedViewsMenuButton: Locator;
1414
navButtonViewUploadViewMenuButton: Locator;
15+
outOfDateViewFilePath: string = 'src/tests/mocks/view/v0/view.json';
1516
renameViewMenuSaveViewButton: Locator;
1617
saveAsMenuSaveAsButton: Locator;
1718
table: Locator;

e2e-tests/tests/view.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,4 +106,15 @@ test.describe.serial('View', () => {
106106
await page.locator('.modal .st-button:has-text("Upload View")').click();
107107
await expect(page.locator('.modal')).not.toBeVisible();
108108
});
109+
110+
test(`Selecting an out of date view file should not display an error and not prevent the file from being uploaded`, async () => {
111+
await view.openViewMenu();
112+
await expect(view.navButtonViewUploadViewMenuButton).toBeVisible();
113+
await view.navButtonViewUploadViewMenuButton.click();
114+
await view.fillViewInputName();
115+
await view.fillViewInputFile(view.outOfDateViewFilePath);
116+
await expect(page.locator('.modal-content .error')).not.toBeVisible();
117+
await page.locator('.modal .st-button:has-text("Upload View")').click();
118+
await expect(page.locator('.modal')).not.toBeVisible();
119+
});
109120
});

src/components/modals/SavedViewsModal.svelte

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,9 @@
6161
}
6262
}
6363
64-
async function getFullView(viewId: number): Promise<View | null> {
64+
async function getFullView(viewId: number, migrate: boolean = true): Promise<View | null> {
6565
const query = new URLSearchParams(`?${SearchParameters.VIEW_ID}=${viewId}`);
66-
return await effects.getView(query, user);
66+
return await effects.getView(query, user, migrate);
6767
}
6868
6969
async function openView({ detail: viewId }: CustomEvent<number>) {
@@ -78,7 +78,7 @@
7878
}
7979
8080
async function downloadView({ detail: viewId }: CustomEvent<number>) {
81-
const view = await getFullView(viewId);
81+
const view = await getFullView(viewId, false);
8282
if (view !== null) {
8383
downloadViewUtil(view);
8484
dispatch('close');

src/components/modals/UploadViewModal.svelte

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
name="file"
7878
required
7979
type="file"
80+
accept="application/json"
8081
bind:files
8182
on:click={onClick}
8283
on:change={onChange}

src/constants/view.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,7 @@ export const ViewXRangeLayerSchemePresets: Record<XRangeLayerColorScheme, readon
6969
schemeSet3,
7070
schemeTableau10,
7171
};
72+
73+
export const viewSchemaVersion = 1;
74+
75+
export const viewSchemaVersionName = `v${viewSchemaVersion}`;

src/routes/plans/[id]/+page.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@
527527
const { detail } = event;
528528
const { definition, id, name, owner } = detail;
529529
if (id != null && hasUpdateViewPermission) {
530-
const success = await effects.updateView(id, { definition, name, owner }, data.user);
530+
const success = await effects.updateView(id, { definition, name, owner }, null, data.user);
531531
if (success) {
532532
resetOriginalView();
533533
}

src/routes/plans/[id]/+page.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export const load: PageLoad = async ({ parent, params, url }) => {
4949
const initialView = await effects.getView(
5050
url.searchParams,
5151
user,
52+
true,
5253
initialActivityTypes,
5354
initialResourceTypes,
5455
initialExternalEventTypes,

src/schemas/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import * as v0 from './ui-view-schema-v0.json';
2+
import * as v1 from './ui-view-schema-v1.json';
3+
4+
export default {
5+
v0,
6+
v1,
7+
};

0 commit comments

Comments
 (0)