diff --git a/web/pgadmin/browser/static/js/toolbar.js b/web/pgadmin/browser/static/js/toolbar.js
index fc915026e..af3ad7d13 100644
--- a/web/pgadmin/browser/static/js/toolbar.js
+++ b/web/pgadmin/browser/static/js/toolbar.js
@@ -116,7 +116,7 @@ export function initializeToolbar(panel, wcDocker) {
     else if ('name' in data && data.name === gettext('View Data'))
       pgAdmin.Tools.SQLEditor.showViewData({mnuid: 3}, pgAdmin.Browser.tree.selected());
     else if ('name' in data && data.name === gettext('Filtered Rows'))
-      pgAdmin.Tools.SQLEditor.show_filtered_row({mnuid: 4}, pgAdmin.Browser.tree.selected());
+      pgAdmin.Tools.SQLEditor.showFilteredRow({mnuid: 4}, pgAdmin.Browser.tree.selected());
     else if ('name' in data && data.name === gettext('Search objects'))
       pgAdmin.SearchObjects.show_search_objects('', pgAdmin.Browser.tree.selected());
     else if ('name' in data && data.name === gettext('PSQL Tool')){
diff --git a/web/pgadmin/static/js/Explain/Analysis.jsx b/web/pgadmin/static/js/Explain/Analysis.jsx
index fa822b156..bf4553dd2 100644
--- a/web/pgadmin/static/js/Explain/Analysis.jsx
+++ b/web/pgadmin/static/js/Explain/Analysis.jsx
@@ -24,16 +24,19 @@ const useStyles = makeStyles((theme)=>({
     borderBottom: '2px dashed '+theme.palette.primary.main,
   },
   level2: {
-    backgroundColor: '#fff',
-    color: '#000',
+    backgroundColor: theme.otherVars.explain.sev2.bg,
+    color: theme.otherVars.explain.sev2.color,
   },
   level3: {
-    backgroundColor: '#fff',
-    color: '#000',
+    backgroundColor: theme.otherVars.explain.sev3.bg,
+    color: theme.otherVars.explain.sev3.color,
   },
   level4: {
-    backgroundColor: '#fff',
-    color: '#000',
+    backgroundColor: theme.otherVars.explain.sev4.bg,
+    color: theme.otherVars.explain.sev4.color,
+  },
+  textRight: {
+    textAlign: 'right',
   },
 }));
 
@@ -43,15 +46,6 @@ function getRowClassname(data, collapseParent) {
   if(data['Plans']?.length > 0) {
     className.push(classes.collapsible);
   }
-  if(!_.isEmpty(data['exclusive_flag'])) {
-    className.push(classes['level'+data['exclusive_flag']]);
-  }
-  if(!_.isEmpty(data['inclusive_flag'])) {
-    className.push(classes['level'+data['inclusive_flag']]);
-  }
-  if(!_.isEmpty(data['rowsx_flag'])) {
-    className.push(classes['level'+data['rowsx_flag']]);
-  }
   if(collapseParent) {
     className.push(classes.collapseParent);
   }
@@ -61,10 +55,10 @@ function getRowClassname(data, collapseParent) {
 function NodeText({displayText, extraInfo}) {
   return (
     <>
-      <ArrowRightAltIcon fontSize="small" /> {displayText}
-      {extraInfo?.length > 0 && <ul>
+      <ArrowRightAltIcon fontSize="small" style={{marginLeft: '-24px'}} /> {displayText}
+      {extraInfo?.length > 0 && <ul style={{fontSize: '13px'}}>
         {extraInfo.map((item, i)=>{
-          return <li key={i}>{HTMLReactParse(item)}</li>;
+          return <li key={i} style={{opacity: '0.8'}}>{HTMLReactParse(item)}</li>;
         })}
       </ul>}
     </>);
@@ -76,6 +70,7 @@ NodeText.propTypes = {
 
 function ExplainRow({row, show, activeExId, setActiveExId, collapsedExId, toggleCollapseExId}) {
   let data = row['data'];
+  const classes = useStyles();
   const exId = `pga_ex_${data['level'].join('_')}`;
   const parentExId = `pga_ex_${data['parent_node']}`;
   const collapsed = collapsedExId.findIndex((v)=>parentExId.startsWith(v)) > -1;
@@ -94,29 +89,28 @@ function ExplainRow({row, show, activeExId, setActiveExId, collapsedExId, toggle
       <td>
         <FiberManualRecordIcon fontSize="small" style={{visibility: activeExId==parentExId ? 'visible' : 'hidden'}} />
       </td>
-      <td>{data['_serial']}.</td>
+      <td className={classes.textRight}>{data['_serial']}.</td>
       <td style={{paddingLeft: data['level'].length*30+'px'}} title={row['tooltip_text']}>
         <NodeText displayText={row['display_text']} extraInfo={row['node_extra_info']} />
       </td>
-      <td style={show.show_timings ? {} : {display: 'none'}}>
+      <td className={clsx(classes.textRight, classes['level'+data['exclusive_flag']])} style={show.show_timings ? {} : {display: 'none'}}>
         {data['exclusive'] && (data['exclusive']+' ms')}
       </td>
-      <td style={show.show_timings ? {} : {display: 'none'}}>
+      <td className={clsx(classes.textRight, classes['level'+data['inclusive_flag']])} style={show.show_timings ? {} : {display: 'none'}}>
         {data['inclusive'] && (data['inclusive']+' ms')}
       </td>
-      <td style={{display: 'none'}}>{!_.isUndefined(data['rowsx_flag'])
-        && (data['rowsx_direction'] == 'positive' ? '&uarr;' : '&darr;')
-      }</td>
-      <td style={show.show_rowsx ? {} : {display: 'none'}}>
-        {data['rowsx']}
+      <td className={clsx(classes.textRight, classes['level'+data['rowsx_flag']])} style={show.show_rowsx ? {} : {display: 'none'}}>
+        {!_.isUndefined(data['rowsx_flag'])
+          && (data['rowsx_direction'] == 'positive' ? <>&uarr;</> : <>&darr;</>)
+        }&nbsp;{data['rowsx']}
       </td>
-      <td style={(show.show_rowsx || show.show_rows) ? {} : {display: 'none'}}>
+      <td className={classes.textRight} style={(show.show_rowsx || show.show_rows) ? {} : {display: 'none'}}>
         {data['Actual Rows']}
       </td>
-      <td style={(show.show_rowsx || show.show_plan_rows) ? {} : {display: 'none'}}>
+      <td className={classes.textRight} style={(show.show_rowsx || show.show_plan_rows) ? {} : {display: 'none'}}>
         {data['Plan Rows']}
       </td>
-      <td style={(show.show_rowsx || show.show_rows) ? {} : {display: 'none'}}>
+      <td className={classes.textRight} style={(show.show_rowsx || show.show_rows) ? {} : {display: 'none'}}>
         {data['Actual Loops']}
       </td>
     </tr>
@@ -130,7 +124,9 @@ ExplainRow.propTypes = {
       _serial: PropTypes.number,
       parent_node: PropTypes.number,
       exclusive: PropTypes.number,
+      exclusive_flag: PropTypes.string,
       inclusive: PropTypes.number,
+      inclusive_flag: PropTypes.string,
       rowsx_direction: PropTypes.string,
       rowsx: PropTypes.number,
       rowsx_flag: PropTypes.number,
@@ -178,7 +174,8 @@ export default function Analysis({explainTable}) {
         <th colSpan="2" style={explainTable.show_timings ? {} : {display: 'none'}}>
           <button disabled="">Timings</button>
         </th>
-        <th style={(explainTable.show_rowsx || explainTable.show_rows) ? {} : {display: 'none'}} colSpan="3">
+        <th style={(explainTable.show_rowsx || explainTable.show_rows) ? {} : {display: 'none'}}
+          colSpan={(explainTable.show_rowsx) ? '3' : '1'}>
           <button disabled="">Rows</button>
         </th>
         <th style={(explainTable.show_rowsx || explainTable.show_rows) ? {} : {display: 'none'}} rowSpan="2">
diff --git a/web/pgadmin/static/js/Explain/Graphical.jsx b/web/pgadmin/static/js/Explain/Graphical.jsx
index 2c7ba2101..be722f4b6 100644
--- a/web/pgadmin/static/js/Explain/Graphical.jsx
+++ b/web/pgadmin/static/js/Explain/Graphical.jsx
@@ -250,6 +250,7 @@ function PlanContent({plan, pXpos, pYpos, ...props}) {
           strokeWidth={1.2}
           fill="gray"
           fillOpacity={0.2}
+          pointerEvents="none"
         />
         <tspan x={currentXpos + pWIDTH - (plan.width / 2) - xMargin}
           y={currentYpos + pHEIGHT - (plan.height / 2) - yMargin}
diff --git a/web/pgadmin/static/js/Explain/index.jsx b/web/pgadmin/static/js/Explain/index.jsx
index f5845a9e8..c5ff0bbe5 100644
--- a/web/pgadmin/static/js/Explain/index.jsx
+++ b/web/pgadmin/static/js/Explain/index.jsx
@@ -23,7 +23,7 @@ const useStyles = makeStyles((theme)=>({
   tabPanel: {
     padding: 0,
     backgroundColor: theme.palette.background.default,
-  }
+  },
 }));
 
 // Some predefined constants used to calculate image location and its border
@@ -261,7 +261,11 @@ function parsePlan(data, ctx) {
     totalCost = data['Total Cost'];
   if (startCost != undefined && totalCost != undefined) {
     arrowSize = Math.round(Math.log((startCost + totalCost) / 2 + startCost));
-    arrowSize = arrowSize < 1 ? 1 : arrowSize > 10 ? 10 : arrowSize;
+    if (arrowSize < 1) {
+      arrowSize = 1;
+    } else if (arrowSize > 10) {
+      arrowSize = 10;
+    }
   }
   data['arr_id'] = _.uniqueId('arr');
   ctx.arrows[data['arr_id']] = arrowSize;
@@ -292,15 +296,21 @@ function parsePlan(data, ctx) {
 
   if ('Actual Total Time' in data && 'Actual Loops' in data) {
     data['inclusive'] = Math.ceil10(
-      data['Actual Total Time'] * data['Actual Loops'], -3
+      data['Actual Total Time'], -3
     );
     data['exclusive'] = data['inclusive'];
     data['inclusive_factor'] =  data['inclusive'] / (
       data['total_time'] || data['Actual Total Time']
     );
-    data['inclusive_flag'] = data['inclusive_factor'] <= 0.1 ? '1' :
-      data['inclusive_factor'] < 0.5 ? '2' :
-        data['inclusive_factor'] <= 0.9 ? '3' : '4';
+    if (data['inclusive_factor'] <= 0.1) {
+      data['inclusive_flag'] = '1';
+    } else if (data['inclusive_factor'] < 0.5) {
+      data['inclusive_flag'] = '2';
+    } else if (data['inclusive_factor'] <= 0.9) {
+      data['inclusive_flag'] = '3';
+    } else {
+      data['inclusive_flag'] = '4';
+    }
   }
 
   if ('Actual Rows' in data && 'Plan Rows' in data) {
@@ -316,10 +326,20 @@ function parsePlan(data, ctx) {
       );
       data['rowsx_direction'] = 'positive';
     }
-    data['rowsx_flag'] = data['rowsx'] <= 10 ? '1' : (
-      data['rowsx'] <= 100 ? '2' : (data['rowsx'] <= 1000 ? '3' : '4')
-    );
-    data['rowsx'] = Math.ceil10(data['rowsx'], -2);
+    if (data['rowsx'] <= 10) {
+      data['rowsx_flag'] = '1';
+    } else if (data['rowsx'] <= 100 ) {
+      data['rowsx_flag'] = '2';
+    } else if (data['rowsx'] <= 1000 ) {
+      data['rowsx_flag'] = '3';
+    } else {
+      data['rowsx_flag'] = '4';
+    }
+    if('loops' in data) {
+      data['rowsx'] = Math.ceil10(data['rowsx'] / data['loops'] || 1, -2);
+    } else {
+      data['rowsx'] = Math.ceil10(data['rowsx'], -2);
+    }
   }
 
   // Start calculating xpos, ypos, width and height for child plans if any
@@ -337,6 +357,7 @@ function parsePlan(data, ctx) {
         ypos: ypos,
         total_time: data['total_time'] || data['Actual Total Time'],
         parent_node: lvl.join('_'),
+        loops: data['Actual Loops']
       }, ctx);
 
       if (maxChildWidth < plan.width) {
@@ -344,7 +365,7 @@ function parsePlan(data, ctx) {
       }
 
       if ('exclusive' in data) {
-        if (plan.inclusive) {
+        if (plan.inclusive < data['exclusive']) {
           data['exclusive'] -= plan.inclusive;
         }
       }
@@ -361,6 +382,11 @@ function parsePlan(data, ctx) {
       plans.push(plan);
       idx++;
     });
+  } else{
+    if('loops' in data && 'exclusive' in data) {
+      data['inclusive'] = Math.ceil10(data['Actual Total Time'] / data['loops'] || 1, -3);
+      data['exclusive'] = data['inclusive'];
+    }
   }
 
   if ('exclusive' in data) {
@@ -368,9 +394,15 @@ function parsePlan(data, ctx) {
     data['exclusive_factor'] = (
       data['exclusive'] / (data['total_time'] || data['Actual Total Time'])
     );
-    data['exclusive_flag'] = data['exclusive_factor'] <= 0.1 ? '1' :
-      data['exclusive_factor'] < 0.5 ? '2' :
-        data['exclusive_factor'] <= 0.9 ? '3' : '4';
+    if (data['exclusive_factor'] <= 0.1) {
+      data['exclusive_flag'] = '1';
+    } else if (data['exclusive_factor'] < 0.5) {
+      data['exclusive_flag'] = '2';
+    } else if (data['exclusive_factor'] <= 0.9) {
+      data['exclusive_flag'] = '3';
+    } else {
+      data['exclusive_flag'] = '4';
+    }
   }
 
   // Final Width and Height of current node
@@ -389,6 +421,7 @@ function parsePlanData(data, ctx) {
         ...data['Plan'],
         xpos: 0,
         ypos: 0,
+        loops: 1,
       }, ctx);
       retPlan['Plan'] = plan;
       retPlan['xpos'] = 0;
@@ -431,20 +464,23 @@ export default function Explain({plans=[]}) {
   const classes = useStyles();
   const [tabValue, setTabValue] = React.useState(0);
 
-  let ctx = React.useRef({
-    totalNodes: 0,
-    totalDownloadedNodes: 0,
-    isDownloaded: 0,
-    explainTable: {
-      rows: [],
-      statistics: {
-        tables: {},
-        nodes: {},
+  let ctx = React.useRef({});
+  let planData = React.useMemo(()=>{
+    ctx.current = {
+      totalNodes: 0,
+      totalDownloadedNodes: 0,
+      isDownloaded: 0,
+      explainTable: {
+        rows: [],
+        statistics: {
+          tables: {},
+          nodes: {},
+        },
       },
-    },
-    arrows: {},
-  });
-  let planData = React.useMemo(()=>(plans && parsePlanData(plans[0], ctx.current)), [plans]);
+      arrows: {},
+    };
+    return plans && parsePlanData(plans[0], ctx.current);
+  }, [plans]);
 
   if(_.isEmpty(plans)) {
     return <Box height="100%" display="flex" flexDirection="column">
diff --git a/web/pgadmin/static/js/Theme/index.jsx b/web/pgadmin/static/js/Theme/index.jsx
index 9124743ec..402e82439 100644
--- a/web/pgadmin/static/js/Theme/index.jsx
+++ b/web/pgadmin/static/js/Theme/index.jsx
@@ -19,6 +19,7 @@ import CustomPropTypes from '../custom_prop_types';
 import getStandardTheme from './standard';
 import getDarkTheme from './dark';
 import getHightContrastTheme from './high_contrast';
+import { CssBaseline } from '@material-ui/core';
 
 /* Common settings across all themes */
 let basicSettings = createMuiTheme();
@@ -278,6 +279,19 @@ function getFinalTheme(baseTheme) {
   return createMuiTheme({
     mixins: mixins,
     overrides: {
+      MuiCssBaseline: {
+        '@global': {
+          ul: {
+            margin: 0,
+            padding: 0,
+          },
+          li: {
+            listStyle: 'none',
+            margin: 0,
+            padding: 0,
+          }
+        },
+      },
       MuiOutlinedInput:  {
         root: {
           '&.Mui-disabled .MuiOutlinedInput-notchedOutline': {
@@ -535,6 +549,7 @@ export default function Theme(props) {
   }, []);
   return (
     <ThemeProvider theme={theme}>
+      <CssBaseline />
       {props.children}
     </ThemeProvider>
   );
@@ -561,6 +576,7 @@ export const commonTableStyles = makeStyles((theme)=>({
       textOverflow: 'ellipsis',
       whiteSpace: 'nowrap',
       userSelect: 'text',
+      maxWidth: '250px',
       '&:first-of-type':{
         borderLeft: 'none',
       },
diff --git a/web/pgadmin/static/js/Theme/standard.js b/web/pgadmin/static/js/Theme/standard.js
index 1efe55300..8b8b1fe41 100644
--- a/web/pgadmin/static/js/Theme/standard.js
+++ b/web/pgadmin/static/js/Theme/standard.js
@@ -105,6 +105,20 @@ export default function(basicSettings) {
       qtDatagridSelectFg: '#222',
       cardHeaderBg: '#fff',
       emptySpaceBg: '#ebeef3',
+      explain: {
+        sev2: {
+          color: '#222222',
+          bg: '#FFEE88',
+        },
+        sev3: {
+          color: '#FFFFFF',
+          bg: '#EE8800'
+        },
+        sev4: {
+          color: '#FFFFFF',
+          bg: '#880000'
+        },
+      }
     }
   });
 }
diff --git a/web/pgadmin/static/js/components/CodeMirror.jsx b/web/pgadmin/static/js/components/CodeMirror.jsx
index de891d62b..218efc8a3 100644
--- a/web/pgadmin/static/js/components/CodeMirror.jsx
+++ b/web/pgadmin/static/js/components/CodeMirror.jsx
@@ -405,6 +405,22 @@ export default function CodeMirror({currEditor, name, value, options, events, re
     }
 
     Object.keys(events||{}).forEach((eventName)=>{
+      if(eventName === 'change') {
+        let timeoutId;
+        const change = (...args)=>{
+          /* In case of indent, change is triggered for each line */
+          /* This can be avoided and taking only the latest */
+          if(timeoutId) {
+            clearTimeout(timeoutId);
+          }
+          timeoutId = setTimeout(()=>{
+            events[eventName](...args);
+            timeoutId = null;
+          }, 0);
+        };
+        editor.current.on(eventName, change);
+        return;
+      }
       editor.current.on(eventName, events[eventName]);
     });
     editor.current.on('drop', handleDrop);
diff --git a/web/pgadmin/static/js/components/ExternalIcon.jsx b/web/pgadmin/static/js/components/ExternalIcon.jsx
index 3fa91b895..249feee7d 100644
--- a/web/pgadmin/static/js/components/ExternalIcon.jsx
+++ b/web/pgadmin/static/js/components/ExternalIcon.jsx
@@ -1,5 +1,6 @@
 import React from 'react';
 import QueryToolSvg from '../../img/fonticon/query_tool.svg?svgr';
+import ViewDataSvg from '../../img/fonticon/view_data.svg?svgr';
 import SaveDataSvg from '../../img/fonticon/save_data_changes.svg?svgr';
 import PasteSvg from '../../img/content_paste.svg?svgr';
 import FilterSvg from '../../img/filter_alt_black.svg?svgr';
@@ -22,16 +23,44 @@ ExternalIcon.propTypes = {
   Icon: PropTypes.elementType.isRequired,
 };
 
-export const QueryToolIcon = ()=><ExternalIcon Icon={QueryToolSvg} style={{height: '1rem'}} />;
-export const SaveDataIcon = ()=><ExternalIcon Icon={SaveDataSvg} style={{height: '1rem'}} />;
-export const PasteIcon = ()=><ExternalIcon Icon={PasteSvg} />;
-export const FilterIcon = ()=><ExternalIcon Icon={FilterSvg} />;
-export const CommitIcon = ()=><ExternalIcon Icon={CommitSvg} />;
-export const RollbackIcon = ()=><ExternalIcon Icon={RollbackSvg} />;
-export const ClearIcon = ()=><ExternalIcon Icon={ClearSvg} />;
-export const ConnectedIcon = ()=><ExternalIcon Icon={ConnectedSvg} style={{height: '1rem'}} />;
-export const DisonnectedIcon = ()=><ExternalIcon Icon={DisconnectedSvg} style={{height: '1rem'}} />;
-export const RegexIcon = ()=><ExternalIcon Icon={RegexSvg} />;
-export const FormatCaseIcon = ()=><ExternalIcon Icon={FormatCaseSvg} />;
-export const ExpandDialogIcon = ()=><ExternalIcon Icon={Expand} style={{height: '1.2rem'}}  />;
-export const MinimizeDialogIcon = ()=><ExternalIcon Icon={Collapse} style={{height: '1.4rem'}} />;
+export const QueryToolIcon = ({style})=><ExternalIcon Icon={QueryToolSvg} style={{height: '1rem', ...style}} />;
+QueryToolIcon.propTypes = {style: PropTypes.object};
+
+export const ViewDataIcon = ({style})=><ExternalIcon Icon={ViewDataSvg} style={{height: '0.8rem', ...style}} />;
+ViewDataIcon.propTypes = {style: PropTypes.object};
+
+export const SaveDataIcon = ({style})=><ExternalIcon Icon={SaveDataSvg} style={{height: '1rem', ...style}} />;
+SaveDataIcon.propTypes = {style: PropTypes.object};
+
+export const PasteIcon = ({style})=><ExternalIcon Icon={PasteSvg} style={style} />;
+PasteIcon.propTypes = {style: PropTypes.object};
+
+export const FilterIcon = ({style})=><ExternalIcon Icon={FilterSvg} style={style} />;
+FilterIcon.propTypes = {style: PropTypes.object};
+
+export const CommitIcon = ({style})=><ExternalIcon Icon={CommitSvg} style={style} />;
+CommitIcon.propTypes = {style: PropTypes.object};
+
+export const RollbackIcon = ({style})=><ExternalIcon Icon={RollbackSvg} style={style} />;
+RollbackIcon.propTypes = {style: PropTypes.object};
+
+export const ClearIcon = ({style})=><ExternalIcon Icon={ClearSvg} style={style} />;
+ClearIcon.propTypes = {style: PropTypes.object};
+
+export const ConnectedIcon = ({style})=><ExternalIcon Icon={ConnectedSvg} style={{height: '1rem', ...style}} />;
+ConnectedIcon.propTypes = {style: PropTypes.object};
+
+export const DisonnectedIcon = ({style})=><ExternalIcon Icon={DisconnectedSvg} style={{height: '1rem', ...style}} />;
+DisonnectedIcon.propTypes = {style: PropTypes.object};
+
+export const RegexIcon = ({style})=><ExternalIcon Icon={RegexSvg} style={style} />;
+RegexIcon.propTypes = {style: PropTypes.object};
+
+export const FormatCaseIcon = ({style})=><ExternalIcon Icon={FormatCaseSvg} style={style} />;
+FormatCaseIcon.propTypes = {style: PropTypes.object};
+
+export const ExpandDialogIcon = ({style})=><ExternalIcon Icon={Expand} style={{height: '1.2rem', ...style}}  />;QueryToolIcon.propTypes = {style: PropTypes.object};
+ExpandDialogIcon.propTypes = {style: PropTypes.object};
+
+export const MinimizeDialogIcon = ({style})=><ExternalIcon Icon={Collapse} style={{height: '1.4rem', ...style}} />;
+MinimizeDialogIcon.propTypes = {style: PropTypes.object};
diff --git a/web/pgadmin/static/js/components/Menu.jsx b/web/pgadmin/static/js/components/Menu.jsx
index 02b3e0b3c..84f51f65c 100644
--- a/web/pgadmin/static/js/components/Menu.jsx
+++ b/web/pgadmin/static/js/components/Menu.jsx
@@ -1,5 +1,5 @@
 import { makeStyles } from '@material-ui/styles';
-import React from 'react';
+import React, { useRef } from 'react';
 import CheckIcon from '@material-ui/icons/Check';
 import PropTypes from 'prop-types';
 
@@ -34,6 +34,9 @@ const useStyles = makeStyles((theme)=>({
       color: theme.palette.primary.contrastText,
     }
   },
+  checkIcon: {
+    width: '1.3rem',
+  },
   hideCheck: {
     visibility: 'hidden',
   },
@@ -70,7 +73,7 @@ export const PgMenuItem = applyStatics(MenuItem)(({hasCheck=false, checked=false
     };
   }
   return <MenuItem {...props} onClick={onClick} className={classes.menuItem}>
-    {hasCheck && <CheckIcon style={checked ? {} : {visibility: 'hidden'}}/>}
+    {hasCheck && <CheckIcon className={classes.checkIcon} style={checked ? {} : {visibility: 'hidden'}} />}
     {children}
     {(shortcut || accesskey) && <div className={classes.shortcut}>({shortcutToString(shortcut, accesskey)})</div>}
   </MenuItem>;
@@ -84,3 +87,32 @@ PgMenuItem.propTypes = {
   children: CustomPropTypes.children,
   onClick: PropTypes.func,
 };
+
+export function usePgMenuGroup() {
+  const [openMenuName, setOpenMenuName] = React.useState(null);
+  const prevMenuOpenIdRef = useRef(null);
+
+  const toggleMenu = React.useCallback((e)=>{
+    setOpenMenuName(()=>{
+      return prevMenuOpenIdRef.current == e.currentTarget?.name ? null : e.currentTarget?.name;
+    });
+    prevMenuOpenIdRef.current = null;
+  }, []);
+
+  const handleMenuClose = React.useCallback(()=>{
+    /* We have no way here to know if the menu was closed using menu button or not
+    We will keep the last menu name ref for sometime so that the menu does not
+    open again if menu button is clicked to close the menu */
+    prevMenuOpenIdRef.current = openMenuName;
+    setTimeout(()=>{
+      prevMenuOpenIdRef.current = null;
+    }, 300);
+    setOpenMenuName(null);
+  }, [openMenuName]);
+
+  return {
+    openMenuName: openMenuName,
+    toggleMenu: toggleMenu,
+    onMenuClose: handleMenuClose,
+  };
+}
diff --git a/web/pgadmin/static/js/helpers/EventBus.js b/web/pgadmin/static/js/helpers/EventBus.js
index 9a6906429..848d2822c 100644
--- a/web/pgadmin/static/js/helpers/EventBus.js
+++ b/web/pgadmin/static/js/helpers/EventBus.js
@@ -20,7 +20,7 @@ export default class EventBus {
         if(e.event === event) {
           return e.callback.toString()!=callback.toString();
         }
-        return e.event!=event && e.callback.toString()!=callback.toString();
+        return true;
       });
     } else {
       this._eventListeners = this._eventListeners.filter((e)=>e.event!=event);
diff --git a/web/pgadmin/tools/sqleditor/static/js/components/QueryToolComponent.jsx b/web/pgadmin/tools/sqleditor/static/js/components/QueryToolComponent.jsx
index 6d2af6045..a2b000bed 100644
--- a/web/pgadmin/tools/sqleditor/static/js/components/QueryToolComponent.jsx
+++ b/web/pgadmin/tools/sqleditor/static/js/components/QueryToolComponent.jsx
@@ -422,7 +422,7 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
         eventBus.current.deregisterListener(e[0], e[1]);
       });
     };
-  }, [qtState]);
+  }, [qtState.params, qtState.current_file]);
 
   useEffect(()=>{
     /* Fire query change so that title changes to latest */
@@ -602,11 +602,12 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
                 onResetLayout={onResetLayout}
                 docker={docker.current}
               />
-              <MainToolBar
-                containerRef={containerRef}
-                onManageMacros={onManageMacros}
-                onFilterClick={onFilterClick}
-              />
+              {React.useMemo(()=>(
+                <MainToolBar
+                  containerRef={containerRef}
+                  onManageMacros={onManageMacros}
+                  onFilterClick={onFilterClick}
+                />), [containerRef.current, onManageMacros, onFilterClick])}
               <Layout
                 getLayoutInstance={(obj)=>docker.current=obj}
                 defaultLayout={defaultLayout}
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 b48152b11..48739c644 100644
--- a/web/pgadmin/tools/sqleditor/static/js/components/QueryToolDataGrid/Editors.jsx
+++ b/web/pgadmin/tools/sqleditor/static/js/components/QueryToolDataGrid/Editors.jsx
@@ -170,8 +170,8 @@ export function TextEditor({row, column, onRowChange, onClose}) {
   }, []);
 
   const onOK = ()=>{
-    if(column.is_array && !isValidArray(value)) {
-      console.error(gettext('Arrays must start with "{" and end with "}"'));
+    if(column.is_array && !isValidArray(localVal)) {
+      Notifier.error(gettext('Arrays must start with "{" and end with "}"'));
     } else {
       let columnVal = textColumnFinalVal(localVal, column);
       onRowChange({ ...row, [column.key]: columnVal}, true);
@@ -205,14 +205,14 @@ TextEditor.propTypes = EditorPropTypes;
 export function NumberEditor({row, column, onRowChange, onClose}) {
   const classes = useStyles();
   const value = row[column.key] ?? '';
-  const onBlur = ()=>{
+  const isValidData = ()=>{
     if(!column.is_array && isNaN(value)){
       Notifier.error(gettext('Please enter a valid number'));
-      return;
+      return false;
     } else if(column.is_array) {
       if(!isValidArray(value)) {
         Notifier.error(gettext('Arrays must start with "{" and end with "}"'));
-        return;
+        return false;
       }
       let checkVal = value.trim().slice(1, -1);
       if(checkVal == '') {
@@ -223,16 +223,25 @@ export function NumberEditor({row, column, onRowChange, onClose}) {
       for (const val of checkVal) {
         if(isNaN(val)) {
           Notifier.error(gettext('Arrays must start with "{" and end with "}"'));
-          return;
+          return false;
         }
       }
     }
-    onClose(column.can_edit ? true : false);
+    return true;
+  };
+  const onBlur = ()=>{
+    if(isValidData()) {
+      onClose(column.can_edit ? true : false);
+      return true;
+    }
+    return false;
   };
   const onKeyDown = (e)=>{
     if(e.code == 'Tab') {
       e.preventDefault();
-      onBlur();
+      if(!onBlur()) {
+        e.stopPropagation();
+      }
     }
   };
   return (
@@ -245,7 +254,7 @@ export function NumberEditor({row, column, onRowChange, onClose}) {
           onRowChange({ ...row, [column.key]: e.target.value });
         }
       }}
-      // onBlur={onBlur}
+      onBlur={onBlur}
       onKeyDown={onKeyDown}
     />
   );
@@ -269,7 +278,7 @@ export function CheckboxEditor({row, column, onRowChange, onClose}) {
   };
   const onBlur = ()=>{onClose(true);};
   let className = 'checked';
-  if(!value) {
+  if(!value && value != null) {
     className = 'unchecked';
   } else if(value == null){
     className = 'intermediate';
@@ -323,7 +332,7 @@ export function JsonTextEditor({row, column, onRowChange, onClose}) {
           value={localVal}
           options={{
             onChange: onChange,
-            onError: (error)=>console.error('Invalid Json: ' + error.message.split(':')[0]),
+            onError: (error)=>Notifier.error('Invalid Json: ' + error.message.split(':')[0]),
           }}
           className={'jsoneditor-div'}
         />
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 fc35c0964..f0763d543 100644
--- a/web/pgadmin/tools/sqleditor/static/js/components/dialogs/NewConnectionDialog.jsx
+++ b/web/pgadmin/tools/sqleditor/static/js/components/dialogs/NewConnectionDialog.jsx
@@ -63,6 +63,9 @@ class NewConnectionSchema extends BaseUISchema {
         .then(({data: respData})=>{
           let groupedOptions = [];
           _.forIn(respData.data.result.server_list, (v, k)=>{
+            if(v.length == 0) {
+              return;
+            }
             /* initial selection */
             _.find(v, (o)=>o.value==obj.params.sid).selected = true;
             groupedOptions.push({
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 da1493e69..cf9db036a 100644
--- a/web/pgadmin/tools/sqleditor/static/js/components/sections/ConnectionBar.jsx
+++ b/web/pgadmin/tools/sqleditor/static/js/components/sections/ConnectionBar.jsx
@@ -106,15 +106,15 @@ export function ConnectionBar({connected, connecting, connectionStatus, connecti
           >
             <Tooltip title={queryToolCtx.params.is_query_tool ? '' : connTitle}>
               <Box display="flex" width="100%">
-                <Box textOverflow="ellipsis" overflow="hidden" marginRight="auto">{connecting && '(Obtaining connection)'}{connTitle}</Box>
+                <Box textOverflow="ellipsis" overflow="hidden" marginRight="auto">{connecting && gettext('(Obtaining connection)')}{connTitle}</Box>
                 {queryToolCtx.params.is_query_tool && <Box><KeyboardArrowDownIcon /></Box>}
               </Box>
             </Tooltip>
           </DefaultButton>
-          <PgIconButton title="New query tool" icon={<QueryToolIcon />} onClick={onNewQueryToolClick}/>
+          <PgIconButton title={gettext('New query tool for current connection')} icon={<QueryToolIcon />} onClick={onNewQueryToolClick}/>
         </PgButtonGroup>
         <PgButtonGroup size="small" variant="text" style={{marginLeft: 'auto'}}>
-          <PgIconButton title="Reset layout" icon={<RotateLeftRoundedIcon />} onClick={onResetLayout}/>
+          <PgIconButton title={gettext('Reset layout')} icon={<RotateLeftRoundedIcon />} onClick={onResetLayout}/>
         </PgButtonGroup>
       </Box>
       <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 755ba4662..97006107e 100644
--- a/web/pgadmin/tools/sqleditor/static/js/components/sections/GeometryViewer.jsx
+++ b/web/pgadmin/tools/sqleditor/static/js/components/sections/GeometryViewer.jsx
@@ -94,7 +94,7 @@ function parseEwkbData(rows, column) {
 
   // generate map info content
   if (tooLargeDataSize || tooManyGeometries) {
-    infoList.push(supportedGeometries.length + ' of ' + rows.length + ' geometries rendered.');
+    infoList.push(gettext('%s of %s geometries rendered.', supportedGeometries.length, rows.length));
   }
   if (geometries3D.length > 0) {
     infoList.push(gettext('3D geometries not rendered.'));
@@ -116,7 +116,7 @@ function parseData(rows, columns, column) {
       'geoJSONs': [],
       'selectedSRID': 0,
       'getPopupContent': undefined,
-      'infoList': ['Empty row.'],
+      'infoList': [gettext('Empty row.')],
     };
   }
 
@@ -294,19 +294,19 @@ function TheMap({data}) {
     <>
       {data.selectedSRID === 4326 &&
     <LayersControl position="topright">
-      <LayersControl.BaseLayer checked name="Empty">
+      <LayersControl.BaseLayer checked name={gettext('Empty')}>
         <TileLayer
           url=""
         />
       </LayersControl.BaseLayer>
-      <LayersControl.BaseLayer checked name="Street">
+      <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="Topography">
+      <LayersControl.BaseLayer name={gettext('Topography')}>
         <TileLayer
           url="https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png"
           maxZoom={17}
@@ -317,7 +317,7 @@ function TheMap({data}) {
           }
         />
       </LayersControl.BaseLayer>
-      <LayersControl.BaseLayer name="Gray Style">
+      <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}
@@ -328,7 +328,7 @@ function TheMap({data}) {
           subdomains='abcd'
         />
       </LayersControl.BaseLayer>
-      <LayersControl.BaseLayer name="Light Color">
+      <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}
@@ -339,7 +339,7 @@ function TheMap({data}) {
           subdomains='abcd'
         />
       </LayersControl.BaseLayer>
-      <LayersControl.BaseLayer name="Dark Matter">
+      <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}
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 42d1222c5..fe0f60a5e 100644
--- a/web/pgadmin/tools/sqleditor/static/js/components/sections/MainToolBar.jsx
+++ b/web/pgadmin/tools/sqleditor/static/js/components/sections/MainToolBar.jsx
@@ -23,7 +23,7 @@ import FormatListNumberedRoundedIcon from '@material-ui/icons/FormatListNumbered
 import HelpIcon from '@material-ui/icons/HelpRounded';
 import {QUERY_TOOL_EVENTS, CONNECTION_STATUS} from '../QueryToolConstants';
 import { QueryToolConnectionContext, QueryToolContext, QueryToolEventsContext } from '../QueryToolComponent';
-import { PgMenu, PgMenuDivider, PgMenuItem } from '../../../../../../static/js/components/Menu';
+import { PgMenu, PgMenuDivider, PgMenuItem, usePgMenuGroup } from '../../../../../../static/js/components/Menu';
 import gettext from 'sources/gettext';
 import { useKeyboardShortcuts } from '../../../../../../static/js/custom_hooks';
 import {shortcut_key} from 'sources/keyboard_shortcuts';
@@ -150,7 +150,7 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros}) {
     'filter': true,
     'limit': false,
   });
-  const [menuOpenId, setMenuOpenId] = React.useState(null);
+  const {openMenuName, toggleMenu, onMenuClose} = usePgMenuGroup();
   const [checkedMenuItems, setCheckedMenuItems] = React.useState({});
   /* Menu button refs */
   const saveAsMenuRef = React.useRef(null);
@@ -189,14 +189,6 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros}) {
     explain(true);
   }, [explain]);
 
-  const openMenu = useCallback((e)=>{
-    setMenuOpenId(e.currentTarget.name);
-  }, []);
-
-  const handleMenuClose = useCallback(()=>{
-    setMenuOpenId(null);
-  }, []);
-
   const checkMenuClick = useCallback((e)=>{
     setCheckedMenuItems((prev)=>{
       let newVal = !prev[e.value];
@@ -453,21 +445,21 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros}) {
             accesskey={shortcut_key(queryToolPref.btn_save_file)} disabled={buttonsDisabled['save'] || !queryToolCtx.params.is_query_tool}
             onClick={()=>{saveFile(false);}} />
           <PgIconButton title={gettext('File')} icon={<KeyboardArrowDownIcon />} splitButton disabled={!queryToolCtx.params.is_query_tool}
-            name="menu-saveas" ref={saveAsMenuRef} onClick={openMenu}
+            name="menu-saveas" ref={saveAsMenuRef} onClick={toggleMenu}
           />
         </PgButtonGroup>
         <PgButtonGroup size="small">
           <PgIconButton title={gettext('Edit')} icon={
             <><EditRoundedIcon /><KeyboardArrowDownIcon style={{marginLeft: '-10px'}} /></>}
           disabled={!queryToolCtx.params.is_query_tool}
-          name="menu-edit" ref={editMenuRef} onClick={openMenu} />
+          name="menu-edit" ref={editMenuRef} onClick={toggleMenu} />
         </PgButtonGroup>
         <PgButtonGroup size="small" color={highlightFilter ? 'primary' : 'default'}>
           <PgIconButton title={gettext('Sort/Filter')} icon={<FilterIcon />}
             onClick={onFilterClick} disabled={buttonsDisabled['filter']} accesskey={shortcut_key(queryToolPref.btn_filter_dialog)}/>
           <PgIconButton title={gettext('Filter options')} icon={<KeyboardArrowDownIcon />} splitButton
             disabled={buttonsDisabled['filter']} name="menu-filter" ref={filterMenuRef} accesskey={shortcut_key(queryToolPref.btn_filter_options)}
-            onClick={openMenu} />
+            onClick={toggleMenu} />
         </PgButtonGroup>
         <InputSelectNonSearch options={[
           {label: gettext('No limit'), value: '-1'},
@@ -482,7 +474,7 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros}) {
             onClick={executeQuery} disabled={buttonsDisabled['execute']} shortcut={queryToolPref.execute_query}/>
           <PgIconButton title={gettext('Execute options')} icon={<KeyboardArrowDownIcon />} splitButton
             name="menu-autocommit" ref={autoCommitMenuRef} accesskey={shortcut_key(queryToolPref.btn_delete_row)}
-            onClick={openMenu} />
+            onClick={toggleMenu} disabled={!queryToolCtx.params.is_query_tool}/>
         </PgButtonGroup>
         <PgButtonGroup size="small">
           <PgIconButton title={gettext('Explain')} icon={<ExplicitRoundedIcon />}
@@ -491,7 +483,7 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros}) {
             onClick={()=>{explainAnalyse();}} disabled={buttonsDisabled['explain_analyse'] || !queryToolCtx.params.is_query_tool} shortcut={queryToolPref.explain_analyze_query}/>
           <PgIconButton title={gettext('Explain Settings')} icon={<KeyboardArrowDownIcon />} splitButton
             disabled={!queryToolCtx.params.is_query_tool}
-            name="menu-explain" ref={explainMenuRef} onClick={openMenu} />
+            name="menu-explain" ref={explainMenuRef} onClick={toggleMenu} />
         </PgButtonGroup>
         <PgButtonGroup size="small">
           <PgIconButton title={gettext('Commit')} icon={<CommitIcon />}
@@ -502,7 +494,7 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros}) {
         <PgButtonGroup size="small">
           <PgIconButton title={gettext('Macros')} icon={
             <><FormatListNumberedRoundedIcon /><KeyboardArrowDownIcon style={{marginLeft: '-10px'}} /></>}
-          disabled={!queryToolCtx.params.is_query_tool} name="menu-macros" ref={macrosMenuRef} onClick={openMenu} />
+          disabled={!queryToolCtx.params.is_query_tool} name="menu-macros" ref={macrosMenuRef} onClick={toggleMenu} />
         </PgButtonGroup>
         <PgButtonGroup size="small">
           <PgIconButton title={gettext('Help')} icon={<HelpIcon />} onClick={onHelpClick} />
@@ -510,15 +502,15 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros}) {
       </Box>
       <PgMenu
         anchorRef={saveAsMenuRef}
-        open={menuOpenId=='menu-saveas'}
-        onClose={handleMenuClose}
+        open={openMenuName=='menu-saveas'}
+        onClose={onMenuClose}
       >
         <PgMenuItem onClick={()=>{saveFile(true);}}>{gettext('Save as')}</PgMenuItem>
       </PgMenu>
       <PgMenu
         anchorRef={editMenuRef}
-        open={menuOpenId=='menu-edit'}
-        onClose={handleMenuClose}
+        open={openMenuName=='menu-edit'}
+        onClose={onMenuClose}
       >
         <PgMenuItem shortcut={FIXED_PREF.find}
           onClick={()=>{eventBus.fireEvent(QUERY_TOOL_EVENTS.EDITOR_FIND_REPLACE, false);}}>{gettext('Find')}</PgMenuItem>
@@ -540,8 +532,8 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros}) {
       </PgMenu>
       <PgMenu
         anchorRef={filterMenuRef}
-        open={menuOpenId=='menu-filter'}
-        onClose={handleMenuClose}
+        open={openMenuName=='menu-filter'}
+        onClose={onMenuClose}
       >
         <PgMenuItem onClick={()=>{eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_INCLUDE_EXCLUDE_FILTER, true);}}>{gettext('Filter by Selection')}</PgMenuItem>
         <PgMenuItem onClick={()=>{eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_INCLUDE_EXCLUDE_FILTER, false);}}>{gettext('Exclude by Selection')}</PgMenuItem>
@@ -549,8 +541,8 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros}) {
       </PgMenu>
       <PgMenu
         anchorRef={autoCommitMenuRef}
-        open={menuOpenId=='menu-autocommit'}
-        onClose={handleMenuClose}
+        open={openMenuName=='menu-autocommit'}
+        onClose={onMenuClose}
       >
         <PgMenuItem hasCheck value="auto_commit" checked={checkedMenuItems['auto_commit']}
           onClick={checkMenuClick}>{gettext('Auto commit?')}</PgMenuItem>
@@ -559,8 +551,8 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros}) {
       </PgMenu>
       <PgMenu
         anchorRef={explainMenuRef}
-        open={menuOpenId=='menu-explain'}
-        onClose={handleMenuClose}
+        open={openMenuName=='menu-explain'}
+        onClose={onMenuClose}
       >
         <PgMenuItem hasCheck value="explain_verbose" checked={checkedMenuItems['explain_verbose']}
           onClick={checkMenuClick}>{gettext('Verbose')}</PgMenuItem>
@@ -577,8 +569,8 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros}) {
       </PgMenu>
       <PgMenu
         anchorRef={macrosMenuRef}
-        open={menuOpenId=='menu-macros'}
-        onClose={handleMenuClose}
+        open={openMenuName=='menu-macros'}
+        onClose={onMenuClose}
       >
         <PgMenuItem onClick={onManageMacros}>{gettext('Manage macros')}</PgMenuItem>
         <PgMenuDivider />
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 cbbca3486..b3c4dc18a 100644
--- a/web/pgadmin/tools/sqleditor/static/js/components/sections/QueryHistory.jsx
+++ b/web/pgadmin/tools/sqleditor/static/js/components/sections/QueryHistory.jsx
@@ -19,7 +19,7 @@ import moment from 'moment';
 import PlayArrowRoundedIcon from '@material-ui/icons/PlayArrowRounded';
 import AssessmentRoundedIcon from '@material-ui/icons/AssessmentRounded';
 import ExplicitRoundedIcon from '@material-ui/icons/ExplicitRounded';
-import { SaveDataIcon, CommitIcon, RollbackIcon } from '../../../../../../static/js/components/ExternalIcon';
+import { SaveDataIcon, CommitIcon, RollbackIcon, ViewDataIcon } from '../../../../../../static/js/components/ExternalIcon';
 import { InputSwitch } from '../../../../../../static/js/components/FormComponents';
 import CodeMirror from '../../../../../../static/js/components/CodeMirror';
 import { DefaultButton } from '../../../../../../static/js/components/Buttons';
@@ -30,6 +30,7 @@ import { LayoutEventsContext, LAYOUT_EVENTS } from '../../../../../../static/js/
 import PropTypes from 'prop-types';
 import { parseApiError } from '../../../../../../static/js/api_instance';
 import * as clipboard from '../../../../../../static/js/clipboard';
+import EmptyPanelMessage from '../../../../../../static/js/components/EmptyPanelMessage';
 
 const useStyles = makeStyles((theme)=>({
   leftRoot: {
@@ -145,9 +146,9 @@ class QueryHistoryUtils {
   getDatePrefix(date) {
     let prefix = '';
     if (this.isDaysBefore(date, 0)) {
-      prefix = 'Today - ';
+      prefix = gettext('Today - ');
     } else if (this.isDaysBefore(date, 1)) {
-      prefix = 'Yesterday - ';
+      prefix = gettext('Yesterday - ');
     }
     return prefix;
   }
@@ -247,7 +248,7 @@ function QuerySourceIcon({source}) {
   case JSON.stringify(QuerySources.SAVE_DATA):
     return <SaveDataIcon style={{marginLeft: '-4px'}}/>;
   case JSON.stringify(QuerySources.VIEW_DATA):
-    return <SaveDataIcon style={{marginLeft: '-4px'}}/>;
+    return <ViewDataIcon style={{marginLeft: '-4px'}}/>;
   default:
     return <></>;
   }
@@ -312,7 +313,9 @@ function QueryHistoryDetails({entry}) {
   }, [entry]);
 
   if(!entry) {
-    return <></>;
+    return <Box display="flex" height="100%">
+      <EmptyPanelMessage text={gettext('Select an history entry to see details.')} />
+    </Box>;
   }
 
   return (
@@ -460,39 +463,45 @@ export function QueryHistory() {
       <Loader message={loaderText} />
       {React.useMemo(()=>(
         <Box display="flex" height="100%">
-          <Box flexBasis="50%" maxWidth="50%" className={classes.leftRoot}>
-            <Box padding="0.25rem" display="flex">
-              {gettext('Show queries generated internally by pgAdmin?')}
-              <InputSwitch value={showInternal} onChange={(e)=>{
-                setShowInternal(e.target.checked);
-                qhu.current.showInternal = e.target.checked;
-                setSelectedItemKey(qhu.current.getNextItemKey());
-              }} />
-              <Box marginLeft="auto">
-                <DefaultButton size="small" disabled={!selectedItemKey} onClick={onRemove}>Remove</DefaultButton>
-                <DefaultButton size="small" disabled={!qhu.current?.getGroups()?.length}
-                  className={classes.removeBtnMargin} onClick={onRemoveAll}>Remove All</DefaultButton>
+          {qhu.current.size() == 0 ?
+            <EmptyPanelMessage text={gettext('No history found')} />:
+            <>
+              <Box flexBasis="50%" maxWidth="50%" className={classes.leftRoot}>
+                <Box padding="0.25rem" display="flex" flexWrap="wrap">
+                  <Box marginRight="auto">
+                    {gettext('Show queries generated internally by pgAdmin?')}
+                    <InputSwitch value={showInternal} onChange={(e)=>{
+                      setShowInternal(e.target.checked);
+                      qhu.current.showInternal = e.target.checked;
+                      setSelectedItemKey(qhu.current.getNextItemKey());
+                    }} />
+                  </Box>
+                  <Box>
+                    <DefaultButton size="small" disabled={!selectedItemKey} onClick={onRemove}>{gettext('Remove')}</DefaultButton>
+                    <DefaultButton size="small" disabled={!qhu.current?.getGroups()?.length}
+                      className={classes.removeBtnMargin} onClick={onRemoveAll}>{gettext('Remove All')}</DefaultButton>
+                  </Box>
+                </Box>
+                <Box flexGrow="1" overflow="auto" className={classes.listRoot}>
+                  <List innerRef={listRef} className={classes.root} subheader={<li />} tabIndex="0" onKeyDown={onKeyPressed}>
+                    {qhu.current.getGroups().map(([groupKey, groupHeader]) => (
+                      <ListItem key={`section-${groupKey}`} className={classes.removePadding}>
+                        <List className={classes.removePadding}>
+                          <ListSubheader className={classes.listSubheader}>{groupHeader}</ListSubheader>
+                          {qhu.current.getGroupEntries(groupKey).map((entry) => (
+                            <HistoryEntry key={entry.itemKey} entry={entry} formatEntryDate={qhu.current.formatEntryDate}
+                              itemKey={entry.itemKey} selectedItemKey={selectedItemKey} onClick={()=>{setSelectedItemKey(entry.itemKey);}}/>
+                          ))}
+                        </List>
+                      </ListItem>
+                    ))}
+                  </List>
+                </Box>
+              </Box>
+              <Box flexBasis="50%" maxWidth="50%" overflow="auto">
+                <QueryHistoryDetails entry={selectedEntry}/>
               </Box>
-            </Box>
-            <Box flexGrow="1" overflow="auto" className={classes.listRoot}>
-              <List innerRef={listRef} className={classes.root} subheader={<li />} tabIndex="0" onKeyDown={onKeyPressed}>
-                {qhu.current.getGroups().map(([groupKey, groupHeader]) => (
-                  <ListItem key={`section-${groupKey}`} className={classes.removePadding}>
-                    <List className={classes.removePadding}>
-                      <ListSubheader className={classes.listSubheader}>{groupHeader}</ListSubheader>
-                      {qhu.current.getGroupEntries(groupKey).map((entry) => (
-                        <HistoryEntry key={entry.itemKey} entry={entry} formatEntryDate={qhu.current.formatEntryDate}
-                          itemKey={entry.itemKey} selectedItemKey={selectedItemKey} onClick={()=>{setSelectedItemKey(entry.itemKey);}}/>
-                      ))}
-                    </List>
-                  </ListItem>
-                ))}
-              </List>
-            </Box>
-          </Box>
-          <Box flexBasis="50%" maxWidth="50%" overflow="auto">
-            <QueryHistoryDetails entry={selectedEntry}/>
-          </Box>
+            </>}
         </Box>
       ), [selectedItemKey, showInternal, qhu.current.size()])}
     </>
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 ee5b2245a..553f2b647 100644
--- a/web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSet.jsx
+++ b/web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSet.jsx
@@ -627,7 +627,7 @@ export class ResultSetUtils {
       data.primary_keys = (_.isEmpty(data.primary_keys) && data.has_oids) ? data.oids : data.primary_keys;
       data.can_edit = !_.isEmpty(data.primary_keys);
       let procColumns = this.processColumns(data);
-      onResultsAvailable(data, procColumns, this.processRows(result, procColumns, this.processRows(result, procColumns)));
+      onResultsAvailable(data, procColumns, this.processRows(result, procColumns));
       this.setStartData(null);
       let planJson = this.getPlanJson(result, data);
       if(planJson) {
@@ -886,12 +886,14 @@ export function ResultSet() {
   };
   useEffect(()=>{
     eventBus.registerListener(QUERY_TOOL_EVENTS.FETCH_MORE_ROWS, fetchMoreRows);
-    return ()=>eventBus.deregisterListener(QUERY_TOOL_EVENTS.FETCH_MORE_ROWS, fetchMoreRows);
-  }, [queryData, columns]);
+    return ()=>{
+      eventBus.deregisterListener(QUERY_TOOL_EVENTS.FETCH_MORE_ROWS, fetchMoreRows);
+    };
+  }, [queryData?.has_more_rows, columns]);
 
   useEffect(()=>{
     eventBus.fireEvent(QUERY_TOOL_EVENTS.ROWS_FETCHED, queryData?.rows_fetched_to, queryData?.rows_affected);
-  }, [queryData]);
+  }, [queryData?.rows_fetched_to, queryData?.rows_affected]);
 
   const warnSaveDataClose = ()=>{
     // No changes.
@@ -975,7 +977,7 @@ export function ResultSet() {
       }
 
       eventBus.fireEvent(QUERY_TOOL_EVENTS.SAVE_DATA_DONE, true);
-      if(!_.size(dataChangeStore.added)) {
+      if(_.size(dataChangeStore.added)) {
         // Update the rows in a grid after addition
         respData.data.query_results.forEach((qr)=>{
           if(!_.isNull(qr.row_added)) {
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 e51e2ad5a..3fd5cd034 100644
--- a/web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSetToolbar.jsx
+++ b/web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSetToolbar.jsx
@@ -158,7 +158,7 @@ export function ResultSetToolbar({containerRef, canEdit}) {
         open={menuOpenId=='menu-copyheader'}
         onClose={handleMenuClose}
       >
-        <PgMenuItem hasCheck value="copy_with_headers" checked={checkedMenuItems['copy_with_headers']} onClick={checkMenuClick}>Copy with headers</PgMenuItem>
+        <PgMenuItem hasCheck value="copy_with_headers" checked={checkedMenuItems['copy_with_headers']} onClick={checkMenuClick}>{gettext('Copy with headers')}</PgMenuItem>
       </PgMenu>
     </>
   );
diff --git a/web/pgadmin/tools/sqleditor/static/js/components/sections/StatusBar.jsx b/web/pgadmin/tools/sqleditor/static/js/components/sections/StatusBar.jsx
index df562884e..446075cd9 100644
--- a/web/pgadmin/tools/sqleditor/static/js/components/sections/StatusBar.jsx
+++ b/web/pgadmin/tools/sqleditor/static/js/components/sections/StatusBar.jsx
@@ -15,6 +15,7 @@ import _ from 'lodash';
 import { QUERY_TOOL_EVENTS } from '../QueryToolConstants';
 import { useStopwatch } from '../../../../../../static/js/custom_hooks';
 import { QueryToolEventsContext } from '../QueryToolComponent';
+import gettext from 'sources/gettext';
 
 
 const useStyles = makeStyles((theme)=>({
@@ -86,18 +87,18 @@ export function StatusBar() {
 
   let stagedText = '';
   if(dataRowChangeCounts.added > 0) {
-    stagedText += ` Added: ${dataRowChangeCounts.added};`;
+    stagedText += ' ' + gettext('Added: %s', dataRowChangeCounts.added);
   }
   if(dataRowChangeCounts.updated > 0) {
-    stagedText += ` Updated: ${dataRowChangeCounts.updated};`;
+    stagedText +=  ' ' + gettext('Updated: %s', dataRowChangeCounts.updated);
   }
   if(dataRowChangeCounts.deleted > 0) {
-    stagedText += ` Deleted: ${dataRowChangeCounts.deleted};`;
+    stagedText +=  ' ' + gettext('Deleted: %s', dataRowChangeCounts.deleted);
   }
 
   return (
     <Box className={classes.root}>
-      <Box className={clsx(classes.padding, classes.divider)}>Total rows: {rowsCount[0]} of {rowsCount[1]}</Box>
+      <Box className={clsx(classes.padding, classes.divider)}>{gettext('Total rows: %s of %s', rowsCount[0], rowsCount[1])}</Box>
       {lastTaskText &&
         <Box className={clsx(classes.padding, classes.divider)}>{lastTaskText} {hours.toString().padStart(2, '0')}:{minutes.toString().padStart(2, '0')}:{seconds.toString().padStart(2, '0')}.{msec.toString().padStart(3, '0')}</Box>
       }
@@ -105,13 +106,13 @@ export function StatusBar() {
         <Box className={clsx(classes.padding, classes.divider)}>{lastTaskText} {hours.toString().padStart(2, '0')}:{minutes.toString().padStart(2, '0')}:{seconds.toString().padStart(2, '0')}.{msec.toString().padStart(3, '0')}</Box>
       }
       {Boolean(selectedRowsCount) &&
-        <Box className={clsx(classes.padding, classes.divider)}>Rows selected: {selectedRowsCount}</Box>}
+        <Box className={clsx(classes.padding, classes.divider)}>{gettext('Rows selected: %s',selectedRowsCount)}</Box>}
       {stagedText &&
         <Box className={clsx(classes.padding, classes.divider)}>
-          <span>Changes staged: {stagedText}</span>
+          <span>{gettext('Changes staged: %s', stagedText)}</span>
         </Box>
       }
-      <Box className={clsx(classes.padding, classes.mlAuto)}>Ln {position[0]}, Col {position[1]}</Box>
+      <Box className={clsx(classes.padding, classes.mlAuto)}>{gettext('Ln %s, Col %s', position[0], position[1])}</Box>
     </Box>
   );
 }
diff --git a/web/regression/javascript/components/Buttons.spec.js b/web/regression/javascript/components/Buttons.spec.js
index 9bedc95ef..7e2269c51 100644
--- a/web/regression/javascript/components/Buttons.spec.js
+++ b/web/regression/javascript/components/Buttons.spec.js
@@ -37,14 +37,14 @@ describe('components Buttons', ()=>{
   it('PrimaryButton', ()=>{
     let ThemedBtn = withTheme(PrimaryButton);
     let btn = mount(<ThemedBtn>Test</ThemedBtn>);
-    expect(btn.getDOMNode().classList.contains('MuiButton-containedPrimary')).toBe(true);
+    expect(btn.find('button').getDOMNode().classList.contains('MuiButton-containedPrimary')).toBe(true);
   });
 
   it('DefaultButton', ()=>{
     let ThemedBtn = withTheme(DefaultButton);
     let btn = mount(<ThemedBtn className="testClass">Test</ThemedBtn>);
-    expect(btn.getDOMNode().classList.contains('MuiButton-outlined')).toBe(true);
-    expect(btn.getDOMNode().classList.contains('testClass')).toBe(true);
+    expect(btn.find('button').getDOMNode().classList.contains('MuiButton-outlined')).toBe(true);
+    expect(btn.find('button').getDOMNode().classList.contains('testClass')).toBe(true);
   });
 
   it('PgIconButton', ()=>{
diff --git a/web/regression/javascript/components/TabPanel.spec.js b/web/regression/javascript/components/TabPanel.spec.js
index e99a062b4..1f1067860 100644
--- a/web/regression/javascript/components/TabPanel.spec.js
+++ b/web/regression/javascript/components/TabPanel.spec.js
@@ -37,12 +37,12 @@ describe('TabPanel', ()=>{
   });
 
   it('init', ()=>{
-    expect(panelInst.getDOMNode().hidden).toBeTrue();
+    expect(panelInst.find('div').at(0).getDOMNode().hidden).toBeTrue();
     expect(panelInst.find('h1')).not.toBe(null);
   });
 
   it('tab select', ()=>{
     panelInst.setProps({value: 0});
-    expect(panelInst.getDOMNode().hidden).toBeFalse();
+    expect(panelInst.find('div').at(0).getDOMNode().hidden).toBeFalse();
   });
 });
