diff --git a/docs/en_US/images/schema_diff_DDL_comparison.png b/docs/en_US/images/schema_diff_DDL_comparison.png
index 0c005b361d7057dc77e5fecf1a12223853c2198b..3ca8dba42a6625e0e3de9b98d4ed393425c6f459 100644
GIT binary patch
diff --git a/docs/en_US/images/schema_diff_compare_button.png b/docs/en_US/images/schema_diff_compare_button.png
index 2bef0396be9676eb006b8c8cc340a5ac2b3c8967..56df496730b0fe45aff9b35e6e6b1534dd83e1df 100644
GIT binary patch
diff --git a/docs/en_US/images/schema_diff_comparison_results.png b/docs/en_US/images/schema_diff_comparison_results.png
index 658e02c98b22d1fa160e7ac7678e544469d858dc..7e1c05d100d5999883b5b83acfb0c67136845e37 100644
GIT binary patch
diff --git a/docs/en_US/images/schema_diff_dialog.png b/docs/en_US/images/schema_diff_dialog.png
index 931e1452fe5a5cf75daba6a219cef32e3f07c84c..c7cfa5a7021fb292ddab7bae40555a811e6bc35f 100644
GIT binary patch
diff --git a/docs/en_US/images/schema_diff_filter_option.png b/docs/en_US/images/schema_diff_filter_option.png
index b7c203919036da60bda70c87928339d1a861173a..78d8a5b84f8fcb678f76fc56b46738c83c66aaf4 100644
GIT binary patch
diff --git a/docs/en_US/images/schema_diff_generate_script_query_editor.png b/docs/en_US/images/schema_diff_generate_script_query_editor.png
index 35675298e68ef203be8b48c7f0b413a4683bdb7c..bd0f1810fe080b0ddcc047e28d91cc3c2263abae 100644
GIT binary patch
diff --git a/web/karma.conf.js b/web/karma.conf.js
index 82f19b72..ac35838b 100644
--- a/web/karma.conf.js
+++ b/web/karma.conf.js
@@ -33,7 +33,6 @@ module.exports = function (config) {
       }),
     ],
     files: [
-      'pgadmin/static/bundle/slickgrid.js',
       {pattern: 'pgadmin/static/**/*.js', included: false, watched: true},
       {pattern: 'pgadmin/browser/static/js/**/*.js', included: false, watched: true},
       {pattern: 'regression/javascript/**/*.js', watched: true},
@@ -50,7 +49,6 @@ module.exports = function (config) {
     preprocessors: {
       'pgadmin/**/js/**/*.js?': ['sourcemap'],
       'regression/javascript/**/*.js': ['webpack', 'sourcemap'],
-      'pgadmin/static/bundle/slickgrid.js': ['webpack', 'sourcemap'],
     },
 
     // optionally, configure the reporter
diff --git a/web/package.json b/web/package.json
index fe8baf94..d70a5b87 100644
--- a/web/package.json
+++ b/web/package.json
@@ -163,7 +163,6 @@
     "react-window": "^1.8.5",
     "select2": "^4.0.13",
     "shim-loader": "^1.0.1",
-    "slickgrid": "git+https://github.com/6pac/SlickGrid.git#2.3.16",
     "snapsvg-cjs": "^0.0.6",
     "socket.io-client": "^4.0.0",
     "split.js": "^1.5.10",
diff --git a/web/pgadmin.themes.json b/web/pgadmin.themes.json
index 5fb853ad..5291ba00 100644
--- a/web/pgadmin.themes.json
+++ b/web/pgadmin.themes.json
@@ -1,4 +1,4 @@
-{
+ {
     "dark": {
         "disp_name": "dark_(Beta)",
         "cssfile": "pgadmin.theme.dark",
diff --git a/web/pgadmin/browser/static/js/frame.js b/web/pgadmin/browser/static/js/frame.js
index d130211b..8a153774 100644
--- a/web/pgadmin/browser/static/js/frame.js
+++ b/web/pgadmin/browser/static/js/frame.js
@@ -18,7 +18,7 @@ define([
   pgAdmin.Browser.Frame = function(options) {
     var defaults = [
       'name', 'title', 'width', 'height', 'showTitle', 'isCloseable',
-      'isPrivate', 'url', 'icon', 'onCreate', 'isLayoutMember',
+      'isPrivate', 'url', 'icon', 'onCreate', 'isLayoutMember', 'isRenamable',
     ];
     _.extend(this, _.pick(options, defaults));
   };
diff --git a/web/pgadmin/browser/templates/browser/index.html b/web/pgadmin/browser/templates/browser/index.html
index 54cff983..6d0f3c16 100644
--- a/web/pgadmin/browser/templates/browser/index.html
+++ b/web/pgadmin/browser/templates/browser/index.html
@@ -11,7 +11,7 @@
 {% block init_script %}
 try {
 require(
-['sources/generated/app.bundle', 'sources/generated/codemirror', 'sources/generated/browser_nodes', 'sources/generated/slickgrid'],
+['sources/generated/app.bundle', 'sources/generated/codemirror', 'sources/generated/browser_nodes'],
 function() {
 },
 function() {
diff --git a/web/pgadmin/static/bundle/slickgrid.js b/web/pgadmin/static/bundle/slickgrid.js
deleted file mode 100644
index 77393f6f..00000000
--- a/web/pgadmin/static/bundle/slickgrid.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import 'slickgrid/lib/jquery.event.drag-2.3.0';
-import 'slickgrid/slick.core';
-import 'slickgrid/slick.grid';
-import 'slickgrid/slick.dataview';
-import 'slickgrid/slick.editors';
-import 'slickgrid/slick.formatters';
-import 'slickgrid/slick.groupitemmetadataprovider';
-import 'slickgrid/plugins/slick.autotooltips';
-import 'slickgrid/plugins/slick.cellrangedecorator';
-import 'slickgrid/plugins/slick.cellrangeselector';
-import 'slickgrid/plugins/slick.checkboxselectcolumn';
-import 'slickgrid/plugins/slick.rowselectionmodel';
-import 'sources/slickgrid/custom_header_buttons';
-import 'sources/slickgrid/plugins/slick.autocolumnsize';
-
-export default window.Slick;
diff --git a/web/pgadmin/static/css/style.css b/web/pgadmin/static/css/style.css
index 26844fcc..bcea3456 100644
--- a/web/pgadmin/static/css/style.css
+++ b/web/pgadmin/static/css/style.css
@@ -14,10 +14,6 @@
 @import 'node_modules/codemirror/addon/dialog/dialog.css';
 @import 'node_modules/codemirror/addon/scroll/simplescrollbars.css';
 
-@import 'node_modules/slickgrid/slick.grid.css';
-@import 'node_modules/slickgrid/slick-default-theme.css';
-@import 'node_modules/slickgrid/css/smoothness/jquery-ui-1.11.3.custom.css';
-
 @import '../vendor/backgrid/backgrid.css';
 @import '../vendor/backgrid/backgrid-select-all.css';
 
diff --git a/web/pgadmin/static/js/Dialogs/RenamePanelContent.jsx b/web/pgadmin/static/js/Dialogs/RenamePanelContent.jsx
new file mode 100644
index 00000000..102f42ab
--- /dev/null
+++ b/web/pgadmin/static/js/Dialogs/RenamePanelContent.jsx
@@ -0,0 +1,115 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+
+import _ from 'lodash';
+import React, { useState, useRef, useEffect } from 'react';
+import PropTypes from 'prop-types';
+
+import { Box } from '@material-ui/core';
+import CloseIcon from '@material-ui/icons/CloseRounded';
+import CheckRoundedIcon from '@material-ui/icons/CheckRounded';
+
+import pgAdmin from 'sources/pgadmin';
+import gettext from 'sources/gettext';
+
+import { DefaultButton, PrimaryButton } from '../components/Buttons';
+import { useModalStyles } from '../helpers/ModalProvider';
+import { FormFooterMessage, InputText, MESSAGE_TYPE } from '../components/FormComponents';
+import { setDebuggerTitle } from '../../../tools/debugger/static/js/debugger_utils';
+import * as queryToolPanelTitleFunc from '../../../tools/sqleditor/static/js/sqleditor_title';
+import * as queryToolPanelViewDataFunc from '../../../tools/sqleditor/static/js/show_view_data';
+
+export default function RenamePanelContent({ closeModal, panel, title, preferences, setHeight, tabType, data }) {
+  const classes = useModalStyles();
+  const containerRef = useRef();
+  const firstEleRef = useRef();
+  const okBtnRef = useRef();
+  const [formData, setFormData] = useState({
+    title: title
+  });
+
+  const onTextChange = (e, id) => {
+    let val = e;
+    if (e && e.target) {
+      val = e.target.value;
+    }
+    setFormData((prev) => ({ ...prev, [id]: val }));
+  };
+
+  const onKeyDown = (e) => {
+    // If enter key is pressed then click on OK button
+    if (e.key === 'Enter') {
+      okBtnRef.current?.click();
+    }
+  };
+
+  useEffect(() => {
+    setTimeout(() => {
+      firstEleRef.current && firstEleRef.current.focus();
+    }, 350);
+  }, [firstEleRef.current]);
+
+  useEffect(() => {
+    setHeight?.(containerRef.current?.offsetHeight);
+  }, [containerRef.current, formData]);
+
+  return (
+    <Box display="flex" flexDirection="column" className={classes.container} ref={containerRef}>
+      <Box flexGrow="1" p={2}>
+
+        <Box marginTop='12px'>
+          <InputText inputRef={firstEleRef} type="text" value={formData['title']} controlProps={{ maxLength: null }}
+            onChange={(e) => onTextChange(e, 'title')} onKeyDown={(e) => onKeyDown(e)} />
+        </Box>
+
+        <FormFooterMessage type={MESSAGE_TYPE.ERROR} message={formData['title'].length == 0 ? gettext('Title cannot be empty') : ''} closable={false} style={{
+          position: 'unset', padding: '12px 0px 0px'
+        }} />
+      </Box>
+      <Box className={classes.footer}>
+        <DefaultButton data-test="close" startIcon={<CloseIcon />} onClick={() => {
+          closeModal();
+        }} >{gettext('Cancel')}</DefaultButton>
+        <PrimaryButton ref={okBtnRef} data-test="save" className={classes.margin} disabled={formData['title'].length == 0 ? true : false} startIcon={<CheckRoundedIcon />} onClick={() => {
+          if (tabType == 'debugger') {
+            setDebuggerTitle(panel, preferences, data.function_name, data.schema_name, data.database_name, _.escape(formData['title']), pgAdmin.Browser);
+          } else if (tabType == 'querytool') {
+            let selected_item = pgAdmin.Browser.tree.selected();
+            let panel_titles = '';
+
+            if (data.is_query_tool) {
+              panel_titles = queryToolPanelTitleFunc.getPanelTitle(pgAdmin.Browser, selected_item, formData['title']);
+            } else {
+              panel_titles = queryToolPanelViewDataFunc.generateViewDataTitle(pgAdmin.Browser, selected_item, formData['title']);
+            }
+            // Set title to the selected tab.
+            if (data.is_dirty_editor) {
+              panel_titles = panel_titles + ' *';
+            }
+            queryToolPanelTitleFunc.setQueryToolDockerTitle(panel, data.is_query_tool, panel_titles, data.is_file);
+          } else {
+            panel.title(_.escape(formData.title));
+          }
+          closeModal();
+        }} >{gettext('OK')}</PrimaryButton>
+      </Box>
+    </Box>
+  );
+}
+
+RenamePanelContent.propTypes = {
+  closeModal: PropTypes.func,
+  data: PropTypes.object,
+  setHeight: PropTypes.func,
+  panel: PropTypes.object,
+  title: PropTypes.string,
+  preferences: PropTypes.object,
+  tabType: PropTypes.string,
+  'panel.title': PropTypes.string,
+};
diff --git a/web/pgadmin/static/js/Dialogs/index.jsx b/web/pgadmin/static/js/Dialogs/index.jsx
index ae4f963b..ee2ca73d 100644
--- a/web/pgadmin/static/js/Dialogs/index.jsx
+++ b/web/pgadmin/static/js/Dialogs/index.jsx
@@ -22,6 +22,7 @@ import ChangePasswordContent from './ChangePasswordContent';
 import NamedRestoreContent from './NamedRestoreContent';
 import ChangeOwnershipContent from './ChangeOwnershipContent';
 import UrlDialogContent from './UrlDialogContent';
+import RenamePanelContent from './RenamePanelContent';
 
 function mountDialog(title, getDialogContent, docker=undefined, width, height) {
   // Register dialog panel
@@ -353,3 +354,29 @@ export function showUrlDialog() {
   { isFullScreen: false, isResizeable: true, showFullScreen: true, isFullWidth: true,
     dialogWidth: width || pgAdmin.Browser.stdW.md, dialogHeight: height || pgAdmin.Browser.stdH.md});
 }
+
+export function showRenamePanel() {
+  let title = arguments[0],
+    preferences = arguments[1],
+    panel = arguments[2],
+    tabType= arguments[3],
+    data= arguments[4];
+
+  mountDialog(gettext(`Rename Panel ${_.escape(title)}`), (onClose, setNewSize)=> {
+    return <Theme>
+      <RenamePanelContent
+        setHeight={(containerHeight)=>{
+          setNewSize(pgAdmin.Browser.stdW.md, containerHeight);
+        }}
+        closeModal={()=>{
+          onClose();
+        }}
+        panel={panel}
+        tabType={tabType}
+        title={title}
+        data={data}
+        preferences={preferences}
+      />
+    </Theme>;
+  });
+}
diff --git a/web/pgadmin/static/js/Theme/dark.js b/web/pgadmin/static/js/Theme/dark.js
index e36072a6..457550b3 100644
--- a/web/pgadmin/static/js/Theme/dark.js
+++ b/web/pgadmin/static/js/Theme/dark.js
@@ -103,6 +103,13 @@ export default function(basicSettings) {
       textMuted: '#8A8A8A',
       erdCanvasBg: '#303030',
       erdGridColor: '#444952',
+      schemaDiff: {
+        diffRowColor: '#807a48',
+        sourceRowColor: '#402025',
+        targetRowColor: '#6b5438',
+        diffColorFg: '#d4d4d4',
+        diffSelectFG: '#d4d4d4'
+      }
     }
   });
 }
diff --git a/web/pgadmin/static/js/Theme/high_contrast.js b/web/pgadmin/static/js/Theme/high_contrast.js
index 9c875737..482c2496 100644
--- a/web/pgadmin/static/js/Theme/high_contrast.js
+++ b/web/pgadmin/static/js/Theme/high_contrast.js
@@ -101,6 +101,13 @@ export default function(basicSettings) {
       textMuted: '#8b9cad',
       erdCanvasBg: '#010B15',
       erdGridColor: '#1F2932',
+      schemaDiff: {
+        diffRowColor: '#CFC56E',
+        sourceRowColor: '#EE97A5',
+        targetRowColor: '#FFAD65',
+        diffColorFg: '#FFFFFF',
+        diffSelectFG: '#010B15'
+      }
     }
   });
 }
diff --git a/web/pgadmin/static/js/Theme/standard.js b/web/pgadmin/static/js/Theme/standard.js
index 66e24ee3..1fea4e6b 100644
--- a/web/pgadmin/static/js/Theme/standard.js
+++ b/web/pgadmin/static/js/Theme/standard.js
@@ -121,6 +121,13 @@ export default function(basicSettings) {
           color: '#FFFFFF',
           bg: '#880000'
         },
+      },
+      schemaDiff: {
+        diffRowColor: '#fff9c4',
+        sourceRowColor: '#ffebee',
+        targetRowColor: '#fbe3bf',
+        diffColorFg: '#222',
+        diffSelectFG: '#222'
       }
     }
   });
diff --git a/web/pgadmin/static/js/components/Loader.jsx b/web/pgadmin/static/js/components/Loader.jsx
index 48dd7f95..fda2d3b0 100644
--- a/web/pgadmin/static/js/components/Loader.jsx
+++ b/web/pgadmin/static/js/components/Loader.jsx
@@ -37,6 +37,7 @@ const useStyles = makeStyles((theme)=>({
   },
   message: {
     marginLeft: '0.5rem',
+    fontSize: '16px',
   }
 }));
 
diff --git a/web/pgadmin/static/js/components/PgReactDataGrid.jsx b/web/pgadmin/static/js/components/PgReactDataGrid.jsx
index e37e5d36..7c2564c1 100644
--- a/web/pgadmin/static/js/components/PgReactDataGrid.jsx
+++ b/web/pgadmin/static/js/components/PgReactDataGrid.jsx
@@ -128,7 +128,7 @@ CustomRow.propTypes = {
 };
 
 export default function PgReactDataGrid({gridRef, className, hasSelectColumn=true, onItemEnter, onItemSelect,
-  onItemClick, noRowsText, ...props}) {
+  onItemClick, noRowsText, noRowsIcon,...props}) {
   const classes = useStyles();
   let finalClassName = [classes.root];
   hasSelectColumn && finalClassName.push(classes.hasSelectColumn);
@@ -142,7 +142,7 @@ export default function PgReactDataGrid({gridRef, className, hasSelectColumn=tru
         components={{
           sortIcon: CutomSortIcon,
           rowRenderer: CustomRow,
-          noRowsFallback: <Box textAlign="center" gridColumn="1/-1" p={1}>{noRowsText || gettext('No rows found.')}</Box>,
+          noRowsFallback: <Box textAlign="center" gridColumn="1/-1" p={1}>{noRowsIcon}{noRowsText || gettext('No rows found.')}</Box>,
         }}
         {...props}
       />
@@ -158,5 +158,6 @@ PgReactDataGrid.propTypes = {
   onItemEnter: PropTypes.func,
   onItemSelect: PropTypes.func,
   onItemClick: PropTypes.func,
-  noRowsText: PropTypes.string
+  noRowsText: PropTypes.string,
+  noRowsIcon: PropTypes.elementType
 };
diff --git a/web/pgadmin/static/js/helpers/Layout.jsx b/web/pgadmin/static/js/helpers/Layout.jsx
index 926904a2..fc0155b1 100644
--- a/web/pgadmin/static/js/helpers/Layout.jsx
+++ b/web/pgadmin/static/js/helpers/Layout.jsx
@@ -67,6 +67,12 @@ const useStyles = makeStyles((theme)=>({
       '& .dock-tabpane': {
         backgroundColor: theme.palette.background.default,
         color: theme.palette.text.primary,
+      },
+      '& #id-schema-diff': {
+        overflowY: 'auto'
+      },
+      '& #id-results': {
+        overflowY: 'auto'
       }
     },
     '& .dock-tab': {
diff --git a/web/pgadmin/static/js/selection/active_cell_capture.js b/web/pgadmin/static/js/selection/active_cell_capture.js
deleted file mode 100644
index 4d11269c..00000000
--- a/web/pgadmin/static/js/selection/active_cell_capture.js
+++ /dev/null
@@ -1,203 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-define([
-  'jquery',
-  'sources/selection/range_selection_helper',
-], function ($, RangeSelectionHelper) {
-
-  return function () {
-    var KEY_RIGHT = 39;
-    var KEY_LEFT = 37;
-    var KEY_UP = 38;
-    var KEY_DOWN = 40;
-
-    var bypassDefaultActiveCellRangeChange = false;
-    var isColumnsResized = false;
-    var isMouseInHeader = false;
-    var grid;
-
-    var init = function (slickGrid) {
-      grid = slickGrid;
-      grid.onDragEnd.subscribe(onDragEndHandler);
-      grid.onHeaderClick.subscribe(onHeaderClickHandler);
-      grid.onClick.subscribe(onClickHandler);
-      grid.onActiveCellChanged.subscribe(onActiveCellChangedHandler);
-      grid.onKeyDown.subscribe(onKeyDownHandler);
-      grid.onHeaderMouseEnter.subscribe(onHeaderMouseEnterHandler);
-      grid.onHeaderMouseLeave.subscribe(onHeaderMouseLeaveHandler);
-      grid.onColumnsResized.subscribe(onColumnsResizedHandler);
-    };
-
-    var destroy = function () {
-      grid.onDragEnd.unsubscribe(onDragEndHandler);
-      grid.onHeaderClick.unsubscribe(onHeaderClickHandler);
-      grid.onActiveCellChanged.unsubscribe(onActiveCellChangedHandler);
-      grid.onKeyDown.unsubscribe(onKeyDownHandler);
-      grid.onHeaderMouseEnter.unsubscribe(onHeaderMouseEnterHandler);
-      grid.onHeaderMouseLeave.unsubscribe(onHeaderMouseLeaveHandler);
-      grid.onColumnsResized.unsubscribe(onColumnsResizedHandler);
-    };
-
-    $.extend(this, {
-      'init': init,
-      'destroy': destroy,
-    });
-
-    function onDragEndHandler(event, dragData) {
-      bypassDefaultActiveCellRangeChange = true;
-      grid.setActiveCell(dragData.range.start.row, dragData.range.start.cell);
-    }
-
-    function onHeaderClickHandler(event, args) {
-      if (isColumnsResizedAndCurrentlyInHeader()) {
-        isColumnsResized = false;
-        event.stopPropagation();
-        return;
-      }
-
-      /* Skip if clicked on resize handler */
-      if($(event.target).hasClass('slick-resizable-handle')) {
-        return;
-      }
-
-      bypassDefaultActiveCellRangeChange = true;
-
-      var clickedColumn = args.column.pos + 1;
-      if (isClickingLastClickedHeader(0, clickedColumn)) {
-        if (isSingleRangeSelected()) {
-          grid.resetActiveCell();
-        } else {
-          grid.setActiveCell(0, retrievePreviousSelectedRange().fromCell);
-        }
-      } else if (!isClickingInSelectedColumn(clickedColumn)) {
-        grid.setActiveCell(0, clickedColumn);
-      }
-    }
-
-    function isEditableNewRow(row) {
-      return row >= grid.getDataLength();
-    }
-
-    function onHeaderMouseLeaveHandler() {
-      isMouseInHeader = false;
-    }
-
-    function onHeaderMouseEnterHandler() {
-      isMouseInHeader = true;
-      isColumnsResized = false;
-    }
-
-    function onColumnsResizedHandler() {
-      isColumnsResized = true;
-    }
-
-    function onClickHandler(event, args) {
-      if (isRowHeader(args.cell)) {
-        bypassDefaultActiveCellRangeChange = true;
-        var rowClicked = args.row;
-
-        if (isEditableNewRow(rowClicked)) {
-          return;
-        }
-
-        if (isClickingLastClickedHeader(rowClicked, 1)) {
-          if (isSingleRangeSelected() || grid.getSelectionModel().getSelectedRanges().length === 0) {
-            grid.resetActiveCell();
-          } else {
-            grid.setActiveCell(retrievePreviousSelectedRange().fromRow, 1);
-          }
-        } else if (!isClickingInSelectedRow(rowClicked)) {
-          grid.setActiveCell(rowClicked, 1);
-        }
-      }
-    }
-
-    function onActiveCellChangedHandler(event) {
-      if (bypassDefaultActiveCellRangeChange) {
-        bypassDefaultActiveCellRangeChange = false;
-        event.stopPropagation();
-      }
-    }
-
-    function onKeyDownHandler(event) {
-      if (hasActiveCell() && isShiftArrowKey(event)) {
-        selectOnlyRangeOfActiveCell();
-      }
-    }
-
-    function isColumnsResizedAndCurrentlyInHeader() {
-      return isMouseInHeader && isColumnsResized;
-    }
-
-    function isClickingLastClickedHeader(clickedRow, clickedColumn) {
-      return hasActiveCell() && grid.getActiveCell().row === clickedRow && grid.getActiveCell().cell === clickedColumn;
-    }
-
-    function isClickingInSelectedColumn(clickedColumn) {
-      var column = RangeSelectionHelper.rangeForColumn(grid, clickedColumn);
-      var cellSelectionModel = grid.getSelectionModel();
-      var ranges = cellSelectionModel.getSelectedRanges();
-      return RangeSelectionHelper.isRangeSelected(ranges, column);
-    }
-
-    function isRowHeader(cellClicked) {
-      return grid.getColumns()[cellClicked].id === 'row-header-column';
-    }
-
-    function isClickingInSelectedRow(rowClicked) {
-      var row = RangeSelectionHelper.rangeForRow(grid, rowClicked);
-      var cellSelectionModel = grid.getSelectionModel();
-      var ranges = cellSelectionModel.getSelectedRanges();
-      return RangeSelectionHelper.isRangeSelected(ranges, row);
-    }
-
-    function isSingleRangeSelected() {
-      var cellSelectionModel = grid.getSelectionModel();
-      var ranges = cellSelectionModel.getSelectedRanges();
-      return ranges.length === 1;
-    }
-
-    function retrievePreviousSelectedRange() {
-      var cellSelectionModel = grid.getSelectionModel();
-      var ranges = cellSelectionModel.getSelectedRanges();
-      return ranges[ranges.length - 2];
-    }
-
-    function isArrowKey(event) {
-      return event.which === KEY_RIGHT
-        || event.which === KEY_UP
-        || event.which === KEY_LEFT
-        || event.which === KEY_DOWN;
-    }
-
-    function isModifiedByShiftOnly(event) {
-      return event.shiftKey
-        && !event.ctrlKey
-        && !event.altKey;
-    }
-
-    function isShiftArrowKey(event) {
-      return isModifiedByShiftOnly(event) && isArrowKey(event);
-    }
-
-    function hasActiveCell() {
-      return !!grid.getActiveCell();
-    }
-
-    function selectOnlyRangeOfActiveCell() {
-      var cellSelectionModel = grid.getSelectionModel();
-      var ranges = cellSelectionModel.getSelectedRanges();
-
-      if (ranges.length > 1) {
-        cellSelectionModel.setSelectedRanges([ranges.pop()]);
-      }
-    }
-  };
-});
diff --git a/web/pgadmin/static/js/selection/column_selector.js b/web/pgadmin/static/js/selection/column_selector.js
deleted file mode 100644
index 12a7e68d..00000000
--- a/web/pgadmin/static/js/selection/column_selector.js
+++ /dev/null
@@ -1,164 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-define([
-  'jquery',
-  'sources/selection/range_selection_helper',
-  'slickgrid',
-], function ($, RangeSelectionHelper) {
-  return function () {
-    var Slick = window.Slick,
-      gridEventBus = new Slick.EventHandler(),
-      onBeforeColumnSelectAll = new Slick.Event(),
-      onColumnSelectAll = new Slick.Event();
-
-    var init = function (grid) {
-      gridEventBus.subscribe(grid.onHeaderClick, handleHeaderClick.bind(null, grid));
-      grid.getSelectionModel().onSelectedRangesChanged
-        .subscribe(handleSelectedRangesChanged.bind(null, grid));
-      onColumnSelectAll.subscribe(function(e, args) {
-        updateRanges(args.grid, args.column.id);
-      });
-    };
-
-    var handleHeaderClick = function (grid, event, args) {
-      var columnDefinition = args.column;
-
-      grid.focus();
-
-      if (isColumnSelectable(columnDefinition)) {
-        var $columnHeader = $(event.target);
-        if (hasClickedChildOfColumnHeader(event)) {
-          if ($(event.target).hasClass('slick-resizable-handle')) {
-            return;
-          }
-          $columnHeader = $(event.target).parents('.slick-header-column');
-        }
-        $columnHeader.toggleClass('selected');
-
-        if ($columnHeader.hasClass('selected')) {
-          onBeforeColumnSelectAll.notify(args, event);
-        }
-
-        if (!(event.isPropagationStopped() || event.isImmediatePropagationStopped())) {
-          updateRanges(grid, columnDefinition.id);
-        }
-      } else {
-        toggleColumnHeaderForCopyHeader(grid);
-      }
-    };
-
-    var toggleColumnHeaderForCopyHeader = function(grid) {
-      if(!$('.copy-with-header').hasClass('visibility-hidden')) {
-        var selRowCnt = grid.getSelectedRows();
-        $('.slick-header-column').each(function (index, columnHeader) {
-          if (selRowCnt.length == 0) {
-            $(columnHeader).removeClass('selected');
-            grid.getColumns()[index].selected = false;
-          }
-          else {
-            if (index > 0 && grid.getColumns()[index].selectable) {
-              $(columnHeader).addClass('selected');
-              grid.getColumns()[index].selected = true;
-            }
-          }
-
-        });
-      } else {
-        $('.slick-header-column').each(function (index, columnHeader) {
-          $(columnHeader).removeClass('selected');
-        });
-      }
-    }.bind(RangeSelectionHelper);
-
-    var handleSelectedRangesChanged = function (grid, event, selectedRanges) {
-      $('.slick-header-column').each(function (index, columnHeader) {
-        var $spanHeaderColumn = $(columnHeader).find('[data-cell-type="column-header-row"]');
-        var columnIndex = grid.getColumnIndex($spanHeaderColumn.data('column-id'));
-        if (isColumnSelected(grid, selectedRanges, columnIndex)) {
-          $(columnHeader).addClass('selected');
-          if (columnIndex) grid.getColumns()[columnIndex].selected = true;
-        } else if(!RangeSelectionHelper.areAllRangesCompleteRows(grid, selectedRanges)){
-          $(columnHeader).removeClass('selected');
-          if (columnIndex) grid.getColumns()[columnIndex].selected = false;
-        }
-      });
-    };
-
-    var updateRanges = function (grid, columnId) {
-      var selectionModel = grid.getSelectionModel();
-      var ranges = selectionModel.getSelectedRanges();
-
-      var columnIndex = grid.getColumnIndex(columnId);
-
-      var columnRange = RangeSelectionHelper.rangeForColumn(grid, columnIndex);
-      var newRanges;
-      if (RangeSelectionHelper.isRangeSelected(ranges, columnRange)) {
-        newRanges = RangeSelectionHelper.removeRange(ranges, columnRange);
-      } else {
-        if (RangeSelectionHelper.areAllRangesSingleColumns(ranges, grid)) {
-          newRanges = RangeSelectionHelper.addRange(ranges, columnRange);
-        } else {
-          newRanges = [columnRange];
-        }
-      }
-      selectionModel.setSelectedRanges(newRanges);
-    };
-
-    var hasClickedChildOfColumnHeader = function (event) {
-      return !$(event.target).hasClass('slick-header-column');
-    };
-
-    var isColumnSelectable = function (columnDefinition) {
-      return columnDefinition.selectable !== false;
-    };
-
-    var isColumnSelected = function (grid, selectedRanges, columnIndex) {
-      var allRangesAreRows = RangeSelectionHelper.areAllRangesCompleteRows(grid, selectedRanges);
-      return isAnyCellSelectedInColumn(grid, selectedRanges, columnIndex) && !allRangesAreRows;
-    };
-
-    var isAnyCellSelectedInColumn = function (grid, selectedRanges, columnIndex) {
-      var isStillSelected = RangeSelectionHelper.isRangeEntirelyWithinSelectedRanges(selectedRanges,
-        RangeSelectionHelper.rangeForColumn(grid, columnIndex));
-      var cellSelectedInColumn = RangeSelectionHelper.isAnyCellOfColumnSelected(selectedRanges, columnIndex);
-
-      return isStillSelected || cellSelectedInColumn;
-    };
-
-    var getColumnDefinitions = function (columnDefinitions) {
-      return _.map(columnDefinitions, function (columnDefinition) {
-        if (isColumnSelectable(columnDefinition)) {
-          var name =
-            '<span data-cell-type=\'column-header-row\' ' +
-            '       data-test=\'output-column-header\'' +
-            '       data-column-id=\'' + columnDefinition.id + '\'>' +
-            '  <span class=\'column-description\'>' +
-            '    <span class=\'column-name\'>' + columnDefinition.display_name + '</span>' +
-            '    <span class=\'column-type\'>' + columnDefinition.column_type + '</span>' +
-            '  </span>' +
-            '</span>';
-          return _.extend(columnDefinition, {
-            name: name,
-          });
-        } else {
-          return columnDefinition;
-        }
-      });
-    };
-
-    $.extend(this, {
-      'init': init,
-      'getColumnDefinitions': getColumnDefinitions,
-      'onBeforeColumnSelectAll': onBeforeColumnSelectAll,
-      'onColumnSelectAll': onColumnSelectAll,
-      'toggleColumnHeaderForCopyHeader': toggleColumnHeaderForCopyHeader,
-    });
-  };
-});
diff --git a/web/pgadmin/static/js/selection/copy_data.js b/web/pgadmin/static/js/selection/copy_data.js
deleted file mode 100644
index 97b30cd0..00000000
--- a/web/pgadmin/static/js/selection/copy_data.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-define([
-  'jquery',
-  'underscore',
-  'sources/selection/clipboard',
-  'sources/selection/range_selection_helper',
-  'sources/selection/range_boundary_navigator',
-],
-function ($, _, clipboard, RangeSelectionHelper, rangeBoundaryNavigator) {
-  var copyData = function () {
-    var self = this || window;
-
-    var grid = self.slickgrid;
-    var columnDefinitions = grid.getColumns();
-    var selectedRanges = grid.getSelectionModel().getSelectedRanges();
-    var dataView = grid.getData();
-    var rows = grid.getSelectedRows();
-    var CSVOptions = grid.CSVOptions;
-
-    if (RangeSelectionHelper.areAllRangesCompleteRows(grid, selectedRanges)) {
-      self.copied_rows = rows.map(function (rowIndex) {
-        return grid.getDataItem(rowIndex);
-      });
-      setPasteRowButtonEnablement(self.can_edit, true);
-    } else {
-      self.copied_rows = [];
-      setPasteRowButtonEnablement(self.can_edit, false);
-    }
-    var csvText = rangeBoundaryNavigator.rangesToCsv(dataView.getItems(), columnDefinitions,
-      selectedRanges, CSVOptions, copyWithHeader());
-    if (csvText) {
-      clipboard.copyTextToClipboard(csvText);
-    }
-  };
-
-  var copyWithHeader = function () {
-    return !$('.copy-with-header').hasClass('visibility-hidden');
-  };
-
-  var setPasteRowButtonEnablement = function (canEditFlag, isEnabled) {
-    if (canEditFlag) {
-      $('#btn-paste-row').prop('disabled', !isEnabled);
-      if(isEnabled && window.parent.$) {
-        // trigger copied event to all sessions
-        window.parent.$(window.parent.document).trigger('pgadmin-sqleditor:rows-copied', copyWithHeader());
-      }
-    }
-  };
-  return copyData;
-});
diff --git a/web/pgadmin/static/js/selection/grid_selector.js b/web/pgadmin/static/js/selection/grid_selector.js
deleted file mode 100644
index feb56a7d..00000000
--- a/web/pgadmin/static/js/selection/grid_selector.js
+++ /dev/null
@@ -1,92 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-define(['jquery',
-  'sources/gettext',
-  'sources/selection/column_selector',
-  'sources/selection/row_selector',
-  'sources/selection/range_selection_helper',
-  'sources/url_for',
-], function ($, gettext, ColumnSelector, RowSelector, RangeSelectionHelper, url_for) {
-  return function (columnDefinitions) {
-    var Slick = window.Slick,
-      rowSelector = new RowSelector(columnDefinitions),
-      columnSelector = new ColumnSelector(columnDefinitions),
-      onBeforeGridSelectAll = new Slick.Event(),
-      onGridSelectAll = new Slick.Event(),
-      onBeforeGridColumnSelectAll = columnSelector.onBeforeColumnSelectAll,
-      onGridColumnSelectAll = columnSelector.onColumnSelectAll;
-
-    var init = function (grid) {
-      this.grid = grid;
-      grid.onHeaderClick.subscribe(function (event, eventArguments) {
-        if (eventArguments.column.selectAllOnClick && !$(event.target).hasClass('slick-resizable-handle')) {
-          toggleSelectAll(grid, event, eventArguments);
-        }
-      });
-
-      grid.getSelectionModel().onSelectedRangesChanged
-        .subscribe(handleSelectedRangesChanged.bind(null, grid));
-
-      grid.registerPlugin(rowSelector);
-      grid.registerPlugin(columnSelector);
-
-      onGridSelectAll.subscribe(function(e, args) {
-        RangeSelectionHelper.selectAll(args.grid);
-      });
-    };
-
-    var getColumnDefinitions = function (columnDefinition) {
-      columnDefinition = columnSelector.getColumnDefinitions(columnDefinition);
-      columnDefinition = rowSelector.getColumnDefinitions(columnDefinition);
-
-      columnDefinition[0].selectAllOnClick = true;
-      columnDefinition[0].name = '<span data-id="select-all" ' +
-          'title="' + gettext('Select/Deselect All') + '">' +
-          '<br>' +
-          columnDefinition[0].name +
-          '<img class="select-all-icon" src="' + url_for('static', {'filename': 'img/select-all-icon.png'}) + '"></img>' +
-      '</span>';
-      return columnDefinition;
-    };
-
-    function handleSelectedRangesChanged(grid) {
-      if(RangeSelectionHelper.isEntireGridSelected(grid)) {
-        $('[data-id=\'select-all\']').addClass('selected');
-      } else {
-        $('[data-id=\'select-all\']').removeClass('selected');
-      }
-    }
-
-    function toggleSelectAll(grid, event, eventArguments) {
-      if (RangeSelectionHelper.isEntireGridSelected(grid)) {
-        selectNone(grid);
-      } else {
-        onBeforeGridSelectAll.notify(eventArguments, event);
-        if (!(event.isPropagationStopped() || event.isImmediatePropagationStopped())) {
-          RangeSelectionHelper.selectAll(grid);
-        }
-      }
-    }
-
-    function selectNone(grid) {
-      var selectionModel = grid.getSelectionModel();
-      selectionModel.setSelectedRanges([]);
-    }
-
-    $.extend(this, {
-      'init': init,
-      'getColumnDefinitions': getColumnDefinitions,
-      'onBeforeGridSelectAll': onBeforeGridSelectAll,
-      'onGridSelectAll': onGridSelectAll,
-      'onBeforeGridColumnSelectAll': onBeforeGridColumnSelectAll,
-      'onGridColumnSelectAll': onGridColumnSelectAll,
-    });
-  };
-});
diff --git a/web/pgadmin/static/js/selection/range_selection_helper.js b/web/pgadmin/static/js/selection/range_selection_helper.js
deleted file mode 100644
index 61d2032a..00000000
--- a/web/pgadmin/static/js/selection/range_selection_helper.js
+++ /dev/null
@@ -1,171 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-define(['slickgrid'], function () {
-  var Slick = window.Slick;
-
-  var isSameRange = function (range, otherRange) {
-    return range.fromCell == otherRange.fromCell && range.toCell == otherRange.toCell &&
-      range.fromRow == otherRange.fromRow && range.toRow == otherRange.toRow;
-  };
-
-  var isRangeSelected = function (selectedRanges, range) {
-    return _.any(selectedRanges, function (selectedRange) {
-      return isSameRange(selectedRange, range);
-    });
-  };
-
-  var isAnyCellOfColumnSelected = function (selectedRanges, column) {
-    return _.any(selectedRanges, function (selectedRange) {
-      return selectedRange.fromCell <= column && selectedRange.toCell >= column;
-    });
-  };
-
-  var isAnyCellOfRowSelected = function (selectedRanges, row) {
-    return _.any(selectedRanges, function (selectedRange) {
-      return selectedRange.fromRow <= row && selectedRange.toRow >= row;
-    });
-  };
-
-  var isRangeEntirelyWithinSelectedRanges = function (selectedRanges, range) {
-    return _.any(selectedRanges, function (selectedRange) {
-      return selectedRange.fromCell <= range.fromCell && selectedRange.toCell >= range.toCell &&
-        selectedRange.fromRow <= range.fromRow && selectedRange.toRow >= range.toRow;
-    });
-  };
-
-  var removeRange = function (selectedRanges, range) {
-    return _.filter(selectedRanges, function (selectedRange) {
-      return !(isSameRange(selectedRange, range));
-    });
-  };
-
-  var addRange = function (ranges, range) {
-    ranges.push(range);
-    return ranges;
-  };
-
-  var areAllRangesSingleRows = function (ranges, grid) {
-    return _.every(ranges, function (range) {
-      return range.fromRow == range.toRow && rangeHasCompleteRows(grid, range);
-    });
-  };
-
-  var areAllRangesSingleColumns = function (ranges, grid) {
-    return _.every(ranges, isRangeAColumn.bind(this, grid));
-  };
-
-  var rangeForRow = function (grid, rowId) {
-    var columnDefinitions = grid.getColumns();
-    if (isFirstColumnData(columnDefinitions)) {
-      return new Slick.Range(rowId, 0, rowId, grid.getColumns().length - 1);
-    }
-    return new Slick.Range(rowId, 1, rowId, grid.getColumns().length - 1);
-  };
-
-  var rangeForColumn = function (grid, columnIndex) {
-    return new Slick.Range(0, columnIndex, grid.getDataLength() - 1, columnIndex);
-  };
-
-  var getRangeOfWholeGrid = function (grid) {
-    return new Slick.Range(0, 1, grid.getDataLength() - 1, grid.getColumns().length - 1);
-  };
-
-  var isEntireGridSelected = function (grid) {
-    var selectionModel = grid.getSelectionModel();
-    var selectedRanges = selectionModel.getSelectedRanges();
-    return selectedRanges.length == 1 && isSameRange(selectedRanges[0], getRangeOfWholeGrid(grid));
-  };
-
-  var isFirstColumnData = function (columnDefinitions) {
-    return !_.isUndefined(columnDefinitions[0].pos);
-  };
-
-  var areAllRangesCompleteColumns = function (grid, ranges) {
-    return _.every(ranges, function (range) {
-      return rangeHasCompleteColumns(grid, range);
-    });
-  };
-
-  var areAllRangesCompleteRows = function (grid, ranges) {
-    return _.every(ranges, function (range) {
-      return rangeHasCompleteRows(grid, range);
-    });
-  };
-
-  var getIndexesOfCompleteRows = function (grid, ranges) {
-    var indexArray = [];
-    ranges.forEach(function (range) {
-      if (rangeHasCompleteRows(grid, range))
-        indexArray = indexArray.concat(_.range(range.fromRow, range.toRow + 1));
-    });
-
-    return indexArray;
-  };
-
-  var isRangeAColumn = function (grid, range) {
-    return range.fromCell == range.toCell &&
-      range.fromRow == 0 && range.toRow == grid.getDataLength() - 1;
-  };
-
-  var rangeHasCompleteColumns = function (grid, range) {
-    return range.fromRow === 0 && range.toRow === grid.getDataLength() - 1;
-  };
-
-  var rangeHasCompleteRows = function (grid, range) {
-    return range.fromCell === getFirstDataColumnIndex(grid) &&
-      range.toCell === getLastDataColumnIndex(grid);
-  };
-
-  function getFirstDataColumnIndex(grid) {
-    return _.findIndex(grid.getColumns(), function (columnDefinition) {
-      var pos = columnDefinition.pos;
-
-      return !_.isUndefined(pos) && isSelectable(columnDefinition);
-    });
-  }
-
-  function getLastDataColumnIndex(grid) {
-    return _.findLastIndex(grid.getColumns(), isSelectable);
-  }
-
-  function isSelectable(columnDefinition) {
-    return (_.isUndefined(columnDefinition.selectable) || columnDefinition.selectable === true);
-  }
-
-  function selectAll(grid) {
-    var range = getRangeOfWholeGrid(grid);
-    var selectionModel = grid.getSelectionModel();
-
-    selectionModel.setSelectedRanges([range]);
-  }
-
-  return {
-    addRange: addRange,
-    removeRange: removeRange,
-    isRangeSelected: isRangeSelected,
-    areAllRangesSingleRows: areAllRangesSingleRows,
-    areAllRangesSingleColumns: areAllRangesSingleColumns,
-    areAllRangesCompleteRows: areAllRangesCompleteRows,
-    areAllRangesCompleteColumns: areAllRangesCompleteColumns,
-    rangeForRow: rangeForRow,
-    rangeForColumn: rangeForColumn,
-    isEntireGridSelected: isEntireGridSelected,
-    getRangeOfWholeGrid: getRangeOfWholeGrid,
-    isFirstColumnData: isFirstColumnData,
-    getIndexesOfCompleteRows: getIndexesOfCompleteRows,
-    selectAll: selectAll,
-    isRangeAColumn: isRangeAColumn,
-    rangeHasCompleteColumns: rangeHasCompleteColumns,
-    rangeHasCompleteRows: rangeHasCompleteRows,
-    isAnyCellOfColumnSelected: isAnyCellOfColumnSelected,
-    isRangeEntirelyWithinSelectedRanges: isRangeEntirelyWithinSelectedRanges,
-    isAnyCellOfRowSelected: isAnyCellOfRowSelected,
-  };
-});
diff --git a/web/pgadmin/static/js/selection/row_selector.js b/web/pgadmin/static/js/selection/row_selector.js
deleted file mode 100644
index 32f6f2ac..00000000
--- a/web/pgadmin/static/js/selection/row_selector.js
+++ /dev/null
@@ -1,110 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-define([
-  'jquery',
-  'sources/selection/range_selection_helper',
-  'sources/selection/column_selector',
-  'slickgrid',
-], function ($, RangeSelectionHelper, ColumnSelector) {
-  return function () {
-    var Slick = window.Slick;
-
-    var gridEventBus = new Slick.EventHandler();
-    var columnSelector = new ColumnSelector();
-
-    var init = function (grid) {
-      grid.getSelectionModel().onSelectedRangesChanged
-        .subscribe(handleSelectedRangesChanged.bind(null, grid));
-      gridEventBus
-        .subscribe(grid.onClick, handleClick.bind(null, grid));
-    };
-
-    var handleClick = function (grid, event, args) {
-      if (grid.getColumns()[args.cell].id === 'row-header-column') {
-        var $rowHeaderSpan = $(event.target);
-
-        if ($rowHeaderSpan.data('cell-type') != 'row-header-selector') {
-          $rowHeaderSpan = $(event.target).find('[data-cell-type="row-header-selector"]');
-        }
-
-        $rowHeaderSpan.parent().toggleClass('selected');
-        updateRanges(grid, args.row);
-        columnSelector.toggleColumnHeaderForCopyHeader(grid);
-      }
-    };
-
-    var handleSelectedRangesChanged = function (grid, event, selectedRanges) {
-      $('[data-cell-type="row-header-selector"]').each(function (index, rowHeaderSpan) {
-        var $rowHeaderSpan = $(rowHeaderSpan);
-        var row = parseInt($rowHeaderSpan.data('row'));
-
-        if (isRowSelected(grid, selectedRanges, row)) {
-          $rowHeaderSpan.parent().addClass('selected');
-        } else {
-          $rowHeaderSpan.parent().removeClass('selected');
-        }
-      });
-    };
-
-    var updateRanges = function (grid, rowId) {
-      var selectionModel = grid.getSelectionModel();
-      var ranges = selectionModel.getSelectedRanges();
-
-      var rowRange = RangeSelectionHelper.rangeForRow(grid, rowId);
-
-      var newRanges;
-      if (RangeSelectionHelper.isRangeSelected(ranges, rowRange)) {
-        newRanges = RangeSelectionHelper.removeRange(ranges, rowRange);
-      } else {
-        if (RangeSelectionHelper.areAllRangesSingleRows(ranges, grid)) {
-          newRanges = RangeSelectionHelper.addRange(ranges, rowRange);
-        } else {
-          newRanges = [rowRange];
-        }
-      }
-      selectionModel.setSelectedRanges(newRanges);
-    };
-
-    var isAnyCellSelectedInRow = function (grid, selectedRanges, row) {
-      var isStillSelected = RangeSelectionHelper.isRangeEntirelyWithinSelectedRanges(selectedRanges,
-        RangeSelectionHelper.rangeForRow(grid, row));
-      var cellSelectedInRow = RangeSelectionHelper.isAnyCellOfRowSelected(selectedRanges, row);
-
-      return isStillSelected || cellSelectedInRow;
-    };
-
-    var isRowSelected = function (grid, selectedRanges, row) {
-      var allRangesAreColumns = RangeSelectionHelper.areAllRangesCompleteColumns(grid, selectedRanges);
-      return isAnyCellSelectedInRow(grid, selectedRanges, row) && !allRangesAreColumns;
-    };
-
-    var getColumnDefinitions = function (columnDefinitions) {
-      columnDefinitions.unshift({
-        id: 'row-header-column',
-        name: '',
-        selectable: false,
-        focusable: false,
-        formatter: function (rowIndex) {
-          return '<span ' +
-            'data-row="' + rowIndex + '" ' +
-            'data-cell-type="row-header-selector">' +
-            (rowIndex+1) + '</span>';
-        },
-        width: 30,
-      });
-      return columnDefinitions;
-    };
-
-    $.extend(this, {
-      'init': init,
-      'getColumnDefinitions': getColumnDefinitions,
-    });
-  };
-});
diff --git a/web/pgadmin/static/js/selection/xcell_selection_model.js b/web/pgadmin/static/js/selection/xcell_selection_model.js
deleted file mode 100644
index d544704a..00000000
--- a/web/pgadmin/static/js/selection/xcell_selection_model.js
+++ /dev/null
@@ -1,240 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-define([
-  'jquery',
-  'underscore',
-  'sources/selection/range_selection_helper',
-  'sources/window',
-  'slickgrid',
-], function ($, _, RangeSelectionHelper, pgWindow) {
-  return function (options) {
-
-    var KEY_ARROW_RIGHT = 39;
-    var KEY_ARROW_LEFT = 37;
-    var KEY_ARROW_UP = 38;
-    var KEY_ARROW_DOWN = 40;
-
-    var Slick = window.Slick;
-    var _grid;
-    var _ranges = [];
-    var _self = this;
-    var _selector = new Slick.CellRangeSelector({
-      selectionCss: {
-        border: '2px solid black',
-      },
-      offset: {
-        top: 0,
-        left: -1,
-        height: 2,
-        width: 1,
-      },
-    });
-    var _options;
-    var _defaults = {
-      selectActiveCell: true,
-    };
-
-
-    function init(grid) {
-      _options = $.extend(true, {}, _defaults, options);
-      _grid = grid;
-      _grid.onActiveCellChanged.subscribe(handleActiveCellChange);
-      _grid.onKeyDown.subscribe(handleKeyDown);
-      grid.registerPlugin(_selector);
-      _selector.onCellRangeSelected.subscribe(handleCellRangeSelected);
-      _selector.onBeforeCellRangeSelected.subscribe(handleBeforeCellRangeSelected);
-      $(pgWindow.default).on('mouseup',handleWindowMouseUp);
-    }
-
-    function destroy() {
-      _grid.onActiveCellChanged.unsubscribe(handleActiveCellChange);
-      _grid.onKeyDown.unsubscribe(handleKeyDown);
-      _selector.onCellRangeSelected.unsubscribe(handleCellRangeSelected);
-      _selector.onBeforeCellRangeSelected.unsubscribe(handleBeforeCellRangeSelected);
-      _grid.unregisterPlugin(_selector);
-      $(pgWindow.default).off('mouseup', handleWindowMouseUp);
-    }
-
-    function removeInvalidRanges(ranges) {
-      var result = [];
-
-      for (let range_val of ranges) {
-        var r = range_val;
-        if (_grid.canCellBeSelected(r.fromRow, r.fromCell) && _grid.canCellBeSelected(r.toRow, r.toCell)) {
-          result.push(r);
-        }
-      }
-
-      return result;
-    }
-
-    function setSelectedRanges(ranges) {
-      // simple check for: empty selection didn't change, prevent firing onSelectedRangesChanged
-      if ((!_ranges || _ranges.length === 0) && (!ranges || ranges.length === 0)) { return; }
-
-      _ranges = removeInvalidRanges(ranges);
-      _self.onSelectedRangesChanged.notify(_ranges);
-    }
-
-    function getSelectedRanges() {
-      return _ranges;
-    }
-
-    function setSelectedRows(rows) {
-      _ranges = [];
-
-      for(let row_val of rows) {
-        _ranges.push(RangeSelectionHelper.rangeForRow(_grid, row_val));
-      }
-    }
-
-    function handleBeforeCellRangeSelected(e) {
-      if (_grid.getEditorLock().isActive()) {
-        e.stopPropagation();
-        return false;
-      }
-    }
-
-    function handleCellRangeSelected(e, args) {
-      setSelectedRanges([args.range]);
-    }
-
-    function handleActiveCellChange(e, args) {
-      if (_options.selectActiveCell && args.row != null && args.cell != null) {
-        setSelectedRanges([new Slick.Range(args.row, args.cell)]);
-      }
-    }
-
-    function arrowKeyPressed(event) {
-      return event.which == KEY_ARROW_RIGHT
-        || event.which == KEY_ARROW_LEFT
-        || event.which == KEY_ARROW_UP
-        || event.which == KEY_ARROW_DOWN;
-    }
-
-    function shiftArrowKeyPressed(event) {
-      return event.shiftKey && !event.ctrlKey && !event.altKey &&
-        (arrowKeyPressed(event));
-    }
-
-    function needUpdateRange(newRange) {
-      return removeInvalidRanges([newRange]).length;
-    }
-
-    function handleKeyDown(e) {
-      var ranges;
-      var lastSelectedRange;
-      var anchorActiveCell = _grid.getActiveCell();
-
-      function isKey(key) { return e.which === key; }
-
-      function getKeycode() { return e.which; }
-
-      function shouldScrollToBottommostRow() { return anchorActiveCell.row === newSelectedRange.fromRow; }
-
-      function shouldScrollToRightmostColumn() { return anchorActiveCell.cell === newSelectedRange.fromCell; }
-
-      function getMobileCellFromRange(range, activeCell) {
-        var localMobileCell = {};
-
-        localMobileCell.row = range.fromRow === activeCell.row ? range.toRow : range.fromRow;
-        localMobileCell.cell = range.fromCell === activeCell.cell ? range.toCell : range.fromCell;
-
-        return localMobileCell;
-      }
-
-      function getNewRange(rangeCorner, oppositeCorner) {
-        var newFromCell = rangeCorner.cell <= oppositeCorner.cell ? rangeCorner.cell : oppositeCorner.cell;
-        var newToCell = rangeCorner.cell <= oppositeCorner.cell ? oppositeCorner.cell : rangeCorner.cell;
-
-        var newFromRow = rangeCorner.row <= oppositeCorner.row ? rangeCorner.row : oppositeCorner.row;
-        var newToRow = rangeCorner.row <= oppositeCorner.row ? oppositeCorner.row : rangeCorner.row;
-
-        return new Slick.Range(
-          newFromRow,
-          newFromCell,
-          newToRow,
-          newToCell
-        );
-      }
-
-      if (anchorActiveCell && shiftArrowKeyPressed(e)) {
-        ranges = getSelectedRanges();
-        if (!ranges.length) {
-          ranges.push(new Slick.Range(anchorActiveCell.row, anchorActiveCell.cell));
-        }
-
-        // keyboard can work with last range only
-        lastSelectedRange = ranges.pop();
-
-        // can't handle selection out of active cell
-        if (!lastSelectedRange.contains(anchorActiveCell.row, anchorActiveCell.cell)) {
-          lastSelectedRange = new Slick.Range(anchorActiveCell.row, anchorActiveCell.cell);
-        }
-
-        var mobileCell = getMobileCellFromRange(lastSelectedRange, anchorActiveCell);
-
-        switch (getKeycode()) {
-        case KEY_ARROW_LEFT:
-          mobileCell.cell -= 1;
-          break;
-        case KEY_ARROW_RIGHT:
-          mobileCell.cell += 1;
-          break;
-        case KEY_ARROW_UP:
-          mobileCell.row -= 1;
-          break;
-        case KEY_ARROW_DOWN:
-          mobileCell.row += 1;
-          break;
-        }
-
-        var newSelectedRange = getNewRange(anchorActiveCell, mobileCell);
-
-        if (needUpdateRange(newSelectedRange)) {
-          var rowToView = shouldScrollToBottommostRow() ? newSelectedRange.toRow : newSelectedRange.fromRow;
-          var columnToView = shouldScrollToRightmostColumn() ? newSelectedRange.toCell : newSelectedRange.fromCell;
-
-          if (isKey(KEY_ARROW_RIGHT) || isKey(KEY_ARROW_LEFT)) {
-            _grid.scrollColumnIntoView(columnToView);
-          } else if (isKey(KEY_ARROW_UP) || isKey(KEY_ARROW_DOWN)) {
-            _grid.scrollRowIntoView(rowToView);
-          }
-          ranges.push(newSelectedRange);
-        } else {
-          ranges.push(lastSelectedRange);
-        }
-
-        setSelectedRanges(ranges);
-
-        e.preventDefault();
-        e.stopPropagation();
-      }
-    }
-
-    function handleWindowMouseUp() {
-      var selectedRange = _selector.getCurrentRange();
-      if (!_.isUndefined(selectedRange)) {
-        _grid.onDragEnd.notify({range: selectedRange});
-      }
-    }
-
-    $.extend(this, {
-      'getSelectedRanges': getSelectedRanges,
-      'setSelectedRanges': setSelectedRanges,
-      'setSelectedRows': setSelectedRows,
-
-      'init': init,
-      'destroy': destroy,
-
-      'onSelectedRangesChanged': new Slick.Event(),
-    });
-  };
-});
diff --git a/web/pgadmin/static/js/slickgrid/cell_selector.js b/web/pgadmin/static/js/slickgrid/cell_selector.js
deleted file mode 100644
index 9d7288b6..00000000
--- a/web/pgadmin/static/js/slickgrid/cell_selector.js
+++ /dev/null
@@ -1,27 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-define(['slickgrid'], function () {
-  var Slick = window.Slick;
-
-  return function () {
-    this.init = function (grid) {
-      grid.onActiveCellChanged.subscribe(function (event, slickEvent) {
-        grid.getSelectionModel().setSelectedRanges([
-          new Slick.Range(
-            slickEvent.row,
-            slickEvent.cell,
-            slickEvent.row,
-            slickEvent.cell
-          ),
-        ]);
-      });
-    };
-  };
-});
diff --git a/web/pgadmin/static/js/slickgrid/custom_header_buttons.js b/web/pgadmin/static/js/slickgrid/custom_header_buttons.js
deleted file mode 100644
index a74ae419..00000000
--- a/web/pgadmin/static/js/slickgrid/custom_header_buttons.js
+++ /dev/null
@@ -1,189 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-(function ($) {
-  // register namespace
-  $.extend(true, window, {
-    'Slick': {
-      'Plugins': {
-        'HeaderButtons': HeaderButtons,
-      },
-    },
-  });
-
-
-  /***
-   * custom header button modified from slick.headerbuttons.js
-   *
-   * USAGE:
-   *
-   * Add the plugin .js & .css files and register it with the grid.
-   *
-   * To specify a custom button in a column header, extend the column definition like so:
-   *
-   *   var columns = [
-   *     {
-   *       id: 'myColumn',
-   *       name: 'My column',
-   *
-   *       // This is the relevant part
-   *       header: {
-   *          buttons: [
-   *              {
-   *                // button options
-   *              },
-   *              {
-   *                // button options
-   *              }
-   *          ]
-   *       }
-   *     }
-   *   ];
-   *
-   * Available button options:
-   *    cssClass:     CSS class to add to the button.
-   *    image:        Relative button image path.
-   *    tooltip:      Button tooltip.
-   *    showOnHover:  Only show the button on hover.
-   *    handler:      Button click handler.
-   *    command:      A command identifier to be passed to the onCommand event handlers.
-   *
-   * The plugin exposes the following events:
-   *    onCommand:    Fired on button click for buttons with 'command' specified.
-   *        Event args:
-   *            grid:     Reference to the grid.
-   *            column:   Column definition.
-   *            command:  Button command identified.
-   *            button:   Button options.  Note that you can change the button options in your
-   *                      event handler, and the column header will be automatically updated to
-   *                      reflect them.  This is useful if you want to implement something like a
-   *                      toggle button.
-   *
-   *
-   * @param options {Object} Options:
-   *    buttonCssClass:   a CSS class to use for buttons (default 'slick-header-button')
-   * @class Slick.Plugins.HeaderButtons
-   * @constructor
-   */
-  function HeaderButtons(options) {
-    var _grid;
-    var _self = this;
-    var _handler = new window.Slick.EventHandler();
-    var _defaults = {
-      buttonCssClass: 'slick-header-button',
-    };
-
-
-    function init(grid) {
-      options = $.extend(true, {}, _defaults, options);
-      _grid = grid;
-      _handler
-        .subscribe(_grid.onHeaderCellRendered, handleHeaderCellRendered)
-        .subscribe(_grid.onBeforeHeaderCellDestroy, handleBeforeHeaderCellDestroy);
-
-      // Force the grid to re-render the header now that the events are hooked up.
-      _grid.setColumns(_grid.getColumns());
-    }
-
-
-    function destroy() {
-      _handler.unsubscribeAll();
-    }
-
-
-    function handleHeaderCellRendered(e, args) {
-      var column = args.column;
-
-      if (column.header && column.header.buttons) {
-        // Append buttons in reverse order since they are floated to the right.
-        var i = column.header.buttons.length;
-        while (i--) {
-          var button = column.header.buttons[i];
-          var btn = $('<div></div>')
-            .addClass(options.buttonCssClass)
-            .data('column', column)
-            .data('button', button);
-
-          if (button.content){
-            btn.append(button.content);
-          }
-
-          if (button.showOnHover) {
-            btn.addClass('slick-header-button-hidden');
-          }
-
-          if (button.image) {
-            btn.css('backgroundImage', 'url(' + button.image + ')');
-          }
-
-          if (button.cssClass) {
-            btn.addClass(button.cssClass);
-          }
-
-          if (button.tooltip) {
-            btn.attr('title', button.tooltip);
-          }
-
-          if (button.command) {
-            btn.data('command', button.command);
-          }
-
-          if (button.handler) {
-            btn.bind('click', button.handler);
-          }
-
-          btn
-            .bind('click', handleButtonClick)
-            .prependTo(args.node);
-        }
-      }
-    }
-
-
-    function handleBeforeHeaderCellDestroy(e, args) {
-      var column = args.column;
-
-      if (column.header && column.header.buttons) {
-        // Removing buttons via jQuery will also clean up any event handlers and data.
-        // NOTE: If you attach event handlers directly or using a different framework,
-        //       you must also clean them up here to avoid memory leaks.
-        $(args.node).find('.' + options.buttonCssClass).remove();
-      }
-    }
-
-
-    function handleButtonClick(e) {
-      var command = $(this).data('command');
-      var columnDef = $(this).data('column');
-      var button = $(this).data('button');
-
-      if (command != null) {
-        _self.onCommand.notify({
-          'grid': _grid,
-          'column': columnDef,
-          'command': command,
-          'button': button,
-        }, e, _self);
-
-        // Update the header in case the user updated the button definition in the handler.
-        _grid.updateColumnHeader(columnDef.id);
-      }
-
-      // Stop propagation so that it doesn't register as a header click event.
-      e.preventDefault();
-      e.stopPropagation();
-    }
-
-    $.extend(this, {
-      'init': init,
-      'destroy': destroy,
-      'onCommand': new window.Slick.Event(),
-    });
-  }
-})(window.jQuery);
diff --git a/web/pgadmin/static/js/slickgrid/editors.js b/web/pgadmin/static/js/slickgrid/editors.js
deleted file mode 100644
index 16846622..00000000
--- a/web/pgadmin/static/js/slickgrid/editors.js
+++ /dev/null
@@ -1,1085 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-/***
- * Contains JSON SlickGrid editors.
- * @module Editors
- * @namespace Slick
- */
-
-import JSONBigNumberLib from 'json-bignumber';
-import gettext from 'sources/gettext';
-import Notify from '../../../static/js/helpers/Notifier';
-
-(function($, JSONBigNumber) {
-  // register namespace
-  $.extend(true, window, {
-    'Slick': {
-      'Editors': {
-        'pgText': pgTextEditor,
-        'JsonText': JsonTextEditor,
-        'CustomNumber': CustomNumberEditor,
-        'Checkbox': pgCheckboxEditor,
-        // Below editor will read only editors, Just to display data
-        'ReadOnlyText': ReadOnlyTextEditor,
-        'ReadOnlyCheckbox': ReadOnlyCheckboxEditor,
-        'ReadOnlypgText': ReadOnlypgTextEditor,
-        'ReadOnlyJsonText': ReadOnlyJsonTextEditor,
-      },
-    },
-  });
-
-  // return wrapper element
-  function getWrapper() {
-    return $('<div class=\'pg-text-editor\' />');
-  }
-
-  // return textarea element
-  function getTextArea() {
-    return $('<textarea class=\'pg-textarea text-12\' hidefocus rows=5\'>');
-  }
-
-  // return json editor element
-  function getJsonEditor() {
-    return $('<div id=\'pg-json-editor\' hidefocus>');
-  }
-
-  // Generate and return editor buttons
-  function getButtons(editable) {
-    var $buttons = $('<div class=\'pg_buttons\' />'),
-      label = editable ? gettext('Cancel') : gettext('OK'),
-      button_type = editable ? 'btn-secondary' : 'btn-primary',
-      button_icon = editable ? 'fa-times' : 'fa-check';
-
-    $('<button class=\'btn ' + button_type + ' long_text_editor pg-alertify-button\' data-label="'+label+'">' +
-    '<span class="fa '+ button_icon +' pg-alertify-button"></span>&nbsp;'+ label +
-    '</button>')
-      .appendTo($buttons);
-
-    if (editable) {
-      $('<button class=\'btn btn-primary long_text_editor\' data-label="' + gettext('OK') + '">'+
-        '<span class="fa fa-check pg-alertify-button"></span>&nbsp;' + gettext('OK') +
-        '</button>')
-        .appendTo($buttons);
-    }
-    return $buttons;
-  }
-
-  function is_valid_array(val) {
-    val = $.trim(val);
-    return !(val != '' && (val.charAt(0) != '{' || val.charAt(val.length - 1) != '}'));
-  }
-  /*
-   * This function handles the [default] and [null] values for cells
-   * if row is copied, otherwise returns the editor value.
-   * @param {args} editor object
-   * @param {item} row cell values
-   * @param {state} entered value
-   * @param {column_type} type of column
-   */
-  function setValue(args, item, state, column_type) {
-    // declare a 2-d array which tracks the status of each updated cell
-    // If a cell is edited for the 1st time and state is null,
-    // set cell value to [default] and update its status [row][cell] to 1.
-    // If same cell is edited again, and kept blank, set cell value to [null]
-
-    // If a row is copied
-    var grid = args.grid;
-    if (item.is_row_copied) {
-      if (!grid.copied_rows) {
-        grid.copied_rows = [
-          [],
-        ];
-      }
-
-      var active_cell = grid.getActiveCell(),
-        row = active_cell['row'],
-        cell = active_cell['cell'],
-        last_value = item[args.column.pos];
-
-      last_value = (column_type === 'number') ?
-        (_.isEmpty(last_value) || last_value) : last_value;
-
-      item[args.column.field] = state;
-      if (last_value && _.isNull(state) &&
-        (_.isUndefined(grid.copied_rows[row]) ||
-          _.isUndefined(grid.copied_rows[row][cell]))
-      ) {
-        item[args.column.field] = undefined;
-        if (grid.copied_rows[row] == undefined) grid.copied_rows[row] = [];
-        grid.copied_rows[row][cell] = 1;
-      }
-    } else {
-      if(column_type === 'jsonb' && state != null) {
-        item[args.column.field] = JSONBigNumber.stringify(JSONBigNumber.parse(state));
-      } else {
-        item[args.column.field] = state;
-      }
-    }
-  }
-
-  function calculateEditorPosition(position, $wrapper) {
-    var $edit_grid = $wrapper.parent().find('#datagrid');
-
-    position.top = position.top - $wrapper.height();
-
-    var grid_width = $edit_grid.width(),
-      popup_width = $wrapper.width() + 32;
-    popup_width += position.left;
-
-    if (popup_width > grid_width) {
-      position.left -= (popup_width - grid_width);
-    }
-    return position;
-  }
-
-  // Text data type editor
-  function pgTextEditor(args) {
-    var $input, $wrapper, $buttons;
-    var defaultValue;
-    var scope = this;
-
-    this.init = function() {
-      var $container = $('body');
-
-      $wrapper = getWrapper().appendTo($container);
-      $input = getTextArea().appendTo($wrapper);
-      $buttons = getButtons(true).appendTo($wrapper);
-
-      $buttons.find('button:first').on('click', this.cancel);
-      $buttons.find('button:last').on('click', this.save);
-      $input.on('keydown', this.handleKeyDown);
-
-      scope.position(args.position);
-      $input.trigger('focus').trigger('select');
-    };
-
-    this.handleKeyDown = function(e) {
-      if (e.which == $.ui.keyCode.ENTER && e.ctrlKey) {
-        scope.save();
-      } else if (e.which == $.ui.keyCode.ESCAPE) {
-        e.preventDefault();
-        scope.cancel();
-      } else if (e.which == $.ui.keyCode.TAB && e.shiftKey) {
-        e.preventDefault();
-        args.grid.navigatePrev();
-      } else if (e.which == $.ui.keyCode.TAB) {
-        e.preventDefault();
-        args.grid.navigateNext();
-      }
-    };
-
-    this.save = function() {
-      args.commitChanges();
-    };
-
-    this.cancel = function() {
-      $input.val(defaultValue);
-      args.cancelChanges();
-    };
-
-    this.hide = function() {
-      $wrapper.hide();
-    };
-
-    this.show = function() {
-      $wrapper.show();
-    };
-
-    this.position = function(position) {
-      calculateEditorPosition(position, $wrapper);
-      $wrapper
-        .css('top', position.top)
-        .css('left', position.left);
-    };
-
-    this.destroy = function() {
-      $wrapper.remove();
-    };
-
-    this.focus = function() {
-      $input.trigger('focus');
-    };
-
-    // When text editor opens
-    this.loadValue = function(item) {
-      if (
-        _.isUndefined(item[args.column.field]) ||
-        _.isNull(item[args.column.field])
-      ) {
-        $input.val(defaultValue = '');
-        return;
-      }
-
-      if (!args.column.is_array) {
-        if (item[args.column.field] === '') {
-          $input.val(defaultValue = '\'\'');
-          $input.trigger('select');
-        } else if (item[args.column.field] === '\'\'') {
-          $input.val(defaultValue = '\\\'\\\'');
-        } else if (item[args.column.field] === '""') {
-          $input.val(defaultValue = '\\"\\"');
-        } else {
-          $input.val(defaultValue = item[args.column.field]);
-          $input.trigger('select');
-        }
-      } else {
-        $input.val(defaultValue = item[args.column.field]);
-        $input.trigger('select');
-      }
-    };
-
-    this.serializeValue = function() {
-
-      var value = $input.val();
-      // If empty return null
-      if (value === '') {
-        return null;
-      }
-
-      if (!args.column.is_array) {
-        if (value === '\'\'' || value === '""') {
-          return '';
-        } else if (value === '\\\'\\\'') {
-          return '\'\'';
-        } else if (value === '\\"\\"') {
-          return '""';
-        } else {
-          return value;
-        }
-      } else {
-        return $.trim(value);
-      }
-    };
-
-    this.applyValue = function(item, state) {
-      setValue(args, item, state, 'text');
-    };
-
-    this.isValueChanged = function() {
-      // Use _.isNull(value) for comparison for null instead of
-      // defaultValue == null, because it returns true for undefined value.
-      if ($input.val() == '' && _.isUndefined(defaultValue)) {
-        return false;
-      } else {
-        return (!($input.val() == '' && _.isNull(defaultValue))) &&
-          ($input.val() !== defaultValue);
-      }
-    };
-
-    this.validate = function() {
-      if (args.column.validator) {
-        var validationResults = args.column.validator($input.val());
-        if (!validationResults.valid) {
-          return validationResults;
-        }
-      }
-
-      if (args.column.is_array && !is_valid_array($input.val())) {
-        return {
-          valid: false,
-          msg: gettext('Arrays must start with "{" and end with "}"'),
-        };
-      }
-
-      return {
-        valid: true,
-        msg: null,
-      };
-    };
-
-    this.init();
-  }
-
-  // JSON data type editor
-  function JsonTextEditor(args) {
-    var $input, $wrapper, $buttons, $editor;
-    var defaultValue, tmpdata;
-    var scope = this;
-    var editorInitialized = false;
-
-    this.init = function() {
-      var $container = $('body');
-
-      $wrapper = getWrapper().appendTo($container);
-      $input = getJsonEditor().appendTo($wrapper);
-      $buttons = getButtons(true).appendTo($wrapper);
-
-      $buttons.find('button:first').on('click', this.cancel);
-      $buttons.find('button:last').on('click', this.save);
-      $input.on('keydown', this.handleKeyDown);
-
-      scope.position(args.position);
-    };
-
-    this.handleKeyDown = function(e) {
-      if (e.which == $.ui.keyCode.ENTER && e.ctrlKey) {
-        scope.save();
-      } else if (e.which == $.ui.keyCode.ESCAPE) {
-        e.preventDefault();
-        scope.cancel();
-      }
-    };
-
-    this.resizeJsoneditorObserver = new ResizeObserver(() => {
-      if ($editor){
-        $editor.resize();
-      }
-    });
-
-    this.save = function() {
-      args.commitChanges();
-    };
-
-    this.cancel = function() {
-      args.cancelChanges();
-    };
-
-    this.hide = function() {
-      $wrapper.hide();
-    };
-
-    this.show = function() {
-      $wrapper.show();
-    };
-
-    this.position = function(position) {
-      calculateEditorPosition(position, $wrapper);
-      position.top = Math.max(position.top, 0);
-      $wrapper
-        .css('top', position.top)
-        .css('left', position.left);
-    };
-
-    this.destroy = function() {
-      this.resizeJsoneditorObserver.unobserve(document.getElementById('pg-json-editor'));
-      $editor.destroy();
-      $wrapper.remove();
-    };
-
-    this.focus = function() {
-      $editor.focus();
-    };
-
-    this.loadValue = function(item) {
-      var data = defaultValue = item[args.column.field];
-      /* Can be useful until JSON editor loads */
-      tmpdata = data;
-
-      /* If jsonb or array */
-      if(args.column.column_type_internal === 'jsonb' && !Array.isArray(data) && data != null) {
-        data = JSONBigNumber.stringify(JSONBigNumber.parse(data), null, 2);
-      } else if (Array.isArray(data)) {
-        var temp = [];
-        $.each(data, function(i, val) {
-          if (typeof val === 'object') {
-            temp.push(JSONBigNumber.stringify(val, null, 2));
-          } else {
-            temp.push(val);
-          }
-        });
-        data = '[' + temp.join() + ']';
-      }
-      /* set editor content to empty if value is null*/
-      if (_.isNull(data)){
-        defaultValue = '';
-        data = '';
-      }
-
-      /* Create editor if required & set data*/
-      if ($editor){
-        $editor.setText(data);
-        $editor.focus();
-      }else{
-        editorInitialized = true;
-        require.ensure(['jsoneditor'], function(require) {
-          var JSONEditor = require('jsoneditor');
-          var jsonContainer = document.getElementById('pg-json-editor');
-          var options = {
-            modes: ['code', 'form', 'tree','preview'],
-            onError: function (error){
-              var msg = 'Invalid Json: ' + error.message.split(':')[0];
-              Notify.error(gettext(msg));
-            }
-          };
-          $editor = new JSONEditor(jsonContainer, options);
-          $editor.setText(data);
-          $editor.focus();
-        }, function(error){
-          throw(error);
-        }, 'jsoneditorchunk');
-      }
-      this.resizeJsoneditorObserver.observe(document.getElementById('pg-json-editor'));
-    };
-
-    this.serializeValue = function() {
-      /* Create editor if data is null/new data entry */
-      if( !editorInitialized) {
-        require.ensure(['jsoneditor'], function(require) {
-          var JSONEditor = require('jsoneditor');
-          var jsonContainer = document.getElementById('pg-json-editor');
-          var options = {
-            modes: ['code', 'form', 'tree','preview'],
-            onError: function (error){
-              var msg = 'Invalid Json: ' + error.message.split(':')[0];
-              Notify.error(gettext(msg));
-            }
-          };
-          if(jsonContainer) {
-            $editor = new JSONEditor(jsonContainer, options);
-            var data = '';
-            $editor.setText(data);
-            $editor.focus();
-            return null;
-          }
-        }, function(error){
-          throw(error);
-        }, 'jsoneditorchunk');}
-
-      if($editor){
-        let data = $editor.getText();
-        if (data === '') {
-          return null;
-        }
-        return data;
-      }else{
-        // The loader is not loaded yet ?
-        return tmpdata;
-      }
-    };
-
-    this.applyValue = function(item, state){
-      if(args.column.column_type_internal === 'jsonb') {
-        setValue(args, item, state, 'jsonb');
-      } else {
-        setValue(args, item, state, 'text');
-      }
-    };
-
-    this.isValueChanged = function() {
-      let data = $editor.getText();
-      if (data == '' && (_.isUndefined(defaultValue) || _.isNull(defaultValue) )) {
-        return false;
-      } else {
-        if( args.column.column_type_internal === 'jsonb' && (! _.isUndefined(defaultValue) && defaultValue != '')){
-          defaultValue = JSON.stringify(JSON.parse(defaultValue), null,2);
-        }
-        return (!( data == '' && _.isNull(defaultValue)) && (data != defaultValue));
-      }
-    };
-
-    this.validate = function() {
-      if(args.column.column_type_internal === 'jsonb' ||
-          args.column.column_type_internal === 'json') {
-        let data = $editor.getText();
-        try {
-          if(data != ''){
-            JSON.parse(data);
-          }
-        } catch(e) {
-          $input.addClass('pg-text-invalid');
-          return {
-            valid: false,
-            msg: e.message,
-          };
-        }
-      }
-      return {
-        valid: true,
-        msg: null,
-      };
-    };
-
-    this.init();
-  }
-
-  // Text data type editor
-  function ReadOnlypgTextEditor(args) {
-    var $input, $wrapper, $buttons;
-    var defaultValue;
-    var scope = this;
-
-    this.init = function() {
-      var $container = $('body');
-
-      $wrapper = getWrapper().appendTo($container);
-      $input = getTextArea().appendTo($wrapper);
-      $buttons = getButtons(false).appendTo($wrapper);
-
-      $buttons.find('button:first').on('click', this.cancel);
-      $input.on('keydown', this.handleKeyDown);
-
-      scope.position(args.position);
-      $input.trigger('focus').trigger('select');
-    };
-
-    this.handleKeyDown = function(e) {
-      if (e.which == $.ui.keyCode.ENTER && e.ctrlKey) {
-        scope.cancel();
-      } else if (e.which == $.ui.keyCode.ESCAPE) {
-        e.preventDefault();
-        scope.cancel();
-      } else if (e.which == $.ui.keyCode.TAB && e.shiftKey) {
-        scope.cancel();
-        e.preventDefault();
-        args.grid.navigatePrev();
-      } else if (e.which == $.ui.keyCode.TAB) {
-        scope.cancel();
-        e.preventDefault();
-        args.grid.navigateNext();
-      }
-    };
-
-    this.cancel = function() {
-      $input.val(defaultValue);
-      args.cancelChanges();
-    };
-
-    this.hide = function() {
-      $wrapper.hide();
-    };
-
-    this.show = function() {
-      $wrapper.show();
-    };
-
-    this.position = function(position) {
-      calculateEditorPosition(position, $wrapper);
-      $wrapper
-        .css('top', position.top)
-        .css('left', position.left);
-    };
-
-    this.destroy = function() {
-      $wrapper.remove();
-    };
-
-    this.focus = function() {
-      $input.trigger('focus');
-    };
-
-    this.loadValue = function(item) {
-      $input.val(defaultValue = item[args.column.field]);
-      $input.trigger('select');
-    };
-
-    this.serializeValue = function() {
-      return $input.val();
-    };
-
-    this.applyValue = function(item, state) {
-      item[args.column.field] = state;
-    };
-
-    this.isValueChanged = function() {
-      return (!($input.val() == '' && defaultValue == null)) && ($input.val() != defaultValue);
-    };
-
-    this.validate = function() {
-      if (args.column.validator) {
-        var validationResults = args.column.validator($input.val());
-        if (!validationResults.valid) {
-          return validationResults;
-        }
-      }
-
-      return {
-        valid: true,
-        msg: null,
-      };
-    };
-
-    this.init();
-  }
-
-  // JSON data type editor
-  function ReadOnlyJsonTextEditor(args) {
-    var $input, $wrapper, $buttons, $editor;
-    var defaultValue;
-    var scope = this;
-    var tmpdata;
-
-    this.init = function() {
-      var $container = $('body');
-
-      $wrapper = getWrapper().appendTo($container);
-      $input = getJsonEditor().appendTo($wrapper);
-      $buttons = getButtons(false).appendTo($wrapper);
-
-      $buttons.find('button:first').on('click', this.cancel);
-      $input.on('keydown', this.handleKeyDown);
-
-      scope.position(args.position);
-    };
-
-    this.handleKeyDown = function(e) {
-      if (e.which == $.ui.keyCode.ENTER && e.ctrlKey) {
-        scope.cancel();
-      } else if (e.which == $.ui.keyCode.ESCAPE) {
-        e.preventDefault();
-        scope.cancel();
-      }
-    };
-
-    this.cancel = function() {
-      $input.val(defaultValue);
-      args.cancelChanges();
-    };
-
-    this.hide = function() {
-      $wrapper.hide();
-    };
-
-    this.show = function() {
-      $wrapper.show();
-    };
-
-    this.position = function(position) {
-      calculateEditorPosition(position, $wrapper);
-      position.top = Math.max(position.top, 0);
-      $wrapper
-        .css('top', position.top)
-        .css('left', position.left);
-    };
-
-    this.destroy = function() {
-      this.resizeJsoneditorObserver.unobserve(document.getElementById('pg-json-editor'));
-      $editor.destroy();
-      $wrapper.remove();
-    };
-
-    this.focus = function() {
-      $editor.focus();
-    };
-
-    // listen to resize event for json editor
-    this.resizeJsoneditorObserver = new ResizeObserver(() => {
-      if ($editor){
-        $editor.resize();
-      }
-    });
-
-    this.loadValue = function(item) {
-      var data = defaultValue = item[args.column.field];
-      tmpdata = data;
-      if(args.column.column_type_internal === 'jsonb' && !Array.isArray(data) && data != null) {
-        data = JSONBigNumber.stringify(JSONBigNumber.parse(data), null, 2);
-      } else if (Array.isArray(data)) {
-        var temp = [];
-        $.each(data, function(i, val) {
-          if (typeof val === 'object') {
-            temp.push(JSONBigNumber.stringify(val, null,2));
-          } else {
-            temp.push(val);
-          }
-        });
-        data = '[' + temp.join() + ']';
-      }
-
-      /* set editor content to empty if value is null*/
-      if (_.isNull(data)){
-        defaultValue = '';
-        data = '';
-      }
-      /* Create editor if required & set data*/
-      require.ensure(['jsoneditor'], function(require) {
-        var JSONEditor = require('jsoneditor');
-        var jsonContainer = document.getElementById('pg-json-editor');
-        jsonContainer.setAttribute('readonly', true);
-        let options = {
-          modes: ['code', 'form',  'tree', 'preview'],
-          onEditable: function() {
-            return false;
-          }
-        };
-        if(jsonContainer) {
-          $editor = new JSONEditor(jsonContainer, options);
-          $editor.setText(data);
-        }
-      }, function(error){
-        throw(error);
-      }, 'jsoneditorchunk');
-      this.resizeJsoneditorObserver.observe(document.getElementById('pg-json-editor'));
-    };
-
-    this.serializeValue = function() {
-      if($editor) {
-        let data = $editor.getText();
-        if (data === '') {
-          return null;
-        }
-        return data;
-      } else {
-        // The loader is not loaded yet ?
-        return tmpdata;
-      }
-    };
-
-    this.applyValue = function(item, state) {
-      item[args.column.field] = state;
-    };
-
-    this.isValueChanged = function() {
-      let data = $editor.getText();
-      return (!(data == '' && defaultValue == null)) && (data != defaultValue);
-    };
-
-    this.validate = function() {
-      if (args.column.validator) {
-        var validationResults = args.column.validator($editor.getText());
-        if (!validationResults.valid) {
-          return validationResults;
-        }
-      }
-
-      return {
-        valid: true,
-        msg: null,
-      };
-    };
-
-    this.init();
-  }
-
-  function ReadOnlyTextEditor(args) {
-    var $input;
-    var defaultValue;
-
-    this.init = function() {
-      $input = $('<input type=text class=\'editor-text\' readonly/>')
-        .appendTo(args.container)
-        .on('keydown.nav', function(e) {
-          if (e.keyCode === $.ui.keyCode.LEFT || e.keyCode === $.ui.keyCode.RIGHT) {
-            e.stopImmediatePropagation();
-          }
-        })
-        .trigger('focus')
-        .trigger('select');
-    };
-
-    this.destroy = function() {
-      $input.remove();
-    };
-
-    this.focus = function() {
-      $input.trigger('focus');
-    };
-
-    this.getValue = function() {
-      return $input.val();
-    };
-
-    this.loadValue = function(item) {
-      var value = item[args.column.field];
-
-      // Check if value is null or undefined
-      if (value === null || typeof value === 'undefined') {
-        value = '';
-      }
-      defaultValue = value;
-      $input.val(defaultValue);
-      $input[0].defaultValue = defaultValue;
-      $input.trigger('select');
-    };
-
-    this.serializeValue = function() {
-      return $input.val();
-    };
-
-    this.applyValue = function(item, state) {
-      item[args.column.field] = state;
-    };
-
-    this.isValueChanged = function() {
-      return (!($input.val() == '' && defaultValue == null)) && ($input.val() != defaultValue);
-    };
-
-    this.validate = function() {
-      if (args.column.validator) {
-        var validationResults = args.column.validator($input.val());
-        if (!validationResults.valid) {
-          return validationResults;
-        }
-      }
-
-      return {
-        valid: true,
-        msg: null,
-      };
-    };
-
-    this.init();
-  }
-
-  function ReadOnlyCheckboxEditor(args) {
-    var $select;
-    var defaultValue;
-
-    this.init = function() {
-      $select = $('<input type=checkbox value=\'true\' class=\'editor-checkbox\' hideFocus disabled>');
-      $select.appendTo(args.container);
-      $select.trigger('focus');
-    };
-
-    this.destroy = function() {
-      $select.remove();
-    };
-
-    this.focus = function() {
-      $select.trigger('focus');
-    };
-
-    this.loadValue = function(item) {
-      defaultValue = item[args.column.pos];
-      if (_.isNull(defaultValue) || _.isUndefined(defaultValue)) {
-        $select.prop('indeterminate', true);
-        $select.data('checked', 2);
-      } else {
-        defaultValue = !!item[args.column.pos];
-        if (defaultValue) {
-          $select.prop('checked', true);
-          $select.data('checked', 0);
-        } else {
-          $select.prop('checked', false);
-          $select.data('checked', 1);
-        }
-      }
-    };
-
-    this.serializeValue = function() {
-      if ($select.prop('indeterminate')) {
-        return null;
-      }
-      return $select.prop('checked');
-    };
-
-    this.applyValue = function(item, state) {
-      item[args.column.pos] = state;
-    };
-
-    this.isValueChanged = function() {
-      var select_value = $select.data('checked');
-      return (!(select_value === 2 && (defaultValue == null || defaultValue == undefined))) &&
-        (select_value !== defaultValue);
-    };
-
-    this.validate = function() {
-      return {
-        valid: true,
-        msg: null,
-      };
-    };
-
-    this.init();
-  }
-
-  function CustomNumberEditor(args) {
-    var $input;
-    var defaultValue;
-
-    this.init = function() {
-      $input = $('<input type=text class=\'editor-text\' />');
-
-      $input.on('keydown.nav', function(e) {
-        if (e.keyCode === $.ui.keyCode.LEFT || e.keyCode === $.ui.keyCode.RIGHT) {
-          e.stopImmediatePropagation();
-        }
-      });
-
-      $input.appendTo(args.container);
-      $input.trigger('focus').trigger('select');
-    };
-
-    this.destroy = function() {
-      $input.remove();
-    };
-
-    this.focus = function() {
-      $input.trigger('focus');
-    };
-
-    this.loadValue = function(item) {
-      defaultValue = item[args.column.field];
-
-      if (Array.isArray(defaultValue) && !_.isNull(defaultValue) && !_.isUndefined(defaultValue)) {
-        $input.val('{' + defaultValue.join() + '}');
-      } else {
-        $input.val(defaultValue);
-      }
-
-      $input[0].defaultValue = defaultValue;
-      $input.trigger('select');
-    };
-
-    this.serializeValue = function() {
-      var value = $input.val();
-
-      if (value === '') {
-        return null;
-      }
-
-      return value;
-    };
-
-    this.applyValue = function(item, state) {
-      setValue(args, item, state, 'number');
-    };
-
-    this.isValueChanged = function() {
-      if ($input.val() == '' && _.isUndefined(defaultValue)) {
-        return false;
-      } else if ($input.val() == '' && defaultValue == '') {
-        return true;
-      } else {
-        return (!($input.val() == '' && _.isNull(defaultValue))) &&
-          ($input.val() != defaultValue);
-      }
-    };
-
-    this.validate = function() {
-      var value = $input.val();
-      if (!args.column.is_array && isNaN(value)) {
-        return {
-          valid: false,
-          msg: gettext('Please enter a valid number'),
-        };
-      }
-      if (args.column.validator) {
-        var validationResults = args.column.validator(value);
-        if (!validationResults.valid) {
-          return validationResults;
-        }
-      }
-
-      if (args.column.is_array) {
-        if (!is_valid_array(value)) {
-          return {
-            valid: false,
-            msg: gettext('Arrays must start with "{" and end with "}"'),
-          };
-        }
-
-        var val = value.trim().slice(1, -1),
-          arr;
-
-        if (val == '') {
-          arr = [];
-        } else {
-          arr = val.split(',');
-        }
-
-        for (var k in arr) {
-          if (isNaN(arr[k])) {
-            return {
-              valid: false,
-              msg: gettext('Please enter a valid number'),
-            };
-          }
-        }
-      }
-
-      return {
-        valid: true,
-        msg: null,
-      };
-    };
-
-    this.init();
-  }
-
-  // Custom checkbox editor, We need it for runtime as it does not render
-  // indeterminate checkbox state
-  function pgCheckboxEditor(args) {
-    var $select;
-    var defaultValue, previousState;
-
-    this.init = function() {
-      $select = $('<div class=\'multi-checkbox\' tabindex="0"><span class=\'check\' hideFocus></span></div>');
-      $select.appendTo(args.container);
-      $select.trigger('focus');
-
-      $select.on('click', this.changeValue);
-
-      $select.on('keydown', (e) => {
-        if (e.which == $.ui.keyCode.SPACE) {
-          e.preventDefault();
-          this.changeValue(e);
-        }
-      });
-    };
-
-    this.changeValue = function() {
-      // The following code is taken from https://css-tricks.com/indeterminate-checkboxes/
-      var states = ['unchecked', 'partial', 'checked'];
-      var curState = $select.find('.check').data('state') || 0;
-      curState++;
-      $select.find('.check')
-        .removeClass('unchecked partial checked')
-        .addClass(states[curState % states.length])
-        .data('state', curState % states.length);
-    };
-
-    this.destroy = function() {
-      $select.remove();
-    };
-
-    this.focus = function() {
-      $select.trigger('focus');
-    };
-
-    this.loadValue = function(item) {
-      defaultValue = item[args.column.field];
-      previousState = 1;
-      if (_.isNull(defaultValue) || _.isUndefined(defaultValue)) {
-        $select.find('.check').data('state', 1).addClass('partial');
-      } else {
-        defaultValue = !!item[args.column.field];
-        if (defaultValue) {
-          $select.find('.check').data('state', 2).addClass('checked');
-          previousState = 2;
-        } else {
-          $select.find('.check').data('state', 0).addClass('unchecked');
-          previousState = 0;
-        }
-      }
-    };
-
-    this.serializeValue = function() {
-      if ($select.find('.check').data('state') == 1) {
-        return null;
-      }
-      return $select.find('.check').data('state') == 2 ? true : false;
-    };
-
-    this.applyValue = function(item, state) {
-      item[args.column.field] = state;
-    };
-
-    this.isValueChanged = function() {
-      var currentState = $select.find('.check').data('state');
-      return currentState !== previousState;
-    };
-
-    this.validate = function() {
-      if (args.column.validator) {
-        var validationResults = args.column.validator(this.serializeValue());
-        if (!validationResults.valid) {
-          return validationResults;
-        }
-      }
-      return {
-        valid: true,
-        msg: null,
-      };
-    };
-
-    this.init();
-  }
-
-})(window.jQuery, JSONBigNumberLib);
diff --git a/web/pgadmin/static/js/slickgrid/event_handlers/handle_query_output_keyboard_event.js b/web/pgadmin/static/js/slickgrid/event_handlers/handle_query_output_keyboard_event.js
deleted file mode 100644
index 99482723..00000000
--- a/web/pgadmin/static/js/slickgrid/event_handlers/handle_query_output_keyboard_event.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-define([
-  'sources/selection/copy_data',
-  'sources/selection/range_selection_helper',
-],
-function (copyData, RangeSelectionHelper) {
-  return function handleQueryOutputKeyboardEvent(event, args) {
-    var KEY_C = 67;
-    var KEY_A = 65;
-    var modifiedKey = event.keyCode;
-    var isModifierDown = event.ctrlKey || event.metaKey;
-    var self = this || window;
-    self.slickgrid = args.grid;
-
-    if (isModifierDown && modifiedKey == KEY_C) {
-      copyData.apply(self);
-    }
-
-    if (isModifierDown && modifiedKey == KEY_A) {
-      RangeSelectionHelper.selectAll(self.slickgrid);
-    }
-  };
-});
diff --git a/web/pgadmin/static/js/slickgrid/formatters.js b/web/pgadmin/static/js/slickgrid/formatters.js
deleted file mode 100644
index f18e3a7f..00000000
--- a/web/pgadmin/static/js/slickgrid/formatters.js
+++ /dev/null
@@ -1,132 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-/***
- * Contains pgAdmin4 related SlickGrid formatters.
- *
- * @module Formatters
- * @namespace Slick
- */
-
-(function($) {
-  // register namespace
-  $.extend(true, window, {
-    'Slick': {
-      'Formatters': {
-        'JsonString': JsonFormatter,
-        'Numbers': NumbersFormatter,
-        'Checkmark': CheckmarkFormatter,
-        'Text': TextFormatter,
-        'Binary': BinaryFormatter,
-      },
-    },
-  });
-
-  function NullAndDefaultFormatter(row, cell, value, columnDef) {
-    if (_.isUndefined(value) && columnDef.has_default_val) {
-      return '<span class=\'pull-left disabled_cell\'>[default]</span>';
-    } else if (
-      (_.isUndefined(value) && columnDef.not_null) ||
-      (_.isUndefined(value) || value === null)
-    ) {
-      return '<span class=\'pull-left disabled_cell\'>[null]</span>';
-    }
-    return null;
-  }
-
-  function NullAndDefaultNumberFormatter(row, cell, value, columnDef) {
-    if (_.isUndefined(value) && columnDef.has_default_val) {
-      return '<span class=\'pull-right disabled_cell\'>[default]</span>';
-    } else if (
-      (_.isUndefined(value) && columnDef.not_null) ||
-      (_.isUndefined(value) || value === null)
-    ) {
-      return '<span class=\'pull-right disabled_cell\'>[null]</span>';
-    }
-    return null;
-  }
-
-  function JsonFormatter(row, cell, value, columnDef) {
-    // If column has default value, set placeholder
-    var data = NullAndDefaultFormatter(row, cell, value, columnDef);
-    if (data) {
-      return data;
-    } else {
-      // Stringify only if it's json object
-      if (typeof value === 'object' && !Array.isArray(value)) {
-        return _.escape(JSON.stringify(value));
-      } else if (Array.isArray(value)) {
-        var temp = [];
-        $.each(value, function(i, val) {
-          if (typeof val === 'object') {
-            temp.push(JSON.stringify(val));
-          } else {
-            temp.push(val);
-          }
-        });
-        return _.escape('[' + temp.join() + ']');
-      } else {
-        return _.escape(value);
-      }
-    }
-  }
-
-  function NumbersFormatter(row, cell, value, columnDef) {
-    // If column has default value, set placeholder
-    var data = NullAndDefaultNumberFormatter(row, cell, value, columnDef);
-    if (data) {
-      return data;
-    } else {
-      return '<span style=\'float:right\'>' + _.escape(value) + '</span>';
-    }
-  }
-
-  function CheckmarkFormatter(row, cell, value, columnDef) {
-    /* Checkbox has 3 states
-     * 1) checked=true
-     * 2) unchecked=false
-     * 3) indeterminate=null
-     */
-    var data = NullAndDefaultFormatter(row, cell, value, columnDef);
-    if (data) {
-      return data;
-    } else {
-      return value ? 'true' : 'false';
-    }
-  }
-
-  function TextFormatter(row, cell, value, columnDef) {
-    // If column has default value, set placeholder
-    var raw = NullAndDefaultFormatter(row, cell, value, columnDef);
-
-    var data;
-    if (raw) {
-      data = raw;
-    } else {
-      data = _.escape(value);
-    }
-
-    // Replace leading whitespace with a marker so we don't just show blank lines
-    if (data.trimStart() != data) {
-      data = '[...] ' + data.trimStart();
-    }
-
-    return data;
-  }
-
-  function BinaryFormatter(row, cell, value, columnDef) {
-    // If column has default value, set placeholder
-    var data = NullAndDefaultFormatter(row, cell, value, columnDef);
-    if (data) {
-      return data;
-    } else {
-      return '<span class=\'pull-left disabled_cell\'>[' + _.escape(value) + ']</span>';
-    }
-  }
-})(window.jQuery);
diff --git a/web/pgadmin/static/js/slickgrid/plugins/slick.autocolumnsize.js b/web/pgadmin/static/js/slickgrid/plugins/slick.autocolumnsize.js
deleted file mode 100644
index 7e76deb1..00000000
--- a/web/pgadmin/static/js/slickgrid/plugins/slick.autocolumnsize.js
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * https://github.com/naresh-n/slickgrid-column-data-autosize
- */
-
-(function($) {
-
-  $.extend(true, window, {
-    'Slick': {
-      'AutoColumnSize': AutoColumnSize,
-    },
-  });
-
-  function AutoColumnSize() {
-
-    var grid, $container, context,
-      keyCodes = {
-        'A': 65,
-      };
-
-    function init(_grid) {
-      grid = _grid;
-
-      $container = $(grid.getContainerNode());
-      $container.on('dblclick.autosize', '.slick-resizable-handle', reSizeColumn);
-      $container.keydown(handleControlKeys);
-
-      context = document.createElement('canvas').getContext('2d');
-      // Expose resizeAllColumns method to call from outside of this file.
-      grid.resizeAllColumns = resizeAllColumns;
-    }
-
-    function destroy() {
-      $container.off();
-    }
-
-    function handleControlKeys(event) {
-      if (event.ctrlKey && event.shiftKey && event.keyCode === keyCodes.A) {
-        resizeAllColumns();
-      }
-    }
-
-    function resizeAllColumns(maxWidth, max_width_changed=false) {
-      var elHeaders = $container.find('.slick-header-column');
-      var allColumns = grid.getColumns();
-      elHeaders.each(function(index, el) {
-        var columnDef = $(el).data('column');
-        // Check if width is set then no need to resize that column.
-        if (typeof(columnDef.width) !== 'undefined' && !isNaN(columnDef.width) && !max_width_changed) {
-          return;
-        }
-
-        var headerWidth = getElementWidth(el);
-        var colIndex = grid.getColumnIndex(columnDef.id);
-        var column = allColumns[colIndex];
-        var autoSizeWidth = Math.max(headerWidth, getMaxColumnTextWidth(columnDef, colIndex)) + 1;
-        // If max width is provided and it is greater than 0
-        if (typeof(maxWidth) !== 'undefined' && maxWidth > 0) {
-          autoSizeWidth = Math.min(maxWidth, autoSizeWidth);
-        }
-        column.width = autoSizeWidth + (columnDef.addWidth || 0);
-      });
-      grid.setColumns(allColumns);
-      grid.onColumnsResized.notify();
-    }
-
-    function reSizeColumn(e) {
-      var headerEl = $(e.currentTarget).closest('.slick-header-column');
-      var columnDef = headerEl.data('column');
-
-      if (!columnDef || !columnDef.resizable) {
-        return;
-      }
-
-      e.preventDefault();
-      e.stopPropagation();
-
-      var headerWidth = getElementWidth(headerEl[0]);
-      var colIndex = grid.getColumnIndex(columnDef.id);
-      var allColumns = grid.getColumns();
-      var column = allColumns[colIndex];
-
-      var autoSizeWidth = Math.max(headerWidth, getMaxColumnTextWidth(columnDef, colIndex)) + 1;
-
-      if (autoSizeWidth !== column.width) {
-        column.width = autoSizeWidth;
-        grid.setColumns(allColumns);
-        grid.onColumnsResized.notify();
-      }
-    }
-
-    function getMaxColumnTextWidth(columnDef, colIndex) {
-      var texts = [];
-      var rowEl = createRow();
-      var data = grid.getData();
-      if (window.Slick.Data && data instanceof window.Slick.Data.DataView) {
-        data = data.getItems();
-      }
-      for (let data_val of data) {
-        texts.push(data_val[columnDef.field]);
-      }
-      var template = getMaxTextTemplate(texts, columnDef, colIndex, data, rowEl);
-      var width = getTemplateWidth(rowEl, template);
-      deleteRow(rowEl);
-      return width;
-    }
-
-    function getTemplateWidth(rowEl, template) {
-      var cell = $(rowEl.find('.slick-cell'));
-      cell.append(template);
-      cell.find('*').css('position', 'relative');
-      return cell.outerWidth() + 1;
-    }
-
-    function getMaxTextTemplate(texts, columnDef, colIndex, data, rowEl) {
-      var max = 0,
-        maxTemplate = null;
-      var formatFun = columnDef.formatter;
-      $(texts).each(function(index, text) {
-        var template;
-        if (formatFun) {
-          template = $('<span>' + formatFun(index, colIndex, text, columnDef, data[index]) + '</span>');
-          text = template.text() || text;
-        }
-        var length = text ? getElementWidthUsingCanvas(rowEl, text) : 0;
-        if (length > max) {
-          max = length;
-          maxTemplate = template || text;
-        }
-      });
-      return maxTemplate;
-    }
-
-    function createRow() {
-      var rowEl = $('<div class="slick-row"><div class="slick-cell"></div></div>');
-      rowEl.find('.slick-cell').css({
-        'visibility': 'hidden',
-        'text-overflow': 'initial',
-        'white-space': 'nowrap',
-      });
-      var gridCanvas = $container.find('.grid-canvas').first();
-      $(gridCanvas).append(rowEl);
-      return rowEl;
-    }
-
-    function deleteRow(rowEl) {
-      $(rowEl).remove();
-    }
-
-    function getElementWidth(element) {
-      var width, clone = element.cloneNode(true);
-      clone.style.cssText = 'position: absolute; visibility: hidden;right: auto;text-overflow: initial;white-space: nowrap;';
-      element.parentNode.insertBefore(clone, element);
-      width = clone.offsetWidth;
-      clone.parentNode.removeChild(clone);
-      return width;
-    }
-
-    function getElementWidthUsingCanvas(element, text) {
-      context.font = element.css('font-size') + ' ' + element.css('font-family');
-      var metrics = context.measureText(text);
-      return metrics.width;
-    }
-
-    return {
-      init: init,
-      destroy: destroy,
-    };
-  }
-}(window.jQuery));
diff --git a/web/pgadmin/static/scss/_pgadmin.style.scss b/web/pgadmin/static/scss/_pgadmin.style.scss
index ea131dc4..f2fe85be 100644
--- a/web/pgadmin/static/scss/_pgadmin.style.scss
+++ b/web/pgadmin/static/scss/_pgadmin.style.scss
@@ -833,18 +833,6 @@ body {
   font-size: inherit !important;
 }
 
-/* CSS for custom checkbox editor in SlickGrid */
-.multi-checkbox .check {
-  display: inline-block;
-  vertical-align: top;
-  width: 16px;
-  height: 16px;
-  border: 1px solid  $color-gray-dark;
-  margin: 3px;
-  text-align: center;
-  line-height: 16px;
-}
-
 .multi-checkbox .check.checked,
 .multi-checkbox .check.unchecked {
   background: $color-bg;
diff --git a/web/pgadmin/static/scss/_slickgrid.overrides.scss b/web/pgadmin/static/scss/_slickgrid.overrides.scss
deleted file mode 100644
index 5b530ac3..00000000
--- a/web/pgadmin/static/scss/_slickgrid.overrides.scss
+++ /dev/null
@@ -1,83 +0,0 @@
-.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 892b370a..2abb70f1 100644
--- a/web/pgadmin/static/scss/pgadmin.scss
+++ b/web/pgadmin/static/scss/pgadmin.scss
@@ -34,6 +34,5 @@ $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/debugger/static/js/DebuggerModule.js b/web/pgadmin/tools/debugger/static/js/DebuggerModule.js
index 2911c6fb..68ef75bf 100644
--- a/web/pgadmin/tools/debugger/static/js/DebuggerModule.js
+++ b/web/pgadmin/tools/debugger/static/js/DebuggerModule.js
@@ -16,7 +16,6 @@ import gettext from 'sources/gettext';
 import { sprintf, registerDetachEvent } from 'sources/utils';
 import url_for from 'sources/url_for';
 import pgWindow from 'sources/window';
-import alertify from 'pgadmin.alertifyjs';
 import Kerberos from 'pgadmin.authenticate.kerberos';
 
 import { refresh_db_node } from 'tools/sqleditor/static/js/sqleditor_title';
@@ -28,6 +27,7 @@ import FunctionArguments from './debugger_ui';
 import ModalProvider from '../../../../static/js/helpers/ModalProvider';
 import DebuggerComponent from './components/DebuggerComponent';
 import Theme from '../../../../static/js/Theme';
+import { showRenamePanel } from '../../../../static/js/Dialogs';
 
 export default class DebuggerModule {
   static instance;
@@ -713,20 +713,13 @@ export default class DebuggerModule {
   }
 
   panel_rename_event(panel_data, panel, treeInfo) {
-    alertify.prompt('', panel_data.$titleText[0].textContent,
-      // We will execute this function when user clicks on the OK button
-      function (evt, value) {
-        if (value) {
-          // Remove the leading and trailing white spaces.
-          value = value.trim();
-          let preferences = this.pgBrowser.get_preferences_for_module('browser');
-          var name = getAppropriateLabel(treeInfo);
-          setDebuggerTitle(panel, preferences, name, treeInfo.schema.label, treeInfo.database.label, value, this.pgBrowser);
-        }
-      },
-      // We will execute this function when user clicks on the Cancel
-      // button.  Do nothing just close it.
-      function (evt) { evt.cancel = false; }
-    ).set({ 'title': gettext('Rename Panel') });
+    let name = getAppropriateLabel(treeInfo);
+    let preferences = this.pgBrowser.get_preferences_for_module('browser');
+    let data = {
+      function_name: name,
+      schema_name: treeInfo.schema.label,
+      database_name: treeInfo.database.label
+    };
+    showRenamePanel(panel_data.$titleText[0].textContent, preferences, panel, 'debugger', data);
   }
 }
diff --git a/web/pgadmin/tools/debugger/static/js/components/DebuggerArgumentComponent.jsx b/web/pgadmin/tools/debugger/static/js/components/DebuggerArgumentComponent.jsx
index ab5b3292..16daa8b7 100644
--- a/web/pgadmin/tools/debugger/static/js/components/DebuggerArgumentComponent.jsx
+++ b/web/pgadmin/tools/debugger/static/js/components/DebuggerArgumentComponent.jsx
@@ -22,7 +22,6 @@ import gettext from 'sources/gettext';
 import * as commonUtils from 'sources/utils';
 import pgAdmin from 'sources/pgadmin';
 import Loader from 'sources/components/Loader';
-import Alertify from 'pgadmin.alertifyjs';
 
 import SchemaView from '../../../../../static/js/SchemaView';
 import getApiInstance from '../../../../../static/js/api_instance';
@@ -31,7 +30,7 @@ import { getAppropriateLabel, setDebuggerTitle } from '../debugger_utils';
 import Notify from '../../../../../static/js/helpers/Notifier';
 import { DebuggerArgumentSchema } from './DebuggerArgs.ui';
 import { DEBUGGER_ARGS } from '../DebuggerConstants';
-
+import { showRenamePanel } from '../../../../../static/js/Dialogs';
 
 
 const useStyles = makeStyles((theme) =>
@@ -677,7 +676,6 @@ export default function DebuggerArgumentComponent({ debuggerInfo, restartDebug,
   }
 
   function startDebugging() {
-    var self = this;
     setLoaderText('Starting debugger.');
     try {
       /* Initialize the target once the debug button is clicked and create asynchronous connection
@@ -759,20 +757,7 @@ export default function DebuggerArgumentComponent({ debuggerInfo, restartDebug,
 
               // Panel Rename event
               panel.on(wcDocker.EVENT.RENAME, function (panel_data) {
-                Alertify.prompt('', panel_data.$titleText[0].textContent,
-                  // We will execute this function when user clicks on the OK button
-                  function (evt, value) {
-                    if (value) {
-                      // Remove the leading and trailing white spaces.
-                      value = value.trim();
-                      var name = getAppropriateLabel(treeInfo);
-                      setDebuggerTitle(panel, self.preferences, name, treeInfo.schema.label, treeInfo.database.label, value, pgAdmin.Browser);
-                    }
-                  },
-                  // We will execute this function when user clicks on the Cancel
-                  // button.  Do nothing just close it.
-                  function (evt) { evt.cancel = false; }
-                ).set({ 'title': gettext('Rename Panel') });
+                panelRenameEvent(panel_data, panel, treeInfo);
               });
             }
 
@@ -861,6 +846,17 @@ export default function DebuggerArgumentComponent({ debuggerInfo, restartDebug,
 
   }
 
+  function panelRenameEvent(panel_data, panel, treeInfo) {
+    let name = getAppropriateLabel(treeInfo);
+    let preferences = pgAdmin.Browser.get_preferences_for_module('browser');
+    let data = {
+      function_name: name,
+      schema_name: treeInfo.schema.label,
+      database_name: treeInfo.database.label
+    };
+    showRenamePanel(panel_data.$titleText[0].textContent, preferences, panel, 'debugger', data);
+  }
+
   return (
     <Box className={classes.root}>
       <Box className={classes.body}>
diff --git a/web/pgadmin/tools/schema_diff/__init__.py b/web/pgadmin/tools/schema_diff/__init__.py
index 6f50f598..7845a51d 100644
--- a/web/pgadmin/tools/schema_diff/__init__.py
+++ b/web/pgadmin/tools/schema_diff/__init__.py
@@ -129,18 +129,7 @@ def panel(trans_id, editor_title):
         trans_id=trans_id,
         requirejs=True,
         basejs=True,
-        editor_title=editor_title
-    )
-
-
-@blueprint.route("/schema_diff.js")
-@login_required
-def script():
-    """render the required javascript"""
-    return Response(
-        response=render_template("schema_diff/js/schema_diff.js", _=gettext),
-        status=200,
-        mimetype=MIMETYPE_APP_JS
+        editor_title=editor_title,
     )
 
 
diff --git a/web/pgadmin/tools/schema_diff/static/css/schema_diff.css b/web/pgadmin/tools/schema_diff/static/css/schema_diff.css
deleted file mode 100644
index 4236dae9..00000000
--- a/web/pgadmin/tools/schema_diff/static/css/schema_diff.css
+++ /dev/null
@@ -1,155 +0,0 @@
-.icon-compare:before {
-  font-size: 1.3em !important;
-}
-
-.icon-script {
-  display: inline-block;
-  align-content: center;
-  vertical-align: middle;
-  height: 18px;
-  width: 18px;
-  background-size: 20px !important;
-  background-repeat: no-repeat;
-  background-position-x: center;
-  background-position-y: center;
-  background-image: url('../img/script.svg') !important;
-}
-
-.really-hidden {
-  display: none !important;
-}
-
-#schema-diff-header {
-  padding: 0.75rem 0.7rem;
-}
-
-#schema-diff-header .control-label {
-  width: 120px !important;
-  padding: 5px 5px !important;
-}
-
-#schema-diff-grid .slick-header-column.ui-state-default {
-    height: 32px !important;
-    line-height: 25px !important;
-}
-
-#schema-diff-grid .grid-header label {
-  display: inline-block;
-  font-weight: bold;
-  margin: auto auto auto 6px;
-}
-
-.grid-header .ui-icon {
-  margin: 4px 4px auto 6px;
-  background-color: transparent;
-  border-color: transparent;
-}
-
-.slick-row .cell-actions {
-  text-align: left;
-}
-
-/* Slick.Editors.Text, Slick.Editors.Date */
-#schema-diff-grid .slick-header > input.editor-text {
-  width: 100%;
-  height: 100%;
-  border: 0;
-  margin: 0;
-  background: transparent;
-  outline: 0;
-  padding: 0;
-}
-
-/* Slick.Editors.Checkbox */
-#schema-diff-grid .slick-header > input.editor-checkbox {
-  margin: 0;
-  height: 100%;
-  padding: 0;
-  border: 0;
-}
-
-.slick-row.selected .cell-selection {
-  background-color: transparent; /* show default selected row background */
-}
-
-#schema-diff-grid .slick-header .ui-state-default,
-#schema-diff-grid .slick-header .ui-widget-content.ui-state-default,
-#schema-diff-grid .slick-header .ui-widget-header .ui-state-default {
-  background: none;
-}
-
-#schema-diff-grid .slick-header .slick-header-column {
-  font-weight: bold;
-  display: block;
-}
-
-.slick-group-toggle.collapsed, .slick-group-toggle.expanded {
-  background: none !important;
-  width: 20px;
-}
-
-.slick-group-toggle {
-  margin-right: 0px !important;
-  height: 11px !important;
-}
-
-#schema-diff-ddl-comp .badge .caret {
-    display: inline-block;
-    margin-left: 2px;
-    margin-right: 4px;
-    width: 0.7rem;
-}
-
-#schema-diff-ddl-comp .badge {
-  font-size: inherit;
-  padding: 7px;
-}
-
-#schema-diff-ddl-comp .accordian-group {
-  padding: 0px;
-}
-
-#ddl_comp_fetching_data.pg-sp-container {
-  height: 100%;
-  bottom: 10px;
-
-  .pg-sp-content {
-    position: absolute;
-    width: 100%;
-  }
-}
-
-.ddl-copy {
-  z-index: 10;
-  position: absolute;
-  right: 1px;
-  top: 1px;
-}
-
-#schema-diff-grid .pg-panel-message {
-  font-size: 0.875rem;
-}
-
-
-#schema-diff-ddl-comp .sql_field_layout {
-  overflow: auto !important;
-  height: 100%;
-}
-
-#schema-diff-ddl-comp .source_ddl, #schema-diff-ddl-comp .target_ddl, #schema-diff-ddl-comp .diff_ddl {
-  height: 300px;
-  overflow: hidden;
-}
-
-.target-buttons {
-  flex-wrap: wrap;
-  max-width: 40% !important;
-}
-
-.slick-cell .ml-2 {
-  margin-left: 2rem !important;
-}
-
-.slick-cell .ml-3 {
-  margin-left: 3rem !important;
-}
diff --git a/web/pgadmin/tools/schema_diff/static/js/SchemaDiffConstants.js b/web/pgadmin/tools/schema_diff/static/js/SchemaDiffConstants.js
new file mode 100644
index 00000000..69495172
--- /dev/null
+++ b/web/pgadmin/tools/schema_diff/static/js/SchemaDiffConstants.js
@@ -0,0 +1,65 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+
+import gettext from 'sources/gettext';
+
+export const PANELS = {
+  SCHEMADIFF: 'id-schema-diff',
+  RESULTS: 'id-results',
+};
+
+export const TYPE = {
+  SOURCE: 1,
+  TARGET: 2
+};
+
+export const MENUS = {
+  COMPARE: 'schema-diff-compare',
+  GENERATE_SCRIPT: 'schema-diff-generate-script',
+  FILTER: 'schema-diff-filter'
+};
+
+export const STYLE_CONSTANT = {
+  IDENTICAL: 'identical',
+  DIFFERENT :'different',
+  SOURCE_ONLY: 'source',
+  TARGET_ONLY: 'target'
+};
+
+export const MENUS_COMPARE_CONSTANT = {
+  COMPARE_IGNORE_OWNER: 1,
+  COMPARE_IGNORE_WHITESPACE: 2
+};
+
+export const MENUS_FILTER_CONSTANT = {
+  FILTER_IDENTICAL: 1,
+  FILTER_DIFFERENT: 2,
+  FILTER_SOURCE_ONLY: 3,
+  FILTER_TARGET_ONLY: 4,
+};
+
+export const SCHEMA_DIFF_EVENT = {
+  TRIGGER_SELECT_SERVER: 'TRIGGER_SELECT_SERVER',
+  TRIGGER_SELECT_DATABASE: 'TRIGGER_SELECT_DATABASE',
+  TRIGGER_SELECT_SCHEMA: 'TRIGGER_SELECT_DATABASE',
+
+  TRIGGER_COMPARE_DIFF: 'TRIGGER_COMPARE_DIFF',
+  TRIGGER_GENERATE_SCRIPT: 'TRIGGER_GENERATE_SCRIPT',
+  TRIGGER_CHANGE_FILTER: 'TRIGGER_CHANGE_FILTER',
+
+  TRIGGER_CHANGE_RESULT_SQL: 'TRIGGER_CHANGE_RESULT_SQL',
+  TRIGGER_ROW_SELECT: 'TRIGGER_ROW_SELECT',
+};
+
+export const FILTER_NAME = {
+  IDENTICAL : gettext('Identical'),
+  DIFFERENT : gettext('Different'),
+  SOURCE_ONLY: gettext('Source Only'),
+  TARGET_ONLY: gettext('Target Only')
+};
diff --git a/web/pgadmin/tools/schema_diff/static/js/SchemaDiffModule.js b/web/pgadmin/tools/schema_diff/static/js/SchemaDiffModule.js
new file mode 100644
index 00000000..6e958afe
--- /dev/null
+++ b/web/pgadmin/tools/schema_diff/static/js/SchemaDiffModule.js
@@ -0,0 +1,165 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+
+import React from 'react';
+import ReactDOM from 'react-dom';
+
+import gettext from 'sources/gettext';
+import url_for from 'sources/url_for';
+import pgWindow from 'sources/window';
+import { registerDetachEvent } from 'sources/utils';
+
+import { _set_dynamic_tab } from '../../../sqleditor/static/js/show_query_tool';
+import getApiInstance from '../../../../static/js/api_instance';
+import Theme from '../../../../static/js/Theme';
+import ModalProvider from '../../../../static/js/helpers/ModalProvider';
+import Notify from '../../../../static/js/helpers/Notifier';
+import SchemaDiffComponent from './components/SchemaDiffComponent';
+import { showRenamePanel } from '../../../../static/js/Dialogs';
+
+
+export default class SchemaDiff {
+  static instance;
+
+  static getInstance(...args) {
+    if (!SchemaDiff.instance) {
+      SchemaDiff.instance = new SchemaDiff(...args);
+    }
+    return SchemaDiff.instance;
+  }
+
+  constructor(pgAdmin, pgBrowser) {
+    this.pgAdmin = pgAdmin;
+    this.pgBrowser = pgBrowser;
+    this.wcDocker = window.wcDocker;
+    this.api = getApiInstance();
+  }
+
+  init() {
+    let self = this;
+    if (self.initialized)
+      return;
+    self.initialized = true;
+    // Define the nodes on which the menus to be appear
+    self.pgBrowser.add_menus([{
+      name: 'schema_diff',
+      module: self,
+      applies: ['tools'],
+      callback: 'showSchemaDiffTool',
+      priority: 1,
+      label: gettext('Schema Diff'),
+      enable: true,
+      below: true,
+    }]);
+
+    /* Create and load the new frame required for schema diff panel */
+    self.frame = new self.pgBrowser.Frame({
+      name: 'frm_schemadiff',
+      title: gettext('Schema Diff'),
+      showTitle: true,
+      isCloseable: true,
+      isRenamable: true,
+      isPrivate: true,
+      icon: 'pg-font-icon icon-compare',
+      url: 'about:blank',
+    });
+
+    /* Cache may take time to load for the first time. Keep trying till available */
+    let cacheIntervalId = setInterval(function () {
+      if (self.pgBrowser.preference_version() > 0) {
+        self.preferences = self.pgBrowser.get_preferences_for_module('schema_diff');
+        clearInterval(cacheIntervalId);
+      }
+    }, 0);
+
+    self.pgBrowser.onPreferencesChange('schema_diff', function () {
+      self.preferences = self.pgBrowser.get_preferences_for_module('schema_diff');
+    });
+
+    self.frame.load(self.pgBrowser.docker);
+  }
+
+  showSchemaDiffTool() {
+    let self = this;
+
+    self.api({
+      url: url_for('schema_diff.initialize', null),
+      method: 'GET',
+    })
+      .then(function (res) {
+        self.trans_id = res.data.data.schemaDiffTransId;
+        res.data.data.panel_title = gettext('Schema Diff');
+        self.launchSchemaDiff(res.data.data);
+      })
+      .catch(function (error) {
+        Notify.error(gettext(`Error in schema diff initialize ${error.response.data}`));
+      });
+  }
+
+  launchSchemaDiff(data) {
+    let self = this;
+    let panelTitle = data.panel_title,
+      trans_id = data.schemaDiffTransId,
+      panelTooltip = '';
+
+    let url_params = {
+        'trans_id': trans_id,
+        'editor_title': panelTitle,
+      },
+      baseUrl = url_for('schema_diff.panel', url_params);
+
+    let browserPreferences = this.pgBrowser.get_preferences_for_module('browser');
+    let openInNewTab = browserPreferences.new_browser_tab_open;
+    if (openInNewTab && openInNewTab.includes('schema_diff')) {
+      window.open(baseUrl, '_blank');
+      // Send the signal to runtime, so that proper zoom level will be set.
+      setTimeout(function () {
+        this.pgBrowser.send_signal_to_runtime('Runtime new window opened');
+      }, 500);
+    } else {
+      this.pgBrowser.Events.once(
+        'pgadmin-browser:frame:urlloaded:frm_schemadiff',
+        function (frame) {
+          frame.openURL(baseUrl);
+        });
+      let propertiesPanel = this.pgBrowser.docker.findPanels('properties'),
+        schemaDiffPanel = this.pgBrowser.docker.addPanel('frm_schemadiff', this.wcDocker.DOCK.STACKED, propertiesPanel[0]);
+
+      registerDetachEvent(schemaDiffPanel);
+
+      // Panel Rename event
+      schemaDiffPanel.on(self.wcDocker.EVENT.RENAME, function (panel_data) {
+        self.panel_rename_event(panel_data, schemaDiffPanel, browserPreferences);
+      });
+
+      _set_dynamic_tab(this.pgBrowser, browserPreferences['dynamic_tabs']);
+      // Set panel title and icon
+      schemaDiffPanel.title('<span title="' + panelTooltip + '">' + panelTitle + '</span>');
+      schemaDiffPanel.icon('pg-font-icon icon-compare');
+      schemaDiffPanel.focus();
+
+    }
+  }
+
+  panel_rename_event(panel_data, panel) {
+    showRenamePanel(panel_data.$titleText[0].textContent, null, panel);
+  }
+
+  load(container, trans_id) {
+    ReactDOM.render(
+      <Theme>
+        <ModalProvider>
+          <SchemaDiffComponent params={{ transId: trans_id, pgAdmin: pgWindow.pgAdmin }}></SchemaDiffComponent>
+        </ModalProvider>
+      </Theme>,
+      container
+    );
+  }
+
+}
diff --git a/web/pgadmin/tools/schema_diff/static/js/components/InputComponent.jsx b/web/pgadmin/tools/schema_diff/static/js/components/InputComponent.jsx
new file mode 100644
index 00000000..440d2d8e
--- /dev/null
+++ b/web/pgadmin/tools/schema_diff/static/js/components/InputComponent.jsx
@@ -0,0 +1,143 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+import _ from 'lodash';
+import PropTypes from 'prop-types';
+
+import React, { useContext, useState } from 'react';
+
+import { Box, Grid, Typography } from '@material-ui/core';
+import { makeStyles } from '@material-ui/styles';
+
+import { InputSelect } from '../../../../../static/js/components/FormComponents';
+import { SchemaDiffEventsContext } from './SchemaDiffComponent';
+import { SCHEMA_DIFF_EVENT } from '../SchemaDiffConstants';
+
+
+const useStyles = makeStyles(() => ({
+  root: {
+    padding: '0rem'
+  },
+  spanLabel: {
+    alignSelf: 'center',
+    marginRight: '4px',
+  },
+  inputLabel: {
+    padding: '0.3rem',
+  },
+}));
+
+export function InputComponent({ label, serverList, databaseList, schemaList, diff_type, selectedSid = null, selectedDid=null, selectedScid=null }) {
+
+  const classes = useStyles();
+  const [selectedServer, setSelectedServer] = useState(selectedSid);
+  const [selectedDatabase, setSelectedDatabase] = useState(selectedDid);
+  const [selectedSchema, setSelectedSchema] = useState(selectedScid);
+  const eventBus = useContext(SchemaDiffEventsContext);
+  const [disableDBSelection, setDisableDBSelection] = useState(selectedSid == null ? true : false);
+  const [disableSchemaSelection, setDisableSchemaSelection] = useState(selectedDid == null ? true : false);
+  const changeServer = (selectedOption) => {
+    setDisableDBSelection(false);
+    setSelectedServer(selectedOption);
+    // Reset the Database selection if user deselect server from DD
+    if(selectedOption == null){
+      setSelectedDatabase(null);
+      setDisableDBSelection(true);
+      setSelectedSchema(null);
+      setDisableSchemaSelection(true);
+    }
+
+    eventBus.fireEvent(SCHEMA_DIFF_EVENT.TRIGGER_SELECT_SERVER, { selectedOption, diff_type, serverList });
+  };
+
+  const changeDatabase = (selectedDB) => {
+    setSelectedDatabase(selectedDB);
+    setDisableSchemaSelection(false);
+    // Reset the Schema selection if user deselect database from DD
+    if(selectedDB == null){
+      setSelectedSchema(null);
+      setDisableSchemaSelection(true);
+    }
+    eventBus.fireEvent(SCHEMA_DIFF_EVENT.TRIGGER_SELECT_DATABASE, {selectedServer, selectedDB, diff_type, databaseList});
+  };
+
+  const changeSchema = (selectedSC) => {
+    setSelectedSchema(selectedSC);
+    eventBus.fireEvent(SCHEMA_DIFF_EVENT.TRIGGER_SELECT_SCHEMA, { selectedSC, diff_type });
+  };
+
+  return (
+    <Box className={classes.root}>
+      <Grid
+        container
+        direction="row"
+        alignItems="center"
+        key={_.uniqueId('c')}
+      >
+        <Grid item lg={2} md={2} sm={2} xs={2} className={classes.inputLabel} key={_.uniqueId('c')}>
+          <Typography id={label}>{label}</Typography>
+        </Grid>
+        <Grid item lg={4} md={4} sm={4} xs={4} className={classes.inputLabel} key={_.uniqueId('c')}>
+          <InputSelect
+            options={serverList}
+            onChange={changeServer}
+            value={selectedServer}
+            controlProps={
+              {
+                placeholder: 'Select server...'
+              }
+            }
+            key={'server_' + diff_type}
+          ></InputSelect>
+        </Grid>
+
+        <Grid item lg={3} md={3} sm={3} xs={3} className={classes.inputLabel} key={_.uniqueId('c')}>
+          <InputSelect
+            options={databaseList}
+            onChange={changeDatabase}
+            value={selectedDatabase}
+            controlProps={
+              {
+                placeholder: 'Select Database...'
+              }
+            }
+            key={'database_' + diff_type}
+            readonly={disableDBSelection}
+          ></InputSelect>
+        </Grid>
+
+        <Grid item lg={3} md={3} sm={3} xs={3} className={classes.inputLabel} key={_.uniqueId('c')}>
+          <InputSelect
+            options={schemaList}
+            onChange={changeSchema}
+            value={selectedSchema}
+            controlProps={
+              {
+                placeholder: 'Select Schema...'
+              }
+            }
+            key={'schema' + diff_type}
+            readonly={disableSchemaSelection}
+          ></InputSelect>
+        </Grid>
+      </Grid>
+
+    </Box >
+  );
+}
+
+InputComponent.propTypes = {
+  label: PropTypes.string,
+  serverList: PropTypes.array, 
+  databaseList:PropTypes.array, 
+  schemaList:PropTypes.array, 
+  diff_type:PropTypes.number,
+  selectedSid: PropTypes.number,
+  selectedDid: PropTypes.number,
+  selectedScid:PropTypes.number,
+};
diff --git a/web/pgadmin/tools/schema_diff/static/js/components/ResultGridComponent.jsx b/web/pgadmin/tools/schema_diff/static/js/components/ResultGridComponent.jsx
new file mode 100644
index 00000000..33ce5754
--- /dev/null
+++ b/web/pgadmin/tools/schema_diff/static/js/components/ResultGridComponent.jsx
@@ -0,0 +1,739 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+import _ from 'lodash';
+import PropTypes from 'prop-types';
+import clsx from 'clsx';
+
+import { SelectColumn } from 'react-data-grid';
+import React, { useContext, useEffect, useLayoutEffect, useReducer, useRef, useState } from 'react';
+
+import { Box } from '@material-ui/core';
+import { makeStyles } from '@material-ui/styles';
+import KeyboardArrowRightRoundedIcon from '@material-ui/icons/KeyboardArrowRightRounded';
+import KeyboardArrowDownRoundedIcon from '@material-ui/icons/KeyboardArrowDownRounded';
+import InfoIcon from '@material-ui/icons/InfoRounded';
+
+import gettext from 'sources/gettext';
+import url_for from 'sources/url_for';
+
+
+import { FILTER_NAME, SCHEMA_DIFF_EVENT } from '../SchemaDiffConstants';
+import { SchemaDiffContext, SchemaDiffEventsContext } from './SchemaDiffComponent';
+import { InputCheckbox } from '../../../../../static/js/components/FormComponents';
+import PgReactDataGrid from '../../../../../static/js/components/PgReactDataGrid';
+import Notifier from '../../../../../static/js/helpers/Notifier';
+
+
+const useStyles = makeStyles((theme) => ({
+  root: { 
+
+    paddingTop: '0.5rem',
+    display: 'flex',
+    height: '100%',
+    flexDirection: 'column',
+    color: theme.palette.text.primary,
+    backgroundColor: theme.otherVars.qtDatagridBg,
+    border: 'none',
+    fontSize: '13px',
+    '& .rdg': {
+      flex: 1,
+      borderTop: '1px solid' + theme.otherVars.borderColor,
+    },
+    '--rdg-background-color': theme.palette.default.main,
+    '--rdg-selection-color': theme.palette.primary.main,
+    '& .rdg-cell': {
+      padding: 0,
+      boxShadow: 'none',
+      color: theme.otherVars.schemaDiff.diffColorFg + ' !important',
+      ...theme.mixins.panelBorder.right,
+      ...theme.mixins.panelBorder.bottom,
+      '&[aria-colindex="1"]': {
+        padding: 0,
+      },
+      '&[aria-selected=true]:not([role="columnheader"]):not([aria-colindex="1"])': {
+        outlineWidth: '0',
+        outlineOffset: '-1px',
+        color: theme.otherVars.qtDatagridSelectFg,
+      },
+      '&[aria-selected=true][aria-colindex="1"]': {
+        outlineWidth: 0,
+      }
+    },
+    '& .rdg-header-row .rdg-cell': {
+      padding: 0,
+      paddingLeft: '0.5rem',
+      boxShadow: 'none',
+    },
+    '& .rdg-header-row': {
+      backgroundColor: theme.palette.background.default,
+    },
+    '& .rdg-row': {
+      backgroundColor: theme.palette.background.default,
+      '&[aria-selected=true]': {
+        backgroundColor: theme.palette.primary.light,
+        color: theme.otherVars.qtDatagridSelectFg,
+        '& .rdg-cell:nth-child(1)': {
+          backgroundColor: 'transparent',
+          outlineColor: 'transparent',
+          color: theme.palette.primary.contrastText,
+        }
+      },
+    }
+  },
+  grid: {
+    fontSize: '13px',
+    '--rdg-selection-color': 'none'
+  },
+  subRow: {
+    paddingLeft: '1rem'
+  },
+  recordRow: {
+    marginLeft: '2.7rem',
+    height: '1.3rem',
+    width: '1.3rem',
+    display: 'inline-block',
+    marginRight: '0.3rem',
+    paddingLeft: '0.5rem',
+  },
+  rowIcon: {
+    display: 'inline-block !important',
+    height: '1.3rem',
+    width: '1.3rem'
+  },
+  cellExpand: {
+    float: 'inline-end',
+    display: 'table',
+    blockSize: '100%',
+
+    '& span': {
+      display: 'table-cell',
+      verticalAlign: 'middle',
+      cursor: 'pointer',
+    }
+  },
+  gridPanel: {
+    '--rdg-background-color': theme.palette.default.main + ' !important',
+  },
+  source: {
+    backgroundColor: theme.otherVars.schemaDiff.sourceRowColor,
+    color: theme.otherVars.schemaDiff.diffSelectFG,
+    paddingLeft: '0.5rem',
+  },
+  target: {
+    backgroundColor: theme.otherVars.schemaDiff.targetRowColor,
+    color: theme.otherVars.schemaDiff.diffSelectFG,
+    paddingLeft: '0.5rem',
+  },
+  different: {
+    backgroundColor: theme.otherVars.schemaDiff.diffRowColor,
+    color: theme.otherVars.schemaDiff.diffSelectFG,
+    paddingLeft: '0.5rem',
+  },
+  identical: {
+    paddingLeft: '0.5rem',
+    color: theme.otherVars.schemaDiff.diffSelectFG,
+  },
+  selectCell: {
+    padding: '0 0.3rem'
+  },
+  headerSelectCell: {
+    padding: '0rem 0.3rem 0 0.3rem'
+  },
+  count: {
+    display: 'inline-block !important',
+  },
+  countStyle: {
+    fontWeight: 900,
+    fontSize: '0.8rem',
+    paddingLeft: '0.3rem',
+  },
+  countLabel: {
+    paddingLeft: '1rem',
+  },
+  selectedRow: {
+    paddingLeft: '0.5rem',
+    backgroundColor: theme.palette.primary.light
+  },
+  selectedRowCheckBox: {
+    paddingLeft: '0.5rem',
+    backgroundColor: theme.palette.primary.light,
+  },
+  selChBox: {
+    paddingLeft: 0,
+  },
+  noRowsIcon:{
+    width: '1.1rem',
+    height: '1.1rem',
+    marginRight: '0.5rem',
+  }
+
+}));
+
+function useFocusRef(isSelected) {
+  const ref = useRef(null);
+
+  useLayoutEffect(() => {
+    if (!isSelected) return;
+    ref.current?.focus({ preventScroll: true });
+  }, [isSelected]);
+
+  return {
+    ref,
+    tabIndex: isSelected ? 0 : -1
+  };
+}
+
+function setRecordCount(row, filterParams) {
+  row['identicalCount'] = 0;
+  row['differentCount'] = 0;
+  row['sourceOnlyCount'] = 0;
+  row['targetOnlyCount'] = 0;
+
+  row.children.map((ch) => {
+    if (filterParams.includes(ch.status)) {
+      if (ch.status == FILTER_NAME.IDENTICAL) {
+        row['identicalCount'] = row['identicalCount'] + 1;
+      } else if (ch.status == FILTER_NAME.DIFFERENT) {
+        row['differentCount'] = row['differentCount'] + 1;
+      } else if (ch.status == FILTER_NAME.SOURCE_ONLY) {
+        row['sourceOnlyCount'] = row['sourceOnlyCount'] + 1;
+      } else if (ch.status == FILTER_NAME.TARGET_ONLY) {
+        row['targetOnlyCount'] = row['targetOnlyCount'] + 1;
+      }
+    }
+  });
+
+}
+
+function CellExpanderFormatter({
+  row,
+  isCellSelected,
+  expanded,
+  filterParams,
+  onCellExpand
+}) {
+  const classes = useStyles();
+  const { ref, tabIndex } = useFocusRef(isCellSelected);
+  'identicalCount' in row && setRecordCount(row, filterParams);
+
+  function handleKeyDown(e) {
+    if (e.key === ' ' || e.key === 'Enter') {
+      e.preventDefault();
+      onCellExpand();
+    }
+  }
+
+  return (
+    <div className={classes.cellExpand}>
+      <span onClick={onCellExpand} onKeyDown={handleKeyDown}>
+        <span ref={ref} tabIndex={tabIndex} className={'identicalCount' in row ? classes.subRow : null}>
+          {expanded ? <KeyboardArrowDownRoundedIcon /> : <KeyboardArrowRightRoundedIcon />} <span className={clsx(row.icon, classes.rowIcon)}></span>{row.label}
+          {
+            'identicalCount' in row ?
+              <span className={clsx(classes.count)}>
+                <span className={classes.countLabel}>{FILTER_NAME.IDENTICAL}:</span> <span className={classes.countStyle}>{row.identicalCount} </span>
+                <span className={classes.countLabel}>{FILTER_NAME.DIFFERENT}:</span> <span className={classes.countStyle}>{row.differentCount}  </span>
+                <span className={classes.countLabel}>{FILTER_NAME.SOURCE_ONLY}:</span> <span className={classes.countStyle}>{row.sourceOnlyCount}  </span>
+                <span className={classes.countLabel}>{FILTER_NAME.TARGET_ONLY}: </span><span className={classes.countStyle}>{row.targetOnlyCount}</span>
+              </span>
+              : null
+
+          }
+        </span>
+      </span>
+    </div>
+  );
+}
+
+CellExpanderFormatter.propTypes = {
+  row: PropTypes.object,
+  isCellSelected: PropTypes.bool,
+  expanded: PropTypes.bool,
+  onCellExpand: PropTypes.func,
+  filterParams: PropTypes.array,
+};
+
+
+function toggleSubRow(rows, id, filterParams) {
+  const newRows = [...rows];
+  const rowIndex = newRows.findIndex((r) => r.id === id);
+
+  const row = newRows[rowIndex];
+  if (!row) return newRows;
+  const { children } = row;
+  if (!children) return newRows;
+
+  if (children.length > 0) {
+    newRows[rowIndex] = { ...row, isExpanded: !row.isExpanded };
+    if (!row.isExpanded) {
+      let tempChild = [];
+      expandRows(children, filterParams, tempChild, newRows, rowIndex);
+    } else {
+      collapseRows(newRows, filterParams, rowIndex);
+    }
+    return newRows;
+  } else {
+    newRows.splice(rowIndex, 1);
+    return newRows;
+  }
+}
+
+function expandRows(children, filterParams, tempChild, newRows, rowIndex) {
+  children.map((child) => {
+    if ('children' in child) {
+      let tempSubChild = [];
+      child.children.map((subChild) => {
+        if (filterParams.includes(subChild.status)) {
+          tempSubChild.push(subChild);
+        }
+      });
+
+      if (tempSubChild.length > 0) {
+        tempChild.push(child);
+      }
+
+    }
+    else {
+      if (filterParams.includes(child.status)) {
+        tempChild.push(child);
+      }
+
+    }
+  });
+  if (tempChild.length > 0) {
+    newRows.splice(rowIndex + 1, 0, ...tempChild);
+  } else {
+    newRows.splice(rowIndex, 1);
+  }
+}
+
+function collapseRows(newRows, filterParams, rowIndex) {
+  let totalChild = 0;
+  let filteredChild = newRows[rowIndex].children.filter((el) => {
+    if (el?.children) {
+      let clist = el.children.filter((subch) => {
+        return filterParams.includes(subch.status);
+      });
+      if (clist.length > 0) {
+        return el;
+      }
+    } else {
+      return el?.status ? filterParams.includes(el.status) : el;
+    }
+  });
+  let totalChCount = filteredChild.length;
+  for (let i = 0; i <= filteredChild.length; i++) {
+    let _index = i + 1;
+    let indx = totalChild ? rowIndex + totalChild + _index : rowIndex + _index;
+    if (newRows[indx]?.isExpanded) {
+      let filteredSubChild = newRows[indx].children.filter((el) => {
+        return filterParams.includes(el.status);
+      });
+      totalChild += filteredSubChild.length;
+    }
+  }
+  newRows.splice(rowIndex + 1, totalChild ? totalChCount + totalChild : totalChCount);
+}
+
+function getChildrenRows(data) {
+  if ('children' in data) {
+    return data.children;
+  }
+
+  return data;
+}
+
+function checkRowExpanedStatus(rows, record) {
+  if (rows.length > 0) {
+    let tempRecord = rows.filter((rec) => {
+      return rec.parentId == record.parentId && rec.label == record.label;
+    });
+    return tempRecord.length > 0 ? tempRecord[0].isExpanded : false;
+  }
+  return false;
+}
+
+function prepareRows(rows, gridData, filterParams) {
+  let newRows = [];
+
+  let adedIds = [];
+  gridData.map((record) => {
+    let childrens = getChildrenRows(record);
+
+    if (childrens.length > 0) {
+      childrens.map((child) => {
+        let subChildrens = getChildrenRows(child);
+        let tempChildList = [];
+        subChildrens.map((subChild) => {
+          if (filterParams.includes(subChild.status)) {
+            tempChildList.push(subChild);
+            adedIds.push(subChild.id);
+          }
+        });
+
+        if (!adedIds.includes(record.id) && tempChildList.length > 0) {
+          adedIds.push(record.id);
+          record.isExpanded = true;
+          newRows.push(record);
+        }
+
+        if (!adedIds.includes(child.id) && tempChildList.length > 0) {
+          adedIds.push(child.id);
+          child.isExpanded = checkRowExpanedStatus(rows, child);
+          newRows.push(child);
+          newRows = checkAndAddChild(child, newRows, tempChildList);
+        }
+
+      });
+
+    }
+  });
+
+  return newRows;
+}
+
+function checkAndAddChild(child, newRows, tempChildList) {
+  if (child.isExpanded) {
+    newRows = newRows.concat(tempChildList);
+  }
+
+  return newRows;
+}
+
+function reducer(rows, { type, id, filterParams, gridData }) {
+  switch (type) {
+  case 'toggleSubRow':
+    return toggleSubRow(rows, id, filterParams);
+  case 'applyFilter':
+    return prepareRows(rows, gridData, filterParams);
+  default:
+    return rows;
+  }
+}
+
+function getStyleClassName(row, selectedRowIds, isCellSelected, activeRowId, isCheckbox = false) {
+  const classes = useStyles();
+  let clsName = null;
+  if (selectedRowIds.includes(`${row.id}`) || isCellSelected || row.id == activeRowId) {
+    clsName = isCheckbox ? classes.selectedRowCheckBox : classes.selectedRow;
+  } else {
+    if (row.status == FILTER_NAME.DIFFERENT) {
+      clsName = classes.different;
+    } else if (row.status == FILTER_NAME.SOURCE_ONLY) {
+      clsName = classes.source;
+    } else if (row.status == FILTER_NAME.TARGET_ONLY) {
+      clsName = classes.target;
+    } else if (row.status == FILTER_NAME.IDENTICAL) {
+      clsName = classes.identical;
+    }
+  }
+
+  return clsName;
+}
+
+export function ResultGridComponent({ gridData, allRowIds, filterParams, selectedRowIds, transId, sourceData, targetData }) {
+  const classes = useStyles();
+  const [rows, dispatch] = useReducer(reducer, [...gridData]);
+  const [selectedRows, setSelectedRows] = useState([]);
+  const [rootSelection, setRootSelection] = useState(false);
+  const [activeRow, setActiveRow] = useState(null);
+  const schemaDiffToolContext = useContext(SchemaDiffContext);
+
+  function checkAllChildInclude(row, tempSelectedRows) {
+    let isChildAllInclude = true;
+    row.metadata.children.map((id) => {
+      if (!tempSelectedRows.includes(id) && id !== `${row.id}`) {
+        isChildAllInclude = false;
+      }
+    });
+    return isChildAllInclude;
+  }
+
+  function selectedResultRows(row, tempSelectedRows) {
+    if (row.metadata.isRoot) {
+      tempSelectedRows.push(`${row.id}`, ...row.metadata.children);
+      tempSelectedRows.push(...row.metadata.subChildren);
+    } else if (row.metadata.subChildren) {
+      tempSelectedRows.push(...row.metadata.dependencies);
+      tempSelectedRows.push(`${row.id}`, ...row.metadata.subChildren);
+      let isChildAllInclude = checkAllChildInclude(row, tempSelectedRows);
+      isChildAllInclude && tempSelectedRows.push(`${row.metadata.parentId}`);
+    } else {
+      tempSelectedRows.push(...row.dependencieRowIds);
+      tempSelectedRows.push(`${row.id}`);
+      let isChildAllInclude = checkAllChildInclude(row, tempSelectedRows);
+      isChildAllInclude && tempSelectedRows.push(`${row.metadata.parentId}`);
+
+      for (let i = 0; i < rows.length; i++) {
+        if (rows[i].id == row.metadata.parentId) {
+          let isChildInclude = checkAllChildInclude(rows[i], tempSelectedRows);
+          isChildInclude && tempSelectedRows.push(`${rows[i].metadata.parentId}`);
+          break;
+        }
+      }
+
+    }
+  }
+
+  function deselectChildAndSubChild(children, tempSelectedRows) {
+    children.map((chid) => {
+      let indx = tempSelectedRows.indexOf(chid);
+      indx != -1 && tempSelectedRows.splice(indx, 1);
+    });
+  }
+
+  function deselectResultRows(row, tempSelectedRows) {
+    if (row.metadata.isRoot) {
+      deselectChildAndSubChild(row.metadata.subChildren, tempSelectedRows);
+
+      deselectChildAndSubChild(row.metadata.children, tempSelectedRows);
+
+      let rootIndex = tempSelectedRows.indexOf(`${row.id}`);
+      rootIndex != -1 && tempSelectedRows.splice(rootIndex, 1);
+
+    } else if (row.metadata.subChildren) {
+      deselectChildAndSubChild(row.metadata.subChildren, tempSelectedRows);
+
+      let isChildAllInclude = true;
+      row.metadata.children.map((id) => {
+        if (tempSelectedRows.includes(id)) {
+          isChildAllInclude = false;
+        }
+      });
+
+      let rootIndex = tempSelectedRows.indexOf(`${row.id}`);
+      rootIndex != -1 && tempSelectedRows.splice(rootIndex, 1);
+
+      let parentIndex = tempSelectedRows.indexOf(`${row.metadata.parentId}`);
+      (!isChildAllInclude && parentIndex != -1) && tempSelectedRows.splice(parentIndex, 1);
+
+      row.metadata.dependencies.map((depid) => {
+        let depIndex = tempSelectedRows.indexOf(`${depid}`);
+        depIndex != -1 && tempSelectedRows.splice(depIndex, 1);
+      });
+
+    } else {
+      let elementIndex = tempSelectedRows.indexOf(`${row.id}`);
+      elementIndex != -1 && tempSelectedRows.splice(elementIndex, 1);
+
+      let parentElIndex = tempSelectedRows.indexOf(`${row.metadata.parentId}`);
+      parentElIndex != -1 && tempSelectedRows.splice(parentElIndex, 1);
+
+      let rootIndex = tempSelectedRows.indexOf(`${row.metadata.rootId}`);
+      rootIndex != -1 && tempSelectedRows.splice(rootIndex, 1);
+
+
+      row.dependencieRowIds.map((id) => {
+        let deptRowIndex = tempSelectedRows.indexOf(`${id}`);
+        deptRowIndex != -1 && tempSelectedRows.splice(deptRowIndex, 1);
+      });
+    }
+  }
+
+  const columns = [
+    {
+      key: 'id',
+      ...SelectColumn,
+      minWidth: 30,
+      width: 30,
+      headerRenderer() {
+        return (
+          <InputCheckbox
+            cid={_.uniqueId('rgc')}
+            className={classes.headerSelectCell}
+            value={selectedRows.length == allRowIds.length ? rootSelection : false}
+            size='small'
+            onChange={(e) => {
+              if (e.target.checked) {
+                setRootSelection(true);
+                setSelectedRows([...allRowIds]);
+                selectedRowIds([...allRowIds]);
+              } else {
+                setRootSelection(false);
+                setSelectedRows([]);
+                selectedRowIds([]);
+              }
+            }
+            }
+          ></InputCheckbox>
+        );
+      },
+      formatter({ row, isCellSelected }) {
+        isCellSelected && setActiveRow(row.id);
+        return (
+          <Box className={!row?.children && clsx(getStyleClassName(row, selectedRows, isCellSelected, activeRow, true), classes.selChBox)}>
+            <InputCheckbox
+              className={classes.selectCell}
+              cid={`${row.id}`}
+              value={selectedRows.includes(`${row.id}`)}
+              size='small'
+              onChange={(e) => {
+                setSelectedRows((prev) => {
+                  let tempSelectedRows = [...prev];
+                  if (!prev.includes(e.target.id)) {
+                    selectedResultRows(row, tempSelectedRows);
+                    tempSelectedRows.length === allRowIds.length && setRootSelection(true);
+                  } else {
+                    deselectResultRows(row, tempSelectedRows);
+                  }
+                  tempSelectedRows = new Set(tempSelectedRows);
+                  selectedRowIds([...tempSelectedRows]);
+                  return [...tempSelectedRows];
+                });
+              }
+              }
+            ></InputCheckbox>
+          </Box>
+        );
+      }
+    },
+    {
+      key: 'label',
+      name: 'Objects',
+      width: '80%',
+      colSpan(args) {
+        if (args.type === 'ROW' && 'children' in args.row) {
+          return 2;
+        }
+
+        return 1;
+      },
+      formatter({ row, isCellSelected }) {
+        const hasChildren = row.children !== undefined;
+        isCellSelected && setActiveRow(row.id);
+        return (
+          <>
+            {hasChildren && (
+
+              <CellExpanderFormatter
+                row={row}
+                isCellSelected={isCellSelected}
+                expanded={row.isExpanded === true}
+                filterParams={filterParams}
+                onCellExpand={() => dispatch({ id: row.id, type: 'toggleSubRow', filterParams: filterParams, gridData: gridData, selectedRows: selectedRows })}
+              />
+            )}
+            <div className="rdg-cell-value">
+
+              {!hasChildren && (
+                <Box className={clsx(getStyleClassName(row, selectedRows, isCellSelected, activeRow), classes.status)}>
+                  <span className={clsx(classes.recordRow, row.icon)}></span>
+                  {row.label}
+                </Box>
+              )}
+            </div>
+          </>
+        );
+      }
+    },
+    {
+      key: 'status',
+      name: 'Comparison Result',
+      formatter({ row, isCellSelected }) {
+        isCellSelected && setActiveRow(row.id);
+
+        return (
+          <Box className={getStyleClassName(row, selectedRows, isCellSelected, activeRow)}>
+            {row.status}
+          </Box>
+        );
+      }
+    },
+  ];
+
+  useEffect(() => {
+    let tempRows = gridData;
+    tempRows.map((row) => {
+      dispatch({ id: row.id, type: 'applyFilter', filterParams: filterParams, gridData: gridData, selectedRows: selectedRows });
+    });
+  }, [filterParams]);
+
+  const eventBus = useContext(SchemaDiffEventsContext);
+
+  const rowSelection = (row) => {
+
+    if (row.ddlData != undefined && row.status != FILTER_NAME.IDENTICAL) {
+      eventBus.fireEvent(SCHEMA_DIFF_EVENT.TRIGGER_CHANGE_RESULT_SQL, row.ddlData);
+    } else if (row.status == FILTER_NAME.IDENTICAL) {
+      let url_params = {
+        'trans_id': transId,
+        'source_sid': sourceData.sid,
+        'source_did': sourceData.did,
+        'source_scid': row.source_scid,
+        'target_sid': targetData.sid,
+        'target_did': targetData.did,
+        'target_scid': row.target_scid,
+        'comp_status': row.status,
+        'source_oid': row.source_oid,
+        'target_oid': row.target_oid,
+        'node_type': row.itemType,
+      };
+
+      let baseUrl = url_for('schema_diff.ddl_compare', url_params);
+      schemaDiffToolContext.api.get(baseUrl).then((res) => {
+        row.ddlData = {
+          'SQLdiff': res.data.diff_ddl,
+          'sourceSQL': res.data.source_ddl,
+          'targetSQL': res.data.target_ddl
+        };
+        eventBus.fireEvent(SCHEMA_DIFF_EVENT.TRIGGER_CHANGE_RESULT_SQL, row.ddlData);
+      }).catch((err) => {
+        Notifier.alert(err.message);
+      });
+    }
+  };
+
+  function rowKeyGetter(row) {
+    return row.id;
+  }
+
+  return (
+    <Box className={classes.root} flexGrow="1" minHeight="0" id="schema-diff-grid">
+      {
+        gridData ?
+          <PgReactDataGrid
+            id="schema-diff-result-grid"
+            columns={columns} rows={rows}
+            className={clsx('big-grid', classes.gridPanel, classes.grid)}
+            treeDepth={2}
+            enableRowSelect={true}
+            defaultColumnOptions={{
+              resizable: true
+            }}
+            headerRowHeight={28}
+            rowHeight={28}
+            onRowClick={rowSelection}
+            enableCellSelect={false}
+            rowKeyGetter={rowKeyGetter}
+            direction={'vertical-lr'}
+            noRowsText={gettext('No difference found')}
+            noRowsIcon={<InfoIcon className={classes.noRowsIcon} />}
+          />
+          :
+          <>
+            {gettext('Loading result grid...')}
+          </>
+      }
+    </Box>
+  );
+}
+
+ResultGridComponent.propTypes = {
+  gridData: PropTypes.array,
+  allRowIds: PropTypes.array,
+  filterParams: PropTypes.array,
+  selectedRowIds: PropTypes.func,
+  transId: PropTypes.number,
+  sourceData: PropTypes.object,
+  targetData: PropTypes.object,
+  'sourceData.sid': PropTypes.number,
+  'sourceData.did': PropTypes.number,
+  'targetData.sid': PropTypes.number,
+  'targetData.did': PropTypes.number,
+};
diff --git a/web/pgadmin/tools/schema_diff/static/js/components/Results.jsx b/web/pgadmin/tools/schema_diff/static/js/components/Results.jsx
new file mode 100644
index 00000000..2781e656
--- /dev/null
+++ b/web/pgadmin/tools/schema_diff/static/js/components/Results.jsx
@@ -0,0 +1,140 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+import gettext from 'sources/gettext';
+
+import React, { useContext, useState, useEffect } from 'react';
+
+import { Box } from '@material-ui/core';
+import { makeStyles } from '@material-ui/styles';
+import { InputSQL } from '../../../../../static/js/components/FormComponents';
+import { SchemaDiffEventsContext } from './SchemaDiffComponent';
+import { SCHEMA_DIFF_EVENT } from '../SchemaDiffConstants';
+
+
+const useStyles = makeStyles((theme) => ({
+  root: {
+    display: 'flex',
+    flexDirection: 'column',
+    flexGrow: 1,
+  },
+  table: {
+    minWidth: 650,
+  },
+  summaryContainer: {
+    flexGrow: 1,
+    minHeight: 0,
+    overflow: 'auto',
+  },
+  panelTitle: {
+    borderBottom: '1px solid ' + theme.otherVars.borderColor,
+    padding: '0.5rem',
+
+  },
+  editorStyle: {
+    height: '100%'
+  },
+  editor: {
+    height: '100%',
+    padding: '0.5rem 0.2rem 2rem 0.5rem',
+  },
+  editorLabel: {
+    padding: '0.3rem 0.6rem 0 0.6rem',
+  },
+  header: {
+    padding: '0.5rem',
+    borderBottom: '1px solid ' + theme.otherVars.borderColor,
+  },
+  sqlContainer: {
+    display: 'flex',
+    flexDirection: 'row',
+    padding: '0rem 0rem 0.5rem',
+    flexGrow: 1,
+    overflow: 'hidden'
+  },
+  sqldata: {
+    display: 'flex',
+    flexGrow: 1,
+    flexDirection: 'column',
+    padding: '0.2rem 0.5rem',
+    width: '33.33%',
+  },
+  label: {
+    flexGrow: 1,
+  }
+}));
+
+export function Results() {
+  const classes = useStyles();
+  const [sourceSQL, setSourceSQL] = useState(null);
+  const [targetSQL, setTargetSQL] = useState(null);
+  const [sqlDiff, setSqlDiff] = useState(null);
+
+  const eventBus = useContext(SchemaDiffEventsContext);
+
+  useEffect(() => {
+    eventBus.registerListener(
+      SCHEMA_DIFF_EVENT.TRIGGER_CHANGE_RESULT_SQL, triggerUpdateResult);
+
+  }, []);
+
+  const triggerUpdateResult = (resultData) => {
+    setSourceSQL(resultData.sourceSQL);
+    setTargetSQL(resultData.targetSQL);
+    setSqlDiff(resultData.SQLdiff);
+  };
+
+
+  return (
+    <>
+      <Box className={classes.header}>
+        <span>{gettext('DDL Comparision')}</span>
+      </Box>
+      <Box className={classes.sqlContainer}>
+        
+        <Box className={classes.sqldata}> 
+          <Box className={classes.label}>{gettext('Source')}</Box>
+          <InputSQL
+            onLable={true}
+            value={sourceSQL}
+            options={{
+              readOnly: true,
+            }}
+            readonly={true}
+          />
+        </Box>
+        <Box className={classes.sqldata}>
+          <Box className={classes.label}>{gettext('Target')}</Box>
+          <InputSQL
+            onLable={true}
+            value={targetSQL}
+            options={{
+              readOnly: true,
+            }}
+            readonly={true}
+          />
+        </Box>
+        <Box className={classes.sqldata}>
+          <Box className={classes.label}>{gettext('Difference')}</Box>
+          <InputSQL
+            onLable={true}
+            value={sqlDiff}
+            options={{
+              readOnly: true,
+            }}
+            readonly={true}
+          />
+        </Box>
+      </Box>
+    </>
+  );
+}
+
+Results.propTypes = {
+
+};
\ No newline at end of file
diff --git a/web/pgadmin/tools/schema_diff/static/js/components/SchemaDiffButtonComponent.jsx b/web/pgadmin/tools/schema_diff/static/js/components/SchemaDiffButtonComponent.jsx
new file mode 100644
index 00000000..569b9063
--- /dev/null
+++ b/web/pgadmin/tools/schema_diff/static/js/components/SchemaDiffButtonComponent.jsx
@@ -0,0 +1,223 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+import _ from 'lodash';
+import PropTypes from 'prop-types';
+
+import React, { useState, useRef, useContext, useEffect } from 'react';
+
+import gettext from 'sources/gettext';
+
+import { Box } from '@material-ui/core';
+import CompareArrowsRoundedIcon from '@material-ui/icons/CompareArrowsRounded';
+import FeaturedPlayListRoundedIcon from '@material-ui/icons/FeaturedPlayListRounded';
+import KeyboardArrowDownIcon from '@material-ui/icons/KeyboardArrowDown';
+import CheckRoundedIcon from '@material-ui/icons/CheckRounded';
+import { makeStyles } from '@material-ui/styles';
+
+import { DefaultButton, PgButtonGroup, PgIconButton, PrimaryButton } from '../../../../../static/js/components/Buttons';
+import { FilterIcon } from '../../../../../static/js/components/ExternalIcon';
+import { PgMenu, PgMenuItem, usePgMenuGroup } from '../../../../../static/js/components/Menu';
+import { FILTER_NAME, MENUS, MENUS_COMPARE_CONSTANT, SCHEMA_DIFF_EVENT } from '../SchemaDiffConstants';
+import { SchemaDiffContext, SchemaDiffEventsContext } from './SchemaDiffComponent';
+
+
+const useStyles = makeStyles((theme) => ({
+  emptyIcon: {
+    width: '1.5rem'
+  },
+  diff_btn: {
+    marginRight: '1rem'
+  },
+  noactionBtn: {
+    cursor: 'default',
+    '&:hover': {
+      backgroundColor: 'inherit',
+      cursor: 'default'
+    }
+  },
+  scriptBtn: {
+    display: 'flex',
+    justifyContent: 'flex-end',
+    paddingRight: '0.3rem',
+    [theme.breakpoints.down('sm')]: {
+      paddingTop: '0.3rem',
+      flexGrow: 1,
+    },
+  },
+  filterBtn: {
+    [theme.breakpoints.down('sm')]: {
+      paddingTop: '0.3rem',
+      flexGrow: 1,
+    }
+  },
+  compareBtn: {
+    display: 'flex',
+    flexGrow: 1,
+    justifyContent: 'flex-start',
+    paddingLeft: '1.5rem',
+    [theme.breakpoints.down('sm')]: {
+      paddingTop: '0.3rem',
+    },
+  }
+}));
+
+export function SchemaDiffButtonComponent({ sourceData, targetData, selectedRowIds, rows, compareParams, filterParams = [FILTER_NAME.DIFFERENT, FILTER_NAME.SOURCE_ONLY, FILTER_NAME.TARGET_ONLY] }) {
+  const classes = useStyles();
+
+  const filterRef = useRef(null);
+  const compareRef = useRef(null);
+
+  const eventBus = useContext(SchemaDiffEventsContext);
+  const schemaDiffCtx = useContext(SchemaDiffContext);
+
+  const [selectedFilters, setSelectedFilters] = useState(filterParams);
+  const [selectedCompare, setSelectedCompare] = useState([]);
+  const [isDisableCompare, setIsDisableCompare] = useState(true);
+
+  const { openMenuName, toggleMenu, onMenuClose } = usePgMenuGroup();
+
+  useEffect(() => {
+    let isDisableComp = true;
+    if (sourceData.sid != null && sourceData.did != null && targetData.sid != null && targetData.did != null) {
+      isDisableComp = false;
+    }
+    setIsDisableCompare(isDisableComp);
+  }, [sourceData, targetData]);
+
+  useEffect(() => {
+    let prefCompareOptions = [];
+
+    if (!_.isUndefined(compareParams)) {
+      compareParams.ignoreOwner && prefCompareOptions.push(MENUS_COMPARE_CONSTANT.COMPARE_IGNORE_OWNER);
+      compareParams.ignoreWhitespaces && prefCompareOptions.push(MENUS_COMPARE_CONSTANT.COMPARE_IGNORE_WHITESPACE);
+      setSelectedCompare(prefCompareOptions);
+    } else {
+      schemaDiffCtx?.preferences_schema_diff?.ignore_owner && prefCompareOptions.push(MENUS_COMPARE_CONSTANT.COMPARE_IGNORE_OWNER);
+      schemaDiffCtx?.preferences_schema_diff?.ignore_whitespaces && prefCompareOptions.push(MENUS_COMPARE_CONSTANT.COMPARE_IGNORE_WHITESPACE);
+      setSelectedCompare(prefCompareOptions);
+    }
+  }, [schemaDiffCtx.preferences_schema_diff]);
+
+
+  const selectFilterOption = (option) => {
+    let newOptions = [];
+    setSelectedFilters((prev) => {
+      let newSelectdOptions = [...prev];
+      let removeIndex = newSelectdOptions.indexOf(option);
+      if (prev.includes(option)) {
+        newSelectdOptions.splice(removeIndex, 1);
+      } else {
+        newSelectdOptions.push(option);
+      }
+      newOptions = [...newSelectdOptions];
+      return newSelectdOptions;
+    });
+
+    let filterParam = newOptions;
+    eventBus.fireEvent(SCHEMA_DIFF_EVENT.TRIGGER_CHANGE_FILTER, { filterParams: filterParam });
+  };
+
+  const selectCompareOption = (option) => {
+    setSelectedCompare((prev) => {
+      let newSelectdOptions = [...prev];
+      let removeIndex = newSelectdOptions.indexOf(option);
+      if (prev.includes(option)) {
+        newSelectdOptions.splice(removeIndex, 1);
+      } else {
+        newSelectdOptions.push(option);
+      }
+      return newSelectdOptions;
+    });
+  };
+
+  const compareDiff = () => {
+    let compareParam = {
+      'ignoreOwner': selectedCompare.includes(MENUS_COMPARE_CONSTANT.COMPARE_IGNORE_OWNER) ? 1 : 0,
+      'ignoreWhitespaces': selectedCompare.includes(MENUS_COMPARE_CONSTANT.COMPARE_IGNORE_WHITESPACE) ? 1 : 0,
+    };
+    let filterParam = selectedFilters;
+    eventBus.fireEvent(SCHEMA_DIFF_EVENT.TRIGGER_COMPARE_DIFF, { sourceData, targetData, compareParams: compareParam, filterParams: filterParam });
+    eventBus.fireEvent(SCHEMA_DIFF_EVENT.TRIGGER_CHANGE_RESULT_SQL, {
+      sourceSQL: null,
+      targetSQL: null,
+      SQLdiff: null,
+    });
+  };
+
+  const generateScript = () => {
+    eventBus.fireEvent(SCHEMA_DIFF_EVENT.TRIGGER_GENERATE_SCRIPT, { sid: targetData.sid, did: targetData.did, selectedIds: selectedRowIds, rows: rows });
+  };
+
+  return (
+    <>
+      <Box className={classes.compareBtn}>
+        <PgButtonGroup size="small" disabled={isDisableCompare}>
+          <PrimaryButton startIcon={<CompareArrowsRoundedIcon />}
+            onClick={compareDiff}>{gettext('Compare')}</PrimaryButton>
+          <PgIconButton title={gettext('Compare')} icon={<KeyboardArrowDownIcon />} color={'primary'} splitButton
+            name={MENUS.COMPARE} ref={compareRef} onClick={toggleMenu} ></PgIconButton>
+        </PgButtonGroup>
+      </Box>
+      <Box className={classes.scriptBtn}>
+        <PgButtonGroup size="small" disabled={selectedRowIds?.length > 0 ? false : true}>
+          <DefaultButton startIcon={<FeaturedPlayListRoundedIcon />} onClick={generateScript}>{gettext('Generate Script')}</DefaultButton>
+        </PgButtonGroup>
+      </Box>
+      <Box className={classes.filterBtn}>
+        <PgButtonGroup size="small" disabled={isDisableCompare} style={{ paddingRight: '0.3rem' }}>
+          <DefaultButton startIcon={<FilterIcon />} className={classes.noactionBtn}
+          >{gettext('Filter')}</DefaultButton>
+          <PgIconButton title={gettext('File')} icon={<KeyboardArrowDownIcon />} splitButton
+            name={MENUS.FILTER} ref={filterRef} onClick={toggleMenu} ></PgIconButton>
+        </PgButtonGroup>
+      </Box>
+      <PgMenu
+        anchorRef={compareRef}
+        open={openMenuName == MENUS.COMPARE}
+        onClose={onMenuClose}
+        label={gettext('Compare')}
+      >
+        <PgMenuItem onClick={() => { selectCompareOption(MENUS_COMPARE_CONSTANT.COMPARE_IGNORE_OWNER); }}>
+          {selectedCompare.includes(MENUS_COMPARE_CONSTANT.COMPARE_IGNORE_OWNER) ? <CheckRoundedIcon /> : <span className={classes.emptyIcon}></span>}{gettext('Ignore owner')}
+        </PgMenuItem>
+        <PgMenuItem onClick={() => { selectCompareOption(MENUS_COMPARE_CONSTANT.COMPARE_IGNORE_WHITESPACE); }}>
+          {selectedCompare.includes(MENUS_COMPARE_CONSTANT.COMPARE_IGNORE_WHITESPACE) ? <CheckRoundedIcon /> : <span className={classes.emptyIcon}></span>}{gettext('Ignore whitespace')}
+        </PgMenuItem>
+      </PgMenu>
+      <PgMenu
+        anchorRef={filterRef}
+        open={openMenuName == MENUS.FILTER}
+        onClose={onMenuClose}
+        label={gettext('Filter')}
+      >
+        <PgMenuItem onClick={() => { selectFilterOption(FILTER_NAME.IDENTICAL); }}>
+          {selectedFilters.includes(FILTER_NAME.IDENTICAL) ? <CheckRoundedIcon /> : <span className={classes.emptyIcon}></span>} {gettext(FILTER_NAME.IDENTICAL)}
+        </PgMenuItem>
+        <PgMenuItem onClick={() => { selectFilterOption(FILTER_NAME.DIFFERENT); }}>
+          {selectedFilters.includes(FILTER_NAME.DIFFERENT) ? <CheckRoundedIcon /> : <span className={classes.emptyIcon}></span>} {gettext(FILTER_NAME.DIFFERENT)}
+        </PgMenuItem>
+        <PgMenuItem onClick={() => { selectFilterOption(FILTER_NAME.SOURCE_ONLY); }}>
+          {selectedFilters.includes(FILTER_NAME.SOURCE_ONLY) ? <CheckRoundedIcon /> : <span className={classes.emptyIcon}></span>} {gettext(FILTER_NAME.SOURCE_ONLY)}
+        </PgMenuItem>
+        <PgMenuItem onClick={() => { selectFilterOption(FILTER_NAME.TARGET_ONLY); }}>
+          {selectedFilters.includes(FILTER_NAME.TARGET_ONLY) ? <CheckRoundedIcon /> : <span className={classes.emptyIcon}></span>} {gettext(FILTER_NAME.TARGET_ONLY)}
+        </PgMenuItem>
+      </PgMenu>
+    </>
+  );
+}
+
+SchemaDiffButtonComponent.propTypes = {
+  sourceData: PropTypes.object,
+  targetData: PropTypes.object,
+  selectedRowIds: PropTypes.array,
+  rows: PropTypes.array,
+  compareParams: PropTypes.object,
+  filterParams: PropTypes.array
+};
diff --git a/web/pgadmin/tools/schema_diff/static/js/components/SchemaDiffCompare.jsx b/web/pgadmin/tools/schema_diff/static/js/components/SchemaDiffCompare.jsx
new file mode 100644
index 00000000..b70adcfb
--- /dev/null
+++ b/web/pgadmin/tools/schema_diff/static/js/components/SchemaDiffCompare.jsx
@@ -0,0 +1,812 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+import _ from 'lodash';
+import PropTypes from 'prop-types';
+
+import React, { useContext, useEffect, useState } from 'react';
+
+import { Box, Grid } from '@material-ui/core';
+import InfoRoundedIcon from '@material-ui/icons/InfoRounded';
+import HelpIcon from '@material-ui/icons/HelpRounded';
+import { makeStyles } from '@material-ui/styles';
+
+import gettext from 'sources/gettext';
+import url_for from 'sources/url_for';
+import Loader from 'sources/components/Loader';
+import pgWindow from 'sources/window';
+
+import { PgButtonGroup, PgIconButton } from '../../../../../static/js/components/Buttons';
+import Notifier from '../../../../../static/js/helpers/Notifier';
+import ConnectServerContent from '../../../../../static/js/Dialogs/ConnectServerContent';
+import { generateScript } from '../../../../sqleditor/static/js/show_query_tool';
+import { FILTER_NAME, SCHEMA_DIFF_EVENT, TYPE } from '../SchemaDiffConstants';
+import { InputComponent } from './InputComponent';
+import { SchemaDiffButtonComponent } from './SchemaDiffButtonComponent';
+import { SchemaDiffContext, SchemaDiffEventsContext } from './SchemaDiffComponent';
+import { ResultGridComponent } from './ResultGridComponent';
+
+
+const useStyles = makeStyles(() => ({
+  table: {
+    minWidth: 650,
+  },
+  summaryContainer: {
+    flexGrow: 1,
+    minHeight: 0,
+    overflow: 'auto',
+  },
+  note: {
+    marginTop: '1.2rem',
+    textAlign: 'center',
+  },
+  helpBtn: {
+    display: 'flex',
+    flexDirection: 'row-reverse',
+    paddingRight: '0.3rem'
+  },
+  compareComp: {
+    flexGrow: 1,
+  },
+  diffBtn: {
+    display: 'flex',
+    justifyContent: 'flex-end'
+  }
+}));
+
+function generateFinalScript(script_array, scriptHeader, script_body) {
+  _.each(Object.keys(script_array).reverse(), function (s) {
+    if (script_array[s].length > 0) {
+      script_body += script_array[s].join('\n') + '\n\n';
+    }
+  });
+
+  return `${scriptHeader} BEGIN; \n ${script_body} END;`;
+}
+
+function checkAndGetSchemaQuery(data, script_array) {
+  /* Check whether the selected object belongs to source only schema
+     if yes then we will have to add create schema statement before creating any other object.*/
+
+  if (!_.isUndefined(data.source_schema_name) && !_.isNull(data.source_schema_name)) {
+    let schema_query = '\nCREATE SCHEMA IF NOT EXISTS ' + data.source_schema_name + ';\n';
+    if (script_array[data.dependLevel].indexOf(schema_query) == -1) {
+      script_array[data.dependLevel].push(schema_query);
+    }
+  }
+}
+
+function getGenerateScriptData(rows, selectedIds, script_array) {
+  for (let selRowVal of rows) {
+    if (selectedIds.includes(`${selRowVal.id}`)) {
+      let data = selRowVal;
+      if (!_.isUndefined(data.diff_ddl)) {
+        if (!(data.dependLevel in script_array)) script_array[data.dependLevel] = [];
+        checkAndGetSchemaQuery(data, script_array);
+        script_array[data.dependLevel].push(data.diff_ddl);
+      }
+    }
+  }
+}
+
+function raiseErrorOnFail(alertTitle, xhr) {
+  try {
+    if (_.isUndefined(xhr.response.data)) {
+      Notifier.alert(alertTitle, gettext('Unable to get the response text.'));
+    } else {
+      let err = JSON.parse(xhr.response.data);
+      Notifier.alert(alertTitle, err.errormsg);
+    }
+  } catch (e) {
+    Notifier.alert(alertTitle, gettext(e.message));
+  }
+}
+
+const onHelpClick=()=>{
+  let url = url_for('help.static', {'filename': 'schema_diff.html'});
+  window.open(url, 'pgadmin_help');
+};
+
+export function SchemaDiffCompare({ params }) {
+  const classes = useStyles();
+  const schemaDiffToolContext = useContext(SchemaDiffContext);
+  const eventBus = useContext(SchemaDiffEventsContext);
+
+  const [showResultGrid, setShowResultGrid] = useState(false);
+  const [selectedSourceSid, setSelectedSourceSid] = useState(null);
+  const [selectedTargetSid, setSelectedTargetSid] = useState(null);
+
+  const [sourceDatabaseList, setSourceDatabaseList] = useState([]);
+  const [targetDatabaseList, setTargetDatabaseList] = useState([]);
+  const [selectedSourceDid, setSelectedSourceDid] = useState(null);
+  const [selectedTargetDid, setSelectedTargetDid] = useState(null);
+
+  const [sourceSchemaList, setSourceSchemaList] = useState([]);
+  const [targetSchemaList, setTargetSchemaList] = useState([]);
+  const [selectedSourceScid, setSelectedSourceScid] = useState(null);
+  const [selectedTargetScid, setSelectedTargetScid] = useState(null);
+
+  const [sourceGroupServerList, setSourceGroupServerList] = useState([]);
+  const [gridData, setGridData] = useState([]);
+  const [allRowIdList, setAllRowIdList] = useState([]);
+  const [filterOptions, setFilterOptions] = useState([]);
+  const [compareOptions, setCompareOptions] = useState(undefined);
+  const [selectedRowIds, setSelectedRowIds] = useState([]);
+  const [loaderText, setLoaderText] = useState(null);
+  const [apiResult, setApiResult] = useState([]);
+  const [rowDep, setRowDep] = useState({});
+  const [isInit, setIsInit] = useState(true);
+
+  useEffect(() => {
+    schemaDiffToolContext.api.get(url_for('schema_diff.servers')).then((res) => {
+      let groupedOptions = [];
+      _.forIn(res.data.data, (val, _key) => {
+        if (val.lenght == 0) {
+          return;
+        }
+        groupedOptions.push({
+          label: _key,
+          options: val
+        });
+      });
+
+      setSourceGroupServerList(groupedOptions);
+    }).catch((err) => {
+      Notifier.alert(err.message);
+    });
+  }, []);
+
+  useEffect(() => {
+    // Register all eventes for debugger.
+    eventBus.registerListener(
+      SCHEMA_DIFF_EVENT.TRIGGER_SELECT_SERVER, triggerSelectServer);
+
+    eventBus.registerListener(
+      SCHEMA_DIFF_EVENT.TRIGGER_SELECT_DATABASE, triggerSelectDatabase);
+
+
+    eventBus.registerListener(
+      SCHEMA_DIFF_EVENT.TRIGGER_SELECT_SCHEMA, triggerSelectSchema);
+
+    eventBus.registerListener(
+      SCHEMA_DIFF_EVENT.TRIGGER_COMPARE_DIFF, triggerCompareDiff);
+
+    eventBus.registerListener(
+      SCHEMA_DIFF_EVENT.TRIGGER_CHANGE_FILTER, triggerChangeFilter);
+
+    eventBus.registerListener(
+      SCHEMA_DIFF_EVENT.TRIGGER_GENERATE_SCRIPT, triggerGenerateScript);
+
+  }, []);
+
+  function checkAndSetSourceData(diff_type, selectedOption) {
+    if(selectedOption == null) {
+      setSelectedRowIds([]);
+      setGridData([]);
+      if (diff_type == TYPE.SOURCE) {
+        setSelectedSourceSid(null);
+        setSelectedSourceDid(null);
+        setSelectedSourceScid(null);
+      } else {
+        setSelectedTargetSid(null);
+        setSelectedTargetDid(null);
+        setSelectedTargetScid(null);
+      }
+    }
+    
+  }
+
+  function setSourceTargetSid(diff_type, selectedOption) {
+    if (diff_type == TYPE.SOURCE) {
+      setSelectedSourceSid(selectedOption);
+    } else {
+      setSelectedTargetSid(selectedOption);
+    }
+  }
+
+  const triggerSelectServer = ({ selectedOption, diff_type, serverList }) => {
+    checkAndSetSourceData(diff_type, selectedOption);
+    for (const group of serverList) {
+      for (const opt of group.options) {
+        if (opt.value == selectedOption) {
+          if (!opt.connected) {
+            connectServer(selectedOption, diff_type, null, serverList);
+            break;
+          } else {
+            setSourceTargetSid(diff_type, selectedOption);
+            getDatabaseList(selectedOption, diff_type);
+          }
+        }
+      }
+    }
+    
+    setSourceGroupServerList(serverList);
+  };
+
+  const triggerSelectDatabase = ({ selectedServer, selectedDB, diff_type, databaseList }) => {
+    if(selectedDB == null) {
+      setGridData([]);
+    }
+    if (databaseList) {
+      for (const opt of databaseList) {
+        if (opt.value == selectedDB) {
+          if (!opt.connected) {
+            connectDatabase(selectedServer, selectedDB, diff_type, databaseList);
+            break;
+          } else {
+            getSchemaList(selectedServer, selectedDB, diff_type);
+            break;
+          }
+        }
+
+      }
+
+      if (diff_type == TYPE.SOURCE) {
+        setSelectedSourceDid(selectedDB);
+        setSourceDatabaseList(databaseList);
+      } else {
+        setSelectedTargetDid(selectedDB);
+        setTargetDatabaseList(databaseList);
+      }
+
+    }
+
+
+  };
+
+  const triggerSelectSchema = ({ selectedSC, diff_type }) => {
+
+    if (diff_type == TYPE.SOURCE) {
+      setSelectedSourceScid(selectedSC);
+    } else {
+      setSelectedTargetScid(selectedSC);
+    }
+  };
+
+  const triggerCompareDiff = ({ sourceData, targetData, compareParams, filterParams }) => {
+    setGridData([]);
+    setIsInit(false);
+    if (JSON.stringify(sourceData) === JSON.stringify(targetData)) {
+      Notifier.alert(gettext('Selection Error'),
+        gettext('Please select the different source and target.'));
+    } else {
+      getCompareStatus();
+      let schemaDiffPollInterval = setInterval(getCompareStatus, 1000);
+      setLoaderText('Comparing objects... (this may take a few minutes)...');
+      let url_params = {
+        'trans_id': params.transId,
+        'source_sid': sourceData['sid'],
+        'source_did': sourceData['did'],
+        'target_sid': targetData['sid'],
+        'target_did': targetData['did'],
+        'ignore_owner': compareParams['ignoreOwner'],
+        'ignore_whitespaces': compareParams['ignoreWhitespaces'],
+      };
+
+      let baseUrl = url_for('schema_diff.compare_database', url_params);
+      if (sourceData['scid'] != null && targetData['scid'] != null) {
+        url_params['source_scid'] = sourceData['scid'];
+        url_params['target_scid'] = targetData['scid'];
+        baseUrl = url_for('schema_diff.compare_schema', url_params);
+      }
+
+      setCompareOptions(compareParams);
+      schemaDiffToolContext.api.get(baseUrl).then((res) => {
+        setShowResultGrid(true);
+        setLoaderText(null);
+        clearInterval(schemaDiffPollInterval);
+        setFilterOptions(filterParams);
+        getResultGridData(res.data.data, filterParams);
+      }).catch((err) => {
+        setLoaderText(null);
+        setShowResultGrid(false);
+        Notifier.error(gettext(err.message));
+      });
+
+    }
+  };
+
+  const triggerChangeFilter = ({ filterParams }) => {
+    setFilterOptions(filterParams);
+  };
+
+  const triggerGenerateScript = ({ sid, did, selectedIds, rows }) => {
+    setLoaderText(gettext('Generating script...'));
+    let generatedScript = undefined, scriptHeader;
+
+    scriptHeader = gettext('-- This script was generated by the Schema Diff utility in pgAdmin 4. \n');
+    scriptHeader += gettext('-- For the circular dependencies, the order in which Schema Diff writes the objects is not very sophisticated \n');
+    scriptHeader += gettext('-- and may require manual changes to the script to ensure changes are applied in the correct order.\n');
+    scriptHeader += gettext('-- Please report an issue for any failure with the reproduction steps. \n');
+
+    if (selectedIds.length > 0) {
+      let script_array = { 1: [], 2: [], 3: [], 4: [], 5: [] },
+        script_body = '';
+      getGenerateScriptData(rows, selectedIds, script_array);
+
+      generatedScript = generateFinalScript(script_array, scriptHeader, script_body);
+      openQueryTool({ sid: sid, did: did, generatedScript: generatedScript, scriptHeader: scriptHeader });
+    } else {
+      openQueryTool({ sid: sid, did: did, scriptHeader: scriptHeader });
+    }
+  };
+
+  function openQueryTool({ sid, did, generatedScript, scriptHeader }) {
+    let baseServerUrl = url_for('schema_diff.get_server', { 'sid': sid, 'did': did });
+
+    schemaDiffToolContext.api({
+      url: baseServerUrl,
+      method: 'GET',
+      dataType: 'json',
+      contentType: 'application/json',
+    })
+      .then(function (res) {
+        let data = res.data.data;
+        let serverData = {};
+        if (data) {
+          let sqlId = `schema${params.transId}`;
+          serverData['sgid'] = data.gid;
+          serverData['sid'] = data.sid;
+          serverData['stype'] = data.type;
+          serverData['server'] = data.name;
+          serverData['user'] = data.user;
+          serverData['did'] = did;
+          serverData['database'] = data.database;
+          serverData['sql_id'] = sqlId;
+
+          if (_.isUndefined(generatedScript)) {
+            generatedScript = scriptHeader + 'BEGIN;' + '\n' + '' + '\n' + 'END;';
+          }
+          localStorage.setItem(sqlId, generatedScript);
+          generateScript(serverData, pgWindow.pgAdmin.Tools.SQLEditor);
+          setLoaderText(null);
+        }
+
+      })
+      .catch(function (xhr) {
+        setLoaderText(null);
+        raiseErrorOnFail(gettext('Generate script error'), xhr);
+      });
+  }
+
+  function generateGridData(record, tempData, allRowIds, filterParams) {
+    if (record.group_name in tempData && record.label in tempData[record.group_name]['children']) {
+      let chidId = record.id;
+      allRowIds.push(`${chidId}`);
+
+      tempData[record.group_name]['children'][record.label]['children'].push({
+        'id': chidId,
+        'parentId': tempData[record.group_name]['children'][record.label].id,
+        'label': record.title,
+        'status': record.status,
+        'isVisible': filterParams.includes(record.status) ? true : false,
+        'icon': `icon-${record.type}`,
+        'isExpanded': false,
+        'selected': false,
+        'oid': record.oid,
+        'itemType': record.type,
+        'source_oid': record.source_oid,
+        'target_oid': record.target_oid,
+        'source_scid': record.source_scid,
+        'target_scid': record.target_scid,
+        'dependenciesOid': record.dependencies.map(({ oid }) => oid),
+        'dependencies': record.dependencies,
+        'dependencieRowIds': [],
+        'ddlData': {
+          'SQLdiff': record.diff_ddl,
+          'sourceSQL': record.source_ddl,
+          'targetSQL': record.target_ddl
+        }
+      });
+
+    } else if (record.group_name in tempData) {
+      let chidId = Math.floor(Math.random() * 1000000);
+      allRowIds.push(`${chidId}`);
+
+      let subChildId = record.id;
+      allRowIds.push(`${subChildId}`);
+      tempData[record.group_name]['children'][record.label] = {
+        'id': chidId,
+        'parentId': tempData[record.group_name]['id'],
+        'label': record.label,
+        'identicalCount': 0,
+        'differentCount': 0,
+        'sourceOnlyCount': 0,
+        'targetOnlyCount': 0,
+        'icon': `icon-coll-${record.type}`,
+        'isExpanded': false,
+        'selected': false,
+        'children': [{
+          'id': subChildId,
+          'parentId': chidId,
+          'label': record.title,
+          'status': record.status,
+          'isVisible': filterParams.includes(record.status) ? true : false,
+          'icon': `icon-${record.type}`,
+          'isExpanded': false,
+          'selected': false,
+          'oid': record.oid,
+          'itemType': record.type,
+          'source_oid': record.source_oid,
+          'target_oid': record.target_oid,
+          'source_scid': record.source_scid,
+          'target_scid': record.target_scid,
+          'dependenciesOid': record.dependencies.map(({ oid }) => oid),
+          'dependencies': record.dependencies,
+          'dependencieRowIds': [],
+          'ddlData': {
+            'SQLdiff': record.diff_ddl,
+            'sourceSQL': record.source_ddl,
+            'targetSQL': record.target_ddl
+          }
+        }]
+      };
+    } else {
+      let label = record.label;
+      let _id = Math.floor(Math.random() * 100000);
+      let _subChildId = Math.floor(Math.random() * 100000);
+      allRowIds.push(`${_id}`);
+      allRowIds.push(`${_subChildId}`);
+      tempData[record.group_name] = {
+        'id': _id,
+        'label': record.group_name,
+        'icon': record.group_name == 'Database Objects' ? 'icon-coll-database' : 'icon-schema',
+        'groupType': record.group_name,
+        'isExpanded': false,
+        'selected': false,
+        'children': {}
+      };
+      let ch_id = record.id;
+      allRowIds.push(`${ch_id}`);
+      tempData[record.group_name]['children'][label] = {
+        'id': _subChildId,
+        'parentId': _id,
+        'label': record.label,
+        'identicalCount': 0,
+        'differentCount': 0,
+        'sourceOnlyCount': 0,
+        'targetOnlyCount': 0,
+        'selected': false,
+        'icon': `icon-coll-${record.type}`,
+        'isExpanded': false,
+        'children': [{
+          'id': ch_id,
+          'parentId': _subChildId,
+          'label': record.title,
+          'status': record.status,
+          'selected': false,
+          'itemType': record.type,
+          'isVisible': filterParams.includes(record.status) ? true : false,
+          'icon': `icon-${record.type}`,
+          'isExpanded': false,
+          'oid': record.oid,
+          'source_oid': record.source_oid,
+          'target_oid': record.target_oid,
+          'source_scid': record.source_scid,
+          'target_scid': record.target_scid,
+          'dependenciesOid': record.dependencies.map(({ oid }) => oid),
+          'dependencies': record.dependencies,
+          'dependencieRowIds': [],
+          'ddlData': {
+            'SQLdiff': record.diff_ddl,
+            'sourceSQL': record.source_ddl,
+            'targetSQL': record.target_ddl
+          }
+        }]
+      };
+    }
+  }
+
+  function getResultGridData(gridDataList, filterParams) {
+    let tempData = {};
+    let allRowIds = [];
+    setApiResult(gridDataList);
+    gridDataList.map((record) => {
+      generateGridData(record, tempData, allRowIds, filterParams);
+    });
+
+    let keyList = Object.keys(tempData);
+    let temp = [];
+    let rowDependencies = {};
+    for (let i = 0; i < keyList.length; i++) {
+      tempData[keyList[i]]['children'] = Object.values(tempData[keyList[i]]['children']);
+
+      let subChildList = [];
+      tempData[keyList[i]]['children'].map((ch) => ch.children.map(({ id }) => subChildList.push(`${id}`)));
+      tempData[keyList[i]]['metadata'] = {
+        isRoot: true,
+        children: tempData[keyList[i]]['children'].map(({ id }) => `${id}`),
+        subChildren: subChildList,
+      };
+      tempData[keyList[i]]['children'].map((child) => {
+        child['metadata'] = {
+          parentId: tempData[keyList[i]].id,
+          children: tempData[keyList[i]]['children'].map(({ id }) => `${id}`),
+          subChildren: child.children.map(({ id }) => `${id}`),
+          dependencies: [],
+        };
+        child.children.map((ch) => {
+          if (ch.dependenciesOid.length > 0) {
+            tempData[keyList[i]]['children'].map((el) => {
+              el.children.map((data) => {
+                if (ch.dependenciesOid.includes(data.oid)) {
+                  ch.dependencieRowIds.push(`${data.id}`);
+                }
+              });
+
+            });
+          }
+          ch['metadata'] = {
+            parentId: child.id,
+            rootId: tempData[keyList[i]].id,
+            children: child.children.map(({ id }) => `${id}`),
+
+          };
+          child['metadata']['dependencies'].push(...ch.dependencieRowIds);
+        });
+
+
+      });
+      temp.push(tempData[keyList[i]]);
+    }
+
+    setRowDep(rowDependencies);
+    setShowResultGrid(true);
+    setGridData(temp);
+    setAllRowIdList([...new Set(allRowIds)]);
+  }
+
+  const getCompareStatus = () => {
+    let url_params = { 'trans_id': params.transId };
+
+    schemaDiffToolContext.api.get(url_for('schema_diff.poll', url_params)).then((res) => {
+      let msg = res.data.data.compare_msg;
+      if (res.data.data.diff_percentage != 100) {
+        msg = msg + gettext(` (this may take a few minutes)... ${res.data.data.diff_percentage} %`);
+        setLoaderText(msg);
+      }
+
+    })
+      .catch((err) => {
+        Notifier.error(gettext(err.message));
+      });
+  };
+
+  const connectDatabase = (sid, selectedDB, diff_type, databaseList) => {
+    schemaDiffToolContext.api({
+      method: 'POST',
+      url: url_for('schema_diff.connect_database', { 'sid': sid, 'did': selectedDB }),
+      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
+    }).then((res) => {
+      let dbList = databaseList;
+      for (const opt of dbList) {
+        if (opt.value == selectedDB) {
+          opt.connected = true;
+          opt.image = res.data.data.icon || 'pg-icon-database';
+          getSchemaList(sid, selectedDB, diff_type);
+          if (diff_type == TYPE.SOURCE) {
+            setSelectedSourceDid(selectedDB);
+            setSourceDatabaseList(dbList);
+          } else {
+            setSelectedTargetDid(selectedDB);
+            setTargetDatabaseList(dbList);
+          }
+          break;
+        }
+      }
+    }).catch((error) => {
+      Notifier.error(gettext(`Error in connect database ${error.response.data}`));
+    });
+
+  };
+
+  const connectServer = (sid, diff_type, formData = null, serverList = []) => {
+    try {
+      schemaDiffToolContext.api({
+        method: 'POST',
+        url: url_for('schema_diff.connect_server', { 'sid': sid }),
+        data: formData,
+        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
+      }).then((res) => {
+        for (const group of serverList) {
+          for (const opt of group.options) {
+            if (opt.value == sid) {
+              opt.connected = true;
+              opt.image = res.data.data.icon || 'icon-pg';
+              break;
+            }
+          }
+        }
+                
+        if (diff_type == TYPE.SOURCE) {
+          setSelectedSourceSid(sid);
+        } else {
+          setSelectedTargetSid(sid);
+        }
+
+        setSourceGroupServerList(serverList);
+        getDatabaseList(sid, diff_type);
+      }).catch((error) => {
+        showConnectServer(error.response?.data.result, sid, diff_type, serverList);
+      });
+    } catch (error) {
+      Notifier.error(gettext(`Error in connect server ${error.response.data}` ));
+    }
+  };
+
+  function getDatabaseList(sid, diff_type) {
+    schemaDiffToolContext.api.get(
+      url_for('schema_diff.databases', { 'sid': sid })
+    ).then((res) => {
+      res.data.data.map((opt) => {
+
+        if (opt.is_maintenance_db) {
+          if (diff_type == TYPE.SOURCE) {
+            setSelectedSourceDid(opt.value);
+          } else {
+            setSelectedTargetDid(opt.value);
+          }
+          getSchemaList(sid, opt.value, diff_type);
+        }
+      });
+      if (diff_type == TYPE.SOURCE) {
+        setSourceDatabaseList(res.data.data);
+      } else {
+        setTargetDatabaseList(res.data.data);
+      }
+
+    });
+  }
+
+  function getSchemaList(sid, did, diff_type) {
+    schemaDiffToolContext.api.get(
+      url_for('schema_diff.schemas', { 'sid': sid, 'did': did })
+    ).then((res) => {
+      if (diff_type == TYPE.SOURCE) {
+        setSourceSchemaList(res.data.data);
+      } else {
+        setTargetSchemaList(res.data.data);
+      }
+
+    });
+  }
+
+  function showConnectServer(result, sid, diff_type, serverList) {
+    schemaDiffToolContext.modal.showModal(gettext('Connect to server'), (closeModal) => {
+      return (
+        <ConnectServerContent
+          closeModal={() => {
+            closeModal();
+          }}
+          data={result}
+          onOK={(formData) => {
+            connectServer(sid, diff_type, formData, serverList);
+          }}
+        />
+      );
+    });
+  }
+
+  function getFilterParams() {
+    let opt = [];
+    if(isInit && filterOptions.length == 0) {
+      opt = [FILTER_NAME.DIFFERENT, FILTER_NAME.SOURCE_ONLY, FILTER_NAME.TARGET_ONLY];
+    } else if(filterOptions.length > 0 ) {
+      opt = filterOptions; 
+    }
+    return opt;
+  }
+
+  return (
+    <>
+      <Loader message={loaderText} style={{fontWeight: 900}}></Loader>
+      <Box id='compare-container-schema-diff'>
+        <Grid
+          container
+          direction="row"
+          alignItems="center"
+          key={_.uniqueId('c')}
+        >
+          <Grid item lg={7} md={7} sm={10} xs={10} key={_.uniqueId('c')}>
+            <InputComponent
+              label={gettext('Select Source')}
+              serverList={sourceGroupServerList}
+              databaseList={sourceDatabaseList}
+              schemaList={sourceSchemaList}
+              selectedSid={selectedSourceSid}
+              selectedDid={selectedSourceDid}
+              selectedScid={selectedSourceScid}
+              diff_type={TYPE.SOURCE}
+            ></InputComponent>
+          </Grid>
+          <Grid item lg={5} md={5} sm={2} xs={2} key={_.uniqueId('c')} className={classes.helpBtn}>
+            <PgButtonGroup size="small">
+              <PgIconButton data-test='schema-diff-help' title={gettext('Help')} icon={<HelpIcon />} onClick={onHelpClick} />
+            </PgButtonGroup>
+          </Grid>
+        </Grid>
+        <Grid
+          container
+          direction="row"
+          alignItems="center"
+          key={_.uniqueId('c')}
+        >
+          <Grid item lg={7} md={7} sm={10} xs={10} key={_.uniqueId('c')}>
+            <InputComponent
+              label={gettext('Select Target')}
+              serverList={sourceGroupServerList}
+              databaseList={targetDatabaseList}
+              schemaList={targetSchemaList}
+              selectedSid={selectedTargetSid}
+              selectedDid={selectedTargetDid}
+              selectedScid={selectedTargetScid}
+              diff_type={TYPE.TARGET}
+            ></InputComponent>
+          </Grid>
+        
+          <Grid item lg={5} md={5} sm={12} xs={12} key={_.uniqueId('c')} className={classes.diffBtn}>
+            <SchemaDiffButtonComponent
+              sourceData={{
+                'sid': selectedSourceSid,
+                'did': selectedSourceDid,
+                'scid': selectedSourceScid,
+              }}
+              selectedRowIds={selectedRowIds}
+              rows={apiResult}
+              targetData={{
+                'sid': selectedTargetSid,
+                'did': selectedTargetDid,
+                'scid': selectedTargetScid,
+              }}           
+              filterParams={getFilterParams()}
+              compareParams={compareOptions}
+            ></SchemaDiffButtonComponent>
+          </Grid>
+        </Grid>
+      </Box>
+      {showResultGrid && gridData.length > 0  && selectedTargetDid && selectedSourceDid ?
+        <ResultGridComponent
+          gridData={gridData}
+          allRowIds={allRowIdList}
+          filterParams={filterOptions}
+          selectedRowIds={(rows) => { setSelectedRowIds(rows); }}
+          rowDependencies={rowDep}
+          transId={params.transId}
+          sourceData={{
+            'sid': selectedSourceSid,
+            'did': selectedSourceDid,
+            'scid': selectedSourceScid,
+          }}
+          targetData={{
+            'sid': selectedTargetSid,
+            'did': selectedTargetDid,
+            'scid': selectedTargetScid,
+          }}
+        ></ResultGridComponent>
+        :
+        <Box className={classes.note}>
+          <InfoRoundedIcon style={{ fontSize: '1.2rem' }} />
+          {gettext(' Source and Target database server must be of the same major version.')}<br />
+          <strong>{gettext(' Database Compare:')}</strong>
+          {gettext(' Select the server and database for the source and target and Click')} <strong>{gettext('Compare.')}</strong>
+          <br />
+          <strong>{gettext('Schema Compare:')}</strong>
+          {gettext(' Select the server, database and schema for the source and target and Click')} <strong>{gettext('Compare.')}</strong>
+          <br />
+          <strong>{gettext('Note:')}</strong> {gettext('The dependencies will not be resolved in the Schema comparison.')}
+        </Box>
+      }
+    </>
+  );
+}
+
+SchemaDiffCompare.propTypes = {
+  params: PropTypes.object,
+  'params.transId': PropTypes.number,
+
+};
\ No newline at end of file
diff --git a/web/pgadmin/tools/schema_diff/static/js/components/SchemaDiffComponent.jsx b/web/pgadmin/tools/schema_diff/static/js/components/SchemaDiffComponent.jsx
new file mode 100644
index 00000000..fa374333
--- /dev/null
+++ b/web/pgadmin/tools/schema_diff/static/js/components/SchemaDiffComponent.jsx
@@ -0,0 +1,124 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+
+
+import React, { createContext, useCallback, useEffect, useMemo, useRef, useState } from 'react';
+import PropTypes from 'prop-types';
+import {DividerBox} from 'rc-dock';
+
+import url_for from 'sources/url_for';
+
+import { Box, makeStyles } from '@material-ui/core';
+
+import { Results } from './Results';
+import { SchemaDiffCompare } from './SchemaDiffCompare';
+import EventBus from '../../../../../static/js/helpers/EventBus';
+import getApiInstance from '../../../../../static/js/api_instance';
+import { useModal } from '../../../../../static/js/helpers/ModalProvider';
+
+export const SchemaDiffEventsContext = createContext();
+export const SchemaDiffContext = createContext();
+
+const useStyles = makeStyles((theme) => ({
+  resetRoot: {
+    padding: '2px 4px',
+    display: 'flex',
+    alignItems: 'center',
+    gap: '4px',
+    backgroundColor: theme.otherVars.editorToolbarBg,
+    flexWrap: 'wrap',
+    ...theme.mixins.panelBorder.bottom,
+
+    '& #id-schema-diff': {
+      overflow: 'auto'
+    },
+
+    '& #id-results': {
+      overflow: 'auto'
+    }
+  },
+  resultPanle: {
+    backgroundColor: theme.palette.default.main,
+    zIndex: 5,
+    border: '1px solid ' + theme.otherVars.borderColor, 
+    display: 'flex',
+    flexDirection: 'column',
+    flexGrow: 1,
+    height: '50%', 
+    minHeight: 150,
+    overflow: 'hidden',   
+  },
+  comparePanel:{
+    overflow: 'hidden',
+    border: '1px solid ' + theme.otherVars.borderColor, 
+    display: 'flex',
+    flexDirection: 'column',
+    flexGrow: 1,
+    minHeight: 150,
+    height: '50%',
+  }
+}));
+
+export default function SchemaDiffComponent({params}) {
+  const classes = useStyles();
+  const eventBus = useRef(new EventBus());
+  const containerRef = React.useRef(null);
+  const api = getApiInstance();
+  const modal = useModal();
+  const [schemaDiffState, setSchemaDiffState] = useState({
+    preferences: null
+  });
+
+  const schemaDiffContextValue = useMemo(()=> ({
+    api: api,
+    modal: modal,
+    preferences_schema_diff: schemaDiffState.preferences
+  }), [schemaDiffState.preferences]);
+
+  registerUnload();
+  useEffect(() => {
+    reflectPreferences();
+    params.pgAdmin.Browser.onPreferencesChange('schema_diff', function () {
+      reflectPreferences();
+    });
+  }, []);
+
+  const reflectPreferences = useCallback(() => {
+    setSchemaDiffState({
+      preferences: params.pgAdmin.Browser.get_preferences_for_module('schema_diff')
+    });
+  }, []);
+
+  function registerUnload() {
+    window.addEventListener('unload', ()=>{
+      api.delete(url_for('schema_diff.close', {
+        trans_id: params.transId
+      }));
+    });
+  }
+    
+  return (
+    <SchemaDiffContext.Provider value={schemaDiffContextValue}>
+      <SchemaDiffEventsContext.Provider value={eventBus.current}>
+        <Box display="flex" flexDirection="column" flexGrow="1" tabIndex="0" style={{overflowY: 'auto', minHeight: 80}}>
+          <DividerBox mode='vertical' style={{flexGrow: 1}}>
+            <div className={classes.comparePanel} id="schema-diff-compare-container" ref={containerRef}><SchemaDiffCompare params={params} /></div>
+            <div className={classes.resultPanle} id="schema-diff-result-container">
+              <Results />
+            </div>
+          </DividerBox>
+        </Box>
+      </SchemaDiffEventsContext.Provider>
+    </SchemaDiffContext.Provider>
+  );
+}
+
+SchemaDiffComponent.propTypes = {
+  params: PropTypes.object
+};
\ No newline at end of file
diff --git a/web/pgadmin/tools/schema_diff/static/js/index.js b/web/pgadmin/tools/schema_diff/static/js/index.js
new file mode 100644
index 00000000..7ed84df3
--- /dev/null
+++ b/web/pgadmin/tools/schema_diff/static/js/index.js
@@ -0,0 +1,22 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+
+import pgAdmin from 'sources/pgadmin';
+import pgBrowser from 'top/browser/static/js/browser';
+import SchemaDiff from './SchemaDiffModule';
+
+if (!pgAdmin.Tools) {
+  pgAdmin.Tools = {};
+}
+
+pgAdmin.Tools.SchemaDiff = SchemaDiff.getInstance(pgAdmin, pgBrowser);
+
+module.exports = {
+  SchemaDiff: SchemaDiff,
+};
diff --git a/web/pgadmin/tools/schema_diff/static/js/schema_diff.backform.js b/web/pgadmin/tools/schema_diff/static/js/schema_diff.backform.js
deleted file mode 100644
index 1bedf59c..00000000
--- a/web/pgadmin/tools/schema_diff/static/js/schema_diff.backform.js
+++ /dev/null
@@ -1,543 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import $ from 'jquery';
-import Backbone from 'backbone';
-import Backform from 'pgadmin.backform';
-import gettext from 'sources/gettext';
-import clipboard from 'sources/selection/clipboard';
-
-var formatNode = function (opt) {
-  if (!opt.id) {
-    return opt.text;
-  }
-
-  var optimage = $(opt.element).data('image');
-
-  if (!optimage) {
-    return opt.text;
-  } else {
-    return $('<span></span>').append(
-      $('<span></span>', {
-        class: 'wcTabIcon ' + optimage,
-      })
-    ).append($('<span></span>').text(opt.text));
-  }
-};
-
-let SchemaDiffSqlControl =
-  Backform.SqlFieldControl.extend({
-    defaults: {
-      label: '',
-      extraClasses: [], // Add default control height
-      helpMessage: null,
-      maxlength: 4096,
-      rows: undefined,
-      copyRequired: false,
-    },
-
-    template: _.template([
-      '<% if (copyRequired) { %><button class="btn btn-secondary ddl-copy d-none">' + gettext('Copy') + '</button> <% } %>',
-      '<div class="pgadmin-controls pg-el-9 pg-el-12 sql_field_layout <%=extraClasses.join(\' \')%>">',
-      '  <textarea ',
-      '    class="<%=Backform.controlClassName%> " name="<%=name%>" aria-label="<%=name%>"',
-      '    maxlength="<%=maxlength%>" placeholder="<%-placeholder%>" <%=disabled ? "disabled" : ""%>',
-      '    rows=<%=rows%>',
-      '    <%=required ? "required" : ""%>><%-value%></textarea>',
-      '  <% if (helpMessage && helpMessage.length) { %>',
-      '    <span class="<%=Backform.helpMessageClassName%>"><%=helpMessage%></span>',
-      '  <% } %>',
-      '</div>',
-    ].join('\n')),
-    initialize: function() {
-      Backform.TextareaControl.prototype.initialize.apply(this, arguments);
-      this.sqlCtrl = null;
-
-      _.bindAll(this, 'onFocus', 'onBlur', 'refreshTextArea', 'copyData');
-    },
-    render: function() {
-      let obj = Backform.SqlFieldControl.prototype.render.apply(this, arguments);
-
-      obj.sqlCtrl.setOption('readOnly', true);
-      if(this.$el.find('.ddl-copy')) this.$el.find('.ddl-copy').on('click', this.copyData);
-      return obj;
-    },
-    copyData() {
-      event.stopPropagation();
-      clipboard.copyTextToClipboard(this.model.get('diff_ddl'));
-      this.$el.find('.ddl-copy').text(gettext('Copied!'));
-      var self = this;
-      setTimeout(function() {
-        let $copy = self.$el.find('.ddl-copy');
-        if (!$copy.hasClass('d-none')) $copy.addClass('d-none');
-        $copy.text(gettext('Copy'));
-      }, 3000);
-      return false;
-    },
-    onFocus: function() {
-      let $ctrl = this.$el.find('.pgadmin-controls').first(),
-        $copy = this.$el.find('.ddl-copy');
-      if (!$ctrl.hasClass('focused')) $ctrl.addClass('focused');
-      if ($copy.hasClass('d-none')) $copy.removeClass('d-none');
-
-    },
-  });
-
-let SchemaDiffSelect2Control =
-  Backform.Select2Control.extend({
-    defaults: _.extend(Backform.Select2Control.prototype.defaults, {
-      url: undefined,
-      transform: undefined,
-      url_with_id: false,
-      select2: {
-        allowClear: true,
-        placeholder: gettext('Select an item...'),
-        width: 'style',
-        templateResult: formatNode,
-        templateSelection: formatNode,
-      },
-      controlsClassName: 'pgadmin-controls pg-el-sm-11 pg-el-12',
-    }),
-    className: function() {
-      return 'pgadmin-controls pg-el-sm-4';
-    },
-    events: {
-      'focus select': 'clearInvalid',
-      'keydown :input': 'processTab',
-      'select2:select': 'onSelect',
-      'select2:selecting': 'beforeSelect',
-      'select2:clear': 'onChange',
-    },
-    template: _.template([
-      '<% if(label == false) {} else {%>',
-      '  <label class="<%=Backform.controlLabelClassName%>"><%=label%></label>',
-      '<% }%>',
-      '<div class="<%=controlsClassName%>">',
-      ' <select class="<%=Backform.controlClassName%> <%=extraClasses.join(\' \')%>"',
-      '  name="<%=name%>" aria-label="<%=name%>" value="<%-value%>" <%=disabled ? "disabled" : ""%>',
-      '  <%=required ? "required" : ""%><%= select2.multiple ? " multiple>" : ">" %>',
-      '  <%=select2.first_empty ? " <option></option>" : ""%>',
-      '  <% for (var i=0; i < options.length; i++) {%>',
-      '   <% if (options[i].group) { %>',
-      '     <% var group = options[i].group; %>',
-      '     <% if (options[i].optval) { %> <% var option_length = options[i].optval.length; %>',
-      '      <optgroup label="<%=group%>">',
-      '      <% for (var subindex=0; subindex < option_length; subindex++) {%>',
-      '        <% var option = options[i].optval[subindex]; %>',
-      '        <option ',
-      '        <% if (option.image) { %> data-image=<%=option.image%> <%}%>',
-      '        <% if (option.connected) { %> data-connected=connected <%}%>',
-      '        value=<%- formatter.fromRaw(option.value) %>',
-      '        <% if (option.selected) {%>selected="selected"<%} else {%>',
-      '        <% if (!select2.multiple && option.value === rawValue) {%>selected="selected"<%}%>',
-      '        <% if (select2.multiple && rawValue && rawValue.indexOf(option.value) != -1){%>selected="selected" data-index="rawValue.indexOf(option.value)"<%}%>',
-      '        <%}%>',
-      '        <%= disabled ? "disabled" : ""%>><%-option.label%></option>',
-      '      <%}%>',
-      '      </optgroup>',
-      '     <%}%>',
-      '   <%} else {%>',
-      '     <% var option = options[i]; %>',
-      '     <option ',
-      '     <% if (option.image) { %> data-image=<%=option.image%> <%}%>',
-      '     <% if (option.connected) { %> data-connected=connected <%}%>',
-      '     value=<%- formatter.fromRaw(option.value) %>',
-      '     <% if (option.selected) {%>selected="selected"<%} else {%>',
-      '     <% if (!select2.multiple && option.value === rawValue) {%>selected="selected"<%}%>',
-      '     <% if (select2.multiple && rawValue && rawValue.indexOf(option.value) != -1){%>selected="selected" data-index="rawValue.indexOf(option.value)"<%}%>',
-      '     <%}%>',
-      '     <%= disabled ? "disabled" : ""%>><%-option.label%></option>',
-      '   <%}%>',
-      '  <%}%>',
-      ' </select>',
-      ' <% if (helpMessage && helpMessage.length) { %>',
-      ' <span class="<%=Backform.helpMessageClassName%>"><%=helpMessage%></span>',
-      ' <% } %>',
-      '</div>',
-    ].join('\n')),
-    beforeSelect: function() {
-      var selVal = arguments[0].params.args.data.id;
-
-      if(this.field.get('connect') && this.$el.find('option[value="'+selVal+'"]').attr('data-connected') !== 'connected') {
-        this.field.get('connect').apply(this, [selVal, this.changeIcon.bind(this)]);
-      } else {
-        $(this.$sel).trigger('change');
-        setTimeout(function(){ this.onChange.apply(this); }.bind(this), 200);
-      }
-    },
-    changeIcon: function(data) {
-      let span = this.$el.find('.select2-selection .select2-selection__rendered span.wcTabIcon'),
-        selSpan = this.$el.find('option:selected');
-
-      if (span.hasClass('icon-server-not-connected') || span.hasClass('icon-shared-server-not-connected')) {
-        let icon = (data.icon) ? data.icon : 'icon-pg';
-        span.removeClass('icon-server-not-connected');
-        span.addClass(icon);
-        span.attr('data-connected', 'connected');
-
-        selSpan.data().image = icon;
-        selSpan.attr('data-connected', 'connected');
-
-        this.onChange.apply(this);
-      }
-      else if (span.hasClass('icon-database-not-connected')) {
-        let icon = (data.icon) ? data.icon : 'pg-icon-database';
-
-        span.removeClass('icon-database-not-connected');
-        span.addClass(icon);
-        span.attr('data-connected', 'connected');
-
-        selSpan.removeClass('icon-database-not-connected');
-        selSpan.data().image = icon;
-        selSpan.attr('data-connected', 'connected');
-
-        this.onChange.apply(this);
-      }
-    },
-    onChange: function() {
-      var model = this.model,
-        attrArr = this.field.get('name').split('.'),
-        name = attrArr.shift(),
-        path = attrArr.join('.'),
-        value = this.getValueFromDOM(),
-        changes = {},
-        that = this;
-
-      if (this.model.errorModel instanceof Backbone.Model) {
-        if (_.isEmpty(path)) {
-          this.model.errorModel.unset(name);
-        } else {
-          var nestedError = this.model.errorModel.get(name);
-          if (nestedError) {
-            this.keyPathSetter(nestedError, path, null);
-            this.model.errorModel.set(name, nestedError);
-          }
-        }
-      }
-
-      changes[name] = _.isEmpty(path) ? value : _.clone(model.get(name)) || {};
-
-      if (!_.isEmpty(path)) that.keyPathSetter(changes[name], path, value);
-      that.stopListening(that.model, 'change:' + name, that.render);
-      model.set(changes);
-      that.listenTo(that.model, 'change:' + name, that.render);
-
-    },
-    render: function() {
-      /*
-       * Initialization from the original control.
-       */
-      this.fetchData();
-      return Backform.Select2Control.prototype.render.apply(this, arguments);
-
-    },
-    fetchData: function() {
-      /*
-       * We're about to fetch the options required for this control.
-       */
-      var self = this,
-        url = self.field.get('url'),
-        m = self.model;
-
-      url = _.isFunction(url) ? url.apply(m) : url;
-
-      if (url && self.field.get('deps')) {
-        url = url.replace('sid', m.get(self.field.get('deps')[0]));
-      }
-
-      // Hmm - we found the url option.
-      // That means - we needs to fetch the options from that node.
-      if (url) {
-        var data;
-
-        m.trigger('pgadmin:view:fetching', m, self.field);
-        $.ajax({
-          async: false,
-          url: url,
-        })
-          .done(function(res) {
-          /*
-           * We will cache this data for short period of time for avoiding
-           * same calls.
-           */
-            data = res.data;
-          })
-          .fail(function() {
-            m.trigger('pgadmin:view:fetch:error', m, self.field);
-          });
-
-        m.trigger('pgadmin:view:fetched', m, self.field);
-        // To fetch only options from cache, we do not need time from 'at'
-        // attribute but only options.
-        //
-
-        /*
-         * Transform the data
-         */
-        var transform = this.field.get('transform') || self.defaults.transform;
-        if (transform && _.isFunction(transform)) {
-          // We will transform the data later, when rendering.
-          // It will allow us to generate different data based on the
-          // dependencies.
-          self.field.set('options', transform.bind(self, data));
-        } else {
-          self.field.set('options', data);
-        }
-      }
-    },
-  });
-
-
-let SchemaDiffHeaderView = Backform.Form.extend({
-  label: '',
-  className: function() {
-    return 'pg-el-sm-12 pg-el-md-12 pg-el-lg-12 pg-el-12';
-  },
-  tabPanelClassName: function() {
-    return Backform.tabClassName;
-  },
-  tabIndex: 0,
-  initialize: function(opts) {
-    this.label = opts.label;
-    Backform.Form.prototype.initialize.apply(this, arguments);
-  },
-  template: _.template(`
-    <div class="row pgadmin-control-group">
-      <div class="col-1 control-label">` + gettext('Select Source') + `</div>
-      <div class="col-6 source row"></div>
-    </div>
-    <div class="row pgadmin-control-group">
-      <div class="col-1 control-label">` + gettext('Select Target') + `</div>
-      <div class="col-6 target row"></div>
-      <div class="col-5 target-buttons">
-          <div class="action-btns d-flex">
-              <div class="btn-group mr-auto" role="group" aria-label="">
-                <button class="btn btn-primary"><span class="pg-font-icon icon-compare sql-icon-lg"></span>&nbsp;` + gettext('Compare') + `</button>
-                <button id="btn-ignore-dropdown" type="button" class="btn btn-primary-icon dropdown-toggle dropdown-toggle-split mr-auto"
-                        data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="ignore"
-                        title=""
-                        tabindex="0">
-                </button>` +
-                [
-                  '<ul class="dropdown-menu ignore">',
-                  '<li>',
-                  '<a class="dropdown-item" id="btn-ignore-owner" href="#" tabindex="0">',
-                  '<i class="fa fa-check visibility-hidden" aria-hidden="true"></i>',
-                  '<span> ' + gettext('Ignore owner') + ' </span>',
-                  '</a>',
-                  '</li>',
-                  '<li>',
-                  '<a class="dropdown-item" id="btn-ignore-whitespaces" href="#" tabindex="0">',
-                  '<i class="fa fa-check visibility-hidden" aria-hidden="true"></i>',
-                  '<span> ' + gettext('Ignore whitespace') + ' </span>',
-                  '</a>',
-                  '</li>',
-                  '</ul>',
-                ].join('\n') + `</div>
-              <button id="generate-script" class="btn btn-primary-icon mr-1" disabled><i class="fa fa-file-code sql-icon-lg"></i>&nbsp;` + gettext('Generate Script') + `</button>
-              <div class="btn-group mr-1" role="group" aria-label="">
-                <button id="btn-filter" type="button" class="btn btn-primary-icon"
-                        title=""
-                        tabindex="0"
-                        style="pointer-events: none;">
-                    <i class="fa fa-filter sql-icon-lg" aria-hidden="true"></i>&nbsp;` + gettext('Filter') + `
-                </button>
-                <button id="btn-filter-dropdown" type="button" class="btn btn-primary-icon dropdown-toggle dropdown-toggle-split"
-                        data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="filter"
-                        title=""
-                        tabindex="0">
-                </button>` +
-      [
-        '<ul class="dropdown-menu filter">',
-        '<li>',
-        '<a class="dropdown-item" id="btn-identical" href="#" tabindex="0">',
-        '<i class="identical fa fa-check visibility-hidden" aria-hidden="true"></i>',
-        '<span> ' + gettext('Identical') + ' </span>',
-        '</a>',
-        '</li>',
-        '<li>',
-        '<a class="dropdown-item" id="btn-differentt" href="#" tabindex="0">',
-        '<i class="different fa fa-check" aria-hidden="true"></i>',
-        '<span> ' + gettext('Different') + ' </span>',
-        '</a>',
-        '</li>',
-        '<li>',
-        '<a class="dropdown-item" id="btn-source-only" href="#" tabindex="0">',
-        '<i class="source-only fa fa-check" aria-hidden="true"></i>',
-        '<span> ' + gettext('Source Only') + ' </span>',
-        '</a>',
-        '</li>',
-        '<li>',
-        '<a class="dropdown-item" id="btn-target-only" href="#" tabindex="0">',
-        '<i class="target-only fa fa-check" aria-hidden="true"></i>',
-        '<span> ' + gettext('Target Only') + ' </span>',
-        '</a>',
-        '</li>',
-        '</ul>',
-        '</div>',
-        '</div>',
-        '</div>',
-        '</div>',
-      ].join('\n')
-  ),
-  render: function() {
-    this.cleanup();
-
-    var controls = this.controls,
-      m = this.model,
-      self = this,
-      idx = (this.tabIndex * 100);
-
-    this.$el.empty();
-
-    $(this.template()).appendTo(this.$el);
-
-    this.fields.each(function(f) {
-      var cntr = new(f.get('control'))({
-        field: f,
-        model: m,
-        dialog: self,
-        tabIndex: idx,
-      });
-
-      if (f.get('group') && f.get('group') == 'source') {
-        self.$el.find('.source').append(cntr.render().$el);
-      }
-      else {
-        self.$el.find('.target').append(cntr.render().$el);
-      }
-
-      controls.push(cntr);
-    });
-
-    return this;
-  },
-  remove: function(opts) {
-    if (opts && opts.data) {
-      if (this.model) {
-        if (this.model.reset) {
-          this.model.reset({
-            validate: false,
-            silent: true,
-            stop: true,
-          });
-        }
-        this.model.clear({
-          validate: false,
-          silent: true,
-          stop: true,
-        });
-        delete(this.model);
-      }
-      if (this.errorModel) {
-        this.errorModel.clear({
-          validate: false,
-          silent: true,
-          stop: true,
-        });
-        delete(this.errorModel);
-      }
-    }
-    this.cleanup();
-    Backform.Form.prototype.remove.apply(this, arguments);
-  },
-});
-
-let SchemaDiffFooterView = Backform.Form.extend({
-  className: function() {
-    return 'set-group pg-el-12';
-  },
-  tabPanelClassName: function() {
-    return Backform.tabClassName;
-  },
-  legendClass: 'badge',
-  contentClass: Backform.accordianContentClassName,
-  template: {
-    'content': _.template(`
-       <div class="pg-el-sm-12 row <%=contentClass%>">
-                  <div class="pg-el-sm-4 ddl-source">` + gettext('Source') + `</div>
-                  <div class="pg-el-sm-4 ddl-target">` + gettext('Target') + `</div>
-                  <div class="pg-el-sm-4 ddl-diff">` + gettext('Difference') + `
-                  </div>
-              </div>
-      </div>
-    `),
-  },
-  initialize: function(opts) {
-    this.label = opts.label;
-    Backform.Form.prototype.initialize.apply(this, arguments);
-  },
-  render: function() {
-    this.cleanup();
-
-    let m = this.model,
-      $el = this.$el,
-      tmpl = this.template,
-      controls = this.controls,
-      data = {
-        'className': _.result(this, 'className'),
-        'legendClass': _.result(this, 'legendClass'),
-        'contentClass': _.result(this, 'contentClass'),
-        'collapse': _.result(this, 'collapse'),
-      },
-      idx = (this.tabIndex * 100);
-
-    this.$el.empty();
-
-    let el = $((tmpl['content'])(data)).appendTo($el);
-
-    this.fields.each(function(f) {
-      let cntr = new(f.get('control'))({
-        field: f,
-        model: m,
-        dialog: self,
-        tabIndex: idx,
-        name: f.get('name'),
-      });
-
-      if (f.get('group') && f.get('group') == 'ddl-source') {
-        el.find('.ddl-source').append(cntr.render().$el);
-      }
-      else if (f.get('group') && f.get('group') == 'ddl-target') {
-        el.find('.ddl-target').append(cntr.render().$el);
-      }
-      else {
-        el.find('.ddl-diff').append(cntr.render().$el);
-      }
-      controls.push(cntr);
-    });
-    $('div.CodeMirror div textarea').attr('aria-label', 'textarea');
-    let $diff_sc = this.$el.find('.source_ddl'),
-      $diff_tr = this.$el.find('.target_ddl'),
-      $diff = this.$el.find('.diff_ddl'),
-      footer_height = this.$el.parent().height() - 50;
-    $diff_sc.height(footer_height);
-    $diff_sc.css({
-      'height': footer_height + 'px',
-    });
-    $diff_tr.height(footer_height);
-    $diff_tr.css({
-      'height': footer_height + 'px',
-    });
-    $diff.height(footer_height);
-    $diff.css({
-      'height': footer_height + 'px',
-    });
-
-
-    return this;
-  },
-});
-
-export {
-  SchemaDiffSelect2Control,
-  SchemaDiffHeaderView,
-  SchemaDiffFooterView,
-  SchemaDiffSqlControl,
-};
diff --git a/web/pgadmin/tools/schema_diff/static/js/schema_diff.js b/web/pgadmin/tools/schema_diff/static/js/schema_diff.js
deleted file mode 100644
index 91658f24..00000000
--- a/web/pgadmin/tools/schema_diff/static/js/schema_diff.js
+++ /dev/null
@@ -1,171 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-define('pgadmin.schemadiff', [
-  'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
-  'sources/pgadmin', 'sources/csrf', 'pgadmin.alertifyjs', 'sources/utils', 'pgadmin.browser.node',
-], function(
-  gettext, url_for, $, _, pgAdmin, csrfToken, Alertify, commonUtils,
-) {
-
-  var wcDocker = window.wcDocker,
-    pgBrowser = pgAdmin.Browser;
-  /* Return back, this has been called more than once */
-  if (pgBrowser.SchemaDiff)
-    return pgBrowser.SchemaDiff;
-
-  // Create an Object Restore of pgBrowser class
-  pgBrowser.SchemaDiff = {
-    init: function() {
-      if (this.initialized)
-        return;
-
-      this.initialized = true;
-      csrfToken.setPGCSRFToken(pgAdmin.csrf_token_header, pgAdmin.csrf_token);
-
-
-      // Define the nodes on which the menus to be appear
-      var menus = [{
-        name: 'schema_diff',
-        module: this,
-        applies: ['tools'],
-        callback: 'show_schema_diff_tool',
-        priority: 1,
-        label: gettext('Schema Diff'),
-        enable: true,
-        below: true,
-      }];
-
-      pgBrowser.add_menus(menus);
-
-      // Creating a new pgBrowser frame to show the data.
-      var schemaDiffFrameType = new pgBrowser.Frame({
-        name: 'frm_schemadiff',
-        showTitle: true,
-        isCloseable: true,
-        isPrivate: true,
-        url: 'about:blank',
-      });
-
-      let self = this;
-      /* Cache may take time to load for the first time
-       * Keep trying till available
-       */
-      let cacheIntervalId = setInterval(function() {
-        if(pgBrowser.preference_version() > 0) {
-          self.preferences = pgBrowser.get_preferences_for_module('schema_diff');
-          clearInterval(cacheIntervalId);
-        }
-      },0);
-
-      pgBrowser.onPreferencesChange('schema_diff', function() {
-        self.preferences = pgBrowser.get_preferences_for_module('schema_diff');
-      });
-
-      // Load the newly created frame
-      schemaDiffFrameType.load(pgBrowser.docker);
-      return this;
-    },
-
-    // Callback to draw schema diff for objects
-    show_schema_diff_tool: function() {
-      var self = this,
-        baseUrl = url_for('schema_diff.initialize', null);
-
-      $.ajax({
-        url: baseUrl,
-        method: 'GET',
-        dataType: 'json',
-        contentType: 'application/json',
-      })
-        .done(function(res) {
-          self.trans_id = res.data.schemaDiffTransId;
-          res.data.panel_title = gettext('Schema Diff'); //TODO: Set the panel title
-          // TODO: Following function is used to test the fetching of the
-          // databases this should be moved to server selection event later.
-          self.launch_schema_diff(res.data);
-        })
-        .fail(function(xhr) {
-          self.raise_error_on_fail(gettext('Schema Diff initialize error') , xhr);
-        });
-    },
-
-    launch_schema_diff: function(data) {
-      var panel_title = data.panel_title,
-        trans_id = data.schemaDiffTransId,
-        panel_tooltip = '';
-
-      var url_params = {
-          'trans_id': trans_id,
-          'editor_title': panel_title,
-        },
-        baseUrl = url_for('schema_diff.panel', url_params);
-
-      var browser_preferences = pgBrowser.get_preferences_for_module('browser');
-      var open_new_tab = browser_preferences.new_browser_tab_open;
-      if (open_new_tab && open_new_tab.includes('schema_diff')) {
-        window.open(baseUrl, '_blank');
-        // Send the signal to runtime, so that proper zoom level will be set.
-        setTimeout(function() {
-          pgBrowser.send_signal_to_runtime('Runtime new window opened');
-        }, 500);
-      } else {
-
-        var propertiesPanel = pgBrowser.docker.findPanels('properties'),
-          schemaDiffPanel = pgBrowser.docker.addPanel('frm_schemadiff', wcDocker.DOCK.STACKED, propertiesPanel[0]);
-
-        commonUtils.registerDetachEvent(schemaDiffPanel);
-
-        // Rename schema diff tab
-        schemaDiffPanel.on(wcDocker.EVENT.RENAME, function(panel_data) {
-          Alertify.prompt('', panel_data.$titleText[0].textContent,
-            // We will execute this function when user clicks on the OK button
-            function(evt, value) {
-              if(value) {
-                // Remove the leading and trailing white spaces.
-                value = value.trim();
-                schemaDiffPanel.title('<span>'+ _.escape(value) +'</span>');
-              }
-            },
-            // We will execute this function when user clicks on the Cancel
-            // button.  Do nothing just close it.
-            function(evt) { evt.cancel = false; }
-          ).set({'title': gettext('Rename Panel')});
-        });
-
-        // Set panel title and icon
-        schemaDiffPanel.title('<span title="'+panel_tooltip+'">'+panel_title+'</span>');
-        schemaDiffPanel.icon('pg-font-icon icon-compare');
-        schemaDiffPanel.focus();
-
-        var openSchemaDiffURL = function(j) {
-          // add spinner element
-          $(j).data('embeddedFrame').$container.append(pgBrowser.SchemaDiff.spinner_el);
-          setTimeout(function() {
-            var frameInitialized = $(j).data('frameInitialized');
-            if (frameInitialized) {
-              var frame = $(j).data('embeddedFrame');
-              if (frame) {
-                frame.openURL(baseUrl);
-                frame.$container.find('.pg-sp-container').delay(1000).hide(1);
-              }
-            } else {
-              openSchemaDiffURL(j);
-            }
-          }, 100);
-        };
-
-        openSchemaDiffURL(schemaDiffPanel);
-      }
-
-    },
-  };
-
-  return pgBrowser.SchemaDiff;
-});
diff --git a/web/pgadmin/tools/schema_diff/static/js/schema_diff_dependency.js b/web/pgadmin/tools/schema_diff/static/js/schema_diff_dependency.js
deleted file mode 100644
index 9f3dc2f2..00000000
--- a/web/pgadmin/tools/schema_diff/static/js/schema_diff_dependency.js
+++ /dev/null
@@ -1,243 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-function handleDependencies() {
-  event.stopPropagation();
-  let isChecked = event.target.checked || (event.target.checked === undefined &&
-   event.target.className && event.target.className.indexOf('unchecked') == -1);
-
-  let isHeaderSelected = false;
-  if (event.target.id !== undefined) isHeaderSelected = event.target.id.includes('header-selector');
-
-  if (this.gridContext && this.gridContext.rowIndex && _.isUndefined(this.gridContext.row.rows)) {
-    // Single Row Selection
-    let rowData = this.grid.getData().getItem(this.gridContext.rowIndex);
-    this.gridContext = {};
-    if (rowData.status) {
-      let depRows = this.selectDependencies(rowData, isChecked);
-      this.selectedRowCount = this.grid.getSelectedRows().length;
-      if (isChecked && depRows.length > 0)
-        this.grid.setSelectedRows(depRows);
-      else if (!isChecked)
-        this.grid.setSelectedRows(this.grid.getSelectedRows().filter(x => !depRows.includes(x)));
-
-      this.ddlCompare(rowData);
-    }
-  } else if((this.gridContext && this.gridContext.row && !_.isUndefined(this.gridContext.row.rows)) ||
-   this.selectedRowCount != this.grid.getSelectedRows().length) {
-
-    // Group / All Rows Selection
-    this.selectedRowCount = this.grid.getSelectedRows().length;
-
-    if (this.gridContext.row && this.gridContext.row.__group) {
-      let context = this.gridContext;
-      this.gridContext = {};
-      this.selectDependenciesForGroup(isChecked, context);
-    } else {
-      this.gridContext = {};
-      this.selectDependenciesForAll(isChecked, isHeaderSelected);
-    }
-  }
-
-  if (this.grid.getSelectedRows().length > 0) {
-    this.header.$el.find('button#generate-script').removeAttr('disabled');
-  } else {
-    this.header.$el.find('button#generate-script').attr('disabled', true);
-  }
-}
-
-function selectDependenciesForGroup(isChecked, context) {
-  let self = this,
-    finalRows = [];
-
-  if (!isChecked) {
-    _.each(context.row.rows, function(row) {
-      if (row && row.status && row.status.toLowerCase() != 'identical' ) {
-        let d = self.selectDependencies(row, isChecked);
-        finalRows = finalRows.concat(d);
-      }
-    });
-  }
-  else {
-    _.each(self.grid.getSelectedRows(), function(row) {
-      let data = self.grid.getData().getItem(row);
-      if (data.status && data.status.toLowerCase() != 'identical') {
-        finalRows = finalRows.concat(self.selectDependencies(data, isChecked));
-      }
-    });
-  }
-
-  finalRows = [...new Set(finalRows)];
-
-  if (isChecked)
-    self.grid.setSelectedRows(finalRows);
-  else {
-    let filterRows = [];
-    filterRows = self.grid.getSelectedRows().filter(x => !finalRows.includes(x));
-
-    self.selectedRowCount = filterRows.length;
-    self.grid.setSelectedRows(filterRows);
-  }
-}
-
-function selectDependenciesForAll(isChecked, isHeaderSelected) {
-  let self = this,
-    finalRows = [];
-
-  if(!isChecked && isHeaderSelected) {
-    self.dataView.getItems().map(function(el) {
-      el.dependentCount = [];
-      el.dependLevel = 1;
-    });
-    self.selectedRowCount = 0;
-    return;
-  }
-
-  _.each(self.grid.getSelectedRows(), function(row) {
-    let data = self.grid.getData().getItem(row);
-    if (data.status) {
-      finalRows = finalRows.concat(self.selectDependencies(data, isChecked));
-    }
-  });
-
-  finalRows = [...new Set(finalRows)];
-
-  if (isChecked && finalRows.length > 0)
-    self.grid.setSelectedRows(finalRows);
-  else if (!isChecked) {
-    let filterRows = [];
-    filterRows = self.grid.getSelectedRows().filter(x => !finalRows.includes(x));
-
-    self.selectedRowCount = filterRows.length;
-    self.grid.setSelectedRows(filterRows);
-  }
-}
-
-
-function selectDependencies(data, isChecked) {
-  let self = this,
-    rows = [],
-    setDependencies = undefined,
-    setOrigDependencies = undefined,
-    finalRows = [];
-
-  if (!data.dependLevel || !isChecked) data.dependLevel = 1;
-  if (!data.dependentCount || !isChecked) data.dependentCount = [];
-
-  if (data.status && data.status.toLowerCase() == 'identical') {
-    self.selectedRowCount = self.grid.getSelectedRows().length;
-    return [];
-  }
-
-  setDependencies = function(rowData, dependencies, is_checked) {
-    // Special handling for extension, if extension is present in the
-    // dependency list then iterate and select only extension node.
-    let extensions = dependencies.filter(item => item.type  == 'extension');
-    if (extensions.length > 0) dependencies = extensions;
-
-    _.each(dependencies, function(dependency) {
-      if (dependency.length == 0) return;
-      let dependencyData = [];
-
-      dependencyData = self.dataView.getItems().filter(item => item.type  == dependency.type && item.oid == dependency.oid);
-
-      if (dependencyData.length > 0) {
-        dependencyData = dependencyData[0];
-        if (!dependencyData.dependentCount) dependencyData.dependentCount = [];
-
-        let groupData = [];
-
-        if (dependencyData.status && dependencyData.status.toLowerCase() != 'identical') {
-          groupData = self.dataView.getGroups().find(
-            (item) => { if (dependencyData.group_name == item.groupingKey) return item.groups; }
-          );
-
-          if (groupData && groupData.groups) {
-            groupData = groupData.groups.find(
-              (item) => { return item.groupingKey == dependencyData.group_name + ':|:' + dependencyData.type; }
-            );
-
-            if (groupData && groupData.collapsed == 1)
-              self.dataView.expandGroup(dependencyData.group_name + ':|:' + dependencyData.type);
-          }
-
-          if (is_checked || _.isUndefined(is_checked)) {
-            dependencyData.dependLevel = rowData.dependLevel + 1;
-            if (dependencyData.dependentCount.indexOf(rowData.oid) === -1)
-              dependencyData.dependentCount.push(rowData.oid);
-            rows[rows.length] = dependencyData;
-          } else {
-            dependencyData.dependentCount.splice(dependencyData.dependentCount.indexOf(rowData.oid), 1);
-            if (dependencyData.dependentCount.length == 0) {
-              rows[rows.length] = dependencyData;
-              dependencyData.dependLevel = 1;
-            }
-          }
-        }
-        if (Object.keys(dependencyData.dependencies).length > 0) {
-          if (dependencyData.dependentCount.indexOf(rowData.oid) !== -1 ) {
-            let depCirRows = dependencyData.dependencies.filter(x => x.oid !== rowData.oid);
-            if (!dependencyData.orig_dependencies)
-              dependencyData.orig_dependencies = Object.assign([], dependencyData.dependencies);
-            dependencyData.dependencies = depCirRows;
-          }
-          setDependencies(dependencyData, dependencyData.dependencies, is_checked);
-        }
-      }
-    });
-  };
-
-  setDependencies(data, data.dependencies, isChecked);
-
-  setOrigDependencies = function(dependencies) {
-    _.each(dependencies, function(dependency) {
-      if (dependency.length == 0) return;
-      let dependencyData = [];
-
-      dependencyData = self.dataView.getItems().filter(item => item.type  == dependency.type && item.oid == dependency.oid);
-
-      if (dependencyData.length > 0) {
-        dependencyData = dependencyData[0];
-
-        if (dependencyData.orig_dependencies && Object.keys(dependencyData.orig_dependencies).length > 0) {
-          if (!dependencyData.dependentCount) dependencyData.dependentCount = [];
-
-          if (dependencyData.status && dependencyData.status.toLowerCase() != 'identical') {
-            dependencyData.dependencies = dependencyData.orig_dependencies;
-            dependencyData.orig_dependencies = [];
-          }
-          if (dependencyData.dependencies.length > 0) {
-            setOrigDependencies(dependencyData.dependencies);
-          }
-        }
-      }
-    });
-  };
-
-  setOrigDependencies(data.dependencies);
-
-  if (isChecked) finalRows = self.grid.getSelectedRows();
-
-  _.each(rows, function(row) {
-    let r = self.grid.getData().getRowByItem(row);
-    if(!_.isUndefined(r) && finalRows.indexOf(r) === -1 ) {
-      finalRows.push(self.grid.getData().getRowByItem(row));
-    }
-  });
-
-  self.selectedRowCount = finalRows.length;
-  return finalRows;
-}
-
-export {
-  handleDependencies,
-  selectDependenciesForGroup,
-  selectDependenciesForAll,
-  selectDependencies,
-};
diff --git a/web/pgadmin/tools/schema_diff/static/js/schema_diff_hook.js b/web/pgadmin/tools/schema_diff/static/js/schema_diff_hook.js
deleted file mode 100644
index 3fe2aab9..00000000
--- a/web/pgadmin/tools/schema_diff/static/js/schema_diff_hook.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-define([
-  'sources/url_for', 'jquery',
-  'sources/pgadmin', 'pgadmin.tools.schema_diff_ui',
-], function(
-  url_for, $, pgAdmin, SchemaDiffUIModule
-) {
-  var pgTools = pgAdmin.Tools = pgAdmin.Tools || {};
-  var SchemaDiffUI = SchemaDiffUIModule.default;
-
-  /* Return back, this has been called more than once */
-  if (pgTools.SchemaDiffHook)
-    return pgTools.SchemaDiffHook;
-
-  pgTools.SchemaDiffHook = {
-    load: function(trans_id) {
-      window.onbeforeunload = function() {
-        $.ajax({
-          url: url_for('schema_diff.close', {'trans_id': trans_id}),
-          method: 'DELETE',
-        });
-      };
-
-      let schemaUi = new SchemaDiffUI($('#schema-diff-container'), trans_id);
-      schemaUi.render();
-    },
-  };
-
-  return pgTools.SchemaDiffHook;
-});
diff --git a/web/pgadmin/tools/schema_diff/static/js/schema_diff_ui.js b/web/pgadmin/tools/schema_diff/static/js/schema_diff_ui.js
deleted file mode 100644
index b5d75acc..00000000
--- a/web/pgadmin/tools/schema_diff/static/js/schema_diff_ui.js
+++ /dev/null
@@ -1,967 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import url_for from 'sources/url_for';
-import $ from 'jquery';
-import gettext from 'sources/gettext';
-import Alertify from 'pgadmin.alertifyjs';
-import Backbone from 'backbone';
-import Slick from 'sources/../bundle/slickgrid';
-import pgAdmin from 'sources/pgadmin';
-import {setPGCSRFToken} from 'sources/csrf';
-import 'pgadmin.tools.sqleditor';
-import pgWindow from 'sources/window';
-import _ from 'underscore';
-import Notify from '../../../../static/js/helpers/Notifier';
-import { showSchemaDiffServerPassword } from '../../../../static/js/Dialogs/index';
-
-
-import { SchemaDiffSelect2Control, SchemaDiffHeaderView,
-  SchemaDiffFooterView, SchemaDiffSqlControl} from './schema_diff.backform';
-
-import { handleDependencies, selectDependenciesForGroup,
-  selectDependenciesForAll, selectDependencies } from './schema_diff_dependency';
-import { generateScript } from '../../../sqleditor/static/js/show_query_tool';
-
-var wcDocker = window.wcDocker;
-
-export default class SchemaDiffUI {
-  constructor(container, trans_id) {
-    var self = this;
-    this.$container = container;
-    this.header = null;
-    this.trans_id = trans_id;
-    this.filters = ['Identical', 'Different', 'Source Only', 'Target Only'];
-    this.sel_filters = ['Different', 'Source Only', 'Target Only'];
-    this.ignore_filters = ['owner', 'whitespaces'];
-    this.ignore_whitespaces = 0;
-    this.ignore_owner = 0;
-    this.dataView = null;
-    this.grid = null;
-    this.selection = {};
-
-    this.model = new Backbone.Model({
-      source_sid: undefined,
-      source_did: undefined,
-      source_scid: undefined,
-      target_sid: undefined,
-      target_did: undefined,
-      target_scid: undefined,
-      source_ddl: undefined,
-      target_ddl: undefined,
-      diff_ddl: undefined,
-    });
-
-    setPGCSRFToken(pgAdmin.csrf_token_header, pgAdmin.csrf_token);
-
-    this.docker = new wcDocker(
-      this.$container, {
-        allowContextMenu: false,
-        allowCollapse: false,
-        loadingClass: 'pg-sp-icon',
-        themePath: url_for('static', {
-          'filename': 'css',
-        }),
-        theme: 'webcabin.overrides.css',
-      }
-    );
-
-    this.header_panel = new pgAdmin.Browser.Panel({
-      name: 'schema_diff_header_panel',
-      showTitle: false,
-      isCloseable: false,
-      isPrivate: true,
-      content: '<div id="schema-diff-header" class="pg-el-container" el="sm"></div><div id="schema-diff-grid" class="pg-el-container" el="sm"></div>',
-      elContainer: true,
-    });
-
-    this.footer_panel = new pgAdmin.Browser.Panel({
-      name: 'schema_diff_footer_panel',
-      title: gettext('DDL Comparison'),
-      isCloseable: false,
-      isPrivate: true,
-      height: '60',
-      content: `<div id="schema-diff-ddl-comp" class="pg-el-container" el="sm">
-      <div id="ddl_comp_fetching_data" class="pg-sp-container schema-diff-busy-fetching d-none">
-        <div class="pg-sp-content">
-            <div class="row">
-                <div class="col-12 pg-sp-icon"></div>
-            </div>
-            <div class="row"><div class="col-12 pg-sp-text">` + gettext('Comparing objects...') + `</div></div>
-        </div>
-    </div></div>`,
-    });
-
-    this.header_panel.load(this.docker);
-    this.footer_panel.load(this.docker);
-
-
-    this.panel_obj = this.docker.addPanel('schema_diff_header_panel', wcDocker.DOCK.TOP, {w:'95%', h:'50%'});
-    this.footer_panel_obj = this.docker.addPanel('schema_diff_footer_panel', wcDocker.DOCK.BOTTOM, this.panel_obj, {w:'95%', h:'50%'});
-
-    self.footer_panel_obj.on(wcDocker.EVENT.VISIBILITY_CHANGED, function() {
-      setTimeout(function() {
-        this.resize_grid();
-      }.bind(self), 200);
-    });
-
-    self.footer_panel_obj.on(wcDocker.EVENT.RESIZE_ENDED, function() {
-      setTimeout(function() {
-        this.resize_panels();
-      }.bind(self), 200);
-    });
-  }
-
-  raise_error_on_fail(alert_title, xhr) {
-    try {
-      if (_.isUndefined(xhr.responseText)) {
-        Notify.alert(alert_title, gettext('Unable to get the response text.'));
-      } else {
-        var err = JSON.parse(xhr.responseText);
-        Notify.alert(alert_title, err.errormsg);
-      }
-    } catch (e) {
-      Notify.alert(alert_title, gettext(e.message));
-    }
-  }
-
-  resize_panels() {
-    let $src_ddl = $('#schema-diff-ddl-comp .source_ddl'),
-      $tar_ddl = $('#schema-diff-ddl-comp .target_ddl'),
-      $diff_ddl = $('#schema-diff-ddl-comp .diff_ddl'),
-      footer_height = $('#schema-diff-ddl-comp').height() - 50;
-
-    $src_ddl.height(footer_height);
-    $src_ddl.css({
-      'height': footer_height + 'px',
-    });
-    $tar_ddl.height(footer_height);
-    $tar_ddl.css({
-      'height': footer_height + 'px',
-    });
-    $diff_ddl.height(footer_height);
-    $diff_ddl.css({
-      'height': footer_height + 'px',
-    });
-
-    this.resize_grid();
-  }
-
-  compare_schemas() {
-    var self = this,
-      url_params = self.model.toJSON();
-
-    if (url_params['source_sid'] == '' || _.isUndefined(url_params['source_sid']) ||
-        url_params['source_did'] == '' || _.isUndefined(url_params['source_did']) ||
-        url_params['target_sid'] == '' || _.isUndefined(url_params['target_sid']) ||
-        url_params['target_did'] == '' || _.isUndefined(url_params['target_did'])
-    ) {
-      Notify.alert(gettext('Selection Error'), gettext('Please select source and target.'));
-      return false;
-    }
-
-    // Check if user has selected the same options for comparison on the GUI
-    let opts = [['source_sid', 'target_sid'], ['source_did', 'target_did'], ['source_scid', 'target_scid']];
-    let isSameOptsSelected = true;
-    for (let opt of opts) {
-      if (url_params[opt[0]] && url_params[opt[1]] &&
-          (parseInt(url_params[opt[0]]) !== parseInt(url_params[opt[1]]))) {
-        isSameOptsSelected = false;
-      }
-    }
-    if (isSameOptsSelected) {
-      Notify.alert(gettext('Selection Error'), gettext('Please select the different source and target.'));
-      return false;
-    }
-
-    this.selection = JSON.parse(JSON.stringify(url_params));
-
-    url_params['trans_id'] = self.trans_id;
-    url_params['ignore_owner'] = self.ignore_owner;
-    url_params['ignore_whitespaces'] = self.ignore_whitespaces;
-
-    _.each(url_params, function(key, val) {
-      url_params[key] = parseInt(val, 10);
-    });
-
-    var baseUrl = url_for('schema_diff.compare_database', url_params);
-    // If compare two schema then change the base url
-    if (url_params['source_scid'] != '' && !_.isUndefined(url_params['source_scid']) &&
-        url_params['target_scid'] != '' && !_.isUndefined(url_params['target_scid'])) {
-      baseUrl = url_for('schema_diff.compare_schema', url_params);
-    }
-
-    self.model.set({
-      'source_ddl': undefined,
-      'target_ddl': undefined,
-      'diff_ddl': undefined,
-    });
-
-    self.render_grid([]);
-    self.footer.render();
-    self.startDiffPoller();
-
-    return $.ajax({
-      url: baseUrl,
-      method: 'GET',
-      dataType: 'json',
-      contentType: 'application/json',
-    })
-      .done(function (res) {
-        self.stopDiffPoller();
-        self.render_grid(res.data);
-      })
-      .fail(function (xhr) {
-        self.raise_error_on_fail(gettext('Schema compare error'), xhr);
-        self.stopDiffPoller();
-      });
-  }
-
-  generate_script() {
-    var self = this,
-      baseServerUrl = url_for('schema_diff.get_server', {'sid': self.selection['target_sid'],
-        'did': self.selection['target_did']}),
-      sel_rows = self.grid ? self.grid.getSelectedRows() : [],
-      url_params = self.selection,
-      generated_script = undefined,
-      open_query_tool,
-      script_header;
-
-    script_header = gettext('-- This script was generated by the Schema Diff utility in pgAdmin 4. \n');
-    script_header += gettext('-- For the circular dependencies, the order in which Schema Diff writes the objects is not very sophisticated \n');
-    script_header += gettext('-- and may require manual changes to the script to ensure changes are applied in the correct order.\n');
-    script_header += gettext('-- Please report an issue for any failure with the reproduction steps. \n');
-
-
-    _.each(url_params, function(key, val) {
-      url_params[key] = parseInt(val, 10);
-    });
-
-    $('#diff_fetching_data').removeClass('d-none');
-    $('#diff_fetching_data').find('.schema-diff-busy-text').text('Generating script...');
-
-
-    open_query_tool = function get_server_details() {
-      $.ajax({
-        url: baseServerUrl,
-        method: 'GET',
-        dataType: 'json',
-        contentType: 'application/json',
-      })
-        .done(function (res) {
-          let data = res.data;
-          let server_data = {};
-          if (data) {
-            let sqlId = `schema${self.trans_id}`;
-            server_data['sgid'] = data.gid;
-            server_data['sid'] = data.sid;
-            server_data['stype'] = data.type;
-            server_data['server'] = data.name;
-            server_data['user'] = data.user;
-            server_data['did'] = self.model.get('target_did');
-            server_data['database'] = data.database;
-            server_data['sql_id'] = sqlId;
-
-            if (_.isUndefined(generated_script)) {
-              generated_script = script_header + 'BEGIN;' + '\n' + self.model.get('diff_ddl') + '\n' + 'END;';
-            }
-            localStorage.setItem(sqlId, generated_script);
-            generateScript(server_data, pgWindow.pgAdmin.Tools.SQLEditor, Alertify);
-          }
-
-          $('#diff_fetching_data').find('.schema-diff-busy-text').text('');
-          $('#diff_fetching_data').addClass('d-none');
-
-        })
-        .fail(function (xhr) {
-          self.raise_error_on_fail(gettext('Generate script error'), xhr);
-          $('#diff_fetching_data').find('.schema-diff-busy-text').text('');
-          $('#diff_fetching_data').addClass('d-none');
-        });
-    };
-
-    if (sel_rows.length > 0) {
-      let script_array = {1: [], 2: [], 3: [], 4: [], 5: []},
-        script_body = '';
-      for (let sel_row_val of sel_rows) {
-        let data = self.grid.getData().getItem(sel_row_val);
-        if(!_.isUndefined(data.diff_ddl)) {
-          if (!(data.dependLevel in script_array)) script_array[data.dependLevel] = [];
-          // Check whether the selected object belongs to source only schema
-          // if yes then we will have to add create schema statement before
-          // creating any other object.
-          if (!_.isUndefined(data.source_schema_name) && !_.isNull(data.source_schema_name)) {
-            let schema_query = '\nCREATE SCHEMA IF NOT EXISTS ' + data.source_schema_name + ';\n';
-            if (script_array[data.dependLevel].indexOf(schema_query) == -1) {
-              script_array[data.dependLevel].push(schema_query);
-            }
-          }
-          script_array[data.dependLevel].push(data.diff_ddl);
-        }
-      }
-
-      _.each(Object.keys(script_array).reverse(), function(s) {
-        if (script_array[s].length > 0) {
-          script_body += script_array[s].join('\n') + '\n\n';
-        }
-      });
-
-      generated_script = script_header + 'BEGIN;' + '\n' + script_body + 'END;';
-      open_query_tool();
-    } else if (!_.isUndefined(self.model.get('diff_ddl'))) {
-      open_query_tool();
-    }
-    return false;
-  }
-
-  check_empty_diff() {
-    var self = this;
-    this.panel_obj.$container.find('#schema-diff-grid .slick-viewport .pg-panel-message').remove();
-    if (self.dataView.getFilteredItems().length == 0) {
-      let msg = gettext('No difference found');
-      // Make the height to 0px to avoid extra scroll bar, height will be calculated automatically.
-      this.panel_obj.$container.find('#schema-diff-grid .slick-viewport .grid-canvas')[0].style.height = '0px';
-      this.panel_obj.$container.find('#schema-diff-grid .slick-viewport'
-      ).prepend('<div class="pg-panel-message">'+ msg +'</div>');
-    }
-  }
-
-  render_grid(data) {
-
-    var self = this;
-    var grid;
-
-    if (self.grid) {
-      // Only render the data
-      self.render_grid_data(data);
-      self.check_empty_diff();
-      return;
-    }
-    // Checkbox Column
-    var checkboxSelector = new Slick.CheckboxSelectColumn({
-      cssClass: 'slick-cell-checkboxsel',
-      minWidth: 30,
-    });
-
-    // Format Schema object title with appropriate icon
-    var formatColumnTitle = function (row, cell, value, columnDef, dataContext) {
-      let icon = 'icon-' + dataContext.type;
-      return '<i class="ml-2 wcTabIcon '+ icon +'"></i><span>' + value + '</span>';
-    };
-
-    // Grid Columns
-    var grid_width =  (self.grid_width - 47) / 2 ;
-    var columns = [
-      checkboxSelector.getColumnDefinition(),
-      {id: 'title', name: gettext('Objects'), field: 'title', minWidth: grid_width, formatter: formatColumnTitle},
-      {id: 'status', name: gettext('Comparison Result'), field: 'status', minWidth: grid_width},
-      {id: 'label', name: gettext('Objects'), field: 'label',  width: 0, minWidth: 0, maxWidth: 0,
-        cssClass: 'really-hidden', headerCssClass: 'really-hidden'},
-      {id: 'type', name: gettext('Objects'), field: 'type',  width: 0, minWidth: 0, maxWidth: 0,
-        cssClass: 'really-hidden', headerCssClass: 'really-hidden'},
-      {id: 'id', name: 'id', field: 'id', width: 0, minWidth: 0, maxWidth: 0,
-        cssClass: 'really-hidden', headerCssClass: 'really-hidden' },
-
-    ];
-
-    // Grid Options
-    var options = {
-      enableCellNavigation: true,
-      enableColumnReorder: false,
-      enableRowSelection: true,
-    };
-
-    // Grouping by Schema Object
-    self.groupBySchemaObject = function() {
-      self.dataView.setGrouping([{
-        getter: 'group_name',
-        formatter: function (g) {
-          let icon = 'icon-schema';
-          if (g.rows[0].group_name == 'Database Objects'){
-            icon = 'icon-coll-database';
-          }
-          return '<i class="wcTabIcon '+ icon +'"></i><span>' + _.escape(g.rows[0].group_name);
-        },
-        aggregateCollapsed: true,
-        lazyTotalsCalculation: true,
-      }, {
-        getter: 'type',
-        formatter: function (g) {
-          let icon = 'icon-coll-' + g.value;
-          let identical=0, different=0, source_only=0, target_only=0;
-          for (let row_val of g.rows) {
-            if (row_val['status'] == self.filters[0]) identical++;
-            else if (row_val['status'] == self.filters[1]) different++;
-            else if (row_val['status'] == self.filters[2]) source_only++;
-            else if (row_val['status'] == self.filters[3]) target_only++;
-          }
-          return '<i class="wcTabIcon '+ icon +'"></i><span>' + g.rows[0].label + ' - ' + gettext('Identical') + ': <strong>' + identical + '</strong>&nbsp;&nbsp;' + gettext('Different') + ': <strong>' + different + '</strong>&nbsp;&nbsp;' + gettext('Source Only') + ': <strong>' + source_only + '</strong>&nbsp;&nbsp;' + gettext('Target Only') + ': <strong>' + target_only + '</strong></span>';
-        },
-        aggregateCollapsed: true,
-        collapsed: true,
-        lazyTotalsCalculation: true,
-      }]);
-    };
-
-    var groupItemMetadataProvider = new Slick.Data.GroupItemMetadataProvider({ checkboxSelect: true,
-      checkboxSelectPlugin: checkboxSelector });
-
-    // Dataview for grid
-    self.dataView = new Slick.Data.DataView({
-      groupItemMetadataProvider: groupItemMetadataProvider,
-      inlineFilters: false,
-    });
-
-    // Wire up model events to drive the grid
-    self.dataView.onRowCountChanged.subscribe(function () {
-      grid.updateRowCount();
-      grid.render();
-      self.accessibility_error();
-    });
-    self.dataView.onRowsChanged.subscribe(function (e, args) {
-      grid.invalidateRows(args.rows);
-      grid.render();
-      self.accessibility_error();
-    });
-
-    // Change Row css on the basis of item status
-    self.dataView.getItemMetadata = function(row) {
-      let item = self.dataView.getItem(row),
-        group_item = groupItemMetadataProvider.getGroupRowMetadata(item);
-      if (item.__group) {
-        return group_item;
-      }
-
-      if(item.status === 'Different') {
-        return { cssClasses: 'different' };
-      } else if (item.status === 'Source Only') {
-        return { cssClasses: 'source' };
-      } else if (item.status === 'Target Only') {
-        return { cssClasses: 'target' };
-      }
-
-      return null;
-    };
-
-    // Grid filter
-    self.filter = function (item) {
-      let self_local = this;
-      if (self_local.sel_filters.indexOf(item.status) !== -1) return true;
-      return false;
-    };
-
-    let $data_grid = $('#schema-diff-grid');
-    grid = this.grid = new Slick.Grid($data_grid, self.dataView, columns, options);
-    $('label[for='+ columns[0].name.split('\'')[1] +']').append('<span style="display:none">checkbox</span>');
-    grid.registerPlugin(groupItemMetadataProvider);
-    grid.setSelectionModel(new Slick.RowSelectionModel({selectActiveRow: false}));
-    grid.registerPlugin(checkboxSelector);
-
-    self.dataView.syncGridSelection(grid, true, true);
-
-    grid.onMouseEnter.subscribe(function (evt) {
-      var cell = grid.getCellFromEvent(evt);
-      self.gridContext = {};
-      self.gridContext.rowIndex = cell.row;
-      self.gridContext.row = grid.getDataItem(cell.row);
-    }.bind(self));
-
-    grid.onMouseLeave.subscribe(function () {
-      self.gridContext = {};
-    });
-
-    grid.onClick.subscribe(function(e, args) {
-      if (args.row) {
-        data = args.grid.getData().getItem(args.row);
-        if (data.status) this.ddlCompare(data);
-      }
-    }.bind(self));
-
-    grid.onSelectedRowsChanged.subscribe(self.handleDependencies.bind(this));
-
-    self.model.on('change:diff_ddl', function(event) {
-      self.handleDependencies.bind(event, self);
-    });
-
-    $('#schema-diff-grid').on('keyup', function() {
-      if ((event.keyCode == 38 || event.keyCode ==40) && this.grid.getActiveCell().row) {
-        data = this.grid.getData().getItem(this.grid.getActiveCell().row);
-        this.ddlCompare(data);
-      }
-    }.bind(self));
-
-    self.render_grid_data(data);
-  }
-
-  render_grid_data(data) {
-    var self = this;
-    self.grid.setSelectedRows([]);
-    self.selected_row_count = self.grid.getSelectedRows().length;
-    data.sort((a, b) => (a.label > b.label) ? 1 : (a.label === b.label) ? ((a.title > b.title) ? 1 : -1) : -1);
-    self.dataView.beginUpdate();
-    self.dataView.setItems(data);
-    self.dataView.setFilter(self.filter.bind(self));
-    self.groupBySchemaObject();
-    self.dataView.endUpdate();
-    self.dataView.refresh();
-
-    self.resize_grid();
-    self.accessibility_error();
-  }
-
-  accessibility_error() {
-    $('.slick-viewport').scroll(function() {
-      setTimeout(function() {
-        $('span.slick-column-name label').append('<span style="display:none">checkbox</span>');
-        $('div.slick-cell.l0 label').each(function(inx, el) {
-          $(el).append('<span style="display:none">checkbox</span>');
-        });
-      }, 0);
-    });
-  }
-
-  handle_generate_button(){
-    if (this.grid.getSelectedRows().length > 0 || (this.model.get('diff_ddl') != '' && !_.isUndefined(this.model.get('diff_ddl')))) {
-      this.header.$el.find('button#generate-script').removeAttr('disabled');
-    } else {
-      this.header.$el.find('button#generate-script').attr('disabled', true);
-    }
-  }
-
-  resize_grid() {
-    let $data_grid = $('#schema-diff-grid'),
-      grid_height = (this.panel_obj.height() > 0) ? this.panel_obj.height() - 100 : this.grid_height - 100;
-
-    $data_grid.height(grid_height);
-    $data_grid.css({
-      'height': grid_height + 'px',
-    });
-    if (this.grid) this.grid.resizeCanvas();
-  }
-
-  getCompareStatus() {
-    var self = this,
-      url_params = {'trans_id': self.trans_id},
-      baseUrl = url_for('schema_diff.poll', url_params);
-
-    $.ajax({
-      url: baseUrl,
-      method: 'GET',
-      dataType: 'json',
-      contentType: 'application/json',
-    })
-      .done(function (res) {
-        let msg = _.escape(res.data.compare_msg);
-        if (res.data.diff_percentage != 100) {
-          msg = msg + gettext(' (this may take a few minutes)...');
-        }
-
-        msg = msg + '<br>' + gettext('%s completed.', res.data.diff_percentage + '%');
-        $('#diff_fetching_data').find('.schema-diff-busy-text').html(msg);
-      })
-      .fail(function (xhr) {
-        self.raise_error_on_fail(gettext('Poll error'), xhr);
-        self.stopDiffPoller('fail');
-      });
-  }
-
-  startDiffPoller() {
-    $('#ddl_comp_fetching_data').addClass('d-none');
-    $('#diff_fetching_data').removeClass('d-none');
-    /* Execute once for the first time as setInterval will not do */
-    this.getCompareStatus();
-    this.diff_poller_int_id = setInterval(this.getCompareStatus.bind(this), 1000);
-  }
-
-  stopDiffPoller(status) {
-    clearInterval(this.diff_poller_int_id);
-    // The last polling for comparison
-    if (status !== 'fail') this.getCompareStatus();
-
-    $('#diff_fetching_data').find('.schema-diff-busy-text').text('');
-    $('#diff_fetching_data').addClass('d-none');
-
-  }
-
-  ddlCompare(data) {
-    var self = this,
-      node_type = data.type,
-      source_oid = data.oid,
-      target_oid;
-
-    self.model.set({
-      'source_ddl': undefined,
-      'target_ddl': undefined,
-      'diff_ddl': undefined,
-    }, {silent: true});
-
-    if(data.status && data.status.toLowerCase() == 'identical') {
-      var url_params = self.selection;
-      target_oid = data.target_oid;
-
-      url_params['trans_id'] = self.trans_id;
-      url_params['source_scid'] = data.source_scid;
-      url_params['target_scid'] = data.target_scid;
-      url_params['source_oid'] = source_oid;
-      url_params['target_oid'] = target_oid;
-      url_params['comp_status'] = data.status;
-      url_params['node_type'] = node_type;
-
-      _.each(url_params, function(key, val) {
-        url_params[key] = parseInt(val, 10);
-      });
-
-      $('#ddl_comp_fetching_data').removeClass('d-none');
-
-      var baseUrl = url_for('schema_diff.ddl_compare', url_params);
-      self.model.url = baseUrl;
-
-      self.model.fetch({
-        success: function() {
-          self.footer.render();
-          $('#ddl_comp_fetching_data').addClass('d-none');
-        },
-        error: function() {
-          self.footer.render();
-          $('#ddl_comp_fetching_data').addClass('d-none');
-        },
-      });
-    } else {
-      self.model.set({
-        'source_ddl': data.source_ddl,
-        'target_ddl': data.target_ddl,
-        'diff_ddl': data.diff_ddl,
-      }, {silent: true});
-
-      self.footer.render();
-    }
-  }
-
-  transformFunc(data) {
-    let group_template_options = [];
-    for (let key in data) {
-      if (data.hasOwnProperty(key)) {
-        group_template_options.push({'group': key, 'optval': data[key]});
-      }
-    }
-    return group_template_options;
-  }
-
-  render() {
-    let self = this;
-    let panel = self.docker.findPanels('schema_diff_header_panel')[0];
-
-    var header = panel.$container.find('#schema-diff-header');
-
-    self.header  = new SchemaDiffHeaderView({
-      el: header,
-      model: this.model,
-      fields: [{
-        name: 'source_sid', label: false,
-        control: SchemaDiffSelect2Control,
-        transform: function(data) {
-          return self.transformFunc(data);
-        },
-        url: url_for('schema_diff.servers'),
-        select2: {
-          allowClear: true,
-          placeholder: gettext('Select server...'),
-        },
-        connect: function() {
-          self.connect_server(arguments[0], arguments[1]);
-        },
-        group: 'source',
-        disabled: function() {
-          return false;
-        },
-      }, {
-        name: 'source_did',
-        group: 'source',
-        deps: ['source_sid'],
-        control: SchemaDiffSelect2Control,
-        url: function() {
-          if (this.get('source_sid'))
-            return url_for('schema_diff.databases', {'sid': this.get('source_sid')});
-          return false;
-        },
-        select2: {
-          allowClear: true,
-          placeholder: gettext('Select database...'),
-        },
-        disabled: function(m) {
-          let self_local = this;
-          if (!_.isUndefined(m.get('source_sid')) && !_.isNull(m.get('source_sid'))
-              && m.get('source_sid') !== '') {
-            setTimeout(function() {
-              for (let opt_val of self_local.options) {
-                if (opt_val.is_maintenance_db) {
-                  m.set('source_did', opt_val.value);
-                }
-              }
-            }, 10);
-            return false;
-          }
-
-          setTimeout(function() {
-            m.set('source_did', undefined);
-          }, 10);
-          return true;
-        },
-        connect: function() {
-          self.connect_database(this.model.get('source_sid'), arguments[0], arguments[1]);
-        },
-      }, {
-        name: 'source_scid',
-        control: SchemaDiffSelect2Control,
-        group: 'source',
-        deps: ['source_sid', 'source_did'],
-        url: function() {
-          if (this.get('source_sid') && this.get('source_did'))
-            return url_for('schema_diff.schemas', {'sid': this.get('source_sid'), 'did': this.get('source_did')});
-          return false;
-        },
-        select2: {
-          allowClear: true,
-          placeholder: gettext('Select schema...'),
-        },
-        disabled: function(m) {
-          if (!_.isUndefined(m.get('source_did')) && !_.isNull(m.get('source_did'))
-              && m.get('source_did') !== '') {
-            return false;
-          }
-          setTimeout(function() {
-            m.set('source_scid', undefined);
-          }, 10);
-          return true;
-        },
-      }, {
-        name: 'target_sid', label: false,
-        control: SchemaDiffSelect2Control,
-        transform: function(data) {
-          return self.transformFunc(data);
-        },
-        group: 'target',
-        url: url_for('schema_diff.servers'),
-        select2: {
-          allowClear: true,
-          placeholder: gettext('Select server...'),
-        },
-        disabled: function() {
-          return false;
-        },
-        connect: function() {
-          self.connect_server(arguments[0], arguments[1]);
-        },
-      }, {
-        name: 'target_did',
-        control: SchemaDiffSelect2Control,
-        group: 'target',
-        deps: ['target_sid'],
-        url: function() {
-          if (this.get('target_sid'))
-            return url_for('schema_diff.databases', {'sid': this.get('target_sid')});
-          return false;
-        },
-        select2: {
-          allowClear: true,
-          placeholder: gettext('Select database...'),
-        },
-        disabled: function(m) {
-          let self_local = this;
-          if (!_.isUndefined(m.get('target_sid')) && !_.isNull(m.get('target_sid'))
-              && m.get('target_sid') !== '') {
-            setTimeout(function() {
-              for (let opt_val of self_local.options) {
-                if (opt_val.is_maintenance_db) {
-                  m.set('target_did', opt_val.value);
-                }
-              }
-            }, 10);
-            return false;
-          }
-
-          setTimeout(function() {
-            m.set('target_did', undefined);
-          }, 10);
-          return true;
-        },
-        connect: function() {
-          self.connect_database(this.model.get('target_sid'), arguments[0], arguments[1]);
-        },
-      }, {
-        name: 'target_scid',
-        control: SchemaDiffSelect2Control,
-        group: 'target',
-        deps: ['target_sid', 'target_did'],
-        url: function() {
-          if (this.get('target_sid') && this.get('target_did'))
-            return url_for('schema_diff.schemas', {'sid': this.get('target_sid'), 'did': this.get('target_did')});
-          return false;
-        },
-        select2: {
-          allowClear: true,
-          placeholder: gettext('Select schema...'),
-        },
-        disabled: function(m) {
-          if (!_.isUndefined(m.get('target_did')) && !_.isNull(m.get('target_did'))
-              && m.get('target_did') !== '') {
-            return false;
-          }
-          setTimeout(function() {
-            m.set('target_scid', undefined);
-          }, 10);
-          return true;
-        },
-      }],
-    });
-
-    self.footer  = new SchemaDiffFooterView({
-      model: this.model,
-      fields: [{
-        name: 'source_ddl', label: false,
-        control: SchemaDiffSqlControl,
-        group: 'ddl-source',
-      }, {
-        name: 'target_ddl', label: false,
-        control: SchemaDiffSqlControl,
-        group: 'ddl-target',
-      }, {
-        name: 'diff_ddl', label: false,
-        control: SchemaDiffSqlControl,
-        group: 'ddl-diff', copyRequired: true,
-      }],
-    });
-
-    self.header.render();
-
-    self.header.$el.find('button.btn-primary').on('click', self.compare_schemas.bind(self));
-    self.header.$el.find('button#generate-script').on('click', self.generate_script.bind(self));
-    self.header.$el.find('ul.filter a.dropdown-item').on('click', self.refresh_filters.bind(self));
-    self.header.$el.find('ul.ignore a.dropdown-item').on('click', self.refresh_ignore_settings.bind(self));
-
-    /* Set the default value for 'ignore owner' and 'ignore whitespace' */
-    let pref = pgWindow.pgAdmin.Browser.get_preferences_for_module('schema_diff');
-    if (pref.ignore_owner) self.header.$el.find('ul.ignore a.dropdown-item#btn-ignore-owner').click();
-    if (pref.ignore_whitespaces) self.header.$el.find('ul.ignore a.dropdown-item#btn-ignore-whitespaces').click();
-
-
-    let footer_panel = self.docker.findPanels('schema_diff_footer_panel')[0],
-      header_panel = self.docker.findPanels('schema_diff_header_panel')[0];
-
-    footer_panel.$container.find('#schema-diff-ddl-comp').append(self.footer.render().$el);
-    $('div.CodeMirror div textarea').attr('aria-label', 'textarea');
-    header_panel.$container.find('#schema-diff-grid').append(`<div class='obj_properties container-fluid'>
-    <div class='pg-panel-message'>` + gettext('<strong>Database Compare:</strong> Select the server and database for the source and target and Click <strong>Compare</strong>.') +
-    gettext('</br><strong>Schema Compare:</strong> Select the server, database and schema for the source and target and Click <strong>Compare</strong>.') +
-    gettext('</br><strong>Note:</strong> The dependencies will not be resolved in the Schema comparison.') + '</div></div>');
-
-    self.grid_width = $('#schema-diff-grid').width();
-    self.grid_height = this.panel_obj.height();
-  }
-
-  refresh_filters(event) {
-    let self = this;
-    _.each(self.filters, function(filter) {
-      let index = self.sel_filters.indexOf(filter);
-      let filter_class = '.' + filter.replace(' ', '-').toLowerCase();
-      if ($(event.currentTarget).find(filter_class).length == 1) {
-        if ($(filter_class).hasClass('visibility-hidden') === true) {
-          $(filter_class).removeClass('visibility-hidden');
-          if (index === -1) self.sel_filters.push(filter);
-        } else {
-          $(filter_class).addClass('visibility-hidden');
-          if(index !== -1 ) self.sel_filters.splice(index, 1);
-        }
-      }
-    });
-
-    // Check whether comparison data is loaded or not
-    if(!_.isUndefined(self.dataView) && !_.isNull(self.dataView)) {
-      // Refresh the grid
-      self.dataView.refresh();
-      self.check_empty_diff();
-    }
-  }
-
-  refresh_ignore_settings(event) {
-    let self = this,
-      element = $(event.currentTarget).find('.fa-check');
-
-    if (element.length == 1) {
-      if (element.hasClass('visibility-hidden') === true) {
-        element.removeClass('visibility-hidden');
-        if (event.currentTarget.id === 'btn-ignore-owner') self.ignore_owner = 1;
-        if (event.currentTarget.id === 'btn-ignore-whitespaces') self.ignore_whitespaces = 1;
-      } else {
-        element.addClass('visibility-hidden');
-        if (event.currentTarget.id === 'btn-ignore-owner') self.ignore_owner = 0;
-        if (event.currentTarget.id === 'btn-ignore-whitespaces') self.ignore_whitespaces = 0;
-      }
-    }
-  }
-
-  connect_database(server_id, db_id, callback) {
-    var url = url_for('schema_diff.connect_database', {'sid': server_id, 'did': db_id});
-    $.post(url)
-      .done(function(res) {
-        if (res.success && res.data) {
-          callback(res.data);
-        }
-      })
-      .fail(function(xhr, error) {
-        Notify.pgNotifier(error, xhr, gettext('Failed to connect the database.'));
-      });
-
-  }
-
-  connect_server(server_id, callback) {
-    let self = this;
-    var  onFailure = function(
-        xhr, status, error, sid, err_callback
-      ) {
-        Notify.pgNotifier('error', xhr, error, function(msg) {
-          setTimeout(function() {
-            showSchemaDiffServerPassword(
-              self.docker,
-              gettext('Connect to Server'),
-              msg,
-              sid,
-              err_callback,
-              onSuccess,
-              onFailure
-            );
-          }, 100);
-        });
-      },
-      onSuccess = function(res, suc_callback) {
-        if (res && res.data) {
-          // We're not reconnecting
-          suc_callback(res.data);
-        }
-      };
-
-    var url = url_for('schema_diff.connect_server', {'sid': server_id});
-    $.post(url)
-      .done(function(res) {
-        if (res.success == 1) {
-          return onSuccess(res, callback);
-        }
-      })
-      .fail(function(xhr, status, error) {
-        return onFailure(
-          xhr, status, error, server_id, callback
-        );
-      });
-  }
-}
-
-SchemaDiffUI.prototype.handleDependencies = handleDependencies;
-SchemaDiffUI.prototype.selectDependenciesForGroup = selectDependenciesForGroup;
-SchemaDiffUI.prototype.selectDependenciesForAll = selectDependenciesForAll;
-SchemaDiffUI.prototype.selectDependencies = selectDependencies;
diff --git a/web/pgadmin/tools/schema_diff/static/scss/_schema_diff.scss b/web/pgadmin/tools/schema_diff/static/scss/_schema_diff.scss
deleted file mode 100644
index de12c331..00000000
--- a/web/pgadmin/tools/schema_diff/static/scss/_schema_diff.scss
+++ /dev/null
@@ -1,145 +0,0 @@
-#schema-diff-container {
-  position: absolute;
-  left: 0;
-  right: 0;
-  top: 0;
-  bottom: 0;
-  background-color: $color-gray-light;
-}
-
-#schema-diff-grid .slick-header .slick-header-columns {
-  background: $color-bg;
-  height: 40px;
-  border-bottom: none;
-}
-
-#schema-diff-grid .slick-header .slick-header-column.ui-state-default {
-  padding: 4px 0 3px 6px;
-  border-bottom: $panel-border;
-  border-right: $panel-border;
-}
-
-#schema-diff-grid {
-  font-family: $font-family-primary;
-  font-size: $tree-font-size;
-  .ui-widget-content {
-    background-color: $input-bg;
-    color: $input-color;
-  }
-
-  .ui-state-default {
-    color: $color-fg;
-  }
-}
-
-.slick-row:hover .slick-cell{
-  border-top: $table-hover-border;
-  border-bottom: $table-hover-border;
-  background-color: $table-hover-bg-color;
-}
-
-#schema-diff-grid .slick-header .slick-header-column.selected {
-  background-color: $color-primary;
-  color: $color-primary-fg;
-}
-.slick-row .slick-cell {
-  border-bottom: $panel-border;
-  border-right: $panel-border;
-  z-index: 0;
-}
-
-#schema-diff-grid .slick-row .slick-cell.l0.r0.selected {
-  background-color: inherit;
-}
-
-#schema-diff-grid .slick-row > .slick-cell.selected {
-  background-color: $table-hover-bg-color !important;
-  border-top: $table-hover-border;
-  border-bottom: $table-hover-border;
-}
-
-#schema-diff-grid div.slick-header.ui-state-default {
-  background: $color-bg;
-  border-bottom: none;
-  border-right: none;
-  border-top: $panel-border;
-}
-
-#schema-diff-grid .different {
-  background-color: $schemadiff-diff-row-color !important;
-  color: $schema-diff-color-fg;
-}
-#schema-diff-grid .source {
-  background-color: $schemadiff-source-row-color;
-  color: $schema-diff-color-fg;
-}
-#schema-diff-grid .target {
-  background-color: $schemadiff-target-row-color !important;
-  color: $schema-diff-color-fg;
-}
-
-#schema-diff-grid .slick-row.active {
-    background-color: $table-bg-selected !important;
-    color: $schema-diff-color-fg;
-}
-
-#schema-diff-ddl-comp {
-  height: 100%;
-  bottom: 10px;
-  background-color: $color-bg !important;
-  overflow-y: hidden;
-}
-
-#schema-diff-grid .slick-group-select-checkbox {
-  width: 13px;
-  height: 13px;
-  margin-right: 1rem;
-  vertical-align: middle;
-  display: inline-block;
-}
-
-.slick-group-toggle.collapsed::before {
-  font-family: $font-family-icon;
-  content: "\f054";
-  font-size: 0.6rem;
-  border: none;
-  font-weight: 900;
-}
-
-.slick-group-toggle.expanded::before {
-  font-family: $font-family-icon;
-  content: "\f078";
-  font-size: 0.6rem;
-  margin-left: 0rem;
-  font-weight: 900;
-}
-
-#schema-diff-ddl-comp .badge .caret::before {
-  font-family: $font-family-icon;
-  content: "\f078";
-  font-size: 0.7rem;
-  margin-left: 0rem;
-  font-weight: 900;
-}
-
-.slick-group {
-  color: $input-color !important;
-}
-
-.slick-group:hover {
-  color: $schema-diff-color-fg !important;
-}
-
-.slick-group.active {
-  color: $schema-diff-color-fg !important;
-}
-
-.select2-selection__placeholder {
-  color: $select2-placeholder !important;
-}
-
-#btn-ignore-dropdown {
-  color: $btn-primary-color !important;
-  background-color: $color-primary !important;
-  border-color: $color-primary !important;
-}
diff --git a/web/pgadmin/tools/schema_diff/templates/schema_diff/index.html b/web/pgadmin/tools/schema_diff/templates/schema_diff/index.html
index 7fa7683d..cc0d31da 100644
--- a/web/pgadmin/tools/schema_diff/templates/schema_diff/index.html
+++ b/web/pgadmin/tools/schema_diff/templates/schema_diff/index.html
@@ -2,14 +2,10 @@
 {% block init_script %}
 try {
   require(
-    ['sources/generated/slickgrid', 'sources/generated/codemirror', 'sources/generated/browser_nodes'],
+    ['sources/generated/codemirror', 'sources/generated/browser_nodes', 'sources/generated/schema_diff'],
     function() {
-      require(['sources/generated/schema_diff'], function(pgSchemaDiffHook) {
-        var pgSchemaDiffHook = pgSchemaDiffHook || pgAdmin.Tools.SchemaDiffHook;
-        pgSchemaDiffHook.load({{trans_id}});
-      }, function() {
-        console.log(arguments);
-      });
+        var pgSchemaDiff = window.pgAdmin.Tools.SchemaDiff;
+        pgSchemaDiff.load(document.getElementById('schema-diff-main-container'),{{trans_id}});
     },
     function() {
       console.log(arguments);
@@ -19,18 +15,28 @@ try {
 }
 {% endblock %}
 {% block css_link %}
+<style>
+  #schema-diff-main-container {
+        display: flex;
+        flex-direction: column;
+        height: 100%;
+    }
+
+    #schema-diff-main-container:not(:empty) + .pg-sp-container {
+        display: none;
+    }
+</style>
 <link type="text/css" rel="stylesheet" href="{{ url_for('browser.browser_css')}}"/>
 {% endblock %}
 {% block title %}{{editor_title}}{% endblock %}
 {% block body %}
-<div id="schema-diff-container">
-    <div id="diff_fetching_data" class="pg-sp-container schema-diff-busy-fetching d-none">
-        <div class="pg-sp-content">
-            <div class="row">
-                <div class="col-12 pg-sp-icon"></div>
-            </div>
-            <div class="row"><div class="col-12 pg-sp-text schema-diff-busy-text"></div></div>
+<div id="schema-diff-main-container" tabindex="0">
+  <div class="pg-sp-container">
+    <div class="pg-sp-content">
+        <div class="row">
+            <div class="col-12 pg-sp-icon"></div>
         </div>
     </div>
 </div>
+</div>
 {% endblock %}
diff --git a/web/pgadmin/tools/sqleditor/static/js/SQLEditorModule.js b/web/pgadmin/tools/sqleditor/static/js/SQLEditorModule.js
index e2aa7b8a..b92f63f2 100644
--- a/web/pgadmin/tools/sqleditor/static/js/SQLEditorModule.js
+++ b/web/pgadmin/tools/sqleditor/static/js/SQLEditorModule.js
@@ -15,7 +15,6 @@ import * as commonUtils from 'sources/utils';
 import $ from 'jquery';
 import url_for from 'sources/url_for';
 import _ from 'lodash';
-import alertify from 'pgadmin.alertifyjs';
 import pgWindow from 'sources/window';
 import pgAdmin from 'sources/pgadmin';
 import pgBrowser from 'pgadmin.browser';
@@ -27,6 +26,7 @@ import ReactDOM from 'react-dom';
 import QueryToolComponent from './components/QueryToolComponent';
 import ModalProvider from '../../../../static/js/helpers/ModalProvider';
 import Theme from '../../../../static/js/Theme';
+import { showRenamePanel } from '../../../../static/js/Dialogs';
 
 const wcDocker = window.wcDocker;
 
@@ -242,38 +242,19 @@ export default class SQLEditor {
   }
 
   onPanelRename(queryToolPanel, panelData, is_query_tool) {
-    var temp_title = panelData.$titleText[0].textContent;
-    var is_dirty_editor = queryToolPanel.is_dirty_editor ? queryToolPanel.is_dirty_editor : false;
-    var title = queryToolPanel.is_dirty_editor ? panelData.$titleText[0].textContent.replace(/.$/, '') : temp_title;
-    alertify.prompt('', title,
-      // We will execute this function when user clicks on the OK button
-      function(evt, value) {
-        // Remove the leading and trailing white spaces.
-        value = value.trim();
-        if(value) {
-          var is_file = false;
-          if(panelData.$titleText[0].innerHTML.includes('File - ')) {
-            is_file = true;
-          }
-          var selected_item = pgBrowser.tree.selected();
-          var panel_titles = '';
 
-          if(is_query_tool) {
-            panel_titles = panelTitleFunc.getPanelTitle(pgBrowser, selected_item, value);
-          } else {
-            panel_titles = showViewData.generateViewDataTitle(pgBrowser, selected_item, value);
-          }
-          // Set title to the selected tab.
-          if (is_dirty_editor) {
-            panel_titles = panel_titles + ' *';
-          }
-          panelTitleFunc.setQueryToolDockerTitle(queryToolPanel, is_query_tool, _.unescape(panel_titles), is_file);
-        }
-      },
-      // We will execute this function when user clicks on the Cancel
-      // button.  Do nothing just close it.
-      function(evt) { evt.cancel = false; }
-    ).set({'title': gettext('Rename Panel')});
+    let preferences = pgBrowser.get_preferences_for_module('browser');
+    let temp_title = panelData.$titleText[0].textContent;
+    let is_dirty_editor = queryToolPanel.is_dirty_editor ? queryToolPanel.is_dirty_editor : false;
+    let title = queryToolPanel.is_dirty_editor ? panelData.$titleText[0].textContent.replace(/.$/, '') : temp_title;
+
+    let qtdata = {
+      is_query_tool: is_query_tool,
+      is_file: panelData.$titleText[0].innerHTML.includes('File - '),
+      is_dirty_editor: is_dirty_editor
+    };
+
+    showRenamePanel(title, preferences, queryToolPanel, 'querytool', qtdata);
   }
 
 
diff --git a/web/regression/feature_tests/xss_checks_panels_and_query_tool_test.py b/web/regression/feature_tests/xss_checks_panels_and_query_tool_test.py
index eb299f89..d3c581f4 100644
--- a/web/regression/feature_tests/xss_checks_panels_and_query_tool_test.py
+++ b/web/regression/feature_tests/xss_checks_panels_and_query_tool_test.py
@@ -32,7 +32,7 @@ class CheckForXssFeatureTest(BaseFeatureTest):
         2) Properties Tab (BackFrom)
         3) Dependents Tab (BackGrid)
         4) SQL Tab (Code Mirror)
-        5) Query Tool (SlickGrid)
+        5) Query Tool (Result Grid)
     """
 
     scenarios = [
@@ -189,7 +189,7 @@ class CheckForXssFeatureTest(BaseFeatureTest):
 
     def _check_xss_in_query_tool(self):
         print(
-            "\n\tChecking the SlickGrid cell for XSS vulnerabilities",
+            "\n\tChecking the Result Grid cell for XSS vulnerabilities",
             file=sys.stderr, end=""
         )
         self.page.fill_codemirror_area_with(
@@ -205,7 +205,7 @@ class CheckForXssFeatureTest(BaseFeatureTest):
         self._check_escaped_characters(
             source_code,
             '&lt;img src="x" onerror="console.log(1)"&gt;',
-            "Query tool (SlickGrid)"
+            "Query tool (Result Grid)"
         )
 
     def _check_xss_in_query_tool_history(self):
@@ -255,7 +255,7 @@ class CheckForXssFeatureTest(BaseFeatureTest):
 
     def _check_xss_view_data(self):
         print(
-            "\n\tChecking the SlickGrid cell for XSS vulnerabilities",
+            "\n\tChecking the Result Grid cell for XSS vulnerabilities",
             file=sys.stderr, end=""
         )
 
@@ -268,7 +268,7 @@ class CheckForXssFeatureTest(BaseFeatureTest):
         self._check_escaped_characters(
             source_code,
             self.check_xss_chars_set2,
-            "View Data (SlickGrid)"
+            "View Data (Result Grid)"
         )
 
     def _check_xss_in_explain_module(self):
diff --git a/web/regression/javascript/schema_diff/schema_diff_spec.js b/web/regression/javascript/schema_diff/schema_diff_spec.js
new file mode 100644
index 00000000..6f822cc6
--- /dev/null
+++ b/web/regression/javascript/schema_diff/schema_diff_spec.js
@@ -0,0 +1,111 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+
+import $ from 'jquery';
+window.jQuery = window.$ = $;
+
+import 'wcdocker';
+import '../helper/enzyme.helper';
+
+import React from 'react';
+import { createMount } from '@material-ui/core/test-utils';
+import jasmineEnzyme from 'jasmine-enzyme';
+import MockAdapter from 'axios-mock-adapter';
+import axios from 'axios/index';
+
+// import pgAdmin from 'sources/pgadmin';
+import pgWindow from 'sources/window';
+import url_for from 'sources/url_for';
+
+import { messages } from '../fake_messages';
+import { TreeFake } from '../tree/tree_fake';
+import Theme from '../../../pgadmin/static/js/Theme';
+import SchemaDiffComponent from '../../../pgadmin/tools/schema_diff/static/js/components/SchemaDiffComponent';
+import SchemaDiff from '../../../pgadmin/tools/schema_diff/static/js/SchemaDiffModule';
+
+
+describe('Schema Diff Component', () => {
+  let mount;
+  let mountDOM;
+  let tree;
+  let params;
+  let networkMock;
+  let schemaDiffInstance;
+
+  /* Use createMount so that material ui components gets the required context */
+  /* https://material-ui.com/guides/testing/#api */
+  beforeAll(() => {
+    mount = createMount();
+  });
+
+  beforeEach(() => {
+    jasmineEnzyme();
+    // Element for mount wcDocker panel
+    mountDOM = $('<div class="dockerContainer">');
+    $(document.body).append(mountDOM);
+
+    $(document.body).append($('<div id="debugger-main-container">'));
+
+    /* messages used by validators */
+    pgWindow.pgAdmin.Browser = pgWindow.pgAdmin.Browser || {};
+    pgWindow.pgAdmin.Browser.messages = pgWindow.pgAdmin.Browser.messages || messages;
+    pgWindow.pgAdmin.Browser.utils = pgWindow.pgAdmin.Browser.utils || {};
+
+    schemaDiffInstance = new SchemaDiff(pgWindow.pgAdmin, pgWindow.pgAdmin.Browser);
+
+    // nodeInfo = { parent: {} };
+
+    // eslint-disable-next-line
+    let docker = new wcDocker(
+      '.dockerContainer', {
+        allowContextMenu: false,
+        allowCollapse: false,
+        loadingClass: 'pg-sp-icon',
+      });
+
+    tree = new TreeFake();
+    pgWindow.pgAdmin.Browser.tree = tree;
+    pgWindow.pgAdmin.Browser.docker = docker;
+
+    params = {
+      transId: 1234,
+      schemaDiff: schemaDiffInstance,
+    };
+    networkMock = new MockAdapter(axios);
+  });
+
+  it('SchemaDiff Init', () => {
+    networkMock.onGet(url_for('schema_diff.servers')).reply(200,
+      {'success':1,
+        'errormsg':'',
+        'info':'',
+        'result':null,
+        'data':{
+          'Servers':[
+            {'value':1,'label':'PostgreSQL 12','image':'icon-pg','_id':1,'connected':true},
+            {'value':2,'label':'PostgreSQL 10','image':'icon-server-not-connected','_id':2,'connected':false},
+            {'value':3,'label':'PostgreSQL 11','image':'icon-server-not-connected','_id':3,'connected':false},
+            {'value':4,'label':'PostgreSQL 13','image':'icon-server-not-connected','_id':4,'connected':false},
+            {'value':5,'label':'PostgreSQL 9.6','image':'icon-server-not-connected','_id':5,'connected':false},
+            {'value':8,'label':'test1234yo','image':'icon-server-not-connected','_id':8,'connected':false}
+          ]
+        }
+      }
+    );
+    mount(
+      <Theme>
+        <SchemaDiffComponent
+          params={{ transId: params.transId, pgAdmin: pgWindow.pgAdmin }}
+        >
+        </SchemaDiffComponent>
+      </Theme>
+    );
+  });
+});
+
diff --git a/web/regression/javascript/selection/active_cell_capture_spec.js b/web/regression/javascript/selection/active_cell_capture_spec.js
deleted file mode 100644
index 376d4127..00000000
--- a/web/regression/javascript/selection/active_cell_capture_spec.js
+++ /dev/null
@@ -1,343 +0,0 @@
-//////////////////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////////////////
-
-define([
-  'sources/selection/active_cell_capture',
-  'sources/selection/range_selection_helper',
-], function (ActiveCellCapture, RangeSelectionHelper) {
-  describe('ActiveCellCapture', function () {
-    var grid, activeCellPlugin, getSelectedRangesSpy, setSelectedRangesSpy;
-    var onHeaderClickFunction;
-    var onClickFunction;
-    var onColumnsResizedFunction;
-    var onHeaderMouseEnterFunction;
-    var onHeaderMouseLeaveFunction;
-    var Slick = window.Slick;
-
-    beforeEach(function () {
-      getSelectedRangesSpy = jasmine.createSpy('getSelectedRangesSpy');
-      setSelectedRangesSpy = jasmine.createSpy('setSelectedRangesSpy');
-      grid = {
-        getSelectionModel: function () {
-          return {
-            getSelectedRanges: getSelectedRangesSpy,
-            setSelectedRanges: setSelectedRangesSpy,
-          };
-        },
-
-        getColumns: function () {
-          return [
-            {id: 'row-header-column'},
-            {id: 'column-1'},
-            {id: 'column-2'},
-          ];
-        },
-
-        onDragEnd: jasmine.createSpyObj('onDragEnd', ['subscribe']),
-        onActiveCellChanged: jasmine.createSpyObj('onActiveCellChanged', ['subscribe']),
-        onHeaderClick: jasmine.createSpy('onHeaderClick'),
-        onClick: jasmine.createSpy('onClick'),
-        onKeyDown: jasmine.createSpyObj('onKeyDown', ['subscribe']),
-        onColumnsResized: jasmine.createSpyObj('onColumnsResized', ['subscribe']),
-        onHeaderMouseEnter: jasmine.createSpyObj('onHeaderMouseEnter', ['subscribe']),
-        onHeaderMouseLeave: jasmine.createSpyObj('onHeaderMouseLeave', ['subscribe']),
-
-        getDataLength: function () { return 10; },
-
-        setActiveCell: jasmine.createSpy('setActiveCell'),
-        getActiveCell: jasmine.createSpy('getActiveCell'),
-        resetActiveCell: jasmine.createSpy('resetActiveCell'),
-      };
-      activeCellPlugin = new ActiveCellCapture();
-
-      grid.onHeaderClick.subscribe =
-        jasmine.createSpy('subscribe').and.callFake(function (callback) {
-          onHeaderClickFunction = callback.bind(activeCellPlugin);
-        });
-
-      grid.onClick.subscribe =
-        jasmine.createSpy('subscribe').and.callFake(function (callback) {
-          onClickFunction = callback.bind(activeCellPlugin);
-        });
-
-      grid.onColumnsResized.subscribe =
-        jasmine.createSpy('subscribe').and.callFake(function (callback) {
-          onColumnsResizedFunction = callback.bind(activeCellPlugin);
-        });
-
-      grid.onHeaderMouseEnter.subscribe =
-        jasmine.createSpy('subscribe').and.callFake(function (callback) {
-          onHeaderMouseEnterFunction = callback.bind(activeCellPlugin);
-        });
-
-      grid.onHeaderMouseLeave.subscribe =
-        jasmine.createSpy('subscribe').and.callFake(function (callback) {
-          onHeaderMouseLeaveFunction = callback.bind(activeCellPlugin);
-        });
-
-      activeCellPlugin.init(grid);
-    });
-
-    describe('onHeaderClickHandler', function () {
-      describe('when no ranges are selected', function () {
-        beforeEach(function () {
-          getSelectedRangesSpy.and.returnValue([]);
-          onHeaderClickFunction({}, {column: {pos: 1}});
-          grid.getActiveCell.and.returnValue(null);
-        });
-
-        it('should set the active cell', function () {
-          expect(grid.setActiveCell).toHaveBeenCalledWith(0, 2);
-        });
-
-        it('should not change the selected ranges', function () {
-          expect(setSelectedRangesSpy).not.toHaveBeenCalled();
-        });
-      });
-
-      describe('when only one column is already selected', function () {
-        beforeEach(function () {
-          getSelectedRangesSpy.and.returnValue([RangeSelectionHelper.rangeForColumn(grid, 2)]);
-          grid.getActiveCell.and.returnValue({cell: 2, row: 0});
-        });
-
-        describe('when a different column is clicked', function () {
-          beforeEach(function () {
-            onHeaderClickFunction({}, {column: {pos: 4}});
-          });
-
-          it('should set the active cell to the newly clicked columns top cell', function () {
-            expect(grid.setActiveCell).toHaveBeenCalledWith(0, 5);
-          });
-        });
-
-        describe('when the same column is clicked', function () {
-          beforeEach(function () {
-            onHeaderClickFunction({}, {column: {pos: 1}});
-          });
-
-          it('should reset the active cell', function () {
-            expect(grid.resetActiveCell).toHaveBeenCalled();
-          });
-        });
-
-        describe('when mouse is inside the header row', function () {
-          beforeEach(function () {
-            onHeaderMouseEnterFunction({}, {});
-          });
-
-          describe('when user finishes resizing the selected column', function () {
-            var eventSpy;
-
-            beforeEach(function () {
-              eventSpy = jasmine.createSpyObj('event', ['stopPropagation']);
-              onColumnsResizedFunction({}, {grid: grid});
-              onHeaderClickFunction(eventSpy, {column: {pos: 1}});
-            });
-
-            it('should not deselect the current selected column', function () {
-              expect(grid.setActiveCell).not.toHaveBeenCalled();
-              expect(grid.resetActiveCell).not.toHaveBeenCalled();
-            });
-
-            it('should prevent further event propagation', function () {
-              expect(eventSpy.stopPropagation).toHaveBeenCalled();
-            });
-
-            describe('when the user clicks the resized column header', function () {
-              beforeEach(function () {
-                eventSpy.stopPropagation.calls.reset();
-                onHeaderClickFunction(eventSpy, {column: {pos: 2}});
-              });
-
-              it('should change the active cell', function () {
-                expect(grid.setActiveCell).toHaveBeenCalledWith(0, 3);
-                expect(grid.resetActiveCell).not.toHaveBeenCalled();
-              });
-
-              it('should allow further event propagation', function () {
-                expect(eventSpy.stopPropagation).not.toHaveBeenCalled();
-              });
-            });
-          });
-        });
-
-        describe('when mouse is outside the header row', function () {
-          beforeEach(function () {
-            onHeaderMouseEnterFunction({}, {});
-            onHeaderMouseLeaveFunction({}, {});
-          });
-
-          describe('when user finishes resizing the selected column', function () {
-            beforeEach(function () {
-              onColumnsResizedFunction({}, {grid: grid});
-            });
-
-            it('should not deselect the current selected column', function () {
-              expect(grid.setActiveCell).not.toHaveBeenCalled();
-              expect(grid.resetActiveCell).not.toHaveBeenCalled();
-            });
-
-            describe('when the user clicks another column header', function () {
-              var eventSpy;
-
-              beforeEach(function () {
-                eventSpy = jasmine.createSpyObj('event', ['stopPropagation']);
-                onHeaderMouseEnterFunction({}, {});
-                onHeaderClickFunction(eventSpy, {column: {pos: 3}});
-              });
-
-              it('should change the active cell', function () {
-                expect(grid.setActiveCell).toHaveBeenCalledWith(0, 4);
-                expect(grid.resetActiveCell).not.toHaveBeenCalled();
-              });
-
-              it('should allow further event propagation', function () {
-                expect(eventSpy.stopPropagation).not.toHaveBeenCalled();
-              });
-            });
-          });
-        });
-      });
-
-      describe('when three non-consecutive columns are selected', function () {
-        beforeEach(function () {
-          getSelectedRangesSpy.and.returnValue([
-            RangeSelectionHelper.rangeForColumn(grid, 10),
-            RangeSelectionHelper.rangeForColumn(grid, 6),
-            RangeSelectionHelper.rangeForColumn(grid, 22),
-          ]);
-          grid.getActiveCell.and.returnValue({cell: 22, row: 0});
-        });
-
-        describe('when the third column is clicked (thereby deselecting it)', function () {
-          beforeEach(function () {
-            onHeaderClickFunction({}, {column: {pos: 21}});
-          });
-
-          it('should set the active cell to the second column', function () {
-            expect(grid.setActiveCell).toHaveBeenCalledWith(0, 6);
-          });
-        });
-
-        describe('when the second column is clicked (thereby deselecting it)', function () {
-          beforeEach(function () {
-            onHeaderClickFunction({}, {column: {pos: 5}});
-          });
-
-          it('should not set the active cell', function () {
-            expect(grid.setActiveCell).not.toHaveBeenCalled();
-          });
-        });
-      });
-    });
-
-    describe('onClick', function () {
-      describe('when the target is a random cell in the grid', function () {
-        it('should not change the active cell', function () {
-          onClickFunction({}, {row: 1, cell: 2});
-          grid.getActiveCell.and.returnValue(null);
-
-          expect(grid.setActiveCell).not.toHaveBeenCalled();
-        });
-      });
-
-      describe('when the target is the row header', function () {
-        describe('when no rows are selected', function () {
-          beforeEach(function () {
-            getSelectedRangesSpy.and.returnValue([]);
-            onClickFunction({}, {row: 1, cell: 0});
-            grid.getActiveCell.and.returnValue(null);
-          });
-
-          it('changes the active cell', function () {
-            expect(grid.setActiveCell).toHaveBeenCalledWith(1, 1);
-          });
-
-          it('should not change the selected ranges', function () {
-            expect(setSelectedRangesSpy).not.toHaveBeenCalled();
-          });
-        });
-
-        describe('when there is one cell selected', function () {
-          beforeEach(function () {
-            grid.getActiveCell.and.returnValue({row: 4, cell: 5});
-            getSelectedRangesSpy.and.returnValue([
-              new Slick.Range(4, 5),
-            ]);
-          });
-
-          it('sets the active cell', function () {
-            onClickFunction({}, {row: 4, cell: 0});
-
-            expect(grid.setActiveCell).toHaveBeenCalledWith(4, 1);
-          });
-        });
-
-        describe('when there is one row selected', function () {
-          beforeEach(function () {
-            grid.getActiveCell.and.returnValue({row: 3, cell: 1});
-            getSelectedRangesSpy.and.returnValue([
-              RangeSelectionHelper.rangeForRow(grid, 3),
-            ]);
-          });
-
-          it('resets the selected row', function () {
-            onClickFunction({}, {row: 3, cell: 0});
-
-            expect(grid.resetActiveCell).toHaveBeenCalled();
-          });
-
-          describe('when we select a different row', function () {
-            it('should change the active cell', function () {
-              onClickFunction({}, {row: 9, cell: 0});
-
-              expect(grid.setActiveCell).toHaveBeenCalledWith(9, 1);
-            });
-          });
-        });
-
-        describe('when there are 2 rows selected', function () {
-          beforeEach(function () {
-            grid.getActiveCell.and.returnValue({row: 3, cell: 1});
-            getSelectedRangesSpy.and.returnValue([
-              RangeSelectionHelper.rangeForRow(grid, 5),
-              RangeSelectionHelper.rangeForRow(grid, 3),
-            ]);
-          });
-
-          describe('when the last selected row is clicked again', function () {
-            it('should change the active cell to the first selected row', function () {
-              onClickFunction({}, {row: 3, cell: 0});
-
-              expect(grid.setActiveCell).toHaveBeenCalledWith(5, 1);
-            });
-          });
-
-          describe('when the first selected row is clicked again', function () {
-            it('should not change the active cell', function () {
-              onClickFunction({}, {row: 5, cell: 0});
-
-              expect(grid.setActiveCell).not.toHaveBeenCalled();
-            });
-          });
-        });
-
-        describe('and the editable new row', function () {
-          beforeEach(function () {
-            onClickFunction({}, {row: 10, cell: 0});
-          });
-          it('does not select the row', function () {
-            expect(grid.setActiveCell).not.toHaveBeenCalled();
-          });
-        });
-      });
-    });
-  });
-});
diff --git a/web/regression/javascript/selection/column_selector_spec.js b/web/regression/javascript/selection/column_selector_spec.js
deleted file mode 100644
index 4cfe901a..00000000
--- a/web/regression/javascript/selection/column_selector_spec.js
+++ /dev/null
@@ -1,414 +0,0 @@
-//////////////////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////////////////
-
-import $ from 'jquery';
-
-import Slick from 'slickgrid';
-import 'slickgrid.grid';
-
-import ColumnSelector from 'sources/selection/column_selector';
-import ActiveCellCapture from 'sources/selection/active_cell_capture';
-import 'sources/selection/grid_selector';
-import 'slickgrid.plugins/slick.cellrangeselector';
-
-import XCellSelectionModel from 'sources/selection/xcell_selection_model';
-
-describe('ColumnSelector', function () {
-  var container, data, columns, options;
-  var SlickGrid = Slick.Grid;
-  var KEY = {
-    RIGHT: 39,
-    LEFT: 37,
-    UP: 38,
-    DOWN: 40,
-  };
-
-  beforeEach(function () {
-    container = $('<div></div>');
-    container.height(9999);
-    container.width(9999);
-
-    data = [{
-      'some-column-name': 'first value',
-      'second column': 'second value',
-      'third column': 'nonselectable value',
-    }, {
-      'some-column-name': 'row 1 - first value',
-      'second column': 'row 1 - second value',
-      'third column': 'row 1 - nonselectable value',
-    }];
-
-    columns = [
-      {
-        id: 'row-header-column',
-        name: 'row header column name',
-        selectable: false,
-        display_name: 'row header column name',
-        column_type: 'text',
-      },
-      {
-        id: '1',
-        name: 'some-column-name',
-        pos: 0,
-        display_name: 'some-column-name',
-        column_type: 'text',
-      },
-      {
-        id: '2',
-        name: 'second column',
-        pos: 1,
-        display_name: 'second column',
-        column_type: 'json',
-      },
-      {
-        id: 'third-column-id',
-        name: 'third column',
-        pos: 2,
-        display_name: 'third column',
-        column_type: 'text',
-      },
-      {
-        name: 'some-non-selectable-column',
-        selectable: false,
-        pos: 3,
-        display_name: 'some-non-selectable-column',
-        column_type: 'numeric',
-      },
-    ];
-  });
-
-  it('displays the name of the column', function () {
-    setupGrid(columns);
-
-    expect($(container.find('.slick-header-columns .slick-column-name')[1]).text())
-      .toContain('some-column-name');
-    expect($(container.find('.slick-header-columns .slick-column-name')[1]).text())
-      .toContain('text');
-    expect($(container.find('.slick-header-columns .slick-column-name')[2]).text())
-      .toContain('second column');
-    expect($(container.find('.slick-header-columns .slick-column-name')[2]).text())
-      .toContain('json');
-  });
-
-  it('preserves the other attributes of column definitions', function () {
-    var columnSelector = new ColumnSelector();
-    var selectableColumns = columnSelector.getColumnDefinitions(columns);
-
-    expect(selectableColumns[1].id).toEqual('1');
-  });
-
-  describe('with ActiveCellCapture, CellSelectionModel, and GridSelector: selecting columns', function () {
-    var grid, cellSelectionModel;
-    beforeEach(function () {
-      var columnSelector = new ColumnSelector();
-      columns = columnSelector.getColumnDefinitions(columns);
-      data = [];
-      for (var i = 0; i < 10; i++) {
-        data.push({
-          'some-column-name': 'some-value-' + i,
-          'second column': 'second value ' + i,
-          'third column': 'third value ' + i,
-          'fourth column': 'fourth value ' + i,
-        });
-      }
-      grid = new SlickGrid(container, data, columns);
-
-      grid.registerPlugin(new ActiveCellCapture());
-      cellSelectionModel = new XCellSelectionModel();
-      grid.setSelectionModel(cellSelectionModel);
-
-      grid.registerPlugin(columnSelector);
-      grid.invalidate();
-      $('body').append(container);
-    });
-
-    afterEach(function () {
-      $('body').find(container).remove();
-    });
-
-    let selectColumnAction = ()=> {
-      container.find('.slick-header-column:contains(some-column-name)').click();
-
-      var selectedRanges = cellSelectionModel.getSelectedRanges();
-      expectOnlyTheFirstColumnToBeSelected(selectedRanges);
-    };
-
-    describe('when the user clicks a column header', function () {
-      it('selects the column', function () {
-        selectColumnAction();
-      });
-
-      it('toggles a selected class to the header cell', function () {
-        container.find('.slick-header-column:contains(second column)').click();
-        expect($(container.find('.slick-header-column:contains(second column)')).hasClass('selected'))
-          .toEqual(true);
-
-        container.find('.slick-header-column:contains(second column)').click();
-        expect($(container.find('.slick-header-column:contains(second column)')).hasClass('selected'))
-          .toEqual(false);
-      });
-    });
-
-    describe('when the user clicks an additional column header', function () {
-      beforeEach(function () {
-        container.find('.slick-header-column:contains(some-column-name)').click();
-        container.find('.slick-header-column:contains(second column)').click();
-      });
-
-      it('selects additional columns', function () {
-
-        var selectedRanges = cellSelectionModel.getSelectedRanges();
-
-        expect(selectedRanges.length).toEqual(2);
-        var column1 = selectedRanges[0];
-        expect(column1.fromCell).toEqual(1);
-        expect(column1.toCell).toEqual(1);
-
-        var column2 = selectedRanges[1];
-        expect(column2.fromCell).toEqual(2);
-        expect(column2.toCell).toEqual(2);
-      });
-
-      describe('and presses shift + right-arrow', function () {
-        beforeEach(function () {
-          pressShiftArrow(KEY.RIGHT);
-        });
-
-        it('keeps the last column selected', function () {
-          expect(cellSelectionModel.getSelectedRanges().length).toEqual(1);
-        });
-
-        it('grows the selection to the right', function () {
-          var selectedRange = cellSelectionModel.getSelectedRanges()[0];
-          expect(selectedRange.fromCell).toEqual(2);
-          expect(selectedRange.toCell).toEqual(3);
-          expect(selectedRange.fromRow).toEqual(0);
-          expect(selectedRange.toRow).toEqual(9);
-        });
-
-        it('keeps selected class on columns 2 and 3', function () {
-          expect($(container.find('.slick-header-column:contains(second column)')).hasClass('selected'))
-            .toEqual(true);
-          expect($(container.find('.slick-header-column:contains(third column)')).hasClass('selected'))
-            .toEqual(true);
-          expect($(container.find('.slick-header-column:contains(some-column-name)')).hasClass('selected'))
-            .toEqual(false);
-        });
-      });
-
-      describe('when the user deselects the last selected column header', function () {
-        beforeEach(function () {
-          container.find('.slick-header-column:contains(second column)').click();
-        });
-
-        describe('and presses shift + right-arrow', function () {
-          it('first and second columns are selected', function () {
-            pressShiftArrow(KEY.RIGHT);
-
-            var selectedRanges = cellSelectionModel.getSelectedRanges();
-
-            expect(selectedRanges.length).toEqual(1);
-            expect(selectedRanges[0].fromCell).toEqual(1);
-            expect(selectedRanges[0].toCell).toEqual(2);
-            expect(selectedRanges[0].fromRow).toEqual(0);
-            expect(selectedRanges[0].toRow).toEqual(9);
-          });
-        });
-      });
-    });
-
-    describe('when the user clicks a column header description', function () {
-      it('selects the column', function () {
-        container.find('.slick-header-columns span.column-description:contains(some-column-name)').click();
-
-        var selectedRanges = cellSelectionModel.getSelectedRanges();
-        expectOnlyTheFirstColumnToBeSelected(selectedRanges);
-      });
-
-      it('toggles a selected class to the header cell', function () {
-        container.find('.slick-header-column span.column-description:contains(second column)').click();
-        expect($(container.find('.slick-header-column:contains(second column)')).hasClass('selected'))
-          .toEqual(true);
-
-        container.find('.slick-header-column span.column-description:contains(second column)').click();
-        expect($(container.find('.slick-header-column:contains(second column)')).hasClass('selected'))
-          .toEqual(false);
-      });
-    });
-
-    describe('when a row is selected', function () {
-      beforeEach(function () {
-        var selectedRanges = [new Slick.Range(0, 0, 0, 1)];
-        cellSelectionModel.setSelectedRanges(selectedRanges);
-      });
-
-      it('deselects the row', function () {
-        container.find('.slick-header-column')[1].click();
-        var selectedRanges = cellSelectionModel.getSelectedRanges();
-
-        expect(selectedRanges.length).toEqual(1);
-
-        var column = selectedRanges[0];
-
-        expect(column.fromCell).toEqual(1);
-        expect(column.toCell).toEqual(1);
-        expect(column.fromRow).toEqual(0);
-        expect(column.toRow).toEqual(9);
-      });
-    });
-
-    describe('clicking a second time', function () {
-      beforeEach(function () {
-        container.find('.slick-header-column')[1].click();
-      });
-
-      it('deselects the column', function () {
-        container.find('.slick-header-column')[1].click();
-        var selectedRanges = cellSelectionModel.getSelectedRanges();
-
-        expect(selectedRanges.length).toEqual(0);
-      });
-    });
-
-    describe('when the column is not selectable', function () {
-      it('does not select the column', function () {
-        $(container.find('.slick-header-column:contains(some-non-selectable-column)')).trigger('click');
-        var selectedRanges = cellSelectionModel.getSelectedRanges();
-
-        expect(selectedRanges.length).toEqual(0);
-      });
-    });
-
-    describe('when a non-column range was already selected', function () {
-      beforeEach(function () {
-        var selectedRanges = [new Slick.Range(0, 0, 2, 0)];
-        cellSelectionModel.setSelectedRanges(selectedRanges);
-      });
-
-      it('deselects the non-column range', function () {
-        selectColumnAction();
-      });
-    });
-
-    describe('when a column is selected', function () {
-      beforeEach(function () {
-        container.find('.slick-header-column:contains(some-column-name)').click();
-      });
-
-      describe('when the user click a cell on the current range', function () {
-        beforeEach(function () {
-          container.find('.slick-cell.l1.r1')[1].click();
-        });
-
-        it('column is deselected', function () {
-
-          var selectedRanges = cellSelectionModel.getSelectedRanges();
-
-          expect(selectedRanges.length).toEqual(1);
-
-          var column = selectedRanges[0];
-
-          expect(column.fromCell).toEqual(1);
-          expect(column.toCell).toEqual(1);
-          expect(column.fromRow).toEqual(1);
-          expect(column.toRow).toEqual(1);
-        });
-
-        it('keep select class on column header', function () {
-          expect($(container.find('.slick-header-column:contains(some-column-name)')).hasClass('selected'))
-            .toBeTruthy();
-        });
-      });
-
-      describe('when the user click a cell outside the current range', function () {
-        beforeEach(function () {
-          container.find('.slick-cell.l2.r2')[2].click();
-        });
-
-        it('column is deselected', function () {
-
-          var selectedRanges = cellSelectionModel.getSelectedRanges();
-
-          expect(selectedRanges.length).toEqual(1);
-
-          var column = selectedRanges[0];
-
-          expect(column.fromCell).toEqual(2);
-          expect(column.toCell).toEqual(2);
-          expect(column.fromRow).toEqual(2);
-          expect(column.toRow).toEqual(2);
-        });
-
-        it('remove select class on \'some-column-name\' column header', function () {
-          expect($(container.find('.slick-header-column:contains(some-column-name)')).hasClass('selected'))
-            .toBeFalsy();
-          expect($(container.find('.slick-header-column:contains(second column)')).hasClass('selected'))
-            .toBeTruthy();
-        });
-      });
-
-      describe('when the user click in a row header', function () {
-        beforeEach(function () {
-          var selectedRanges = [new Slick.Range(1, 1, 1, 3)];
-          cellSelectionModel.setSelectedRanges(selectedRanges);
-        });
-
-        it('column is deselected', function () {
-          var selectedRanges = cellSelectionModel.getSelectedRanges();
-
-          expect(selectedRanges.length).toEqual(1);
-
-          var column = selectedRanges[0];
-
-          expect(column.fromCell).toEqual(1);
-          expect(column.toCell).toEqual(3);
-          expect(column.fromRow).toEqual(1);
-          expect(column.toRow).toEqual(1);
-        });
-
-        it('no column should have the class \'selected\'', function () {
-          expect($(container.find('.slick-header-column:contains(some-column-name)')).hasClass('selected'))
-            .toBeTruthy();
-        });
-      });
-    });
-  });
-
-  function setupGrid(gridColumns) {
-    var columnSelector = new ColumnSelector();
-    gridColumns = columnSelector.getColumnDefinitions(gridColumns);
-    var grid = new SlickGrid(container, data, gridColumns, options);
-
-    var cellSelectionModel = new XCellSelectionModel();
-    grid.setSelectionModel(cellSelectionModel);
-
-    grid.registerPlugin(columnSelector);
-    grid.invalidate();
-  }
-
-  function expectOnlyTheFirstColumnToBeSelected(selectedRanges) {
-    var row = selectedRanges[0];
-
-    expect(selectedRanges.length).toEqual(1);
-    expect(row.fromCell).toEqual(1);
-    expect(row.toCell).toEqual(1);
-    expect(row.fromRow).toEqual(0);
-    expect(row.toRow).toEqual(9);
-  }
-
-  function pressShiftArrow(keyCode) {
-    var pressEvent = new $.Event('keydown');
-    pressEvent.shiftKey = true;
-    pressEvent.ctrlKey = false;
-    pressEvent.altKey = false;
-    pressEvent.which = keyCode;
-
-    $(container.find('.grid-canvas')).trigger(pressEvent);
-  }
-});
diff --git a/web/regression/javascript/selection/copy_data_spec.js b/web/regression/javascript/selection/copy_data_spec.js
deleted file mode 100644
index 372ea09a..00000000
--- a/web/regression/javascript/selection/copy_data_spec.js
+++ /dev/null
@@ -1,150 +0,0 @@
-//////////////////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////////////////
-
-import $ from 'jquery';
-
-import Slick from 'slickgrid';
-import 'slickgrid.grid';
-
-import clipboard from '../../../pgadmin/static/js/selection/clipboard';
-import copyData from '../../../pgadmin/static/js/selection/copy_data';
-import RangeSelectionHelper from 'sources/selection/range_selection_helper';
-import XCellSelectionModel from 'sources/selection/xcell_selection_model';
-describe('copyData', function () {
-  var grid, sqlEditor, gridContainer, buttonPasteRow, buttonCopyWithHeader;
-  var SlickGrid;
-
-  beforeEach(function () {
-    SlickGrid = Slick.Grid;
-    var data = [{'id': 1, 'brand':'leopord', 'size':12, '__temp_PK': '123'},
-        {'id': 2, 'brand':'lion', 'size':13, '__temp_PK': '456'},
-        {'id': 3, 'brand':'puma', 'size':9, '__temp_PK': '789'}],
-      dataView = new Slick.Data.DataView();
-
-    var CSVOptions = {'quoting': 'strings', 'quote_char': '"', 'field_separator': ','};
-    var columns = [
-      {
-        id: 'row-header-column',
-        name: 'row header column name',
-        selectable: false,
-        display_name: 'row header column name',
-        column_type: 'text',
-      },
-      {
-        name: 'id',
-        field: 'id',
-        pos: 0,
-        label: 'id<br> numeric',
-        cell: 'number',
-        can_edit: false,
-        type: 'numeric',
-      }, {
-        name: 'brand',
-        field: 'brand',
-        pos: 1,
-        label: 'flavor<br> character varying',
-        cell: 'string',
-        can_edit: false,
-        type: 'character varying',
-      }, {
-        name: 'size',
-        field: 'size',
-        pos: 2,
-        label: 'size<br> numeric',
-        cell: 'number',
-        can_edit: false,
-        type: 'numeric',
-      },
-    ];
-    gridContainer = $('<div id="grid"></div>');
-    $('body').append(gridContainer);
-    buttonPasteRow = $('<button id="btn-paste-row" disabled></button>');
-    buttonCopyWithHeader = $('<button class="copy-with-header visibility-hidden"></button>');
-    $('body').append(buttonPasteRow);
-    $('body').append(buttonCopyWithHeader);
-    grid = new SlickGrid('#grid', dataView, columns, {});
-    grid.CSVOptions = CSVOptions;
-    dataView.setItems(data, '__temp_PK');
-    grid.setSelectionModel(new XCellSelectionModel());
-    sqlEditor = {slickgrid: grid};
-  });
-
-  afterEach(function() {
-    grid.destroy();
-    gridContainer.remove();
-    buttonPasteRow.remove();
-    buttonCopyWithHeader.remove();
-  });
-
-  describe('when rows are selected', function () {
-    beforeEach(function () {
-      grid.getSelectionModel().setSelectedRanges([
-        RangeSelectionHelper.rangeForRow(grid, 0),
-        RangeSelectionHelper.rangeForRow(grid, 2)]
-      );
-    });
-
-    it('copies them', function () {
-      spyOn(clipboard, 'copyTextToClipboard').and.callThrough();
-
-      copyData.apply(sqlEditor);
-
-      expect(sqlEditor.copied_rows.length).toEqual(2);
-
-      expect(clipboard.copyTextToClipboard).toHaveBeenCalled();
-      expect(clipboard.copyTextToClipboard.calls.mostRecent().args[0]).toContain('1,"leopord",12');
-      expect(clipboard.copyTextToClipboard.calls.mostRecent().args[0]).toContain('3,"puma",9');
-    });
-
-    describe('when the user can edit the grid', function () {
-      it('enables the paste row button', function () {
-        copyData.apply(_.extend({can_edit: true}, sqlEditor));
-
-        expect($('#btn-paste-row').prop('disabled')).toEqual(false);
-      });
-    });
-  });
-
-  describe('when a column is selected', function () {
-    beforeEach(function () {
-      var firstDataColumn = RangeSelectionHelper.rangeForColumn(grid, 1);
-      grid.getSelectionModel().setSelectedRanges([firstDataColumn]);
-    });
-
-    it('copies text to the clipboard', function () {
-      spyOn(clipboard, 'copyTextToClipboard');
-
-      copyData.apply(sqlEditor);
-
-      expect(clipboard.copyTextToClipboard).toHaveBeenCalled();
-
-      var copyArg = clipboard.copyTextToClipboard.calls.mostRecent().args[0];
-      var rowStrings = copyArg.split('\n');
-      expect(rowStrings[0]).toEqual('1');
-      expect(rowStrings[1]).toEqual('2');
-      expect(rowStrings[2]).toEqual('3');
-    });
-
-    it('sets copied_rows to empty', function () {
-      copyData.apply(sqlEditor);
-
-      expect(sqlEditor.copied_rows.length).toEqual(0);
-    });
-
-    describe('when the user can edit the grid', function () {
-      beforeEach(function () {
-        copyData.apply(_.extend({can_edit: true}, sqlEditor));
-      });
-
-      it('disables the paste row button', function () {
-        expect($('#btn-paste-row').prop('disabled')).toEqual(true);
-      });
-    });
-  });
-});
diff --git a/web/regression/javascript/selection/grid_selector_spec.js b/web/regression/javascript/selection/grid_selector_spec.js
deleted file mode 100644
index 2a3522b8..00000000
--- a/web/regression/javascript/selection/grid_selector_spec.js
+++ /dev/null
@@ -1,128 +0,0 @@
-//////////////////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////////////////
-
-import $ from 'jquery';
-
-import Slick from 'slickgrid';
-import 'slickgrid.grid';
-
-import GridSelector from 'sources/selection/grid_selector';
-import XCellSelectionModel from 'sources/selection/xcell_selection_model';
-
-describe('GridSelector', function () {
-  var container, data, columns, gridSelector, xCellSelectionModel;
-  var SlickGrid;
-
-  beforeEach(function () {
-    SlickGrid = Slick.Grid;
-    container = $('<div></div>');
-    container.height(9999);
-    columns = [{
-      id: '1',
-      name: 'some-column-name',
-      pos: 0,
-    }, {
-      id: '2',
-      name: 'second column',
-      pos: 1,
-    }];
-
-    gridSelector = new GridSelector();
-    columns = gridSelector.getColumnDefinitions(columns);
-
-    data = [];
-    for (var i = 0; i < 10; i++) {
-      data.push({'some-column-name': 'some-value-' + i, 'second column': 'second value ' + i});
-    }
-    var grid = new SlickGrid(container, data, columns);
-
-    xCellSelectionModel = new XCellSelectionModel();
-    grid.setSelectionModel(xCellSelectionModel);
-
-    grid.registerPlugin(gridSelector);
-    grid.invalidate();
-
-    $('body').append(container);
-  });
-
-  afterEach(function () {
-    $('body').find(container).remove();
-  });
-
-  it('renders an additional column on the left for selecting rows', function () {
-    expect(columns.length).toEqual(3);
-
-    var leftmostColumn = columns[0];
-    expect(leftmostColumn.id).toEqual('row-header-column');
-  });
-
-  it('renders a button for selecting all the cells', function () {
-    expect(container.find('[title=\'Select/Deselect All\']').length).toEqual(1);
-  });
-
-  describe('when the cell for the select/deselect all is clicked', function () {
-    it('selects the whole grid', function () {
-      container.find('[title=\'Select/Deselect All\']').parent().trigger('click');
-
-      var selectedRanges = xCellSelectionModel.getSelectedRanges();
-      expect(selectedRanges.length).toEqual(1);
-      var selectedRange = selectedRanges[0];
-      expect(selectedRange.fromCell).toEqual(1);
-      expect(selectedRange.toCell).toEqual(2);
-      expect(selectedRange.fromRow).toEqual(0);
-      expect(selectedRange.toRow).toEqual(9);
-    });
-
-    it('adds selected class', function () {
-      container.find('[title=\'Select/Deselect All\']').parent().trigger('click');
-
-      expect($(container.find('[data-id=\'select-all\']')).hasClass('selected')).toBeTruthy();
-    });
-  });
-
-  describe('when the select all button in the corner gets selected', function () {
-
-    it('selects all the cells', function () {
-      container.find('[title=\'Select/Deselect All\']').trigger('click');
-
-      var selectedRanges = xCellSelectionModel.getSelectedRanges();
-      expect(selectedRanges.length).toEqual(1);
-      var selectedRange = selectedRanges[0];
-      expect(selectedRange.fromCell).toEqual(1);
-      expect(selectedRange.toCell).toEqual(2);
-      expect(selectedRange.fromRow).toEqual(0);
-      expect(selectedRange.toRow).toEqual(9);
-    });
-
-    describe('when the select all button in the corner gets deselected', function () {
-      beforeEach(function () {
-        container.find('[title=\'Select/Deselect All\']').trigger('click');
-      });
-
-      it('deselects all the cells', function () {
-        container.find('[title=\'Select/Deselect All\']').trigger('click');
-
-        var selectedRanges = xCellSelectionModel.getSelectedRanges();
-        expect(selectedRanges.length).toEqual(0);
-      });
-    });
-
-    describe('and then the underlying selection changes', function () {
-      beforeEach(function () {
-        container.find('[title=\'Select/Deselect All\']').trigger('click');
-      });
-
-      it('removes the selected class', function () {
-        container.find('[title=\'Select/Deselect All\']').parent().trigger('click');
-
-        expect($(container.find('[data-id=\'select-all\']')).hasClass('selected')).toBeFalsy();
-      });
-    });
-  });
-});
diff --git a/web/regression/javascript/selection/range_boundary_navigator_spec.js b/web/regression/javascript/selection/range_boundary_navigator_spec.js
deleted file mode 100644
index 9ec71df5..00000000
--- a/web/regression/javascript/selection/range_boundary_navigator_spec.js
+++ /dev/null
@@ -1,189 +0,0 @@
-//////////////////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////////////////
-
-import rangeBoundaryNavigator from 'sources/selection/range_boundary_navigator';
-import Slick from 'slickgrid';
-
-describe('RangeBoundaryNavigator', function () {
-
-  describe('#getUnion', function () {
-    describe('when the ranges completely overlap', function () {
-      it('returns a list with that range', function () {
-        var ranges = [[1, 4], [1, 4], [1, 4]];
-
-        var union = rangeBoundaryNavigator.getUnion(ranges);
-
-        expect(union).toEqual([[1, 4]]);
-      });
-    });
-
-    describe('when the ranges all overlap partially or touch', function () {
-      it('returns one long range', function () {
-        var rangeBounds = [[3, 6], [1, 4], [7, 14]];
-
-        var union = rangeBoundaryNavigator.getUnion(rangeBounds);
-
-        expect(union).toEqual([[1, 14]]);
-      });
-
-      it('returns them in order from lowest to highest', function () {
-        var rangeBounds = [[3, 6], [2, 3], [10, 12]];
-
-        var union = rangeBoundaryNavigator.getUnion(rangeBounds);
-
-        expect(union).toEqual([[2, 6], [10, 12]]);
-      });
-
-      describe('when one range completely overlaps another', function() {
-
-        it('returns them in order from lowest to highest', function () {
-          var rangeBounds = [[9, 14], [2, 3], [11, 13]];
-
-          var union = rangeBoundaryNavigator.getUnion(rangeBounds);
-
-          expect(union).toEqual([[2, 3], [9, 14]]);
-        });
-      });
-
-      describe('when one range is a subset of another', function () {
-        it('returns the larger range', function () {
-          var rangeBounds = [[2, 6], [1, 14], [8, 10]];
-
-          var union = rangeBoundaryNavigator.getUnion(rangeBounds);
-
-          expect(union).toEqual([[1, 14]]);
-        });
-      });
-    });
-
-    describe('when the ranges do not touch', function () {
-      it('returns them in order from lowest to highest', function () {
-        var rangeBounds = [[3, 6], [1, 1], [8, 10]];
-
-        var union = rangeBoundaryNavigator.getUnion(rangeBounds);
-
-        expect(union).toEqual([[1, 1], [3, 6], [8, 10]]);
-      });
-    });
-  });
-
-  describe('#mapDimensionBoundaryUnion', function () {
-    it('returns a list of the results of the callback', function () {
-      var rangeBounds = [[0, 1], [3, 3]];
-      var callback = function () {
-        return 'hello';
-      };
-      var result = rangeBoundaryNavigator.mapDimensionBoundaryUnion(rangeBounds, callback);
-      expect(result).toEqual(['hello', 'hello', 'hello']);
-    });
-
-    it('calls the callback with each index in the dimension', function () {
-      var rangeBounds = [[0, 1], [3, 3]];
-      var callback = jasmine.createSpy('callbackSpy');
-      rangeBoundaryNavigator.mapDimensionBoundaryUnion(rangeBounds, callback);
-      expect(callback.calls.allArgs()).toEqual([[0], [1], [3]]);
-    });
-  });
-
-  describe('#mapOver2DArray', function () {
-    var data, rowCollector, processCell;
-    beforeEach(function () {
-      data = [[0, 1, 2, 3], [2, 2, 2, 2], [4, 5, 6, 7]];
-      processCell = function (rowIndex, columnIndex) {
-        return data[rowIndex][columnIndex];
-      };
-      rowCollector = function (rowData) {
-        return JSON.stringify(rowData);
-      };
-    });
-
-    it('calls the callback for each item in the ranges', function () {
-      var rowRanges = [[0, 0], [2, 2]];
-      var colRanges = [[0, 3]];
-
-      var selectionResult = rangeBoundaryNavigator.mapOver2DArray(rowRanges, colRanges, processCell, rowCollector);
-
-      expect(selectionResult).toEqual(['[0,1,2,3]', '[4,5,6,7]']);
-    });
-
-    describe('when the ranges are out of order/duplicated', function () {
-      var rowRanges, colRanges;
-      beforeEach(function () {
-        rowRanges = [[2, 2], [2, 2], [0, 0]];
-        colRanges = [[0, 3]];
-      });
-
-      it('uses the union of the ranges', function () {
-        spyOn(rangeBoundaryNavigator, 'getUnion').and.callThrough();
-
-        var selectionResult = rangeBoundaryNavigator.mapOver2DArray(rowRanges, colRanges, processCell, rowCollector);
-
-        expect(rangeBoundaryNavigator.getUnion).toHaveBeenCalledWith(rowRanges);
-        expect(rangeBoundaryNavigator.getUnion).toHaveBeenCalledWith(colRanges);
-        expect(selectionResult).toEqual(['[0,1,2,3]', '[4,5,6,7]']);
-      });
-    });
-  });
-
-  describe('#rangesToCsv', function () {
-    var data, columnDefinitions, ranges, CSVOptions;
-    beforeEach(function () {
-      data = [{'id':1, 'animal':'leopard', 'size':'12'},
-        {'id':2, 'animal':'lion', 'size':'13'},
-        {'id':3, 'animal':'cougar', 'size':'9'},
-        {'id':4, 'animal':'tiger', 'size':'10'}];
-
-      columnDefinitions = [{name: 'id', field: 'id', pos: 0, cell:'number'},
-        {name: 'animal', field: 'animal', pos: 1, cell:'string'},
-        {name: 'size', field: 'size', pos: 2, cell:'string'}];
-      ranges = [new Slick.Range(0, 0, 0, 2), new Slick.Range(3, 0, 3, 2)];
-
-      CSVOptions = [{'quoting': 'all', 'quote_char': '"', 'field_separator': ','},
-        {'quoting': 'strings', 'quote_char': '"', 'field_separator': ';'},
-        {'quoting': 'strings', 'quote_char': '\'', 'field_separator': '|'},
-        {'quoting': 'none', 'quote_char': '"', 'field_separator': '\t'}];
-    });
-
-    it('returns csv for the provided ranges for CSV options quoting All with char " with field separator ,', function () {
-      var csvResult = rangeBoundaryNavigator.rangesToCsv(data, columnDefinitions, ranges, CSVOptions[0]);
-      expect(csvResult).toEqual('"1","leopard","12"\n"4","tiger","10"');
-    });
-
-    describe('when no cells are selected for CSV options quoting Strings with char " with field separator ;', function () {
-      it('should return an empty string', function () {
-        var csvResult = rangeBoundaryNavigator.rangesToCsv(data, columnDefinitions, [], CSVOptions[1]);
-
-        expect(csvResult).toEqual('');
-      });
-    });
-
-    describe('when there is an extra column with checkboxes', function () {
-      beforeEach(function () {
-        columnDefinitions = [{name: 'not-a-data-column'},
-          {name: 'id', field: 'id', pos: 0, cell:'number'},
-          {name: 'animal', field: 'animal', pos: 1, cell:'string'},
-          {name: 'size', field: 'size',pos: 2, cell:'string'}];
-        ranges = [new Slick.Range(0, 0, 0, 3), new Slick.Range(3, 0, 3, 3)];
-      });
-
-      it('returns csv for the columns with data for CSV options quoting Strings with char \' with field separator |', function () {
-        var csvResult = rangeBoundaryNavigator.rangesToCsv(data, columnDefinitions, ranges, CSVOptions[2]);
-
-        expect(csvResult).toEqual('1|\'leopard\'|\'12\'\n4|\'tiger\'|\'10\'');
-      });
-      describe('when no cells are selected for CSV options quoting none with field separator tab', function () {
-        it('should return an empty string', function () {
-          var csvResult = rangeBoundaryNavigator.rangesToCsv(data, columnDefinitions, [], CSVOptions[3]);
-
-          expect(csvResult).toEqual('');
-        });
-      });
-    });
-  });
-});
diff --git a/web/regression/javascript/selection/range_selection_helper_spec.js b/web/regression/javascript/selection/range_selection_helper_spec.js
deleted file mode 100644
index cfbf2b15..00000000
--- a/web/regression/javascript/selection/range_selection_helper_spec.js
+++ /dev/null
@@ -1,100 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import $ from 'jquery';
-import Slick from 'slickgrid';
-import 'slickgrid.grid';
-import RangeSelectionHelper from 'sources/selection/range_selection_helper';
-
-describe('RangeSelectionHelper utility functions', function () {
-  var grid;
-  beforeEach(function () {
-    var container, data, columns, options;
-    container = $('<div></div>');
-    container.height(9999);
-
-    columns = [{
-      id: '1',
-      name: 'some-column-name',
-      pos: 0,
-    }, {
-      id: 'second-column-id',
-      name: 'second column',
-      pos: 1,
-    }];
-
-    data = [];
-    for (var i = 0; i < 10; i++) {
-      data.push({'some-column-name': 'some-value-' + i, 'second column': 'second value ' + i});
-    }
-
-    grid = new Slick.Grid(container, data, columns, options);
-    grid.invalidate();
-  });
-
-  describe('#getIndexesOfCompleteRows', function () {
-    describe('when selected ranges are not rows', function () {
-      it('returns an empty array', function () {
-        var rowlessRanges = [RangeSelectionHelper.rangeForColumn(grid, 1)];
-
-        expect(RangeSelectionHelper.getIndexesOfCompleteRows(grid, rowlessRanges))
-          .toEqual([]);
-      });
-    });
-    describe('when selected range', function () {
-      describe('is a single row', function () {
-        it('returns an array with one index', function () {
-          var singleRowRange = [RangeSelectionHelper.rangeForRow(grid, 1)];
-
-          expect(RangeSelectionHelper.getIndexesOfCompleteRows(grid, singleRowRange))
-            .toEqual([1]);
-        });
-      });
-
-      describe('is multiple rows', function () {
-        it('returns an array of each row\'s index', function () {
-          var multipleRowRange = [
-            RangeSelectionHelper.rangeForRow(grid, 0),
-            RangeSelectionHelper.rangeForRow(grid, 3),
-            RangeSelectionHelper.rangeForRow(grid, 2),
-          ];
-
-          var indexesOfCompleteRows = RangeSelectionHelper.getIndexesOfCompleteRows(grid, multipleRowRange);
-          indexesOfCompleteRows.sort();
-          expect(indexesOfCompleteRows).toEqual([0, 2, 3]);
-        });
-      });
-
-      describe('contains a multi row selection', function () {
-        it('returns an array of each individual row\'s index', function () {
-          var multipleRowRange = [
-            new Slick.Range(3, 0, 5, 1),
-          ];
-
-          var indexesOfCompleteRows = RangeSelectionHelper.getIndexesOfCompleteRows(grid, multipleRowRange);
-          indexesOfCompleteRows.sort();
-          expect(indexesOfCompleteRows).toEqual([3, 4, 5]);
-        });
-
-        describe('and also contains a selection that is not a row', function () {
-          it('returns an array of only the complete rows\' indexes', function () {
-            var multipleRowRange = [
-              new Slick.Range(8, 1, 9, 1),
-              new Slick.Range(3, 0, 5, 1),
-            ];
-
-            var indexesOfCompleteRows = RangeSelectionHelper.getIndexesOfCompleteRows(grid, multipleRowRange);
-            indexesOfCompleteRows.sort();
-            expect(indexesOfCompleteRows).toEqual([3, 4, 5]);
-          });
-        });
-      });
-    });
-  });
-});
diff --git a/web/regression/javascript/selection/row_selector_spec.js b/web/regression/javascript/selection/row_selector_spec.js
deleted file mode 100644
index 40a8970e..00000000
--- a/web/regression/javascript/selection/row_selector_spec.js
+++ /dev/null
@@ -1,328 +0,0 @@
-//////////////////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////////////////
-import $ from 'jquery';
-
-import Slick from 'slickgrid';
-import 'slickgrid.grid';
-
-import RowSelector from 'sources/selection/row_selector';
-import ActiveCellCapture from 'sources/selection/active_cell_capture';
-import XCellSelectionModel from 'sources/selection/xcell_selection_model';
-
-describe('RowSelector', function () {
-  var KEY = {
-    RIGHT: 39,
-    LEFT: 37,
-    UP: 38,
-    DOWN: 40,
-  };
-  var container, dataView, columnDefinitions, grid, cellSelectionModel;
-  var SlickGrid = Slick.Grid;
-
-  beforeEach(function () {
-    container = $('<div></div>');
-    container.height(9999);
-    container.width(9999);
-
-    columnDefinitions = [{
-      id: '1',
-      name: 'some-column-name',
-      selectable: true,
-      pos: 0,
-    }, {
-      id: '2',
-      name: 'second column',
-      selectable: true,
-      pos: 1,
-    }];
-
-    dataView = new Slick.Data.DataView();
-    var rowSelector = new RowSelector();
-    var data = [];
-    for (var i = 0; i < 10; i++) {
-      data.push({'some-column-name':'some-value-' + i, 'second column':'second value ' + i});
-    }
-    columnDefinitions = rowSelector.getColumnDefinitions(columnDefinitions);
-    dataView.setItems(data, 'some-column-name');
-    grid = new SlickGrid(container, dataView, columnDefinitions);
-    grid.registerPlugin(new ActiveCellCapture());
-    cellSelectionModel = new XCellSelectionModel();
-    grid.setSelectionModel(cellSelectionModel);
-
-    grid.registerPlugin(rowSelector);
-    grid.invalidate();
-
-    $('body').append(container);
-  });
-
-  afterEach(function () {
-    $('body').find(container).remove();
-  });
-
-  it('renders an additional column on the left', function () {
-    expect(columnDefinitions.length).toEqual(3);
-
-    var leftmostColumn = columnDefinitions[0];
-    expect(leftmostColumn.id).toEqual('row-header-column');
-    expect(leftmostColumn.name).toEqual('');
-    expect(leftmostColumn.selectable).toEqual(false);
-  });
-
-  it('renders a span on the leftmost column', function () {
-    expect(container.find('.slick-row').length).toEqual(10);
-    expect(container.find('.slick-row .slick-cell:first-child span[data-cell-type="row-header-selector"]').length).toEqual(10);
-  });
-
-  it('preserves the other attributes of column definitions', function () {
-    expect(columnDefinitions[1].id).toEqual('1');
-    expect(columnDefinitions[1].selectable).toEqual(true);
-  });
-
-  describe('selecting rows', function () {
-    describe('when the user clicks a row header span', function () {
-      it('selects the row', function () {
-        container.find('.slick-row .slick-cell:first-child span[data-cell-type="row-header-selector"]')[0].click();
-
-        var selectedRanges = cellSelectionModel.getSelectedRanges();
-        expectOnlyTheFirstRowToBeSelected(selectedRanges);
-      });
-
-      it('add selected class to parent of the span', function () {
-        container.find('.slick-row .slick-cell:first-child span[data-cell-type="row-header-selector"]')[5].click();
-
-        expect($(container.find('.slick-row .slick-cell:first-child ')[5])
-          .hasClass('selected')).toBeTruthy();
-      });
-    });
-
-    describe('when the user clicks a row header', function () {
-      beforeEach(function () {
-        container.find('.slick-row .slick-cell:first-child')[1].click();
-
-      });
-      it('selects the row', function () {
-
-        var selectedRanges = cellSelectionModel.getSelectedRanges();
-        var row = selectedRanges[0];
-
-        expect(selectedRanges.length).toEqual(1);
-        expect(row.fromCell).toEqual(1);
-        expect(row.toCell).toEqual(2);
-        expect(row.fromRow).toEqual(1);
-        expect(row.toRow).toEqual(1);
-      });
-
-      it('add selected class to parent of the span', function () {
-
-        expect($(container.find('.slick-row .slick-cell:first-child ')[1])
-          .hasClass('selected')).toBeTruthy();
-      });
-
-      describe('when the user clicks again the same row header', function () {
-        it('add selected class to parent of the span', function () {
-          container.find('.slick-row .slick-cell:first-child span[data-cell-type="row-header-selector"]')[1].click();
-
-          expect($(container.find('.slick-row .slick-cell:first-child ')[1])
-            .hasClass('selected')).toBeFalsy();
-        });
-      });
-
-      describe('and presses shift + down-arrow', function () {
-        beforeEach(function () {
-          pressShiftArrow(KEY.DOWN);
-        });
-
-        it('keeps the last row selected', function () {
-          expect(cellSelectionModel.getSelectedRanges().length).toEqual(1);
-        });
-
-        it('grows the selection down', function () {
-          var selectedRanges = cellSelectionModel.getSelectedRanges();
-
-          var row = selectedRanges[0];
-
-          expect(selectedRanges.length).toEqual(1);
-          expect(row.fromCell).toEqual(1);
-          expect(row.toCell).toEqual(2);
-          expect(row.fromRow).toEqual(1);
-          expect(row.toRow).toEqual(2);
-        });
-
-        it('keeps selected class on rows 1 and 2', function () {
-          expect($(container.find('.slick-row .slick-cell:first-child ')[0])
-            .hasClass('selected')).toBeFalsy();
-          expect($(container.find('.slick-row .slick-cell:first-child ')[1])
-            .hasClass('selected')).toBeTruthy();
-          expect($(container.find('.slick-row .slick-cell:first-child ')[2])
-            .hasClass('selected')).toBeTruthy();
-          expect($(container.find('.slick-row .slick-cell:first-child ')[3])
-            .hasClass('selected')).toBeFalsy();
-        });
-      });
-
-      describe('when the user clicks a cell on the current range', function () {
-        beforeEach(function () {
-          container.find('.slick-cell.l1.r1')[5].click();
-        });
-
-        it('row gets deselected', function () {
-
-          var selectedRanges = cellSelectionModel.getSelectedRanges();
-
-          expect(selectedRanges.length).toEqual(1);
-
-          var newSelection = selectedRanges[0];
-
-          expect(newSelection.fromCell).toEqual(1);
-          expect(newSelection.fromRow).toEqual(5);
-          expect(newSelection.toCell).toEqual(1);
-          expect(newSelection.toRow).toEqual(5);
-        });
-
-        it('keep select class on row header', function () {
-          expect($(container.find('.slick-cell.l0.r0')[5]).hasClass('selected'))
-            .toBeTruthy();
-        });
-      });
-
-      describe('when the user clicks a cell outside the current range', function () {
-        beforeEach(function () {
-          container.find('.slick-cell.l2.r2')[2].click();
-        });
-
-        it('row gets deselected', function () {
-
-          var selectedRanges = cellSelectionModel.getSelectedRanges();
-
-          expect(selectedRanges.length).toEqual(1);
-
-          var newSelection = selectedRanges[0];
-
-          expect(newSelection.fromCell).toEqual(2);
-          expect(newSelection.fromRow).toEqual(2);
-          expect(newSelection.toCell).toEqual(2);
-          expect(newSelection.toRow).toEqual(2);
-        });
-
-        it('remove select class on "some-column-name" column header', function () {
-          expect($(container.find('.slick-cell.l0.r0')[5]).hasClass('selected'))
-            .toBeFalsy();
-          expect($(container.find('.slick-cell.l0.r0')[2]).hasClass('selected'))
-            .toBeTruthy();
-        });
-      });
-
-      describe('when the user has a column selected', function () {
-        beforeEach(function () {
-          var selectedRanges = [new Slick.Range(0, 1, 9, 1)];
-          cellSelectionModel.setSelectedRanges(selectedRanges);
-        });
-
-        it('no row should have the class "selected"', function () {
-          expect($(container.find('.slick-cell.l0.r0')[0]).hasClass('selected'))
-            .toBeFalsy();
-          expect($(container.find('.slick-cell.l0.r0')[1]).hasClass('selected'))
-            .toBeFalsy();
-          expect($(container.find('.slick-cell.l0.r0')[2]).hasClass('selected'))
-            .toBeFalsy();
-          expect($(container.find('.slick-cell.l0.r0')[3]).hasClass('selected'))
-            .toBeFalsy();
-          expect($(container.find('.slick-cell.l0.r0')[4]).hasClass('selected'))
-            .toBeFalsy();
-          expect($(container.find('.slick-cell.l0.r0')[5]).hasClass('selected'))
-            .toBeFalsy();
-        });
-      });
-    });
-
-    describe('when the user clicks multiple row headers', function () {
-      it('selects another row', function () {
-        container.find('.slick-row .slick-cell:first-child')[4].click();
-        container.find('.slick-row .slick-cell:first-child')[0].click();
-
-        var selectedRanges = cellSelectionModel.getSelectedRanges();
-        expect(selectedRanges.length).toEqual(2);
-
-        var row1 = selectedRanges[0];
-        expect(row1.fromRow).toEqual(4);
-        expect(row1.toRow).toEqual(4);
-
-        var row2 = selectedRanges[1];
-        expect(row2.fromRow).toEqual(0);
-        expect(row2.toRow).toEqual(0);
-      });
-    });
-
-    describe('when a column was already selected', function () {
-      beforeEach(function () {
-        var selectedRanges = [new Slick.Range(0, 0, 0, 1)];
-        cellSelectionModel.setSelectedRanges(selectedRanges);
-      });
-
-      it('deselects the column', function () {
-        container.find('.slick-row .slick-cell:first-child')[0].click();
-        var selectedRanges = cellSelectionModel.getSelectedRanges();
-
-        expectOnlyTheFirstRowToBeSelected(selectedRanges);
-      });
-    });
-
-    describe('when the row is deselected through setSelectedRanges', function () {
-      beforeEach(function () {
-        container.find('.slick-row .slick-cell:first-child')[4].click();
-      });
-
-      it('should remove the selected class', function () {
-        cellSelectionModel.setSelectedRanges([]);
-
-        expect($(container.find('.slick-row .slick-cell:first-child span[data-cell-type="row-header-selector"]')[4])
-          .hasClass('selected')).toBeFalsy();
-      });
-    });
-
-    describe('click a second time', function () {
-      beforeEach(function () {
-        container.find('.slick-row .slick-cell:first-child')[1].click();
-      });
-
-      it('removes the selected class', function () {
-        container.find('.slick-row .slick-cell:first-child')[1].click();
-        expect($(container.find('.slick-row .slick-cell:first-child span[data-cell-type="row-header-selector"]')[1])
-          .hasClass('selected')).toBeFalsy();
-      });
-
-      it('unselects the row', function () {
-        container.find('.slick-row .slick-cell:first-child')[1].click();
-        var selectedRanges = cellSelectionModel.getSelectedRanges();
-
-        expect(selectedRanges.length).toEqual(0);
-      });
-    });
-  });
-
-  function pressShiftArrow(keyCode) {
-    var pressEvent = new $.Event('keydown');
-    pressEvent.shiftKey = true;
-    pressEvent.ctrlKey = false;
-    pressEvent.altKey = false;
-    pressEvent.which = keyCode;
-
-    $(container.find('.grid-canvas')).trigger(pressEvent);
-  }
-
-  function expectOnlyTheFirstRowToBeSelected(selectedRanges) {
-    var row = selectedRanges[0];
-
-    expect(selectedRanges.length).toEqual(1);
-    expect(row.fromCell).toEqual(1);
-    expect(row.toCell).toEqual(2);
-    expect(row.fromRow).toEqual(0);
-    expect(row.toRow).toEqual(0);
-  }
-});
diff --git a/web/regression/javascript/selection/set_staged_rows_spec.js b/web/regression/javascript/selection/set_staged_rows_spec.js
deleted file mode 100644
index 3ed3ae25..00000000
--- a/web/regression/javascript/selection/set_staged_rows_spec.js
+++ /dev/null
@@ -1,253 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import $ from 'jquery';
-import 'slickgrid.grid';
-import Slick from 'slickgrid';
-import SetStagedRows from 'sources/selection/set_staged_rows';
-
-describe('set_staged_rows', function () {
-  var sqlEditorObj, gridSpy, deleteButton, copyButton, selectionSpy;
-  beforeEach(function () {
-    var data = [{'a pk column': 'one', 'some column': 'two', '__temp_PK': '123'},
-        {'a pk column': 'three', 'some column': 'four', '__temp_PK': '456'},
-        {'a pk column': 'five', 'some column': 'six', '__temp_PK': '789'},
-        {'a pk column': 'seven', 'some column': 'eight', '__temp_PK': '432'}],
-      dataView = new Slick.Data.DataView();
-
-    dataView.setItems(data, '__temp_PK');
-
-    gridSpy = jasmine.createSpyObj('gridSpy', ['getData', 'getCellNode', 'getColumns']);
-    gridSpy.getData.and.returnValue(dataView);
-    gridSpy.getColumns.and.returnValue([
-      {
-        name: 'a pk column',
-        field: 'a pk column',
-        pos: 0,
-        selectable: true,
-      }, {
-        name: 'some column',
-        field: 'some column',
-        pos: 1,
-        selectable: true,
-      },
-    ]);
-    selectionSpy = jasmine.createSpyObj('selectionSpy', ['setSelectedRows', 'getSelectedRanges']);
-    deleteButton = $('<button id="btn-delete-row"></button>');
-    copyButton = $('<button id="btn-copy-row"></button>');
-
-    sqlEditorObj = {
-      grid: gridSpy,
-      editor: {
-        handler: {
-          data_store: {
-            staged_rows: {'456': {}},
-          },
-          can_edit: false,
-        },
-      },
-      keys: null,
-      selection: selectionSpy,
-      columns: [
-        {
-          name: 'a pk column',
-          field: 'a pk column',
-          pos: 0,
-        },
-        {
-          name: 'some column',
-          field: 'some column',
-          pos: 1,
-        },
-      ],
-      client_primary_key: '__temp_PK',
-    };
-
-    $('body').append(deleteButton);
-    $('body').append(copyButton);
-
-    deleteButton.prop('disabled', true);
-    copyButton.prop('disabled', true);
-
-    selectionSpy = jasmine.createSpyObj('selectionSpy', [
-      'setSelectedRows',
-      'getSelectedRanges',
-    ]);
-  });
-
-  afterEach(function () {
-    copyButton.remove();
-    deleteButton.remove();
-  });
-  describe('when no full rows are selected', function () {
-    describe('when nothing is selected', function () {
-      beforeEach(function () {
-        selectionSpy.getSelectedRanges.and.returnValue([]);
-        sqlEditorObj.selection = selectionSpy;
-        SetStagedRows.call(sqlEditorObj, {}, {});
-      });
-
-      it('should disable the delete row button', function () {
-        expect($('#btn-delete-row').prop('disabled')).toBeTruthy();
-      });
-
-      it('should disable the copy row button', function () {
-        expect($('#btn-copy-row').prop('disabled')).toBeTruthy();
-      });
-
-      it('should clear staged rows', function () {
-        expect(sqlEditorObj.editor.handler.data_store.staged_rows).toEqual({});
-      });
-    });
-
-    describe('when there is a selection', function () {
-      beforeEach(function () {
-        var range = {
-          fromCell: 0,
-          toCell: 0,
-          fromRow: 1,
-          toRow: 1,
-        };
-
-        selectionSpy.getSelectedRanges.and.returnValue([range]);
-        sqlEditorObj.selection = selectionSpy;
-        SetStagedRows.call(sqlEditorObj, {}, {});
-      });
-
-      it('should disable the delete row button', function () {
-        expect($('#btn-delete-row').prop('disabled')).toBeTruthy();
-      });
-
-      it('should disable the copy row button', function () {
-        expect($('#btn-copy-row').prop('disabled')).toBeFalsy();
-      });
-
-      it('should clear staged rows', function () {
-        expect(sqlEditorObj.editor.handler.data_store.staged_rows).toEqual({});
-      });
-    });
-  });
-
-  describe('when 2 full rows are selected', function () {
-    beforeEach(function () {
-      var range1 = {
-        fromCell: 0,
-        toCell: 1,
-        fromRow: 1,
-        toRow: 1,
-      };
-      var range2 = {
-        fromCell: 0,
-        toCell: 1,
-        fromRow: 2,
-        toRow: 2,
-      };
-
-      selectionSpy.getSelectedRanges.and.returnValue([range1, range2]);
-      sqlEditorObj.selection = selectionSpy;
-    });
-
-    describe('when table does not have primary keys', function () {
-      it('should enable the copy row button', function () {
-        SetStagedRows.call(sqlEditorObj, {}, {});
-        expect($('#btn-copy-row').prop('disabled')).toBeFalsy();
-      });
-
-      it('should not enable the delete row button', function () {
-        SetStagedRows.call(sqlEditorObj, {}, {});
-        expect($('#btn-delete-row').prop('disabled')).toBeTruthy();
-      });
-
-      it('should update staged rows with the __temp_PK value of the new Selected Rows', function () {
-        SetStagedRows.call(sqlEditorObj, {}, {});
-        expect(sqlEditorObj.editor.handler.data_store.staged_rows).toEqual({'456': {}, '789': {}});
-      });
-
-      describe('the user can edit', function () {
-        it('should enable the delete row button', function () {
-          sqlEditorObj.editor.handler.can_edit = true;
-          SetStagedRows.call(sqlEditorObj, {}, {});
-          expect($('#btn-delete-row').prop('disabled')).toBeFalsy();
-        });
-      });
-    });
-
-    describe('when table has primary keys', function () {
-      beforeEach(function () {
-        sqlEditorObj.keys = {'a pk column': 'varchar'};
-        sqlEditorObj.editor.handler.data_store.staged_rows = {'456': {'a pk column': 'three'}};
-      });
-
-      describe('selected rows have primary key', function () {
-        it('should set the staged rows correctly', function () {
-          SetStagedRows.call(sqlEditorObj, {}, {});
-          expect(sqlEditorObj.editor.handler.data_store.staged_rows).toEqual(
-            {'456': {'a pk column': 'three'}, '789': {'a pk column': 'five'}});
-        });
-
-        it('should not clear selected rows in Cell Selection Model', function () {
-          SetStagedRows.call(sqlEditorObj, {}, {});
-          expect(sqlEditorObj.selection.setSelectedRows).not.toHaveBeenCalledWith();
-        });
-      });
-
-      describe('selected rows missing primary key', function () {
-        beforeEach(function () {
-          var data = [{'a pk column': 'one', 'some column': 'two', '__temp_PK': '123'},
-              {'some column': 'four', '__temp_PK': '456'},
-              {'some column': 'six', '__temp_PK': '789'},
-              {'a pk column': 'seven', 'some column': 'eight', '__temp_PK': '432'}],
-            dataView = new Slick.Data.DataView();
-
-          dataView.setItems(data, '__temp_PK');
-
-          gridSpy.getData.and.returnValue(dataView);
-        });
-
-        it('should clear the staged rows', function () {
-          SetStagedRows.call(sqlEditorObj, {}, {});
-          expect(sqlEditorObj.editor.handler.data_store.staged_rows).toEqual({});
-        });
-
-        it('should clear selected rows in Cell Selection Model', function () {
-          SetStagedRows.call(sqlEditorObj, {}, {});
-          expect(sqlEditorObj.selection.setSelectedRows).toHaveBeenCalledWith([]);
-        });
-      });
-
-      describe('when the selected row is a new row', function () {
-        var parentDiv;
-        beforeEach(function () {
-          var childDiv = $('<div></div>');
-          parentDiv = $('<div class="new_row"></div>');
-          parentDiv.append(childDiv);
-          $('body').append(parentDiv);
-          gridSpy.getCellNode.and.returnValue(childDiv);
-          SetStagedRows.call(sqlEditorObj, {}, {});
-        });
-
-        afterEach(function () {
-          parentDiv.remove();
-        });
-
-        it('should not clear the staged rows', function () {
-          expect(sqlEditorObj.editor.handler.data_store.staged_rows).toEqual({
-            '456': {'a pk column': 'three'},
-            '789': {'a pk column': 'five'},
-          });
-        });
-
-        it('should not clear selected rows in Cell Selection Model', function () {
-          expect(sqlEditorObj.selection.setSelectedRows).not.toHaveBeenCalled();
-        });
-      });
-    });
-  });
-});
-
diff --git a/web/regression/javascript/selection/xcell_selection_model_spec.js b/web/regression/javascript/selection/xcell_selection_model_spec.js
deleted file mode 100644
index 54639579..00000000
--- a/web/regression/javascript/selection/xcell_selection_model_spec.js
+++ /dev/null
@@ -1,518 +0,0 @@
-//////////////////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////////////////
-
-import 'slickgrid.plugins/slick.cellrangeselector';
-import XCellSelectionModel from 'sources/selection/xcell_selection_model';
-import 'slickgrid.grid';
-import Slick from 'slickgrid';
-import $ from 'jquery';
-
-describe('XCellSelectionModel', function () {
-  var KEY_RIGHT = 39;
-  var KEY_LEFT = 37;
-  var KEY_UP = 38;
-  var KEY_DOWN = 40;
-
-  var container, grid;
-  var SlickGrid = Slick.Grid;
-  var oldWindowParent = window.parent;
-
-  beforeEach(function () {
-    window.parent = window;
-
-    var columns = [{
-      id: 'row-header-column',
-      name: 'row header column name',
-      selectable: false,
-    }, {
-      id: '1',
-      name: 'some-column-name',
-      field: 'some-column-name',
-      pos: 0,
-    }, {
-      id: 'second-column-id',
-      name: 'second column',
-      field: 'second column',
-      pos: 1,
-    }, {
-      id: 'third-column-id',
-      name: 'third column',
-      field: 'third column',
-      pos: 2,
-    },
-    ];
-
-    var data = [];
-    for (var i = 0; i < 10; i++) {
-      data.push({
-        'some-column-name': 'some-value-' + i,
-        'second column': 'second value ' + i,
-        'third column': 'third value ' + i,
-        'fourth column': 'fourth value ' + i,
-        '__temp_PK': '123' + i,
-      });
-    }
-    container = $('<div></div>');
-    var dataView = new Slick.Data.DataView();
-    container.height(9999);
-    container.width(9999);
-    dataView.setItems(data, '__temp_PK');
-    grid = new SlickGrid(container, dataView, columns);
-    grid.setSelectionModel(new XCellSelectionModel());
-    $('body').append(container);
-  });
-
-  afterEach(function () {
-    grid.destroy();
-    container.remove();
-    window.parent = oldWindowParent;
-  });
-
-  describe('handleKeyDown', function () {
-    describe('when we press a random key', function () {
-      it('should not change the range', function () {
-        var range = new Slick.Range(1, 2);
-        grid.setActiveCell(1, 2);
-        grid.getSelectionModel().setSelectedRanges([range]);
-        pressKey(72);
-
-        expect(grid.getSelectionModel().getSelectedRanges()[0]).toEqual(range);
-      });
-    });
-
-    describe('when we press an arrow key ', function () {
-      it('should select the cell to the right', function () {
-        var range = new Slick.Range(1, 2);
-        grid.setActiveCell(1, 2);
-        grid.getSelectionModel().setSelectedRanges([range]);
-        pressKey(KEY_RIGHT);
-
-        expectOneSelectedRange(1, 3, 1, 3);
-      });
-    });
-
-    describe('when we press shift', function () {
-      describe('and we press an arrow key', function () {
-        var scrollColumnIntoViewSpy, scrollRowIntoViewSpy;
-
-        beforeEach(function () {
-          scrollColumnIntoViewSpy = spyOn(grid, 'scrollColumnIntoView');
-          scrollRowIntoViewSpy = spyOn(grid, 'scrollRowIntoView');
-        });
-
-        describe('the right arrow', function () {
-          describe('when a cell is selected', function () {
-            beforeEach(function () {
-              var range = new Slick.Range(1, 1);
-              grid.setActiveCell(1, 1);
-              grid.getSelectionModel().setSelectedRanges([range]);
-              pressShiftPlusKey(KEY_RIGHT);
-            });
-
-            it('increases the range by one to the right', function () {
-              expectOneSelectedRange(1, 1, 1, 2);
-            });
-
-            it('should scroll the next column into view', function () {
-              expect(scrollColumnIntoViewSpy).toHaveBeenCalledWith(2);
-              expect(scrollRowIntoViewSpy).not.toHaveBeenCalled();
-            });
-
-            it('pressing right again grows the range right', function () {
-              pressShiftPlusKey(KEY_RIGHT);
-
-              expectOneSelectedRange(1, 1, 1, 3);
-            });
-
-            it('then pressing left keeps the original selection', function () {
-              pressShiftPlusKey(KEY_LEFT);
-
-              expectOneSelectedRange(1, 1, 1, 1);
-            });
-          });
-
-          describe('when a column is selected', function () {
-            beforeEach(function () {
-              var range = new Slick.Range(0, 1, 9, 1);
-              grid.setActiveCell(0, 1);
-              grid.getSelectionModel().setSelectedRanges([range]);
-              pressShiftPlusKey(KEY_RIGHT);
-            });
-
-            it('increases the range by one column to the right', function () {
-              expectOneSelectedRange(0, 1, 9, 2);
-            });
-
-            it('should scroll the next column into view', function () {
-              expect(scrollColumnIntoViewSpy).toHaveBeenCalledWith(2);
-              expect(scrollRowIntoViewSpy).not.toHaveBeenCalled();
-            });
-          });
-        });
-
-        describe('the left arrow', function () {
-          describe('when a cell is selected', function () {
-            beforeEach(function () {
-              var range = new Slick.Range(1, 3);
-              grid.setActiveCell(1, 3);
-              grid.getSelectionModel().setSelectedRanges([range]);
-              pressShiftPlusKey(KEY_LEFT);
-            });
-
-            it('increases the range by one to the left', function () {
-              expectOneSelectedRange(1, 2, 1, 3);
-            });
-
-            it('should scroll previous column into view', function () {
-              expect(scrollColumnIntoViewSpy).toHaveBeenCalledWith(2);
-              expect(scrollRowIntoViewSpy).not.toHaveBeenCalled();
-            });
-
-            it('pressing left again grows the range the left', function () {
-              pressShiftPlusKey(KEY_LEFT);
-
-              expectOneSelectedRange(1, 1, 1, 3);
-            });
-
-            it('then pressing right keeps the original selection', function () {
-              pressShiftPlusKey(KEY_RIGHT);
-
-              expectOneSelectedRange(1, 3, 1, 3);
-            });
-          });
-
-          describe('when a column is selected', function () {
-            beforeEach(function () {
-              var range = new Slick.Range(0, 2, 9, 2);
-              grid.setActiveCell(0, 2);
-              grid.getSelectionModel().setSelectedRanges([range]);
-              pressShiftPlusKey(KEY_LEFT);
-            });
-
-            it('increases the range by one column to the left', function () {
-              expectOneSelectedRange(0, 1, 9, 2);
-            });
-
-            it('should scroll previous column into view', function () {
-              expect(scrollColumnIntoViewSpy).toHaveBeenCalledWith(1);
-              expect(scrollRowIntoViewSpy).not.toHaveBeenCalled();
-            });
-          });
-        });
-
-        describe('the up arrow', function () {
-          describe('when a cell is selected', function () {
-            beforeEach(function () {
-              var range = new Slick.Range(2, 2);
-              grid.setActiveCell(2, 2);
-              grid.getSelectionModel().setSelectedRanges([range]);
-              pressShiftPlusKey(KEY_UP);
-            });
-
-            it('increases the range by one up', function () {
-              expectOneSelectedRange(1, 2, 2, 2);
-            });
-
-            it('should scroll the row above into view', function () {
-              expect(scrollRowIntoViewSpy).toHaveBeenCalledWith(1);
-              expect(scrollColumnIntoViewSpy).not.toHaveBeenCalled();
-            });
-
-            it('pressing up again grows the range up', function () {
-              pressShiftPlusKey(KEY_UP);
-
-              expectOneSelectedRange(0, 2, 2, 2);
-            });
-
-            it('then pressing down keeps the original selection', function () {
-              pressShiftPlusKey(KEY_DOWN);
-
-              expectOneSelectedRange(2, 2, 2, 2);
-            });
-          });
-
-          describe('when a row is selected', function () {
-            beforeEach(function () {
-              var range = new Slick.Range(2, 1, 2, 3);
-              grid.setActiveCell(2, 1);
-              grid.getSelectionModel().setSelectedRanges([range]);
-              pressShiftPlusKey(KEY_UP);
-            });
-
-            it('increases the range by one row up', function () {
-              expectOneSelectedRange(1, 1, 2, 3);
-            });
-
-            it('should scroll the row above into view', function () {
-              expect(scrollRowIntoViewSpy).toHaveBeenCalledWith(1);
-              expect(scrollColumnIntoViewSpy).not.toHaveBeenCalled();
-            });
-          });
-        });
-
-        describe('the down arrow', function () {
-          describe('when a cell is selected', function () {
-            beforeEach(function () {
-              var range = new Slick.Range(2, 2);
-              grid.setActiveCell(2, 2);
-              grid.getSelectionModel().setSelectedRanges([range]);
-              pressShiftPlusKey(KEY_DOWN);
-            });
-
-            it('increases the range by one down', function () {
-              expectOneSelectedRange(2, 2, 3, 2);
-            });
-
-            it('should scroll the row below into view', function () {
-              expect(scrollRowIntoViewSpy).toHaveBeenCalledWith(3);
-              expect(scrollColumnIntoViewSpy).not.toHaveBeenCalled();
-            });
-
-            it('pressing down again grows the range down', function () {
-              pressShiftPlusKey(KEY_DOWN);
-
-              expectOneSelectedRange(2, 2, 4, 2);
-            });
-
-            it('then pressing up keeps the original selection', function () {
-              pressShiftPlusKey(KEY_UP);
-
-              expectOneSelectedRange(2, 2, 2, 2);
-            });
-          });
-
-          describe('when a row is selected', function () {
-            beforeEach(function () {
-              var range = new Slick.Range(2, 1, 2, 3);
-              grid.setActiveCell(2, 1);
-              grid.getSelectionModel().setSelectedRanges([range]);
-              pressShiftPlusKey(KEY_DOWN);
-            });
-
-            it('increases the range by one row down', function () {
-              expectOneSelectedRange(2, 1, 3, 3);
-            });
-
-            it('should scroll the row below into view', function () {
-              expect(scrollRowIntoViewSpy).toHaveBeenCalledWith(3);
-              expect(scrollColumnIntoViewSpy).not.toHaveBeenCalled();
-            });
-          });
-        });
-
-        describe('rectangular selection works', function () {
-
-          it('in the down-and-rightward direction', function () {
-            var range = new Slick.Range(1, 1);
-            grid.setActiveCell(1, 1);
-            grid.getSelectionModel().setSelectedRanges([range]);
-
-            pressShiftPlusKey(KEY_DOWN);
-            pressShiftPlusKey(KEY_DOWN);
-            pressShiftPlusKey(KEY_DOWN);
-            pressShiftPlusKey(KEY_RIGHT);
-            pressShiftPlusKey(KEY_RIGHT);
-
-            expectOneSelectedRange(1, 1, 4, 3);
-          });
-
-          it('in the up-and-leftward direction', function () {
-            var range = new Slick.Range(4, 3);
-            grid.setActiveCell(4, 3);
-            grid.getSelectionModel().setSelectedRanges([range]);
-
-            pressShiftPlusKey(KEY_UP);
-            pressShiftPlusKey(KEY_UP);
-            pressShiftPlusKey(KEY_UP);
-            pressShiftPlusKey(KEY_LEFT);
-            pressShiftPlusKey(KEY_LEFT);
-
-            expectOneSelectedRange(1, 1, 4, 3);
-          });
-
-          it('in the up-and-rightward direction', function () {
-            var range = new Slick.Range(4, 1);
-            grid.setActiveCell(4, 1);
-            grid.getSelectionModel().setSelectedRanges([range]);
-
-            pressShiftPlusKey(KEY_UP);
-            pressShiftPlusKey(KEY_UP);
-            pressShiftPlusKey(KEY_UP);
-            pressShiftPlusKey(KEY_RIGHT);
-            pressShiftPlusKey(KEY_RIGHT);
-
-            expectOneSelectedRange(1, 1, 4, 3);
-          });
-
-          it('in the down-and-leftward direction', function () {
-            var range = new Slick.Range(1, 3);
-            grid.setActiveCell(1, 3);
-            grid.getSelectionModel().setSelectedRanges([range]);
-
-            pressShiftPlusKey(KEY_DOWN);
-            pressShiftPlusKey(KEY_DOWN);
-            pressShiftPlusKey(KEY_DOWN);
-            pressShiftPlusKey(KEY_LEFT);
-            pressShiftPlusKey(KEY_LEFT);
-
-            expectOneSelectedRange(1, 1, 4, 3);
-          });
-        });
-
-        describe('and we are on an edge', function () {
-          var range;
-
-          beforeEach(function () {
-            range = new Slick.Range(2, 1);
-            grid.setActiveCell(2, 1);
-            grid.getSelectionModel().setSelectedRanges([range]);
-          });
-
-          it('we still have the selected range before we arrowed', function () {
-            pressShiftPlusKey(KEY_LEFT);
-            expectOneSelectedRange(2, 1, 2, 1);
-          });
-        });
-      });
-    });
-  });
-
-  describe('when we drag and drop', function () {
-    var dd;
-    // We could not find an elegant way to calculate this value
-    // after changing window size we saw this was a constant value
-    var offsetLeftColumns = 100;
-
-    function cellTopPosition($cell, rowNumber) {
-      return $(grid.getCanvasNode()).offset().top + $cell[0].scrollHeight * rowNumber;
-    }
-
-    function cellLeftPosition(columnNumber) {
-      return $(grid.getCanvasNode()).offset().left + offsetLeftColumns * columnNumber;
-    }
-
-    beforeEach(function () {
-      var initialPosition = {cell: 3, row: 4};
-      var $cell = $($('.slick-cell.l3')[initialPosition.row]);
-      var event = {
-        target: $cell,
-        isPropagationStopped: jasmine.createSpy('isPropagationStopped').and.returnValue(false),
-        isImmediatePropagationStopped: jasmine.createSpy('isImmediatePropagationStopped').and.returnValue(false),
-        stopImmediatePropagation: jasmine.createSpy('stopImmediatePropagation'),
-      };
-
-      dd = {
-        grid: grid,
-        startX: cellLeftPosition(initialPosition.cell),
-        startY: cellTopPosition($cell, initialPosition.row),
-      };
-
-      grid.onDragStart.notify(dd, event, grid);
-    });
-
-    describe('when the drop happens outside of the grid', function () {
-      beforeEach(function () {
-        var $cell = $($('.slick-cell.l1')[1]);
-        var finalPosition = {cell: 1, row: 1};
-
-        var event = {
-          target: $cell,
-          isPropagationStopped: jasmine.createSpy('isPropagationStopped').and.returnValue(false),
-          isImmediatePropagationStopped: jasmine.createSpy('isImmediatePropagationStopped').and.returnValue(false),
-          stopImmediatePropagation: jasmine.createSpy('stopImmediatePropagation'),
-
-          pageX: cellLeftPosition(finalPosition.cell),
-          pageY: cellTopPosition($cell, finalPosition.row),
-        };
-
-        grid.onDrag.notify(dd, event, grid);
-        $(window).mouseup();
-      });
-      it('should call handleDragEnd from CellRangeSelector', function () {
-        var newRange = grid.getSelectionModel().getSelectedRanges();
-
-        expect(newRange.length).toEqual(1);
-
-        expect(newRange[0].fromCell).toEqual(1);
-        expect(newRange[0].toCell).toEqual(3);
-        expect(newRange[0].fromRow).toEqual(1);
-        expect(newRange[0].toRow).toEqual(4);
-      });
-    });
-  });
-
-  describe('when we mouse up and no drag and drop occured', function () {
-    beforeEach(function () {
-      grid.onDragEnd.notify = jasmine.createSpy('notify');
-      grid.onDragEnd.notify.calls.reset();
-      $(window).mouseup();
-    });
-
-    it('do not notify onDragEnd', function () {
-      expect(grid.onDragEnd.notify).not.toHaveBeenCalled();
-    });
-  });
-
-  describe('setSelectedRows', function () {
-
-    beforeEach(function () {
-      grid.getSelectionModel().setSelectedRanges(
-        [new Slick.Range(1, 1, 1, 1)]
-      );
-    });
-
-    describe('when passed an empty array', function () {
-      beforeEach(function () {
-        grid.getSelectionModel().setSelectedRows([]);
-      });
-      it('clears ranges', function () {
-        var newRanges = grid.getSelectionModel().getSelectedRanges();
-        expect(newRanges.length).toEqual(0);
-      });
-    });
-
-    it('sets ranges corresponding to rows', function () {
-      grid.getSelectionModel().setSelectedRows([0, 2]);
-
-      var selectedRanges = grid.getSelectionModel().getSelectedRanges();
-
-      expect(selectedRanges.length).toEqual(2);
-      expectRangeToMatch(selectedRanges[0], 0, 1, 0, 3);
-      expectRangeToMatch(selectedRanges[1], 2, 1, 2, 3);
-    });
-  });
-
-  function pressKey(keyCode) {
-    var pressEvent = new $.Event('keydown');
-    pressEvent.which = keyCode;
-
-    $(container.find('.grid-canvas')).trigger(pressEvent);
-  }
-
-  function pressShiftPlusKey(keyCode) {
-    var pressEvent = new $.Event('keydown');
-    pressEvent.shiftKey = true;
-    pressEvent.which = keyCode;
-
-    $(container.find('.grid-canvas')).trigger(pressEvent);
-  }
-
-  function expectOneSelectedRange(fromRow, fromCell, toRow, toCell) {
-    var selectedRanges = grid.getSelectionModel().getSelectedRanges();
-    expect(selectedRanges.length).toEqual(1);
-    expectRangeToMatch(selectedRanges[0], fromRow, fromCell, toRow, toCell);
-  }
-
-  function expectRangeToMatch(range, fromRow, fromCell, toRow, toCell) {
-    expect(range.fromRow).toEqual(fromRow);
-    expect(range.toRow).toEqual(toRow);
-    expect(range.fromCell).toEqual(fromCell);
-    expect(range.toCell).toEqual(toCell);
-  }
-});
diff --git a/web/regression/javascript/slickgrid/cell_selector_spec.js b/web/regression/javascript/slickgrid/cell_selector_spec.js
deleted file mode 100644
index bd407c3c..00000000
--- a/web/regression/javascript/slickgrid/cell_selector_spec.js
+++ /dev/null
@@ -1,80 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import $ from 'jquery';
-import 'slickgrid';
-import 'slickgrid.grid';
-
-import XCellSelectionModel from 'sources/selection/xcell_selection_model';
-import CellSelector from 'sources/slickgrid/cell_selector';
-import RangeSelectionHelper from 'sources/selection/range_selection_helper';
-
-describe('CellSelector', function () {
-  var container, columns, cellSelector, data, cellSelectionModel, grid;
-
-  var Slick = window.Slick;
-
-  beforeEach(function () {
-    container = $('<div></div>');
-    container.height(9999);
-    container.width(9999);
-    columns = [{
-      name: 'some-column-name',
-    }, {
-      name: 'second column',
-    }];
-
-    cellSelector = new CellSelector();
-
-    data = [];
-    for (var i = 0; i < 10; i++) {
-      data.push({'some-column-name': 'some-value-' + i, 'second column': 'second value ' + i});
-    }
-    grid = new Slick.Grid(container, data, columns);
-
-    cellSelectionModel = new XCellSelectionModel();
-    grid.setSelectionModel(cellSelectionModel);
-
-    grid.registerPlugin(cellSelector);
-    grid.invalidate();
-
-    $('body').append(container);
-  });
-
-  afterEach(function () {
-    $('body').find(container).remove();
-  });
-
-  describe('when the user clicks or tabs to a cell', function () {
-    it('sets the selected range to that cell', function () {
-      var row = 1, column = 0;
-      $(container.find('.slick-row .slick-cell.l' + column)[row]).trigger('click');
-
-      var selectedRanges = cellSelectionModel.getSelectedRanges();
-      expect(selectedRanges.length).toEqual(1);
-      expect(selectedRanges[0].fromCell).toEqual(0);
-      expect(selectedRanges[0].toCell).toEqual(0);
-      expect(selectedRanges[0].fromRow).toEqual(1);
-      expect(selectedRanges[0].toRow).toEqual(1);
-    });
-
-    it('deselects previously selected ranges', function () {
-      var row2Range = RangeSelectionHelper.rangeForRow(grid, 2);
-      var ranges = RangeSelectionHelper.addRange(cellSelectionModel.getSelectedRanges(),
-        row2Range);
-      cellSelectionModel.setSelectedRanges(ranges);
-
-      var row = 4, column = 1;
-      $(container.find('.slick-row .slick-cell.l' + column)[row]).trigger('click');
-
-      expect(RangeSelectionHelper.isRangeSelected(cellSelectionModel.getSelectedRanges(), row2Range))
-        .toEqual(false);
-    });
-  });
-});
diff --git a/web/regression/javascript/slickgrid/event_handlers/handle_query_output_keyboard_event_spec.js b/web/regression/javascript/slickgrid/event_handlers/handle_query_output_keyboard_event_spec.js
deleted file mode 100644
index a24955d1..00000000
--- a/web/regression/javascript/slickgrid/event_handlers/handle_query_output_keyboard_event_spec.js
+++ /dev/null
@@ -1,125 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import HandleQueryOutputKeyboardEvent from 'sources/slickgrid/event_handlers/handle_query_output_keyboard_event';
-import clipboard from 'sources/selection/clipboard';
-import RangeSelectionHelper from 'sources/selection/range_selection_helper';
-import XCellSelectionModel from 'sources/selection/xcell_selection_model';
-import Slick from 'slickgrid';
-import 'slickgrid.grid';
-
-import $ from 'jquery';
-
-describe('#handleQueryOutputKeyboardEvent', function () {
-  var event, grid, slickEvent;
-  var handleQueryOutputKeyboardEvent, buttonCopyWithHeader;
-
-  beforeEach(function () {
-    event = {
-      shiftKey: false,
-      ctrlKey: false,
-      metaKey: false,
-      which: -1,
-      keyCode: -1,
-      preventDefault: jasmine.createSpy('preventDefault'),
-    };
-
-    var data = [{'checkboxColumn': '', 'firstColumn': '0,0-cell-content', 'secondColumn': '0,1-cell-content', '__temp_PK': '123'},
-        {'checkboxColumn': '', 'firstColumn': '1,0-cell-content', 'secondColumn': '1,1-cell-content', '__temp_PK': '456'},
-        {'checkboxColumn': '', 'firstColumn': '2,0-cell-content', 'secondColumn': '2,1-cell-content', '__temp_PK': '789'}],
-      columnDefinitions = [{name: 'checkboxColumn'},
-        {pos: 1, name: 'firstColumn', field: 'firstColumn'},
-        { pos: 2, name: 'secondColumn', field: 'secondColumn'}],
-      dataView = new Slick.Data.DataView(),
-      CSVOptions = {'quoting': 'all', 'quote_char': '\'', 'field_separator': ','};
-
-    grid = new Slick.Grid($('<div></div>'), dataView, columnDefinitions);
-    grid.setSelectionModel(new XCellSelectionModel());
-    grid.CSVOptions = CSVOptions;
-    dataView.setItems(data, '__temp_PK');
-    slickEvent = {
-      grid: grid,
-    };
-
-    buttonCopyWithHeader = $('<button class="copy-with-header visibility-hidden"></button>');
-    $('body').append(buttonCopyWithHeader);
-
-    spyOn(clipboard, 'copyTextToClipboard');
-    handleQueryOutputKeyboardEvent = HandleQueryOutputKeyboardEvent.bind(window);
-  });
-
-  let selectEntireGridAction = ()=> {
-    handleQueryOutputKeyboardEvent(event, slickEvent);
-
-    expect(RangeSelectionHelper.isEntireGridSelected(grid)).toBeTruthy();
-    expect(grid.getSelectionModel().getSelectedRanges().length).toEqual(1);
-  };
-
-  let commandAAction = ()=> {
-    beforeEach(function () {
-      event.metaKey = true;
-      event.keyCode = 65;
-    });
-
-    it('selects the entire grid to ranges', function () {
-      selectEntireGridAction();
-    });
-  };
-
-  let ctrlAAction = ()=> {
-    beforeEach(function () {
-      event.ctrlKey = true;
-      event.keyCode = 65;
-    });
-
-    it('selects the entire grid to ranges', function () {
-      selectEntireGridAction();
-    });
-  };
-
-  describe('when a range is selected', function () {
-    beforeEach(function () {
-      grid.getSelectionModel().setSelectedRanges([
-        RangeSelectionHelper.rangeForRow(grid, 0),
-        RangeSelectionHelper.rangeForRow(grid, 2),
-      ]);
-    });
-
-    let copyCellContentAction = ()=> {
-      handleQueryOutputKeyboardEvent(event, slickEvent);
-      expect(clipboard.copyTextToClipboard).toHaveBeenCalledWith('\'0,0-cell-content\',\'0,1-cell-content\'\n\'2,0-cell-content\',\'2,1-cell-content\'');
-    };
-
-    describe('pressing Command + C', function () {
-      beforeEach(function () {
-        event.metaKey = true;
-        event.keyCode = 67;
-      });
-
-      it('copies the cell content to the clipboard', copyCellContentAction);
-    });
-
-    describe('pressing Ctrl + C', function () {
-      beforeEach(function () {
-        event.ctrlKey = true;
-        event.keyCode = 67;
-      });
-
-      it('copies the cell content to the clipboard', copyCellContentAction);
-    });
-
-    describe('pressing Command + A', commandAAction);
-    describe('pressing Ctrl + A', ctrlAAction);
-  });
-
-  describe('when no ranges are selected', function () {
-    describe('pressing Command + A', commandAAction);
-    describe('pressing Ctrl + A', ctrlAAction);
-  });
-});
diff --git a/web/webpack.config.js b/web/webpack.config.js
index 266a7b2c..ac4fe32f 100644
--- a/web/webpack.config.js
+++ b/web/webpack.config.js
@@ -56,7 +56,7 @@ const providePlugin = new webpack.ProvidePlugin({
 // Reference: https://webpack.js.org/plugins/source-map-dev-tool-plugin/#components/sidebar/sidebar.jsx
 const sourceMapDevToolPlugin = new webpack.SourceMapDevToolPlugin({
   filename: '[name].js.map',
-  exclude: /(vendor|codemirror|slickgrid|pgadmin\.js|pgadmin.theme|pgadmin.static|style\.js|popper)/,
+  exclude: /(vendor|codemirror|pgadmin\.js|pgadmin.theme|pgadmin.static|style\.js|popper)/,
   columns: false,
 });
 
@@ -376,9 +376,8 @@ module.exports = [{
   entry: {
     'app.bundle': sourceDir + '/bundle/app.js',
     codemirror: sourceDir + '/bundle/codemirror.js',
-    slickgrid: sourceDir + '/bundle/slickgrid.js',
     sqleditor: './pgadmin/tools/sqleditor/static/js/index.js',
-    schema_diff: './pgadmin/tools/schema_diff/static/js/schema_diff_hook.js',
+    schema_diff: './pgadmin/tools/schema_diff/static/js/index.js',
     erd_tool: './pgadmin/tools/erd/static/js/index.js',
     psql_tool: './pgadmin/tools/psql/static/js/index.js',
     debugger: './pgadmin/tools/debugger/static/js/index.js',
diff --git a/web/webpack.shim.js b/web/webpack.shim.js
index a9d334d4..750751d3 100644
--- a/web/webpack.shim.js
+++ b/web/webpack.shim.js
@@ -72,16 +72,6 @@ var webpackShimConfig = {
       'deps': ['jquery'], 'exports': 'jQuery.fn.drag',
     },
     'jquery.ui': {'deps': ['jquery']},
-    'slick.pgadmin.formatters': {
-      'deps': ['slickgrid'],
-    },
-    'slick.pgadmin.editors': {
-      'deps': ['slickgrid'],
-    },
-    'slickgrid': {
-      'deps': ['jquery', 'jquery.ui', 'jquery.event.drag'],
-      'exports': 'Slick',
-    },
     'alertify': {
       'exports': 'alertify',
     },
@@ -132,8 +122,6 @@ var webpackShimConfig = {
     'wcdocker': path.join(__dirname, './node_modules/webcabin-docker/Build/wcDocker.min'),
     'alertify': path.join(__dirname, './node_modules/alertifyjs/build/alertify'),
     'moment': path.join(__dirname, './node_modules/moment/moment'),
-    'jquery.event.drag': path.join(__dirname, './node_modules/slickgrid/lib/jquery.event.drag-2.3.0'),
-    'jquery.ui': path.join(__dirname, './node_modules/slickgrid/lib/jquery-ui-1.11.3.min'),
     'jqueryui.position': path.join(__dirname, './node_modules/jquery-contextmenu/dist/jquery.ui.position'),
     'jquery.contextmenu': path.join(__dirname, './node_modules/jquery-contextmenu/dist/jquery.contextMenu'),
     'dropzone': path.join(__dirname, './node_modules/dropzone/dist/dropzone'),
@@ -278,8 +266,7 @@ var webpackShimConfig = {
     'pgadmin.tools.import_export_servers': path.join(__dirname, './pgadmin/tools/import_export_servers/static/js/'),
     'pgadmin.tools.maintenance': path.join(__dirname, './pgadmin/tools/maintenance/static/js/maintenance'),
     'pgadmin.tools.restore': path.join(__dirname, './pgadmin/tools/restore/static/js/restore'),
-    'pgadmin.tools.schema_diff': path.join(__dirname, './pgadmin/tools/schema_diff/static/js/schema_diff'),
-    'pgadmin.tools.schema_diff_ui': path.join(__dirname, './pgadmin/tools/schema_diff/static/js/schema_diff_ui'),
+    'pgadmin.tools.schema_diff': path.join(__dirname, './pgadmin/tools/schema_diff/static/js/'),
     'pgadmin.tools.search_objects': path.join(__dirname, './pgadmin/tools/search_objects/static/js'),
     'pgadmin.tools.erd': path.join(__dirname, './pgadmin/tools/erd/static/js'),
     'pgadmin.tools.psql_module': path.join(__dirname, './pgadmin/tools/psql/static/js/psql_module'),
@@ -287,9 +274,6 @@ var webpackShimConfig = {
     'pgadmin.tools.sqleditor': path.join(__dirname, './pgadmin/tools/sqleditor/static/js'),
     'pgadmin.tools.user_management': path.join(__dirname, './pgadmin/tools/user_management/static/js/user_management'),
     'pgadmin.user_management.current_user': '/user_management/current_user',
-    'slick.pgadmin.editors': path.join(__dirname, './pgadmin/tools/../static/js/slickgrid/editors'),
-    'slick.pgadmin.formatters': path.join(__dirname, './pgadmin/tools/../static/js/slickgrid/formatters'),
-    'slick.pgadmin.plugins': path.join(__dirname, './pgadmin/tools/../static/js/slickgrid/plugins'),
   },
   externals: [
     'pgadmin.user_management.current_user',
@@ -306,8 +290,7 @@ var webpackShimConfig = {
     'pgadmin.browser.error', 'pgadmin.browser.server.privilege',
     'pgadmin.browser.server.variable', 'pgadmin.browser.collection', 'pgadmin.browser.node.ui',
     'pgadmin.browser.datamodel', 'pgadmin.browser.menu', 'pgadmin.browser.panel', 'pgadmin',
-    'pgadmin.browser.frame', 'slick.pgadmin.editors', 'slick.pgadmin.formatters',
-    'pgadmin.backform', 'pgadmin.backgrid', 'pgadmin.browser',
+    'pgadmin.browser.frame', 'pgadmin.backform', 'pgadmin.backgrid', 'pgadmin.browser',
     'pgadmin.browser.node',
     'pgadmin.alertifyjs', 'pgadmin.settings', 'pgadmin.preferences', 'pgadmin.sqlfoldcode',
   ],
diff --git a/web/webpack.test.config.js b/web/webpack.test.config.js
index 9a2add64..73f5abe7 100644
--- a/web/webpack.test.config.js
+++ b/web/webpack.test.config.js
@@ -13,7 +13,6 @@ const webpack = require('webpack');
 const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
 
 const sourcesDir = path.resolve(__dirname, 'pgadmin/static');
-const nodeModulesDir = path.resolve(__dirname, 'node_modules');
 const regressionDir = path.resolve(__dirname, 'regression');
 
 module.exports = {
@@ -99,62 +98,6 @@ module.exports = {
         filename: 'img/[name].[ext]',
       },
       exclude: /vendor/,
-    }, {
-      test: /.*slickgrid[\\\/]+slick\.(?!core)*/,
-      use:[
-        {
-          loader: 'imports-loader',
-          options: {
-            type: 'commonjs',
-            imports: [
-              'pure|jquery.ui',
-              'pure|jquery.event.drag',
-              'pure|slickgrid',
-            ],
-          },
-        },
-      ],
-    }, {
-      test: /.*slickgrid\.plugins[\\\/]+slick\.cellrangeselector/,
-      use:[
-        {
-          loader: 'imports-loader',
-          options: {
-            type: 'commonjs',
-            imports: [
-              'pure|jquery.ui',
-              'pure|jquery.event.drag',
-              'pure|slickgrid',
-            ],
-          },
-        }, {
-          loader: 'exports-loader',
-          options: {
-            type: 'commonjs',
-            exports: 'single|Slick.CellRangeSelector',
-          },
-        },
-      ],
-    }, {
-      test: /.*slickgrid[\\\/]+slick\.core.*/,
-      use:[
-        {
-          loader: 'imports-loader',
-          options: {
-            type: 'commonjs',
-            imports: [
-              'pure|jquery.ui',
-              'pure|jquery.event.drag',
-            ],
-          },
-        }, {
-          loader: 'exports-loader',
-          options: {
-            type: 'commonjs',
-            exports: 'single|Slick',
-          },
-        },
-      ],
     },
     {
       test: /\.js$|\.jsx$/,
@@ -163,7 +106,7 @@ module.exports = {
         options: { esModules: true },
       },
       enforce: 'post',
-      exclude: /node_modules|slickgrid|plugins|bundle|generated|regression|[Tt]est.js|[Ss]pecs.js|[Ss]pec.js|\.spec\.js$/,
+      exclude: /node_modules|plugins|bundle|generated|regression|[Tt]est.js|[Ss]pecs.js|[Ss]pec.js|\.spec\.js$/,
     },
     ],
   },
@@ -175,8 +118,6 @@ module.exports = {
       'jquery': path.join(__dirname, './node_modules/jquery/dist/jquery'),
       'wcdocker': path.join(__dirname, './node_modules/webcabin-docker/Build/wcDocker'),
       'alertify': path.join(__dirname, './node_modules/alertifyjs/build/alertify'),
-      'jquery.event.drag': path.join(__dirname, './node_modules/slickgrid/lib/jquery.event.drag-2.3.0'),
-      'jquery.ui': path.join(__dirname, './node_modules/slickgrid/lib/jquery-ui-1.11.3'),
       'color-picker': path.join(__dirname, './node_modules/@simonwep/pickr/dist/pickr.min'),
       'bignumber': path.join(__dirname, './node_modules/bignumber.js/bignumber'),
       'bootstrap.datetimepicker': path.join(__dirname, './node_modules/tempusdominus-bootstrap-4/build/js/tempusdominus-bootstrap-4.min'),
@@ -192,9 +133,6 @@ module.exports = {
       'pgadmin.browser.messages': regressionDir + '/javascript/fake_messages',
       'pgadmin.server.supported_servers': regressionDir + '/javascript/fake_supported_servers',
       'pgadmin.browser.endpoints': regressionDir + '/javascript/fake_endpoints',
-      'slickgrid': nodeModulesDir + '/slickgrid/',
-      'slickgrid.plugins': nodeModulesDir + '/slickgrid/plugins/',
-      'slickgrid.grid': nodeModulesDir + '/slickgrid/slick.grid',
       'moment': path.join(__dirname, './node_modules/moment/moment'),
       'jsoneditor.min': path.join(__dirname, './node_modules/jsoneditor/dist/jsoneditor.min'),
       'browser': path.resolve(__dirname, 'pgadmin/browser/static/js'),
