diff --git a/packages/web/src/datagrid/DataGridContextMenu.js b/packages/web/src/datagrid/DataGridContextMenu.js new file mode 100644 index 000000000..9fca5b523 --- /dev/null +++ b/packages/web/src/datagrid/DataGridContextMenu.js @@ -0,0 +1,24 @@ +import React from 'react'; +import { DropDownMenuItem } from '../modals/DropDownMenu'; + +export default function DataGridContextMenu({ copy, revertRowChanges, deleteSelectedRows, insertNewRow, reload }) { + return ( + <> + + Reload + + + Copy + + + Revert row changes + + + Delete selected rows + + + Insert new row + + + ); +} diff --git a/packages/web/src/datagrid/DataGridCore.js b/packages/web/src/datagrid/DataGridCore.js index 6ce81383d..43676a89d 100644 --- a/packages/web/src/datagrid/DataGridCore.js +++ b/packages/web/src/datagrid/DataGridCore.js @@ -24,7 +24,13 @@ import { import keycodes from '../utility/keycodes'; import InplaceEditor from './InplaceEditor'; import DataGridRow from './DataGridRow'; -import { countColumnSizes, countVisibleRealColumns, filterCellForRow, filterCellsForRow } from './gridutil'; +import { + countColumnSizes, + countVisibleRealColumns, + filterCellForRow, + filterCellsForRow, + cellIsSelected, +} from './gridutil'; import useModalState from '../modals/useModalState'; import ConfirmSqlModal from '../modals/ConfirmSqlModal'; import { @@ -44,6 +50,8 @@ import DataGridToolbar from './DataGridToolbar'; import usePropsCompare from '../utility/usePropsCompare'; import ColumnHeaderControl from './ColumnHeaderControl'; import InlineButton from '../widgets/InlineButton'; +import { showMenu } from '../modals/DropDownMenu'; +import DataGridContextMenu from './DataGridContextMenu'; const GridContainer = styled.div` position: absolute; @@ -335,6 +343,21 @@ export default function DataGridCore(props) { setFirstVisibleColumnScrollIndex(value); }; + const handleContextMenu = event => { + event.preventDefault(); + showMenu( + event.pageX, + event.pageY, + + ); + }; + function handleGridMouseDown(event) { if (event.target.closest('.buttonLike')) return; if (event.target.closest('input')) return; @@ -343,6 +366,9 @@ export default function DataGridCore(props) { // @ts-ignore if (focusFieldRef.current) focusFieldRef.current.focus(); const cell = cellFromEvent(event); + + if (event.button == 2 && cell && cellIsSelected(cell[0], cell[1], selectedCells)) return; + const autofill = event.target.closest('div.autofillHandleMarker'); if (autofill) { setAutofillDragStartCell(cell); @@ -528,7 +554,7 @@ export default function DataGridCore(props) { setChangeSet(createChangeSet()); } - function deleteCurrentRow() { + function deleteSelectedRows() { const updatedChangeSet = getSelectedRowDefinitions().reduce((chs, row) => deleteChangeSetRows(chs, row), changeSet); setChangeSet(updatedChangeSet); } @@ -595,7 +621,24 @@ export default function DataGridCore(props) { display.reload(); } + const insertNewRow = () => { + if (display.baseTable) { + setChangeSet(changeSetInsertNewRow(changeSet, display.baseTable)); + const cell = [rowCountNewIncluded, (currentCell && currentCell[1]) || 0]; + // @ts-ignore + setCurrentCell(cell); + // @ts-ignore + setSelectedCells([cell]); + scrollIntoView(cell); + } + }; + function handleGridKeyDown(event) { + if (event.keyCode == keycodes.f5) { + event.preventDefault(); + reload(); + } + if (event.keyCode == keycodes.s && event.ctrlKey) { event.preventDefault(); handleSave(); @@ -624,21 +667,13 @@ export default function DataGridCore(props) { if (event.keyCode == keycodes.delete && event.ctrlKey) { event.preventDefault(); - deleteCurrentRow(); + deleteSelectedRows(); // this.saveAndFocus(); } if (event.keyCode == keycodes.insert && !event.ctrlKey) { event.preventDefault(); - if (display.baseTable) { - setChangeSet(changeSetInsertNewRow(changeSet, display.baseTable)); - const cell = [rowCountNewIncluded, (currentCell && currentCell[1]) || 0]; - // @ts-ignore - setCurrentCell(cell); - // @ts-ignore - setSelectedCells([cell]); - scrollIntoView(cell); - } + insertNewRow(); // this.saveAndFocus(); } @@ -834,6 +869,7 @@ export default function DataGridCore(props) { onMouseUp={handleGridMouseUp} onWheel={handleGridWheel} ref={tableRef} + onContextMenu={handleContextMenu} > diff --git a/packages/web/src/datagrid/DataGridRow.js b/packages/web/src/datagrid/DataGridRow.js index 670f98ef3..b140c093d 100644 --- a/packages/web/src/datagrid/DataGridRow.js +++ b/packages/web/src/datagrid/DataGridRow.js @@ -16,6 +16,7 @@ import { findExistingChangeSetItem } from '@dbgate/datalib'; import keycodes from '../utility/keycodes'; import InplaceEditor from './InplaceEditor'; import usePropsCompare from '../utility/usePropsCompare'; +import { cellIsSelected } from './gridutil'; const TableBodyCell = styled.td` font-weight: normal; @@ -126,17 +127,6 @@ function CellFormattedValue({ value }) { return value; } -function cellIsSelected(row, col, selectedCells) { - if (!selectedCells) return false; - for (const [selectedRow, selectedCol] of selectedCells) { - if (row == selectedRow && col == selectedCol) return true; - if (selectedRow == 'header' && col == selectedCol) return true; - if (row == selectedRow && selectedCol == 'header') return true; - if (selectedRow == 'header' && selectedCol == 'header') return true; - } - return false; -} - function DataGridRow({ rowHeight, rowIndex, diff --git a/packages/web/src/datagrid/gridutil.ts b/packages/web/src/datagrid/gridutil.ts index 59a28aeb7..a6841e75c 100644 --- a/packages/web/src/datagrid/gridutil.ts +++ b/packages/web/src/datagrid/gridutil.ts @@ -116,3 +116,14 @@ export function filterCellsForRow(cells, row: number): CellAddress[] | null { const res = (cells || []).filter(x => x[0] == row || _.isString(x[0])); return res.length > 0 ? res : null; } + +export function cellIsSelected(row, col, selectedCells) { + if (!selectedCells) return false; + for (const [selectedRow, selectedCol] of selectedCells) { + if (row == selectedRow && col == selectedCol) return true; + if (selectedRow == 'header' && col == selectedCol) return true; + if (row == selectedRow && selectedCol == 'header') return true; + if (selectedRow == 'header' && selectedCol == 'header') return true; + } + return false; +}