grider refactor WIP

This commit is contained in:
Jan Prochazka
2020-10-24 21:05:24 +02:00
parent 00453ae379
commit 45d172d0b1
6 changed files with 123 additions and 71 deletions

View File

@@ -1,16 +1,20 @@
import {
ChangeSet,
changeSetContainsChanges,
changeSetInsertNewRow,
createChangeSet,
deleteChangeSetRows,
findExistingChangeSetItem,
getChangeSetInsertedRows,
GridDisplay,
revertChangeSetRowChanges,
setChangeSetValue,
} from '@dbgate/datalib';
import Grider, { GriderRowStatus } from './Grider';
export default class ChangeSetGrider extends Grider {
public insertedRows: any[];
public changeSet: ChangeSet;
public setChangeSet: Function;
private rowCacheIndexes: Set<number>;
private rowDataCache;
@@ -18,14 +22,10 @@ export default class ChangeSetGrider extends Grider {
private rowDefinitionsCache;
private batchChangeSet: ChangeSet;
constructor(
public sourceRows: any[],
public changeSet: ChangeSet,
public dispatchChangeSet,
public display: GridDisplay
) {
constructor(public sourceRows: any[], public changeSetState, public dispatchChangeSet, public display: GridDisplay) {
super();
this.insertedRows = getChangeSetInsertedRows(changeSet, display.baseTable);
this.changeSet = changeSetState && changeSetState.value;
this.insertedRows = getChangeSetInsertedRows(this.changeSet, display.baseTable);
this.setChangeSet = (value) => dispatchChangeSet({ type: 'set', value });
this.rowCacheIndexes = new Set();
this.rowDataCache = {};
@@ -112,10 +112,36 @@ export default class ChangeSetGrider extends Grider {
this.batchChangeSet = null;
}
static factory({ sourceRows, changeSet, dispatchChangeSet, display }): ChangeSetGrider {
return new ChangeSetGrider(sourceRows, changeSet, dispatchChangeSet, display);
revertRowChanges(index: number) {
this.requireRowCache(index);
this.applyModification((chs) => revertChangeSetRowChanges(chs, this.rowDefinitionsCache[index]));
}
static factoryDeps({ sourceRows, changeSet, dispatchChangeSet, display }) {
return [sourceRows, changeSet, dispatchChangeSet, display];
revertAllChanges() {
this.applyModification((chs) => createChangeSet());
}
undo() {
this.dispatchChangeSet({ type: 'undo' });
}
redo() {
this.dispatchChangeSet({ type: 'redo' });
}
get canUndo() {
return this.changeSetState.canUndo;
}
get canRedo() {
return this.changeSetState.canRedo;
}
get containsChanges() {
return changeSetContainsChanges(this.changeSet);
}
get disableLoadNextPage() {
return this.insertedRows.length > 0;
}
static factory({ sourceRows, changeSetState, dispatchChangeSet, display }): ChangeSetGrider {
return new ChangeSetGrider(sourceRows, changeSetState, dispatchChangeSet, display);
}
static factoryDeps({ sourceRows, changeSetState, dispatchChangeSet, display }) {
return [sourceRows, changeSetState ? changeSetState.value : null, dispatchChangeSet, display];
}
}

View File

@@ -132,8 +132,8 @@ export default function DataGridCore(props) {
display,
conid,
database,
changeSetState,
dispatchChangeSet,
// changeSetState,
// dispatchChangeSet,
tabVisible,
loadNextData,
errorMessage,
@@ -203,8 +203,8 @@ export default function DataGridCore(props) {
const [containerRef, { height: containerHeight, width: containerWidth }] = useDimensions();
// const [tableRef, { height: tableHeight, width: tableWidth }] = useDimensions();
const changeSet = changeSetState && changeSetState.value;
const setChangeSet = React.useCallback((value) => dispatchChangeSet({ type: 'set', value }), [dispatchChangeSet]);
// 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) {
@@ -446,7 +446,8 @@ export default function DataGridCore(props) {
copyToClipboard();
}
function setCellValue(chs, cell, value) {
function setCellValue(cell, value) {
grider.setCellValue(cell[0], realColumnUniqueNames[cell[1]], value);
// return setChangeSetValue(
// chs,
// display.getChangeSetField(
@@ -518,6 +519,11 @@ export default function DataGridCore(props) {
}
function setNull() {
grider.beginUpdate();
selectedCells.filter(isRegularCell).forEach((cell) => {
setCellValue(cell, null);
});
grider.endUpdate();
// let chs = changeSet;
// selectedCells.filter(isRegularCell).forEach((cell) => {
// chs = setCellValue(chs, cell, null);
@@ -588,17 +594,11 @@ export default function DataGridCore(props) {
const currentRowNumber = currentCell[0];
if (_.isNumber(currentRowNumber)) {
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(grider.getRowData(currentRowNumber), colNames);
setChangeSet(
batchUpdateChangeSet(
changeSet,
getRowDefinitions(rowIndexes),
// @ts-ignore
rowIndexes.map(() => changeObject)
)
);
grider.beginUpdate();
for (const index of rowIndexes) grider.updateRow(index, changeObject);
grider.endUpdate();
}
setAutofillDragStartCell(null);
@@ -607,36 +607,41 @@ 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));
// }
// }
return res;
}
// 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));
// // }
// // }
// return res;
// }
function getSelectedRowIndexes() {
return _.uniq((selectedCells || []).map((x) => x[0]));
}
function getSelectedRowDefinitions() {
return getRowDefinitions(getSelectedRowIndexes());
}
// function getSelectedRowDefinitions() {
// return getRowDefinitions(getSelectedRowIndexes());
// }
function getSelectedRowData() {
return _.compact(getSelectedRowIndexes().map((index) => grider.getRowData(index)));
}
function revertRowChanges() {
const updatedChangeSet = getSelectedRowDefinitions().reduce(
(chs, row) => revertChangeSetRowChanges(chs, row),
changeSet
);
setChangeSet(updatedChangeSet);
grider.beginUpdate();
for (const index of getSelectedRowIndexes()) {
if (_.isNumber(index)) grider.revertRowChanges(index);
}
grider.endUpdate();
// const updatedChangeSet = getSelectedRowDefinitions().reduce(
// (chs, row) => revertChangeSetRowChanges(chs, row),
// changeSet
// );
// setChangeSet(updatedChangeSet);
}
function filterSelectedValue() {
@@ -655,7 +660,8 @@ export default function DataGridCore(props) {
}
function revertAllChanges() {
setChangeSet(createChangeSet());
grider.revertAllChanges();
// setChangeSet(createChangeSet());
}
function deleteSelectedRows() {
@@ -690,10 +696,10 @@ export default function DataGridCore(props) {
}
function undo() {
dispatchChangeSet({ type: 'undo' });
grider.undo();
}
function redo() {
dispatchChangeSet({ type: 'redo' });
grider.redo();
}
function handleSave() {
@@ -709,7 +715,6 @@ export default function DataGridCore(props) {
// confirmSqlModalState.open();
}
const insertNewRow = () => {
if (display.baseTable) {
const rowIndex = grider.insertRow();
@@ -1101,9 +1106,10 @@ export default function DataGridCore(props) {
<DataGridToolbar
reload={() => display.reload()}
save={handleSave}
changeSetState={changeSetState}
dispatchChangeSet={dispatchChangeSet}
revert={revertAllChanges}
grider={grider}
// changeSetState={changeSetState}
// dispatchChangeSet={dispatchChangeSet}
// revert={revertAllChanges}
/>,
props.toolbarPortalRef.current
)}

View File

@@ -1,23 +1,22 @@
import React from 'react';
import ToolbarButton from '../widgets/ToolbarButton';
import { changeSetContainsChanges } from '@dbgate/datalib';
export default function DataGridToolbar({ reload, changeSetState, dispatchChangeSet, save, revert }) {
export default function DataGridToolbar({ reload, grider, save }) {
return (
<>
<ToolbarButton onClick={reload} icon="fas fa-sync">
Refresh
</ToolbarButton>
<ToolbarButton disabled={!changeSetState.canUndo} onClick={() => dispatchChangeSet({ type: 'undo' })} icon="fas fa-undo">
<ToolbarButton disabled={!grider.canUndo} onClick={() => grider.undo()} icon="fas fa-undo">
Undo
</ToolbarButton>
<ToolbarButton disabled={!changeSetState.canRedo} onClick={() => dispatchChangeSet({ type: 'redo' })} icon="fas fa-redo">
<ToolbarButton disabled={!grider.canRedo} onClick={() => grider.redo()} icon="fas fa-redo">
Redo
</ToolbarButton>
<ToolbarButton disabled={!changeSetContainsChanges(changeSetState.value)} onClick={save} icon="fas fa-save">
<ToolbarButton disabled={!grider.containsChanges} onClick={save} icon="fas fa-save">
Save
</ToolbarButton>
<ToolbarButton disabled={!changeSetContainsChanges(changeSetState.value)} onClick={revert} icon="fas fa-times">
<ToolbarButton disabled={!grider.containsChanges} onClick={() => grider.revertAllChanges()} icon="fas fa-times">
Revert
</ToolbarButton>
</>

View File

@@ -25,4 +25,25 @@ export default abstract class Grider {
insertRow(): number {
return null;
}
revertRowChanges(index: number) {}
revertAllChanges() {}
undo() {}
redo() {}
get canUndo() {
return false;
}
get canRedo() {
return false;
}
get containsChanges() {
return false;
}
get disableLoadNextPage() {
return false;
}
updateRow(index, changeObject) {
for (const key of Object.keys(changeObject)) {
this.setCellValue(index, key, changeObject[key]);
}
}
}

View File

@@ -109,14 +109,14 @@ export default function LoadingDataGridCore(props) {
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 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);
// const changeSetRef = React.useRef(changeSet);
changeSetRef.current = changeSet;
// changeSetRef.current = changeSet;
const handleLoadRowCount = async () => {
const rowCount = await loadRowCount(props);
@@ -196,11 +196,14 @@ export default function LoadingDataGridCore(props) {
}));
}, [loadNextDataToken]);
const insertedRows = getChangeSetInsertedRows(changeSet, display.baseTable);
const rowCountNewIncluded = loadedRows.length + insertedRows.length;
// const insertedRows = getChangeSetInsertedRows(changeSet, display.baseTable);
// const rowCountNewIncluded = loadedRows.length + insertedRows.length;
const griderProps = { ...props, sourceRows: loadedRows };
const grider = React.useMemo(() => griderFactory(griderProps), griderFactoryDeps(griderProps));
const handleLoadNextData = () => {
if (!isLoadedAll && !errorMessage && insertedRows.length == 0) {
if (!isLoadedAll && !errorMessage && !grider.disableLoadNextPage) {
if (dataPageAvailable(props)) {
// If not, callbacks to load missing metadata are dispatched
loadNextData();
@@ -208,9 +211,6 @@ export default function LoadingDataGridCore(props) {
}
};
const griderProps = { ...props, sourceRows: loadedRows };
const grider = React.useMemo(() => griderFactory(griderProps), griderFactoryDeps(griderProps));
return (
<DataGridCore
{...props}
@@ -219,7 +219,7 @@ export default function LoadingDataGridCore(props) {
isLoadedAll={isLoadedAll}
loadedTime={loadedTime}
exportGrid={exportGrid}
// allRowCount={allRowCount}
allRowCount={allRowCount}
openQuery={openQuery}
isLoading={isLoading}
// rows={loadedRows}

View File

@@ -137,7 +137,7 @@ export default function SqlDataGridCore(props) {
loadRowCount={loadRowCount}
griderFactory={ChangeSetGrider.factory}
griderFactoryDeps={ChangeSetGrider.factoryDeps}
changeSet={changeSetState && changeSetState.value}
// changeSet={changeSetState && changeSetState.value}
onSave={handleSave}
/>
<ConfirmSqlModal