import React, { useEffect, useRef, useState } from 'react'; import { connectPlayer, jump } from 'Player'; import Log from 'Types/session/log'; import BottomBlock from '../BottomBlock'; import { LEVEL } from 'Types/session/log'; import { Tabs, Input, Icon, NoContent } from 'UI'; import cn from 'classnames'; import ConsoleRow from '../ConsoleRow'; import { getRE } from 'App/utils'; import { List, CellMeasurer, CellMeasurerCache, AutoSizer } from 'react-virtualized'; import { useObserver } from 'mobx-react-lite'; import { useStore } from 'App/mstore'; import ErrorDetailsModal from 'App/components/Dashboard/components/Errors/ErrorDetailsModal'; import { useModal } from 'App/components/Modal'; const ALL = 'ALL'; const INFO = 'INFO'; const WARNINGS = 'WARNINGS'; const ERRORS = 'ERRORS'; const LEVEL_TAB = { [LEVEL.INFO]: INFO, [LEVEL.LOG]: INFO, [LEVEL.WARNING]: WARNINGS, [LEVEL.ERROR]: ERRORS, [LEVEL.EXCEPTION]: ERRORS, }; const TABS = [ALL, ERRORS, WARNINGS, INFO].map((tab) => ({ text: tab, key: tab })); function renderWithNL(s = '') { if (typeof s !== 'string') return ''; return s.split('\n').map((line, i) =>
{line}
); } const getIconProps = (level: any) => { switch (level) { case LEVEL.INFO: case LEVEL.LOG: return { name: 'console/info', color: 'blue2', }; case LEVEL.WARN: case LEVEL.WARNING: return { name: 'console/warning', color: 'red2', }; case LEVEL.ERROR: return { name: 'console/error', color: 'red', }; } return null; }; const INDEX_KEY = 'console'; let timeOut: any = null; const TIMEOUT_DURATION = 5000; interface Props { logs: any; exceptions: any; time: any; } function ConsolePanel(props: Props) { const { logs, time } = props; const additionalHeight = 0; // const [activeTab, setActiveTab] = useState(ALL); // const [filter, setFilter] = useState(''); const { sessionStore: { devTools }, } = useStore(); const [filteredList, setFilteredList] = useState([]); const filter = useObserver(() => devTools[INDEX_KEY].filter); const activeTab = useObserver(() => devTools[INDEX_KEY].activeTab); const activeIndex = useObserver(() => devTools[INDEX_KEY].index); const [pauseSync, setPauseSync] = useState(activeIndex > 0); const synRef: any = useRef({}); const { showModal, component: modalActive } = useModal(); const onTabClick = (activeTab: any) => devTools.update(INDEX_KEY, { activeTab }); const onFilterChange = ({ target: { value } }: any) => { devTools.update(INDEX_KEY, { filter: value }); }; synRef.current = { pauseSync, activeIndex, }; const removePause = () => { if (!!modalActive) return; clearTimeout(timeOut); timeOut = setTimeout(() => { devTools.update(INDEX_KEY, { index: getCurrentIndex() }); setPauseSync(false); }, TIMEOUT_DURATION); }; const onMouseLeave = () => { removePause(); }; useEffect(() => { if (pauseSync) { removePause(); } return () => { clearTimeout(timeOut); if (!synRef.current.pauseSync) { devTools.update(INDEX_KEY, { index: 0 }); } }; }, []); const getCurrentIndex = () => { return filteredList.filter((item: any) => item.time <= time).length - 1; }; useEffect(() => { const currentIndex = getCurrentIndex(); if (currentIndex !== activeIndex && !pauseSync) { devTools.update(INDEX_KEY, { index: currentIndex }); } }, [time]); const cache = new CellMeasurerCache({ fixedWidth: true, keyMapper: (index: number) => filteredList[index], }); const _list = React.useRef(); const showDetails = (log: any) => { clearTimeout(timeOut); showModal(, { right: true, onClose: removePause }); devTools.update(INDEX_KEY, { index: filteredList.indexOf(log) }); setPauseSync(true); }; const _rowRenderer = ({ index, key, parent, style }: any) => { const item = filteredList[index]; return ( // @ts-ignore {({ measure }: any) => ( showDetails(item)} recalcHeight={() => { measure(); (_list as any).current.recomputeRowHeights(index); }} /> )} ); }; React.useMemo(() => { const filterRE = getRE(filter, 'i'); let list = logs; list = list.filter( ({ value, level }: any) => (!!filter ? filterRE.test(value) : true) && (activeTab === ALL || activeTab === LEVEL_TAB[level]) ); setFilteredList(list); }, [logs, filter, activeTab]); useEffect(() => { if (_list.current) { // @ts-ignore _list.current.scrollToRow(activeIndex); } }, [activeIndex]); return ( setPauseSync(true)} onMouseLeave={onMouseLeave} > {/* @ts-ignore */}
Console
{/* @ts-ignore */}
{/* @ts-ignore */} No Data } size="small" show={filteredList.length === 0} > {/* @ts-ignore */} {({ height, width }: any) => ( // @ts-ignore )} {/* @ts-ignore */}
); } export default connectPlayer((state: any) => { const logs = state.logList; const exceptions = state.exceptionsList; // TODO merge const logExceptions = exceptions.map(({ time, errorId, name, projectId }: any) => Log({ level: LEVEL.ERROR, value: name, time, errorId, }) ); return { time: state.time, logs: logs.concat(logExceptions), }; })(ConsolePanel);