类似云图日志分析, 后续补充图
支持功能
- 下载
- 复制
- 搜索
- 定位
- 行号
- 样式
- 全屏
- 回到顶部
- 虚拟加载
import React, { Fragment, PureComponent } from '@alipay/bigfish/react';
import { Empty, BackTop } from '@alipay/bigfish/antd';
import cs from '@alipay/bigfish/util/classnames';
import styles from './index.less';
export interface LogResultProps<T extends any> {
className?: string;
style?: React.CSSProperties;
logRender?: (item: T) => JSX.Element;
dataSource?: T[];
empty?: JSX.Element;
footerRender?: () => JSX.Element;
}
/**
* 1. 动态计算 height
* 2. 添加滚动顶部
* 3. 添加行数
*/
class LogResult<T> extends PureComponent<LogResultProps<T>> {
domRef: any = React.createRef<HTMLDivElement | null>();
static defaultProps: LogResultProps<any> = {
empty: <Empty />,
dataSource: [],
footerRender: () => <Fragment />,
};
getSnapshotBeforeUpdate(prevProps: LogResultProps<T>) {
// @ts-ignore
if (prevProps.dataSource?.length < this.props.dataSource?.length) {
const list = this.domRef.current;
return list.scrollHeight - list.scrollTop;
}
return null;
}
componentDidUpdate(
_prevProps: LogResultProps<T>,
_prevState: any,
snapshot: number
) {
if (snapshot !== null) {
const list = this.domRef.current;
list.scrollTop = list.scrollHeight - snapshot;
}
}
goToTop = () => {
if (this.domRef.current) {
this.domRef.current.scrollTop = 0;
}
};
renderLine = (item: T) => {
const { logRender } = this.props;
if (typeof logRender === 'function') {
return logRender(item);
}
return <span>{JSON.stringify(item)}</span>;
};
/** 动态计算最大 height */
render() {
const {
className,
empty,
style,
dataSource = [],
footerRender,
} = this.props;
const cls = cs(styles.wrapper, className);
return (
<div className={cls} style={style} ref={this.domRef}>
<div className={styles.content}>
{dataSource.length ? (
<Fragment>
{dataSource.map((item, index) => (
<Fragment key={index}>
<div className={styles.line}>{this.renderLine(item)}</div>
</Fragment>
))}
<BackTop
onClick={this.goToTop}
target={() => this.domRef.current}
visibilityHeight={200}
/>
</Fragment>
) : (
empty
)}
<div className="footer">{footerRender?.()}</div>
</div>
</div>
);
}
}
export default LogResult;
.wrapper {
.content {
counter-reset: line-numbering;
.line {
font-size: 12px;
line-height: 14px;
&::before {
display: inline-block;
padding-right: 1em;
content: counter(line-numbering);
counter-increment: line-numbering;
}
}
}
}