feat: session replay

* wip

* wip

* wip

* wip

* final fixes

* comments

* fix
This commit is contained in:
Carl-Gerhard Lindesvärd
2026-02-26 14:09:53 +01:00
committed by GitHub
parent 38d9b65ec8
commit aa81bbfe77
67 changed files with 3059 additions and 556 deletions

View File

@@ -1,13 +1,12 @@
import { ProjectLink } from '@/components/links';
import { SerieIcon } from '@/components/report-chart/common/serie-icon';
import { formatDateTime, formatTimeAgoOrDateTime } from '@/utils/date';
import type { ColumnDef } from '@tanstack/react-table';
import { ColumnCreatedAt } from '@/components/column-created-at';
import { ProfileAvatar } from '@/components/profiles/profile-avatar';
import { getProfileName } from '@/utils/getters';
import { round } from '@openpanel/common';
import type { IServiceSession } from '@openpanel/db';
import type { ColumnDef } from '@tanstack/react-table';
import { Video } from 'lucide-react';
import { ColumnCreatedAt } from '@/components/column-created-at';
import { ProjectLink } from '@/components/links';
import { ProfileAvatar } from '@/components/profiles/profile-avatar';
import { SerieIcon } from '@/components/report-chart/common/serie-icon';
import { getProfileName } from '@/utils/getters';
function formatDuration(milliseconds: number): string {
const seconds = milliseconds / 1000;
@@ -44,13 +43,25 @@ export function useColumns() {
cell: ({ row }) => {
const session = row.original;
return (
<ProjectLink
href={`/sessions/${session.id}`}
className="font-medium"
title={session.id}
>
{session.id.slice(0, 8)}...
</ProjectLink>
<div className="row items-center gap-2">
<ProjectLink
className="font-medium"
href={`/sessions/${session.id}`}
title={session.id}
>
{session.id.slice(0, 8)}...
</ProjectLink>
{session.hasReplay && (
<ProjectLink
aria-label="View replay"
className="text-muted-foreground hover:text-foreground"
href={`/sessions/${session.id}#replay`}
title="View replay"
>
<Video className="size-4" />
</ProjectLink>
)}
</div>
);
},
},
@@ -63,8 +74,8 @@ export function useColumns() {
if (session.profile) {
return (
<ProjectLink
className="row items-center gap-2 font-medium"
href={`/profiles/${encodeURIComponent(session.profile.id)}`}
className="font-medium row gap-2 items-center"
>
<ProfileAvatar size="sm" {...session.profile} />
{getProfileName(session.profile)}
@@ -73,8 +84,8 @@ export function useColumns() {
}
return (
<ProjectLink
className="font-medium font-mono"
href={`/profiles/${encodeURIComponent(session.profileId)}`}
className="font-mono font-medium"
>
{session.profileId}
</ProjectLink>