Fix session profile replays for mobile layout
This commit is contained in:
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
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user