feat: render dashboard from model #20
3 changed files with 44 additions and 15 deletions
|
|
@ -20,7 +20,7 @@ describe("dashboard runtime loader", () => {
|
||||||
test("seeds and loads the active dashboard from sqlite", async () => {
|
test("seeds and loads the active dashboard from sqlite", async () => {
|
||||||
const store = await createTestStore();
|
const store = await createTestStore();
|
||||||
|
|
||||||
const runtime = loadDashboardRuntime(store);
|
const runtime = loadDashboardRuntime(store, { seedIfEmpty: true });
|
||||||
|
|
||||||
expect(runtime.state).toBe("ready");
|
expect(runtime.state).toBe("ready");
|
||||||
if (runtime.state !== "ready") throw new Error("expected ready dashboard");
|
if (runtime.state !== "ready") throw new Error("expected ready dashboard");
|
||||||
|
|
@ -46,6 +46,17 @@ describe("dashboard runtime loader", () => {
|
||||||
expect(runtime.document.metadata.title).toBe(genericDashboardFixture.metadata.title);
|
expect(runtime.document.metadata.title).toBe(genericDashboardFixture.metadata.title);
|
||||||
expect(store.listRevisions()).toHaveLength(1);
|
expect(store.listRevisions()).toHaveLength(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("returns empty state when no dashboard is active and seeding is disabled", async () => {
|
||||||
|
const store = await createTestStore();
|
||||||
|
|
||||||
|
const runtime = loadDashboardRuntime(store);
|
||||||
|
|
||||||
|
expect(runtime.state).toBe("empty");
|
||||||
|
if (runtime.state !== "empty") throw new Error("expected empty dashboard");
|
||||||
|
expect(runtime.title).toBe("No Dashboard Model");
|
||||||
|
expect(store.listRevisions()).toHaveLength(0);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
async function createTestStore() {
|
async function createTestStore() {
|
||||||
|
|
|
||||||
|
|
@ -42,21 +42,24 @@ export interface DashboardRuntimeInvalid {
|
||||||
errors: string[];
|
errors: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface DashboardRuntimeOptions {
|
||||||
|
seedIfEmpty?: boolean;
|
||||||
|
seedDocument?: DashboardDocument;
|
||||||
|
}
|
||||||
|
|
||||||
export function loadDashboardRuntime(
|
export function loadDashboardRuntime(
|
||||||
store?: DashboardStore,
|
store?: DashboardStore,
|
||||||
|
options: DashboardRuntimeOptions = {},
|
||||||
): DashboardRuntimeState {
|
): DashboardRuntimeState {
|
||||||
const dashboardStore = store || createDashboardStore();
|
const dashboardStore = store || createDashboardStore();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const seeded = dashboardStore.seedDashboardIfEmpty(dimensionLabDashboardFixture, {
|
|
||||||
actor: "initial-seed",
|
|
||||||
message: "load initial dashboard document",
|
|
||||||
});
|
|
||||||
const active = dashboardStore.getActiveDashboard();
|
const active = dashboardStore.getActiveDashboard();
|
||||||
const document = active?.document || seeded.document;
|
if (active) {
|
||||||
const currentRevisionId = active?.currentRevisionId || seeded.id;
|
return readyRuntimeState(active.document, active.currentRevisionId);
|
||||||
|
}
|
||||||
|
|
||||||
if (!document) {
|
if (!options.seedIfEmpty) {
|
||||||
return {
|
return {
|
||||||
state: "empty",
|
state: "empty",
|
||||||
title: "No Dashboard Model",
|
title: "No Dashboard Model",
|
||||||
|
|
@ -65,12 +68,15 @@ export function loadDashboardRuntime(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
const seeded = dashboardStore.seedDashboardIfEmpty(
|
||||||
state: "ready",
|
options.seedDocument || dimensionLabDashboardFixture,
|
||||||
document,
|
{
|
||||||
schemaVersion: document.schemaVersion,
|
actor: "initial-seed",
|
||||||
currentRevisionId,
|
message: "load initial dashboard document",
|
||||||
};
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return readyRuntimeState(seeded.document, seeded.id);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof DashboardPersistenceValidationError) {
|
if (error instanceof DashboardPersistenceValidationError) {
|
||||||
return invalidRuntimeState(error.failure.errors);
|
return invalidRuntimeState(error.failure.errors);
|
||||||
|
|
@ -86,6 +92,18 @@ export function loadDashboardRuntime(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function readyRuntimeState(
|
||||||
|
document: DashboardDocument,
|
||||||
|
currentRevisionId: string,
|
||||||
|
): DashboardRuntimeReady {
|
||||||
|
return {
|
||||||
|
state: "ready",
|
||||||
|
document,
|
||||||
|
schemaVersion: document.schemaVersion,
|
||||||
|
currentRevisionId,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function invalidRuntimeState(errors: string[]): DashboardRuntimeInvalid {
|
function invalidRuntimeState(errors: string[]): DashboardRuntimeInvalid {
|
||||||
return {
|
return {
|
||||||
state: "invalid",
|
state: "invalid",
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,6 @@ import { loadDashboardRuntime } from "$lib/server/dashboard";
|
||||||
|
|
||||||
export function load() {
|
export function load() {
|
||||||
return {
|
return {
|
||||||
dashboard: loadDashboardRuntime(),
|
dashboard: loadDashboardRuntime(undefined, { seedIfEmpty: true }),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue