refactor(frontend): StackEventsPanel & ProfilePanel
This commit is contained in:
parent
dda632a5dd
commit
52c9edcc98
3 changed files with 77 additions and 119 deletions
|
|
@ -5,7 +5,6 @@ import { Tabs, Input, Icon, NoContent } from 'UI';
|
|||
import cn from 'classnames';
|
||||
import ConsoleRow from '../ConsoleRow';
|
||||
import useLatestRef from 'App/hooks/useLatestRef'
|
||||
import { getRE } from 'App/utils';
|
||||
import { PlayerContext } from 'App/components/Session/playerContext';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { List, CellMeasurer, CellMeasurerCache, AutoSizer } from 'react-virtualized';
|
||||
|
|
@ -159,7 +158,7 @@ function ConsolePanel() {
|
|||
|
||||
return (
|
||||
<BottomBlock
|
||||
style={{ height: 300 + 'px' }}
|
||||
style={{ height: '300px' }}
|
||||
onMouseEnter={onMouseEnter}
|
||||
onMouseLeave={onMouseLeave}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
import React, { useState } from 'react';
|
||||
import { TextEllipsis, Input } from 'UI';
|
||||
import { getRE } from 'App/utils';
|
||||
import { PlayerContext } from 'App/components/Session/playerContext';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { TextEllipsis, Input } from 'UI';
|
||||
import { PlayerContext } from 'App/components/Session/playerContext';
|
||||
import useInputState from 'App/hooks/useInputState'
|
||||
|
||||
import TimeTable from '../TimeTable';
|
||||
import BottomBlock from '../BottomBlock';
|
||||
import { useModal } from 'App/components/Modal';
|
||||
import ProfilerModal from '../ProfilerModal';
|
||||
import { useRegExListFilterMemo } from '../useListFilter'
|
||||
|
||||
const renderDuration = (p: any) => `${p.duration}ms`;
|
||||
const renderName = (p: any) => <TextEllipsis text={p.name} />;
|
||||
|
|
@ -15,19 +16,12 @@ const renderName = (p: any) => <TextEllipsis text={p.name} />;
|
|||
function ProfilerPanel() {
|
||||
const { store } = React.useContext(PlayerContext)
|
||||
|
||||
const profiles = store.get().profilesList
|
||||
const profiles = store.get().profilesList as any[] // TODO lest internal types
|
||||
|
||||
const { showModal } = useModal();
|
||||
const [filter, setFilter] = useState('');
|
||||
const filtered: any = React.useMemo(() => {
|
||||
const filterRE = getRE(filter, 'i');
|
||||
let list = profiles;
|
||||
const [ filter, onFilterChange ] = useInputState()
|
||||
const filtered = useRegExListFilterMemo(profiles, pr => pr.name, filter)
|
||||
|
||||
list = list.filter(({ name }: any) => (!!filter ? filterRE.test(name) : true));
|
||||
return list;
|
||||
}, [filter]);
|
||||
|
||||
const onFilterChange = ({ target: { value } }: any) => setFilter(value);
|
||||
const onRowClick = (profile: any) => {
|
||||
showModal(<ProfilerModal profile={profile} />, { right: true });
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,95 +1,61 @@
|
|||
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { hideHint } from 'Duck/components/player';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { Tooltip, Tabs, Input, NoContent, Icon, Toggler } from 'UI';
|
||||
import { getRE } from 'App/utils';
|
||||
import { List, CellMeasurer, CellMeasurerCache, AutoSizer } from 'react-virtualized';
|
||||
|
||||
import { PlayerContext } from 'App/components/Session/playerContext';
|
||||
import BottomBlock from '../BottomBlock';
|
||||
import { connectPlayer, jump } from 'Player';
|
||||
import { useModal } from 'App/components/Modal';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { useObserver } from 'mobx-react-lite';
|
||||
import { DATADOG, SENTRY, STACKDRIVER, typeList } from 'Types/session/stackEvent';
|
||||
import { connect } from 'react-redux';
|
||||
import { typeList } from 'Types/session/stackEvent';
|
||||
import StackEventRow from 'Shared/DevTools/StackEventRow';
|
||||
import StackEventModal from '../StackEventModal';
|
||||
|
||||
let timeOut: any = null;
|
||||
const TIMEOUT_DURATION = 5000;
|
||||
import StackEventModal from '../StackEventModal';
|
||||
import useAutoscroll from '../useAutoscroll';
|
||||
import { useRegExListFilterMemo, useTabListFilterMemo } from '../useListFilter'
|
||||
|
||||
const INDEX_KEY = 'stackEvent';
|
||||
const ALL = 'ALL';
|
||||
const TABS = [ALL, ...typeList].map((tab) => ({ text: tab, key: tab }));
|
||||
const TAB_KEYS = [ ALL, ...typeList] as const
|
||||
const TABS = TAB_KEYS.map((tab) => ({ text: tab, key: tab }))
|
||||
|
||||
function StackEventPanel() {
|
||||
const { player, store } = React.useContext(PlayerContext)
|
||||
const jump = (t: number) => player.jump(t)
|
||||
const { stackList: list, stackListNow: listNow } = store.get()
|
||||
|
||||
interface Props {
|
||||
list: any;
|
||||
hideHint: any;
|
||||
time: any;
|
||||
}
|
||||
function StackEventPanel(props: Props) {
|
||||
const { list, time } = props;
|
||||
const additionalHeight = 0;
|
||||
const {
|
||||
sessionStore: { devTools },
|
||||
} = useStore();
|
||||
const { showModal } = useModal();
|
||||
const [isDetailsModalActive, setIsDetailsModalActive] = useState(false);
|
||||
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({});
|
||||
synRef.current = {
|
||||
pauseSync,
|
||||
const [isDetailsModalActive, setIsDetailsModalActive] = useState(false) // TODO:embed that into useModal
|
||||
const filter = devTools[INDEX_KEY].filter
|
||||
const activeTab = devTools[INDEX_KEY].activeTab)
|
||||
const activeIndex = devTools[INDEX_KEY].index
|
||||
|
||||
let filteredList = useRegExListFilterMemo(list, it => it.name, filter)
|
||||
filteredList = useTabListFilterMemo(filteredList, it => it.source, ALL, activeTab)
|
||||
|
||||
const onTabClick = (activeTab: typeof TAB_KEYS[number]) => devTools.update(INDEX_KEY, { activeTab })
|
||||
const onFilterChange = ({ target: { value } }: any) => devTools.update(INDEX_KEY, { filter: value })
|
||||
|
||||
const tabs = useMemo(() =>
|
||||
TABS.filter(({ key }) => key === ALL || list.some(({ source }) => key === source)),
|
||||
[ list.length ],
|
||||
)
|
||||
|
||||
const {
|
||||
timeoutStartAutoscroll,
|
||||
stopAutoscroll,
|
||||
} = useAutoscroll(
|
||||
activeIndex,
|
||||
};
|
||||
const _list = React.useRef();
|
||||
|
||||
const onTabClick = (activeTab: any) => devTools.update(INDEX_KEY, { activeTab });
|
||||
const onFilterChange = ({ target: { value } }: any) => {
|
||||
devTools.update(INDEX_KEY, { filter: value });
|
||||
};
|
||||
|
||||
const getCurrentIndex = () => {
|
||||
return filteredList.filter((item: any) => item.time <= time).length - 1;
|
||||
};
|
||||
|
||||
const removePause = () => {
|
||||
clearTimeout(timeOut);
|
||||
setIsDetailsModalActive(false);
|
||||
timeOut = setTimeout(() => {
|
||||
devTools.update(INDEX_KEY, { index: getCurrentIndex() });
|
||||
setPauseSync(false);
|
||||
}, TIMEOUT_DURATION);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const currentIndex = getCurrentIndex();
|
||||
if (currentIndex !== activeIndex && !pauseSync) {
|
||||
devTools.update(INDEX_KEY, { index: currentIndex });
|
||||
}
|
||||
}, [time]);
|
||||
|
||||
listNow.length,
|
||||
index => devTools.update(INDEX_KEY, { index })
|
||||
)
|
||||
const onMouseEnter = stopAutoscroll
|
||||
const onMouseLeave = () => {
|
||||
if (isDetailsModalActive) return;
|
||||
removePause();
|
||||
};
|
||||
|
||||
React.useMemo(() => {
|
||||
const filterRE = getRE(filter, 'i');
|
||||
let list = props.list;
|
||||
|
||||
list = list.filter(
|
||||
({ name, source }: any) =>
|
||||
(!!filter ? filterRE.test(name) : true) && (activeTab === ALL || activeTab === source)
|
||||
);
|
||||
|
||||
setFilteredList(list);
|
||||
}, [filter, activeTab]);
|
||||
|
||||
const tabs = useMemo(() => {
|
||||
return TABS.filter(({ key }) => key === ALL || list.some(({ source }: any) => key === source));
|
||||
}, []);
|
||||
if (isDetailsModalActive) { return }
|
||||
timeoutStartAutoscroll()
|
||||
}
|
||||
|
||||
const cache = new CellMeasurerCache({
|
||||
fixedWidth: true,
|
||||
|
|
@ -97,11 +63,29 @@ function StackEventPanel(props: Props) {
|
|||
});
|
||||
|
||||
const showDetails = (item: any) => {
|
||||
setIsDetailsModalActive(true);
|
||||
showModal(<StackEventModal event={item} />, { right: true, onClose: removePause });
|
||||
devTools.update(INDEX_KEY, { index: filteredList.indexOf(item) });
|
||||
setPauseSync(true);
|
||||
};
|
||||
setIsDetailsModalActive(true)
|
||||
showModal(
|
||||
<StackEventModal event={item} />,
|
||||
{
|
||||
right: true,
|
||||
onClose: () => {
|
||||
setIsDetailsModalActive(false)
|
||||
timeoutStartAutoscroll()
|
||||
}
|
||||
}
|
||||
)
|
||||
devTools.update(INDEX_KEY, { index: filteredList.indexOf(item) })
|
||||
stopAutoscroll()
|
||||
}
|
||||
|
||||
const _list = React.useRef()
|
||||
useEffect(() => {
|
||||
if (_list.current) {
|
||||
// @ts-ignore
|
||||
_list.current.scrollToRow(activeIndex)
|
||||
}
|
||||
}, [ activeIndex ])
|
||||
|
||||
|
||||
const _rowRenderer = ({ index, key, parent, style }: any) => {
|
||||
const item = filteredList[index];
|
||||
|
|
@ -116,7 +100,7 @@ function StackEventPanel(props: Props) {
|
|||
key={item.key}
|
||||
event={item}
|
||||
onJump={() => {
|
||||
setPauseSync(true);
|
||||
stopAutoscroll()
|
||||
devTools.update(INDEX_KEY, { index: filteredList.indexOf(item) });
|
||||
jump(item.time);
|
||||
}}
|
||||
|
|
@ -125,19 +109,12 @@ function StackEventPanel(props: Props) {
|
|||
)}
|
||||
</CellMeasurer>
|
||||
);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (_list.current) {
|
||||
// @ts-ignore
|
||||
_list.current.scrollToRow(activeIndex);
|
||||
}
|
||||
}, [activeIndex]);
|
||||
}
|
||||
|
||||
return (
|
||||
<BottomBlock
|
||||
style={{ height: 300 + additionalHeight + 'px' }}
|
||||
onMouseEnter={() => setPauseSync(true)}
|
||||
style={{ height: '300px' }}
|
||||
onMouseEnter={onMouseEnter}
|
||||
onMouseLeave={onMouseLeave}
|
||||
>
|
||||
<BottomBlock.Header>
|
||||
|
|
@ -187,16 +164,4 @@ function StackEventPanel(props: Props) {
|
|||
);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
(state: any) => ({
|
||||
hintIsHidden:
|
||||
state.getIn(['components', 'player', 'hiddenHints', 'stack']) ||
|
||||
!state.getIn(['site', 'list']).some((s: any) => s.stackIntegrations),
|
||||
}),
|
||||
{ hideHint }
|
||||
)(
|
||||
connectPlayer((state: any) => ({
|
||||
list: state.stackList,
|
||||
time: state.time,
|
||||
}))(StackEventPanel)
|
||||
);
|
||||
export default observer(StackEventPanel)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue