Commit c09b2491 by zhaochengxiang

虚拟滚动低版本兼容

parent 90b7e8b0
......@@ -2,7 +2,7 @@ import React, { useState, useEffect, useRef, useMemo } from "react";
import { Tooltip, Modal, Table, Typography } from 'antd';
import LocalStorage from 'local-storage';
import DataGrid from '../../VirtualTable';
import DataGrid, { defaultPageSize } from '../../VirtualTable';
import { dispatch } from '../../../../model';
import { showMessage, getQueryParam, isSzseEnv, formatDate, getDataModelerRole } from '../../../../util';
import { AnchorId, AnchorTimestamp, Action, CatalogId, ModelerId, DataModelerRoleReader } from '../../../../util/constant';
......@@ -10,7 +10,6 @@ import ExpandedModelTable from "./ExpandedModelTable";
// import Tag from "../../Tag";
import { useContextMenu, Menu as RcMenu, Item as RcItem } from "react-contexify";
import './ModelTable.less';
import 'react-contexify/dist/ReactContexify.css';
......@@ -99,6 +98,7 @@ const ModelTable = (props) => {
const [ selectedRowKeys, setSelectedRowKeys ] = useState([]);
const [ expandedSelectedRowKeys, setExpandedSelectedRowKeys ] = useState([]);
const [ currentItem, setCurrentItem ] = useState(null);
const [ scrollRowIndex, setScrollRowIndex ] = useState();
const expandedDataMapRef = useRef(new Map());
const shouldScrollRef = useRef(false);
......@@ -247,6 +247,14 @@ const ModelTable = (props) => {
}, [selectedRowKeys, expandedSelectedRowKeys, data])
useEffect(() => {
if (data && gridRef.current) {
setTimeout(() => {
gridRef.current?.scrollToRow(0);
}, 100)
}
}, [data])
useEffect(() => {
window?.addEventListener("storage", modelEventChange);
return () => {
window?.removeEventListener("storage", modelEventChange);
......@@ -277,8 +285,9 @@ const ModelTable = (props) => {
useEffect(() => {
if (shouldScrollRef.current && gridRef.current && offset!==null && (data||[]).length>0) {
setScrollRowIndex(offset);
setTimeout(() => {
gridRef.current?.scrollToRow(offset-1);
gridRef.current?.scrollToRow((offset-1)%defaultPageSize);
shouldScrollRef.current = false;
}, 300)
}
......@@ -497,11 +506,15 @@ const ModelTable = (props) => {
style={{ blockSize: 'calc(100vh - 94px - 37px - 57px - 24px - 32px)' }}
checkable
columns={columns}
// rows={Array.from({ length: 10000 }).map((_, i) => ({
// name: 'test',
// }))}
rows={data||[]}
rowHeight={51}
rowClassName={(row) => {
return (row.id === anchorId)?'anchor':''
}}
scrollRowIndex={scrollRowIndex}
expandable={expandable}
onContextMenu={(e, row) => {
setCurrentItem(row);
......
......@@ -6,6 +6,7 @@ import type { CheckboxChangeEvent } from 'antd/es/checkbox';
import { DownOutlined, UpOutlined } from '@ant-design/icons';
import { downNode, upNode } from './virtual-table-helper';
import { paginate } from '../../../util';
import './index.less';
......@@ -43,6 +44,7 @@ interface Props<Row> {
onSelectedRowsChange?: (selectedRows: Array<any>) => void
rowHeight?: number
rowClassName?: (row: RowData) => string
scrollRowIndex: number
}
const CheckboxFormatter = forwardRef<HTMLInputElement, CheckboxFormatterProps>(
......@@ -102,13 +104,15 @@ export function getExpandingCol<Row extends RowData, SR>({ colSpan, expandRender
return col
}
export const defaultPageSize = 800
function FC<Row extends RowData, SR, K extends React.Key = React.Key>(props: DataGridProps<Row, SR, K> & Props<Row>) {
const {
gridRef,
expandable,
getComparator,
loadMoreRows,
onSelectedRowsChange, columns, rows, checkable, selectedRows, rowHeight = 45, rowClassName, onContextMenu, ...rest } = props
onSelectedRowsChange, columns, rows, checkable, selectedRows, rowHeight = 45, rowClassName, onContextMenu, scrollRowIndex, ...rest } = props
const rowKeyGetter = (row: Row): K => {
return row.id as K;
......@@ -135,10 +139,27 @@ function FC<Row extends RowData, SR, K extends React.Key = React.Key>(props: Dat
// 已排序行
const [sortColumns, setSortColumns] = useState<readonly SortColumn[]>([]); // 排序列图标状态
const [_rows, _setRows] = useState<readonly Row[]>([])
const [pagination, setPagination] = useState({ pageNum: 1, pageSize: defaultPageSize });
const {pageNum, pageSize} = pagination;
useEffect(() => {
const newRows = [...rows];
if (rows) {
setPagination(prev => {
return {...prev, pageNum: 1}
})
}
}, [rows])
useEffect(() => {
if (scrollRowIndex) {
setPagination(prev => {
return {...prev, pageNum: parseInt((scrollRowIndex/defaultPageSize + ((scrollRowIndex%defaultPageSize===0)?0:1)).toString())}
})
}
}, [scrollRowIndex])
useEffect(() => {
const newRows = [...paginate(rows, pageNum, pageSize)];
if (sortColumns.length > 0) {
newRows
// .filter(item => item.__type__ !== RowType.Detail)
......@@ -155,12 +176,11 @@ function FC<Row extends RowData, SR, K extends React.Key = React.Key>(props: Dat
}
(newRows||[]).forEach((item, index) => {
item.index = `${index+1}`;
item.index = `${(pageNum-1)*pageSize+index+1}`;
})
_setRows(newRows);
}, [rows, sortColumns, getComparator]);
}, [sortColumns, getComparator, pagination]);
// 组装功能s列
const cols = useMemo(() => {
......@@ -196,9 +216,23 @@ function FC<Row extends RowData, SR, K extends React.Key = React.Key>(props: Dat
// 处理滚动
const handleScroll = useCallback((event: React.UIEvent<HTMLDivElement>) => {
if (!isAtBottom(event)) return;
loadMoreRows?.(rows.length)
}, [loadMoreRows, rows])
if (isAtTop(event)) {
if (pageNum > 1) {
setPagination(prev => {
return {...prev, pageNum: prev.pageNum-1}
})
}
} else if (isAtBottom(event)) {
if (rows?.length > pageNum* pageSize) {
event.currentTarget.scrollTop = 0;
setPagination(prev => {
return {...prev, pageNum: prev.pageNum+1}
})
}
}
// loadMoreRows?.(rows.length)
}, [loadMoreRows, rows, pageNum])
return (
<div className='virtual-table'>
......@@ -243,7 +277,7 @@ function FC<Row extends RowData, SR, K extends React.Key = React.Key>(props: Dat
onSelectedRowsChange && onSelectedRowsChange(Array.from(values));
}}
// 滚动
onScroll={loadMoreRows ? handleScroll : undefined}
onScroll={handleScroll}
/>
</div>
);
......@@ -260,6 +294,10 @@ function GetComparator(sortColumn: string): (a: any, b: any) => number {
};
}
function isAtTop({ currentTarget }: React.UIEvent<HTMLDivElement>): boolean {
return currentTarget.scrollTop === 0;
}
function isAtBottom({ currentTarget }: React.UIEvent<HTMLDivElement>): boolean {
return currentTarget.scrollTop + 10 >= currentTarget.scrollHeight - currentTarget.clientHeight;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment