change(ui): add unified row height to state tab, add virt to console tab

This commit is contained in:
sylenien 2022-11-18 14:34:00 +01:00 committed by Delirium
parent 605f047e90
commit a111dc95e9
6 changed files with 116 additions and 57 deletions

View file

@ -9,12 +9,14 @@ interface Props {
iconProps: any;
jump?: any;
renderWithNL?: any;
style?: any;
}
function ConsoleRow(props: Props) {
const { log, iconProps, jump, renderWithNL } = props;
const { log, iconProps, jump, renderWithNL, style } = props;
const [expanded, setExpanded] = useState(false);
const lines = log.value.split('\n').filter((l: any) => !!l);
const canExpand = lines.length > 1;
return (
<div
className={cn(stl.line, 'flex py-2 px-4 overflow-hidden group relative select-none', {
@ -23,6 +25,7 @@ function ConsoleRow(props: Props) {
error: log.isRed(),
'cursor-pointer': canExpand,
})}
style={style}
onClick={() => setExpanded(!expanded)}
>
<div className={cn(stl.timestamp)}>
@ -38,7 +41,7 @@ function ConsoleRow(props: Props) {
)}
<span>{renderWithNL(lines.pop())}</span>
</div>
{canExpand && expanded && lines.map((l: any) => <div className="ml-4 mb-1">{l}</div>)}
{canExpand && expanded && lines.map((l: any, i: number) => <div key={l.slice(0,3)+i} className="ml-4 mb-1">{l}</div>)}
</div>
<JumpButton onClick={() => jump(log.time)} />
</div>

View file

@ -63,17 +63,27 @@ function DiffRow({ diff, path }: Props) {
)}
>
{oldValueSafe || 'undefined'}
{diffLengths[0] > 50
? (
<div onClick={() => setShortenOldVal(!shortenOldVal)} className="cursor-pointer px-1 text-white bg-gray-light rounded text-sm w-fit">
{!shortenOldVal ? 'collapse' : 'expand'}
</div>
) : null}
</span>
{' -> '}
<span
onClick={() => setShortenNewVal(!shortenNewVal)}
className={cn(
'whitespace-pre',
newValue ? 'text-red' : 'text-green',
diffLengths[1] > 50 ? 'cursor-pointer' : ''
)}
>
{newValueSafe || 'undefined'}
{diffLengths[1] > 50
? (
<div onClick={() => setShortenNewVal(!shortenNewVal)} className="cursor-pointer px-1 text-white bg-gray-light rounded text-sm w-fit">
{!shortenNewVal ? 'collapse' : 'expand'}
</div>
) : null}
</span>
</div>
);

View file

@ -12,7 +12,6 @@ import { JSONTree, NoContent, Tooltip } from 'UI';
import { formatMs } from 'App/date';
import { diff } from 'deep-diff';
import { jump } from 'Player';
import Autoscroll from '../Autoscroll';
import BottomBlock from '../BottomBlock/index';
import DiffRow from './DiffRow';
import cn from 'classnames';
@ -22,6 +21,7 @@ import { List, CellMeasurer, CellMeasurerCache, AutoSizer } from 'react-virtuali
// const STATE = 'STATE';
// const DIFF = 'DIFF';
// const TABS = [ DIFF, STATE ].map(tab => ({ text: tab, key: tab }));
const ROW_HEIGHT = 90;
function getActionsName(type) {
switch (type) {
@ -48,8 +48,8 @@ function getActionsName(type) {
)
//@withEnumToggle('activeTab', 'setActiveTab', DIFF)
export default class Storage extends React.PureComponent {
constructor(props, ctx) {
super(props, ctx);
constructor(props) {
super(props);
this.lastBtnRef = React.createRef();
this._list = React.createRef();
@ -57,8 +57,6 @@ export default class Storage extends React.PureComponent {
fixedWidth: true,
keyMapper: index => this.props.listNow[index]
});
this._listNowLen = this.props.listNow.length
this._listLen = this.props.list.length
this._rowRenderer = this._rowRenderer.bind(this)
}
@ -72,27 +70,25 @@ export default class Storage extends React.PureComponent {
this.focusNextButton();
}
componentDidUpdate(prevProps) {
componentDidUpdate(prevProps, prevState) {
if (prevProps.listNow.length !== this.props.listNow.length) {
this.focusNextButton();
const newRows = this.props.listNow.filter(evt => prevProps.listNow.indexOf(evt.id) < 0);
console.log(newRows, this.props.listNow)
if (newRows.length > 0) {
const newRowsIndexes = newRows.map(r => this.props.listNow.indexOf(r))
newRowsIndexes.forEach(ind => this.cache.clean(ind))
this._list.recomputeRowHeights([...newRowsIndexes])
}
this._listNowLen = this.props.listNow.length
this._listLen = this.props.list.length
/** possible performance gain, but does not work with dynamic list insertion for some reason
* getting NaN offsets, maybe I detect changed rows wrongly
*/
// const newRows = this.props.listNow.filter(evt => prevProps.listNow.indexOf(evt._index) < 0);
// if (newRows.length > 0) {
// const newRowsIndexes = newRows.map(r => this.props.listNow.indexOf(r))
// newRowsIndexes.forEach(ind => this.cache.clear(ind))
// this._list.recomputeRowHeights(newRowsIndexes)
// }
}
}
renderDiff(item, prevItem) {
if (!prevItem) {
// we don't have state before first action
return <div style={{ flex: 1 }} className="p-1" />;
return <div style={{ flex: 3 }} className="p-1" />;
}
const stateDiff = diff(prevItem.state, item.state);
@ -106,7 +102,7 @@ export default class Storage extends React.PureComponent {
}
return (
<div style={{ flex: 3 }} className="flex flex-col p-1 font-mono">
<div style={{ flex: 3, maxHeight: ROW_HEIGHT, overflowY: 'scroll' }} className="flex flex-col p-1 font-mono">
{stateDiff.map((d, i) => this.renderDiffs(d, i))}
</div>
);
@ -114,6 +110,7 @@ export default class Storage extends React.PureComponent {
renderDiffs(diff, i) {
const path = this.createPath(diff);
return (
<React.Fragment key={i}>
<DiffRow shades={this.pathShades} path={path} diff={diff} />
@ -153,7 +150,7 @@ export default class Storage extends React.PureComponent {
return <JSONTree collapsed={2} src={listNow[listNow.length - 1].state} />;
}
renderItem(item, i, prevItem, style) {
renderItem(item, i, prevItem, style, measure) {
const { type } = this.props;
let src;
let name;
@ -179,10 +176,10 @@ export default class Storage extends React.PureComponent {
return (
<div
style={style}
style={{ ...style, height: ROW_HEIGHT }}
className={cn('flex justify-between items-start', src !== null ? 'border-b' : '')}
key={`store-${i}`}
onClick={() => this._list.recomputeRowHeights(i)}
// onClick={() => {measure(); this._list.recomputeRowHeights(i)}}
>
{src === null ? (
<div className="font-mono" style={{ flex: 2, marginLeft: '26.5%' }}>
@ -190,13 +187,14 @@ export default class Storage extends React.PureComponent {
</div>
) : (
<>
{this.renderDiff(item, prevItem)}
<div style={{ flex: 2 }} className="flex pl-10 pt-2">
{this.renderDiff(item, prevItem, i)}
<div style={{ flex: 2, maxHeight: ROW_HEIGHT, overflowY: 'scroll', overflowX: 'scroll' }} className="flex pl-10 pt-2">
<JSONTree
name={this.ensureString(name)}
src={src}
collapsed
collapseStringsAfterLength={7}
onSelect={() => console.log('test')}
/>
</div>
</>
@ -206,12 +204,12 @@ export default class Storage extends React.PureComponent {
<div className="font-size-12 color-gray-medium">{formatMs(item.duration)}</div>
)}
<div className="w-12">
{i + 1 < this._listNowLen && (
{i + 1 < this.props.listNow.length && (
<button className={stl.button} onClick={() => jump(item.time, item._index)}>
{'JUMP'}
</button>
)}
{i + 1 === this._listNowLen && i + 1 < this._listLen && (
{i + 1 === this.props.listNow.length && i + 1 < this.props.list.length && (
<button className={stl.button} ref={this.lastBtnRef} onClick={this.goNext}>
{'NEXT'}
</button>
@ -227,6 +225,9 @@ export default class Storage extends React.PureComponent {
// this.renderItem(item, i, i > 0 ? listNow[i - 1] : undefined, listNowLen, listLen)
// )
const { listNow } = this.props;
if (!listNow[index]) return console.warn(index, listNow)
return (
<CellMeasurer
cache={this.cache}
@ -235,7 +236,7 @@ export default class Storage extends React.PureComponent {
rowIndex={index}
parent={parent}
>
{this.renderItem(listNow[index], index, index > 0 ? listNow[index - 1] : undefined, style)}
{({ measure }) => this.renderItem(listNow[index], index, index > 0 ? listNow[index - 1] : undefined, style, measure)}
</CellMeasurer>
)
}
@ -351,9 +352,9 @@ export default class Storage extends React.PureComponent {
this._list = element;
}}
deferredMeasurementCache={this.cache}
overscanRowCount={2}
rowCount={this._listNowLen}
rowHeight={this.cache.rowHeight}
overscanRowCount={1}
rowCount={Math.ceil(parseInt(this.props.listNow.length) || 1)}
rowHeight={ROW_HEIGHT}
rowRenderer={this._rowRenderer}
width={width}
height={height}

View file

@ -8,6 +8,12 @@ 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';
const ALL = 'ALL';
const INFO = 'INFO';
@ -62,6 +68,34 @@ function ConsolePanel(props: Props) {
const [activeTab, setActiveTab] = useState(ALL);
const [filter, setFilter] = useState('');
const cache = new CellMeasurerCache({
fixedWidth: true,
keyMapper: (index: number) => filtered[index],
});
const _list = React.useRef();
const _rowRenderer = ({ index, key, parent, style }: any) => {
const item = filtered[index];
return (
<CellMeasurer cache={cache} columnIndex={0} key={key} rowIndex={index} parent={parent}>
{({ measure }: any) => (
<ConsoleRow
style={style}
log={item}
jump={jump}
iconProps={getIconProps(item.level)}
renderWithNL={renderWithNL}
recalcHeight={() => {
measure();
(_list as any).current.recomputeRowHeights(index);
}}
/>
)}
</CellMeasurer>
);
};
let filtered = React.useMemo(() => {
const filterRE = getRE(filter, 'i');
let list = logs;
@ -105,17 +139,20 @@ function ConsolePanel(props: Props) {
size="small"
show={filtered.length === 0}
>
{/* <Autoscroll> */}
{filtered.map((l: any, index: any) => (
<ConsoleRow
key={index}
log={l}
jump={jump}
iconProps={getIconProps(l.level)}
renderWithNL={renderWithNL}
<AutoSizer>
{({ height, width }: any) => (
<List
ref={_list}
deferredMeasurementCache={cache}
overscanRowCount={5}
rowCount={Math.ceil(filtered.length || 1)}
rowHeight={cache.rowHeight}
rowRenderer={_rowRenderer}
width={width}
height={height}
/>
))}
{/* </Autoscroll> */}
)}
</AutoSizer>
</NoContent>
</BottomBlock.Content>
</BottomBlock>

View file

@ -10,9 +10,11 @@ interface Props {
iconProps: any;
jump?: any;
renderWithNL?: any;
style?: any;
recalcHeight?: () => void;
}
function ConsoleRow(props: Props) {
const { log, iconProps, jump, renderWithNL } = props;
const { log, iconProps, jump, renderWithNL, style, recalcHeight } = props;
const { showModal } = useModal();
const [expanded, setExpanded] = useState(false);
const lines = log.value.split('\n').filter((l: any) => !!l);
@ -23,8 +25,14 @@ function ConsoleRow(props: Props) {
const onErrorClick = () => {
showModal(<ErrorDetailsModal errorId={log.errorId} />, { right: true });
};
const toggleExpand = () => {
setExpanded(!expanded)
setTimeout(() => recalcHeight(), 0)
}
return (
<div
style={style}
className={cn(
'border-b flex items-center py-2 px-4 overflow-hidden group relative select-none',
{
@ -36,7 +44,7 @@ function ConsoleRow(props: Props) {
}
)}
onClick={
clickable ? () => (!!log.errorId ? onErrorClick() : setExpanded(!expanded)) : () => {}
clickable ? () => (!!log.errorId ? onErrorClick() : toggleExpand()) : () => {}
}
>
<div className="mr-2">
@ -49,7 +57,7 @@ function ConsoleRow(props: Props) {
)}
<span>{renderWithNL(lines.pop())}</span>
</div>
{canExpand && expanded && lines.map((l: any) => <div className="ml-4 mb-1">{l}</div>)}
{canExpand && expanded && lines.map((l: string, i: number) => <div key={l.slice(0,4)+i} className="ml-4 mb-1">{l}</div>)}
</div>
<JumpButton onClick={() => jump(log.time)} />
</div>