🔨 Refactor: Project Layout & Timeline Page

- Refactor layout page in projects route
- Add timeline page for project
- Load sessions, deltas, and UI sessions for project
- Sort sessions, deltas, and UI sessions by timestamp
- Set earliest and latest delta timestamp for each UI session
This commit is contained in:
Kiril Videlov 2023-03-03 15:51:15 +01:00
parent 7db4f427bf
commit d2bbf1cfa0
3 changed files with 75 additions and 72 deletions

View File

@ -9,10 +9,6 @@
export let data: LayoutData;
$: project = data.project;
$: sessions = data.sessions;
$: lastSessionId = $sessions[$sessions.length - 1]?.id;
$: dateSessions = data.dateSessions;
console.debug('loading sessions for project: ', $dateSessions === undefined); // Force pre-loading of dateSessions
function projectUrl(project: Project) {
const gitUrl = project.api?.git_url;

View File

@ -1,75 +1,8 @@
import { readable, derived } from 'svelte/store';
import type { LayoutLoad } from './$types';
import { building } from '$app/environment';
import type { Session } from '$lib/sessions';
import type { UISession } from '$lib/uisessions';
import { asyncDerived } from '@square/svelte-store';
import { list as listDeltas } from '$lib/deltas';
import type { Delta } from '$lib/deltas';
import { startOfDay } from 'date-fns';
export const prerender = false;
export const load: LayoutLoad = async ({ parent, params }) => {
const { projects } = await parent();
const sessions = building
? readable<Session[]>([])
: await (await import('$lib/sessions')).default({ projectId: params.projectId });
const orderedSessions = derived(sessions, (sessions) => {
return sessions.slice().sort((a, b) => a.meta.startTimestampMs - b.meta.startTimestampMs);
});
const dateSessions = asyncDerived([orderedSessions], async ([sessions]) => {
const deltas = await Promise.all(
sessions.map((session) => {
return listDeltas({
projectId: params.projectId ?? '',
sessionId: session.id
});
})
);
// Sort deltas by timestamp
deltas.forEach((delta) => {
Object.keys(delta).forEach((key) => {
delta[key].sort((a, b) => a.timestampMs - b.timestampMs);
});
});
const uiSessions = sessions
.map((session, i) => {
return { session, deltas: deltas[i] } as UISession;
})
.filter((uiSession) => {
return Object.keys(uiSession.deltas).length > 0;
});
const dateSessions: Record<number, UISession[]> = {};
uiSessions.forEach((uiSession) => {
const date = startOfDay(new Date(uiSession.session.meta.startTimestampMs));
if (dateSessions[date.getTime()]) {
dateSessions[date.getTime()]?.push(uiSession);
} else {
dateSessions[date.getTime()] = [uiSession];
}
});
// For each UISession in dateSessions, set the earliestDeltaTimestampMs and latestDeltaTimestampMs
Object.keys(dateSessions).forEach((date: any) => {
dateSessions[date].forEach((uiSession: any) => {
const deltaTimestamps = Object.keys(uiSession.deltas).reduce((acc, key) => {
return acc.concat(uiSession.deltas[key].map((delta: Delta) => delta.timestampMs));
}, []);
uiSession.earliestDeltaTimestampMs = Math.min(...deltaTimestamps);
uiSession.latestDeltaTimestampMs = Math.max(...deltaTimestamps);
});
});
return dateSessions;
});
return {
project: projects.get(params.projectId),
sessions: orderedSessions,
dateSessions: dateSessions
project: projects.get(params.projectId)
};
};

View File

@ -0,0 +1,74 @@
import type { PageLoad } from './$types';
import { readable, derived } from 'svelte/store';
import { building } from '$app/environment';
import type { Session } from '$lib/sessions';
import type { UISession } from '$lib/uisessions';
import { asyncDerived } from '@square/svelte-store';
import { list as listDeltas } from '$lib/deltas';
import type { Delta } from '$lib/deltas';
import { startOfDay } from 'date-fns';
export const load: PageLoad = async ({ parent, params }) => {
const { project } = await parent();
const sessions = building
? readable<Session[]>([])
: await (await import('$lib/sessions')).default({ projectId: params.projectId });
const orderedSessions = derived(sessions, (sessions) => {
return sessions.slice().sort((a, b) => a.meta.startTimestampMs - b.meta.startTimestampMs);
});
const dateSessions = asyncDerived([orderedSessions], async ([sessions]) => {
const deltas = await Promise.all(
sessions.map((session) => {
return listDeltas({
projectId: params.projectId ?? '',
sessionId: session.id
});
})
);
// Sort deltas by timestamp
deltas.forEach((delta) => {
Object.keys(delta).forEach((key) => {
delta[key].sort((a, b) => a.timestampMs - b.timestampMs);
});
});
const uiSessions = sessions
.map((session, i) => {
return { session, deltas: deltas[i] } as UISession;
})
.filter((uiSession) => {
return Object.keys(uiSession.deltas).length > 0;
});
const dateSessions: Record<number, UISession[]> = {};
uiSessions.forEach((uiSession) => {
const date = startOfDay(new Date(uiSession.session.meta.startTimestampMs));
if (dateSessions[date.getTime()]) {
dateSessions[date.getTime()]?.push(uiSession);
} else {
dateSessions[date.getTime()] = [uiSession];
}
});
// For each UISession in dateSessions, set the earliestDeltaTimestampMs and latestDeltaTimestampMs
Object.keys(dateSessions).forEach((date: any) => {
dateSessions[date].forEach((uiSession: any) => {
const deltaTimestamps = Object.keys(uiSession.deltas).reduce((acc, key) => {
return acc.concat(uiSession.deltas[key].map((delta: Delta) => delta.timestampMs));
}, []);
uiSession.earliestDeltaTimestampMs = Math.min(...deltaTimestamps);
uiSession.latestDeltaTimestampMs = Math.max(...deltaTimestamps);
});
});
return dateSessions;
});
return {
project: project,
sessions: orderedSessions,
dateSessions: dateSessions
};
};