ui: add jump and sync for backend logs

This commit is contained in:
nick-delirium 2024-10-29 17:14:57 +01:00
parent 36edfd8413
commit fc63e4d83d
No known key found for this signature in database
GPG key ID: 93ABD695DF5FDBA0
2 changed files with 51 additions and 42 deletions

View file

@ -2,6 +2,7 @@ import { useQuery } from '@tanstack/react-query';
import { Segmented } from 'antd';
import React from 'react';
import { VList, VListHandle } from 'virtua';
import { PlayerContext } from "App/components/Session/playerContext";
import { processLog, UnifiedLog } from './utils';
import { observer } from 'mobx-react-lite';
import { useStore } from 'App/mstore';
@ -32,6 +33,7 @@ async function fetchLogs(
const logsResp = await fetch(json.url)
if (logsResp.ok) {
const logJson = await logsResp.json()
if (logJson.length === 0) return []
return processLog(logJson)
} else {
throw new Error('Failed to fetch logs')
@ -59,16 +61,7 @@ function BackendLogsPanel() {
enabled: tab !== null,
retry: 3,
});
console.log(isError, isPending, isSuccess)
const [filter, setFilter] = React.useState('');
const _list = React.useRef<VListHandle>(null);
const activeIndex = 1;
React.useEffect(() => {
if (_list.current) {
_list.current.scrollToIndex(activeIndex);
}
}, [activeIndex]);
const onFilterChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setFilter(e.target.value);
@ -122,40 +115,44 @@ function BackendLogsPanel() {
/>
) : null}
{isSuccess ? (
<>
<TableHeader size={data.length} />
<VList ref={_list} count={testLogs.length}>
{data.map((log, index) => (
<LogRow key={index} log={log} />
))}
</VList>
</>
<LogsTable data={data} />
) : null}
</BottomBlock.Content>
</BottomBlock>
);
}
const testLogs = [
{
key: 1,
timestamp: '2021-09-01 12:00:00',
status: 'INFO',
content: 'This is a test log',
},
{
key: 2,
timestamp: '2021-09-01 12:00:00',
status: 'WARN',
content: 'This is a test log',
},
{
key: 3,
timestamp: '2021-09-01 12:00:00',
status: 'ERROR',
content:
'This is a test log that is very long and should be truncated to fit in the table cell and it will be displayed later in a separate thing when clicked on a row because its so long you never gonna give htem up or alskjhaskfjhqwfhwekfqwfjkqlwhfkjqhflqkwjhefqwklfehqwlkfjhqwlkjfhqwe \n kjhdafskjfhlqkwjhfwelefkhwqlkqehfkqlwehfkqwhefkqhwefkjqwhf',
},
];
const LogsTable = observer(({ data }: { data: UnifiedLog[] }) => {
const { store, player } = React.useContext(PlayerContext);
const time = store.get().time;
const sessionStart = store.get().sessionStart;
const _list = React.useRef<VListHandle>(null);
const activeIndex = React.useMemo(() => {
const currTs = time + sessionStart;
const index = data.findIndex(
(log) => log.timestamp !== 'N/A' ? new Date(log.timestamp).getTime() >= currTs : false
);
return index === -1 ? data.length - 1 : index;
}, [time, data.length]);
React.useEffect(() => {
if (_list.current) {
_list.current.scrollToIndex(activeIndex);
}
}, [activeIndex]);
const onJump = (ts: number) => {
player.jump(ts - sessionStart);
}
return (
<>
<TableHeader size={data.length} />
<VList ref={_list} count={data.length}>
{data.map((log, index) => (
<LogRow key={index} isActive={index === activeIndex} log={log} onJump={onJump} />
))}
</VList>
</>
)
});
export default observer(BackendLogsPanel);

View file

@ -5,6 +5,7 @@ import { Button } from 'antd';
import cn from 'classnames';
import copy from 'copy-to-clipboard';
import { getDateFromString } from 'App/date';
import JumpButton from 'App/components/shared/DevTools/JumpButton';
export function TableHeader({ size }: { size: number }) {
return (
@ -28,8 +29,12 @@ export function TableHeader({ size }: { size: number }) {
export function LogRow({
log,
onJump,
isActive,
}: {
log: { timestamp: string; status: string; content: string };
onJump: (ts: number) => void;
isActive?: boolean;
}) {
const [isExpanded, setIsExpanded] = React.useState(false);
const bg = (status: string) => {
@ -54,13 +59,16 @@ export function LogRow({
return 'border-l border-l-4 border-gray-lighter';
};
return (
<div className={'code-font'}>
<div
className={'code-font relative group'}
>
<JumpButton onClick={() => onJump(new Date(log.timestamp).getTime())} />
<div
className={cn(
'text-sm grid items-center py-2 px-4',
'cursor-pointer border-b border-b-gray-light last:border-b-0',
border(log.status),
bg(log.status)
isActive ? 'bg-gray-lightest' : bg(log.status)
)}
style={{
gridTemplateColumns: 'repeat(14, minmax(0, 1fr))',
@ -90,10 +98,14 @@ export function LogRow({
</div>
</div>
{isExpanded ? (
<div className={'rounded bg-gray-lightest px-4 py-2 relative mx-4 my-2'}>
<div
className={'rounded bg-gray-lightest px-4 py-2 relative mx-4 my-2'}
>
{log.content.split('\n').map((line, index) => (
<div key={index} className={'flex items-start gap-2'}>
<div className={'border-r border-r-gray-light pr-2 select-none'}>{index}</div>
<div className={'border-r border-r-gray-light pr-2 select-none'}>
{index}
</div>
<div className={'whitespace-pre-wrap'}>{line}</div>
</div>
))}