Port Domain and Domain Constraints node to react. Fixes #6330
parent
438d591d5b
commit
6d18842dd3
|
@ -7,6 +7,8 @@
|
|||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
import DomainConstraintSchema from './domain_constraints.ui';
|
||||
|
||||
// Domain Constraint Module: Collection and Node
|
||||
define('pgadmin.node.domain_constraints', [
|
||||
'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
|
||||
|
@ -69,47 +71,19 @@ define('pgadmin.node.domain_constraints', [
|
|||
|
||||
},
|
||||
canDrop: schemaChildTreeNode.isTreeItemOfChildOfSchema,
|
||||
|
||||
getSchema: function() {
|
||||
return new DomainConstraintSchema();
|
||||
},
|
||||
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
defaults: {
|
||||
name: undefined,
|
||||
oid: undefined,
|
||||
description: undefined,
|
||||
consrc: undefined,
|
||||
connoinherit: undefined,
|
||||
convalidated: true,
|
||||
},
|
||||
// Domain Constraint Schema
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), type:'text', cell:'string',
|
||||
},{
|
||||
id: 'oid', label: gettext('OID'), cell: 'string',
|
||||
type: 'text' , mode: ['properties'],
|
||||
},{
|
||||
id: 'is_sys_obj', label: gettext('System domain constraint?'),
|
||||
cell:'boolean', type: 'switch', mode: ['properties'],
|
||||
},{
|
||||
id: 'description', label: gettext('Comment'), type: 'multiline', cell:
|
||||
'string', mode: ['properties', 'create', 'edit'], min_version: 90500,
|
||||
},{
|
||||
id: 'consrc', label: gettext('Check'), type: 'multiline', cel:
|
||||
'string', group: gettext('Definition'), mode: ['properties',
|
||||
'create', 'edit'], readonly: function(m) { return !m.isNew(); },
|
||||
},{
|
||||
id: 'connoinherit', label: gettext('No inherit?'), type:
|
||||
'switch', cell: 'boolean', group: gettext('Definition'), mode:
|
||||
['properties', 'create', 'edit'],
|
||||
visible: false,
|
||||
},{
|
||||
id: 'convalidated', label: gettext('Validate?'), type: 'switch', cell:
|
||||
'boolean', group: gettext('Definition'), min_version: 90200,
|
||||
disabled: function(m) {
|
||||
if (!m.isNew() && m.get('convalidated')) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
mode: ['properties', 'create', 'edit'],
|
||||
}],
|
||||
// Client Side Validation
|
||||
validate: function() {
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 DomainConstraintSchema extends BaseUISchema {
|
||||
constructor(initValues) {
|
||||
super({
|
||||
name: undefined,
|
||||
oid: undefined,
|
||||
description: undefined,
|
||||
consrc: undefined,
|
||||
convalidated: true,
|
||||
...initValues,
|
||||
});
|
||||
}
|
||||
|
||||
get idAttribute() {
|
||||
return 'oid';
|
||||
}
|
||||
|
||||
get baseFields() {
|
||||
let obj = this;
|
||||
return [
|
||||
{
|
||||
id: 'name', label: gettext('Name'), type:'text', cell:'text',
|
||||
noEmpty: true,
|
||||
}, {
|
||||
id: 'oid', label: gettext('OID'), cell: 'text',
|
||||
type: 'text' , mode: ['properties'],
|
||||
}, {
|
||||
id: 'is_sys_obj', label: gettext('System domain constraint?'),
|
||||
cell:'boolean', type: 'switch', mode: ['properties'],
|
||||
}, {
|
||||
id: 'description', label: gettext('Comment'), type: 'multiline', cell:
|
||||
'text', mode: ['properties', 'create', 'edit'], min_version: 90500,
|
||||
}, {
|
||||
id: 'consrc', label: gettext('Check'), type: 'multiline',
|
||||
group: gettext('Definition'), mode: ['properties', 'create', 'edit'],
|
||||
readonly: function(state) {return !obj.isNew(state); },
|
||||
noEmpty: true,
|
||||
}, {
|
||||
id: 'convalidated', label: gettext('Validate?'), type: 'switch',
|
||||
cell:'boolean', group: gettext('Definition'), min_version: 90200,
|
||||
mode: ['properties', 'create', 'edit'],
|
||||
readonly: function(state) {
|
||||
if (!obj.isNew(state) && obj._origData.convalidated) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
|
@ -7,6 +7,9 @@
|
|||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
import { getNodeAjaxOptions, getNodeListByName } from '../../../../../../../static/js/node_ajax';
|
||||
import DomainSchema from './domain.ui';
|
||||
|
||||
// Domain Module: Collection and Node.
|
||||
define('pgadmin.node.domain', [
|
||||
'sources/gettext', 'sources/url_for', 'jquery', 'underscore', 'backbone',
|
||||
|
@ -31,65 +34,6 @@ define('pgadmin.node.domain', [
|
|||
});
|
||||
}
|
||||
|
||||
// Constraint Model
|
||||
var ConstraintModel = pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'conoid',
|
||||
initialize: function(attrs) {
|
||||
if (_.size(attrs) !== 0) {
|
||||
this.convalidated_default = this.get('convalidated');
|
||||
}
|
||||
pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
defaults: {
|
||||
conoid: undefined,
|
||||
conname: undefined,
|
||||
consrc: undefined,
|
||||
convalidated: true,
|
||||
},
|
||||
convalidated_default: true,
|
||||
schema: [{
|
||||
id: 'conoid', type: 'text', cell: 'string', visible: false,
|
||||
},{
|
||||
id: 'conname', label: gettext('Name'), type: 'text', cell: 'string',
|
||||
cellHeaderClasses: 'width_percent_40',
|
||||
editable: function(m) {
|
||||
if (_.isUndefined(m.isNew)) { return true; }
|
||||
if (!m.isNew()) {
|
||||
var server = this.get('node_info').server;
|
||||
if (server.version < 90200) { return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
},{
|
||||
id: 'consrc', label: gettext('Check'), type: 'multiline',
|
||||
cell: Backgrid.Extension.TextareaCell, group: gettext('Definition'),
|
||||
cellHeaderClasses: 'width_percent_60', editable: function(m) {
|
||||
return _.isUndefined(m.isNew) ? true : m.isNew();
|
||||
},
|
||||
},{
|
||||
id: 'convalidated', label: gettext('Validate?'), type: 'switch', cell:
|
||||
'boolean', group: gettext('Definition'),
|
||||
editable: function(m) {
|
||||
var server = this.get('node_info').server;
|
||||
if (server.version < 90200) { return false;
|
||||
}
|
||||
if (_.isUndefined(m.isNew)) { return true; }
|
||||
if (!m.isNew()) {
|
||||
if(m.get('convalidated') && m.convalidated_default) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
}],
|
||||
toJSON: Backbone.Model.prototype.toJSON,
|
||||
validate: function() {
|
||||
return null;
|
||||
},
|
||||
});
|
||||
|
||||
// Domain Node
|
||||
if (!pgBrowser.Nodes['domain']) {
|
||||
pgBrowser.Nodes['domain'] = schemaChild.SchemaChildNode.extend({
|
||||
|
@ -130,6 +74,31 @@ define('pgadmin.node.domain', [
|
|||
]);
|
||||
|
||||
},
|
||||
|
||||
getSchema: function(treeNodeInfo, itemNodeData) {
|
||||
return new DomainSchema(
|
||||
{
|
||||
role: ()=>getNodeListByName('role', treeNodeInfo, itemNodeData),
|
||||
schema: ()=>getNodeListByName('schema', treeNodeInfo, itemNodeData, {
|
||||
cacheLevel: 'database',
|
||||
cacheNode: 'database'
|
||||
}),
|
||||
basetype: ()=>getNodeAjaxOptions('get_types', this, treeNodeInfo, itemNodeData, {
|
||||
cacheNode: 'type'
|
||||
}),
|
||||
collation: ()=>getNodeAjaxOptions('get_collations', this, treeNodeInfo, itemNodeData, {
|
||||
cacheLevel: 'database',
|
||||
cacheNode: 'schema'
|
||||
}),
|
||||
},
|
||||
{
|
||||
owner: pgBrowser.serverInfo[treeNodeInfo.server._id].user.name,
|
||||
schema: itemNodeData.label,
|
||||
basensp: itemNodeData.label,
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
// Domain Node Model
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
|
@ -146,23 +115,6 @@ define('pgadmin.node.domain', [
|
|||
}
|
||||
pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
defaults: {
|
||||
name: undefined,
|
||||
oid: undefined,
|
||||
owner: undefined,
|
||||
basensp: undefined,
|
||||
description: undefined,
|
||||
basetype: undefined,
|
||||
typlen: undefined,
|
||||
precision: undefined,
|
||||
typdefault: undefined,
|
||||
typnotnull: undefined,
|
||||
sysdomain: undefined,
|
||||
collname: undefined,
|
||||
constraints: [],
|
||||
seclabels: [],
|
||||
},
|
||||
type_options: undefined,
|
||||
// Domain Schema
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), cell: 'string',
|
||||
|
@ -173,141 +125,10 @@ define('pgadmin.node.domain', [
|
|||
},{
|
||||
id: 'owner', label: gettext('Owner'), cell: 'string', control: Backform.NodeListByNameControl,
|
||||
node: 'role', type: 'text', mode: ['edit', 'create', 'properties'],
|
||||
},{
|
||||
id: 'basensp', label: gettext('Schema'), cell: 'node-list-by-name',
|
||||
control: 'node-list-by-name', cache_level: 'database', type: 'text',
|
||||
node: 'schema', mode: ['create', 'edit'],
|
||||
},{
|
||||
id: 'sysdomain', label: gettext('System domain?'), cell: 'boolean',
|
||||
type: 'switch', mode: ['properties'],
|
||||
},{
|
||||
id: 'description', label: gettext('Comment'), cell: 'string',
|
||||
type: 'multiline',
|
||||
},{
|
||||
id: 'basetype', label: gettext('Base type'), cell: 'string',
|
||||
control: 'node-ajax-options', type: 'text', url: 'get_types',
|
||||
mode:['properties', 'create', 'edit'], group: gettext('Definition'),
|
||||
first_empty: true, cache_node: 'type',
|
||||
readonly: function(m) {
|
||||
return !m.isNew();
|
||||
},
|
||||
transform: function(d) {
|
||||
this.model.type_options = d;
|
||||
return d;
|
||||
},
|
||||
},{
|
||||
id: 'typlen', label: gettext('Length'), cell: 'string',
|
||||
type: 'text', group: gettext('Definition'), deps: ['basetype'],
|
||||
readonly: function(m) {return !m.isNew();},
|
||||
disabled: function(m) {
|
||||
// We will store type from selected from combobox
|
||||
var of_type = m.get('basetype');
|
||||
if(m.type_options) {
|
||||
// iterating over all the types
|
||||
_.each(m.type_options, function(o) {
|
||||
// if type from selected from combobox matches in options
|
||||
if ( of_type == o.value ) {
|
||||
// if length is allowed for selected type
|
||||
if(o.length)
|
||||
{
|
||||
// set the values in model
|
||||
m.set('is_tlength', true, {silent: true});
|
||||
m.set('min_val', o.min_val, {silent: true});
|
||||
m.set('max_val', o.max_val, {silent: true});
|
||||
}
|
||||
else
|
||||
m.set('is_tlength', false, {silent: true});
|
||||
}
|
||||
});
|
||||
|
||||
!m.get('is_tlength') && setTimeout(function() {
|
||||
if(m.get('typlen')) {
|
||||
m.set('typlen', null);
|
||||
}
|
||||
},10);
|
||||
}
|
||||
return !m.get('is_tlength');
|
||||
},
|
||||
},{
|
||||
id: 'precision', label: gettext('Precision'), cell: 'string',
|
||||
type: 'text', group: gettext('Definition'), deps: ['basetype'],
|
||||
readonly: function(m) {return !m.isNew();},
|
||||
disabled: function(m) {
|
||||
// We will store type from selected from combobox
|
||||
var of_type = m.get('basetype');
|
||||
if(m.type_options) {
|
||||
// iterating over all the types
|
||||
_.each(m.type_options, function(o) {
|
||||
// if type from selected from combobox matches in options
|
||||
if ( of_type == o.value ) {
|
||||
// if precession is allowed for selected type
|
||||
if(o.precision)
|
||||
{
|
||||
// set the values in model
|
||||
m.set('is_precision', true, {silent: true});
|
||||
m.set('min_val', o.min_val, {silent: true});
|
||||
m.set('max_val', o.max_val, {silent: true});
|
||||
}
|
||||
else
|
||||
m.set('is_precision', false, {silent: true});
|
||||
}
|
||||
});
|
||||
|
||||
!m.get('is_precision') && setTimeout(function() {
|
||||
if(m.get('precision')) {
|
||||
m.set('precision', null);
|
||||
}
|
||||
},10);
|
||||
}
|
||||
return !m.get('is_precision');
|
||||
},
|
||||
},{
|
||||
id: 'typdefault', label: gettext('Default'), cell: 'string',
|
||||
type: 'text', group: gettext('Definition'),
|
||||
placeholder: gettext('Enter an expression or a value.'),
|
||||
},{
|
||||
id: 'typnotnull', label: gettext('Not NULL?'), cell: 'boolean',
|
||||
type: 'switch', group: gettext('Definition'),
|
||||
},{
|
||||
id: 'collname', label: gettext('Collation'), cell: 'string',
|
||||
control: 'node-ajax-options', type: 'text', url: 'get_collations',
|
||||
group: gettext('Definition'), cache_level: 'database',
|
||||
cache_node: 'schema', readonly: function(m) {
|
||||
return !m.isNew();
|
||||
},
|
||||
},{
|
||||
id: 'constraints', label: gettext('Constraints'), cell: 'string',
|
||||
type: 'collection', group: gettext('Constraints'), mode: ['edit', 'create'],
|
||||
model: ConstraintModel, canAdd: true, canDelete: true,
|
||||
canEdit: false, columns: ['conname','consrc', 'convalidated'],
|
||||
},
|
||||
pgBrowser.SecurityGroupSchema,
|
||||
{
|
||||
id: 'seclabels', label: gettext('Security labels'),
|
||||
model: pgBrowser.SecLabelModel, type: 'collection',
|
||||
group: 'security', mode: ['edit', 'create'],
|
||||
min_version: 90100, canAdd: true,
|
||||
canEdit: false, canDelete: true,
|
||||
control: 'unique-col-collection', uniqueCol : ['provider'],
|
||||
}],
|
||||
validate: function() { // Client Side Validation
|
||||
var err = {},
|
||||
errmsg;
|
||||
|
||||
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('basetype')) || String(this.get('basetype')).replace(/^\s+|\s+$/g, '') == '') {
|
||||
err['basetype'] = gettext('Base Type cannot be empty.');
|
||||
errmsg = errmsg || err['basetype'];
|
||||
}
|
||||
|
||||
this.errorModel.clear().set(err);
|
||||
|
||||
return errmsg;
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
|
|
|
@ -0,0 +1,227 @@
|
|||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 DomainConstSchema extends BaseUISchema {
|
||||
constructor() {
|
||||
super({
|
||||
conoid: undefined,
|
||||
conname: undefined,
|
||||
consrc: undefined,
|
||||
convalidated: true,
|
||||
});
|
||||
}
|
||||
|
||||
get idAttribute() {
|
||||
return 'conoid';
|
||||
}
|
||||
|
||||
get baseFields() {
|
||||
let obj = this;
|
||||
return [
|
||||
{
|
||||
id: 'conname', label: gettext('Name'), cell: 'text', type: 'text',
|
||||
}, {
|
||||
id: 'consrc', label: gettext('Check'), cell: 'text', type: 'text',
|
||||
editable: function(state) {return obj.isNew(state);},
|
||||
}, {
|
||||
id: 'convalidated', label: gettext('Validate?'), cell: 'checkbox',
|
||||
type: 'checkbox',
|
||||
readonly: function(state) {
|
||||
let currCon = _.find(obj.top.origData.constraints, (con)=>con.conoid == state.conoid);
|
||||
if (!obj.isNew(state) && currCon.convalidated) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
validate(state, setError) {
|
||||
if (isEmptyString(state.conname)) {
|
||||
setError('conname', 'Constraint Name cannot be empty.');
|
||||
return true;
|
||||
} else {
|
||||
setError('conname', null);
|
||||
}
|
||||
|
||||
if (isEmptyString(state.consrc)) {
|
||||
setError('consrc', 'Constraint Check cannot be empty.');
|
||||
return true;
|
||||
} else {
|
||||
setError('consrc', null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default class DomainSchema extends BaseUISchema {
|
||||
constructor(fieldOptions={}, initValues) {
|
||||
super({
|
||||
name: undefined,
|
||||
oid: undefined,
|
||||
owner: undefined,
|
||||
basensp: undefined,
|
||||
description: undefined,
|
||||
basetype: undefined,
|
||||
typlen: undefined,
|
||||
precision: undefined,
|
||||
typdefault: undefined,
|
||||
typnotnull: undefined,
|
||||
sysdomain: undefined,
|
||||
collname: undefined,
|
||||
constraints: [],
|
||||
seclabels: [],
|
||||
...initValues,
|
||||
});
|
||||
this.fieldOptions = {
|
||||
role: [],
|
||||
schema: [],
|
||||
basetype: [],
|
||||
collation: [],
|
||||
...fieldOptions,
|
||||
};
|
||||
}
|
||||
|
||||
get idAttribute() {
|
||||
return 'oid';
|
||||
}
|
||||
|
||||
get baseFields() {
|
||||
let obj = this;
|
||||
return [
|
||||
{
|
||||
id: 'name', label: gettext('Name'), cell: 'text',
|
||||
type: 'text', mode: ['properties', 'create', 'edit'],
|
||||
noEmpty: true,
|
||||
}, {
|
||||
id: 'oid', label: gettext('OID'), cell: 'text',
|
||||
type: 'text' , mode: ['properties'],
|
||||
}, {
|
||||
id: 'owner', label: gettext('Owner'),
|
||||
editable: false, type: 'select', options: this.fieldOptions.role,
|
||||
controlProps: { allowClear: false },
|
||||
}, {
|
||||
id: 'basensp', label: gettext('Schema'),
|
||||
editable: false, type: 'select', options: this.fieldOptions.schema,
|
||||
controlProps: { allowClear: false },
|
||||
mode: ['create', 'edit'],
|
||||
}, {
|
||||
id: 'sysdomain', label: gettext('System domain?'), cell: 'boolean',
|
||||
type: 'switch', mode: ['properties'],
|
||||
}, {
|
||||
id: 'description', label: gettext('Comment'), cell: 'text',
|
||||
type: 'multiline',
|
||||
}, {
|
||||
id: 'basetype', label: gettext('Base type'),
|
||||
type: 'select', options: this.fieldOptions.basetype,
|
||||
optionsLoaded: (options) => { obj.type_options = options; },
|
||||
mode:['properties', 'create', 'edit'], group: gettext('Definition'),
|
||||
readonly: function(state) {return !obj.isNew(state);}, noEmpty: true,
|
||||
}, {
|
||||
id: 'typlen', label: gettext('Length'), cell: 'text',
|
||||
type: 'text', group: gettext('Definition'), deps: ['basetype'],
|
||||
readonly: function(state) {return !obj.isNew(state);},
|
||||
disabled: function(state) {
|
||||
// We will store type from selected from combobox
|
||||
var of_type = state.basetype;
|
||||
if(obj.type_options) {
|
||||
// iterating over all the types
|
||||
_.each(obj.type_options, function(o) {
|
||||
// if type from selected from combobox matches in options
|
||||
if ( of_type == o.value ) {
|
||||
// if length is allowed for selected type
|
||||
if(o.length) {
|
||||
// set the values in model
|
||||
state.is_tlength = true;
|
||||
state.min_val = o.min_val;
|
||||
state.max_val = o.max_val;
|
||||
}
|
||||
else
|
||||
state.is_tlength = false;
|
||||
}
|
||||
});
|
||||
|
||||
if(!state.is_tlength) {
|
||||
if(state.typlen) {
|
||||
state.typlen = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return !state.is_tlength;
|
||||
},
|
||||
}, {
|
||||
id: 'precision', label: gettext('Precision'), cell: 'text',
|
||||
type: 'text', group: gettext('Definition'), deps: ['basetype'],
|
||||
readonly: function(state) {return !obj.isNew(state);},
|
||||
disabled: function(state) {
|
||||
// We will store type from selected from combobox
|
||||
var of_type = state.basetype;
|
||||
if(obj.type_options) {
|
||||
// iterating over all the types
|
||||
_.each(obj.type_options, function(o) {
|
||||
// if type from selected from combobox matches in options
|
||||
if ( of_type == o.value ) {
|
||||
// if precession is allowed for selected type
|
||||
if(o.precision)
|
||||
{
|
||||
// set the values in model
|
||||
state.is_precision = true;
|
||||
state.min_val = o.min_val;
|
||||
state.max_val = o.max_val;
|
||||
}
|
||||
else
|
||||
state.is_precision = false;
|
||||
}
|
||||
});
|
||||
|
||||
if (!state.is_precision) {
|
||||
if(state.precision) {
|
||||
state.precision = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return !state.is_precision;
|
||||
},
|
||||
}, {
|
||||
id: 'typdefault', label: gettext('Default'), cell: 'text',
|
||||
type: 'text', group: gettext('Definition'),
|
||||
placeholder: gettext('Enter an expression or a value.'),
|
||||
}, {
|
||||
id: 'typnotnull', label: gettext('Not NULL?'), cell: 'boolean',
|
||||
type: 'switch', group: gettext('Definition'),
|
||||
}, {
|
||||
id: 'collname', label: gettext('Collation'), cell: 'text',
|
||||
type: 'select', group: gettext('Definition'),
|
||||
options: this.fieldOptions.collation,
|
||||
readonly: function(state) {return !obj.isNew(state);},
|
||||
}, {
|
||||
id: 'constraints', label: gettext('Constraints'), type: 'collection',
|
||||
schema: new DomainConstSchema(),
|
||||
editable: false, group: gettext('Constraints'),
|
||||
mode: ['edit', 'create'],
|
||||
canAdd: true, canEdit: false, canDelete: true,
|
||||
uniqueCol : ['conname'],
|
||||
}, {
|
||||
id: 'seclabels', label: gettext('Security labels'), type: 'collection',
|
||||
schema: new SecLabelSchema(),
|
||||
editable: false, group: gettext('Security'),
|
||||
mode: ['edit', 'create'],
|
||||
canAdd: true, canEdit: false, canDelete: true,
|
||||
uniqueCol : ['provider'],
|
||||
min_version: 90200,
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
|
@ -781,9 +781,7 @@ class FtsDictionaryView(PGChildNodeView, SchemaDiffObjectCompare):
|
|||
if not status:
|
||||
return internal_server_error(errormsg=rset)
|
||||
|
||||
# Empty set is added before actual list as initially it will be visible
|
||||
# at template control while creating a new FTS Dictionary
|
||||
res = [{'label': '', 'value': ''}]
|
||||
res = []
|
||||
for row in rset['rows']:
|
||||
if row['nspname'] != "pg_catalog":
|
||||
row['tmplname'] = self.qtIdent(
|
||||
|
|
|
@ -11,7 +11,7 @@ import React, { useCallback } from 'react';
|
|||
import _ from 'lodash';
|
||||
|
||||
import { FormInputText, FormInputSelect, FormInputSwitch, FormInputCheckbox, FormInputColor, FormInputFileSelect, FormInputToggle, InputSwitch, FormInputSQL } from '../components/FormComponents';
|
||||
import { InputSelect, InputText } from '../components/FormComponents';
|
||||
import { InputSelect, InputText, InputCheckbox } from '../components/FormComponents';
|
||||
import Privilege from '../components/Privilege';
|
||||
import { evalFunc } from 'sources/utils';
|
||||
import PropTypes from 'prop-types';
|
||||
|
@ -172,6 +172,9 @@ function MappedCellControlBase({cell, value, id, optionsLoaded, onCellChange, vi
|
|||
case 'switch':
|
||||
return <InputSwitch name={name} value={value}
|
||||
onChange={(e)=>onTextChange(e.target.checked, e.target.name)} {...props} />;
|
||||
case 'checkbox':
|
||||
return <InputCheckbox name={name} value={value}
|
||||
onChange={(e)=>onTextChange(e.target.checked, e.target.name)} {...props} />;
|
||||
case 'privilege':
|
||||
return <Privilege name={name} value={value} onChange={onTextChange} {...props}/>;
|
||||
default:
|
||||
|
|
|
@ -0,0 +1,220 @@
|
|||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 DomainSchema from '../../../pgadmin/browser/server_groups/servers/databases/schemas/domains/static/js/domain.ui';
|
||||
import { DomainConstSchema } from '../../../pgadmin/browser/server_groups/servers/databases/schemas/domains/static/js/domain.ui';
|
||||
|
||||
describe('DomainSchema', ()=>{
|
||||
let mount;
|
||||
let schemaObj = new DomainSchema(
|
||||
{
|
||||
role: ()=>[],
|
||||
schema: ()=>[],
|
||||
basetype: ()=>[],
|
||||
collation: ()=>[],
|
||||
},
|
||||
[],
|
||||
{
|
||||
owner: 'postgres',
|
||||
schema: 'public',
|
||||
basensp: '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('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={()=>{}}
|
||||
/>);
|
||||
});
|
||||
});
|
||||
|
||||
/* Used to check collection mode */
|
||||
class MockSchema extends BaseUISchema {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
get baseFields() {
|
||||
return [{
|
||||
id: 'constraint', label: '', type: 'collection',
|
||||
schema: new DomainConstSchema(),
|
||||
editable: false,
|
||||
group: 'Constraints', mode: ['edit', 'create'],
|
||||
canAdd: true, canEdit: false, canDelete: true, hasRole: true,
|
||||
node: 'role',
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
describe('DomainConstSchema', ()=>{
|
||||
let mount;
|
||||
let schemaObj = new MockSchema();
|
||||
let domainConstObj = new DomainConstSchema();
|
||||
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', ()=>{
|
||||
let ctrl = mount(<SchemaView
|
||||
formType='dialog'
|
||||
schema={schemaObj}
|
||||
viewHelperProps={{
|
||||
mode: 'create',
|
||||
}}
|
||||
onSave={()=>{}}
|
||||
onClose={()=>{}}
|
||||
onHelp={()=>{}}
|
||||
onEdit={()=>{}}
|
||||
onDataChange={()=>{}}
|
||||
confirmOnCloseReset={false}
|
||||
hasSQL={false}
|
||||
disableSqlHelp={false}
|
||||
/>);
|
||||
|
||||
/* Make sure you hit every corner */
|
||||
ctrl.find('DataGridView').at(0).find('PgIconButton[data-test="add-row"]').find('button').simulate('click');
|
||||
});
|
||||
|
||||
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('validate', ()=>{
|
||||
let state = {};
|
||||
let setError = jasmine.createSpy('setError');
|
||||
|
||||
state.conname = undefined;
|
||||
domainConstObj.validate(state, setError);
|
||||
expect(setError).toHaveBeenCalledWith('conname', 'Constraint Name cannot be empty.');
|
||||
|
||||
state.conname = 'my_syn';
|
||||
state.consrc = undefined;
|
||||
domainConstObj.validate(state, setError);
|
||||
expect(setError).toHaveBeenCalledWith('consrc', 'Constraint Check cannot be empty.');
|
||||
|
||||
state.consrc = 'public';
|
||||
domainConstObj.validate(state, setError);
|
||||
expect(setError).toHaveBeenCalledWith('consrc', null);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,92 @@
|
|||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 DomainConstraintSchema from '../../../pgadmin/browser/server_groups/servers/databases/schemas/domains/domain_constraints/static/js/domain_constraints.ui';
|
||||
|
||||
describe('DomainConstraintSchema', ()=>{
|
||||
let mount;
|
||||
let schemaObj = new DomainConstraintSchema();
|
||||
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={()=>{}}
|
||||
/>);
|
||||
});
|
||||
});
|
||||
|
|
@ -38,7 +38,7 @@ class MockSchema extends BaseUISchema {
|
|||
}
|
||||
}
|
||||
|
||||
describe('PrivilegeSchema', ()=>{
|
||||
describe('VariableSchema', ()=>{
|
||||
let mount;
|
||||
let schemaObj = new VariableSchema(
|
||||
()=>[],
|
||||
|
|
Loading…
Reference in New Issue