From 3417186df74f07e54e61149e9c5e1dcb9b45b5e2 Mon Sep 17 00:00:00 2001 From: Aditya Toshniwal Date: Thu, 7 Nov 2024 18:02:39 +0530 Subject: [PATCH] Fix issues found while testing pagination changes. #1780 --- web/pgadmin/misc/bgprocess/processes.py | 6 +--- .../static/js/components/PgReactDataGrid.jsx | 4 +-- web/pgadmin/static/js/validators.js | 2 +- web/pgadmin/tools/psql/__init__.py | 12 +++++-- web/pgadmin/tools/sqleditor/__init__.py | 4 +-- .../js/components/QueryToolDataGrid/index.jsx | 4 --- .../js/components/sections/ResultSet.jsx | 15 ++++---- .../components/sections/ResultSetToolbar.jsx | 34 ++++++++++++++----- 8 files changed, 49 insertions(+), 32 deletions(-) diff --git a/web/pgadmin/misc/bgprocess/processes.py b/web/pgadmin/misc/bgprocess/processes.py index 2e97bc422..fd7225f2d 100644 --- a/web/pgadmin/misc/bgprocess/processes.py +++ b/web/pgadmin/misc/bgprocess/processes.py @@ -177,11 +177,7 @@ class BatchProcess: import secrets import string - return ''.join( - secrets.choice( - string.ascii_uppercase + string.digits - ) for _ in range(size) - ) + return ''.join(secrets.choice(string.digits) for _ in range(size)) created = False size = 0 diff --git a/web/pgadmin/static/js/components/PgReactDataGrid.jsx b/web/pgadmin/static/js/components/PgReactDataGrid.jsx index c8d94e6c0..6cf8f0425 100644 --- a/web/pgadmin/static/js/components/PgReactDataGrid.jsx +++ b/web/pgadmin/static/js/components/PgReactDataGrid.jsx @@ -33,7 +33,7 @@ const StyledReactDataGrid = styled(ReactDataGrid)(({theme})=>({ '&[aria-colindex="1"]': { padding: 0, }, - '&[aria-selected=true]:not([role="columnheader"])': { + '&[aria-selected=true]:not([aria-colindex="1"]):not([role="columnheader"])': { outlineWidth: '0px', outlineOffset: '0px', }, @@ -61,7 +61,7 @@ const StyledReactDataGrid = styled(ReactDataGrid)(({theme})=>({ }, '&.ReactGrid-cellSelection': { '& .rdg-cell': { - '&[aria-selected=true]:not([role="columnheader"])': { + '&[aria-selected=true]:not([aria-colindex="1"]):not([role="columnheader"])': { outlineWidth: '1px', outlineOffset: '-1px', backgroundColor: theme.palette.primary.light, diff --git a/web/pgadmin/static/js/validators.js b/web/pgadmin/static/js/validators.js index d315f55b9..c9f1bb71b 100644 --- a/web/pgadmin/static/js/validators.js +++ b/web/pgadmin/static/js/validators.js @@ -15,7 +15,7 @@ import pgAdmin from 'sources/pgadmin'; export function minMaxValidator(label, value, minValue, maxValue) { if((_.isUndefined(value) || _.isNull(value) || String(value) === '')) return null; - if (!_.isUndefined(minValue) && value < minValue) { + if (!_.isUndefined(minValue) && (value < minValue || value === '-')) { return sprintf(pgAdmin.Browser.messages.MUST_GR_EQ, label, minValue); } else if (!_.isUndefined(maxValue) && value > maxValue) { return sprintf(pgAdmin.Browser.messages.MUST_LESS_EQ, label, maxValue); diff --git a/web/pgadmin/tools/psql/__init__.py b/web/pgadmin/tools/psql/__init__.py index 52bd33a0e..11b2ce05f 100644 --- a/web/pgadmin/tools/psql/__init__.py +++ b/web/pgadmin/tools/psql/__init__.py @@ -263,10 +263,16 @@ def non_windows_platform(parent, p, fd, data, max_read_bytes, sid): timeout = 0 # module provides access to platform-specific I/O # monitoring functions - (data_ready, _, _) = select.select([parent, fd], [], [], - timeout) + try: + (data_ready, _, _) = select.select([parent, fd], [], [], + timeout) - read_terminal_data(parent, data_ready, max_read_bytes, sid) + read_terminal_data(parent, data_ready, max_read_bytes, sid) + except OSError as e: + # If the process is killed, bad file descriptor exception may + # occur. Handle it gracefully + if p.poll() is not None: + raise e def pty_handel_io(connection_data, data, sid): diff --git a/web/pgadmin/tools/sqleditor/__init__.py b/web/pgadmin/tools/sqleditor/__init__.py index a4a1df6e3..8b7f17f8a 100644 --- a/web/pgadmin/tools/sqleditor/__init__.py +++ b/web/pgadmin/tools/sqleditor/__init__.py @@ -1129,7 +1129,7 @@ def poll(trans_id): pagination = { 'page_size': page_size, 'page_count': math.ceil(conn.total_rows / page_size), - 'page_no': math.floor(rows_fetched_from / page_size) + 1, + 'page_no': math.floor((rows_fetched_from - 1) / page_size) + 1, 'rows_from': rows_fetched_from, 'rows_to': rows_fetched_to } @@ -1197,7 +1197,7 @@ def fetch_window(trans_id, from_rownum=0, to_rownum=0): pagination = { 'page_size': page_size, 'page_count': math.ceil(conn.total_rows / page_size), - 'page_no': math.floor(rows_fetched_from / page_size) + 1, + 'page_no': math.floor((rows_fetched_from - 1) / page_size) + 1, 'rows_from': rows_fetched_from, 'rows_to': rows_fetched_to } 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 1471902d0..780e4bf5f 100644 --- a/web/pgadmin/tools/sqleditor/static/js/components/QueryToolDataGrid/index.jsx +++ b/web/pgadmin/tools/sqleditor/static/js/components/QueryToolDataGrid/index.jsx @@ -73,10 +73,6 @@ const StyledPgReactDataGrid = styled(PgReactDataGrid)(({theme})=>({ '& .rdg-cell:nth-of-type(1)': { backgroundColor: theme.palette.grey[600], }, - '& .rdg-cell:nth-of-type(1)[aria-selected="true"]':{ - backgroundColor: theme.palette.primary.main, - color: theme.palette.primary.contrastText, - }, '&[aria-selected="true"] .rdg-cell:nth-of-type(1)': { backgroundColor: theme.palette.primary.main, color: theme.palette.primary.contrastText, 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 4853cbb83..aab595514 100644 --- a/web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSet.jsx +++ b/web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSet.jsx @@ -868,15 +868,19 @@ export function ResultSet() { eventBus.fireEvent(QUERY_TOOL_EVENTS.SELECTED_ROWS_COLS_CELL_CHANGED, selectedRows.size, selectedColumns.size, selectedRange.current, selectedCell.current?.length); }; + const resetSelectionAndChanges = ()=>{ + dispatchDataChange({type: 'reset'}); + setSelectedRows(new Set()); + setSelectedColumns(new Set()); + }; + const executionStartCallback = async (query, { explainObject, macroSQL, external=false, reconnect=false, executeCursor=false, refreshData=false })=>{ const yesCallback = async ()=>{ /* Reset */ eventBus.fireEvent(QUERY_TOOL_EVENTS.HIGHLIGHT_ERROR, null); - dispatchDataChange({type: 'reset'}); - setSelectedRows(new Set()); - setSelectedColumns(new Set()); + resetSelectionAndChanges(); rsu.current.resetClientPKIndex(); setLoaderText(gettext('Waiting for the query to complete...')); setDataOutputQuery(query); @@ -1110,6 +1114,7 @@ export function ResultSet() { pageDataDirty.current = false; fetchWindow(...args); } + resetSelectionAndChanges(); }); return ()=>{ deregFetch(); @@ -1234,9 +1239,7 @@ export function ResultSet() { }); setColumns((prev)=>prev); } - dispatchDataChange({type: 'reset'}); - setSelectedRows(new Set()); - setSelectedColumns(new Set()); + resetSelectionAndChanges(); eventBus.fireEvent(QUERY_TOOL_EVENTS.SET_CONNECTION_STATUS, respData.data.transaction_status); eventBus.fireEvent(QUERY_TOOL_EVENTS.SET_MESSAGE, ''); pgAdmin.Browser.notifier.success(gettext('Data saved successfully.')); 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 7fe0f9bf2..046f34bc7 100644 --- a/web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSetToolbar.jsx +++ b/web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSetToolbar.jsx @@ -35,7 +35,7 @@ import PropTypes from 'prop-types'; import CodeMirror from '../../../../../../static/js/components/ReactCodeMirror'; import { setEditorPosition } from '../QueryToolDataGrid/Editors'; import { InputText } from '../../../../../../static/js/components/FormComponents'; -import { minMaxValidator } from '../../../../../../static/js/validators'; +import { isEmptyString, minMaxValidator } from '../../../../../../static/js/validators'; const StyledDiv = styled('div')(({theme})=>({ padding: '2px', @@ -111,6 +111,7 @@ function PaginationInputs({pagination, totalRowCount, clearSelection}) { from: pagination.rows_from ?? 0, to: pagination.rows_to ?? 0, pageNo: pagination.page_no ?? 0, + pageCount: pagination.page_count ?? 0, }); const goToPage = (pageNo)=>{ @@ -138,22 +139,31 @@ function PaginationInputs({pagination, totalRowCount, clearSelection}) { } }; + useEffect(()=>{ + setInputs({ + from: pagination.rows_from ?? 0, + to: pagination.rows_to ?? 0, + pageNo: pagination.page_no ?? 0, + pageCount: pagination.page_count ?? 0, + }); + }, [pagination, editPageRange]); + useEffect(()=>{ // validate setErrorInputs((prev)=>{ let errors = {...prev}; - if(minMaxValidator('', inputs.pageNo, 1, pagination.page_count)) { + if(minMaxValidator('', inputs.pageNo, 1, inputs.pageCount) || isEmptyString(inputs.pageNo)) { errors.pageNo = true; } else { errors.pageNo = false; } - if(minMaxValidator('', inputs.from, 1, inputs.to)) { + if(minMaxValidator('', inputs.from, 1, inputs.to) || isEmptyString(inputs.from)) { errors.from = true; } else { errors.from = false; } - if(minMaxValidator('', inputs.to, 1, totalRowCount)) { + if(minMaxValidator('', inputs.to, 1, totalRowCount) || isEmptyString(inputs.to)) { errors.to = true; } else { errors.to = false; @@ -161,14 +171,16 @@ function PaginationInputs({pagination, totalRowCount, clearSelection}) { return errors; }); - }, [inputs, pagination]); + }, [inputs]); return ( {editPageRange ?
{gettext('Showing rows:')}
-
{gettext('to')}
- eventBus.fireEvent(QUERY_TOOL_EVENTS.FETCH_WINDOW, inputs.from, inputs.to)} - icon={} + disabled={errorInputs.from || errorInputs.to} icon={} />}
 
{gettext('Page No:')} -