diff --git a/web/package.json b/web/package.json
index 8f625ab77..ff59c9251 100644
--- a/web/package.json
+++ b/web/package.json
@@ -151,7 +151,7 @@
     "react": "^17.0.1",
     "react-aspen": "^1.1.0",
     "react-checkbox-tree": "^1.7.2",
-    "react-data-grid": "^7.0.0-beta.11",
+    "react-data-grid": "^7.0.0-beta.12",
     "react-dom": "^17.0.1",
     "react-draggable": "^4.4.4",
     "react-leaflet": "^3.2.2",
diff --git a/web/pgadmin/static/js/Explain/Analysis.jsx b/web/pgadmin/static/js/Explain/Analysis.jsx
index bf4553dd2..17ed8479f 100644
--- a/web/pgadmin/static/js/Explain/Analysis.jsx
+++ b/web/pgadmin/static/js/Explain/Analysis.jsx
@@ -15,6 +15,7 @@ import FiberManualRecordIcon from '@material-ui/icons/FiberManualRecord';
 import HTMLReactParse from 'html-react-parser';
 import { commonTableStyles } from '../Theme';
 import PropTypes from 'prop-types';
+import gettext from 'sources/gettext';
 
 const useStyles = makeStyles((theme)=>({
   collapsible: {
@@ -172,26 +173,26 @@ export default function Analysis({explainTable}) {
         <th rowSpan="2"><button disabled="">#</button></th>
         <th rowSpan="2"><button disabled="">Node</button></th>
         <th colSpan="2" style={explainTable.show_timings ? {} : {display: 'none'}}>
-          <button disabled="">Timings</button>
+          <button disabled="">{gettext('Timings')}</button>
         </th>
-        <th style={(explainTable.show_rowsx || explainTable.show_rows) ? {} : {display: 'none'}}
+        <th style={(explainTable.show_rowsx || explainTable.show_rows || explainTable.show_plan_rows) ? {} : {display: 'none'}}
           colSpan={(explainTable.show_rowsx) ? '3' : '1'}>
-          <button disabled="">Rows</button>
+          <button disabled="">{gettext('Rows')}</button>
         </th>
         <th style={(explainTable.show_rowsx || explainTable.show_rows) ? {} : {display: 'none'}} rowSpan="2">
-          <button disabled="">Loops</button>
+          <button disabled="">{gettext('Loops')}</button>
         </th>
       </tr>
       <tr>
         <th style={explainTable.show_timings ? {} : {display: 'none'}}>
-          <button disabled="">Exclusive</button>
+          <button disabled="">{gettext('Exclusive')}</button>
         </th>
         <th style={explainTable.show_timings ? {} : {display: 'none'}}>
-          <button disabled="">Inclusive</button>
+          <button disabled="">{gettext('Inclusive')}</button>
         </th>
-        <th style={explainTable.show_rowsx ? {} : {display: 'none'}}><button disabled="">Rows X</button></th>
-        <th style={(explainTable.show_rowsx || explainTable.show_rows) ? {} : {display: 'none'}}><button disabled="">Actual</button></th>
-        <th style={(explainTable.show_rowsx || explainTable.plan_rows) ? {} : {display: 'none'}}><button disabled="">Plan</button></th>
+        <th style={explainTable.show_rowsx ? {} : {display: 'none'}}><button disabled="">{gettext('Rows X')}</button></th>
+        <th style={(explainTable.show_rowsx || explainTable.show_rows) ? {} : {display: 'none'}}><button disabled="">{gettext('Actual')}</button></th>
+        <th style={(explainTable.show_rowsx || explainTable.show_plan_rows) ? {} : {display: 'none'}}><button disabled="">{gettext('Plan')}</button></th>
       </tr>
     </thead>
     <tbody>
diff --git a/web/pgadmin/static/js/Explain/ExplainStatistics.jsx b/web/pgadmin/static/js/Explain/ExplainStatistics.jsx
index c9d1ce670..7a114a42b 100644
--- a/web/pgadmin/static/js/Explain/ExplainStatistics.jsx
+++ b/web/pgadmin/static/js/Explain/ExplainStatistics.jsx
@@ -92,7 +92,7 @@ export default function ExplainStatistics({explainTable}) {
             <tbody>
               {_.sortBy(Object.keys(explainTable.statistics.tables)).map((key, i)=>{
                 let table = explainTable.statistics.tables[key];
-                table.sum_of_times = _.sumBy(table.nodes, 'sum_of_times');
+                table.sum_of_times = _.sumBy(Object.values(table.nodes), 'sum_of_times');
                 return <React.Fragment key={i}>
                   <tr className={classes.tableRow}>
                     <td className={classes.tableName}>{table.name}</td>
diff --git a/web/pgadmin/static/js/Explain/Graphical.jsx b/web/pgadmin/static/js/Explain/Graphical.jsx
index be722f4b6..0ce0c6068 100644
--- a/web/pgadmin/static/js/Explain/Graphical.jsx
+++ b/web/pgadmin/static/js/Explain/Graphical.jsx
@@ -419,7 +419,7 @@ export default function Graphical({planData, ctx}) {
           </Box>
         </Box>} />
         <CardContent className={classes.explainContent}>
-          <table className={clsx(tableStyles.table, tableStyles.borderBottom)}>
+          <table className={clsx(tableStyles.table, tableStyles.borderBottom, tableStyles.wrapTd)}>
             <tbody>
               <NodeDetails download={false} plan={explainPlanDetails} />
             </tbody>
diff --git a/web/pgadmin/static/js/Explain/index.jsx b/web/pgadmin/static/js/Explain/index.jsx
index c5ff0bbe5..9f6854080 100644
--- a/web/pgadmin/static/js/Explain/index.jsx
+++ b/web/pgadmin/static/js/Explain/index.jsx
@@ -237,6 +237,14 @@ function nodeExplainTableData(_planData, _ctx) {
   info.statistics.nodes[node_info] = node;
 }
 
+function parseExplainTableData(plan, ctx) {
+  nodeExplainTableData(plan, ctx);
+
+  plan['Plans']?.map((p)=>{
+    parseExplainTableData(p, ctx);
+  });
+}
+
 function parsePlan(data, ctx) {
   var idx = 1,
     lvl = data.level = data.level || [idx],
@@ -408,7 +416,6 @@ function parsePlan(data, ctx) {
   // Final Width and Height of current node
   data['width'] += maxChildWidth;
   data['Plans'] = plans;
-  nodeExplainTableData(data, ctx);
 
   return data;
 }
@@ -456,6 +463,8 @@ function parsePlanData(data, ctx) {
     if (data && 'Settings' in data) {
       retPlan['Statistics']['Settings'] = data['Settings'];
     }
+
+    parseExplainTableData(retPlan['Plan'], ctx);
   }
   return retPlan;
 }
diff --git a/web/pgadmin/static/js/Theme/index.jsx b/web/pgadmin/static/js/Theme/index.jsx
index 402e82439..2dbcadbe3 100644
--- a/web/pgadmin/static/js/Theme/index.jsx
+++ b/web/pgadmin/static/js/Theme/index.jsx
@@ -27,6 +27,18 @@ basicSettings = createMuiTheme(basicSettings, {
   typography: {
     fontSize: 14,
     htmlFontSize: 14,
+    fontFamily: [
+      'Roboto',
+      '"Helvetica Neue"',
+      '-apple-system',
+      'BlinkMacSystemFont',
+      '"Segoe UI"',
+      'Arial',
+      'sans-serif',
+      '"Apple Color Emoji"',
+      '"Segoe UI Emoji"',
+      '"Segoe UI Symbol"',
+    ].join(','),
   },
   shape: {
     borderRadius: 4,
@@ -281,6 +293,9 @@ function getFinalTheme(baseTheme) {
     overrides: {
       MuiCssBaseline: {
         '@global': {
+          body: {
+            fontFamily: baseTheme.typography.fontFamily,
+          },
           ul: {
             margin: 0,
             padding: 0,
@@ -618,6 +633,11 @@ export const commonTableStyles = makeStyles((theme)=>({
       borderBottom: '1px solid '+theme.otherVars.borderColor,
     },
   },
+  wrapTd: {
+    '& tbody td': {
+      whiteSpace: 'pre-wrap',
+    }
+  },
   noHover: {
     '& tbody > tr': {
       '&:hover': {
diff --git a/web/pgadmin/static/js/components/CodeMirror.jsx b/web/pgadmin/static/js/components/CodeMirror.jsx
index 218efc8a3..c220ccb88 100644
--- a/web/pgadmin/static/js/components/CodeMirror.jsx
+++ b/web/pgadmin/static/js/components/CodeMirror.jsx
@@ -462,16 +462,12 @@ export default function CodeMirror({currEditor, name, value, options, events, re
 
   useEffect(()=>{
     if(editor.current) {
-      if(disabled) {
-        editor.current.setOption('readOnly', true);
-        cmWrapper.current.classList.add(classes.hideCursor);
-      } else if(readonly) {
+      if(readonly || disabled) {
         editor.current.setOption('readOnly', true);
         editor.current.addKeyMap({'Tab': false});
         editor.current.addKeyMap({'Shift-Tab': false});
         cmWrapper.current.classList.add(classes.hideCursor);
       } else {
-        cmWrapper.current.classList.remove('cm_disabled');
         editor.current.setOption('readOnly', false);
         editor.current.removeKeyMap('Tab');
         editor.current.removeKeyMap('Shift-Tab');
diff --git a/web/pgadmin/static/js/components/EmptyPanelMessage.jsx b/web/pgadmin/static/js/components/EmptyPanelMessage.jsx
index 8b96374f5..d8fc8d4f3 100644
--- a/web/pgadmin/static/js/components/EmptyPanelMessage.jsx
+++ b/web/pgadmin/static/js/components/EmptyPanelMessage.jsx
@@ -9,7 +9,9 @@ const useStyles = makeStyles((theme)=>({
     color: theme.palette.text.primary,
     margin: 'auto',
     marginTop: '24px',
-    fontSize: '0.9em',
+    fontSize: '0.8rem',
+    display: 'flex',
+    alignItems: 'center',
   },
 }));
 
@@ -17,8 +19,8 @@ export default function EmptyPanelMessage({text}) {
   const classes = useStyles();
   return (
     <Box className={classes.root}>
-      <InfoRoundedIcon />
-      <span marginLeft='4px'>{text}</span>
+      <InfoRoundedIcon style={{height: '1.2rem'}}/>
+      <span style={{marginLeft: '4px'}}>{text}</span>
     </Box>
   );
 }
diff --git a/web/pgadmin/static/js/helpers/Layout.jsx b/web/pgadmin/static/js/helpers/Layout.jsx
index 5074024cc..c9f8054e3 100644
--- a/web/pgadmin/static/js/helpers/Layout.jsx
+++ b/web/pgadmin/static/js/helpers/Layout.jsx
@@ -81,6 +81,9 @@ const useStyles = makeStyles((theme)=>({
       },
       '& > div': {
         padding: '4px 10px',
+        '&:focus': {
+          outline: '2px solid '+theme.otherVars.activeBorder,
+        }
       },
       '& .drag-initiator': {
         display: 'flex',
@@ -190,6 +193,11 @@ export class LayoutHelper {
     return Boolean(docker.find(panelId));
   }
 
+  static isTabVisible(docker, panelId) {
+    let panelData = docker.find(panelId);
+    return panelData?.parent?.activeId == panelData.id;
+  }
+
   static openTab(docker, panelData, refTabId, direction, forceRerender=false) {
     let panel = docker.find(panelData.id);
     if(panel) {
@@ -203,6 +211,43 @@ export class LayoutHelper {
       docker.dockMove(LayoutHelper.getPanel(panelData), tgtPanel, direction);
     }
   }
+
+  static moveTo(direction) {
+    let dockBar = document.activeElement.closest('.dock')?.querySelector('.dock-bar.drag-initiator');
+    if(dockBar) {
+      let key = {
+        key: 'ArrowRight', keyCode: 39, which: 39, code: 'ArrowRight',
+        metaKey: false, ctrlKey: false, shiftKey: false, altKey: false,
+        bubbles: true,
+      };
+      if(direction == 'right') {
+        key = {
+          ...key,
+          key: 'ArrowRight', keyCode: 39, which: 39, code: 'ArrowRight'
+        };
+      } else if(direction == 'left') {
+        key = {
+          ...key,
+          key: 'ArrowLeft', keyCode: 37, which: 37, code: 'ArrowLeft',
+        };
+      }
+      dockBar.dispatchEvent(new KeyboardEvent('keydown', key));
+    }
+  }
+
+  static switchPanel() {
+    let currDockPanel = document.activeElement.closest('.dock-panel.dock-style-default');
+    let dockLayoutPanels = currDockPanel?.closest('.dock-layout').querySelectorAll('.dock-panel.dock-style-default');
+    if(dockLayoutPanels?.length > 1) {
+      for(let i=0; i<dockLayoutPanels.length; i++) {
+        if(dockLayoutPanels[i] == currDockPanel) {
+          let newPanelIdx = (i+1)%dockLayoutPanels.length;
+          dockLayoutPanels[newPanelIdx]?.querySelector('.dock-tab.dock-tab-active .dock-tab-btn')?.focus();
+          break;
+        }
+      }
+    }
+  }
 }
 
 function saveLayout(layoutObj, layoutId) {
diff --git a/web/pgadmin/static/scss/_slickgrid.overrides.scss b/web/pgadmin/static/scss/_slickgrid.overrides.scss
new file mode 100644
index 000000000..5b530ac36
--- /dev/null
+++ b/web/pgadmin/static/scss/_slickgrid.overrides.scss
@@ -0,0 +1,83 @@
+.slick-row .cell-actions {
+  text-align: left;
+}
+
+.slick-row.selected .cell-selection {
+  background-color: transparent; /* show default selected row background */
+}
+
+.slick-cell span[data-cell-type="row-header-selector"] {
+  display: block;
+  text-align: center;
+}
+
+/*
+  SlickGrid, To fix the issue of width misalignment between Column Header &
+  actual Column in Mozilla Firefox browser
+  Ref: https://github.com/mleibman/SlickGrid/issues/742
+*/
+.slickgrid, .slickgrid *, .slick-header-column {
+  box-sizing: content-box;
+  -moz-box-sizing: content-box;
+  -webkit-box-sizing: content-box;
+  -ms-box-sizing: content-box;
+}
+
+.slick-cell.selected span[data-cell-type="row-header-selector"] {
+  color: $color-primary-fg;
+}
+
+.slick-cell.cell-move-handle {
+  font-weight: bold;
+  text-align: right;
+  border-right: solid  $border-color;
+  background: $color-gray-lighter;
+  cursor: move;
+
+  &:hover {
+    background: $color-gray-light;
+  }
+}
+
+.cell-selection {
+  border-right-color: $border-color;
+  border-right-style: solid;
+  background: $color-gray-lighter;
+  color:  $color-gray;
+  text-align: right;
+  font-size: 10px;
+}
+
+.slick-row.selected .cell-move-handle {
+  background: $color-warning-light;
+}
+
+.slick-row.complete {
+  background-color: $color-success-light;
+  color:  $color-gray-dark;
+}
+
+.slick-row:hover .slick-cell{
+  border-top: $table-hover-border;
+  border-bottom: $table-hover-border;
+  background-color: $table-hover-bg-color;
+}
+
+.slick-row .slick-cell {
+  border-bottom: $panel-border;
+  border-right: $panel-border;
+  z-index: 0;
+}
+
+.slick-cell.active {
+  border: 1px solid transparent;
+  border-right: 1px solid $color-gray-light;
+  border-bottom-color: $color-gray-light;
+}
+
+.ui-widget-content.slick-row {
+  &.even,  &.odd {
+    background: none;
+    background-color: $table-bg;
+  }
+}
diff --git a/web/pgadmin/static/scss/pgadmin.scss b/web/pgadmin/static/scss/pgadmin.scss
index 8015668b7..78e3eecd0 100644
--- a/web/pgadmin/static/scss/pgadmin.scss
+++ b/web/pgadmin/static/scss/pgadmin.scss
@@ -35,5 +35,6 @@ $theme-colors: (
 @import 'jsoneditor.overrides';
 @import 'pgadmin4-tree.overrides';
 @import 'pgadmin4-tree/src/css/styles';
+@import 'slickgrid.overrides';
 @import 'rc-dock/dist/rc-dock.css';
 @import '@szhsin/react-menu/dist/index.css';
diff --git a/web/pgadmin/tools/search_objects/static/scss/_search_objects.scss b/web/pgadmin/tools/search_objects/static/scss/_search_objects.scss
index 86f3eb8a7..fc989a081 100644
--- a/web/pgadmin/tools/search_objects/static/scss/_search_objects.scss
+++ b/web/pgadmin/tools/search_objects/static/scss/_search_objects.scss
@@ -60,6 +60,13 @@
                 .slick-header-sortable {
                     cursor: pointer !important;
 
+                    .slick-sort-indicator {
+                      width: 0px;
+                      height: 0px;
+                      position: relative;
+                      top: -2px;
+                    }
+
                     .slick-sort-indicator-asc {
                         background: none;
                         border-top: none;
diff --git a/web/pgadmin/tools/sqleditor/static/js/SQLEditorModule.js b/web/pgadmin/tools/sqleditor/static/js/SQLEditorModule.js
index 7a2501f63..298148a1d 100644
--- a/web/pgadmin/tools/sqleditor/static/js/SQLEditorModule.js
+++ b/web/pgadmin/tools/sqleditor/static/js/SQLEditorModule.js
@@ -348,7 +348,7 @@ export default class SQLEditor {
         <input name="close_url" value="${closeUrl}" hidden />`;
 
 
-    if(sURL){
+    if(sURL && typeof(sURL) === 'string'){
       queryToolForm +=`<input name="query_url" value="${sURL}" hidden />`;
     }
     if(sql_filter) {
diff --git a/web/pgadmin/tools/sqleditor/static/js/components/QueryToolComponent.jsx b/web/pgadmin/tools/sqleditor/static/js/components/QueryToolComponent.jsx
index a2b000bed..5326201e0 100644
--- a/web/pgadmin/tools/sqleditor/static/js/components/QueryToolComponent.jsx
+++ b/web/pgadmin/tools/sqleditor/static/js/components/QueryToolComponent.jsx
@@ -487,7 +487,7 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
     const onClose = ()=>LayoutHelper.close(docker.current, 'new-conn');
     LayoutHelper.openDialog(docker.current, {
       id: 'new-conn',
-      title: gettext('Add new connection'),
+      title: gettext('Add New Connection'),
       content: <NewConnectionDialog onSave={(_isNew, data)=>{
         let connectionData = {
           sgid: 0,
diff --git a/web/pgadmin/tools/sqleditor/static/js/components/QueryToolDataGrid/Editors.jsx b/web/pgadmin/tools/sqleditor/static/js/components/QueryToolDataGrid/Editors.jsx
index 48739c644..d7815170b 100644
--- a/web/pgadmin/tools/sqleditor/static/js/components/QueryToolDataGrid/Editors.jsx
+++ b/web/pgadmin/tools/sqleditor/static/js/components/QueryToolDataGrid/Editors.jsx
@@ -173,6 +173,10 @@ export function TextEditor({row, column, onRowChange, onClose}) {
     if(column.is_array && !isValidArray(localVal)) {
       Notifier.error(gettext('Arrays must start with "{" and end with "}"'));
     } else {
+      if(value == localVal) {
+        onClose(false);
+        return;
+      }
       let columnVal = textColumnFinalVal(localVal, column);
       onRowChange({ ...row, [column.key]: columnVal}, true);
       onClose();
@@ -320,6 +324,10 @@ export function JsonTextEditor({row, column, onRowChange, onClose}) {
     setLocalVal(newVal);
   }, []);
   const onOK = ()=>{
+    if(value == localVal) {
+      onClose(false);
+      return;
+    }
     onRowChange({ ...row, [column.key]: localVal}, true);
     onClose();
   };
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 17b4b7bf9..f5c5b1c0d 100644
--- a/web/pgadmin/tools/sqleditor/static/js/components/QueryToolDataGrid/index.jsx
+++ b/web/pgadmin/tools/sqleditor/static/js/components/QueryToolDataGrid/index.jsx
@@ -105,7 +105,7 @@ function CustomRow(props) {
   const rowInfoValue = {
     rowIdx: props.rowIdx,
     getCellElement: (colIdx)=>{
-      return rowRef.current.querySelector(`.rdg-cell[aria-colindex="${colIdx+1}"]`);
+      return rowRef.current?.querySelector(`.rdg-cell[aria-colindex="${colIdx+1}"]`);
     }
   };
   return (
diff --git a/web/pgadmin/tools/sqleditor/static/js/components/dialogs/NewConnectionDialog.jsx b/web/pgadmin/tools/sqleditor/static/js/components/dialogs/NewConnectionDialog.jsx
index f0763d543..bfcf872ef 100644
--- a/web/pgadmin/tools/sqleditor/static/js/components/dialogs/NewConnectionDialog.jsx
+++ b/web/pgadmin/tools/sqleditor/static/js/components/dialogs/NewConnectionDialog.jsx
@@ -67,7 +67,8 @@ class NewConnectionSchema extends BaseUISchema {
               return;
             }
             /* initial selection */
-            _.find(v, (o)=>o.value==obj.params.sid).selected = true;
+            let foundServer = _.find(v, (o)=>o.value==obj.params.sid);
+            foundServer && (foundServer.selected = true);
             groupedOptions.push({
               label: k,
               options: v,
diff --git a/web/pgadmin/tools/sqleditor/static/js/components/sections/ConnectionBar.jsx b/web/pgadmin/tools/sqleditor/static/js/components/sections/ConnectionBar.jsx
index cf9db036a..158431cdc 100644
--- a/web/pgadmin/tools/sqleditor/static/js/components/sections/ConnectionBar.jsx
+++ b/web/pgadmin/tools/sqleditor/static/js/components/sections/ConnectionBar.jsx
@@ -129,7 +129,7 @@ export function ConnectionBar({connected, connecting, connectionStatus, connecti
               onClick={onConnItemClick}>{conn.conn_title}</PgMenuItem>
           );
         })}
-        <PgMenuItem onClick={onNewConnClick}>{`< ${gettext('New connection...')} >`}</PgMenuItem>
+        <PgMenuItem onClick={onNewConnClick}>{`< ${gettext('New Connection...')} >`}</PgMenuItem>
       </PgMenu>
     </>
   );
diff --git a/web/pgadmin/tools/sqleditor/static/js/components/sections/GeometryViewer.jsx b/web/pgadmin/tools/sqleditor/static/js/components/sections/GeometryViewer.jsx
index 97006107e..b49d8762b 100644
--- a/web/pgadmin/tools/sqleditor/static/js/components/sections/GeometryViewer.jsx
+++ b/web/pgadmin/tools/sqleditor/static/js/components/sections/GeometryViewer.jsx
@@ -19,6 +19,10 @@ import gettext from 'sources/gettext';
 import Theme from 'sources/Theme';
 import clsx from 'clsx';
 import PropTypes from 'prop-types';
+import { Box } from '@material-ui/core';
+import { LayoutHelper } from '../../../../../../static/js/helpers/Layout';
+import { PANELS } from '../QueryToolConstants';
+import { QueryToolContext } from '../QueryToolComponent';
 
 const useStyles = makeStyles((theme)=>({
   mapContainer: {
@@ -233,7 +237,7 @@ function GeoJsonLayer({data}) {
     } else {
       mapObj.setView(bounds.getCenter(), mapObj.getZoom());
     }
-  });
+  }, [data]);
 
   return (
     <GeoJSON
@@ -278,6 +282,7 @@ GeoJsonLayer.propTypes = {
 function TheMap({data}) {
   const mapObj = useMap();
   const infoControl = useRef(null);
+  const resetLayersKey = useRef(0);
   useEffect(()=>{
     infoControl.current = Leaflet.control({position: 'topright'});
     infoControl.current.onAdd = function () {
@@ -288,70 +293,71 @@ function TheMap({data}) {
     if(data.infoList.length > 0) {
       infoControl.current.addTo(mapObj);
     }
+    resetLayersKey.current++;
     return ()=>{infoControl.current && infoControl.current.remove();};
   }, [data]);
   return (
     <>
       {data.selectedSRID === 4326 &&
-    <LayersControl position="topright">
-      <LayersControl.BaseLayer checked name={gettext('Empty')}>
-        <TileLayer
-          url=""
-        />
-      </LayersControl.BaseLayer>
-      <LayersControl.BaseLayer checked name={gettext('Street')}>
-        <TileLayer
-          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
-          maxZoom={19}
-          attribution='&copy; <a href="http://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>'
-        />
-      </LayersControl.BaseLayer>
-      <LayersControl.BaseLayer name={gettext('Topography')}>
-        <TileLayer
-          url="https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png"
-          maxZoom={17}
-          attribution={
-            '&copy; <a href="http://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>,'
-            + ' &copy; <a href="http://viewfinderpanoramas.org" target="_blank">SRTM</a>,'
-            + ' &copy; <a href="https://opentopomap.org" target="_blank">OpenTopoMap</a>'
-          }
-        />
-      </LayersControl.BaseLayer>
-      <LayersControl.BaseLayer name={gettext('Gray Style')}>
-        <TileLayer
-          url="https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}{r}.png"
-          maxZoom={19}
-          attribution={
-            '&copy; <a href="http://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>,'
-            + ' &copy; <a href="http://cartodb.com/attributions" target="_blank">CartoDB</a>'
-          }
-          subdomains='abcd'
-        />
-      </LayersControl.BaseLayer>
-      <LayersControl.BaseLayer name={gettext('Light Color')}>
-        <TileLayer
-          url="https://cartodb-basemaps-{s}.global.ssl.fastly.net/rastertiles/voyager/{z}/{x}/{y}{r}.pn"
-          maxZoom={19}
-          attribution={
-            '&copy; <a href="http://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>,'
-            + ' &copy; <a href="http://cartodb.com/attributions" target="_blank">CartoDB</a>'
-          }
-          subdomains='abcd'
-        />
-      </LayersControl.BaseLayer>
-      <LayersControl.BaseLayer name={gettext('Dark Matter')}>
-        <TileLayer
-          url="https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}{r}.png"
-          maxZoom={19}
-          attribution={
-            '&copy; <a href="http://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>,'
-            + ' &copy; <a href="http://cartodb.com/attributions" target="_blank">CartoDB</a>'
-          }
-          subdomains='abcd'
-        />
-      </LayersControl.BaseLayer>
-    </LayersControl>}
-      <GeoJsonLayer key={data.geoJSONs.length} data={data}/>
+      <LayersControl position="topright">
+        <LayersControl.BaseLayer checked name={gettext('Empty')}>
+          <TileLayer
+            url=""
+          />
+        </LayersControl.BaseLayer>
+        <LayersControl.BaseLayer checked name={gettext('Street')}>
+          <TileLayer
+            url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
+            maxZoom={19}
+            attribution='&copy; <a href="http://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>'
+          />
+        </LayersControl.BaseLayer>
+        <LayersControl.BaseLayer name={gettext('Topography')}>
+          <TileLayer
+            url="https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png"
+            maxZoom={17}
+            attribution={
+              '&copy; <a href="http://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>,'
+              + ' &copy; <a href="http://viewfinderpanoramas.org" target="_blank">SRTM</a>,'
+              + ' &copy; <a href="https://opentopomap.org" target="_blank">OpenTopoMap</a>'
+            }
+          />
+        </LayersControl.BaseLayer>
+        <LayersControl.BaseLayer name={gettext('Gray Style')}>
+          <TileLayer
+            url="https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}{r}.png"
+            maxZoom={19}
+            attribution={
+              '&copy; <a href="http://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>,'
+              + ' &copy; <a href="http://cartodb.com/attributions" target="_blank">CartoDB</a>'
+            }
+            subdomains='abcd'
+          />
+        </LayersControl.BaseLayer>
+        <LayersControl.BaseLayer name={gettext('Light Color')}>
+          <TileLayer
+            url="https://cartodb-basemaps-{s}.global.ssl.fastly.net/rastertiles/voyager/{z}/{x}/{y}{r}.pn"
+            maxZoom={19}
+            attribution={
+              '&copy; <a href="http://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>,'
+              + ' &copy; <a href="http://cartodb.com/attributions" target="_blank">CartoDB</a>'
+            }
+            subdomains='abcd'
+          />
+        </LayersControl.BaseLayer>
+        <LayersControl.BaseLayer name={gettext('Dark Matter')}>
+          <TileLayer
+            url="https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}{r}.png"
+            maxZoom={19}
+            attribution={
+              '&copy; <a href="http://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>,'
+              + ' &copy; <a href="http://cartodb.com/attributions" target="_blank">CartoDB</a>'
+            }
+            subdomains='abcd'
+          />
+        </LayersControl.BaseLayer>
+      </LayersControl>}
+      <GeoJsonLayer key={resetLayersKey.current} data={data} />
     </>
   );
 }
@@ -367,18 +373,40 @@ TheMap.propTypes = {
 
 export function GeometryViewer({rows, columns, column}) {
   const classes = useStyles();
+  const mapRef = React.useRef();
+  const contentRef = React.useRef();
   const data = parseData(rows, columns, column);
+  const queryToolCtx = React.useContext(QueryToolContext);
   const crs = data.selectedSRID === 4326 ? CRS.EPSG3857 : CRS.Simple;
+
+  useEffect(()=>{
+    let timeoutId;
+    const contentResizeObserver = new ResizeObserver(()=>{
+      clearTimeout(timeoutId);
+      if(LayoutHelper.isTabVisible(queryToolCtx.docker, PANELS.GEOMETRY)) {
+        timeoutId = setTimeout(function () {
+          mapRef.current?.invalidateSize();
+        }, 100);
+      }
+    });
+    contentResizeObserver.observe(contentRef.current);
+  }, []);
+
   return (
-    <MapContainer
-      crs={crs}
-      zoom={2} center={[20, 100]}
-      preferCanvas={true}
-      scrollWheelZoom={false}
-      className={classes.mapContainer}
-    >
-      <TheMap data={data} />
-    </MapContainer>
+    <Box ref={contentRef} width="100%" height="100%">
+      <MapContainer
+        crs={crs}
+        zoom={2} center={[20, 100]}
+        preferCanvas={true}
+        scrollWheelZoom={false}
+        className={classes.mapContainer}
+        whenCreated={(map)=>{
+          mapRef.current = map;
+        }}
+      >
+        <TheMap data={data}/>
+      </MapContainer>
+    </Box>
   );
 }
 
diff --git a/web/pgadmin/tools/sqleditor/static/js/components/sections/MainToolBar.jsx b/web/pgadmin/tools/sqleditor/static/js/components/sections/MainToolBar.jsx
index fe0f60a5e..e2d6f9bdd 100644
--- a/web/pgadmin/tools/sqleditor/static/js/components/sections/MainToolBar.jsx
+++ b/web/pgadmin/tools/sqleditor/static/js/components/sections/MainToolBar.jsx
@@ -34,6 +34,7 @@ import PropTypes from 'prop-types';
 import CustomPropTypes from '../../../../../../static/js/custom_prop_types';
 import ConfirmTransactionContent from '../dialogs/ConfirmTransactionContent';
 import { isMac } from '../../../../../../static/js/keyboard_shortcuts';
+import { LayoutHelper } from '../../../../../../static/js/helpers/Layout';
 
 const useStyles = makeStyles((theme)=>({
   root: {
@@ -435,6 +436,34 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros}) {
     containerRef
   );
 
+  /* Panel shortcuts */
+  useKeyboardShortcuts([
+    {
+      shortcut: queryToolPref.move_previous,
+      options: {
+        callback: ()=>{
+          LayoutHelper.moveTo('left');
+        }
+      }
+    },
+    {
+      shortcut: queryToolPref.move_next,
+      options: {
+        callback: ()=>{
+          LayoutHelper.moveTo('right');
+        }
+      }
+    },
+    {
+      shortcut: queryToolPref.switch_panel,
+      options: {
+        callback: ()=>{
+          LayoutHelper.switchPanel(queryToolCtx.docker);
+        }
+      }
+    },
+  ], containerRef);
+
   return (
     <>
       <Box className={classes.root}>
diff --git a/web/pgadmin/tools/sqleditor/static/js/components/sections/Query.jsx b/web/pgadmin/tools/sqleditor/static/js/components/sections/Query.jsx
index e37f91a8a..13a81c17d 100644
--- a/web/pgadmin/tools/sqleditor/static/js/components/sections/Query.jsx
+++ b/web/pgadmin/tools/sqleditor/static/js/components/sections/Query.jsx
@@ -311,7 +311,7 @@ export default function Query() {
         key.metaKey = true;
         key.ctrlKey = false;
         key.shiftKey = false;
-        key.altKey = true;
+        key.altKey = replace;
       }
       editor.current?.triggerOnKeyDown(
         new KeyboardEvent('keydown', key)
diff --git a/web/pgadmin/tools/sqleditor/static/js/components/sections/QueryHistory.jsx b/web/pgadmin/tools/sqleditor/static/js/components/sections/QueryHistory.jsx
index b3c4dc18a..9319bbb3a 100644
--- a/web/pgadmin/tools/sqleditor/static/js/components/sections/QueryHistory.jsx
+++ b/web/pgadmin/tools/sqleditor/static/js/components/sections/QueryHistory.jsx
@@ -373,7 +373,7 @@ export function QueryHistory() {
 
   React.useEffect(async ()=>{
     layoutEvenBus.registerListener(LAYOUT_EVENTS.ACTIVE, (currentTabId)=>{
-      currentTabId == PANELS.HISTORY && listRef.current.focus();
+      currentTabId == PANELS.HISTORY && listRef.current?.focus();
     });
 
     setLoaderText(gettext('Fetching history...'));
@@ -399,7 +399,7 @@ export function QueryHistory() {
       refresh({});
     };
 
-    listRef.current.focus();
+    listRef.current?.focus();
     eventBus.registerListener(QUERY_TOOL_EVENTS.PUSH_HISTORY, pushHistory);
     return ()=>eventBus.deregisterListener(QUERY_TOOL_EVENTS.PUSH_HISTORY, pushHistory);
   }, []);
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 553f2b647..6bdb45624 100644
--- a/web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSet.jsx
+++ b/web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSet.jsx
@@ -1116,8 +1116,8 @@ export function ResultSet() {
   }, [selectedRows, selectedColumns, queryData, dataChangeStore, selectedCell.current]);
 
   useEffect(()=>{
-    const triggerAddRows = (_rows)=>{
-      let newRows = rsu.current.processRows(_rows, columns, true);
+    const triggerAddRows = (_rows, fromClipboard)=>{
+      let newRows = rsu.current.processRows(_rows, columns, fromClipboard);
       setRows((prev)=>[...newRows, ...prev]);
       let add = {};
       newRows.forEach((row)=>{
@@ -1191,7 +1191,7 @@ export function ResultSet() {
 
   const rowKeyGetter = React.useCallback((row)=>row[rsu.current.clientPK]);
   return (
-    <Box className={classes.root} ref={containerRef}>
+    <Box className={classes.root} ref={containerRef} tabIndex="0">
       <Loader message={loaderText} />
       <Loader message={isLoadingMore ? gettext('Loading more rows...') : null} style={{top: 'unset', right: 'unset', padding: '0.5rem 1rem'}}/>
       {(columns.length == 0 && rows.length == 0) &&
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 3fd5cd034..c1bd5463b 100644
--- a/web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSetToolbar.jsx
+++ b/web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSetToolbar.jsx
@@ -70,7 +70,7 @@ export function ResultSetToolbar({containerRef, canEdit}) {
       field_separator: queryToolPref.results_grid_field_separator,
     });
     let copiedRows = copyUtils.getCopiedRows();
-    eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_ADD_ROWS, copiedRows);
+    eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_ADD_ROWS, copiedRows, true);
   }, [queryToolPref]);
   const copyData = ()=>{
     eventBus.fireEvent(QUERY_TOOL_EVENTS.COPY_DATA, checkedMenuItems['copy_with_headers']);
diff --git a/web/yarn.lock b/web/yarn.lock
index ff4557e75..c87f3b0e1 100644
--- a/web/yarn.lock
+++ b/web/yarn.lock
@@ -8880,10 +8880,10 @@ react-checkbox-tree@^1.7.2:
     nanoid "^3.0.0"
     prop-types "^15.5.8"
 
-react-data-grid@^7.0.0-beta.11:
-  version "7.0.0-beta.11"
-  resolved "https://registry.yarnpkg.com/react-data-grid/-/react-data-grid-7.0.0-beta.11.tgz#16e87f87ac2d1f2c33816837f1be3c4210f1e4b2"
-  integrity sha512-IjJf3GZ7HxH7uSoDaQhKXV9+L8I64xRKgLVQNCblSgvEY20mg2XlMmEjiV9KqROTUM2MqI+IlEpeBLCZRB3mEw==
+react-data-grid@^7.0.0-beta.12:
+  version "7.0.0-beta.12"
+  resolved "https://registry.yarnpkg.com/react-data-grid/-/react-data-grid-7.0.0-beta.12.tgz#a6310a83a7ad4913a595a8b2a667e4951a95dc58"
+  integrity sha512-cgKE4fl/glKllpfY444H1ZF4mNDUfIU7kyrSYVUy8W1npTvGk9CL++ASs1pTSSi2Eg2Sx7vqnC1gEx6C92Kqjw==
   dependencies:
     clsx "^1.1.1"
 
