From 6d26d5833f9c02ebfcf02cc1549a093f07ec8f80 Mon Sep 17 00:00:00 2001 From: Aditya Toshniwal Date: Tue, 24 May 2022 11:39:34 +0530 Subject: [PATCH] Added support for multi-cell selection in the query tool grid. Fixes #7380 --- docs/en_US/release_notes_6_10.rst | 1 + web/package.json | 2 +- .../js/components/QueryToolDataGrid/index.jsx | 9 +++++ .../js/components/sections/ResultSet.jsx | 35 ++++++++++++++++--- .../components/sections/ResultSetToolbar.jsx | 4 +-- web/yarn.lock | 4 +-- 6 files changed, 46 insertions(+), 9 deletions(-) diff --git a/docs/en_US/release_notes_6_10.rst b/docs/en_US/release_notes_6_10.rst index 30b88e6d9..1e6d44106 100644 --- a/docs/en_US/release_notes_6_10.rst +++ b/docs/en_US/release_notes_6_10.rst @@ -25,6 +25,7 @@ Bug fixes | `Issue #7372 `_ - Tell Docker to always pull the latest base images when building containers. | `Issue #7373 `_ - Fixed an issue with geometry window zoom mouse scroll not working. | `Issue #7376 `_ - Fixed an issue where a popup for unsaved changes appears when clicking on the open file button for a blank query editor. + | `Issue #7380 `_ - Added support for multi-cell selection in the query tool grid. | `Issue #7383 `_ - Fixed an issue where Preferences are not saved when the dialog is maximized. | `Issue #7388 `_ - Fixed an issue where an error message fills the entire window if the query is long. | `Issue #7393 `_ - Ensure that the editor position should not get changed once it is opened. diff --git a/web/package.json b/web/package.json index be816ebf0..d9324de8f 100644 --- a/web/package.json +++ b/web/package.json @@ -152,7 +152,7 @@ "react": "^17.0.1", "react-aspen": "^1.1.0", "react-checkbox-tree": "^1.7.2", - "react-data-grid": "git+https://github.com/adityatoshniwal/react-data-grid.git/#1dc310dfaf5afea359404e867b7cf54953f47d1e", + "react-data-grid": "git+https://github.com/adityatoshniwal/react-data-grid.git/#8074ba4a31f3a320c50a17b6c5b528d9afd2b5de", "react-dom": "^17.0.1", "react-draggable": "^4.4.4", "react-leaflet": "^3.2.2", diff --git a/web/pgadmin/tools/sqleditor/static/js/components/QueryToolDataGrid/index.jsx b/web/pgadmin/tools/sqleditor/static/js/components/QueryToolDataGrid/index.jsx index 7ca5278bf..6dad918ef 100644 --- a/web/pgadmin/tools/sqleditor/static/js/components/QueryToolDataGrid/index.jsx +++ b/web/pgadmin/tools/sqleditor/static/js/components/QueryToolDataGrid/index.jsx @@ -39,6 +39,12 @@ const useStyles = makeStyles((theme)=>({ fontWeight: 'abc', '&[aria-colindex="1"]': { padding: 0, + }, + '&[aria-selected=true]:not([role="columnheader"]):not([aria-colindex="1"])': { + outlineWidth: '1px', + outlineOffset: '-1px', + backgroundColor: theme.palette.primary.light, + color: theme.otherVars.qtDatagridSelectFg, } }, '& .rdg-header-row .rdg-cell': { @@ -412,9 +418,12 @@ export default function QueryToolDataGrid({columns, rows, totalRowCount, dataCha mincolumnWidthBy={50} enableCellSelect={true} onCopy={handleCopy} + onMultiCopy={handleCopy} components={{ rowRenderer: CustomRow, }} + enableRangeSelection={true} + rangeLeftBoundaryColIdx={0} {...props} /> diff --git a/web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSet.jsx b/web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSet.jsx index 095a0b7ab..02779262b 100644 --- a/web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSet.jsx +++ b/web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSet.jsx @@ -733,10 +733,20 @@ export function ResultSet() { const [selectedRows, setSelectedRows] = useState(new Set()); const [selectedColumns, setSelectedColumns] = useState(new Set()); const selectedCell = useRef([]); + const selectedRange = useRef(null); const setSelectedCell = (val)=>{ selectedCell.current=val; fireRowsColsCellChanged(); }; + const setSelectedRange = (val)=>{ + if(val.startColumnIdx != val.endColumnIdx || + val.startRowIdx != val.endRowIdx) { + selectedRange.current=val; + } else { + selectedRange.current=null; + } + fireRowsColsCellChanged(); + }; const [rowsResetKey, setRowsResetKey] = useState(true); rsu.current.setEventBus(eventBus); @@ -746,7 +756,7 @@ export function ResultSet() { }; const fireRowsColsCellChanged = ()=>{ - eventBus.fireEvent(QUERY_TOOL_EVENTS.SELECTED_ROWS_COLS_CELL_CHANGED, selectedRows.size, selectedColumns.size, selectedCell.current?.length); + eventBus.fireEvent(QUERY_TOOL_EVENTS.SELECTED_ROWS_COLS_CELL_CHANGED, selectedRows.size, selectedColumns.size, selectedRange.current, selectedCell.current?.length); }; const executionStartCallback = async (query, explainObject, external=false, reconnect=false)=>{ @@ -1078,6 +1088,17 @@ export function ResultSet() { /* Row num col is added by QueryDataGrid, index will be +1 */ copyCols = _.filter(columns, (_c, i)=>selectedColumns.has(i+1)); copyRows = _.map(rows, (r)=>_.pick(r, _.map(copyCols, (c)=>c.key))); + } else if(selectedRange.current) { + let startColumnIdx = Math.min(selectedRange.current.startColumnIdx, selectedRange.current.endColumnIdx); + let endColumnIdx = Math.max(selectedRange.current.startColumnIdx, selectedRange.current.endColumnIdx); + let startRowIdx = Math.min(selectedRange.current.startRowIdx, selectedRange.current.endRowIdx); + let endRowIdx = Math.max(selectedRange.current.startRowIdx, selectedRange.current.endRowIdx); + copyCols = _.filter(columns, (_c, i)=>{ + /* Row num col is added by QueryDataGrid, index will be +1 */ + let idx = i+1; + return idx>=startColumnIdx && idx<=endColumnIdx; + }); + copyRows = rows.slice(startRowIdx, endRowIdx+1); } else if(selectedCell.current[0] && selectedCell.current[1]) { copyCols = [selectedCell.current[1]]; copyRows = [{[selectedCell.current[1].key]: selectedCell.current[0][selectedCell.current[1].key]}]; @@ -1139,13 +1160,18 @@ export function ResultSet() { }; useEffect(()=>{ - eventBus.registerListener(QUERY_TOOL_EVENTS.TRIGGER_DELETE_ROWS, triggerDeleteRows); eventBus.registerListener(QUERY_TOOL_EVENTS.COPY_DATA, copyDataFunc); return ()=>{ - eventBus.deregisterListener(QUERY_TOOL_EVENTS.TRIGGER_DELETE_ROWS, triggerDeleteRows); eventBus.deregisterListener(QUERY_TOOL_EVENTS.COPY_DATA, copyDataFunc); }; - }, [selectedRows, selectedColumns, queryData, dataChangeStore, selectedCell.current]); + }, [selectedRows, selectedColumns, columns, rows]); + + useEffect(()=>{ + eventBus.registerListener(QUERY_TOOL_EVENTS.TRIGGER_DELETE_ROWS, triggerDeleteRows); + return ()=>{ + eventBus.deregisterListener(QUERY_TOOL_EVENTS.TRIGGER_DELETE_ROWS, triggerDeleteRows); + }; + }, [selectedRows, queryData, dataChangeStore, rows]); useEffect(()=>{ const triggerAddRows = (_rows, fromClipboard)=>{ @@ -1251,6 +1277,7 @@ export function ResultSet() { selectedColumns={selectedColumns} onSelectedColumnsChange={setSelectedColumns} onSelectedCellChange={setSelectedCell} + onSelectedRangeChange={setSelectedRange} /> } diff --git a/web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSetToolbar.jsx b/web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSetToolbar.jsx index e525776fe..c141674e9 100644 --- a/web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSetToolbar.jsx +++ b/web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSetToolbar.jsx @@ -104,9 +104,9 @@ export function ResultSetToolbar({containerRef, canEdit, totalRowCount}) { eventBus.registerListener(QUERY_TOOL_EVENTS.DATAGRID_CHANGED, (isDirty)=>{ setDisableButton('save-data', !isDirty); }); - eventBus.registerListener(QUERY_TOOL_EVENTS.SELECTED_ROWS_COLS_CELL_CHANGED, (rows, cols, cells)=>{ + eventBus.registerListener(QUERY_TOOL_EVENTS.SELECTED_ROWS_COLS_CELL_CHANGED, (rows, cols, range, cell)=>{ setDisableButton('delete-rows', !rows); - setDisableButton('copy-rows', (!rows && !cols && !cells)); + setDisableButton('copy-rows', (!rows && !cols && !cell && !range)); }); }, []); diff --git a/web/yarn.lock b/web/yarn.lock index 6f8889118..f36434383 100644 --- a/web/yarn.lock +++ b/web/yarn.lock @@ -9069,9 +9069,9 @@ react-checkbox-tree@^1.7.2: nanoid "^3.0.0" prop-types "^15.5.8" -"react-data-grid@git+https://github.com/adityatoshniwal/react-data-grid.git/#1dc310dfaf5afea359404e867b7cf54953f47d1e": +"react-data-grid@git+https://github.com/adityatoshniwal/react-data-grid.git/#8074ba4a31f3a320c50a17b6c5b528d9afd2b5de": version "7.0.0-beta.12" - resolved "git+https://github.com/adityatoshniwal/react-data-grid.git/#1dc310dfaf5afea359404e867b7cf54953f47d1e" + resolved "git+https://github.com/adityatoshniwal/react-data-grid.git/#8074ba4a31f3a320c50a17b6c5b528d9afd2b5de" dependencies: clsx "^1.1.1"