diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.js
index 536dc9472..9ceeb6b76 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.js
@@ -7,14 +7,20 @@
 //
 //////////////////////////////////////////////////////////////
 
+import { getNodeAjaxOptions, getNodeListByName, getNodeListById} from '../../../../../../../static/js/node_ajax';
+import FunctionSchema from './function.ui';
+import { getNodePrivilegeRoleSchema } from '../../../../../static/js/privilege.ui';
+import { getNodeVariableSchema } from '../../../../../static/js/variable.ui';
+import _ from 'lodash';
+
 /* Create and Register Function Collection and Node. */
 define('pgadmin.node.function', [
-  'sources/gettext', 'sources/url_for', 'jquery', 'underscore', 'backbone',
+  'sources/gettext', 'sources/url_for', 'jquery', 'backbone',
   'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform',
   'pgadmin.node.schema.dir/child', 'pgadmin.node.schema.dir/schema_child_tree_node',
   'pgadmin.browser.collection', 'pgadmin.browser.server.privilege',
 ], function(
-  gettext, url_for, $, _, Backbone, pgAdmin, pgBrowser, Backform, schemaChild,
+  gettext, url_for, $, Backbone, pgAdmin, pgBrowser, Backform, schemaChild,
   schemaChildTreeNode
 ) {
 
@@ -30,69 +36,6 @@ define('pgadmin.node.function', [
         canDropCascade: schemaChildTreeNode.isTreeItemOfChildOfSchema,
       });
   }
-
-  // Argument Model
-  var ArgumentModel = pgBrowser.Node.Model.extend({
-    idAttribute: 'argid',
-    defaults: {
-      argid: undefined,
-      argtype: undefined,
-      argmode: undefined,
-      argname: undefined,
-      argdefval: undefined,
-    },
-    schema: [{
-      id: 'argid', visible: false, type: 'text',
-      mode: ['properties', 'edit','create'],
-    },{
-      id: 'argtype', label: gettext('Data type'), cell:
-        'node-ajax-options', cellHeaderClasses: 'width_percent_30',
-      control: 'node-ajax-options', type: 'text', url: 'get_types',
-      editable: 'isEditable', first_empty: true,
-    },{
-      id: 'argmode', label: gettext('Mode'), type: 'options',
-      control: 'node-ajax-options', cellHeaderClasses:'width_percent_20',
-      cell: 'node-ajax-options', select2: {
-        allowClear: false,
-      },
-      options:[
-        {'label': 'IN', 'value': 'IN'},
-        {'label': 'OUT', 'value': 'OUT'},
-        {'label': 'INOUT', 'value': 'INOUT'},
-        {'label': 'VARIADIC', 'value': 'VARIADIC'},
-      ], editable: 'isEditable',
-    },{
-      id: 'argname', label: gettext('Argument name'), type: 'text',
-      cell: 'string', editable: 'isInCatalog', cellHeaderClasses:'width_percent_30',
-    },{
-      id: 'argdefval', label: gettext('Default'), type: 'text',
-      cell: 'string', editable: 'isInCatalog',  cellHeaderClasses:'width_percent_20',
-    },
-    ],
-    toJSON: Backbone.Model.prototype.toJSON,
-    isEditable: function(m) {
-      var node_info = this.get('node_info');
-      if(node_info && 'catalog' in node_info) {
-        return false;
-      }
-      return _.isUndefined(m.isNew) ? true : m.isNew();
-    },
-    isInCatalog: function(m){
-      var node_info = this.get('node_info');
-      if(node_info && 'catalog' in node_info) {
-        return false;
-      }
-      // Below will disable default value cell if argument mode is 'INOUT' or 'OUT' as
-      // user cannot set default value for out parameters.
-      if(!_.isUndefined(m.get('argmode')) && !_.isUndefined(this.get('name')) &&
-         this.get('name') == 'argdefval' &&
-         (m.get('argmode') == 'INOUT' || m.get('argmode') == 'OUT')) {
-        return false;
-      }
-      return true;
-    },
-  });
-
   if (!pgBrowser.Nodes['function']) {
 
     pgBrowser.Nodes['function'] = schemaChild.SchemaChildNode.extend({
@@ -138,6 +81,36 @@ define('pgadmin.node.function', [
         ]);
 
       },
+      getSchema: function(treeNodeInfo, itemNodeData) {
+        return new FunctionSchema(
+          (privileges)=>getNodePrivilegeRoleSchema(this, treeNodeInfo, itemNodeData, privileges),
+          ()=>getNodeVariableSchema(this, treeNodeInfo, itemNodeData, false, false),
+          {
+            role: ()=>getNodeListByName('role', treeNodeInfo, itemNodeData),
+            schema: ()=>getNodeListById(pgBrowser.Nodes['schema'], treeNodeInfo, itemNodeData, {
+              cacheLevel: 'database'
+            }
+            ),
+            getTypes: ()=>getNodeAjaxOptions('get_types', this, treeNodeInfo, itemNodeData),
+            getLanguage: ()=>getNodeAjaxOptions('get_languages', this, treeNodeInfo, itemNodeData),
+            getSupportFunctions: ()=>getNodeAjaxOptions('get_support_functions', this, treeNodeInfo, itemNodeData, {
+              cacheNode: 'function'
+            }),
+
+          },
+          {
+            node_info: treeNodeInfo,
+          },
+          {
+            type: pgBrowser.Nodes['function'].type,
+          },
+          {
+            funcowner: pgBrowser.serverInfo[treeNodeInfo.server._id].user.name,
+            pronamespace: treeNodeInfo.schema ? treeNodeInfo.schema._id : null,
+            lanname: 'sql',
+          }
+        );
+      },
       model: pgBrowser.Node.Model.extend({
         idAttribute: 'oid',
         initialize: function(attrs, args) {
@@ -153,40 +126,6 @@ define('pgadmin.node.function', [
           }
           pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
         },
-        defaults: {
-          name: undefined,
-          oid: undefined,
-          xmin: undefined,
-          funcowner: undefined,
-          pronamespace: undefined,
-          description: 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 */
-          provolatile: undefined, /* Volatility */
-          proretset: undefined, /* Return Set */
-          proisstrict: undefined,
-          prosecdef: undefined, /* Security of definer */
-          proiswindow: undefined, /* Window Function ? */
-          proparallel: undefined, /* Parallel mode */
-          procost: undefined, /* Estimated execution Cost */
-          prorows: 0, /* Estimated number of rows */
-          proleakproof: undefined,
-          prosupportfunc: undefined, /* Support function */
-          arguments: [],
-          prosrc: undefined,
-          prosrc_c: undefined,
-          probin: '$libdir/',
-          options: [],
-          variables: [],
-          proacl: undefined,
-          seclabels: [],
-          acl: [],
-          sysfunc: undefined,
-          sysproc: undefined,
-        },
         schema: [{
           id: 'name', label: gettext('Name'), cell: 'string',
           type: 'text', mode: ['properties', 'create', 'edit'],
@@ -202,270 +141,8 @@ define('pgadmin.node.function', [
           id: 'pronamespace', label: gettext('Schema'), cell: 'string',
           control: 'node-list-by-id', type: 'text', cache_level: 'database',
           node: 'schema', disabled: 'isDisabled', mode: ['create', 'edit'],
-        },{
-          id: 'sysfunc', label: gettext('System function?'),
-          cell:'boolean', type: 'switch',
-          mode: ['properties'], visible: 'isVisible',
-        },{
-          id: 'sysproc', label: gettext('System procedure?'),
-          cell:'boolean', type: 'switch',
-          mode: ['properties'], visible: 'isVisible',
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', disabled: 'isDisabled',
-        },{
-          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',
-          control: 'node-ajax-options', type: 'text', group: gettext('Definition'),
-          url: 'get_types', readonly: 'isReadonly', first_empty: true,
-          mode: ['create'], visible: 'isVisible',
-        },{
-          id: 'prorettypename', label: gettext('Return type'), cell: 'string',
-          type: 'text', group: gettext('Definition'),
-          mode: ['properties', 'edit'], readonly: 'isReadonly', visible: 'isVisible',
-        },  {
-          id: 'lanname', label: gettext('Language'), cell: 'string',
-          control: 'node-ajax-options', type: 'text', group: gettext('Definition'),
-          url: 'get_languages', disabled: 'isDisabled',
-        },{
-          id: 'prosrc', label: gettext('Code'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          group: gettext('Code'), deps: ['lanname'],
-          tabPanelCodeClass: 'sql-code-control',
-          control: Backform.SqlCodeControl,
-          extraClasses:['custom_height_css_class'],
-          visible: function(m) {
-            if (m.get('lanname') == 'c') {
-              return false;
-            }
-            return true;
-          }, disabled: 'isDisabled',
-        },{
-          id: 'probin', label: gettext('Object file'), cell: 'string',
-          type: 'text', group: gettext('Definition'), deps: ['lanname'], visible:
-          function(m) {
-            if (m.get('lanname') == 'c') { return true; }
-            return false;
-          }, disabled: 'isDisabled',
-        },{
-          id: 'prosrc_c', label: gettext('Link symbol'), cell: 'string',
-          type: 'text', group: gettext('Definition'),  deps: ['lanname'], visible:
-          function(m) {
-            if (m.get('lanname') == 'c') { return true; }
-            return false;
-          }, disabled: 'isDisabled',
-        },{
-          id: 'provolatile', label: gettext('Volatility'), cell: 'string',
-          control: 'node-ajax-options', type: 'text', group: gettext('Options'),
-          deps: ['lanname'],
-          options:[
-            {'label': 'VOLATILE', 'value': 'v'},
-            {'label': 'STABLE', 'value': 's'},
-            {'label': 'IMMUTABLE', 'value': 'i'},
-          ], disabled: 'isDisabled', select2: {allowClear: false},
-        },{
-          id: 'proretset', label: gettext('Returns a set?'), type: 'switch',
-          disabled: 'isDisabled', group: gettext('Options'),
-          visible: 'isVisible',
-        },{
-          id: 'proisstrict', label: gettext('Strict?'), type: 'switch',
-          group: gettext('Options'), disabled: 'isDisabled',
-          deps: ['lanname'],
-        },{
-          id: 'prosecdef', label: gettext('Security of definer?'),
-          group: gettext('Options'), type: 'switch',
-          disabled: 'isDisabled',
-        },{
-          id: 'proiswindow', label: gettext('Window?'),
-          group: gettext('Options'), cell:'boolean', type: 'switch',
-          disabled: 'isDisabled', visible: 'isVisible',
-        },{
-          id: 'proparallel', label: gettext('Parallel'), cell: 'string',
-          control: 'node-ajax-options', type: 'text', group: gettext('Options'),
-          deps: ['lanname'],
-          options:[
-            {'label': 'UNSAFE', 'value': 'u'},
-            {'label': 'RESTRICTED', 'value': 'r'},
-            {'label': 'SAFE', 'value': 's'},
-          ], disabled: 'isDisabled', min_version: 90600,
-          select2: {allowClear: false},
-        },{
-          id: 'procost', label: gettext('Estimated cost'), group: gettext('Options'),
-          cell:'string', type: 'text', readonly: 'isReadonly', deps: ['lanname'], disabled: 'isDisabled',
-        },{
-          id: 'prorows', label: gettext('Estimated rows'), type: 'text',
-          deps: ['proretset'], visible: 'isVisible', readonly: 'isReadonly',
-          group: gettext('Options'),disabled: 'isDisabled',
-        },{
-          id: 'proleakproof', label: gettext('Leak proof?'),
-          group: gettext('Options'), cell:'boolean', type: 'switch', min_version: 90200,
-          disabled: 'isDisabled', deps: ['lanname'],
-        },{
-          id: 'prosupportfunc', label: gettext('Support function'),
-          type: 'text', disabled: 'isDisabled',
-          group: gettext('Options'), visible: 'isVisible',
-          control: 'node-ajax-options', url: 'get_support_functions',
-          cache_node: 'function', min_version: 120000,
-        },{
-          id: 'proacl', label: gettext('Privileges'), type: 'text',
-          mode: ['properties'], group: gettext('Security'),
-        },{
-          id: 'arguments', label: gettext('Arguments'), cell: 'string',
-          group: gettext('Definition'), type: 'collection', canAdd: function(m){
-            return m.isNew();
-          },
-          canDelete: true, model: ArgumentModel, mode: ['create', 'edit'],
-          columns: ['argtype', 'argmode', 'argname', 'argdefval'],
-          disabled: 'isDisabled', canDeleteRow: function(m) {
-            return m.isNew();
-          },
-        },{
-          id: 'variables', label: '', type: 'collection',
-          group: gettext('Parameters'), control: 'variable-collection',
-          model: pgBrowser.Node.VariableModel,
-          mode: ['edit', 'create'], canAdd: 'canVarAdd', canEdit: false,
-          canDelete: true, disabled: 'isDisabled',
-        }, pgBrowser.SecurityGroupSchema, {
-          id: 'acl', label: gettext('Privileges'), editable: false,
-          model: pgBrowser.Node.PrivilegeRoleModel.extend({
-            privileges: ['X'],
-          }), uniqueCol : ['grantee', 'grantor'], type: 'collection',
-          group: 'security', mode: ['edit', 'create'], canAdd: true,
-          canDelete: true, control: 'unique-col-collection',
-          disabled: 'isDisabled',
-        },{
-          id: 'seclabels', label: gettext('Security labels'), canAdd: true,
-          model: pgBrowser.SecLabelModel, type: 'collection',
-          min_version: 90100, group: 'security', mode: ['edit', 'create'],
-          canEdit: false, canDelete: true, uniqueCol : ['provider'],
-          disabled: 'isDisabled', control: 'unique-col-collection',
-          visible: function() {
-            return this.node && this.node.type != 'procedure';
-          },
         },
         ],
-        validate: function()
-        {
-          var err = {},
-            errmsg,
-            seclabels = this.get('seclabels');
-
-          if (_.isUndefined(this.get('name')) || String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
-            err['name'] = gettext('Name cannot be empty.');
-            errmsg = err['name'];
-          }
-
-          if (_.isUndefined(this.get('funcowner')) || String(this.get('funcowner')).replace(/^\s+|\s+$/g, '') == '') {
-            err['funcowner'] = gettext('Owner cannot be empty.');
-            errmsg = errmsg || err['funcowner'];
-          }
-
-          if (_.isUndefined(this.get('pronamespace')) || String(this.get('pronamespace')).replace(/^\s+|\s+$/g, '') == '') {
-            err['pronamespace'] = gettext('Schema cannot be empty.');
-            errmsg = errmsg || err['pronamespace'];
-          }
-
-          if (_.isUndefined(this.get('prorettypename')) || String(this.get('prorettypename')).replace(/^\s+|\s+$/g, '') == '') {
-            err['prorettypename'] = gettext('Return type cannot be empty.');
-            errmsg = errmsg || err['prorettypename'];
-          }
-
-          if (_.isUndefined(this.get('lanname')) || String(this.get('lanname')).replace(/^\s+|\s+$/g, '') == '') {
-            err['lanname'] = gettext('Language cannot be empty.');
-            errmsg = errmsg || err['lanname'];
-          }
-
-          if (String(this.get('lanname')) == 'c') {
-            if (_.isUndefined(this.get('probin')) || String(this.get('probin'))
-              .replace(/^\s+|\s+$/g, '') == '') {
-              err['probin'] = gettext('Object File cannot be empty.');
-              errmsg = errmsg || err['probin'];
-            }
-
-            if (_.isUndefined(this.get('prosrc_c')) || String(this.get('prosrc_c')).replace(/^\s+|\s+$/g, '') == '') {
-              err['prosrc_c'] = gettext('Link Symbol cannot be empty.');
-              errmsg = errmsg || err['prosrc_c'];
-            }
-          }
-          else {
-            if (_.isUndefined(this.get('prosrc')) || String(this.get('prosrc')).replace(/^\s+|\s+$/g, '') == '') {
-              err['prosrc'] = gettext('Code cannot be empty.');
-              errmsg = errmsg || err['prosrc'];
-            }
-          }
-
-          if (seclabels) {
-            var secLabelsErr;
-            for (var i = 0; i < seclabels.models.length && !secLabelsErr; i++) {
-              secLabelsErr = (seclabels.models[i]).validate.apply(seclabels.models[i]);
-              if (secLabelsErr) {
-                err['seclabels'] = secLabelsErr;
-                errmsg = errmsg || secLabelsErr;
-              }
-            }
-          }
-
-          this.errorModel.clear().set(err);
-
-          if (_.size(err)) {
-            this.trigger('on-status', {msg: errmsg});
-            return errmsg;
-          }
-
-          return null;
-        },
-        isVisible: function() {
-          if (this.name == 'sysproc') { return false; }
-          return true;
-        },
-        isDisabled: function(m) {
-          //Disable the returns a set and window in edit mode.
-          if((this.name == 'proretset' || this.name == 'proiswindow') && !m.isNew()){
-            return true;
-          }
-          if(this.node_info && 'catalog' in this.node_info) {
-            return true;
-          }
-          if(this.name === 'prosupportfunc'){
-            var item = pgAdmin.Browser.tree.selected();
-            if(pgAdmin.Browser.Nodes['function'].getTreeNodeHierarchy(item).server.user.is_superuser)
-              return false;
-            return true;
-          } else {
-            return false;
-          }
-        },
-        isReadonly: function(m) {
-          switch(this.name){
-          case 'proargs':
-          case 'proargtypenames':
-          case 'proretset':
-          case 'proiswindow':
-          case 'prorettypename':
-            return !m.isNew();
-          case 'prorows':
-            if(m.get('proretset') == true) {
-              return false;
-            }
-            return true;
-          default:
-            return false;
-          }
-        },
-        canVarAdd: function() {
-          if(this.node_info &&  'catalog' in this.node_info) {
-            return false;
-          }
-          return true;
-        },
       }),
     });
 
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.ui.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.ui.js
new file mode 100644
index 000000000..ac29accb9
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.ui.js
@@ -0,0 +1,470 @@
+/////////////////////////////////////////////////////////////
+//
+// 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 SecLabelSchema from '../../../../../static/js/sec_label.ui';
+import { isEmptyString } from 'sources/validators';
+import _ from 'lodash';
+
+export class DefaultArgumentSchema extends BaseUISchema {
+  constructor(node_info, getTypes) {
+    super();
+    this.node_info = node_info;
+    this.getTypes = getTypes;
+    this.type_options = {};
+  }
+  setTypeOptions(options) {
+    options.forEach((option)=>{
+      this.type_options[option.value] = {
+        ...option,
+      };
+    });
+  }
+
+  get baseFields() {
+    return[{
+      id: 'argid', visible: false, type: 'text',
+      mode: ['properties', 'edit','create'],
+    },{
+      id: 'argtype', label: gettext('Data type'),
+      options: this.getTypes,
+      type: 'text',
+      cell: ()=>({
+        cell: 'select', options: this.getTypes,
+        optionsLoaded: (options)=>{this.setTypeOptions(options);},
+        controlProps: {
+          allowClear: false,
+        }
+      }),
+      editable: this.isEditable, first_empty: true,
+    },{
+      id: 'argmode', label: gettext('Mode'),
+      type: 'text',
+      cell: ()=>({
+        cell: 'select',
+        options:[
+          {'label': 'IN', 'value': 'IN'},
+          {'label': 'OUT', 'value': 'OUT'},
+          {'label': 'INOUT', 'value': 'INOUT'},
+          {'label': 'VARIADIC', 'value': 'VARIADIC'},
+        ],
+        optionsLoaded: (options)=>{this.setTypeOptions(options);},
+        controlProps: {
+          allowClear: false,
+        }
+      }),
+      editable: this.isEditable,
+    },{
+      id: 'argname', label: gettext('Argument name'), type: 'text',
+      editable: this.isInCatalog, cell: ()=>({cell: 'text'})
+    },{
+      id: 'argdefval', label: gettext('Default'), type: 'text',
+      cell: ()=>({cell: 'text'}), editable: this.isInCatalog,
+    }];
+  }
+
+  isEditable() {
+    var node_info = this.node_info;
+    if(node_info && 'catalog' in node_info) {
+      return false;
+    }
+    return _.isUndefined(this.isNew) ? true : this.isNew();
+  }
+  isInCatalog(state){
+    var node_info = this.node_info;
+    if(node_info && 'catalog' in node_info) {
+      return false;
+    }
+    // Below will disable default value cell if argument mode is 'INOUT' or 'OUT' as
+    // user cannot set default value for out parameters.
+    if(!_.isUndefined(state.argmode) && !_.isUndefined(state.name) &&
+       state.name == 'argdefval' &&
+       (state.argmode == 'INOUT' || state.argmode == 'OUT')) {
+      return false;
+    }
+    return true;
+  }
+}
+
+export default class FunctionSchema extends BaseUISchema {
+  constructor(getPrivilegeRoleSchema, getNodeVariableSchema, fieldOptions={}, node_info, type, initValues) {
+    super({
+      name: undefined,
+      oid: undefined,
+      xmin: undefined,
+      funcowner: undefined,
+      pronamespace: undefined,
+      description: undefined,
+      pronargs: undefined, /* Argument Count */
+      proargs: undefined, /* Arguments */
+      proargtypenames: undefined, /* Argument Signature */
+      prorettypename: undefined, /* Return Type */
+      lanname: undefined, /* Language Name in which function is being written */
+      provolatile: undefined, /* Volatility */
+      proretset: undefined, /* Return Set */
+      proisstrict: undefined,
+      prosecdef: undefined, /* Security of definer */
+      proiswindow: undefined, /* Window Function ? */
+      proparallel: undefined, /* Parallel mode */
+      procost: undefined, /* Estimated execution Cost */
+      prorows: 0, /* Estimated number of rows */
+      proleakproof: undefined,
+      prosupportfunc: undefined, /* Support function */
+      arguments: [],
+      prosrc: undefined,
+      prosrc_c: undefined,
+      probin: '$libdir/',
+      options: [],
+      variables: [],
+      proacl: undefined,
+      seclabels: [],
+      acl: [],
+      sysfunc: undefined,
+      sysproc: undefined,
+      ...initValues
+    });
+
+    this.getPrivilegeRoleSchema = getPrivilegeRoleSchema;
+    this.getNodeVariableSchema = getNodeVariableSchema;
+    this.node_info = node_info;
+    this.type =  type.type;
+    this.fieldOptions = {
+      role: [],
+      schema: [],
+      getTypes: [],
+      ...fieldOptions,
+    };
+  }
+
+  get idAttribute() {
+    return 'oid';
+  }
+
+  isVisible(state) {
+    if(!(this.type === 'procedure')){
+      if (state.sysproc) { return false; }
+      return true;
+    }else{
+      if (state.sysfunc) {
+        return false;
+      } else if (state.sysproc) {
+        return true;
+      }
+
+      return false;
+    }
+  }
+  isDisabled() {
+    if (this.node_info && 'catalog' in this.node_info) {
+      return true;
+    }
+  }
+  isGreaterThan95(state){
+    if (
+      this.node_info['node_info'].server.version < 90500 ||
+      this.node_info['node_info']['server'].server_type != 'ppas' ||
+      state.lanname != 'edbspl'
+    ) {
+      state.provolatile = null;
+      state.proisstrict = false;
+      state.procost = null;
+      state.proleakproof = false;
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  isGreaterThan96(state){
+    if (
+      this.node_info['node_info'].server.version < 90600 ||
+      this.node_info['node_info']['server'].server_type != 'ppas' ||
+      state.lanname != 'edbspl'
+    ) {
+      state.proparallel = null;
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  isProcedure(state) {
+
+    if (this.node_info && 'catalog' in this.node_info) {
+      return true;
+    }
+        
+    if (state.prorows) {
+      var server = this.node_info['node_info']['server'];
+      return !(server.version >= 90500 && state.proretset == true);
+    }
+  }
+
+  isReadonly() {
+    return !this.isNew();
+  }
+
+  canVarAdd(){
+    if(this.node_info &&  'catalog' in this.node_info) {
+      return false;
+    }
+    return true;
+  }
+
+  get baseFields() {
+    let obj = this;
+    return [{
+      id: 'name', label: gettext('Name'), cell: 'string',
+      type: 'text', mode: ['properties', 'create', 'edit'],
+      disabled: (!(this.type === 'procedure')) ? obj.isDisabled: obj.isProcedure,
+      noEmpty: true,
+    },{
+      id: 'oid', label: gettext('OID'), cell: 'string',
+      type: 'text' , mode: ['properties'],
+    },{
+      id: 'funcowner', label: gettext('Owner'), cell: 'string',
+      options: this.fieldOptions.role, type: 'select',
+      disabled: (!(this.type === 'procedure')) ? obj.isDisabled : obj.isGreaterThan95,
+      noEmpty: true,
+    },{
+      id: 'pronamespace', label: gettext('Schema'), cell: 'string',
+      type: 'select', disabled: (!(this.type === 'procedure')) ? obj.isDisabled: obj.isProcedure,
+      mode: ['create', 'edit'],
+      controlProps: {
+        allowClear: false,
+        first_empty: false,
+      },
+      options: obj.fieldOptions.schema, noEmpty: true,
+    },{
+      id: 'sysfunc', label: gettext('System function?'),
+      cell:'boolean', type: 'switch',
+      mode: ['properties'], visible: obj.isVisible,
+    },{
+      id: 'sysproc', label: gettext('System procedure?'),
+      cell:'boolean', type: 'switch',
+      mode: ['properties'], visible: obj.isVisible,
+    },{
+      id: 'description', label: gettext('Comment'), cell: 'string',
+      type: 'multiline', disabled: obj.isDisabled,
+    },{
+      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: 'select', group: gettext('Definition'),
+      options: this.fieldOptions.getTypes,
+      readonly: obj.isReadonly, first_empty: true,
+      mode: ['create'], visible: obj.isVisible,
+    },{
+      id: 'prorettypename', label: gettext('Return type'), cell: 'string',
+      type: 'text', group: gettext('Definition'),
+      mode: ['properties', 'edit'], readonly: obj.isReadonly, visible: obj.isVisible,
+    },{
+      id: 'lanname', label: gettext('Language'), cell: 'string',
+      options: this.fieldOptions.getLanguage, type: 'select', group: gettext('Definition'),
+      disabled: function() {
+        if (this.node_info && 'catalog' in this.node_info) {
+          return true;
+        }
+
+        return this.node_info['node_info'].server.version < 110000;
+      }
+    },
+    {
+      id: 'probin', label: gettext('Object file'), cell: 'string',
+      type: 'text', group: gettext('Definition'), deps: ['lanname'], visible:
+      function(state) {
+        if (state.lanname == 'c') { return true; }
+        return false;
+      }, disabled: (!(this.type === 'procedure')) ? obj.isDisabled: obj.isProcedure,
+    },{
+      id: 'prosrc_c', label: gettext('Link symbol'), cell: 'string',
+      type: 'text', group: gettext('Definition'),  deps: ['lanname'], visible:
+      function(state) {
+        if (state.lanname == 'c') { return true; }
+        return false;
+      }, disabled: (!(this.type === 'procedure')) ? obj.isDisabled: obj.isProcedure,
+    },
+    {
+      id: 'arguments', label: gettext('Arguments'), cell: 'string',
+      group: gettext('Definition'), type: 'collection', canAdd: function(){
+        return obj.isNew();
+      },
+      canDelete: true, mode: ['create', 'edit'],
+      columns: ['argtype', 'argmode', 'argname', 'argdefval'],
+      schema : new DefaultArgumentSchema(this.node_info, this.fieldOptions.getTypes),
+      disabled: (!(this.type === 'procedure')) ? obj.isDisabled: obj.isProcedure,
+      canDeleteRow: function() {
+        return obj.isNew();
+      },
+    },{
+      id: 'prosrc', label: gettext('Code'), cell: 'text',
+      type: 'sql', mode: ['properties', 'create', 'edit'],
+      group: gettext('Code'), deps: ['lanname'],
+      isFullTab: true,
+      visible: function(state) {
+        if (state.lanname === 'c') {
+          return false;
+        }
+        return true;
+      }, disabled: (!(this.type === 'procedure')) ? obj.isDisabled: obj.isProcedure,
+    },{
+      id: 'provolatile', label: gettext('Volatility'), cell: 'text',
+      type: 'select', group: gettext('Options'),
+      deps: ['lanname'],
+      options:[
+        {'label': 'VOLATILE', 'value': 'v'},
+        {'label': 'STABLE', 'value': 's'},
+        {'label': 'IMMUTABLE', 'value': 'i'},
+      ], disabled: (!(this.type === 'procedure')) ? obj.isDisabled: obj.isProcedure,
+      controlProps: {allowClear: false},
+    },{
+      id: 'proretset', label: gettext('Returns a set?'), type: 'switch',
+      disabled: ()=>{return !obj.isNew();}, group: gettext('Options'),
+      visible: obj.isVisible, readonly: obj.isReadonly,
+    },{
+      id: 'proisstrict', label: gettext('Strict?'), type: 'switch',
+      group: gettext('Options'), disabled: (!(this.type === 'procedure')) ? obj.isDisabled: obj.isGreaterThan95,
+      deps: ['lanname'],
+    },{
+      id: 'prosecdef', label: gettext('Security of definer?'),
+      group: gettext('Options'), type: 'switch',
+      disabled: (!(this.type === 'procedure')) ? obj.isDisabled: ()=>{
+        return obj.node_info['node_info'].server.version < 90500;
+      },
+    },{
+      id: 'proiswindow', label: gettext('Window?'),
+      group: gettext('Options'), cell:'boolean', type: 'switch',
+      disabled: ()=>{return !obj.isNew();}, visible: obj.isVisible, readonly: obj.isReadonly,
+    },{
+      id: 'proparallel', label: gettext('Parallel'), cell: 'string',
+      type: 'select', group: gettext('Options'),
+      deps: ['lanname'],
+      options:[
+        {'label': 'UNSAFE', 'value': 'u'},
+        {'label': 'RESTRICTED', 'value': 'r'},
+        {'label': 'SAFE', 'value': 's'},
+      ],
+      disabled: (!(this.type === 'procedure')) ? obj.isDisabled: obj.isGreaterThan96,
+      min_version: 90600,
+      controlProps: {allowClear: false},
+    },{
+      id: 'procost', label: gettext('Estimated cost'), group: gettext('Options'),
+      cell:'string', type: 'text', deps: ['lanname'],
+      disabled: (!(this.type === 'procedure')) ? obj.isDisabled: obj.isGreaterThan95,
+    },{
+      id: 'prorows', label: gettext('Estimated rows'), type: 'text',
+      deps: ['proretset'], visible: obj.isVisible,
+      readonly: (state) => {
+        let isReadonly = true;
+        if(state.proretset == true) {
+          isReadonly = false;
+        }
+        return isReadonly;
+      },
+      group: gettext('Options'),
+    },{
+      id: 'proleakproof', label: gettext('Leak proof?'),
+      group: gettext('Options'), cell:'boolean', type: 'switch', min_version: 90200,
+      disabled: (!(this.type === 'procedure')) ? obj.isDisabled: obj.isGreaterThan95,
+      deps: ['lanname'],
+    },{
+      id: 'prosupportfunc', label: gettext('Support function'),
+      type: 'select',
+      disabled: ()=>{
+        if (obj.node_info && 'catalog' in obj.node_info) {
+          return true;
+        }
+
+        if (obj.node_info['node_info'].server.user.is_superuser)
+          return false;
+        return true;
+      },
+      group: gettext('Options'), visible: obj.isVisible,
+      options: this.fieldOptions.getSupportFunctions, min_version: 120000,
+    },{
+      id: 'proacl', label: gettext('Privileges'), type: 'text',
+      mode: ['properties'], group: gettext('Security'),
+    },
+    {
+      id: 'variables', label: '', type: 'collection',
+      group: gettext('Parameters'),
+      schema: this.getNodeVariableSchema(),
+      mode: ['edit', 'create'], canAdd: obj.canVarAdd, canEdit: false,
+      canDelete: true,
+    },
+    {
+      id: 'acl', label: gettext('Privileges'), editable: false,
+      schema: this.getPrivilegeRoleSchema(['X']),
+      uniqueCol : ['grantee', 'grantor'], type: 'collection',
+      group: 'Security', mode: ['edit', 'create'], canAdd: true,
+      canDelete: true,
+      disabled: (!(this.type === 'procedure')) ? obj.isDisabled: obj.isProcedure,
+    },{
+      id: 'seclabels', label: gettext('Security labels'), canAdd: true,
+      schema: new SecLabelSchema(), type: 'collection',
+      min_version: 90100, group: 'Security', mode: ['edit', 'create'],
+      canEdit: false, canDelete: true, uniqueCol : ['provider'],
+      disabled: (!(this.type === 'procedure')) ? obj.isDisabled: obj.isProcedure,
+      visible: function() {
+        return this.node_info && !(this.type === 'procedure');
+      },
+    },
+    ];
+  }
+  validate(state, setError) {
+    let errmsg = null;
+    if (!(this.type === 'procedure') &&(isEmptyString(state.prorettypename))) {
+      errmsg = gettext('Return type cannot be empty.');
+      setError('prorettypename', errmsg);
+      return true;
+    } else {
+      errmsg = null;
+      setError('prorettypename', errmsg);
+    }
+
+    if ((String(state.lanname) == 'c')) {
+      if (isEmptyString(state.probin)){
+        errmsg = gettext('Object File cannot be empty.');
+        setError('probin', errmsg);
+        return true;
+      }else {
+        errmsg = null;
+        setError('probin', errmsg);
+      }
+
+      if (isEmptyString(state.prosrc_c)) {
+        errmsg = gettext('Link Symbol cannot be empty.');
+        setError('prosrc_c', errmsg);
+        return true;
+      }else {
+        errmsg = null;
+        setError('prosrc_c', errmsg);
+      }
+
+    }else {
+      /* code validation*/
+      if (isEmptyString(state.prosrc)) {
+        errmsg = gettext('Code cannot be empty.');
+        setError('prosrc', errmsg);
+        return true;
+      } else {
+        errmsg = null;
+        setError('prosrc', errmsg);
+      }
+    }
+  }
+}
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/procedure.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/procedure.js
index 850e5386b..ad9d9a46f 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/procedure.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/procedure.js
@@ -7,14 +7,20 @@
 //
 //////////////////////////////////////////////////////////////
 
+import { getNodeAjaxOptions, getNodeListByName, getNodeListById} from '../../../../../../../static/js/node_ajax';
+import FunctionSchema from './function.ui';
+import { getNodePrivilegeRoleSchema } from '../../../../../static/js/privilege.ui';
+import { getNodeVariableSchema } from '../../../../../static/js/variable.ui';
+import _ from 'lodash';
+
 /* Create and Register Procedure Collection and Node. */
 define('pgadmin.node.procedure', [
-  'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
+  'sources/gettext', 'jquery', 'underscore',
   'sources/pgadmin', 'pgadmin.browser', 'alertify',
   'pgadmin.node.function', 'pgadmin.node.schema.dir/child',
   'pgadmin.node.schema.dir/schema_child_tree_node',
   'pgadmin.browser.collection', 'pgadmin.browser.server.privilege',
-], function(gettext, url_for, $, _, pgAdmin, pgBrowser, alertify, Function,
+], function(gettext, url_for, $, pgAdmin, pgBrowser, alertify, Function,
   schemaChild, schemaChildTreeNode) {
 
   if (!pgBrowser.Nodes['coll-procedure']) {
@@ -89,6 +95,37 @@ define('pgadmin.node.procedure', [
           )
         );
       },
+      getSchema: function(treeNodeInfo, itemNodeData) {
+        return new FunctionSchema(
+          (privileges)=>getNodePrivilegeRoleSchema(this, treeNodeInfo, itemNodeData, privileges),
+          ()=>getNodeVariableSchema(this, treeNodeInfo, itemNodeData, false, false),
+          {
+            role: ()=>getNodeListByName('role', treeNodeInfo, itemNodeData),
+            schema: ()=>getNodeListById(pgBrowser.Nodes['schema'], treeNodeInfo, itemNodeData, {
+              cacheLevel: 'database'
+            }
+            ),
+            getTypes: ()=>getNodeAjaxOptions('get_types', this, treeNodeInfo, itemNodeData),
+            getLanguage: ()=>getNodeAjaxOptions('get_languages', this, treeNodeInfo, itemNodeData),
+            getSupportFunctions: ()=>getNodeAjaxOptions('get_support_functions', this, treeNodeInfo, itemNodeData, {
+              cacheNode: 'function'
+            }),
+
+          },
+          {
+            node_info: treeNodeInfo,
+          },
+          {
+            type: pgBrowser.Nodes['procedure'].type,
+          },
+          {
+            funcowner: pgBrowser.serverInfo[treeNodeInfo.server._id].user.name,
+            pronamespace: treeNodeInfo.schema ? treeNodeInfo.schema._id : null,
+            lanname: 'edbspl',
+          }
+        );
+      },
+
       model: Function.model.extend({
         defaults: _.extend({},
           Function.model.prototype.defaults,
diff --git a/web/regression/javascript/schema_ui_files/cast.ui.spec.js b/web/regression/javascript/schema_ui_files/cast.ui.spec.js
index 516d9ca4d..7b94fe5f3 100644
--- a/web/regression/javascript/schema_ui_files/cast.ui.spec.js
+++ b/web/regression/javascript/schema_ui_files/cast.ui.spec.js
@@ -70,7 +70,7 @@ describe('CastSchema', ()=>{
       schema={schemaObj}
       getInitData={getInitData}
       viewHelperProps={{
-        mode: 'create',
+        mode: 'edit',
       }}
       onSave={()=>{}}
       onClose={()=>{}}
@@ -99,12 +99,14 @@ describe('CastSchema', ()=>{
 
   it('srctyp depChange', ()=>{
     let depChange = _.find(schemaObj.fields, (f)=>f.id=='srctyp').depChange;
-    depChange({srctyp: 'abc', trgtyp: 'abc'});
+    let status = depChange({srctyp: 'abc', trgtyp: 'abc'});
+    expect(status).toEqual('abc->abc');
   });
 
   it('trgtyp depChange', ()=>{
     let depChange = _.find(schemaObj.fields, (f)=>f.id=='trgtyp').depChange;
-    depChange({srctyp: 'abc', trgtyp: 'abc'});
+    let status = depChange({srctyp: 'abc', trgtyp: 'abc'});
+    expect(status).toEqual('abc->abc');
   });
 
   it('validate', ()=>{
diff --git a/web/regression/javascript/schema_ui_files/functions.ui.spec.js b/web/regression/javascript/schema_ui_files/functions.ui.spec.js
new file mode 100644
index 000000000..e9f78663e
--- /dev/null
+++ b/web/regression/javascript/schema_ui_files/functions.ui.spec.js
@@ -0,0 +1,610 @@
+/////////////////////////////////////////////////////////////
+//
+// 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 BaseUISchema from 'sources/SchemaView/base_schema.ui';
+import FunctionSchema from '../../../pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.ui';
+
+class MockSchema extends BaseUISchema {
+  get baseFields() {
+    return [];
+  }
+}
+
+describe('FunctionSchema', ()=>{
+  let mount;
+  //Procedure schema
+  let procedureSchemaObj = new FunctionSchema(
+    ()=>new MockSchema(),
+    ()=>new MockSchema(),
+    {
+      role: [],
+      schema: [],
+      getLanguage: [],
+      getTypes: [],
+      getSupportFunctions: [],
+    },
+    {
+      node_info: {
+        connected: true,
+        user: {id: 10, name: 'postgres', is_superuser: true, can_create_role: true, can_create_db: true},
+        user_id: 1,
+        user_name: 'postgres',
+        version: 130005,
+        server: {
+          host: '127.0.0.1',
+          port: 5432,
+          server_type: 'postgres',
+          user: {
+            id: 10,
+            name: 'postgres',
+            is_superuser: true,
+            can_create_role: true,
+            can_create_db: true,
+          },
+        }      },
+    },
+    {
+      type: 'procedure',
+    },
+    {
+      funcowner: 'postgres',
+      pronamespace: 'public',
+    }
+  );
+
+
+  let schemaObj = new FunctionSchema(
+    () => new MockSchema(),
+    () => new MockSchema(),
+    {
+      role: [],
+      schema: [],
+      getLanguage: [],
+      getTypes: [],
+      getSupportFunctions: [],
+    },
+    {
+      node_info: {
+        connected: true,
+        user: {
+          id: 10,
+          name: 'postgres',
+          is_superuser: true,
+          can_create_role: true,
+          can_create_db: true,
+        },
+        user_id: 1,
+        user_name: 'postgres',
+        version: 130005,
+        server: {
+          host: '127.0.0.1',
+          port: 5432,
+          server_type: 'postgres',
+          user: {
+            id: 10,
+            name: 'postgres',
+            is_superuser: true,
+            can_create_role: true,
+            can_create_db: true,
+          },
+        },
+      },
+    },
+    {
+      type: 'function',
+    },
+    {
+      funcowner: 'postgres',
+      pronamespace: 'public',
+    }
+  );
+  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={schemaObj}
+      viewHelperProps={{
+        mode: 'create',
+      }}
+      onSave={()=>{}}
+      onClose={()=>{}}
+      onHelp={()=>{}}
+      onEdit={()=>{}}
+      onDataChange={()=>{}}
+      confirmOnCloseReset={false}
+      hasSQL={false}
+      disableSqlHelp={false}
+    />);
+  });
+
+  it('create', ()=>{
+    mount(<SchemaView
+      formType='dialog'
+      schema={procedureSchemaObj}
+      viewHelperProps={{
+        mode: 'create',
+      }}
+      onSave={()=>{}}
+      onClose={()=>{}}
+      onHelp={()=>{}}
+      onEdit={()=>{}}
+      onDataChange={()=>{}}
+      confirmOnCloseReset={false}
+      hasSQL={false}
+      disableSqlHelp={false}
+    />);
+  });
+
+  it('edit', ()=>{
+    mount(<SchemaView
+      formType='dialog'
+      schema={schemaObj}
+      getInitData={getInitData}
+      viewHelperProps={{
+        mode: 'edit',
+      }}
+      onSave={()=>{}}
+      onClose={()=>{}}
+      onHelp={()=>{}}
+      onEdit={()=>{}}
+      onDataChange={()=>{}}
+      confirmOnCloseReset={false}
+      hasSQL={false}
+      disableSqlHelp={false}
+    />);
+  });
+
+  it('properties', ()=>{
+    mount(<SchemaView
+      formType='tab'
+      schema={schemaObj}
+      getInitData={getInitData}
+      viewHelperProps={{
+        mode: 'properties',
+      }}
+      onHelp={()=>{}}
+      onEdit={()=>{}}
+    />);
+  });
+  
+  it('proiswindow visible', ()=>{
+
+    
+    let editSchemaObj = new FunctionSchema(
+      () => new MockSchema(),
+      () => new MockSchema(),
+      {
+        role: [],
+        schema: [],
+        getLanguage: [],
+        getTypes: [],
+        getSupportFunctions: [],
+      },
+      {
+        node_info: {
+          catalog: {},
+          connected: true,
+          user_id: 1,
+          user_name: 'postgres',
+          version: 130005,
+          server: {
+            host: '127.0.0.1',
+            port: 5432,
+            server_type: 'postgres',
+            user: {
+              id: 10,
+              name: 'postgres',
+              is_superuser: true,
+              can_create_role: true,
+              can_create_db: true,
+            },
+          },
+        },
+      },
+      {
+        type: 'function',
+      },
+      {
+        funcowner: 'postgres',
+        pronamespace: 'public',
+      }
+    );
+
+    let initData = ()=>Promise.resolve({
+      sysfunc: true,
+      type: 'function',
+    });
+
+    mount(<SchemaView
+      formType='dialog'
+      schema={editSchemaObj}
+      getInitData={initData}
+      viewHelperProps={{
+        mode: 'edit',
+      }}
+      onSave={()=>{}}
+      onClose={()=>{}}
+      onHelp={()=>{}}
+      onEdit={()=>{}}
+      onDataChange={()=>{}}
+      confirmOnCloseReset={false}
+      hasSQL={false}
+      disableSqlHelp={false}
+    />);
+
+  });
+
+  it('proiswindow visible', ()=>{
+
+    
+    let editSchemaObj = new FunctionSchema(
+      () => new MockSchema(),
+      () => new MockSchema(),
+      {
+        role: [],
+        schema: [],
+        getLanguage: [],
+        getTypes: [],
+        getSupportFunctions: [],
+      },
+      {
+        node_info: {
+          catalog: {},
+          connected: true,
+          user_id: 1,
+          user_name: 'postgres',
+          version: 130005,
+          server: {
+            host: '127.0.0.1',
+            port: 5432,
+            server_type: 'postgres',
+            user: {
+              id: 10,
+              name: 'postgres',
+              is_superuser: true,
+              can_create_role: true,
+              can_create_db: true,
+            },
+          },
+        },
+      },
+      {
+        type: 'function',
+      },
+      {
+        funcowner: 'postgres',
+        pronamespace: 'public',
+      }
+    );
+
+    let initData = ()=>Promise.resolve({
+      sysproc: true,
+      type: 'function',
+    });
+
+    mount(<SchemaView
+      formType='dialog'
+      schema={editSchemaObj}
+      getInitData={initData}
+      viewHelperProps={{
+        mode: 'edit',
+      }}
+      onSave={()=>{}}
+      onClose={()=>{}}
+      onHelp={()=>{}}
+      onEdit={()=>{}}
+      onDataChange={()=>{}}
+      confirmOnCloseReset={false}
+      hasSQL={false}
+      disableSqlHelp={false}
+    />);
+
+  });
+  
+  it('proiswindow visible', ()=>{
+
+    
+    let editSchemaObj = new FunctionSchema(
+      () => new MockSchema(),
+      () => new MockSchema(),
+      {
+        role: [],
+        schema: [],
+        getLanguage: [],
+        getTypes: [],
+        getSupportFunctions: [],
+      },
+      {
+        node_info: {
+          connected: true,
+          user_id: 1,
+          user_name: 'postgres',
+          version: 130005,
+          server: {
+            host: '127.0.0.1',
+            port: 5432,
+            server_type: 'postgres',
+            user: {
+              id: 10,
+              name: 'postgres',
+              is_superuser: true,
+              can_create_role: true,
+              can_create_db: true,
+            },
+          },
+        },
+      },
+      {
+        type: 'procedure',
+      },
+      {
+        funcowner: 'postgres',
+        pronamespace: 'public',
+      }
+    );
+
+    let initData = ()=>Promise.resolve({
+      sysfunc: true,
+      type: 'procedure',
+    });
+
+    mount(<SchemaView
+      formType='dialog'
+      schema={editSchemaObj}
+      getInitData={initData}
+      viewHelperProps={{
+        mode: 'edit',
+      }}
+      onSave={()=>{}}
+      onClose={()=>{}}
+      onHelp={()=>{}}
+      onEdit={()=>{}}
+      onDataChange={()=>{}}
+      confirmOnCloseReset={false}
+      hasSQL={false}
+      disableSqlHelp={false}
+    />);
+  });
+
+  it('proiswindow visible', ()=>{
+
+    
+    let editSchemaObj = new FunctionSchema(
+      () => new MockSchema(),
+      () => new MockSchema(),
+      {
+        role: [],
+        schema: [],
+        getLanguage: [],
+        getTypes: [],
+        getSupportFunctions: [],
+      },
+      {
+        node_info: {
+          connected: true,
+          user_id: 1,
+          user_name: 'postgres',
+          version: 130005,
+          server: {
+            host: '127.0.0.1',
+            port: 5432,
+            server_type: 'postgres',
+            user: {
+              id: 10,
+              name: 'postgres',
+              is_superuser: true,
+              can_create_role: true,
+              can_create_db: true,
+            },
+          },
+        },
+      },
+      {
+        type: 'procedure',
+      },
+      {
+        funcowner: 'postgres',
+        pronamespace: 'public',
+      }
+    );
+
+    let initData = ()=>Promise.resolve({
+      sysproc: true,
+      type: 'procedure',
+    });
+
+    mount(<SchemaView
+      formType='dialog'
+      schema={editSchemaObj}
+      getInitData={initData}
+      viewHelperProps={{
+        mode: 'edit',
+      }}
+      onSave={()=>{}}
+      onClose={()=>{}}
+      onHelp={()=>{}}
+      onEdit={()=>{}}
+      onDataChange={()=>{}}
+      confirmOnCloseReset={false}
+      hasSQL={false}
+      disableSqlHelp={false}
+    />);
+  });
+
+  it('pronamespace disabled', ()=>{
+
+    
+    let editSchemaObj = new FunctionSchema(
+      () => new MockSchema(),
+      () => new MockSchema(),
+      {
+        role: [],
+        schema: [],
+        getLanguage: [],
+        getTypes: [],
+        getSupportFunctions: [],
+      },
+      {
+        node_info: {
+          catalog: {},
+          connected: true,
+          user_id: 1,
+          user_name: 'postgres',
+          version: 130005,
+          server: {
+            host: '127.0.0.1',
+            port: 5432,
+            server_type: 'postgres',
+            user: {
+              id: 10,
+              name: 'postgres',
+              is_superuser: true,
+              can_create_role: true,
+              can_create_db: true,
+            },
+          },
+        },
+      },
+      {
+        type: 'procedure',
+      },
+      {
+        funcowner: 'postgres',
+        pronamespace: 'public',
+      }
+    );
+
+    let initData = ()=>Promise.resolve({
+      sysfunc: true,
+      type: 'procedure',
+    });
+
+    mount(<SchemaView
+      formType='dialog'
+      schema={editSchemaObj}
+      getInitData={initData}
+      viewHelperProps={{
+        mode: 'edit',
+      }}
+      onSave={()=>{}}
+      onClose={()=>{}}
+      onHelp={()=>{}}
+      onEdit={()=>{}}
+      onDataChange={()=>{}}
+      confirmOnCloseReset={false}
+      hasSQL={false}
+      disableSqlHelp={false}
+    />);
+
+  });
+
+  it('probin visible', ()=>{
+    let editable = _.find(schemaObj.fields, (f)=>f.id=='probin').visible;
+    let status = editable({lanname: 'c'});
+    expect(status).toBe(true);
+  });
+
+  it('prosrc_c visible', ()=>{
+    let visibleData = _.find(schemaObj.fields, (f)=>f.id=='prosrc_c').visible;
+    let status = visibleData({lanname: 'c'});
+    expect(status).toBe(true);
+  });
+
+  it('prosrc visible', ()=>{
+    let visibleData = _.find(schemaObj.fields, (f)=>f.id=='prosrc').visible;
+    let status = visibleData({lanname: 'c'});
+    expect(status).toBe(false);
+  });
+
+  it('prorows readonly', ()=>{
+    let readOnly = _.find(schemaObj.fields, (f)=>f.id=='prorows').readonly;
+    let status = readOnly({proretset: true});
+    expect(status).toBe(false);
+  });
+
+  it('prorettypename validate', () => {
+    let state = {lanname: 'c', prorettypename: null};
+    let setError = jasmine.createSpy('setError');
+
+    schemaObj.validate(state, setError);
+    expect(setError).toHaveBeenCalledWith('prorettypename', 'Return type cannot be empty.');
+  });
+
+  it('probin validate', () => {
+    let state = { lanname: 'c', prorettypename: 'char' }; 
+    let setError = jasmine.createSpy('setError');
+
+    schemaObj.validate(state, setError);
+    expect(setError).toHaveBeenCalledWith('probin', 'Object File cannot be empty.');
+  });
+
+  it('probin validate', () => {
+    let state = { lanname: 'c', probin: 'test1', prorettypename: 'char'}; 
+    let setError = jasmine.createSpy('setError');
+
+    schemaObj.validate(state, setError);
+    expect(setError).toHaveBeenCalledWith('probin', null);
+  });
+
+  it('prosrc_c validate', () => {
+    let state = { lanname: 'c',  probin : '$libdir/', prorettypename: 'char'};
+    let setError = jasmine.createSpy('setError');
+
+    schemaObj.validate(state, setError);
+    expect(setError).toHaveBeenCalledWith('prosrc_c', 'Link Symbol cannot be empty.');
+  });
+
+  it('prosrc_c validate', () => {
+    let state = { lanname: 'c',  probin : '$libdir/', prosrc_c: 'test1', prorettypename: 'char'};
+    let setError = jasmine.createSpy('setError');
+
+    schemaObj.validate(state, setError);
+    expect(setError).toHaveBeenCalledWith('prosrc_c', null);
+  });
+
+  it('validate', ()=>{
+    let state = {prorettypename: 'char'};
+    let setError = jasmine.createSpy('setError');
+    state.prosrc = null;
+    schemaObj.validate(state, setError);
+    expect(setError).toHaveBeenCalledWith('prosrc', 'Code cannot be empty.');
+
+    state.prosrc = 'SELECT 1';
+    schemaObj.validate(state, setError);
+    expect(setError).toHaveBeenCalledWith('prosrc', null);
+  });
+
+});
+
diff --git a/web/regression/javascript/schema_ui_files/language.ui.spec.js b/web/regression/javascript/schema_ui_files/language.ui.spec.js
index 8ad431097..026ea7f72 100644
--- a/web/regression/javascript/schema_ui_files/language.ui.spec.js
+++ b/web/regression/javascript/schema_ui_files/language.ui.spec.js
@@ -85,7 +85,7 @@ describe('LanguageSchema', ()=>{
       schema={schemaObj}
       getInitData={getInitData}
       viewHelperProps={{
-        mode: 'create',
+        mode: 'edit',
       }}
       onSave={()=>{}}
       onClose={()=>{}}
diff --git a/web/regression/javascript/schema_ui_files/publication.ui.spec.js b/web/regression/javascript/schema_ui_files/publication.ui.spec.js
index 2471268a6..2bb31cf36 100644
--- a/web/regression/javascript/schema_ui_files/publication.ui.spec.js
+++ b/web/regression/javascript/schema_ui_files/publication.ui.spec.js
@@ -109,12 +109,14 @@ describe('PublicationSchema', ()=>{
 
   it('pubtable disabled', ()=>{
     let disabled = _.find(schemaObj.fields, (f)=>f.id=='pubtable').disabled;
-    disabled({all_table: true});
+    let status = disabled({all_table: true});
+    expect(status).toBe(true);
   });
 
   it('only_table readonly', ()=>{
     let readonly = _.find(schemaObj.fields, (f)=>f.id=='only_table').readonly;
-    readonly({all_table: true});
+    let status = readonly({all_table: true});
+    expect(status).toBe(true);
   });
 
 });
diff --git a/web/regression/javascript/schema_ui_files/subscription.ui.spec.js b/web/regression/javascript/schema_ui_files/subscription.ui.spec.js
index d84d130a7..5d04b5b4c 100644
--- a/web/regression/javascript/schema_ui_files/subscription.ui.spec.js
+++ b/web/regression/javascript/schema_ui_files/subscription.ui.spec.js
@@ -81,7 +81,7 @@ describe('SubscriptionSchema', ()=>{
       schema={schemaObj}
       getInitData={getInitData}
       viewHelperProps={{
-        mode: 'create',
+        mode: 'edit',
       }}
       onSave={()=>{}}
       onClose={()=>{}}
@@ -110,12 +110,14 @@ describe('SubscriptionSchema', ()=>{
 
   it('copy_data_after_refresh readonly', ()=>{
     let isReadonly = _.find(schemaObj.fields, (f)=>f.id=='copy_data_after_refresh').readonly;
-    isReadonly({host: '127.0.0.1', port : 5432});
+    let status = isReadonly({host: '127.0.0.1', port : 5432});
+    expect(status).toBe(true);
   });
 
   it('copy_data_after_refresh readonly', ()=>{
     let isReadonly = _.find(schemaObj.fields, (f)=>f.id=='copy_data_after_refresh').readonly;
-    isReadonly({refresh_pub : true});
+    let status = isReadonly({refresh_pub : true});
+    expect(status).toBe(false);
   });
 
   it('validate', ()=>{
@@ -159,9 +161,5 @@ describe('SubscriptionSchema', ()=>{
     state.tunnel_identity_file = '/file/path/xyz.pem';
     expect(schemaObj.validate(state, setError)).toBeFalse();
   });
-
-
-
-
 });
 
