diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/edbfuncs/static/js/edbfunc.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/edbfuncs/static/js/edbfunc.js
index 7d805c5d6..214d6a620 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/edbfuncs/static/js/edbfunc.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/edbfuncs/static/js/edbfunc.js
@@ -7,12 +7,14 @@
 //
 //////////////////////////////////////////////////////////////
 
+import EDBFuncSchema from './edbfunc.ui';
+
 /* Create and Register Function Collection and Node. */
 define('pgadmin.node.edbfunc', [
   'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
   'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform',
   'pgadmin.browser.collection', 'pgadmin.browser.server.privilege',
-], function(gettext, url_for, $, _, pgAdmin, pgBrowser, Backform) {
+], function(gettext, url_for, $, _, pgAdmin, pgBrowser) {
 
   if (!pgBrowser.Nodes['coll-edbfunc']) {
     pgBrowser.Nodes['coll-edbfunc'] =
@@ -49,19 +51,6 @@ define('pgadmin.node.edbfunc', [
       canDropCascade: false,
       model: pgBrowser.Node.Model.extend({
         idAttribute: 'oid',
-        defaults: {
-          name: undefined,
-          oid: undefined,
-          funcowner: undefined,
-          pronargs: undefined, /* Argument Count */
-          proargs: undefined, /* Arguments */
-          proargtypenames: undefined, /* Argument Signature */
-          prorettypename: undefined, /* Return Type */
-          lanname: 'sql', /* Language Name in which function is being written */
-          prosrc: undefined,
-          proacl: undefined,
-          visibility: 'Unknown',
-        },
         schema: [{
           id: 'name', label: gettext('Name'), cell: 'string',
           type: 'text', mode: ['properties'],
@@ -71,44 +60,15 @@ define('pgadmin.node.edbfunc', [
         },{
           id: 'funcowner', label: gettext('Owner'), cell: 'string',
           type: 'text', readonly: true,
-        },{
-          id: 'pronargs', label: gettext('Argument count'), cell: 'string',
-          type: 'text', group: gettext('Definition'), mode: ['properties'],
-        },{
-          id: 'proargs', label: gettext('Arguments'), cell: 'string',
-          type: 'text', group: gettext('Definition'), mode: ['properties'],
-        },{
-          id: 'proargtypenames', label: gettext('Signature arguments'), cell:
-          'string', type: 'text', group: gettext('Definition'), mode: ['properties'],
-        },{
-          id: 'prorettypename', label: gettext('Return type'), cell: 'string',
-          type: 'text', group: gettext('Definition'),
-          mode: ['properties'], visible: 'isVisible',
-        },{
-          id: 'visibility', label: gettext('Visibility'), cell: 'string',
-          type: 'text', mode: ['properties'],
-        },{
-          id: 'lanname', label: gettext('Language'), cell: 'string',
-          type: 'text', group: gettext('Definition'), readonly: true,
-        },{
-          id: 'prosrc', label: gettext('Code'), cell: 'string',
-          type: 'text', mode: ['properties'],
-          group: gettext('Code'),
-          tabPanelCodeClass: 'sql-code-control',
-          control: Backform.SqlCodeControl,
-          visible: function(m) {
-            if (m.get('lanname') == 'c') {
-              return false;
-            }
-            return true;
-          }, disabled: true,
-        }],
-        validate: function() { return null; },
-        isVisible: function() {
-          if (this.name == 'sysproc') { return false; }
-          return true;
-        },
+        }]
       }),
+      getSchema: () => {
+        return new EDBFuncSchema(
+          {}, {
+            name: 'sysfunc'
+          }
+        );
+      }
     });
 
   }
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/edbfuncs/static/js/edbfunc.ui.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/edbfuncs/static/js/edbfunc.ui.js
new file mode 100644
index 000000000..ecc602592
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/edbfuncs/static/js/edbfunc.ui.js
@@ -0,0 +1,88 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2021, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+
+import gettext from 'sources/gettext';
+import BaseUISchema from 'sources/SchemaView/base_schema.ui';
+
+export default class EDBFuncSchema extends BaseUISchema {
+  constructor(fieldOptions = {}, initValues) {
+    super({
+      name: undefined,
+      oid: undefined,
+      funcowner: undefined,
+      pronargs: undefined, /* Argument Count */
+      proargs: undefined, /* Arguments */
+      proargtypenames: undefined, /* Argument Signature */
+      prorettypename: undefined, /* Return Type */
+      lanname: 'sql', /* Language Name in which function is being written */
+      prosrc: undefined,
+      proacl: undefined,
+      visibility: 'Unknown',
+      warn_text: undefined,
+      ...initValues
+    });
+    this.fieldOptions = {
+      ...fieldOptions
+    };
+  }
+
+  isVisible(state) {
+    if (state.name == 'sysfunc') { return true; }
+    else if (state.name == 'sysproc') { return true; }
+    return false;
+  }
+
+  get idAttribute() {
+    return 'oid';
+  }
+
+  get baseFields() {
+    return [{
+      id: 'name', label: gettext('Name'), cell: 'string',
+      type: 'text', mode: ['properties'],
+    },{
+      id: 'oid', label: gettext('OID'), cell: 'string',
+      type: 'text' , mode: ['properties'],
+    },{
+      id: 'funcowner', label: gettext('Owner'), cell: 'string',
+      type: 'text', readonly: true,
+    },{
+      id: 'pronargs', label: gettext('Argument count'), cell: 'string',
+      type: 'text', group: gettext('Definition'), mode: ['properties'],
+    },{
+      id: 'proargs', label: gettext('Arguments'), cell: 'string',
+      type: 'text', group: gettext('Definition'), mode: ['properties'],
+    },{
+      id: 'proargtypenames', label: gettext('Signature arguments'), cell:
+      'string', type: 'text', group: gettext('Definition'), mode: ['properties'],
+    },{
+      id: 'prorettypename', label: gettext('Return type'), cell: 'string',
+      type: 'text', group: gettext('Definition'),
+      mode: ['properties'], visible: (state) => this.isVisible(state),
+    },{
+      id: 'visibility', label: gettext('Visibility'), cell: 'string',
+      type: 'text', mode: ['properties'],
+    },{
+      id: 'lanname', label: gettext('Language'), cell: 'string',
+      type: 'text', group: gettext('Definition'), readonly: true,
+    },{
+      id: 'prosrc', label: gettext('Code'), cell: 'string',
+      mode: ['properties'],
+      group: gettext('Code'),
+      type: 'sql', isFullTab: true,
+      visible: function(state) {
+        if (state.lanname == 'c') {
+          return false;
+        }
+        return true;
+      },
+      disabled: true,
+    }];
+  }
+}
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/edbfuncs/static/js/edbproc.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/edbfuncs/static/js/edbproc.js
index 3a4597c14..7f1628013 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/edbfuncs/static/js/edbproc.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/edbfuncs/static/js/edbproc.js
@@ -7,6 +7,8 @@
 //
 //////////////////////////////////////////////////////////////
 
+import EDBFuncSchema from './edbfunc.ui';
+
 /* Create and Register Procedure Collection and Node. */
 define('pgadmin.node.edbproc', [
   'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
@@ -70,6 +72,13 @@ define('pgadmin.node.edbproc', [
         },
       }
       ),
+      getSchema: () => {
+        return new EDBFuncSchema(
+          {}, {
+            name: 'sysproc'
+          }
+        );
+      }
     });
 
   }
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/edbvars/static/js/edbvar.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/edbvars/static/js/edbvar.js
index 8e61cf309..79e9d3ae8 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/edbvars/static/js/edbvar.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/edbvars/static/js/edbvar.js
@@ -7,6 +7,8 @@
 //
 //////////////////////////////////////////////////////////////
 
+import EDBVarSchema from './edbvar.ui';
+
 /* Create and Register Function Collection and Node. */
 define('pgadmin.node.edbvar', [
   'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
@@ -48,30 +50,17 @@ define('pgadmin.node.edbvar', [
       canDropCascade: false,
       model: pgBrowser.Node.Model.extend({
         idAttribute: 'oid',
-        defaults: {
-          name: undefined,
-          oid: undefined,
-          datatype: undefined,
-          visibility: 'Unknown',
-        },
         schema: [{
           id: 'name', label: gettext('Name'), cell: 'string',
           type: 'text', mode: ['properties'],
         },{
           id: 'oid', label: gettext('OID'), cell: 'string',
           type: 'text' , mode: ['properties'],
-        },{
-          id: 'datatype', label: gettext('Data type'), cell: 'string',
-          type: 'text', readonly: true,
-        },{
-          id: 'visibility', label: gettext('Visibility'), cell: 'string',
-          type: 'text', mode: ['properties'],
-        }],
-        validate: function()
-        {
-          return null;
-        },
+        }]
       }),
+      getSchema: () => {
+        return new EDBVarSchema();
+      }
     });
 
   }
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/edbvars/static/js/edbvar.ui.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/edbvars/static/js/edbvar.ui.js
new file mode 100644
index 000000000..37813f47e
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/edbvars/static/js/edbvar.ui.js
@@ -0,0 +1,46 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2021, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+
+import gettext from 'sources/gettext';
+import BaseUISchema from 'sources/SchemaView/base_schema.ui';
+
+export default class EDBVarSchema extends BaseUISchema {
+  constructor(fieldOptions = {}, initValues) {
+    super({
+      name: undefined,
+      oid: undefined,
+      datatype: undefined,
+      visibility: 'Unknown',
+      ...initValues
+    });
+    this.fieldOptions = {
+      ...fieldOptions
+    };
+  }
+
+  get idAttribute() {
+    return 'oid';
+  }
+
+  get baseFields() {
+    return [{
+      id: 'name', label: gettext('Name'), cell: 'string',
+      type: 'text', mode: ['properties'],
+    },{
+      id: 'oid', label: gettext('OID'), cell: 'string',
+      type: 'text' , mode: ['properties'],
+    },{
+      id: 'datatype', label: gettext('Data type'), cell: 'string',
+      type: 'text', readonly: true,
+    },{
+      id: 'visibility', label: gettext('Visibility'), cell: 'string',
+      type: 'text', mode: ['properties'],
+    }];
+  }
+}
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/static/js/package.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/static/js/package.js
index 52bcd8386..94c34b29a 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/static/js/package.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/static/js/package.js
@@ -7,6 +7,10 @@
 //
 //////////////////////////////////////////////////////////////
 
+import PackageSchema from './package.ui';
+import { getNodePrivilegeRoleSchema } from '../../../../../static/js/privilege.ui';
+import { getNodeListByName } from '../../../../../../../static/js/node_ajax';
+
 define('pgadmin.node.package', [
   'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
   'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform',
@@ -90,18 +94,6 @@ define('pgadmin.node.package', [
       // Define the model for package node.
       model: pgBrowser.Node.Model.extend({
         idAttribute: 'oid',
-        defaults: {
-          name: undefined,
-          oid: undefined,
-          owner: undefined,
-          is_sys_object: undefined,
-          description: undefined,
-          pkgheadsrc: undefined,
-          pkgbodysrc: undefined,
-          acl: undefined,
-          pkgacl: [],
-          warn_text: undefined,
-        },
         initialize: function(attrs, args) {
           if (_.size(attrs) === 0) {
             var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
@@ -129,104 +121,25 @@ define('pgadmin.node.package', [
           readonly: true, editable: false, visible: function(m) {
             return !m.isNew();
           },
-        },{
-          id: 'schema', label: gettext('Schema'), type: 'text', node: 'schema',
-          control: 'node-list-by-name',
-          readonly: function(m) { return !m.isNew(); }, filter: function(d) {
-            // If schema name start with pg_* then we need to exclude them
-            if(d && d.label.match(/^pg_/))
-            {
-              return false;
-            }
-            return true;
-          }, cache_node: 'database', cache_level: 'database',
-        },{
-          id: 'is_sys_object', label: gettext('System package?'),
-          cell:'boolean', type: 'switch',mode: ['properties'],
         },{
           id: 'description', label: gettext('Comment'), type: 'multiline',
           mode: ['properties', 'create', 'edit'],
-        },{
-          id: 'pkgheadsrc', label: gettext('Header'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'], group: gettext('Header'),
-          tabPanelCodeClass: 'sql-code-control',
-          control: Backform.SqlCodeControl.extend({
-            onChange: function() {
-              Backform.SqlCodeControl.prototype.onChange.apply(this, arguments);
-              if(this.model && this.model.changed) {
-                if(this.model.origSessAttrs && (this.model.changed.pkgheadsrc != this.model.origSessAttrs.pkgheadsrc)) {
-                  this.model.warn_text = gettext(
-                    'Updating the package header definition may remove its existing body.'
-                  ) + '<br><br><b>' + gettext('Do you want to continue?') +
-                    '</b>';
-                }
-                else {
-                  this.model.warn_text = undefined;
-                }
-              }
-              else {
-                this.model.warn_text = undefined;
-              }
-            },
-          }),
-        },{
-          id: 'pkgbodysrc', label: gettext('Body'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'], group: gettext('Body'),
-          tabPanelCodeClass: 'sql-code-control',
-          control:  Backform.SqlCodeControl.extend({
-            onChange: function() {
-              Backform.SqlCodeControl.prototype.onChange.apply(this, arguments);
-              if(this.model && this.model.changed) {
-                if (this.model.origSessAttrs && (this.model.changed.pkgbodysrc != this.model.origSessAttrs.pkgbodysrc)) {
-                  this.model.warn_text = undefined;
-                } else if(this.model.origSessAttrs && !_.isUndefined(this.model.origSessAttrs.pkgheadsrc) &&
-                  this.model.sessAttrs && !_.isUndefined(this.model.sessAttrs.pkgheadsrc) &&
-                  (this.model.origSessAttrs.pkgheadsrc != this.model.sessAttrs.pkgheadsrc)){
-                  this.model.warn_text = gettext(
-                    'Updating the package header definition may remove its existing body.'
-                  ) + '<br><br><b>' + gettext('Do you want to continue?') +
-                    '</b>';
-                }
-              }
-            },
-          }),
-        },{
-          id: 'acl', label: gettext('Privileges'), type: 'text',
-          group: gettext('Security'), mode: ['properties'],
-        },{
-          id: 'pkgacl', label: gettext('Privileges'), type: 'collection',
-          model: pgBrowser.Node.PrivilegeRoleModel.extend({
-            privileges: ['X'],
-          }), uniqueCol : ['grantee', 'grantor'], editable: false,
-          group: gettext('Security'), mode: ['edit', 'create'],
-          canAdd: true, canDelete: true, control: 'unique-col-collection',
-        }],
-        /* validate function is used to validate the input given by
-         * the user. In case of error, message will be displayed on
-         * the GUI for the respective control.
-         */
-        validate: function() {
-          var msg = undefined;
-          // Clear any existing error msg.
-          this.errorModel.clear();
-
-          if (_.isUndefined(this.get('name'))
-              || String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Name cannot be empty.');
-            this.errorModel.set('name', msg);
-            return msg;
-          }
-
-          if (_.isUndefined(this.get('pkgheadsrc'))
-              || String(this.get('pkgheadsrc')).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Header cannot be empty.');
-            this.errorModel.set('pkgheadsrc', msg);
-            return msg;
-          }
-
-          return null;
-        },
+        }]
       }),
+      getSchema: (treeNodeInfo, itemNodeData) => {
+        var nodeObj = pgBrowser.Nodes['package'];
+        return new PackageSchema(
+          (privileges)=>getNodePrivilegeRoleSchema(nodeObj, treeNodeInfo, itemNodeData, privileges),
+          {
+            schemas:() => getNodeListByName('schema', treeNodeInfo, itemNodeData, {
+              cacheLevel: 'database'
+            }),
+            node_info: treeNodeInfo
+          }, {
+            schema: treeNodeInfo.schema.label
+          }
+        );
+      }
     });
   }
 
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/static/js/package.ui.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/static/js/package.ui.js
new file mode 100644
index 000000000..b8ce86985
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/static/js/package.ui.js
@@ -0,0 +1,155 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2021, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+
+import gettext from 'sources/gettext';
+import BaseUISchema from 'sources/SchemaView/base_schema.ui';
+import { isEmptyString } from 'sources/validators';
+
+export default class PackageSchema extends BaseUISchema {
+  constructor(getPrivilegeRoleSchema, fieldOptions = {}, initValues) {
+    super({
+      name: undefined,
+      oid: undefined,
+      owner: undefined,
+      is_sys_object: undefined,
+      description: undefined,
+      pkgheadsrc: undefined,
+      pkgbodysrc: undefined,
+      acl: undefined,
+      pkgacl: [],
+      warn_text: undefined,
+      ...initValues
+    });
+    this.fieldOptions = {
+      schemas: [],
+      ...fieldOptions
+    };
+    this.warningText = null;
+    this.getPrivilegeRoleSchema = getPrivilegeRoleSchema;
+  }
+
+  get idAttribute() {
+    return 'oid';
+  }
+
+  get baseFields() {
+    let packageSchemaObj = this;
+    return [
+      {
+        id: 'name', label: gettext('Name'), cell: 'string',
+        type: 'text', mode: ['properties', 'create', 'edit'], noEmpty: true,
+        readonly: function (state) {
+          return !packageSchemaObj.isNew(state);
+        },
+      },{
+        id: 'oid', label: gettext('OID'), cell: 'string',
+        type: 'text', mode: ['properties'],
+      },{
+        id: 'owner', label: gettext('Owner'), cell: 'string',
+        type: 'text', mode: ['properties', 'create', 'edit'],
+        readonly: true, editable: false,
+        visible: function (state) {
+          return !packageSchemaObj.isNew(state);
+        },
+      },{
+        id: 'schema', label: gettext('Schema'), node: 'schema',
+        readonly: function (state) {
+          return !packageSchemaObj.isNew(state);
+        }, noEmpty: true,
+        type: (state) => {
+          return {
+            type: 'select',
+            options: packageSchemaObj.fieldOptions.schemas,
+            optionsLoaded: (options) => { packageSchemaObj.fieldOptions.schemas = options; },
+            controlProps: {
+              allowClear: true,
+              filter: (options) => {
+                let res = [];
+                if (state && packageSchemaObj.isNew(state)) {
+                  options.forEach((option) => {
+                    // If schema name start with pg_* then we need to exclude them
+                    if(option && option.label.match(/^pg_/)) {
+                      return;
+                    }
+                    res.push({ label: option.label, value: option.value, image: 'icon-schema' });
+                  });
+                } else {
+                  res = options;
+                }
+                return res;
+              }
+            }
+          };
+        }
+      },{
+        id: 'is_sys_object', label: gettext('System package?'),
+        cell:'boolean', type: 'switch',mode: ['properties'],
+      },{
+        id: 'description', label: gettext('Comment'), type: 'multiline',
+        mode: ['properties', 'create', 'edit'],
+      },{
+        id: 'pkgheadsrc',
+        type: 'sql', isFullTab: true, cell: 'text',
+        mode: ['properties', 'create', 'edit'],
+        group: gettext('Header'),
+        depChange: (state, source, topState, actionObj) => {
+
+          if(packageSchemaObj._origData.oid && state.pkgheadsrc != actionObj.oldState.pkgheadsrc) {
+            packageSchemaObj.warningText = gettext(
+              'Updating the package header definition may remove its existing body.'
+            ) + '<br><br><b>' + gettext('Do you want to continue?') +
+              '</b>';
+          }
+          else {
+            packageSchemaObj.warningText = null;
+          }
+        }
+      },{
+        id: 'pkgbodysrc',
+        type: 'sql', isFullTab: true, cell: 'text',
+        mode: ['properties', 'create', 'edit'], group: gettext('Body'),
+        depChange: (state, source, topState, actionObj) => {
+
+          if(packageSchemaObj._origData.oid && state.pkgbodysrc != actionObj.oldState.pkgbodysrc) {
+            packageSchemaObj.warningText = gettext(
+              'Updating the package header definition may remove its existing body.'
+            ) + '<br><br><b>' + gettext('Do you want to continue?') +
+              '</b>';
+          }
+          else {
+            packageSchemaObj.warningText = null;
+          }
+        }
+      },{
+        id: 'acl', label: gettext('Privileges'), type: 'text',
+        group: gettext('Security'), mode: ['properties'],
+      },{
+        id: 'pkgacl', label: gettext('Privileges'), type: 'collection',
+        schema: this.getPrivilegeRoleSchema(['X']),
+        uniqueCol : ['grantee', 'grantor'], editable: false,
+        group: gettext('Security'), mode: ['edit', 'create'],
+        canAdd: true, canDelete: true,
+      }
+    ];
+  }
+
+  validate(state, setError) {
+    let errmsg = null;
+    /* code validation */
+    if (isEmptyString(state.pkgheadsrc)) {
+      errmsg = gettext('Header cannot be empty.');
+      setError('pkgheadsrc', errmsg);
+      return true;
+    } else {
+      errmsg = null;
+      setError('pkgheadsrc', errmsg);
+    }
+    return null;
+  }
+}
diff --git a/web/pgadmin/static/js/SchemaView/index.jsx b/web/pgadmin/static/js/SchemaView/index.jsx
index 6904d1792..4d5c280e8 100644
--- a/web/pgadmin/static/js/SchemaView/index.jsx
+++ b/web/pgadmin/static/js/SchemaView/index.jsx
@@ -733,6 +733,7 @@ function SchemaPropertiesView({
   const classes = usePropsStyles();
   let defaultTab = 'General';
   let tabs = {};
+  let tabsClassname = {};
   const [origData, setOrigData] = useState({});
   const [loaderText, setLoaderText] = useState('');
 
@@ -745,12 +746,19 @@ function SchemaPropertiesView({
     });
   }, [getInitData]);
 
+  let fullTabs = [];
+
   /* A simple loop to get all the controls for the fields */
   schema.fields.forEach((field)=>{
     let {group} = field;
     let {visible, disabled, readonly, modeSupported} = getFieldMetaData(field, schema, origData, viewHelperProps);
     group = group || defaultTab;
 
+    if(field.isFullTab) {
+      tabsClassname[group] = classes.fullSpace;
+      fullTabs.push(group);
+    }
+
     readonly = true;
     if(visible && modeSupported) {
       if(!tabs[group]) tabs[group] = [];
@@ -798,6 +806,7 @@ function SchemaPropertiesView({
             disabled={disabled}
             visible={visible}
             className={classes.controlRow}
+            noLabel={field.isFullTab}
           />
         );
       }
diff --git a/web/regression/javascript/schema_ui_files/edbfunc.ui.spec.js b/web/regression/javascript/schema_ui_files/edbfunc.ui.spec.js
new file mode 100644
index 000000000..c1bb88e97
--- /dev/null
+++ b/web/regression/javascript/schema_ui_files/edbfunc.ui.spec.js
@@ -0,0 +1,99 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2021, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+
+import jasmineEnzyme from 'jasmine-enzyme';
+import React from 'react';
+import '../helper/enzyme.helper';
+import { createMount } from '@material-ui/core/test-utils';
+import pgAdmin from 'sources/pgadmin';
+import {messages} from '../fake_messages';
+import SchemaView from '../../../pgadmin/static/js/SchemaView';
+import EDBFuncSchema from '../../../pgadmin/browser/server_groups/servers/databases/schemas/packages/edbfuncs/static/js/edbfunc.ui';
+
+
+describe('EDBFuncSchema', ()=>{
+  let mount;
+  let edbFuncSchemaObj = new EDBFuncSchema(
+    {}, {
+      name: 'sysfunc'
+    }
+  );
+  let getInitData = ()=>Promise.resolve({});
+
+  /* Use createMount so that material ui components gets the required context */
+  /* https://material-ui.com/guides/testing/#api */
+  beforeAll(()=>{
+    mount = createMount();
+  });
+
+  afterAll(() => {
+    mount.cleanUp();
+  });
+
+  beforeEach(()=>{
+    jasmineEnzyme();
+    /* messages used by validators */
+    pgAdmin.Browser = pgAdmin.Browser || {};
+    pgAdmin.Browser.messages = pgAdmin.Browser.messages || messages;
+    pgAdmin.Browser.utils = pgAdmin.Browser.utils || {};
+  });
+
+  it('create', ()=>{
+    mount(<SchemaView
+      formType='dialog'
+      schema={edbFuncSchemaObj}
+      viewHelperProps={{
+        mode: 'create',
+      }}
+      onSave={()=>{}}
+      onClose={()=>{}}
+      onHelp={()=>{}}
+      onEdit={()=>{}}
+      onDataChange={()=>{}}
+      confirmOnCloseReset={false}
+      hasSQL={false}
+      disableSqlHelp={false}
+      disableDialogHelp={false}
+    />);
+  });
+
+  it('edit', ()=>{
+    mount(<SchemaView
+      formType='dialog'
+      schema={edbFuncSchemaObj}
+      getInitData={getInitData}
+      viewHelperProps={{
+        mode: 'create',
+      }}
+      onSave={()=>{}}
+      onClose={()=>{}}
+      onHelp={()=>{}}
+      onEdit={()=>{}}
+      onDataChange={()=>{}}
+      confirmOnCloseReset={false}
+      hasSQL={false}
+      disableSqlHelp={false}
+      disableDialogHelp={false}
+    />);
+  });
+
+  it('properties', ()=>{
+    mount(<SchemaView
+      formType='tab'
+      schema={edbFuncSchemaObj}
+      getInitData={getInitData}
+      viewHelperProps={{
+        mode: 'properties',
+      }}
+      onHelp={()=>{}}
+      onEdit={()=>{}}
+    />);
+  });
+});
+
diff --git a/web/regression/javascript/schema_ui_files/edbvar.ui.spec.js b/web/regression/javascript/schema_ui_files/edbvar.ui.spec.js
new file mode 100644
index 000000000..d7b315597
--- /dev/null
+++ b/web/regression/javascript/schema_ui_files/edbvar.ui.spec.js
@@ -0,0 +1,95 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2021, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+
+import jasmineEnzyme from 'jasmine-enzyme';
+import React from 'react';
+import '../helper/enzyme.helper';
+import { createMount } from '@material-ui/core/test-utils';
+import pgAdmin from 'sources/pgadmin';
+import {messages} from '../fake_messages';
+import SchemaView from '../../../pgadmin/static/js/SchemaView';
+import EDBVarSchema from '../../../pgadmin/browser/server_groups/servers/databases/schemas/packages/edbvars/static/js/edbvar.ui';
+
+
+describe('EDBVarSchema', ()=>{
+  let mount;
+  let edbVarSchemaObj = new EDBVarSchema();
+  let getInitData = ()=>Promise.resolve({});
+
+  /* Use createMount so that material ui components gets the required context */
+  /* https://material-ui.com/guides/testing/#api */
+  beforeAll(()=>{
+    mount = createMount();
+  });
+
+  afterAll(() => {
+    mount.cleanUp();
+  });
+
+  beforeEach(()=>{
+    jasmineEnzyme();
+    /* messages used by validators */
+    pgAdmin.Browser = pgAdmin.Browser || {};
+    pgAdmin.Browser.messages = pgAdmin.Browser.messages || messages;
+    pgAdmin.Browser.utils = pgAdmin.Browser.utils || {};
+  });
+
+  it('create', ()=>{
+    mount(<SchemaView
+      formType='dialog'
+      schema={edbVarSchemaObj}
+      viewHelperProps={{
+        mode: 'create',
+      }}
+      onSave={()=>{}}
+      onClose={()=>{}}
+      onHelp={()=>{}}
+      onEdit={()=>{}}
+      onDataChange={()=>{}}
+      confirmOnCloseReset={false}
+      hasSQL={false}
+      disableSqlHelp={false}
+      disableDialogHelp={false}
+    />);
+  });
+
+  it('edit', ()=>{
+    mount(<SchemaView
+      formType='dialog'
+      schema={edbVarSchemaObj}
+      getInitData={getInitData}
+      viewHelperProps={{
+        mode: 'create',
+      }}
+      onSave={()=>{}}
+      onClose={()=>{}}
+      onHelp={()=>{}}
+      onEdit={()=>{}}
+      onDataChange={()=>{}}
+      confirmOnCloseReset={false}
+      hasSQL={false}
+      disableSqlHelp={false}
+      disableDialogHelp={false}
+    />);
+  });
+
+  it('properties', ()=>{
+    mount(<SchemaView
+      formType='tab'
+      schema={edbVarSchemaObj}
+      getInitData={getInitData}
+      viewHelperProps={{
+        mode: 'properties',
+      }}
+      onHelp={()=>{}}
+      onEdit={()=>{}}
+    />);
+  });
+});
+
diff --git a/web/regression/javascript/schema_ui_files/packages.ui.spec.js b/web/regression/javascript/schema_ui_files/packages.ui.spec.js
new file mode 100644
index 000000000..e00c25af2
--- /dev/null
+++ b/web/regression/javascript/schema_ui_files/packages.ui.spec.js
@@ -0,0 +1,156 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2021, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+
+import jasmineEnzyme from 'jasmine-enzyme';
+import React from 'react';
+import '../helper/enzyme.helper';
+import { createMount } from '@material-ui/core/test-utils';
+import pgAdmin from 'sources/pgadmin';
+import {messages} from '../fake_messages';
+import SchemaView from '../../../pgadmin/static/js/SchemaView';
+import { getNodePrivilegeRoleSchema } from '../../../pgadmin/browser/server_groups/servers/static/js/privilege.ui';
+import PackageSchema from '../../../pgadmin/browser/server_groups/servers/databases/schemas/packages/static/js/package.ui';
+
+
+describe('PackageSchema', ()=>{
+  let mount;
+  let packageSchemaObj = new PackageSchema(
+    (privileges)=>getNodePrivilegeRoleSchema({}, {server: {user: {name: 'postgres'}}}, {}, privileges),
+    {
+      schemas:() => [],
+      node_info: {'schema': []}
+    },
+  );
+  let getInitData = ()=>Promise.resolve({});
+
+  /* Use createMount so that material ui components gets the required context */
+  /* https://material-ui.com/guides/testing/#api */
+  beforeAll(()=>{
+    mount = createMount();
+  });
+
+  afterAll(() => {
+    mount.cleanUp();
+  });
+
+  beforeEach(()=>{
+    jasmineEnzyme();
+    /* messages used by validators */
+    pgAdmin.Browser = pgAdmin.Browser || {};
+    pgAdmin.Browser.messages = pgAdmin.Browser.messages || messages;
+    pgAdmin.Browser.utils = pgAdmin.Browser.utils || {};
+  });
+
+  it('create', ()=>{
+    mount(<SchemaView
+      formType='dialog'
+      schema={packageSchemaObj}
+      viewHelperProps={{
+        mode: 'create',
+      }}
+      onSave={()=>{}}
+      onClose={()=>{}}
+      onHelp={()=>{}}
+      onEdit={()=>{}}
+      onDataChange={()=>{}}
+      confirmOnCloseReset={false}
+      hasSQL={false}
+      disableSqlHelp={false}
+      disableDialogHelp={false}
+    />);
+  });
+
+  it('edit', ()=>{
+    mount(<SchemaView
+      formType='dialog'
+      schema={packageSchemaObj}
+      getInitData={getInitData}
+      viewHelperProps={{
+        mode: 'create',
+      }}
+      onSave={()=>{}}
+      onClose={()=>{}}
+      onHelp={()=>{}}
+      onEdit={()=>{}}
+      onDataChange={()=>{}}
+      confirmOnCloseReset={false}
+      hasSQL={false}
+      disableSqlHelp={false}
+      disableDialogHelp={false}
+    />);
+  });
+
+  it('properties', ()=>{
+    mount(<SchemaView
+      formType='tab'
+      schema={packageSchemaObj}
+      getInitData={getInitData}
+      viewHelperProps={{
+        mode: 'properties',
+      }}
+      onHelp={()=>{}}
+      onEdit={()=>{}}
+    />);
+  });
+
+  it('pkgheadsrc depChange', ()=>{
+
+    let state = {
+      pkgheadsrc: 'changed text'
+    };
+    packageSchemaObj.warningText = null;
+    packageSchemaObj._origData = {
+      oid: '123'
+    };
+    let actionObj = {
+      oldState: {
+        pkgheadsrc: 'original text'
+      }
+    };
+
+    let depChange = _.find(packageSchemaObj.fields, (f)=>f.id=='pkgheadsrc').depChange;
+    depChange(state, {}, {}, actionObj);
+    expect(packageSchemaObj.warningText).not.toBeNull();
+  });
+
+  it('pkgbodysrc depChange', ()=>{
+
+    let state = {
+      pkgheadsrc: 'changed text'
+    };
+    packageSchemaObj.warningText = null;
+    packageSchemaObj._origData = {
+      oid: '123'
+    };
+    let actionObj = {
+      oldState: {
+        pkgbodysrc: 'original text'
+      }
+    };
+
+    let depChange = _.find(packageSchemaObj.fields, (f)=>f.id=='pkgbodysrc').depChange;
+    depChange(state, {}, {}, actionObj);
+    expect(packageSchemaObj.warningText).not.toBeNull();
+  });
+
+  it('package validate', () => {
+    let state = {
+      pkgheadsrc: undefined
+    };
+    let setError = jasmine.createSpy('setError');
+
+    packageSchemaObj.validate(state, setError);
+    expect(setError).toHaveBeenCalledWith('pkgheadsrc', 'Header cannot be empty.');
+
+    state.pkgheadsrc = 'changed';
+    let validate = packageSchemaObj.validate(state, setError);
+    expect(validate).toBe(null);
+  });
+});
+
