using reducer for inplace editor

This commit is contained in:
Jan Prochazka
2020-03-27 21:11:11 +01:00
parent cdb3215b5f
commit 03550f1d27
3 changed files with 78 additions and 58 deletions

View File

@@ -105,10 +105,11 @@ export default function DataGridCore(props) {
const [dragStartCell, setDragStartCell] = React.useState(nullCell); const [dragStartCell, setDragStartCell] = React.useState(nullCell);
const [shiftDragStartCell, setShiftDragStartCell] = React.useState(nullCell); const [shiftDragStartCell, setShiftDragStartCell] = React.useState(nullCell);
const [inplaceEditorCell, setInplaceEditorCell] = React.useState(nullCell); // const [inplaceEditorCell, setInplaceEditorCell] = React.useState(nullCell);
const [inplaceEditorInitText, setInplaceEditorInitText] = React.useState(''); // const [inplaceEditorInitText, setInplaceEditorInitText] = React.useState('');
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 changeSetRef = React.useRef(changeSet); const changeSetRef = React.useRef(changeSet);
changeSetRef.current = changeSet; changeSetRef.current = changeSet;
@@ -175,6 +176,31 @@ export default function DataGridCore(props) {
const confirmSqlModalState = useModalState(); const confirmSqlModalState = useModalState();
const [confirmSql, setConfirmSql] = React.useState(''); 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), [ const columnSizes = React.useMemo(() => countColumnSizes(loadedRows, columns, containerWidth, display), [
loadedRows, loadedRows,
columns, columns,
@@ -223,19 +249,19 @@ export default function DataGridCore(props) {
} }
}, [tabVisible, tableElement]); }, [tabVisible, tableElement]);
const handleCloseInplaceEditor = React.useCallback( // const handleCloseInplaceEditor = React.useCallback(
mode => { // mode => {
const [row, col] = currentCell || []; // const [row, col] = currentCell || [];
setInplaceEditorCell(null); // setInplaceEditorCell(null);
setInplaceEditorInitText(null); // setInplaceEditorInitText(null);
setInplaceEditorShouldSave(false); // setInplaceEditorShouldSave(false);
if (tableElement) tableElement.focus(); // if (tableElement) tableElement.focus();
// @ts-ignore // // @ts-ignore
if (mode == 'enter' && row) moveCurrentCell(row + 1, col); // if (mode == 'enter' && row) moveCurrentCell(row + 1, col);
if (mode == 'save') setTimeout(handleSave, 1); // if (mode == 'save') setTimeout(handleSave, 1);
}, // },
[tableElement, currentCell] // [tableElement, currentCell]
); // );
const visibleRealColumns = React.useMemo( const visibleRealColumns = React.useMemo(
() => countVisibleRealColumns(columnSizes, firstVisibleColumnScrollIndex, gridScrollAreaWidth, columns), () => countVisibleRealColumns(columnSizes, firstVisibleColumnScrollIndex, gridScrollAreaWidth, columns),
@@ -275,11 +301,12 @@ export default function DataGridCore(props) {
setSelectedCells(getCellRange(cell, cell)); setSelectedCells(getCellRange(cell, cell));
setDragStartCell(cell); setDragStartCell(cell);
if (isRegularCell(cell) && !_.isEqual(cell, inplaceEditorCell) && _.isEqual(cell, currentCell)) { if (isRegularCell(cell) && !_.isEqual(cell, inplaceEditorState.cell) && _.isEqual(cell, currentCell)) {
setInplaceEditorShouldSave(false); // @ts-ignore
setInplaceEditorCell(cell); dispatchInsplaceEditor({ type: 'show', cell });
} else if (!_.isEqual(cell, inplaceEditorCell)) { } else if (!_.isEqual(cell, inplaceEditorState.cell)) {
handleCloseInplaceEditor(); // @ts-ignore
dispatchInsplaceEditor({ type: 'close' });
} }
} }
@@ -327,9 +354,10 @@ export default function DataGridCore(props) {
// await sleep(1); // await sleep(1);
// } // }
function handleSave() { function handleSave() {
if (inplaceEditorCell) { if (inplaceEditorState.cell) {
setInplaceEditorShouldSave(true); // @ts-ignore
dispatchInsplaceEditor({ type: 'shouldSave' });
return; return;
} }
const script = changeSetToSql(changeSetRef.current); const script = changeSetToSql(changeSetRef.current);
@@ -367,7 +395,7 @@ export default function DataGridCore(props) {
// this.saveAndFocus(); // this.saveAndFocus();
} }
if (inplaceEditorCell) return; if (inplaceEditorState.cell) return;
if ( if (
!event.ctrlKey && !event.ctrlKey &&
@@ -376,15 +404,14 @@ export default function DataGridCore(props) {
(event.keyCode >= keycodes.n0 && event.keyCode <= keycodes.n9) || (event.keyCode >= keycodes.n0 && event.keyCode <= keycodes.n9) ||
event.keyCode == keycodes.dash) event.keyCode == keycodes.dash)
) { ) {
setInplaceEditorInitText(event.nativeEvent.key); // @ts-ignore
setInplaceEditorShouldSave(false); dispatchInsplaceEditor({ type: 'show', text: event.nativeEvent.key, cell: currentCell });
setInplaceEditorCell(currentCell);
// console.log('event', event.nativeEvent); // console.log('event', event.nativeEvent);
} }
if (event.keyCode == keycodes.f2) { if (event.keyCode == keycodes.f2) {
setInplaceEditorShouldSave(false); // @ts-ignore
setInplaceEditorCell(currentCell); dispatchInsplaceEditor({ type: 'show', cell: currentCell });
} }
const moved = handleCursorMove(event); const moved = handleCursorMove(event);
@@ -604,10 +631,8 @@ export default function DataGridCore(props) {
rowIndex={firstVisibleRowScrollIndex + index} rowIndex={firstVisibleRowScrollIndex + index}
rowHeight={rowHeight} rowHeight={rowHeight}
visibleRealColumns={visibleRealColumns} visibleRealColumns={visibleRealColumns}
inplaceEditorCell={inplaceEditorCell} inplaceEditorState={inplaceEditorState}
inplaceEditorInitText={inplaceEditorInitText} dispatchInsplaceEditor={dispatchInsplaceEditor}
inplaceEditorShouldSave={inplaceEditorShouldSave}
onCloseInplaceEditor={handleCloseInplaceEditor}
cellIsSelected={cellIsSelected} cellIsSelected={cellIsSelected}
changeSet={changeSet} changeSet={changeSet}
setChangeSet={setChangeSet} setChangeSet={setChangeSet}

View File

@@ -79,10 +79,8 @@ export default function DataGridRow({
rowHeight, rowHeight,
rowIndex, rowIndex,
visibleRealColumns, visibleRealColumns,
inplaceEditorCell, inplaceEditorState,
inplaceEditorInitText, dispatchInsplaceEditor,
inplaceEditorShouldSave,
onCloseInplaceEditor,
cellIsSelected, cellIsSelected,
row, row,
display, display,
@@ -113,17 +111,16 @@ export default function DataGridRow({
isModifiedRow={!!matchedChangeSetItem} isModifiedRow={!!matchedChangeSetItem}
isModifiedCell={matchedChangeSetItem && col.uniqueName in matchedChangeSetItem.fields} 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] ? (
<InplaceEditor <InplaceEditor
widthPx={col.widthPx} widthPx={col.widthPx}
value={inplaceEditorInitText || rowUpdated[col.uniqueName]} inplaceEditorState={inplaceEditorState}
selectAll={!inplaceEditorInitText} dispatchInsplaceEditor={dispatchInsplaceEditor}
cellValue={rowUpdated[col.uniqueName]}
changeSet={changeSet} changeSet={changeSet}
setChangeSet={setChangeSet} setChangeSet={setChangeSet}
definition={display.getChangeSetField(row, col.uniqueName)} definition={display.getChangeSetField(row, col.uniqueName)}
onClose={onCloseInplaceEditor} />
shouldSave={inplaceEditorShouldSave}
/>
) : ( ) : (
<> <>
<CellFormattedValue value={rowUpdated[col.uniqueName]} /> <CellFormattedValue value={rowUpdated[col.uniqueName]} />

View File

@@ -16,22 +16,20 @@ const StyledInput = styled.input`
export default function InplaceEditor({ export default function InplaceEditor({
widthPx, widthPx,
value,
definition, definition,
changeSet, changeSet,
setChangeSet, setChangeSet,
onClose, cellValue,
selectAll, inplaceEditorState,
shouldSave, dispatchInsplaceEditor,
changedOnCreate,
}) { }) {
const editorRef = React.useRef(); const editorRef = React.useRef();
const isChangedRef = React.createRef(changedOnCreate); const isChangedRef = React.useRef(!!inplaceEditorState.text);
React.useEffect(() => { React.useEffect(() => {
const editor = editorRef.current; const editor = editorRef.current;
editor.value = value; editor.value = inplaceEditorState.text || cellValue;
editor.focus(); editor.focus();
if (selectAll) { if (inplaceEditorState.selectAll) {
editor.select(); editor.select();
} }
}, []); }, []);
@@ -40,25 +38,25 @@ export default function InplaceEditor({
const editor = editorRef.current; const editor = editorRef.current;
setChangeSet(setChangeSetValue(changeSet, definition, editor.value)); setChangeSet(setChangeSetValue(changeSet, definition, editor.value));
} }
onClose(); dispatchInsplaceEditor({ type: 'close' });
} }
if (shouldSave) { if (inplaceEditorState.shouldSave) {
const editor = editorRef.current; const editor = editorRef.current;
setChangeSet(setChangeSetValue(changeSet, definition, editor.value)); setChangeSet(setChangeSetValue(changeSet, definition, editor.value));
editor.blur(); editor.blur();
onClose('save'); dispatchInsplaceEditor({ type: 'close', mode: 'save' });
} }
function handleKeyDown(event) { function handleKeyDown(event) {
const editor = editorRef.current; const editor = editorRef.current;
switch (event.keyCode) { switch (event.keyCode) {
case keycodes.escape: case keycodes.escape:
isChangedRef.current = false; isChangedRef.current = false;
onClose(); dispatchInsplaceEditor({ type: 'close' });
break; break;
case keycodes.enter: case keycodes.enter:
setChangeSet(setChangeSetValue(changeSet, definition, editor.value)); setChangeSet(setChangeSetValue(changeSet, definition, editor.value));
editor.blur(); editor.blur();
onClose('enter'); dispatchInsplaceEditor({ type: 'close', mode: 'enter' });
break; break;
} }
} }