mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-17 23:45:59 +00:00
column scroll
This commit is contained in:
@@ -48,10 +48,11 @@ export default function TabContent() {
|
||||
|
||||
return _.keys(mountedTabs).map(tabid => {
|
||||
const { TabComponent, props } = mountedTabs[tabid];
|
||||
const tabVisible = tabid == (selectedTab && selectedTab.tabid);
|
||||
return (
|
||||
// @ts-ignore
|
||||
<TabContainer key={tabid} tabVisible={tabid == (selectedTab && selectedTab.tabid)}>
|
||||
<TabComponent {...props} />
|
||||
<TabContainer key={tabid} tabVisible={tabVisible}>
|
||||
<TabComponent {...props} tabVisible={tabVisible} />
|
||||
</TabContainer>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -110,7 +110,7 @@ function CellFormattedValue({ value }) {
|
||||
|
||||
/** @param props {import('./types').DataGridProps} */
|
||||
export default function DataGridCore(props) {
|
||||
const { conid, database, display, isMainGrid } = props;
|
||||
const { conid, database, display, tabVisible } = props;
|
||||
const columns = display.getGridColumns();
|
||||
|
||||
// console.log(`GRID, conid=${conid}, database=${database}, sql=${sql}`);
|
||||
@@ -124,6 +124,12 @@ export default function DataGridCore(props) {
|
||||
|
||||
const loadedTimeRef = React.useRef(0);
|
||||
|
||||
const [vScrollValueToSet, setvScrollValueToSet] = React.useState();
|
||||
const [vScrollValueToSetDate, setvScrollValueToSetDate] = React.useState(new Date());
|
||||
|
||||
const [hScrollValueToSet, sethScrollValueToSet] = React.useState();
|
||||
const [hScrollValueToSetDate, sethScrollValueToSetDate] = React.useState(new Date());
|
||||
|
||||
const [currentCell, setCurrentCell] = React.useState(topLeftCell);
|
||||
const [selectedCells, setSelectedCells] = React.useState(emptyCellArray);
|
||||
const [dragStartCell, setDragStartCell] = React.useState(nullCell);
|
||||
@@ -186,19 +192,23 @@ export default function DataGridCore(props) {
|
||||
const [headerRowRef, { height: rowHeight }] = useDimensions();
|
||||
const [tableBodyRef] = useDimensions();
|
||||
const [containerRef, { height: containerHeight, width: containerWidth }] = useDimensions();
|
||||
const tableRef = React.useRef();
|
||||
const [tableRef, { height: tableHeight, width: tableWidth }, tableElement] = useDimensions();
|
||||
|
||||
const columnSizes = React.useMemo(() => countColumnSizes(), [loadedRows, containerWidth, display]);
|
||||
const headerColWidth = 40;
|
||||
|
||||
// console.log('containerWidth', containerWidth);
|
||||
|
||||
const gridScrollAreaHeight = containerHeight - 2 * rowHeight;
|
||||
const gridScrollAreaWidth = containerWidth - columnSizes.frozenSize;
|
||||
const gridScrollAreaWidth = containerWidth - columnSizes.frozenSize - headerColWidth;
|
||||
|
||||
const visibleRowCountUpperBound = Math.ceil(gridScrollAreaHeight / Math.floor(rowHeight));
|
||||
const visibleRowCountLowerBound = Math.floor(gridScrollAreaHeight / Math.ceil(rowHeight));
|
||||
// const visibleRowCountUpperBound = 20;
|
||||
// const visibleRowCountLowerBound = 20;
|
||||
// console.log('containerHeight', containerHeight);
|
||||
// console.log('visibleRowCountUpperBound', visibleRowCountUpperBound);
|
||||
// console.log('rowHeight', rowHeight);
|
||||
|
||||
const reload = () => {
|
||||
setLoadProps({
|
||||
@@ -221,11 +231,11 @@ export default function DataGridCore(props) {
|
||||
});
|
||||
|
||||
React.useEffect(() => {
|
||||
if (isMainGrid) {
|
||||
if (tabVisible) {
|
||||
// @ts-ignore
|
||||
if (tableRef.current) tableRef.current.focus();
|
||||
if (tableElement) tableElement.focus();
|
||||
}
|
||||
}, []);
|
||||
}, [tabVisible, tableElement]);
|
||||
|
||||
if (!loadedRows || !columns) return null;
|
||||
const rowCountNewIncluded = loadedRows.length;
|
||||
@@ -280,7 +290,7 @@ export default function DataGridCore(props) {
|
||||
// if (headerWidth > this.rowHeaderWidth) this.rowHeaderWidth = headerWidth;
|
||||
|
||||
context.font = '14px Helvetica';
|
||||
for (let row of loadedRows) {
|
||||
for (let row of loadedRows.slice(0, 20)) {
|
||||
for (let colIndex = 0; colIndex < columns.length; colIndex++) {
|
||||
let uqName = columns[colIndex].uniqueName;
|
||||
let text = row[uqName];
|
||||
@@ -397,9 +407,8 @@ export default function DataGridCore(props) {
|
||||
if (col < 0) col = 0;
|
||||
if (col >= columnSizes.realCount) col = columnSizes.realCount - 1;
|
||||
setCurrentCell([row, col]);
|
||||
if (!event.shiftKey) {
|
||||
setSelectedCells([]);
|
||||
}
|
||||
setSelectedCells([...(event.ctrlKey ? selectedCells : []), [row, col]]);
|
||||
scrollIntoView([row, col]);
|
||||
// this.selectedCells.push(this.currentCell);
|
||||
// this.scrollIntoView(this.currentCell);
|
||||
|
||||
@@ -407,6 +416,50 @@ export default function DataGridCore(props) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function scrollIntoView(cell) {
|
||||
const [row, col] = cell;
|
||||
|
||||
if (row != null) {
|
||||
let newRow = null;
|
||||
const rowCount = rowCountNewIncluded;
|
||||
|
||||
if (row < firstVisibleRowScrollIndex) newRow = row;
|
||||
else if (row + 1 >= firstVisibleRowScrollIndex + visibleRowCountLowerBound)
|
||||
newRow = row - visibleRowCountLowerBound + 2;
|
||||
|
||||
if (newRow < 0) newRow = 0;
|
||||
if (newRow >= rowCount) newRow = rowCount - 1;
|
||||
|
||||
if (newRow != null) {
|
||||
setFirstVisibleRowScrollIndex(newRow);
|
||||
// firstVisibleRowScrollIndex = newRow;
|
||||
setvScrollValueToSet(newRow);
|
||||
setvScrollValueToSetDate(new Date());
|
||||
// vscroll.value = newRow;
|
||||
}
|
||||
//int newRow = _rowSizes.ScrollInView(FirstVisibleRowScrollIndex, cell.Row.Value - _rowSizes.FrozenCount, GridScrollAreaHeight);
|
||||
//ScrollContent(newRow, FirstVisibleColumnScrollIndex);
|
||||
}
|
||||
|
||||
if (col != null) {
|
||||
if (col >= columnSizes.frozenCount) {
|
||||
let newColumn = columnSizes.scrollInView(
|
||||
firstVisibleColumnScrollIndex,
|
||||
col - columnSizes.frozenCount,
|
||||
gridScrollAreaWidth
|
||||
);
|
||||
setFirstVisibleColumnScrollIndex(newColumn);
|
||||
|
||||
// @ts-ignore
|
||||
sethScrollValueToSet(newColumn);
|
||||
sethScrollValueToSetDate(new Date());
|
||||
|
||||
// firstVisibleColumnScrollIndex = newColumn;
|
||||
// hscroll.value = newColumn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function cellIsSelected(row, col) {
|
||||
const [currentRow, currentCol] = currentCell;
|
||||
if (row == currentRow && col == currentCol) return true;
|
||||
@@ -424,7 +477,8 @@ export default function DataGridCore(props) {
|
||||
// console.log('containerHeight', containerHeight);
|
||||
|
||||
const visibleColumnCount = columnSizes.getVisibleScrollCount(firstVisibleColumnScrollIndex, gridScrollAreaWidth);
|
||||
// console.log('visibleColumnCount', visibleColumnCount);
|
||||
console.log('visibleColumnCount', visibleColumnCount);
|
||||
console.log('gridScrollAreaWidth', gridScrollAreaWidth);
|
||||
|
||||
const visibleRealColumnIndexes = [];
|
||||
const modelIndexes = {};
|
||||
@@ -459,7 +513,7 @@ export default function DataGridCore(props) {
|
||||
});
|
||||
}
|
||||
|
||||
const hederColwidthPx = '40px';
|
||||
const hederColwidthPx = `${headerColWidth}px`;
|
||||
const filterCount = display.filterCount;
|
||||
|
||||
const handleClearFilters = () => {
|
||||
@@ -467,6 +521,12 @@ export default function DataGridCore(props) {
|
||||
};
|
||||
|
||||
// console.log('visibleRealColumnIndexes', visibleRealColumnIndexes);
|
||||
console.log(
|
||||
'gridScrollAreaWidth / columnSizes.getVisibleScrollSizeSum()',
|
||||
gridScrollAreaWidth,
|
||||
columnSizes.getVisibleScrollSizeSum()
|
||||
);
|
||||
|
||||
return (
|
||||
<GridContainer ref={containerRef}>
|
||||
<Table
|
||||
@@ -524,14 +584,18 @@ export default function DataGridCore(props) {
|
||||
{loadedRows
|
||||
.slice(firstVisibleRowScrollIndex, firstVisibleRowScrollIndex + visibleRowCountUpperBound)
|
||||
.map((row, index) => (
|
||||
<TableBodyRow key={firstVisibleRowScrollIndex + index}>
|
||||
<TableBodyRow key={firstVisibleRowScrollIndex + index} style={{ height: `${rowHeight}px` }}>
|
||||
<TableHeaderCell data-row={firstVisibleRowScrollIndex + index} data-col="header">
|
||||
{firstVisibleRowScrollIndex + index + 1}
|
||||
</TableHeaderCell>
|
||||
{realColumns.map(col => (
|
||||
<TableBodyCell
|
||||
key={col.uniqueName}
|
||||
style={{ width: col.widthPx, minWidth: col.widthPx, maxWidth: col.widthPx }}
|
||||
style={{
|
||||
width: col.widthPx,
|
||||
minWidth: col.widthPx,
|
||||
maxWidth: col.widthPx,
|
||||
}}
|
||||
data-row={firstVisibleRowScrollIndex + index}
|
||||
data-col={col.colIndex}
|
||||
// @ts-ignore
|
||||
@@ -546,12 +610,16 @@ export default function DataGridCore(props) {
|
||||
</TableBody>
|
||||
</Table>
|
||||
<HorizontalScrollBar
|
||||
valueToSet={hScrollValueToSet}
|
||||
valueToSetDate={hScrollValueToSetDate}
|
||||
minimum={0}
|
||||
maximum={columns.length - 1}
|
||||
viewportRatio={gridScrollAreaWidth / columnSizes.getVisibleScrollSizeSum()}
|
||||
onScroll={handleColumnScroll}
|
||||
/>
|
||||
<VerticalScrollBar
|
||||
valueToSet={vScrollValueToSet}
|
||||
valueToSetDate={vScrollValueToSetDate}
|
||||
minimum={0}
|
||||
maximum={rowCountNewIncluded - visibleRowCountUpperBound + 2}
|
||||
onScroll={handleRowScroll}
|
||||
|
||||
331
packages/web/src/datagrid/SeriesSizes.ts
Normal file
331
packages/web/src/datagrid/SeriesSizes.ts
Normal file
@@ -0,0 +1,331 @@
|
||||
import _ from 'lodash';
|
||||
|
||||
export class SeriesSizeItem {
|
||||
public scrollIndex: number = -1;
|
||||
public modelIndex: number;
|
||||
public frozenIndex: number = -1;
|
||||
public size: number;
|
||||
public position: number;
|
||||
public get endPosition(): number {
|
||||
return this.position + this.size;
|
||||
}
|
||||
}
|
||||
|
||||
export class SeriesSizes {
|
||||
private sizeOverridesByModelIndex: { [id: number]: number } = {};
|
||||
public count: number = 0;
|
||||
public defaultSize: number = 50;
|
||||
public maxSize: number = 1000;
|
||||
private hiddenAndFrozenModelIndexes: number[] = [];
|
||||
private frozenModelIndexes: number[] = [];
|
||||
private hiddenModelIndexes: number[] = [];
|
||||
private scrollItems: SeriesSizeItem[] = [];
|
||||
private positions: number[] = [];
|
||||
private scrollIndexes: number[] = [];
|
||||
private frozenItems: SeriesSizeItem[] = [];
|
||||
|
||||
public get scrollCount(): number {
|
||||
return this.count - (this.hiddenAndFrozenModelIndexes != null ? this.hiddenAndFrozenModelIndexes.length : 0);
|
||||
}
|
||||
public get frozenCount(): number {
|
||||
return this.frozenModelIndexes != null ? this.frozenModelIndexes.length : 0;
|
||||
}
|
||||
public get frozenSize(): number {
|
||||
return _.sumBy(this.frozenItems, x => x.size);
|
||||
}
|
||||
public get realCount(): number {
|
||||
return this.frozenCount + this.scrollCount;
|
||||
}
|
||||
|
||||
// public clear(): void {
|
||||
// this.scrollItems = [];
|
||||
// this.sizeOverridesByModelIndex = {};
|
||||
// this.positions = [];
|
||||
// this.scrollIndexes = [];
|
||||
// this.frozenItems = [];
|
||||
// this.hiddenAndFrozenModelIndexes = null;
|
||||
// this.frozenModelIndexes = null;
|
||||
// }
|
||||
public putSizeOverride(modelIndex: number, size: number, sizeByUser = false): void {
|
||||
if (this.maxSize && size > this.maxSize && !sizeByUser) {
|
||||
size = this.maxSize;
|
||||
}
|
||||
|
||||
let currentSize = this.sizeOverridesByModelIndex[modelIndex];
|
||||
if (sizeByUser || !currentSize || size > currentSize) {
|
||||
this.sizeOverridesByModelIndex[modelIndex] = size;
|
||||
}
|
||||
// if (!_.has(this.sizeOverridesByModelIndex, modelIndex))
|
||||
// this.sizeOverridesByModelIndex[modelIndex] = size;
|
||||
// if (size > this.sizeOverridesByModelIndex[modelIndex])
|
||||
// this.sizeOverridesByModelIndex[modelIndex] = size;
|
||||
}
|
||||
public buildIndex(): void {
|
||||
this.scrollItems = [];
|
||||
this.scrollIndexes = _.filter(
|
||||
_.map(this.intKeys(this.sizeOverridesByModelIndex), x => this.modelToReal(x) - this.frozenCount),
|
||||
x => x >= 0
|
||||
);
|
||||
this.scrollIndexes.sort();
|
||||
let lastScrollIndex: number = -1;
|
||||
let lastEndPosition: number = 0;
|
||||
this.scrollIndexes.forEach(scrollIndex => {
|
||||
let modelIndex: number = this.realToModel(scrollIndex + this.frozenCount);
|
||||
let size: number = this.sizeOverridesByModelIndex[modelIndex];
|
||||
let item = new SeriesSizeItem();
|
||||
item.scrollIndex = scrollIndex;
|
||||
item.modelIndex = modelIndex;
|
||||
item.size = size;
|
||||
item.position = lastEndPosition + (scrollIndex - lastScrollIndex - 1) * this.defaultSize;
|
||||
this.scrollItems.push(item);
|
||||
lastScrollIndex = scrollIndex;
|
||||
lastEndPosition = item.endPosition;
|
||||
});
|
||||
this.positions = _.map(this.scrollItems, x => x.position);
|
||||
this.frozenItems = [];
|
||||
let lastpos: number = 0;
|
||||
for (let i: number = 0; i < this.frozenCount; i++) {
|
||||
let modelIndex: number = this.frozenModelIndexes[i];
|
||||
let size: number = this.getSizeByModelIndex(modelIndex);
|
||||
let item = new SeriesSizeItem();
|
||||
item.frozenIndex = i;
|
||||
item.modelIndex = modelIndex;
|
||||
item.size = size;
|
||||
item.position = lastpos;
|
||||
this.frozenItems.push(item);
|
||||
lastpos += size;
|
||||
}
|
||||
}
|
||||
|
||||
public getScrollIndexOnPosition(position: number): number {
|
||||
let itemOrder: number = _.sortedIndex(this.positions, position);
|
||||
if (this.positions[itemOrder] == position) return itemOrder;
|
||||
if (itemOrder == 0) return Math.floor(position / this.defaultSize);
|
||||
if (position <= this.scrollItems[itemOrder - 1].endPosition) return this.scrollItems[itemOrder - 1].scrollIndex;
|
||||
return (
|
||||
Math.floor((position - this.scrollItems[itemOrder - 1].position) / this.defaultSize) +
|
||||
this.scrollItems[itemOrder - 1].scrollIndex
|
||||
);
|
||||
}
|
||||
public getFrozenIndexOnPosition(position: number): number {
|
||||
this.frozenItems.forEach(function(item) {
|
||||
if (position >= item.position && position <= item.endPosition) return item.frozenIndex;
|
||||
});
|
||||
return -1;
|
||||
}
|
||||
// public getSizeSum(startScrollIndex: number, endScrollIndex: number): number {
|
||||
// let order1: number = _.sortedIndexOf(this.scrollIndexes, startScrollIndex);
|
||||
// let order2: number = _.sortedIndexOf(this.scrollIndexes, endScrollIndex);
|
||||
// let count: number = endScrollIndex - startScrollIndex;
|
||||
// if (order1 < 0)
|
||||
// order1 = ~order1;
|
||||
// if (order2 < 0)
|
||||
// order2 = ~order2;
|
||||
// let result: number = 0;
|
||||
// for (let i: number = order1; i <= order2; i++) {
|
||||
// if (i < 0)
|
||||
// continue;
|
||||
// if (i >= this.scrollItems.length)
|
||||
// continue;
|
||||
// let item = this.scrollItems[i];
|
||||
// if (item.scrollIndex < startScrollIndex)
|
||||
// continue;
|
||||
// if (item.scrollIndex >= endScrollIndex)
|
||||
// continue;
|
||||
// result += item.size;
|
||||
// count--;
|
||||
// }
|
||||
// result += count * this.defaultSize;
|
||||
// return result;
|
||||
// }
|
||||
public getSizeByModelIndex(modelIndex: number): number {
|
||||
if (_.has(this.sizeOverridesByModelIndex, modelIndex)) return this.sizeOverridesByModelIndex[modelIndex];
|
||||
return this.defaultSize;
|
||||
}
|
||||
public getSizeByScrollIndex(scrollIndex: number): number {
|
||||
return this.getSizeByRealIndex(scrollIndex + this.frozenCount);
|
||||
}
|
||||
public getSizeByRealIndex(realIndex: number): number {
|
||||
let modelIndex: number = this.realToModel(realIndex);
|
||||
return this.getSizeByModelIndex(modelIndex);
|
||||
}
|
||||
public removeSizeOverride(realIndex: number): void {
|
||||
let modelIndex: number = this.realToModel(realIndex);
|
||||
delete this.sizeOverridesByModelIndex[modelIndex];
|
||||
}
|
||||
public getScroll(sourceScrollIndex: number, targetScrollIndex: number): number {
|
||||
if (sourceScrollIndex < targetScrollIndex) {
|
||||
return -_.sum(
|
||||
_.map(_.range(sourceScrollIndex, targetScrollIndex - sourceScrollIndex), x => this.getSizeByScrollIndex(x))
|
||||
);
|
||||
} else {
|
||||
return _.sum(
|
||||
_.map(_.range(targetScrollIndex, sourceScrollIndex - targetScrollIndex), x => this.getSizeByScrollIndex(x))
|
||||
);
|
||||
}
|
||||
}
|
||||
public modelIndexIsInScrollArea(modelIndex: number): boolean {
|
||||
let realIndex = this.modelToReal(modelIndex);
|
||||
return realIndex >= this.frozenCount;
|
||||
}
|
||||
public getTotalScrollSizeSum(): number {
|
||||
let scrollSizeOverrides = _.map(
|
||||
_.filter(this.intKeys(this.sizeOverridesByModelIndex), x => this.modelIndexIsInScrollArea(x)),
|
||||
x => this.sizeOverridesByModelIndex[x]
|
||||
);
|
||||
return _.sum(scrollSizeOverrides) + (this.count - scrollSizeOverrides.length) * this.defaultSize;
|
||||
}
|
||||
public getVisibleScrollSizeSum(): number {
|
||||
let scrollSizeOverrides = _.map(
|
||||
_.filter(this.intKeys(this.sizeOverridesByModelIndex), x => !_.includes(this.hiddenAndFrozenModelIndexes, x)),
|
||||
x => this.sizeOverridesByModelIndex[x]
|
||||
);
|
||||
return (
|
||||
_.sum(scrollSizeOverrides) +
|
||||
(this.count - this.hiddenModelIndexes.length - scrollSizeOverrides.length) * this.defaultSize
|
||||
);
|
||||
}
|
||||
private intKeys(value): number[] {
|
||||
return _.keys(value).map(x => _.parseInt(x));
|
||||
}
|
||||
public getPositionByRealIndex(realIndex: number): number {
|
||||
if (realIndex < 0) return 0;
|
||||
if (realIndex < this.frozenCount) return this.frozenItems[realIndex].position;
|
||||
return this.getPositionByScrollIndex(realIndex - this.frozenCount);
|
||||
}
|
||||
public getPositionByScrollIndex(scrollIndex: number): number {
|
||||
let order: number = _.sortedIndex(this.scrollIndexes, scrollIndex);
|
||||
if (this.scrollIndexes[order] == scrollIndex) return this.scrollItems[order].position;
|
||||
order--;
|
||||
if (order < 0) return scrollIndex * this.defaultSize;
|
||||
return (
|
||||
this.scrollItems[order].endPosition + (scrollIndex - this.scrollItems[order].scrollIndex - 1) * this.defaultSize
|
||||
);
|
||||
}
|
||||
public getVisibleScrollCount(firstVisibleIndex: number, viewportSize: number): number {
|
||||
let res: number = 0;
|
||||
let index: number = firstVisibleIndex;
|
||||
let count: number = 0;
|
||||
while (res < viewportSize && index <= this.scrollCount) {
|
||||
res += this.getSizeByScrollIndex(index);
|
||||
index++;
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
public getVisibleScrollCountReversed(lastVisibleIndex: number, viewportSize: number): number {
|
||||
let res: number = 0;
|
||||
let index: number = lastVisibleIndex;
|
||||
let count: number = 0;
|
||||
while (res < viewportSize && index >= 0) {
|
||||
res += this.getSizeByScrollIndex(index);
|
||||
index--;
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
public invalidateAfterScroll(
|
||||
oldFirstVisible: number,
|
||||
newFirstVisible: number,
|
||||
invalidate: (_: number) => void,
|
||||
viewportSize: number
|
||||
): void {
|
||||
if (newFirstVisible > oldFirstVisible) {
|
||||
let oldVisibleCount: number = this.getVisibleScrollCount(oldFirstVisible, viewportSize);
|
||||
let newVisibleCount: number = this.getVisibleScrollCount(newFirstVisible, viewportSize);
|
||||
for (let i: number = oldFirstVisible + oldVisibleCount - 1; i <= newFirstVisible + newVisibleCount; i++) {
|
||||
invalidate(i + this.frozenCount);
|
||||
}
|
||||
} else {
|
||||
for (let i: number = newFirstVisible; i <= oldFirstVisible; i++) {
|
||||
invalidate(i + this.frozenCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
public isWholeInView(firstVisibleIndex: number, index: number, viewportSize: number): boolean {
|
||||
let res: number = 0;
|
||||
let testedIndex: number = firstVisibleIndex;
|
||||
while (res < viewportSize && testedIndex < this.count) {
|
||||
res += this.getSizeByScrollIndex(testedIndex);
|
||||
if (testedIndex == index) return res <= viewportSize;
|
||||
testedIndex++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public scrollInView(firstVisibleIndex: number, scrollIndex: number, viewportSize: number): number {
|
||||
if (this.isWholeInView(firstVisibleIndex, scrollIndex, viewportSize)) {
|
||||
return firstVisibleIndex;
|
||||
}
|
||||
if (scrollIndex < firstVisibleIndex) {
|
||||
return scrollIndex;
|
||||
}
|
||||
let res: number = 0;
|
||||
let testedIndex: number = scrollIndex;
|
||||
while (res < viewportSize && testedIndex >= 0) {
|
||||
let size: number = this.getSizeByScrollIndex(testedIndex);
|
||||
if (res + size > viewportSize) return testedIndex + 1;
|
||||
testedIndex--;
|
||||
res += size;
|
||||
}
|
||||
if (res >= viewportSize && testedIndex < scrollIndex) return testedIndex + 1;
|
||||
return firstVisibleIndex;
|
||||
}
|
||||
public resize(realIndex: number, newSize: number): void {
|
||||
if (realIndex < 0) return;
|
||||
let modelIndex: number = this.realToModel(realIndex);
|
||||
if (modelIndex < 0) return;
|
||||
this.sizeOverridesByModelIndex[modelIndex] = newSize;
|
||||
this.buildIndex();
|
||||
}
|
||||
public setExtraordinaryIndexes(hidden: number[], frozen: number[]): void {
|
||||
//this._hiddenAndFrozenModelIndexes = _.clone(hidden);
|
||||
hidden = hidden.filter(x => x >= 0);
|
||||
frozen = frozen.filter(x => x >= 0);
|
||||
|
||||
hidden.sort((a, b) => a - b);
|
||||
frozen.sort((a, b) => a - b);
|
||||
this.frozenModelIndexes = _.filter(frozen, x => !_.includes(hidden, x));
|
||||
this.hiddenModelIndexes = _.filter(hidden, x => !_.includes(frozen, x));
|
||||
this.hiddenAndFrozenModelIndexes = _.concat(hidden, this.frozenModelIndexes);
|
||||
this.frozenModelIndexes.sort((a, b) => a - b);
|
||||
if (this.hiddenAndFrozenModelIndexes.length == 0) this.hiddenAndFrozenModelIndexes = null;
|
||||
if (this.frozenModelIndexes.length == 0) this.frozenModelIndexes = null;
|
||||
this.buildIndex();
|
||||
}
|
||||
public realToModel(realIndex: number): number {
|
||||
if (this.hiddenAndFrozenModelIndexes == null && this.frozenModelIndexes == null) return realIndex;
|
||||
if (realIndex < 0) return -1;
|
||||
if (realIndex < this.frozenCount && this.frozenModelIndexes != null) return this.frozenModelIndexes[realIndex];
|
||||
if (this.hiddenAndFrozenModelIndexes == null) return realIndex;
|
||||
realIndex -= this.frozenCount;
|
||||
for (let hidItem of this.hiddenAndFrozenModelIndexes) {
|
||||
if (realIndex < hidItem) return realIndex;
|
||||
realIndex++;
|
||||
}
|
||||
return realIndex;
|
||||
}
|
||||
public modelToReal(modelIndex: number): number {
|
||||
if (this.hiddenAndFrozenModelIndexes == null && this.frozenModelIndexes == null) return modelIndex;
|
||||
if (modelIndex < 0) return -1;
|
||||
let frozenIndex: number = this.frozenModelIndexes != null ? _.indexOf(this.frozenModelIndexes, modelIndex) : -1;
|
||||
if (frozenIndex >= 0) return frozenIndex;
|
||||
if (this.hiddenAndFrozenModelIndexes == null) return modelIndex;
|
||||
let hiddenIndex: number = _.sortedIndex(this.hiddenAndFrozenModelIndexes, modelIndex);
|
||||
if (this.hiddenAndFrozenModelIndexes[hiddenIndex] == modelIndex) return -1;
|
||||
if (hiddenIndex >= 0) return modelIndex - hiddenIndex + this.frozenCount;
|
||||
return modelIndex;
|
||||
}
|
||||
public getFrozenPosition(frozenIndex: number): number {
|
||||
return this.frozenItems[frozenIndex].position;
|
||||
}
|
||||
public hasSizeOverride(modelIndex: number): boolean {
|
||||
return _.has(this.sizeOverridesByModelIndex, modelIndex);
|
||||
}
|
||||
public isVisible(testedRealIndex: number, firstVisibleScrollIndex: number, viewportSize: number): boolean {
|
||||
if (testedRealIndex < 0) return false;
|
||||
if (testedRealIndex >= 0 && testedRealIndex < this.frozenCount) return true;
|
||||
let scrollIndex: number = testedRealIndex - this.frozenCount;
|
||||
let onPageIndex: number = scrollIndex - firstVisibleScrollIndex;
|
||||
return onPageIndex >= 0 && onPageIndex < this.getVisibleScrollCount(firstVisibleScrollIndex, viewportSize);
|
||||
}
|
||||
}
|
||||
@@ -4,5 +4,5 @@ export interface DataGridProps {
|
||||
conid: number;
|
||||
database: string;
|
||||
display: GridDisplay;
|
||||
isMainGrid?: boolean;
|
||||
tabVisible?: boolean;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import useConnectionInfo from '../utility/useConnectionInfo';
|
||||
import engines from '@dbgate/engines';
|
||||
import getTableInfo from '../utility/getTableInfo';
|
||||
|
||||
export default function TableDataTab({ conid, database, schemaName, pureName }) {
|
||||
export default function TableDataTab({ conid, database, schemaName, pureName, tabVisible }) {
|
||||
const tableInfo = useTableInfo({ conid, database, schemaName, pureName });
|
||||
const [config, setConfig] = React.useState(createGridConfig());
|
||||
const [cache, setCache] = React.useState(createGridCache());
|
||||
@@ -24,7 +24,7 @@ export default function TableDataTab({ conid, database, schemaName, pureName })
|
||||
conid={conid}
|
||||
database={database}
|
||||
display={display}
|
||||
isMainGrid
|
||||
tabVisible={tabVisible}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user