Fix session profile replays for mobile layout

This commit is contained in:
Francis Cao committed 2026-08-04 11:20:17 -07:00
1 parent 9bb1f5519a
commit 80d02254ae
5 files changed
+49 -14

No files matched your search

@@ -7,6 +7,7 @@ import { Avatar } from '@/components/common/Avatar';
import { LoadingPanel } from '@/components/common/LoadingPanel';
import {
useMessages,
useMobile,
useReplayQuery,
useReplaySavedQuery,
useUpdateQuery,
@@ -36,6 +37,7 @@ export function ReplayPlayback({
const { data: replaySaved } = useReplaySavedQuery(websiteId, replayId);
const { data: session } = useWebsiteSessionQuery(websiteId, replay?.sessionId);
const { t, labels } = useMessages();
const { isMobile } = useMobile();
const [isSaved, setIsSaved] = useState<boolean | null>(null);
const { mutate } = useUpdateQuery(`/websites/${websiteId}/replays/saved/${replayId}`);
const replayViewport = useMemo(() => getReplayViewport(replay?.events), [replay?.events]);
@@ -67,19 +69,24 @@ export function ReplayPlayback({
style={{ minHeight: '400px' }}
>
{replay && (
<Column gap="6">
<Column gap="6" width="100%" minWidth="0">
{session && (
<Row justifyContent="space-between" alignItems="flex-start">
<Row alignItems="center" gap="4">
<Row
justifyContent="space-between"
alignItems="flex-start"
gap="3"
style={{ flexWrap: isMobile ? 'wrap' : 'nowrap' }}
>
<Row alignItems="center" gap="4" minWidth="0" style={{ flex: '1 1 240px' }}>
<Avatar seed={replay.sessionId} size={48} />
<Column>
<Column minWidth="0">
<Text weight="bold">{t(labels.replay)}</Text>
<Text color="muted">
{replay.eventCount} {t(labels.actions).toLowerCase()}
</Text>
</Column>
</Row>
<Row gap="2">
<Row gap="2" style={{ flex: '0 0 auto' }}>
{saved ? (
<Button onPress={handleUnsave} variant="quiet">
<Icon>
@@ -2,7 +2,7 @@
import { Column, Dialog, Modal, type ModalProps } from '@umami/react-zen';
import { SessionProfile } from '@/app/(main)/websites/[websiteId]/sessions/SessionProfile';
import { ControlledDialog } from '@/components/common/ControlledDialog';
import { useNavigation } from '@/components/hooks';
import { useMobile, useNavigation } from '@/components/hooks';
import styles from './SessionModal.module.css';
export interface SessionModalProps extends ModalProps {
@@ -16,6 +16,7 @@ export function SessionModal({ websiteId, className, ...props }: SessionModalPro
query: { session },
updateParams,
} = useNavigation();
const { isMobile } = useMobile();
const isSharePage = pathname.includes('/share/');
const handleOpenChange = (isOpen: boolean) => {
if (!isOpen) {
@@ -34,7 +35,7 @@ export function SessionModal({ websiteId, className, ...props }: SessionModalPro
<Column height="100%">
<Dialog className="h-full rounded-lg">
{({ close }) => (
<Column padding="10">
<Column padding={isMobile ? '6' : '10'} minWidth="0" width="100%">
<SessionProfile
websiteId={websiteId}
sessionId={session}
@@ -57,7 +57,7 @@ export function SessionProfile({
loadingPlacement="absolute"
>
{data && (
<Column gap>
<Column gap width="100%" minWidth="0">
{onClose && (
<Row justifyContent="flex-end" gap="1">
{showDeleteButton && (
@@ -74,7 +74,7 @@ export function SessionProfile({
</Button>
</Row>
)}
<Column gap="6">
<Column gap="6" width="100%" minWidth="0">
<Row
justifyContent="center"
alignItems="center"
@@ -108,7 +108,7 @@ export function SessionProfile({
<SessionData sessionId={sessionId} websiteId={websiteId} />
</TabPanel>
{showReplays && (
<TabPanel id="replays">
<TabPanel id="replays" style={{ width: '100%', minWidth: 0, overflowX: 'hidden' }}>
<SessionReplaysDataTable websiteId={websiteId} sessionId={sessionId} />
</TabPanel>
)}
@@ -2,7 +2,7 @@
import { Column } from '@umami/react-zen';
import { useState } from 'react';
import { DataGrid } from '@/components/common/DataGrid';
import { useSessionReplaysQuery } from '@/components/hooks';
import { useMobile, useSessionReplaysQuery } from '@/components/hooks';
import { ReplayPlayback } from '../replays/[replayId]/ReplayPlayback';
import { SessionReplaysTable } from './SessionReplaysTable';
@@ -10,13 +10,22 @@ function InlinePlayer({
websiteId,
replayId,
onClose,
isMobile,
}: {
websiteId: string;
replayId: string;
onClose: () => void;
isMobile: boolean;
}) {
return (
<div style={{ padding: '1.5rem 0' }}>
<div
style={{
padding: isMobile ? '0.75rem 0' : '1.5rem 0',
width: '100%',
maxWidth: '100%',
overflowX: 'hidden',
}}
>
<ReplayPlayback
websiteId={websiteId}
replayId={replayId}
@@ -34,6 +43,7 @@ export function SessionReplaysDataTable({
websiteId: string;
sessionId: string;
}) {
const { isMobile } = useMobile();
const queryResult = useSessionReplaysQuery(websiteId, sessionId);
const [selectedId, setSelectedId] = useState<string | undefined>();
@@ -42,12 +52,13 @@ export function SessionReplaysDataTable({
};
return (
<Column>
<Column width="100%" minWidth="0">
{selectedId && (
<InlinePlayer
websiteId={websiteId}
replayId={selectedId}
onClose={() => setSelectedId(undefined)}
isMobile={isMobile}
/>
)}
<DataGrid query={queryResult} allowPaging>
+17 -1
View File
@@ -86,6 +86,7 @@ select:is(:-webkit-autofill, :autofill):focus {
height: auto !important;
padding: 8px 0 10px;
gap: 8px;
overflow: hidden;
}
.rr-timeline {
@@ -95,7 +96,7 @@ select:is(:-webkit-autofill, :autofill):focus {
.rr-timeline__time {
width: auto !important;
min-width: 52px;
min-width: 44px;
font-size: 12px;
}
@@ -105,8 +106,23 @@ select:is(:-webkit-autofill, :autofill):focus {
.rr-controller__btns {
width: calc(100% - 24px);
box-sizing: border-box;
flex-wrap: wrap;
justify-content: center;
column-gap: 6px;
row-gap: 8px;
font-size: 12px;
overflow: hidden;
}
.rr-controller__btns button {
width: 28px;
height: 28px;
flex: 0 0 28px;
}
.rr-controller__btns .label {
margin: 0 4px;
font-size: 12px;
}
}