From 03550f1d272c624da4a0aa26db618d53dee72b9d Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Fri, 27 Mar 2020 21:11:11 +0100 Subject: [PATCH] using reducer for inplace editor --- packages/web/src/datagrid/DataGridCore.js | 95 ++++++++++++++-------- packages/web/src/datagrid/DataGridRow.js | 17 ++-- packages/web/src/datagrid/InplaceEditor.js | 24 +++--- 3 files changed, 78 insertions(+), 58 deletions(-) diff --git a/packages/web/src/datagrid/DataGridCore.js b/packages/web/src/datagrid/DataGridCore.js index 5553deeb..4df86dec 100644 --- a/packages/web/src/datagrid/DataGridCore.js +++ b/packages/web/src/datagrid/DataGridCore.js @@ -105,10 +105,11 @@ export default function DataGridCore(props) { const [dragStartCell, setDragStartCell] = React.useState(nullCell); const [shiftDragStartCell, setShiftDragStartCell] = React.useState(nullCell); - const [inplaceEditorCell, setInplaceEditorCell] = React.useState(nullCell); - const [inplaceEditorInitText, setInplaceEditorInitText] = React.useState(''); - const [inplaceEditorShouldSave, setInplaceEditorShouldSave] = React.useState(false); - const [inplaceEditorChangedOnCreate, setInplaceEditorChangedOnCreate] = React.useState(false); + // 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; @@ -175,6 +176,31 @@ export default function DataGridCore(props) { const confirmSqlModalState = useModalState(); const [confirmSql, setConfirmSql] = React.useState(''); + const [inplaceEditorState, dispatchInsplaceEditor] = React.useReducer((state, action) => { + switch (action.type) { + case 'show': + return { + cell: action.cell, + text: action.text, + }; + case 'close': { + const [row, col] = currentCell || []; + if (tableElement) tableElement.focus(); + // @ts-ignore + if (action.mode == 'enter' && row) setTimeout(() => moveCurrentCell(row + 1, col), 0); + if (action.mode == 'save') setTimeout(handleSave, 0); + return {}; + } + case 'shouldSave': { + return { + ...state, + shouldSave: true, + }; + } + } + return {}; + }, {}); + const columnSizes = React.useMemo(() => countColumnSizes(loadedRows, columns, containerWidth, display), [ loadedRows, columns, @@ -223,19 +249,19 @@ export default function DataGridCore(props) { } }, [tabVisible, tableElement]); - 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 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), @@ -275,11 +301,12 @@ export default function DataGridCore(props) { setSelectedCells(getCellRange(cell, cell)); setDragStartCell(cell); - if (isRegularCell(cell) && !_.isEqual(cell, inplaceEditorCell) && _.isEqual(cell, currentCell)) { - setInplaceEditorShouldSave(false); - setInplaceEditorCell(cell); - } else if (!_.isEqual(cell, inplaceEditorCell)) { - handleCloseInplaceEditor(); + if (isRegularCell(cell) && !_.isEqual(cell, inplaceEditorState.cell) && _.isEqual(cell, currentCell)) { + // @ts-ignore + dispatchInsplaceEditor({ type: 'show', cell }); + } else if (!_.isEqual(cell, inplaceEditorState.cell)) { + // @ts-ignore + dispatchInsplaceEditor({ type: 'close' }); } } @@ -327,9 +354,10 @@ export default function DataGridCore(props) { // await sleep(1); // } - function handleSave() { - if (inplaceEditorCell) { - setInplaceEditorShouldSave(true); + function handleSave() { + if (inplaceEditorState.cell) { + // @ts-ignore + dispatchInsplaceEditor({ type: 'shouldSave' }); return; } const script = changeSetToSql(changeSetRef.current); @@ -367,7 +395,7 @@ export default function DataGridCore(props) { // this.saveAndFocus(); } - if (inplaceEditorCell) return; + if (inplaceEditorState.cell) return; if ( !event.ctrlKey && @@ -376,15 +404,14 @@ export default function DataGridCore(props) { (event.keyCode >= keycodes.n0 && event.keyCode <= keycodes.n9) || event.keyCode == keycodes.dash) ) { - setInplaceEditorInitText(event.nativeEvent.key); - setInplaceEditorShouldSave(false); - setInplaceEditorCell(currentCell); + // @ts-ignore + dispatchInsplaceEditor({ type: 'show', text: event.nativeEvent.key, cell: currentCell }); // console.log('event', event.nativeEvent); } if (event.keyCode == keycodes.f2) { - setInplaceEditorShouldSave(false); - setInplaceEditorCell(currentCell); + // @ts-ignore + dispatchInsplaceEditor({ type: 'show', cell: currentCell }); } const moved = handleCursorMove(event); @@ -604,10 +631,8 @@ export default function DataGridCore(props) { rowIndex={firstVisibleRowScrollIndex + index} rowHeight={rowHeight} visibleRealColumns={visibleRealColumns} - inplaceEditorCell={inplaceEditorCell} - inplaceEditorInitText={inplaceEditorInitText} - inplaceEditorShouldSave={inplaceEditorShouldSave} - onCloseInplaceEditor={handleCloseInplaceEditor} + inplaceEditorState={inplaceEditorState} + dispatchInsplaceEditor={dispatchInsplaceEditor} cellIsSelected={cellIsSelected} changeSet={changeSet} setChangeSet={setChangeSet} diff --git a/packages/web/src/datagrid/DataGridRow.js b/packages/web/src/datagrid/DataGridRow.js index ff21b45e..2cf0a68b 100644 --- a/packages/web/src/datagrid/DataGridRow.js +++ b/packages/web/src/datagrid/DataGridRow.js @@ -79,10 +79,8 @@ export default function DataGridRow({ rowHeight, rowIndex, visibleRealColumns, - inplaceEditorCell, - inplaceEditorInitText, - inplaceEditorShouldSave, - onCloseInplaceEditor, + inplaceEditorState, + dispatchInsplaceEditor, cellIsSelected, row, display, @@ -113,17 +111,16 @@ export default function DataGridRow({ isModifiedRow={!!matchedChangeSetItem} isModifiedCell={matchedChangeSetItem && col.uniqueName in matchedChangeSetItem.fields} > - {inplaceEditorCell && rowIndex == inplaceEditorCell[0] && col.colIndex == inplaceEditorCell[1] ? ( + {inplaceEditorState.cell && rowIndex == inplaceEditorState.cell[0] && col.colIndex == inplaceEditorState.cell[1] ? ( + /> ) : ( <> diff --git a/packages/web/src/datagrid/InplaceEditor.js b/packages/web/src/datagrid/InplaceEditor.js index 03e073eb..8b687a83 100644 --- a/packages/web/src/datagrid/InplaceEditor.js +++ b/packages/web/src/datagrid/InplaceEditor.js @@ -16,22 +16,20 @@ const StyledInput = styled.input` export default function InplaceEditor({ widthPx, - value, definition, changeSet, setChangeSet, - onClose, - selectAll, - shouldSave, - changedOnCreate, + cellValue, + inplaceEditorState, + dispatchInsplaceEditor, }) { const editorRef = React.useRef(); - const isChangedRef = React.createRef(changedOnCreate); + const isChangedRef = React.useRef(!!inplaceEditorState.text); React.useEffect(() => { const editor = editorRef.current; - editor.value = value; + editor.value = inplaceEditorState.text || cellValue; editor.focus(); - if (selectAll) { + if (inplaceEditorState.selectAll) { editor.select(); } }, []); @@ -40,25 +38,25 @@ export default function InplaceEditor({ const editor = editorRef.current; setChangeSet(setChangeSetValue(changeSet, definition, editor.value)); } - onClose(); + dispatchInsplaceEditor({ type: 'close' }); } - if (shouldSave) { + if (inplaceEditorState.shouldSave) { const editor = editorRef.current; setChangeSet(setChangeSetValue(changeSet, definition, editor.value)); editor.blur(); - onClose('save'); + dispatchInsplaceEditor({ type: 'close', mode: 'save' }); } function handleKeyDown(event) { const editor = editorRef.current; switch (event.keyCode) { case keycodes.escape: isChangedRef.current = false; - onClose(); + dispatchInsplaceEditor({ type: 'close' }); break; case keycodes.enter: setChangeSet(setChangeSetValue(changeSet, definition, editor.value)); editor.blur(); - onClose('enter'); + dispatchInsplaceEditor({ type: 'close', mode: 'enter' }); break; } }