openreplay/frontend/app/components/Session/Player/ReplayPlayer/SummaryBlock/index.tsx
Delirium e0799f74e1
feat(ui): ai summary UI (#1868)
* feat(ui): start ai summary UI

* feat(ui): add api

* feat(ui): rm console log

* feat(ui): style fix

* feat(ui): some ui changes

* feat(ui): some ui changes

* feat(ui): some text formatting

* fix(ui): method fix

* fix(ui): fix icon gen

* fix(ui): fix global ts declaration for window env
2024-02-12 15:34:43 +01:00

85 lines
2.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React from 'react';
import Icon from 'UI/Icon';
import { useStore } from 'App/mstore';
import { observer } from 'mobx-react-lite';
const userBehaviorRegex = /User\s+(\w+\s+)?Behavior/i;
const issuesErrorsRegex = /Issues\s+(and\s+|,?\s+)?(\w+\s+)?Errors/i;
function testLine(line: string): boolean {
return userBehaviorRegex.test(line) || issuesErrorsRegex.test(line);
}
function SummaryBlock({ sessionId }: { sessionId: string }) {
const { aiSummaryStore } = useStore();
React.useEffect(() => {
void aiSummaryStore.getSummary(sessionId);
}, []);
const formattedText = aiSummaryStore.text.split('\n').map((line) => {
if (testLine(line)) {
return <div className={'font-semibold mt-2'}>{line}</div>;
}
if (line.startsWith('*')) {
return <li className={'ml-1 marker:mr-1'}>{line.replace('* ', '')}</li>;
}
return <div>{line}</div>;
});
return (
<div style={summaryBlockStyle}>
<div className={'flex items-center gap-2'}>
<Icon name={'sparkles'} size={18} />
<div className={'font-semibold text-xl'}>AI Summary</div>
</div>
{aiSummaryStore.text ? (
<div className={'rounded p-4 bg-white whitespace-pre-wrap flex flex-col'}>
<div>
Heres the AI breakdown of the session, covering user behavior and technical insights.
</div>
<>{formattedText.map((v) => v)}</>
</div>
) : (
<TextPlaceholder />
)}
</div>
);
}
function TextPlaceholder() {
return (
<div className={'animate-pulse rounded p-4 bg-white whitespace-pre-wrap flex flex-col gap-2'}>
<div className={'h-2 bg-gray-medium rounded'} />
<div className={'h-2 bg-gray-medium rounded'} />
<div className={'grid grid-cols-3 gap-2'}>
<div className={'h-2 bg-gray-medium rounded col-span-2'} />
<div className={'h-2 bg-gray-medium rounded col-span-1'} />
</div>
<div className={'grid grid-cols-4 gap-2 mt-3'}>
<div className={'h-2 bg-gray-medium rounded col-span-1'} />
<div className={'h-2 bg-gray-medium rounded col-span-1'} />
<div className={'h-2 bg-gray-medium rounded col-span-2'} />
</div>
<div className={'grid grid-cols-4 gap-2'}>
<div className={'h-2 bg-gray-medium rounded col-span-2'} />
<div className={'h-2 bg-transparent rounded col-span-2'} />
</div>
</div>
);
}
const summaryBlockStyle: React.CSSProperties = {
background: 'linear-gradient(156deg, #E3E6FF 0%, #E4F3F4 69.48%)',
width: '100%',
height: '100vh',
overflow: 'auto',
display: 'flex',
flexDirection: 'column',
gap: '0.5rem',
padding: '1rem',
};
export default observer(SummaryBlock);