From cdb3215b5fe8bf034947985cf1c7f4677696b262 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Wed, 25 Mar 2020 21:48:44 +0100 Subject: [PATCH] inplace editor improvements --- packages/web/src/datagrid/DataGridCore.js | 80 +++++++++++++++++----- packages/web/src/datagrid/DataGridRow.js | 2 + packages/web/src/datagrid/InplaceEditor.js | 27 +++++++- packages/web/src/datagrid/gridutil.js | 4 +- packages/web/src/tabs/TableDataTab.js | 2 +- 5 files changed, 93 insertions(+), 22 deletions(-) diff --git a/packages/web/src/datagrid/DataGridCore.js b/packages/web/src/datagrid/DataGridCore.js index a15b0c6dc..5553deeba 100644 --- a/packages/web/src/datagrid/DataGridCore.js +++ b/packages/web/src/datagrid/DataGridCore.js @@ -28,6 +28,7 @@ import useModalState from '../modals/useModalState'; import ConfirmSqlModal from '../modals/ConfirmSqlModal'; import { changeSetToSql, createChangeSet } from '@dbgate/datalib'; import { scriptToSql } from '@dbgate/sqltree'; +import { sleep } from '../utility/common'; const GridContainer = styled.div` position: absolute; @@ -106,6 +107,11 @@ export default function DataGridCore(props) { const [inplaceEditorCell, setInplaceEditorCell] = React.useState(nullCell); const [inplaceEditorInitText, setInplaceEditorInitText] = React.useState(''); + const [inplaceEditorShouldSave, setInplaceEditorShouldSave] = React.useState(false); + const [inplaceEditorChangedOnCreate, setInplaceEditorChangedOnCreate] = React.useState(false); + const changeSetRef = React.useRef(changeSet); + + changeSetRef.current = changeSet; const loadNextData = async () => { if (isLoading) return; @@ -217,10 +223,19 @@ export default function DataGridCore(props) { } }, [tabVisible, tableElement]); - const handleCloseInplaceEditor = React.useCallback(() => { - setInplaceEditorCell(null); - setInplaceEditorInitText(null); - }, []); + const handleCloseInplaceEditor = React.useCallback( + mode => { + const [row, col] = currentCell || []; + setInplaceEditorCell(null); + setInplaceEditorInitText(null); + setInplaceEditorShouldSave(false); + if (tableElement) tableElement.focus(); + // @ts-ignore + if (mode == 'enter' && row) moveCurrentCell(row + 1, col); + if (mode == 'save') setTimeout(handleSave, 1); + }, + [tableElement, currentCell] + ); const visibleRealColumns = React.useMemo( () => countVisibleRealColumns(columnSizes, firstVisibleColumnScrollIndex, gridScrollAreaWidth, columns), @@ -261,6 +276,7 @@ export default function DataGridCore(props) { setDragStartCell(cell); if (isRegularCell(cell) && !_.isEqual(cell, inplaceEditorCell) && _.isEqual(cell, currentCell)) { + setInplaceEditorShouldSave(false); setInplaceEditorCell(cell); } else if (!_.isEqual(cell, inplaceEditorCell)) { handleCloseInplaceEditor(); @@ -305,8 +321,18 @@ export default function DataGridCore(props) { setvScrollValueToSetDate(new Date()); } - function handleSave() { - const script = changeSetToSql(changeSet); + // async function blurEditorAndSave() { + // setInplaceEditorCell(null); + // setInplaceEditorInitText(null); + // await sleep(1); + // } + + function handleSave() { + if (inplaceEditorCell) { + setInplaceEditorShouldSave(true); + return; + } + const script = changeSetToSql(changeSetRef.current); const sql = scriptToSql(display.driver, script); setConfirmSql(sql); confirmSqlModalState.open(); @@ -329,6 +355,20 @@ export default function DataGridCore(props) { } function handleGridKeyDown(event) { + if (event.keyCode == keycodes.s && event.ctrlKey) { + event.preventDefault(); + handleSave(); + // this.saveAndFocus(); + } + + if (event.keyCode == keycodes.r && event.ctrlKey) { + event.preventDefault(); + // revertRowChanges(); + // this.saveAndFocus(); + } + + if (inplaceEditorCell) return; + if ( !event.ctrlKey && !event.altKey && @@ -337,14 +377,14 @@ export default function DataGridCore(props) { event.keyCode == keycodes.dash) ) { setInplaceEditorInitText(event.nativeEvent.key); + setInplaceEditorShouldSave(false); setInplaceEditorCell(currentCell); // console.log('event', event.nativeEvent); } - if (event.keyCode == keycodes.s && event.ctrlKey) { - event.preventDefault(); - handleSave(); - // this.saveAndFocus(); + if (event.keyCode == keycodes.f2) { + setInplaceEditorShouldSave(false); + setInplaceEditorCell(currentCell); } const moved = handleCursorMove(event); @@ -421,7 +461,7 @@ export default function DataGridCore(props) { return ['filter', columnRealIndex]; } - function moveCurrentCell(row, col, event) { + function moveCurrentCell(row, col, event = null) { const rowCount = rowCountNewIncluded; if (row < 0) row = 0; @@ -495,11 +535,11 @@ export default function DataGridCore(props) { }; // console.log('visibleRealColumnIndexes', visibleRealColumnIndexes); - console.log( - 'gridScrollAreaWidth / columnSizes.getVisibleScrollSizeSum()', - gridScrollAreaWidth, - columnSizes.getVisibleScrollSizeSum() - ); + // console.log( + // 'gridScrollAreaWidth / columnSizes.getVisibleScrollSizeSum()', + // gridScrollAreaWidth, + // columnSizes.getVisibleScrollSizeSum() + // ); return ( @@ -566,6 +606,7 @@ export default function DataGridCore(props) { visibleRealColumns={visibleRealColumns} inplaceEditorCell={inplaceEditorCell} inplaceEditorInitText={inplaceEditorInitText} + inplaceEditorShouldSave={inplaceEditorShouldSave} onCloseInplaceEditor={handleCloseInplaceEditor} cellIsSelected={cellIsSelected} changeSet={changeSet} @@ -592,7 +633,12 @@ export default function DataGridCore(props) { onScroll={handleRowScroll} viewportRatio={visibleRowCountUpperBound / rowCountNewIncluded} /> - + ); } diff --git a/packages/web/src/datagrid/DataGridRow.js b/packages/web/src/datagrid/DataGridRow.js index feca3df4c..ff21b45ec 100644 --- a/packages/web/src/datagrid/DataGridRow.js +++ b/packages/web/src/datagrid/DataGridRow.js @@ -81,6 +81,7 @@ export default function DataGridRow({ visibleRealColumns, inplaceEditorCell, inplaceEditorInitText, + inplaceEditorShouldSave, onCloseInplaceEditor, cellIsSelected, row, @@ -121,6 +122,7 @@ export default function DataGridRow({ setChangeSet={setChangeSet} definition={display.getChangeSetField(row, col.uniqueName)} onClose={onCloseInplaceEditor} + shouldSave={inplaceEditorShouldSave} /> ) : ( <> diff --git a/packages/web/src/datagrid/InplaceEditor.js b/packages/web/src/datagrid/InplaceEditor.js index f22311dbb..03e073ebb 100644 --- a/packages/web/src/datagrid/InplaceEditor.js +++ b/packages/web/src/datagrid/InplaceEditor.js @@ -14,9 +14,19 @@ const StyledInput = styled.input` padding: 0px; `; -export default function InplaceEditor({ widthPx, value, definition, changeSet, setChangeSet, onClose, selectAll }) { +export default function InplaceEditor({ + widthPx, + value, + definition, + changeSet, + setChangeSet, + onClose, + selectAll, + shouldSave, + changedOnCreate, +}) { const editorRef = React.useRef(); - const isChangedRef = React.createRef(); + const isChangedRef = React.createRef(changedOnCreate); React.useEffect(() => { const editor = editorRef.current; editor.value = value; @@ -30,13 +40,26 @@ export default function InplaceEditor({ widthPx, value, definition, changeSet, s const editor = editorRef.current; setChangeSet(setChangeSetValue(changeSet, definition, editor.value)); } + onClose(); + } + if (shouldSave) { + const editor = editorRef.current; + setChangeSet(setChangeSetValue(changeSet, definition, editor.value)); + editor.blur(); + onClose('save'); } function handleKeyDown(event) { + const editor = editorRef.current; switch (event.keyCode) { case keycodes.escape: isChangedRef.current = false; onClose(); break; + case keycodes.enter: + setChangeSet(setChangeSetValue(changeSet, definition, editor.value)); + editor.blur(); + onClose('enter'); + break; } } return ( diff --git a/packages/web/src/datagrid/gridutil.js b/packages/web/src/datagrid/gridutil.js index 6ef53f740..457410295 100644 --- a/packages/web/src/datagrid/gridutil.js +++ b/packages/web/src/datagrid/gridutil.js @@ -68,8 +68,8 @@ export function countColumnSizes(loadedRows, columns, containerWidth, display) { export function countVisibleRealColumns(columnSizes, firstVisibleColumnScrollIndex, gridScrollAreaWidth, columns) { const visibleColumnCount = columnSizes.getVisibleScrollCount(firstVisibleColumnScrollIndex, gridScrollAreaWidth); - console.log('visibleColumnCount', visibleColumnCount); - console.log('gridScrollAreaWidth', gridScrollAreaWidth); + // console.log('visibleColumnCount', visibleColumnCount); + // console.log('gridScrollAreaWidth', gridScrollAreaWidth); const visibleRealColumnIndexes = []; const modelIndexes = {}; diff --git a/packages/web/src/tabs/TableDataTab.js b/packages/web/src/tabs/TableDataTab.js index 35c6373c3..17fa0f38a 100644 --- a/packages/web/src/tabs/TableDataTab.js +++ b/packages/web/src/tabs/TableDataTab.js @@ -15,7 +15,7 @@ export default function TableDataTab({ conid, database, schemaName, pureName, ta const [cache, setCache] = React.useState(createGridCache()); const [changeSet, setChangeSet] = React.useState(createChangeSet()); - console.log('changeSet', changeSet); + // console.log('changeSet', changeSet); const connection = useConnectionInfo(conid); const display = React.useMemo(