mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-05-02 06:43:59 +00:00
undo, redo in table data editing
This commit is contained in:
@@ -96,7 +96,7 @@ const FocusField = styled.input`
|
|||||||
|
|
||||||
/** @param props {import('./types').DataGridProps} */
|
/** @param props {import('./types').DataGridProps} */
|
||||||
export default function DataGridCore(props) {
|
export default function DataGridCore(props) {
|
||||||
const { conid, database, display, changeSet, setChangeSet, tabVisible } = props;
|
const { conid, database, display, changeSetState, dispatchChangeSet, tabVisible } = props;
|
||||||
const columns = display.getGridColumns();
|
const columns = display.getGridColumns();
|
||||||
|
|
||||||
// console.log(`GRID, conid=${conid}, database=${database}, sql=${sql}`);
|
// console.log(`GRID, conid=${conid}, database=${database}, sql=${sql}`);
|
||||||
@@ -129,6 +129,9 @@ export default function DataGridCore(props) {
|
|||||||
// const [inplaceEditorShouldSave, setInplaceEditorShouldSave] = React.useState(false);
|
// const [inplaceEditorShouldSave, setInplaceEditorShouldSave] = React.useState(false);
|
||||||
// const [inplaceEditorChangedOnCreate, setInplaceEditorChangedOnCreate] = React.useState(false);
|
// const [inplaceEditorChangedOnCreate, setInplaceEditorChangedOnCreate] = React.useState(false);
|
||||||
|
|
||||||
|
const changeSet = changeSetState.value;
|
||||||
|
const setChangeSet = value => dispatchChangeSet({ type: 'set', value });
|
||||||
|
|
||||||
const changeSetRef = React.useRef(changeSet);
|
const changeSetRef = React.useRef(changeSet);
|
||||||
|
|
||||||
changeSetRef.current = changeSet;
|
changeSetRef.current = changeSet;
|
||||||
@@ -537,6 +540,13 @@ export default function DataGridCore(props) {
|
|||||||
// await sleep(1);
|
// await sleep(1);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
function undo() {
|
||||||
|
dispatchChangeSet({ type: 'undo' });
|
||||||
|
}
|
||||||
|
function redo() {
|
||||||
|
dispatchChangeSet({ type: 'redo' });
|
||||||
|
}
|
||||||
|
|
||||||
function handleSave() {
|
function handleSave() {
|
||||||
if (inplaceEditorState.cell) {
|
if (inplaceEditorState.cell) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
@@ -560,7 +570,7 @@ export default function DataGridCore(props) {
|
|||||||
data: { sql: confirmSql },
|
data: { sql: confirmSql },
|
||||||
});
|
});
|
||||||
|
|
||||||
setChangeSet(createChangeSet());
|
dispatchChangeSet({ type: 'reset', value: createChangeSet() });
|
||||||
setConfirmSql(null);
|
setConfirmSql(null);
|
||||||
display.reload();
|
display.reload();
|
||||||
}
|
}
|
||||||
@@ -577,6 +587,16 @@ export default function DataGridCore(props) {
|
|||||||
revertRowChanges();
|
revertRowChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (event.keyCode == keycodes.z && event.ctrlKey) {
|
||||||
|
event.preventDefault();
|
||||||
|
undo();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.keyCode == keycodes.y && event.ctrlKey) {
|
||||||
|
event.preventDefault();
|
||||||
|
redo();
|
||||||
|
}
|
||||||
|
|
||||||
if (event.keyCode == keycodes.c && event.ctrlKey) {
|
if (event.keyCode == keycodes.c && event.ctrlKey) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
copyToClipboard();
|
copyToClipboard();
|
||||||
|
|||||||
@@ -38,12 +38,16 @@ export default function InplaceEditor({
|
|||||||
if (isChangedRef.current) {
|
if (isChangedRef.current) {
|
||||||
const editor = editorRef.current;
|
const editor = editorRef.current;
|
||||||
setChangeSet(setChangeSetValue(changeSet, definition, editor.value));
|
setChangeSet(setChangeSetValue(changeSet, definition, editor.value));
|
||||||
|
isChangedRef.current = false;
|
||||||
}
|
}
|
||||||
dispatchInsplaceEditor({ type: 'close' });
|
dispatchInsplaceEditor({ type: 'close' });
|
||||||
}
|
}
|
||||||
if (inplaceEditorState.shouldSave) {
|
if (inplaceEditorState.shouldSave) {
|
||||||
const editor = editorRef.current;
|
const editor = editorRef.current;
|
||||||
setChangeSet(setChangeSetValue(changeSet, definition, editor.value));
|
if (isChangedRef.current) {
|
||||||
|
setChangeSet(setChangeSetValue(changeSet, definition, editor.value));
|
||||||
|
isChangedRef.current = false;
|
||||||
|
}
|
||||||
editor.blur();
|
editor.blur();
|
||||||
dispatchInsplaceEditor({ type: 'close', mode: 'save' });
|
dispatchInsplaceEditor({ type: 'close', mode: 'save' });
|
||||||
}
|
}
|
||||||
@@ -55,7 +59,10 @@ export default function InplaceEditor({
|
|||||||
dispatchInsplaceEditor({ type: 'close' });
|
dispatchInsplaceEditor({ type: 'close' });
|
||||||
break;
|
break;
|
||||||
case keycodes.enter:
|
case keycodes.enter:
|
||||||
setChangeSet(setChangeSetValue(changeSet, definition, editor.value));
|
if (isChangedRef.current) {
|
||||||
|
setChangeSet(setChangeSetValue(changeSet, definition, editor.value));
|
||||||
|
isChangedRef.current = false;
|
||||||
|
}
|
||||||
editor.blur();
|
editor.blur();
|
||||||
dispatchInsplaceEditor({ type: 'close', mode: 'enter' });
|
dispatchInsplaceEditor({ type: 'close', mode: 'enter' });
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -5,6 +5,6 @@ export interface DataGridProps {
|
|||||||
database: string;
|
database: string;
|
||||||
display: GridDisplay;
|
display: GridDisplay;
|
||||||
tabVisible?: boolean;
|
tabVisible?: boolean;
|
||||||
changeSet?: ChangeSet;
|
changeSetState: { value: ChangeSet };
|
||||||
setChangeSet?: Function;
|
dispatchChangeSet: Function;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,12 +8,13 @@ import useTableInfo from '../utility/useTableInfo';
|
|||||||
import useConnectionInfo from '../utility/useConnectionInfo';
|
import useConnectionInfo from '../utility/useConnectionInfo';
|
||||||
import engines from '@dbgate/engines';
|
import engines from '@dbgate/engines';
|
||||||
import getTableInfo from '../utility/getTableInfo';
|
import getTableInfo from '../utility/getTableInfo';
|
||||||
|
import useUndoReducer from '../utility/useUndoReducer';
|
||||||
|
|
||||||
export default function TableDataTab({ conid, database, schemaName, pureName, tabVisible }) {
|
export default function TableDataTab({ conid, database, schemaName, pureName, tabVisible }) {
|
||||||
const tableInfo = useTableInfo({ conid, database, schemaName, pureName });
|
const tableInfo = useTableInfo({ conid, database, schemaName, pureName });
|
||||||
const [config, setConfig] = React.useState(createGridConfig());
|
const [config, setConfig] = React.useState(createGridConfig());
|
||||||
const [cache, setCache] = React.useState(createGridCache());
|
const [cache, setCache] = React.useState(createGridCache());
|
||||||
const [changeSet, setChangeSet] = React.useState(createChangeSet());
|
const [changeSetState, dispatchChangeSet] = useUndoReducer(createChangeSet());
|
||||||
|
|
||||||
// console.log('changeSet', changeSet);
|
// console.log('changeSet', changeSet);
|
||||||
|
|
||||||
@@ -37,8 +38,8 @@ export default function TableDataTab({ conid, database, schemaName, pureName, ta
|
|||||||
database={database}
|
database={database}
|
||||||
display={display}
|
display={display}
|
||||||
tabVisible={tabVisible}
|
tabVisible={tabVisible}
|
||||||
changeSet={changeSet}
|
changeSetState={changeSetState}
|
||||||
setChangeSet={setChangeSet}
|
dispatchChangeSet={dispatchChangeSet}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
43
packages/web/src/utility/useUndoReducer.js
Normal file
43
packages/web/src/utility/useUndoReducer.js
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
function reducer(state, action) {
|
||||||
|
switch (action.type) {
|
||||||
|
case 'set':
|
||||||
|
// console.log('SET', state.history, action.value);
|
||||||
|
return {
|
||||||
|
history: [...state.history.slice(0, state.current + 1), action.value],
|
||||||
|
current: state.current + 1,
|
||||||
|
value: action.value,
|
||||||
|
};
|
||||||
|
case 'undo':
|
||||||
|
if (state.current > 0)
|
||||||
|
return {
|
||||||
|
history: state.history,
|
||||||
|
current: state.current - 1,
|
||||||
|
value: state.history[state.current - 1],
|
||||||
|
};
|
||||||
|
return state;
|
||||||
|
case 'redo':
|
||||||
|
if (state.current < state.history.length - 1)
|
||||||
|
return {
|
||||||
|
history: state.history,
|
||||||
|
current: state.current + 1,
|
||||||
|
value: state.history[state.current + 1],
|
||||||
|
};
|
||||||
|
return state;
|
||||||
|
case 'reset':
|
||||||
|
return {
|
||||||
|
history: [action.value],
|
||||||
|
current: 0,
|
||||||
|
value: action.value,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function useUndoReducer(initialValue) {
|
||||||
|
return React.useReducer(reducer, {
|
||||||
|
history: [initialValue],
|
||||||
|
current: 0,
|
||||||
|
value: initialValue,
|
||||||
|
});
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user