Port Foreign Data Wrapper, Foreign Server and User Mapping nodes to react. Fixes #6583

This commit is contained in:
Akshay Joshi 2021-07-10 12:59:20 +05:30
parent 79e1b0c5d8
commit 4b8e655948
20 changed files with 705 additions and 355 deletions

View File

@ -46,7 +46,6 @@ export default class EventTriggerSchema extends BaseUISchema {
get baseFields() { get baseFields() {
//let obj = this;
return [ return [
{ {
id: 'name', label: gettext('Name'), cell: 'text', id: 'name', label: gettext('Name'), cell: 'text',

View File

@ -194,72 +194,10 @@ define('pgadmin.node.extension', [
cache_level: 'server', cache_level: 'server',
}, },
{ {
id: 'schema', label: gettext('Schema'), type: 'text',
control: 'node-list-by-name', group: gettext('Definition'),
mode: ['properties', 'create', 'edit'], deps: ['relocatable'],
node: 'schema', first_empty: true,
disabled: function(m) {
/*
* enable or disable schema field if model's relocatable
* attribute is True or False
*/
return (m.has('relocatable') ? !m.get('relocatable') : false);
},
},
{
id: 'relocatable', label: gettext('Relocatable?'), cell: 'switch',
group: gettext('Definition'), type: 'switch', mode: ['properties'],
},
{
id: 'version', label: gettext('Version'), cell: 'string',
mode: ['properties', 'create', 'edit'], group: gettext('Definition'),
control: 'node-ajax-options', url:'avails', first_empty: true,
// Transform the data into version for the selected extension.
transform: function(data, cell) {
var res = [],
control = cell || this,
extension = control.model.get('name');
_.each(data, function(dt) {
if(dt.name == extension) {
if(dt.version && _.isArray(dt.version)) {
_.each(dt.version, function(v) {
res.push({ label: v, value: v });
});
}
}
});
return res;
},
},{
id: 'is_sys_obj', label: gettext('System extension?'),
cell:'boolean', type: 'switch', mode: ['properties'],
},{
id: 'comment', label: gettext('Comment'), cell: 'string', id: 'comment', label: gettext('Comment'), cell: 'string',
type: 'multiline', readonly: true, type: 'multiline', readonly: true,
}, },
], ],
validate: function() {
/*
* Triggers error messages for name
* if it is empty/undefined/null
*/
var err = {},
errmsg,
name = this.get('name');
if (_.isUndefined(name) || _.isNull(name) ||
String(name).replace(/^\s+|\s+$/g, '') == '') {
err['name'] = gettext('Name cannot be empty.');
errmsg = err['name'];
this.errorModel.set('name', errmsg);
return errmsg;
}
else {
this.errorModel.unset('name');
}
return null;
},
}), }),
getSchema: (treeNodeInfo, itemNodeData)=>{ getSchema: (treeNodeInfo, itemNodeData)=>{
let nodeObj = pgAdmin.Browser.Nodes['extension']; let nodeObj = pgAdmin.Browser.Nodes['extension'];

View File

@ -42,6 +42,7 @@ export default class ExtensionsSchema extends BaseUISchema {
id: 'name', label: gettext('Name'), id: 'name', label: gettext('Name'),
mode: ['properties', 'create', 'edit'], mode: ['properties', 'create', 'edit'],
editable: false, editable: false,
noEmpty: true,
readonly: function (state) { readonly: function (state) {
return !obj.isNew(state); return !obj.isNew(state);
}, },
@ -171,4 +172,4 @@ export default class ExtensionsSchema extends BaseUISchema {
return false; return false;
} }
} }

View File

@ -7,45 +7,16 @@
// //
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
import { getNodeListByName } from '../../../../../../../static/js/node_ajax';
import { getNodePrivilegeRoleSchema } from '../../../../../static/js/privilege.ui';
import ForeignServerSchema from './foreign_server.ui';
define('pgadmin.node.foreign_server', [ define('pgadmin.node.foreign_server', [
'sources/gettext', 'jquery', 'underscore', 'sources/pgadmin', 'sources/gettext', 'jquery', 'underscore', 'sources/pgadmin',
'pgadmin.browser', 'pgadmin.backform', 'pgadmin.browser.collection', 'pgadmin.browser', 'pgadmin.backform', 'pgadmin.browser.collection',
'pgadmin.browser.server.privilege', 'pgadmin.browser.server.privilege',
], function(gettext, $, _, pgAdmin, pgBrowser, Backform) { ], function(gettext, $, _, pgAdmin, pgBrowser, Backform) {
// Extend the browser's node model class to create a Options model
var OptionsModel = pgAdmin.Browser.Node.Model.extend({
idAttribute: 'fsrvoption',
defaults: {
fsrvoption: undefined,
fsrvvalue: undefined,
},
// Defining schema for the Options model
schema: [
{id: 'fsrvoption', label: gettext('Options'), type:'text', cellHeaderClasses:'width_percent_50', group: null, editable: true},
{id: 'fsrvvalue', label: gettext('Value'), type: 'text', cellHeaderClasses:'width_percent_50', group:null, editable: true},
],
/* validate function is used to validate the input given by
* the user. In case of error, message will be displayed on
* the browser for the respective control.
*/
validate: function() {
// Validation for the option name
if (_.isUndefined(this.get('fsrvoption')) ||
_.isNull(this.get('fsrvoption')) ||
String(this.get('fsrvoption')).replace(/^\s+|\s+$/g, '') == '') {
var msg = gettext('Please enter an option name.');
this.errorModel.set('fsrvoption', msg);
return msg;
} else {
this.errorModel.unset('fsrvoption');
}
return null;
},
});
// Extend the browser's collection class for foreign server collection // Extend the browser's collection class for foreign server collection
if (!pgBrowser.Nodes['coll-foreign_server']) { if (!pgBrowser.Nodes['coll-foreign_server']) {
pgAdmin.Browser.Nodes['coll-foreign_server'] = pgAdmin.Browser.Nodes['coll-foreign_server'] =
@ -99,20 +70,21 @@ define('pgadmin.node.foreign_server', [
]); ]);
}, },
getSchema: function(treeNodeInfo, itemNodeData) {
return new ForeignServerSchema(
(privileges)=>getNodePrivilegeRoleSchema(this, treeNodeInfo, itemNodeData, privileges),
{
role: ()=>getNodeListByName('role', treeNodeInfo, itemNodeData),
},
{
fsrvowner: pgBrowser.serverInfo[treeNodeInfo.server._id].user.name,
}
);
},
// Defining model for foreign server node // Defining model for foreign server node
model: pgAdmin.Browser.Node.Model.extend({ model: pgAdmin.Browser.Node.Model.extend({
idAttribute: 'oid', idAttribute: 'oid',
defaults: {
name: undefined,
fsrvtype: undefined,
fsrvversion: undefined,
fsrvvalue: undefined,
fsrvoptions: [],
fsrvowner: undefined,
is_sys_obj: undefined,
description: undefined,
fsrvacl: [],
},
// Default values! // Default values!
initialize: function(attrs, args) { initialize: function(attrs, args) {
@ -127,66 +99,26 @@ define('pgadmin.node.foreign_server', [
}, },
// Defining schema for the foreign server node // Defining schema for the foreign server node
schema: [{ schema: [
id: 'name', label: gettext('Name'), cell: 'string', {
type: 'text', disabled: function() { id: 'name', label: gettext('Name'), cell: 'string',
return ( type: 'text', disabled: function() {
this.mode == 'edit' && this.node_info.server.version < 90200 return (
); this.mode == 'edit' && this.node_info.server.version < 90200
);
},
}, {
id: 'oid', label: gettext('OID'), cell: 'string',
type: 'text', mode: ['properties'],
}, {
id: 'fsrvowner', label: gettext('Owner'), type: 'text',
control: Backform.NodeListByNameControl, node: 'role',
mode: ['edit', 'create', 'properties'], select2: { allowClear: false },
}, {
id: 'description', label: gettext('Comment'), cell: 'string',
type: 'multiline',
}, },
},{
id: 'oid', label: gettext('OID'), cell: 'string',
type: 'text', mode: ['properties'],
},{
id: 'fsrvowner', label: gettext('Owner'), type: 'text',
control: Backform.NodeListByNameControl, node: 'role',
mode: ['edit', 'create', 'properties'], select2: { allowClear: false },
},{
id: 'fsrvtype', label: gettext('Type'), cell: 'string',
group: gettext('Definition'), type: 'text', mode: ['edit','create','properties'], disabled: function(m) {
return !m.isNew();
},
},{
id: 'fsrvversion', label: gettext('Version'), cell: 'string',
group: gettext('Definition'), type: 'text',
},{
id: 'is_sys_obj', label: gettext('System foreign server?'),
cell:'boolean', type: 'switch', mode: ['properties'],
},{
id: 'description', label: gettext('Comment'), cell: 'string',
type: 'multiline',
},{
id: 'fsrvoptions', label: gettext('Options'), type: 'collection', group: gettext('Options'),
model: OptionsModel, control: 'unique-col-collection', mode: ['edit', 'create'],
canAdd: true, canDelete: true, uniqueCol : ['fsrvoption'],
columns: ['fsrvoption','fsrvvalue'],
}, pgBrowser.SecurityGroupSchema, {
id: 'fsrvacl', label: gettext('Privileges'), type: 'collection', group: 'security',
model: pgAdmin.Browser.Node.PrivilegeRoleModel.extend({privileges: ['U']}), control: 'unique-col-collection',
mode: ['edit', 'create'], canAdd: true, canDelete: true, uniqueCol : ['grantee'],
},{
id: 'acl', label: gettext('Privileges'), type: 'text',
group: gettext('Security'), mode: ['properties'],
},
], ],
/* validate function is used to validate the input given by
* the user. In case of error, message will be displayed on
* the browser for the respective control.
*/
validate: function() {
var name = this.get('name');
if (_.isUndefined(name) || _.isNull(name) ||
String(name).replace(/^\s+|\s+$/g, '') == '') {
var msg = gettext('Name cannot be empty.');
this.errorModel.set('name', msg);
return msg;
} else {
this.errorModel.unset('name');
}
return null;
},
}), }),
}); });

View File

@ -0,0 +1,86 @@
/////////////////////////////////////////////////////////////
//
// 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 OptionsSchema from '../../../../../static/js/options.ui';
export default class ForeignServerSchema extends BaseUISchema {
constructor(getPrivilegeRoleSchema, fieldOptions={}, initValues) {
super({
name: undefined,
fsrvtype: undefined,
fsrvversion: undefined,
fsrvvalue: undefined,
fsrvoptions: [],
fsrvowner: undefined,
is_sys_obj: undefined,
description: undefined,
fsrvacl: [],
...initValues,
});
this.getPrivilegeRoleSchema = getPrivilegeRoleSchema;
this.fieldOptions = {
role: [],
...fieldOptions,
};
}
get idAttribute() {
return 'oid';
}
get baseFields() {
let obj = this;
return [
{
id: 'name', label: gettext('Name'), cell: 'text',
type: 'text', noEmpty: true,
}, {
id: 'oid', label: gettext('OID'), cell: 'text',
type: 'text', mode: ['properties'],
}, {
id: 'fsrvowner', label: gettext('Owner'),
editable: false, type: 'select', options: this.fieldOptions.role,
controlProps: { allowClear: false },
}, {
id: 'is_sys_obj', label: gettext('System foreign server?'),
cell:'boolean', type: 'switch', mode: ['properties'],
}, {
id: 'description', label: gettext('Comment'), cell: 'text',
type: 'multiline',
}, {
id: 'fsrvtype', label: gettext('Type'),
type: 'text', group: gettext('Definition'),
readonly: function(state) {return !obj.isNew(state); },
}, {
id: 'fsrvversion', label: gettext('Version'),
type: 'text', group: gettext('Definition'),
}, {
id: 'fsrvoptions', label: gettext('Options'), type: 'collection',
schema: new OptionsSchema('fsrvoption', 'fsrvvalue'),
group: gettext('Options'),
mode: ['edit', 'create'],
canAdd: true, canDelete: true, uniqueCol : ['fsrvoption'],
}, {
id: 'security', label: gettext('Security'), type: 'group',
}, {
id: 'fsrvacl', label: gettext('Privileges'), type: 'collection',
schema: this.getPrivilegeRoleSchema(['U']),
uniqueCol : ['grantee'],
editable: false,
group: gettext('Security'), mode: ['edit', 'create'],
canAdd: true, canDelete: true,
}, {
id: 'acl', label: gettext('Privileges'), type: 'text',
group: gettext('Security'), mode: ['properties'],
}
];
}
}

View File

@ -7,48 +7,15 @@
// //
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
import { getNodeListByName } from '../../../../../../../../static/js/node_ajax';
import UserMappingSchema from './user_mapping.ui';
define('pgadmin.node.user_mapping', [ define('pgadmin.node.user_mapping', [
'sources/gettext', 'sources/url_for', 'jquery', 'underscore', 'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
'sources/pgadmin', 'pgadmin.browser', 'sources/pgadmin', 'pgadmin.browser',
'pgadmin.backform', 'pgadmin.browser.collection', 'pgadmin.backform', 'pgadmin.browser.collection',
], function(gettext, url_for, $, _, pgAdmin, pgBrowser, Backform) { ], function(gettext, url_for, $, _, pgAdmin, pgBrowser, Backform) {
// Extend the browser's node model class to create a Options model
var OptionsModel = pgAdmin.Browser.Node.Model.extend({
idAttribute: 'umoption',
defaults: {
umoption: undefined,
umvalue: undefined,
},
// Defining schema for the Options model
schema: [{
id: 'umoption', label: gettext('Options'), type:'text',
cellHeaderClasses:'width_percent_50', group: null, editable: true,
}, {
id: 'umvalue', label: gettext('Value'), type: 'text',
cellHeaderClasses:'width_percent_50', group:null, editable: true,
}],
/* validate function is used to validate the input given by
* the user. In case of error, message will be displayed on
* the browser for the respective control.
*/
validate: function() {
// Validation for the option value
if (_.isUndefined(this.get('umoption')) ||
_.isNull(this.get('umoption')) ||
String(this.get('umoption')).replace(/^\s+|\s+$/g, '') == '') {
var msg = gettext('Please enter an option name.');
this.errorModel.set('umoption', msg);
return msg;
} else {
this.errorModel.unset('umoption');
}
return null;
},
});
// Extend the browser's collection class for user mapping collection // Extend the browser's collection class for user mapping collection
if (!pgBrowser.Nodes['coll-user_mapping']) { if (!pgBrowser.Nodes['coll-user_mapping']) {
pgAdmin.Browser.Nodes['coll-user_mapping'] = pgAdmin.Browser.Nodes['coll-user_mapping'] =
@ -103,14 +70,28 @@ define('pgadmin.node.user_mapping', [
]); ]);
}, },
getSchema: function(treeNodeInfo, itemNodeData) {
return new UserMappingSchema(
{
role: ()=>getNodeListByName('role', treeNodeInfo, itemNodeData, {}, ()=>true, (res)=>{
res.unshift({
label: 'CURRENT_USER', value: 'CURRENT_USER',
image: 'icon-role',
},{
label: 'PUBLIC', value: 'PUBLIC', image: 'icon-role',
});
return res;
})
},
{
name: pgBrowser.serverInfo[treeNodeInfo.server._id].user.name,
}
);
},
// Defining model for user mapping node // Defining model for user mapping node
model: pgAdmin.Browser.Node.Model.extend({ model: pgAdmin.Browser.Node.Model.extend({
idAttribute: 'um_oid', idAttribute: 'oid',
defaults: {
name: undefined,
is_sys_obj: undefined,
um_options: [],
},
// Default values! // Default values!
initialize: function(attrs, args) { initialize: function(attrs, args) {
@ -125,56 +106,32 @@ define('pgadmin.node.user_mapping', [
}, },
// Defining schema for the user mapping node // Defining schema for the user mapping node
schema: [{ schema: [
id: 'name', label: gettext('User'), type: 'text', {
control: Backform.NodeListByNameControl, node: 'role', id: 'name', label: gettext('User'), type: 'text',
mode: ['edit', 'create', 'properties'], select2: { allowClear: false }, control: Backform.NodeListByNameControl, node: 'role',
disabled: function(m) { return !m.isNew(); }, mode: ['edit', 'create', 'properties'], select2: { allowClear: false },
transform: function() { disabled: function(m) { return !m.isNew(); },
var self = this, transform: function() {
node = self.field.get('schema_node'); var self = this,
var res = node = self.field.get('schema_node');
Backform.NodeListByNameControl.prototype.defaults.transform.apply( var res =
this, arguments Backform.NodeListByNameControl.prototype.defaults.transform.apply(
); this, arguments
res.unshift({ );
label: 'CURRENT_USER', value: 'CURRENT_USER', res.unshift({
image: 'icon-' + node.type, label: 'CURRENT_USER', value: 'CURRENT_USER',
},{ image: 'icon-' + node.type,
label: 'PUBLIC', value: 'PUBLIC', image: 'icon-' + node.type, },{
}); label: 'PUBLIC', value: 'PUBLIC', image: 'icon-' + node.type,
return res; });
}, return res;
},{ },
id: 'um_oid', label: gettext('OID'), cell: 'string', }, {
type: 'text', mode: ['properties'], id: 'oid', label: gettext('OID'), cell: 'string',
}, { type: 'text', mode: ['properties'],
id: 'is_sys_obj', label: gettext('System user mapping?'),
cell:'boolean', type: 'switch', mode: ['properties'],
},{
id: 'umoptions', label: gettext('Options'), type: 'collection', group: gettext('Options'),
model: OptionsModel, control: 'unique-col-collection', mode: ['create', 'edit'],
canAdd: true, canDelete: true, uniqueCol : ['umoption'],
},
],
/* validate function is used to validate the input given by
* the user. In case of error, message will be displayed on
* the browser for the respective control.
*/
validate: function() {
var name = this.get('name');
if (_.isUndefined(name) || _.isNull(name) ||
String(name).replace(/^\s+|\s+$/g, '') == '') {
var msg = gettext('Name cannot be empty.');
this.errorModel.set('name', msg);
return msg;
} else {
this.errorModel.unset('name');
} }
return null; ],
},
}), }),
}); });

View File

@ -0,0 +1,56 @@
/////////////////////////////////////////////////////////////
//
// 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 OptionsSchema from '../../../../../../static/js/options.ui';
export default class UserMappingSchema extends BaseUISchema {
constructor(fieldOptions={}, initValues) {
super({
name: undefined,
is_sys_obj: undefined,
um_options: [],
...initValues,
});
this.fieldOptions = {
role: [],
...fieldOptions,
};
}
get idAttribute() {
return 'oid';
}
get baseFields() {
let obj = this;
return [
{
id: 'name', label: gettext('User'), type: 'select',
options: this.fieldOptions.role,
controlProps: { allowClear: false },
readonly: function(state) {return !obj.isNew(state); },
mode: ['edit', 'create', 'properties']
}, {
id: 'oid', label: gettext('OID'), cell: 'text',
type: 'text', mode: ['properties'],
}, {
id: 'is_sys_obj', label: gettext('System user mapping?'),
cell:'boolean', type: 'switch', mode: ['properties'],
}, {
id: 'umoptions', label: gettext('Options'), type: 'collection',
schema: new OptionsSchema('umoption', 'umvalue'),
group: gettext('Options'),
mode: ['edit', 'create'],
canAdd: true, canDelete: true, uniqueCol : ['umoption'],
}
];
}
}

View File

@ -7,46 +7,16 @@
// //
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
import { getNodeAjaxOptions, getNodeListByName } from '../../../../../../static/js/node_ajax';
import { getNodePrivilegeRoleSchema } from '../../../../static/js/privilege.ui';
import ForeignDataWrapperSchema from './foreign_data_wrapper.ui';
define('pgadmin.node.foreign_data_wrapper', [ define('pgadmin.node.foreign_data_wrapper', [
'sources/gettext', 'sources/url_for', 'jquery', 'underscore', 'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform', 'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform',
'pgadmin.browser.collection', 'pgadmin.browser.server.privilege', 'pgadmin.browser.collection', 'pgadmin.browser.server.privilege',
], function(gettext, url_for, $, _, pgAdmin, pgBrowser, Backform) { ], function(gettext, url_for, $, _, pgAdmin, pgBrowser, Backform) {
// Extend the browser's node model class to create a Options model
var OptionsModel = pgBrowser.Node.Model.extend({
idAttribute: 'fdwoption',
defaults: {
fdwoption: undefined,
fdwvalue: undefined,
},
// Defining schema for the Options model
schema: [{
id: 'fdwoption', label: gettext('Option'), type:'text',
cellHeaderClasses:'width_percent_50', editable: true,
},{
id: 'fdwvalue', label: gettext('Value'), type: 'text',
cellHeaderClasses:'width_percent_50', group:null, editable: true,
}],
/* validate function is used to validate the input given by
* the user. In case of error, message will be displayed on
* the browser for the respective control.
*/
validate: function() {
// Validation for the option name
if (_.isUndefined(this.get('fdwoption')) ||
_.isNull(this.get('fdwoption')) ||
String(this.get('fdwoption')).replace(/^\s+|\s+$/g, '') == '') {
var msg = gettext('Please enter an option name.');
this.errorModel.set('fdwoption', msg);
return msg;
} else {
this.errorModel.unset('fdwoption');
}
return null;
},
});
// Extend the browser's collection class for foreign data wrapper collection // Extend the browser's collection class for foreign data wrapper collection
if (!pgBrowser.Nodes['coll-foreign_data_wrapper']) { if (!pgBrowser.Nodes['coll-foreign_data_wrapper']) {
pgBrowser.Nodes['coll-foreign_data_wrapper'] = pgBrowser.Nodes['coll-foreign_data_wrapper'] =
@ -102,19 +72,25 @@ define('pgadmin.node.foreign_data_wrapper', [
]); ]);
}, },
getSchema: function(treeNodeInfo, itemNodeData) {
return new ForeignDataWrapperSchema(
(privileges)=>getNodePrivilegeRoleSchema(this, treeNodeInfo, itemNodeData, privileges),
{
role: ()=>getNodeListByName('role', treeNodeInfo, itemNodeData),
fdwhan:
()=>getNodeAjaxOptions('get_handlers', this, treeNodeInfo, itemNodeData),
fdwvalue:
()=>getNodeAjaxOptions('get_validators', this, treeNodeInfo, itemNodeData),
},
{
fdwowner: pgBrowser.serverInfo[treeNodeInfo.server._id].user.name,
}
);
},
// Defining model for foreign data wrapper node // Defining model for foreign data wrapper node
model: pgBrowser.Node.Model.extend({ model: pgBrowser.Node.Model.extend({
idAttribute: 'oid', idAttribute: 'oid',
defaults: {
name: undefined,
fdwowner: undefined,
is_sys_obj: undefined,
comment: undefined,
fdwvalue: undefined,
fdwhan: undefined,
fdwoption: undefined,
fdwacl: [],
},
// Default values! // Default values!
initialize: function(attrs, args) { initialize: function(attrs, args) {
@ -137,60 +113,17 @@ define('pgadmin.node.foreign_data_wrapper', [
this.mode == 'edit' this.mode == 'edit'
); );
}, },
},{ }, {
id: 'oid', label: gettext('OID'), cell: 'string', id: 'oid', label: gettext('OID'), cell: 'string',
type: 'text', mode: ['properties'], type: 'text', mode: ['properties'],
},{ }, {
id: 'fdwowner', label: gettext('Owner'), type: 'text', id: 'fdwowner', label: gettext('Owner'), type: 'text',
control: Backform.NodeListByNameControl, node: 'role', control: Backform.NodeListByNameControl, node: 'role',
mode: ['edit', 'create', 'properties'], select2: { allowClear: false }, mode: ['edit', 'create', 'properties'], select2: { allowClear: false },
},{ }, {
id: 'fdwhan', label: gettext('Handler'), type: 'text', control: 'node-ajax-options',
group: gettext('Definition'), mode: ['edit', 'create', 'properties'], url:'get_handlers',
},{
id: 'is_sys_obj', label: gettext('System foreign data wrapper?'),
cell:'boolean', type: 'switch', mode: ['properties'],
},{
id: 'description', label: gettext('Comment'), cell: 'string', id: 'description', label: gettext('Comment'), cell: 'string',
type: 'multiline', type: 'multiline',
},{
id: 'fdwoptions', label: gettext('Options'), type: 'collection', group: gettext('Options'),
model: OptionsModel, control: 'unique-col-collection', mode: ['edit', 'create'],
canAdd: true, canDelete: true, uniqueCol : ['fdwoption'],
columns: ['fdwoption','fdwvalue'],
},{
id: 'fdwvalue', label: gettext('Validator'), type: 'text', control: 'node-ajax-options',
group: gettext('Definition'), mode: ['edit', 'create', 'properties'], url:'get_validators',
},{
id: 'security', label: gettext('Security'), type: 'group',
},{
id: 'fdwacl', label: gettext('Privileges'), type: 'collection',
group: 'security', mode: ['edit', 'create'], canAdd: true,
canDelete: true, uniqueCol : ['grantee'],
model: pgBrowser.Node.PrivilegeRoleModel.extend({
privileges: ['U'],
}), control: 'unique-col-collection',
},{
id: 'acl', label: gettext('Privileges'), type: 'text',
group: gettext('Security'), mode: ['properties'],
}], }],
/* validate function is used to validate the input given by
* the user. In case of error, message will be displayed on
* the browser for the respective control.
*/
validate: function() {
var name = this.get('name');
if (_.isUndefined(name) || _.isNull(name) ||
String(name).replace(/^\s+|\s+$/g, '') == '') {
var msg = gettext('Name cannot be empty.');
this.errorModel.set('name', msg);
return msg;
} else {
this.errorModel.unset('name');
}
return null;
},
}), }),
}); });
} }

View File

@ -0,0 +1,91 @@
/////////////////////////////////////////////////////////////
//
// 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 OptionsSchema from '../../../../static/js/options.ui';
export default class ForeignDataWrapperSchema extends BaseUISchema {
constructor(getPrivilegeRoleSchema, fieldOptions={}, initValues) {
super({
name: undefined,
fdwowner: undefined,
is_sys_obj: undefined,
comment: undefined,
fdwvalue: undefined,
fdwhan: undefined,
fdwoption: undefined,
fdwacl: [],
...initValues,
});
this.getPrivilegeRoleSchema = getPrivilegeRoleSchema;
this.fieldOptions = {
role: [],
fdwhan: [],
fdwvalue: [],
...fieldOptions,
};
}
get idAttribute() {
return 'oid';
}
get baseFields() {
let obj = this;
return [
{
id: 'name', label: gettext('Name'), cell: 'text',
type: 'text', noEmpty: true,
readonly: function(state) {return !obj.isNew(state); },
}, {
id: 'oid', label: gettext('OID'), cell: 'text',
type: 'text', mode: ['properties'],
}, {
id: 'fdwowner', label: gettext('Owner'),
editable: false, type: 'select', options: this.fieldOptions.role,
controlProps: { allowClear: false },
}, {
id: 'is_sys_obj', label: gettext('System foreign data wrapper?'),
cell:'boolean', type: 'switch', mode: ['properties'],
}, {
id: 'description', label: gettext('Comment'), cell: 'text',
type: 'multiline',
}, {
id: 'fdwhan', label: gettext('Handler'),
editable: false, type: 'select', group: gettext('Definition'),
options: this.fieldOptions.fdwhan,
mode: ['edit', 'create', 'properties'],
}, {
id: 'fdwvalue', label: gettext('Validator'),
editable: false, type: 'select', group: gettext('Definition'),
options: this.fieldOptions.fdwvalue,
mode: ['edit', 'create', 'properties'],
}, {
id: 'fdwoptions', label: gettext('Options'), type: 'collection',
schema: new OptionsSchema('fdwoption', 'fdwvalue'),
group: gettext('Options'),
mode: ['edit', 'create'],
canAdd: true, canDelete: true, uniqueCol : ['fdwoption'],
}, {
id: 'security', label: gettext('Security'), type: 'group',
}, {
id: 'fdwacl', label: gettext('Privileges'), type: 'collection',
schema: this.getPrivilegeRoleSchema(['U']),
uniqueCol : ['grantee'],
editable: false,
group: gettext('Security'), mode: ['edit', 'create'],
canAdd: true, canDelete: true,
}, {
id: 'acl', label: gettext('Privileges'), type: 'text',
group: gettext('Security'), mode: ['properties'],
}
];
}
}

View File

@ -0,0 +1,35 @@
/////////////////////////////////////////////////////////////
//
// 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 OptionsSchema extends BaseUISchema {
constructor(optionID='option', valueID='value') {
super({
[optionID]: undefined,
[valueID]: undefined,
});
this.optionID = optionID;
this.valueID = valueID;
}
get baseFields() {
return [{
id: this.optionID, label: gettext('Option'),
type: 'text', editable: true, cell: 'text',
noEmpty: true, width: 220,
},
{
id: this.valueID, label: gettext('Value'),
type: 'text', editable: true, cell: 'text',
noEmpty: true, width: 220
}];
}
}

View File

@ -55,7 +55,7 @@ export default class PrivilegeRoleSchema extends BaseUISchema {
type: 'text', group: null, type: 'text', group: null,
cell: ()=>({cell: 'privilege', controlProps: { cell: ()=>({cell: 'privilege', controlProps: {
supportedPrivs: this.supportedPrivs, supportedPrivs: this.supportedPrivs,
}}), minWidth: 280, }}), minWidth: 230,
disabled : function(state) { disabled : function(state) {
return !( return !(
obj.nodeInfo && obj.nodeInfo &&

View File

@ -186,7 +186,7 @@ export const InputText = forwardRef(({
changeVal = controlProps.formatter.toRaw(changeVal); changeVal = controlProps.formatter.toRaw(changeVal);
} }
onChange && onChange(changeVal); onChange && onChange(changeVal);
} };
let finalValue = (_.isNull(value) || _.isUndefined(value)) ? '' : value; let finalValue = (_.isNull(value) || _.isUndefined(value)) ? '' : value;
if(controlProps?.formatter) { if(controlProps?.formatter) {
@ -562,7 +562,7 @@ function getRealValue(options, value, creatable, formatter) {
} }
export function InputSelect({ export function InputSelect({
cid, onChange, options, readonly=false, value, controlProps={}, optionsLoaded, optionsReloadBasis, disabled, ...props}) { cid, onChange, options, readonly=false, value, controlProps={}, optionsLoaded, optionsReloadBasis, disabled, ...props}) {
const [[finalOptions, isLoading], setFinalOptions] = useState([[], true]); const [[finalOptions, isLoading], setFinalOptions] = useState([[], true]);
const theme = useTheme(); const theme = useTheme();

View File

@ -96,7 +96,6 @@ describe('FormComponents', ()=>{
expect(ctrl.find(OutlinedInput).prop('readOnly')).toBe(true); expect(ctrl.find(OutlinedInput).prop('readOnly')).toBe(true);
expect(ctrl.find(OutlinedInput).prop('disabled')).toBe(true); expect(ctrl.find(OutlinedInput).prop('disabled')).toBe(true);
expect(ctrl.find(OutlinedInput).prop('value')).toBe('new value'); expect(ctrl.find(OutlinedInput).prop('value')).toBe('new value');
expect(ctrl.find(OutlinedInput).prop('onChange')).toBe(onChange);
}); });
it('accessibility', ()=>{ it('accessibility', ()=>{

View File

@ -86,7 +86,7 @@ describe('DatabaseSchema', ()=>{
schema={schemaObj} schema={schemaObj}
getInitData={getInitData} getInitData={getInitData}
viewHelperProps={{ viewHelperProps={{
mode: 'create', mode: 'edit',
}} }}
onSave={()=>{}} onSave={()=>{}}
onClose={()=>{}} onClose={()=>{}}

View File

@ -72,7 +72,7 @@ describe('EventTriggerSchema', ()=>{
schema={schemaObj} schema={schemaObj}
getInitData={getInitData} getInitData={getInitData}
viewHelperProps={{ viewHelperProps={{
mode: 'create', mode: 'edit',
}} }}
onSave={()=>{}} onSave={()=>{}}
onClose={()=>{}} onClose={()=>{}}

View File

@ -69,7 +69,7 @@ describe('ExtensionSchema', ()=>{
schema={schemaObj} schema={schemaObj}
getInitData={getInitData} getInitData={getInitData}
viewHelperProps={{ viewHelperProps={{
mode: 'create', mode: 'edit',
}} }}
onSave={()=>{}} onSave={()=>{}}
onClose={()=>{}} onClose={()=>{}}

View File

@ -0,0 +1,109 @@
/////////////////////////////////////////////////////////////
//
// 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 ForeignDataWrapperSchema from '../../../pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/static/js/foreign_data_wrapper.ui';
class MockSchema extends BaseUISchema {
get baseFields() {
return [];
}
}
describe('ForeignDataWrapperSchema', ()=>{
let mount;
let schemaObj = new ForeignDataWrapperSchema(
()=>new MockSchema(),
{
role: ()=>[],
fdwhan: ()=>[],
fdwvalue: ()=>[],
},
{
fdwowner: 'postgres'
}
);
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('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={()=>{}}
/>);
});
});

View File

@ -0,0 +1,107 @@
/////////////////////////////////////////////////////////////
//
// 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 ForeignServerSchema from '../../../pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/foreign_servers/static/js/foreign_server.ui';
class MockSchema extends BaseUISchema {
get baseFields() {
return [];
}
}
describe('ForeignServerSchema', ()=>{
let mount;
let schemaObj = new ForeignServerSchema(
()=>new MockSchema(),
{
role: ()=>[],
},
{
fsrvowner: 'postgres'
}
);
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('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={()=>{}}
/>);
});
});

View File

@ -72,7 +72,7 @@ describe('PrivilegeSchema', ()=>{
schema={schemaObj} schema={schemaObj}
getInitData={getInitData} getInitData={getInitData}
viewHelperProps={{ viewHelperProps={{
mode: 'create', mode: 'edit',
}} }}
onSave={()=>{}} onSave={()=>{}}
onClose={()=>{}} onClose={()=>{}}

View File

@ -0,0 +1,107 @@
/////////////////////////////////////////////////////////////
//
// 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 UserMappingSchema from '../../../pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/foreign_servers/user_mappings/static/js/user_mapping.ui';
class MockSchema extends BaseUISchema {
get baseFields() {
return [];
}
}
describe('UserMappingSchema', ()=>{
let mount;
let schemaObj = new UserMappingSchema(
()=>new MockSchema(),
{
role: ()=>[],
},
{
name: 'postgres'
}
);
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('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={()=>{}}
/>);
});
});