mirror of
https://github.com/dbgate/dbgate
synced 2024-11-07 20:26:23 +00:00
datagrid
This commit is contained in:
parent
c2dc4d76ba
commit
4bfba2ec02
@ -1,5 +1,5 @@
|
|||||||
:root {
|
:root {
|
||||||
--dim-widget-icon-size: 50px;
|
--dim-widget-icon-size: 60px;
|
||||||
--dim-statusbar-height: 20px;
|
--dim-statusbar-height: 20px;
|
||||||
--dim-left-panel-width: 300px;
|
--dim-left-panel-width: 300px;
|
||||||
--dim-tabs-panel-height: 53px;
|
--dim-tabs-panel-height: 53px;
|
||||||
|
@ -11,6 +11,30 @@
|
|||||||
enabledStore: derived([currentDataGrid], ([grid]) => grid != null),
|
enabledStore: derived([currentDataGrid], ([grid]) => grid != null),
|
||||||
onClick: () => get(currentDataGrid).refresh(),
|
onClick: () => get(currentDataGrid).refresh(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function getRowCountInfo(selectedCells, grider, realColumnUniqueNames, selectedRowData, allRowCount) {
|
||||||
|
if (selectedCells.length > 1 && selectedCells.every(x => _.isNumber(x[0]) && _.isNumber(x[1]))) {
|
||||||
|
let sum = _.sumBy(selectedCells, cell => {
|
||||||
|
const row = grider.getRowData(cell[0]);
|
||||||
|
if (row) {
|
||||||
|
const colName = realColumnUniqueNames[cell[1]];
|
||||||
|
if (colName) {
|
||||||
|
const data = row[colName];
|
||||||
|
if (!data) return 0;
|
||||||
|
let num = +data;
|
||||||
|
if (_.isNaN(num)) return 0;
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
let count = selectedCells.length;
|
||||||
|
let rowCount = selectedRowData.length;
|
||||||
|
return `Rows: ${rowCount.toLocaleString()}, Count: ${count.toLocaleString()}, Sum:${sum.toLocaleString()}`;
|
||||||
|
}
|
||||||
|
if (allRowCount == null) return 'Loading row count...';
|
||||||
|
return `Rows: ${allRowCount.toLocaleString()}`;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
@ -31,6 +55,7 @@
|
|||||||
import HorizontalScrollBar from './HorizontalScrollBar.svelte';
|
import HorizontalScrollBar from './HorizontalScrollBar.svelte';
|
||||||
import { cellFromEvent, emptyCellArray, getCellRange, isRegularCell, nullCell, topLeftCell } from './selection';
|
import { cellFromEvent, emptyCellArray, getCellRange, isRegularCell, nullCell, topLeftCell } from './selection';
|
||||||
import VerticalScrollBar from './VerticalScrollBar.svelte';
|
import VerticalScrollBar from './VerticalScrollBar.svelte';
|
||||||
|
import LoadingInfo from '../widgets/LoadingInfo.svelte';
|
||||||
|
|
||||||
export let loadNextData = undefined;
|
export let loadNextData = undefined;
|
||||||
export let grider = undefined;
|
export let grider = undefined;
|
||||||
@ -38,6 +63,8 @@
|
|||||||
export let conid = undefined;
|
export let conid = undefined;
|
||||||
export let database = undefined;
|
export let database = undefined;
|
||||||
export let frameSelection = undefined;
|
export let frameSelection = undefined;
|
||||||
|
export let isLoading = false;
|
||||||
|
export let allRowCount = undefined;
|
||||||
|
|
||||||
const wheelRowCount = 5;
|
const wheelRowCount = 5;
|
||||||
const instance = get_current_component();
|
const instance = get_current_component();
|
||||||
@ -209,6 +236,28 @@
|
|||||||
export function refresh() {
|
export function refresh() {
|
||||||
display.reload();
|
display.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getSelectedRowIndexes() {
|
||||||
|
if (selectedCells.find(x => x[0] == 'header')) return _.range(0, grider.rowCount);
|
||||||
|
return _.uniq((selectedCells || []).map(x => x[0])).filter(x => _.isNumber(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSelectedColumnIndexes() {
|
||||||
|
if (selectedCells.find(x => x[1] == 'header')) return _.range(0, realColumnUniqueNames.length);
|
||||||
|
return _.uniq((selectedCells || []).map(x => x[1])).filter(x => _.isNumber(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSelectedRowData() {
|
||||||
|
return _.compact(getSelectedRowIndexes().map(index => grider.getRowData(index)));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSelectedColumns() {
|
||||||
|
return _.compact(
|
||||||
|
getSelectedColumnIndexes().map(index => ({
|
||||||
|
columnName: realColumnUniqueNames[index],
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="container" bind:clientWidth={containerWidth} bind:clientHeight={containerHeight}>
|
<div class="container" bind:clientWidth={containerWidth} bind:clientHeight={containerHeight}>
|
||||||
@ -250,16 +299,18 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{#each _.range(firstVisibleRowScrollIndex, firstVisibleRowScrollIndex + visibleRowCountUpperBound) as rowIndex (rowIndex)}
|
{#each _.range(firstVisibleRowScrollIndex, firstVisibleRowScrollIndex + visibleRowCountUpperBound) as rowIndex (rowIndex)}
|
||||||
<DataGridRow
|
{#if rowIndex < grider.rowCount}
|
||||||
{rowIndex}
|
<DataGridRow
|
||||||
{grider}
|
{rowIndex}
|
||||||
{visibleRealColumns}
|
{grider}
|
||||||
{rowHeight}
|
{visibleRealColumns}
|
||||||
{autofillSelectedCells}
|
{rowHeight}
|
||||||
selectedCells={filterCellsForRow(selectedCells, rowIndex)}
|
{autofillSelectedCells}
|
||||||
autofillMarkerCell={filterCellForRow(autofillMarkerCell, rowIndex)}
|
selectedCells={filterCellsForRow(selectedCells, rowIndex)}
|
||||||
{frameSelection}
|
autofillMarkerCell={filterCellForRow(autofillMarkerCell, rowIndex)}
|
||||||
/>
|
{frameSelection}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@ -277,6 +328,15 @@
|
|||||||
on:scroll={e => (firstVisibleRowScrollIndex = e.detail)}
|
on:scroll={e => (firstVisibleRowScrollIndex = e.detail)}
|
||||||
bind:this={domVerticalScroll}
|
bind:this={domVerticalScroll}
|
||||||
/>
|
/>
|
||||||
|
{#if allRowCount}
|
||||||
|
<div class="row-count-label">
|
||||||
|
{getRowCountInfo(selectedCells, grider, realColumnUniqueNames, getSelectedRowData(), allRowCount)}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if isLoading}
|
||||||
|
<LoadingInfo wrapper message="Loading data" />
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -15,28 +15,35 @@
|
|||||||
let allRowCount = null;
|
let allRowCount = null;
|
||||||
let errorMessage = null;
|
let errorMessage = null;
|
||||||
let loadNextDataToken = 0;
|
let loadNextDataToken = 0;
|
||||||
|
const loadedTimeRef = { current: null };
|
||||||
|
|
||||||
|
const handleLoadRowCount = async () => {
|
||||||
|
const rowCount = await loadRowCount($$props);
|
||||||
|
allRowCount = rowCount;
|
||||||
|
};
|
||||||
|
|
||||||
async function loadNextData() {
|
async function loadNextData() {
|
||||||
if (isLoading) return;
|
if (isLoading) return;
|
||||||
isLoading = true;
|
isLoading = true;
|
||||||
|
|
||||||
const loadStart = new Date().getTime();
|
const loadStart = new Date().getTime();
|
||||||
|
// await new Promise(resolve => setTimeout(resolve, 5000));
|
||||||
|
|
||||||
// loadedTimeRef.current = loadStart;
|
loadedTimeRef.current = loadStart;
|
||||||
// console.log('LOAD NEXT ROWS', loadedRows);
|
// console.log('LOAD NEXT ROWS', loadedRows);
|
||||||
|
|
||||||
const nextRows = await loadDataPage($$props, loadedRows.length, 100);
|
const nextRows = await loadDataPage($$props, loadedRows.length, 100);
|
||||||
// if (loadedTimeRef.current !== loadStart) {
|
if (loadedTimeRef.current !== loadStart) {
|
||||||
// // new load was dispatched
|
// new load was dispatched
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
|
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
|
|
||||||
if (nextRows.errorMessage) {
|
if (nextRows.errorMessage) {
|
||||||
errorMessage = nextRows.errorMessage;
|
errorMessage = nextRows.errorMessage;
|
||||||
} else {
|
} else {
|
||||||
// if (allRowCount == null) handleLoadRowCount();
|
if (allRowCount == null) handleLoadRowCount();
|
||||||
loadedRows = [...loadedRows, ...nextRows];
|
loadedRows = [...loadedRows, ...nextRows];
|
||||||
isLoadedAll = nextRows.length === 0;
|
isLoadedAll = nextRows.length === 0;
|
||||||
// const loadedInfo = {
|
// const loadedInfo = {
|
||||||
@ -82,8 +89,4 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<DataGridCore
|
<DataGridCore {...$$props} loadNextData={handleLoadNextData} {grider} {isLoading} {allRowCount} />
|
||||||
{...$$props}
|
|
||||||
loadNextData={handleLoadNextData}
|
|
||||||
{grider}
|
|
||||||
/>
|
|
||||||
|
@ -47,8 +47,8 @@
|
|||||||
justify-content: space-around;
|
justify-content: space-around;
|
||||||
}
|
}
|
||||||
.box {
|
.box {
|
||||||
background-color: var(--thme-bg-2);
|
background-color: var(--theme-bg-2);
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border: 1px solid gray;
|
border: 1px solid var(--theme-border);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
Loading…
Reference in New Issue
Block a user