diff --git a/docs/en_US/release_notes_8_14.rst b/docs/en_US/release_notes_8_14.rst index 13d24e1088b..e93b13ee0e3 100644 --- a/docs/en_US/release_notes_8_14.rst +++ b/docs/en_US/release_notes_8_14.rst @@ -25,7 +25,6 @@ New features | `Issue #5786 `_ - Allow the use of a pgpass file in the pgAdmin container via Docker secrets. | `Issue #6592 `_ - Fixed multiple issues and improved ERD auto-layout. | `Issue #8095 `_ - Added support for a builtin locale provider in the Database dialog. - | `Issue #8134 `_ - Add a user preference to enable/disable alternating row background colors in the data output of query tool. Housekeeping ************ @@ -39,5 +38,9 @@ Bug fixes | `Issue #7486 `_ - Fixed an issue where indent with space was not aligning to next tab position. | `Issue #7865 `_ - Fixed an issue related to the query tool update connection after the server disconnected from the object explorer. | `Issue #8010 `_ - Fixed an issue where query tool should show results and messages only from the last executed query. + | `Issue #8028 `_ - Fixed an issue where query tool throws syntax error if a newly added row is untouched and saved. | `Issue #8065 `_ - Ensure the crypt key is retrieved correctly on backend server restart. + | `Issue #8098 `_ - Fixed an issue in schema diff where an error message popup was showing some garbage without any info. | `Issue #8127 `_ - Fixed an issue where query tool should not prompt for unsaved changes when there are no changes. + | `Issue #8134 `_ - Add a user preference to enable/disable alternating row background colors in the data output of query tool. + | `Issue #8158 `_ - Fixed an issue where auto-width of wide columns in data output is incorrectly calculated. diff --git a/web/pgadmin/static/js/utils.js b/web/pgadmin/static/js/utils.js index 95b5f7deba3..8a38c01ba79 100644 --- a/web/pgadmin/static/js/utils.js +++ b/web/pgadmin/static/js/utils.js @@ -654,15 +654,15 @@ export function requestAnimationAndFocus(ele) { }); } - -export function scrollbarWidth() { - // thanks too https://davidwalsh.name/detect-scrollbar-width - const scrollDiv = document.createElement('div'); - scrollDiv.setAttribute('style', 'width: 100px; height: 100px; overflow: scroll; position:absolute; top:-9999px;'); - document.body.appendChild(scrollDiv); - const scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth; - document.body.removeChild(scrollDiv); - return scrollbarWidth; +export function measureText(text, font) { + if(!measureText.ele) { + measureText.ele = document.createElement('div'); + measureText.ele.style.cssText = `position: absolute; visibility: hidden; white-space: nowrap; font: ${font}`; + document.body.appendChild(measureText.ele); + } + measureText.ele.innerHTML = text; + const dim = measureText.ele.getBoundingClientRect(); + return {width: dim.width, height: dim.height}; } const CHART_THEME_COLORS = { 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 94593a3d81f..1882e744715 100644 --- a/web/pgadmin/tools/sqleditor/static/js/components/QueryToolDataGrid/index.jsx +++ b/web/pgadmin/tools/sqleditor/static/js/components/QueryToolDataGrid/index.jsx @@ -23,6 +23,7 @@ import PropTypes from 'prop-types'; import gettext from 'sources/gettext'; import PgReactDataGrid from '../../../../../../static/js/components/PgReactDataGrid'; import { isMac } from '../../../../../../static/js/keyboard_shortcuts'; +import { measureText } from '../../../../../../static/js/utils'; export const ROWNUM_KEY = '$_pgadmin_rownum_key_$'; export const GRID_ROW_SELECT_KEY = '$_pgadmin_gridrowselect_key_$'; @@ -271,7 +272,7 @@ function initialiseColumns(columns, rows, totalRowCount, columnWidthBy) { canvasContext.font = '12px Roboto'; for(const col of retColumns) { - col.width = getTextWidth(col, rows, canvasContext, columnWidthBy); + col.width = getColumnWidth(col, rows, canvasContext, columnWidthBy); col.resizable = true; col.renderEditCellOptions = { commitOnOutsideClick: false, @@ -347,7 +348,7 @@ function formatColumns(columns, dataChangeStore, selectedColumns, onSelectedColu return retColumns; } -function getTextWidth(column, rows, canvas, columnWidthBy) { +function getColumnWidth(column, rows, canvas, columnWidthBy) { const dataWidthReducer = (longest, nextRow) => { let value = nextRow[column.key]; if(_.isNull(value) || _.isUndefined(value)) { @@ -358,16 +359,16 @@ function getTextWidth(column, rows, canvas, columnWidthBy) { }; let columnHeaderLen = column.display_name.length > column.display_type.length ? - canvas.measureText(column.display_name).width : canvas.measureText(column.display_type).width; - /* padding 12, icon-width 15 */ - columnHeaderLen += 15 + 12; + measureText(column.display_name, '12px Roboto').width : measureText(column.display_type, '12px Roboto').width; + /* padding 12, margin 4, icon-width 15, */ + columnHeaderLen += 15 + 12 + 4; if(column.column_type_internal == 'geometry' || column.column_type_internal == 'geography') { columnHeaderLen += 40; } let width = columnHeaderLen; if(typeof(columnWidthBy) == 'number') { - /* padding 16 */ - width = 16 + Math.ceil(canvas.measureText(rows.reduce(dataWidthReducer, '')).width); + /* padding 16, border 1px */ + width = 16 + measureText(rows.reduce(dataWidthReducer, ''), '12px Roboto').width + 1; if(width > columnWidthBy && columnWidthBy > 0) { width = columnWidthBy; } @@ -375,8 +376,6 @@ function getTextWidth(column, rows, canvas, columnWidthBy) { width = columnHeaderLen; } } - /* Gracefull */ - width += 8; return width; } 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 ead2943a547..f3f3e577da5 100644 --- a/web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSet.jsx +++ b/web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSet.jsx @@ -675,15 +675,18 @@ export class ResultSetUtils { return retVal; } let copiedRowsObjects = []; - try { - /* If the raw row objects are available, use to them identify null values */ - copiedRowsObjects = JSON.parse(localStorage.getItem('copied-rows')); - } catch {/* Suppress the error */} + if(fromClipboard) { + try { + /* If the raw row objects are available, use to them identify null values */ + copiedRowsObjects = JSON.parse(localStorage.getItem('copied-rows')); + } catch {/* Suppress the error */} + } for(const [recIdx, rec] of result?.entries()??[]) { // Convert 2darray to dict. let rowObj = {}; for(const col of columns) { - let columnVal = rec[col.pos]; + // if column data is undefined and there is not default value then set it to null. + let columnVal = rec[col.pos] ?? (col.has_default_val ? undefined : null); /* If the source is clipboard, then it needs some extra handling */ if(fromClipboard) { columnVal = this.processClipboardVal(columnVal, col, copiedRowsObjects[recIdx]?.[col.key], pasteSerials);