diff --git a/packages/web/src/datagrid/ChangeSetDataGrid.js b/packages/web/src/datagrid/ChangeSetDataGrid.js
new file mode 100644
index 00000000..3c20ec51
--- /dev/null
+++ b/packages/web/src/datagrid/ChangeSetDataGrid.js
@@ -0,0 +1,17 @@
+import { getChangeSetInsertedRows } from '@dbgate/datalib';
+import React from 'react';
+import DataGridCore from './DataGridCore';
+
+export default function ChangeSetDataGrid(props) {
+ const { changeSet, display, dispatchChangeSet } = props;
+ function undo() {
+ dispatchChangeSet({ type: 'undo' });
+ }
+ function redo() {
+ dispatchChangeSet({ type: 'redo' });
+ }
+
+ const insertedRows = getChangeSetInsertedRows(changeSet, display.baseTable);
+
+ return ;
+}
diff --git a/packages/web/src/datagrid/DataGrid.js b/packages/web/src/datagrid/DataGrid.js
index 36db2362..f7cfb19c 100644
--- a/packages/web/src/datagrid/DataGrid.js
+++ b/packages/web/src/datagrid/DataGrid.js
@@ -42,7 +42,7 @@ const DataGridContainer = styled.div`
flex-grow: 1;
`;
-/** @param props {import('./types').DataGridProps} */
+/** @param props {import('./types').LoadingDataGridProps} */
export default function DataGrid(props) {
const Container1 = props.showReferences ? ManagerOuterContainer1 : ManagerOuterContainerFull;
const [managerSize, setManagerSize] = React.useState(0);
diff --git a/packages/web/src/datagrid/DataGridCore.js b/packages/web/src/datagrid/DataGridCore.js
index e7e5791a..d67480e8 100644
--- a/packages/web/src/datagrid/DataGridCore.js
+++ b/packages/web/src/datagrid/DataGridCore.js
@@ -126,98 +126,35 @@ const LoadingInfoBox = styled.div`
border: 1px solid gray;
`;
-/** @param props {import('./types').DataGridProps} */
-async function loadDataPage(props, offset, limit) {
- const { display, conid, database, jslid } = props;
-
- if (jslid) {
- const response = await axios.request({
- url: 'jsldata/get-rows',
- method: 'get',
- params: {
- jslid,
- offset,
- limit,
- },
- });
- return response.data;
- }
-
- const sql = display.getPageQuery(offset, limit);
-
- const response = await axios.request({
- url: 'database-connections/query-data',
- method: 'post',
- params: {
- conid,
- database,
- },
- data: { sql },
- });
-
- if (response.data.errorMessage) return response.data;
- return response.data.rows;
-}
-
-function dataPageAvailable(props) {
- const { display, jslid } = props;
- if (jslid) return true;
- const sql = display.getPageQuery(0, 1);
- return !!sql;
-}
-
-/** @param props {import('./types').DataGridProps} */
-async function loadRowCount(props) {
- const { display, conid, database, jslid } = props;
-
- if (jslid) {
- const response = await axios.request({
- url: 'jsldata/get-stats',
- method: 'get',
- params: {
- jslid,
- },
- });
- return response.data.rowCount;
- }
-
- const sql = display.getCountQuery();
-
- const response = await axios.request({
- url: 'database-connections/query-data',
- method: 'post',
- params: {
- conid,
- database,
- },
- data: { sql },
- });
-
- return parseInt(response.data.rows[0].count);
-}
-
-/** @param props {import('./types').DataGridProps} */
+/** @param props {import('./types').DataGridCoreProps} */
export default function DataGridCore(props) {
- const { conid, database, display, changeSetState, dispatchChangeSet, tabVisible, jslid } = props;
+ const {
+ display,
+ conid,
+ database,
+ changeSetState,
+ dispatchChangeSet,
+ tabVisible,
+ rows,
+ loadNextData,
+ errorMessage,
+ isLoadedAll,
+ loadedTime,
+ exportGrid,
+ allRowCount,
+ openQuery,
+ insertedRowCount,
+ isLoading,
+ undo,
+ redo
+ } = props;
// console.log('RENDER GRID', display.baseTable.pureName);
const columns = React.useMemo(() => display.allColumns, [display]);
// usePropsCompare(props);
// console.log(`GRID, conid=${conid}, database=${database}, sql=${sql}`);
- const [loadProps, setLoadProps] = React.useState({
- isLoading: false,
- loadedRows: [],
- isLoadedAll: false,
- loadedTime: new Date().getTime(),
- allRowCount: null,
- errorMessage: null,
- jslStatsCounter: 0,
- jslChangeIndex: 0,
- });
- const { isLoading, loadedRows, isLoadedAll, loadedTime, allRowCount, errorMessage } = loadProps;
- const loadedTimeRef = React.useRef(0);
const focusFieldRef = React.useRef(null);
const [vScrollValueToSet, setvScrollValueToSet] = React.useState();
@@ -239,14 +176,6 @@ export default function DataGridCore(props) {
// const [inplaceEditorShouldSave, setInplaceEditorShouldSave] = React.useState(false);
// const [inplaceEditorChangedOnCreate, setInplaceEditorChangedOnCreate] = React.useState(false);
- const changeSet = changeSetState && changeSetState.value;
- const setChangeSet = React.useCallback((value) => dispatchChangeSet({ type: 'set', value }), [dispatchChangeSet]);
- const setOpenedTabs = useSetOpenedTabs();
-
- const changeSetRef = React.useRef(changeSet);
-
- changeSetRef.current = changeSet;
-
const autofillMarkerCell = React.useMemo(
() =>
selectedCells && selectedCells.length > 0 && _.uniq(selectedCells.map((x) => x[0])).length == 1
@@ -257,54 +186,6 @@ export default function DataGridCore(props) {
const showModal = useShowModal();
- const handleLoadRowCount = async () => {
- const rowCount = await loadRowCount(props);
- setLoadProps((oldLoadProps) => ({
- ...oldLoadProps,
- allRowCount: rowCount,
- }));
- };
-
- const loadNextData = async () => {
- if (isLoading) return;
- setLoadProps((oldLoadProps) => ({
- ...oldLoadProps,
- isLoading: true,
- }));
- const loadStart = new Date().getTime();
- loadedTimeRef.current = loadStart;
-
- const nextRows = await loadDataPage(props, loadedRows.length, 100);
- if (loadedTimeRef.current !== loadStart) {
- // new load was dispatched
- return;
- }
- // if (!_.isArray(nextRows)) {
- // console.log('Error loading data from server', nextRows);
- // nextRows = [];
- // }
- // console.log('nextRows', nextRows);
- if (nextRows.errorMessage) {
- setLoadProps((oldLoadProps) => ({
- ...oldLoadProps,
- isLoading: false,
- errorMessage: nextRows.errorMessage,
- }));
- } else {
- if (allRowCount == null) handleLoadRowCount();
- const loadedInfo = {
- loadedRows: [...loadedRows, ...nextRows],
- loadedTime,
- };
- setLoadProps((oldLoadProps) => ({
- ...oldLoadProps,
- isLoading: false,
- isLoadedAll: oldLoadProps.jslStatsCounter == loadProps.jslStatsCounter && nextRows.length === 0,
- ...loadedInfo,
- }));
- }
- };
-
// const data = useFetch({
// url: 'database-connections/query-data',
// method: 'post',
@@ -317,7 +198,6 @@ export default function DataGridCore(props) {
// const { rows, columns } = data || {};
const [firstVisibleRowScrollIndex, setFirstVisibleRowScrollIndex] = React.useState(0);
const [firstVisibleColumnScrollIndex, setFirstVisibleColumnScrollIndex] = React.useState(0);
- const socket = useSocket();
const [headerRowRef, { height: rowHeight }] = useDimensions();
const [tableBodyRef] = useDimensions();
@@ -326,6 +206,9 @@ export default function DataGridCore(props) {
const confirmSqlModalState = useModalState();
const [confirmSql, setConfirmSql] = React.useState('');
+ const changeSet = changeSetState && changeSetState.value;
+ const setChangeSet = React.useCallback((value) => dispatchChangeSet({ type: 'set', value }), [dispatchChangeSet]);
+
const [inplaceEditorState, dispatchInsplaceEditor] = React.useReducer((state, action) => {
switch (action.type) {
case 'show':
@@ -355,8 +238,8 @@ export default function DataGridCore(props) {
// usePropsCompare({ loadedRows, columns, containerWidth, display });
- const columnSizes = React.useMemo(() => countColumnSizes(loadedRows, columns, containerWidth, display), [
- loadedRows,
+ const columnSizes = React.useMemo(() => countColumnSizes(rows, columns, containerWidth, display), [
+ rows,
columns,
containerWidth,
display,
@@ -376,43 +259,6 @@ export default function DataGridCore(props) {
// console.log('visibleRowCountUpperBound', visibleRowCountUpperBound);
// console.log('rowHeight', rowHeight);
- const reload = () => {
- setLoadProps({
- allRowCount: null,
- isLoading: false,
- loadedRows: [],
- isLoadedAll: false,
- loadedTime: new Date().getTime(),
- errorMessage: null,
- jslStatsCounter: 0,
- jslChangeIndex: 0,
- });
- };
-
- const insertedRows = getChangeSetInsertedRows(changeSet, display.baseTable);
-
- const rowCountNewIncluded = loadedRows.length + insertedRows.length;
-
- React.useEffect(() => {
- if (
- !isLoadedAll &&
- !errorMessage &&
- firstVisibleRowScrollIndex + visibleRowCountUpperBound >= loadedRows.length &&
- insertedRows.length == 0
- ) {
- if (dataPageAvailable(props)) {
- // If not, callbacks to load missing metadata are dispatched
- loadNextData();
- }
- }
- if (props.masterLoadedTime && props.masterLoadedTime > loadedTime) {
- display.reload();
- }
- if (display.cache.refreshTime > loadedTime) {
- reload();
- }
- });
-
React.useEffect(() => {
if (tabVisible) {
if (focusFieldRef.current) focusFieldRef.current.focus();
@@ -424,31 +270,11 @@ export default function DataGridCore(props) {
return newColumn;
}, [columnSizes, gridScrollAreaWidth]);
- const handleJslDataStats = React.useCallback((stats) => {
- if (stats.changeIndex < loadProps.jslChangeIndex) return;
- setLoadProps((oldProps) => ({
- ...oldProps,
- allRowCount: stats.rowCount,
- isLoadedAll: false,
- jslStatsCounter: oldProps.jslStatsCounter + 1,
- jslChangeIndex: stats.changeIndex,
- }));
- }, []);
-
React.useEffect(() => {
- if (jslid && socket) {
- socket.on(`jsldata-stats-${jslid}`, handleJslDataStats);
- return () => {
- socket.off(`jsldata-stats-${jslid}`, handleJslDataStats);
- };
- }
- }, [jslid]);
-
- React.useEffect(() => {
- if (props.onReferenceSourceChanged && ((loadedRows && loadedRows.length > 0) || isLoadedAll)) {
+ if (props.onReferenceSourceChanged && ((rows && rows.length > 0) || isLoadedAll)) {
props.onReferenceSourceChanged(getSelectedRowData(), loadedTime);
}
- }, [selectedCells, props.refReloadToken, loadedRows && loadedRows[0]]);
+ }, [selectedCells, props.refReloadToken, rows && rows[0]]);
// const handleCloseInplaceEditor = React.useCallback(
// mode => {
@@ -487,6 +313,12 @@ export default function DataGridCore(props) {
}
}, [display && display.focusedColumn]);
+ React.useEffect(() => {
+ if (rows && loadNextData && firstVisibleRowScrollIndex + visibleRowCountUpperBound >= rows.length) {
+ loadNextData();
+ }
+ });
+
React.useEffect(() => {
if (display.groupColumns) {
props.onReferenceClick({
@@ -504,7 +336,7 @@ export default function DataGridCore(props) {
const rowCountInfo = React.useMemo(() => {
if (selectedCells.length > 1 && selectedCells.every((x) => _.isNumber(x[0]) && _.isNumber(x[1]))) {
let sum = _.sumBy(selectedCells, (cell) => {
- const row = loadedRows[cell[0]];
+ const row = rows[cell[0]];
if (row) {
const colName = realColumnUniqueNames[cell[1]];
if (colName) {
@@ -526,9 +358,9 @@ export default function DataGridCore(props) {
// if (this.isLoadingFirstPage) return "Loading first page...";
// if (this.isFirstPageError) return "Error loading first page";
// return `Rows: ${this.rowCount.toLocaleString()}`;
- }, [selectedCells, allRowCount, loadedRows, visibleRealColumns]);
+ }, [selectedCells, allRowCount, rows, visibleRealColumns]);
- if (!loadedRows || !columns || columns.length == 0)
+ if (!rows || !columns || columns.length == 0)
return (
@@ -563,7 +395,7 @@ export default function DataGridCore(props) {
setNull={setNull}
exportGrid={exportGrid}
filterSelectedValue={filterSelectedValue}
- openQuery={display.baseTable ? openQuery : null}
+ openQuery={openQuery}
/>
);
};
@@ -617,108 +449,83 @@ export default function DataGridCore(props) {
copyToClipboard();
}
- function exportGrid() {
- const initialValues = {};
- if (jslid) {
- const archiveMatch = jslid.match(/^archive:\/\/([^/]+)\/(.*)$/);
- if (archiveMatch) {
- initialValues.sourceStorageType = 'archive';
- initialValues.sourceArchiveFolder = archiveMatch[1];
- initialValues.sourceList = [archiveMatch[2]];
- } else {
- initialValues.sourceStorageType = 'jsldata';
- initialValues.sourceJslId = jslid;
- initialValues.sourceList = ['query-data'];
- }
- } else {
- initialValues.sourceStorageType = 'query';
- initialValues.sourceConnectionId = conid;
- initialValues.sourceDatabaseName = database;
- initialValues.sourceSql = display.getExportQuery();
- initialValues.sourceList = display.baseTable ? [display.baseTable.pureName] : [];
- }
- showModal((modalState) => );
- }
-
function setCellValue(chs, cell, value) {
- return setChangeSetValue(
- chs,
- display.getChangeSetField(
- loadedAndInsertedRows[cell[0]],
- realColumnUniqueNames[cell[1]],
- cell[0] >= loadedRows.length ? cell[0] - loadedRows.length : null
- ),
- value
- );
+ // return setChangeSetValue(
+ // chs,
+ // display.getChangeSetField(
+ // rows[cell[0]],
+ // realColumnUniqueNames[cell[1]],
+ // cell[0] >= rows.length ? cell[0] - rows.length : null
+ // ),
+ // value
+ // );
}
function handlePaste(event) {
- var pastedText = undefined;
- // @ts-ignore
- if (window.clipboardData && window.clipboardData.getData) {
- // IE
- // @ts-ignore
- pastedText = window.clipboardData.getData('Text');
- } else if (event.clipboardData && event.clipboardData.getData) {
- pastedText = event.clipboardData.getData('text/plain');
- }
- event.preventDefault();
- const pasteRows = pastedText
- .replace(/\r/g, '')
- .split('\n')
- .map((row) => row.split('\t'));
- let chs = changeSet;
- let allRows = loadedAndInsertedRows;
-
- if (selectedCells.length <= 1) {
- const startRow = isRegularCell(currentCell) ? currentCell[0] : loadedAndInsertedRows.length;
- const startCol = isRegularCell(currentCell) ? currentCell[1] : 0;
- let rowIndex = startRow;
- for (const rowData of pasteRows) {
- if (rowIndex >= allRows.length) {
- chs = changeSetInsertNewRow(chs, display.baseTable);
- allRows = [...loadedRows, ...getChangeSetInsertedRows(chs, display.baseTable)];
- }
- let colIndex = startCol;
- const row = allRows[rowIndex];
- for (const cell of rowData) {
- chs = setChangeSetValue(
- chs,
- display.getChangeSetField(
- row,
- realColumnUniqueNames[colIndex],
- rowIndex >= loadedRows.length ? rowIndex - loadedRows.length : null
- ),
- cell == '(NULL)' ? null : cell
- );
- colIndex += 1;
- }
- rowIndex += 1;
- }
- }
- if (selectedCells.length > 1) {
- const regularSelected = selectedCells.filter(isRegularCell);
- const startRow = _.min(regularSelected.map((x) => x[0]));
- const startCol = _.min(regularSelected.map((x) => x[1]));
- for (const cell of regularSelected) {
- const [rowIndex, colIndex] = cell;
- const selectionRow = rowIndex - startRow;
- const selectionCol = colIndex - startCol;
- const pasteRow = pasteRows[selectionRow % pasteRows.length];
- const pasteCell = pasteRow[selectionCol % pasteRow.length];
- chs = setCellValue(chs, cell, pasteCell);
- }
- }
-
- setChangeSet(chs);
+ // var pastedText = undefined;
+ // // @ts-ignore
+ // if (window.clipboardData && window.clipboardData.getData) {
+ // // IE
+ // // @ts-ignore
+ // pastedText = window.clipboardData.getData('Text');
+ // } else if (event.clipboardData && event.clipboardData.getData) {
+ // pastedText = event.clipboardData.getData('text/plain');
+ // }
+ // event.preventDefault();
+ // const pasteRows = pastedText
+ // .replace(/\r/g, '')
+ // .split('\n')
+ // .map((row) => row.split('\t'));
+ // let chs = changeSet;
+ // let allRows = loadedAndInsertedRows;
+ // if (selectedCells.length <= 1) {
+ // const startRow = isRegularCell(currentCell) ? currentCell[0] : loadedAndInsertedRows.length;
+ // const startCol = isRegularCell(currentCell) ? currentCell[1] : 0;
+ // let rowIndex = startRow;
+ // for (const rowData of pasteRows) {
+ // if (rowIndex >= allRows.length) {
+ // chs = changeSetInsertNewRow(chs, display.baseTable);
+ // allRows = [...loadedRows, ...getChangeSetInsertedRows(chs, display.baseTable)];
+ // }
+ // let colIndex = startCol;
+ // const row = allRows[rowIndex];
+ // for (const cell of rowData) {
+ // chs = setChangeSetValue(
+ // chs,
+ // display.getChangeSetField(
+ // row,
+ // realColumnUniqueNames[colIndex],
+ // rowIndex >= loadedRows.length ? rowIndex - loadedRows.length : null
+ // ),
+ // cell == '(NULL)' ? null : cell
+ // );
+ // colIndex += 1;
+ // }
+ // rowIndex += 1;
+ // }
+ // }
+ // if (selectedCells.length > 1) {
+ // const regularSelected = selectedCells.filter(isRegularCell);
+ // const startRow = _.min(regularSelected.map((x) => x[0]));
+ // const startCol = _.min(regularSelected.map((x) => x[1]));
+ // for (const cell of regularSelected) {
+ // const [rowIndex, colIndex] = cell;
+ // const selectionRow = rowIndex - startRow;
+ // const selectionCol = colIndex - startCol;
+ // const pasteRow = pasteRows[selectionRow % pasteRows.length];
+ // const pasteCell = pasteRow[selectionCol % pasteRow.length];
+ // chs = setCellValue(chs, cell, pasteCell);
+ // }
+ // }
+ // setChangeSet(chs);
}
function setNull() {
- let chs = changeSet;
- selectedCells.filter(isRegularCell).forEach((cell) => {
- chs = setCellValue(chs, cell, null);
- });
- setChangeSet(chs);
+ // let chs = changeSet;
+ // selectedCells.filter(isRegularCell).forEach((cell) => {
+ // chs = setCellValue(chs, cell, null);
+ // });
+ // setChangeSet(chs);
}
function cellsToRegularCells(cells) {
@@ -746,7 +553,7 @@ export default function DataGridCore(props) {
const rowIndexes = _.sortBy(_.uniq(cells.map((x) => x[0])));
const lines = rowIndexes.map((rowIndex) => {
let colIndexes = _.sortBy(cells.filter((x) => x[0] == rowIndex).map((x) => x[1]));
- const rowData = loadedAndInsertedRows[rowIndex];
+ const rowData = rows[rowIndex];
if (!rowData) return '';
const line = colIndexes
.map((col) => realColumnUniqueNames[col])
@@ -786,7 +593,7 @@ export default function DataGridCore(props) {
const rowIndexes = _.uniq((autofillSelectedCells || []).map((x) => x[0])).filter((x) => x != currentRowNumber);
// @ts-ignore
const colNames = selectedCells.map((cell) => realColumnUniqueNames[cell[1]]);
- const changeObject = _.pick(loadedAndInsertedRows[currentRowNumber], colNames);
+ const changeObject = _.pick(rows[currentRowNumber], colNames);
setChangeSet(
batchUpdateChangeSet(
changeSet,
@@ -805,13 +612,13 @@ export default function DataGridCore(props) {
function getRowDefinitions(rowIndexes) {
const res = [];
- if (!loadedAndInsertedRows) return res;
- for (const index of rowIndexes) {
- if (loadedAndInsertedRows[index] && _.isNumber(index)) {
- const insertedRowIndex = index >= loadedRows.length ? index - loadedRows.length : null;
- res.push(display.getChangeSetRow(loadedAndInsertedRows[index], insertedRowIndex));
- }
- }
+ // if (!loadedAndInsertedRows) return res;
+ // for (const index of rowIndexes) {
+ // if (loadedAndInsertedRows[index] && _.isNumber(index)) {
+ // const insertedRowIndex = index >= loadedRows.length ? index - loadedRows.length : null;
+ // res.push(display.getChangeSetRow(loadedAndInsertedRows[index], insertedRowIndex));
+ // }
+ // }
return res;
}
@@ -824,7 +631,7 @@ export default function DataGridCore(props) {
}
function getSelectedRowData() {
- return _.compact(getSelectedRowIndexes().map((index) => loadedRows && loadedRows[index]));
+ return _.compact(getSelectedRowIndexes().map((index) => rows && rows[index]));
}
function revertRowChanges() {
@@ -841,7 +648,7 @@ export default function DataGridCore(props) {
if (!isRegularCell(cell)) continue;
const modelIndex = columnSizes.realToModel(cell[1]);
const columnName = columns[modelIndex].uniqueName;
- let value = loadedRows[cell[0]][columnName];
+ let value = rows[cell[0]][columnName];
let svalue = getFilterValueExpression(value, columns[modelIndex].dataType);
if (_.has(flts, columnName)) flts[columnName] += ',' + svalue;
else flts[columnName] = svalue;
@@ -850,21 +657,6 @@ export default function DataGridCore(props) {
display.setFilters(flts);
}
- function openQuery() {
- openNewTab(setOpenedTabs, {
- title: 'Query',
- icon: 'sql.svg',
- tabComponent: 'QueryTab',
- props: {
- initialScript: display.getExportQuery(),
- schemaName: display.baseTable.schemaName,
- pureName: display.baseTable.pureName,
- conid,
- database,
- },
- });
- }
-
function revertAllChanges() {
setChangeSet(createChangeSet());
}
@@ -882,7 +674,7 @@ export default function DataGridCore(props) {
if (event.deltaY < 0) {
newFirstVisibleRowScrollIndex -= wheelRowCount;
}
- let rowCount = rowCountNewIncluded;
+ let rowCount = rows.length;
if (newFirstVisibleRowScrollIndex + visibleRowCountLowerBound > rowCount) {
newFirstVisibleRowScrollIndex = rowCount - visibleRowCountLowerBound + 1;
}
@@ -895,58 +687,44 @@ export default function DataGridCore(props) {
setvScrollValueToSetDate(new Date());
}
- // async function blurEditorAndSave() {
- // setInplaceEditorCell(null);
- // setInplaceEditorInitText(null);
- // await sleep(1);
- // }
-
- function undo() {
- dispatchChangeSet({ type: 'undo' });
- }
- function redo() {
- dispatchChangeSet({ type: 'redo' });
- }
-
function handleSave() {
if (inplaceEditorState.cell) {
// @ts-ignore
dispatchInsplaceEditor({ type: 'shouldSave' });
return;
}
- const script = changeSetToSql(changeSetRef.current, display.dbinfo);
- const sql = scriptToSql(display.driver, script);
- setConfirmSql(sql);
- confirmSqlModalState.open();
+ // const script = changeSetToSql(changeSetRef.current, display.dbinfo);
+ // const sql = scriptToSql(display.driver, script);
+ // setConfirmSql(sql);
+ // confirmSqlModalState.open();
}
async function handleConfirmSql() {
- const resp = await axios.request({
- url: 'database-connections/query-data',
- method: 'post',
- params: {
- conid,
- database,
- },
- data: { sql: confirmSql },
- });
-
- const { errorMessage } = resp.data || {};
- if (errorMessage) {
- showModal((modalState) => (
-
- ));
- } else {
- dispatchChangeSet({ type: 'reset', value: createChangeSet() });
- setConfirmSql(null);
- display.reload();
- }
+ // const resp = await axios.request({
+ // url: 'database-connections/query-data',
+ // method: 'post',
+ // params: {
+ // conid,
+ // database,
+ // },
+ // data: { sql: confirmSql },
+ // });
+ // const { errorMessage } = resp.data || {};
+ // if (errorMessage) {
+ // showModal((modalState) => (
+ //
+ // ));
+ // } else {
+ // dispatchChangeSet({ type: 'reset', value: createChangeSet() });
+ // setConfirmSql(null);
+ // display.reload();
+ // }
}
const insertNewRow = () => {
if (display.baseTable) {
setChangeSet(changeSetInsertNewRow(changeSet, display.baseTable));
- const cell = [rowCountNewIncluded, (currentCell && currentCell[1]) || 0];
+ const cell = [rows.length, (currentCell && currentCell[1]) || 0];
// @ts-ignore
setCurrentCell(cell);
// @ts-ignore
@@ -1060,7 +838,7 @@ export default function DataGridCore(props) {
function handleCursorMove(event) {
if (!isRegularCell(currentCell)) return null;
- let rowCount = rowCountNewIncluded;
+ let rowCount = rows.length;
if (event.ctrlKey) {
switch (event.keyCode) {
case keycodes.upArrow:
@@ -1118,7 +896,7 @@ export default function DataGridCore(props) {
}
function moveCurrentCell(row, col, event = null) {
- const rowCount = rowCountNewIncluded;
+ const rowCount = rows.length;
if (row < 0) row = 0;
if (row >= rowCount) row = rowCount - 1;
@@ -1140,7 +918,7 @@ export default function DataGridCore(props) {
if (row != null) {
let newRow = null;
- const rowCount = rowCountNewIncluded;
+ const rowCount = rows.length;
if (rowCount == 0) return;
if (row < firstVisibleRowScrollIndex) newRow = row;
@@ -1202,7 +980,7 @@ export default function DataGridCore(props) {
// columnSizes.getVisibleScrollSizeSum()
// );
- const loadedAndInsertedRows = [...loadedRows, ...insertedRows];
+ // const loadedAndInsertedRows = [...loadedRows, ...insertedRows];
// console.log('focusFieldRef.current', focusFieldRef.current);
@@ -1282,7 +1060,7 @@ export default function DataGridCore(props) {
)}
- {loadedAndInsertedRows
+ {rows
.slice(firstVisibleRowScrollIndex, firstVisibleRowScrollIndex + visibleRowCountUpperBound)
.map((row, index) => (
= loadedRows.length
- ? firstVisibleRowScrollIndex + index - loadedRows.length
+ firstVisibleRowScrollIndex + index >= rows.length - (insertedRowCount || 0)
+ ? firstVisibleRowScrollIndex + index - rows.length - (insertedRowCount || 0)
: null
}
autofillMarkerCell={filterCellForRow(autofillMarkerCell, firstVisibleRowScrollIndex + index)}
@@ -1321,9 +1099,9 @@ export default function DataGridCore(props) {
valueToSet={vScrollValueToSet}
valueToSetDate={vScrollValueToSetDate}
minimum={0}
- maximum={rowCountNewIncluded - visibleRowCountUpperBound + 2}
+ maximum={rows.length - visibleRowCountUpperBound + 2}
onScroll={handleRowScroll}
- viewportRatio={visibleRowCountUpperBound / rowCountNewIncluded}
+ viewportRatio={visibleRowCountUpperBound / rows.length}
/>
;
+ const { conid, database, display, changeSetState, dispatchChangeSet, tabVisible, jslid } = props;
+
+ const [loadProps, setLoadProps] = React.useState({
+ isLoading: false,
+ loadedRows: [],
+ isLoadedAll: false,
+ loadedTime: new Date().getTime(),
+ allRowCount: null,
+ errorMessage: null,
+ jslStatsCounter: 0,
+ jslChangeIndex: 0,
+ });
+ const { isLoading, loadedRows, isLoadedAll, loadedTime, allRowCount, errorMessage } = loadProps;
+ const showModal = useShowModal();
+
+ const loadedTimeRef = React.useRef(0);
+
+ const changeSet = changeSetState && changeSetState.value;
+ const setChangeSet = React.useCallback((value) => dispatchChangeSet({ type: 'set', value }), [dispatchChangeSet]);
+ const setOpenedTabs = useSetOpenedTabs();
+ const socket = useSocket();
+
+ const changeSetRef = React.useRef(changeSet);
+
+ changeSetRef.current = changeSet;
+
+ const handleLoadRowCount = async () => {
+ const rowCount = await loadRowCount(props);
+ setLoadProps((oldLoadProps) => ({
+ ...oldLoadProps,
+ allRowCount: rowCount,
+ }));
+ };
+
+ const reload = () => {
+ setLoadProps({
+ allRowCount: null,
+ isLoading: false,
+ loadedRows: [],
+ isLoadedAll: false,
+ loadedTime: new Date().getTime(),
+ errorMessage: null,
+ jslStatsCounter: 0,
+ jslChangeIndex: 0,
+ });
+ };
+
+ function exportGrid() {
+ const initialValues = {};
+ if (jslid) {
+ const archiveMatch = jslid.match(/^archive:\/\/([^/]+)\/(.*)$/);
+ if (archiveMatch) {
+ initialValues.sourceStorageType = 'archive';
+ initialValues.sourceArchiveFolder = archiveMatch[1];
+ initialValues.sourceList = [archiveMatch[2]];
+ } else {
+ initialValues.sourceStorageType = 'jsldata';
+ initialValues.sourceJslId = jslid;
+ initialValues.sourceList = ['query-data'];
+ }
+ } else {
+ initialValues.sourceStorageType = 'query';
+ initialValues.sourceConnectionId = conid;
+ initialValues.sourceDatabaseName = database;
+ initialValues.sourceSql = display.getExportQuery();
+ initialValues.sourceList = display.baseTable ? [display.baseTable.pureName] : [];
+ }
+ showModal((modalState) => );
+ }
+
+ React.useEffect(() => {
+ if (props.masterLoadedTime && props.masterLoadedTime > loadedTime) {
+ display.reload();
+ }
+ if (display.cache.refreshTime > loadedTime) {
+ reload();
+ }
+ });
+
+ const loadNextData = async () => {
+ if (isLoading) return;
+ setLoadProps((oldLoadProps) => ({
+ ...oldLoadProps,
+ isLoading: true,
+ }));
+ const loadStart = new Date().getTime();
+ loadedTimeRef.current = loadStart;
+
+ const nextRows = await loadDataPage(props, loadedRows.length, 100);
+ if (loadedTimeRef.current !== loadStart) {
+ // new load was dispatched
+ return;
+ }
+ // if (!_.isArray(nextRows)) {
+ // console.log('Error loading data from server', nextRows);
+ // nextRows = [];
+ // }
+ // console.log('nextRows', nextRows);
+ if (nextRows.errorMessage) {
+ setLoadProps((oldLoadProps) => ({
+ ...oldLoadProps,
+ isLoading: false,
+ errorMessage: nextRows.errorMessage,
+ }));
+ } else {
+ if (allRowCount == null) handleLoadRowCount();
+ const loadedInfo = {
+ loadedRows: [...loadedRows, ...nextRows],
+ loadedTime,
+ };
+ setLoadProps((oldLoadProps) => ({
+ ...oldLoadProps,
+ isLoading: false,
+ isLoadedAll: oldLoadProps.jslStatsCounter == loadProps.jslStatsCounter && nextRows.length === 0,
+ ...loadedInfo,
+ }));
+ }
+ };
+
+ const handleJslDataStats = React.useCallback((stats) => {
+ if (stats.changeIndex < loadProps.jslChangeIndex) return;
+ setLoadProps((oldProps) => ({
+ ...oldProps,
+ allRowCount: stats.rowCount,
+ isLoadedAll: false,
+ jslStatsCounter: oldProps.jslStatsCounter + 1,
+ jslChangeIndex: stats.changeIndex,
+ }));
+ }, []);
+
+ React.useEffect(() => {
+ if (jslid && socket) {
+ socket.on(`jsldata-stats-${jslid}`, handleJslDataStats);
+ return () => {
+ socket.off(`jsldata-stats-${jslid}`, handleJslDataStats);
+ };
+ }
+ }, [jslid]);
+
+ const insertedRows = getChangeSetInsertedRows(changeSet, display.baseTable);
+ const rowCountNewIncluded = loadedRows.length + insertedRows.length;
+
+ const handleLoadNextData = () => {
+ if (!isLoadedAll && !errorMessage && insertedRows.length == 0) {
+ if (dataPageAvailable(props)) {
+ // If not, callbacks to load missing metadata are dispatched
+ loadNextData();
+ }
+ }
+ };
+
+ function openQuery() {
+ openNewTab(setOpenedTabs, {
+ title: 'Query',
+ icon: 'sql.svg',
+ tabComponent: 'QueryTab',
+ props: {
+ initialScript: display.getExportQuery(),
+ schemaName: display.baseTable.schemaName,
+ pureName: display.baseTable.pureName,
+ conid,
+ database,
+ },
+ });
+ }
+
+ return (
+
+ );
}
diff --git a/packages/web/src/datagrid/types.ts b/packages/web/src/datagrid/types.ts
index 65a591ad..069fbeef 100644
--- a/packages/web/src/datagrid/types.ts
+++ b/packages/web/src/datagrid/types.ts
@@ -1,14 +1,11 @@
import { GridDisplay, ChangeSet, GridReferenceDefinition } from '@dbgate/datalib';
export interface DataGridProps {
- conid?: string;
- database?: string;
display: GridDisplay;
tabVisible?: boolean;
changeSetState?: { value: ChangeSet };
dispatchChangeSet?: Function;
toolbarPortalRef?: any;
- jslid?: string;
showReferences?: boolean;
onReferenceClick?: (def: GridReferenceDefinition) => void;
onReferenceSourceChanged?: Function;
@@ -16,3 +13,27 @@ export interface DataGridProps {
masterLoadedTime?: number;
managerSize?: number;
}
+
+export interface DataGridCoreProps extends DataGridProps {
+ rows: any[];
+ loadNextData?: Function;
+ exportGrid?: Function;
+ openQuery?: Function;
+ undo?: Function;
+ redo?: Function;
+
+ errorMessage?: string;
+ isLoadedAll?: boolean;
+ loadedTime?: any;
+ allRowCount?: number;
+ conid?: string;
+ database?: string;
+ insertedRowCount?: number;
+ isLoading?: boolean;
+}
+
+export interface LoadingDataGridProps extends DataGridProps {
+ conid?: string;
+ database?: string;
+ jslid?: string;
+}