mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
1) Port Properties panel for collection node, Dashboard, and SQL panel in React. Fixes #7132
2) Added transaction start time to Server activity sessions view. Fixes #7215
This commit is contained in:
committed by
Akshay Joshi
parent
931a399890
commit
cb052f1988
@@ -68,25 +68,6 @@ define('pgadmin.node.cast', [
|
||||
|
||||
},
|
||||
|
||||
// Define the backform model for cast node
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
|
||||
// Define the schema for cast
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), cell: 'string',
|
||||
editable: false, type: 'text', readonly: true, cellHeaderClasses: 'width_percent_50',
|
||||
},{
|
||||
id: 'oid', label: gettext('OID'), cell: 'string',
|
||||
editable: false, type: 'text', mode: ['properties'],
|
||||
},
|
||||
{
|
||||
id: 'description', label: gettext('Comment'),
|
||||
type: 'multiline', cellHeaderClasses: 'width_percent_50',
|
||||
},
|
||||
],
|
||||
}),
|
||||
|
||||
getSchema: function(treeNodeInfo, itemNodeData){
|
||||
return new CastSchema({
|
||||
getTypeOptions: ()=>getNodeAjaxOptions('get_type', this, treeNodeInfo, itemNodeData),
|
||||
|
||||
@@ -12,9 +12,8 @@ import { getNodeListByName, getNodeAjaxOptions } from '../../../../../../static/
|
||||
|
||||
define('pgadmin.node.event_trigger', [
|
||||
'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
|
||||
'sources/pgadmin', 'pgadmin.browser',
|
||||
'pgadmin.backform', 'pgadmin.browser.collection',
|
||||
], function(gettext, url_for, $, _, pgAdmin, pgBrowser, Backform) {
|
||||
'sources/pgadmin', 'pgadmin.browser', 'pgadmin.browser.collection',
|
||||
], function(gettext, url_for, $, _, pgAdmin, pgBrowser) {
|
||||
|
||||
// Extend the browser's collection class for event trigger collection
|
||||
if (!pgBrowser.Nodes['coll-event_trigger']) {
|
||||
@@ -80,132 +79,6 @@ define('pgadmin.node.event_trigger', [
|
||||
}
|
||||
);
|
||||
},
|
||||
// Define the model for event trigger node
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
defaults: {
|
||||
oid: undefined,
|
||||
name: undefined,
|
||||
eventowner: undefined,
|
||||
is_sys_obj: undefined,
|
||||
comment: undefined,
|
||||
enabled: 'O',
|
||||
eventfuncoid: undefined,
|
||||
eventfunname: undefined,
|
||||
eventname: 'DDL_COMMAND_START',
|
||||
when: undefined,
|
||||
xmin: undefined,
|
||||
source: undefined,
|
||||
language: undefined,
|
||||
},
|
||||
|
||||
// Default values!
|
||||
initialize: function(attrs, args) {
|
||||
var isNew = (_.size(attrs) === 0);
|
||||
|
||||
if (isNew) {
|
||||
var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
|
||||
|
||||
this.set({'eventowner': userInfo.name}, {silent: true});
|
||||
}
|
||||
pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
|
||||
// Define the schema for the event trigger node
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), cell: 'string',
|
||||
type: 'text',
|
||||
},{
|
||||
id: 'oid', label: gettext('OID'), cell: 'string',
|
||||
type: 'text', mode: ['properties'],
|
||||
},{
|
||||
id: 'eventowner', label: gettext('Owner'), cell: 'string',
|
||||
type: 'text', mode: ['properties', 'edit','create'], node: 'role',
|
||||
control: Backform.NodeListByNameControl,
|
||||
},{
|
||||
id: 'is_sys_obj', label: gettext('System event trigger?'),
|
||||
cell:'boolean', type: 'switch',
|
||||
mode: ['properties'],
|
||||
},{
|
||||
id: 'comment', label: gettext('Comment'), type: 'multiline',
|
||||
},{
|
||||
id: 'enabled', label: gettext('Trigger enabled?'),
|
||||
group: gettext('Definition'), mode: ['properties', 'edit','create'],
|
||||
options: [
|
||||
{label: gettext('Enable'), value: 'O'},
|
||||
{label: gettext('Disable'), value: 'D'},
|
||||
{label: gettext('Replica'), value: 'R'},
|
||||
{label: gettext('Always'), value: 'A'},
|
||||
],
|
||||
control: 'select2', select2: { allowClear: false, width: '100%' },
|
||||
},{
|
||||
id: 'eventfunname', label: gettext('Trigger function'),
|
||||
type: 'text', control: 'node-ajax-options', group: gettext('Definition'),
|
||||
url:'fopts', cache_node: 'trigger_function',
|
||||
},{
|
||||
id: 'eventname', label: gettext('Event'),
|
||||
group: gettext('Definition'), cell: 'string',
|
||||
options: [
|
||||
{label: gettext('DDL COMMAND START'), value: 'DDL_COMMAND_START'},
|
||||
{label: gettext('DDL COMMAND END'), value: 'DDL_COMMAND_END'},
|
||||
{label: gettext('SQL DROP'), value: 'SQL_DROP'},
|
||||
],
|
||||
control: 'select2', select2: { allowClear: false, width: '100%' },
|
||||
},{
|
||||
id: 'when', label: gettext('When TAG in'), cell: 'string',
|
||||
type: 'text', group: gettext('Definition'),
|
||||
control: Backform.SqlFieldControl,
|
||||
extraClasses:['custom_height_css_class'],
|
||||
},{
|
||||
id: 'seclabels', label: gettext('Security labels'),
|
||||
model: pgBrowser.SecLabelModel, editable: false, type: 'collection',
|
||||
group: gettext('Security'), mode: ['edit', 'create'],
|
||||
min_version: 90200, canAdd: true,
|
||||
canEdit: false, canDelete: true, control: 'unique-col-collection',
|
||||
},
|
||||
],
|
||||
// event trigger model data validation.
|
||||
validate: function() {
|
||||
var msg = undefined;
|
||||
// Clear any existing error msg.
|
||||
this.errorModel.clear();
|
||||
|
||||
if (_.isUndefined(this.get('name'))
|
||||
|| String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
|
||||
msg = gettext('Event trigger name cannot be empty.');
|
||||
this.errorModel.set('name', msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
if (_.isUndefined(this.get('eventowner'))
|
||||
|| String(this.get('eventowner')).replace(/^\s+|\s+$/g, '') == '') {
|
||||
msg = gettext('Event trigger owner cannot be empty.');
|
||||
this.errorModel.set('eventowner', msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
if (_.isUndefined(this.get('enabled'))) {
|
||||
msg = gettext('Event trigger enabled status cannot be empty.');
|
||||
this.errorModel.set('enabled', msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
if (_.isUndefined(this.get('eventfunname'))
|
||||
|| String(this.get('eventfunname')).replace(/^\s+|\s+$/g, '') == '') {
|
||||
msg = gettext('Event trigger function cannot be empty.');
|
||||
this.errorModel.set('eventfunname', msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
if (_.isUndefined(this.get('eventname'))) {
|
||||
msg = gettext('Event trigger event cannot be empty.');
|
||||
this.errorModel.set('eventname', msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@@ -13,9 +13,8 @@ import ExtensionsSchema from './extension.ui';
|
||||
|
||||
define('pgadmin.node.extension', [
|
||||
'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
|
||||
'sources/pgadmin', 'pgadmin.browser',
|
||||
'pgadmin.backform', 'pgadmin.browser.collection',
|
||||
], function(gettext, url_for, $, _, pgAdmin, pgBrowser, Backform) {
|
||||
'sources/pgadmin', 'pgadmin.browser', 'pgadmin.browser.collection',
|
||||
], function(gettext, url_for, $, _, pgAdmin, pgBrowser) {
|
||||
|
||||
/*
|
||||
* Create and Add an Extension Collection into nodes
|
||||
@@ -96,109 +95,6 @@ define('pgadmin.node.extension', [
|
||||
* Define model for the Node and specify the properties
|
||||
* of the model in schema.
|
||||
*/
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
schema: [
|
||||
{
|
||||
id: 'name', label: gettext('Name'), first_empty: true,
|
||||
type: 'text', mode: ['properties', 'create', 'edit'],
|
||||
visible: true, url:'avails', readonly: function(m) {
|
||||
return !m.isNew();
|
||||
},
|
||||
transform: function(data, cell) {
|
||||
var res = [],
|
||||
control = cell || this,
|
||||
label = control.model.get('name');
|
||||
|
||||
if (!control.model.isNew()) {
|
||||
res.push({label: label, value: label});
|
||||
}
|
||||
else {
|
||||
if (data && _.isArray(data)) {
|
||||
_.each(data, function(d) {
|
||||
if (d.installed_version === null)
|
||||
|
||||
/*
|
||||
* d contains json data and sets into
|
||||
* select's option control
|
||||
*
|
||||
* We need to stringify data because formatter will
|
||||
* convert Array Object as [Object] string
|
||||
*/
|
||||
res.push({label: d.name, value: JSON.stringify(d)});
|
||||
});
|
||||
}
|
||||
}
|
||||
return res;
|
||||
},
|
||||
|
||||
/*
|
||||
* extends NodeAjaxOptionsControl to override the properties
|
||||
* getValueFromDOM which takes stringified data from option of
|
||||
* select control and parse it. And `onChange` takes the stringified
|
||||
* data from select's option, thus convert it to json format and set the
|
||||
* data into Model which is used to enable/disable the schema field.
|
||||
*/
|
||||
control: Backform.NodeAjaxOptionsControl.extend({
|
||||
getValueFromDOM: function() {
|
||||
var data = this.formatter.toRaw(
|
||||
_.unescape(this.$el.find('select').val()), this.model);
|
||||
/*
|
||||
* return null if data is empty to prevent it from
|
||||
* throwing parsing error. Adds check as name can be empty
|
||||
*/
|
||||
if (data === '') {
|
||||
return null;
|
||||
}
|
||||
else if (typeof(data) === 'string') {
|
||||
data=JSON.parse(data);
|
||||
}
|
||||
return data.name;
|
||||
},
|
||||
|
||||
/*
|
||||
* When name is changed, extract value from its select option and
|
||||
* set attributes values into the model
|
||||
*/
|
||||
onChange: function() {
|
||||
Backform.NodeAjaxOptionsControl.prototype.onChange.apply(
|
||||
this, arguments
|
||||
);
|
||||
var selectedValue = this.$el.find('select').val();
|
||||
if (selectedValue.trim() != '') {
|
||||
var d = this.formatter.toRaw(selectedValue, this.model);
|
||||
if(typeof(d) === 'string')
|
||||
d=JSON.parse(d);
|
||||
this.model.set({
|
||||
'version' : '',
|
||||
'relocatable': (
|
||||
(!_.isNull(d.relocatable[0]) &&
|
||||
!_.isUndefined(d.relocatable[0])) ? d.relocatable[0]: ''
|
||||
),
|
||||
});
|
||||
} else {
|
||||
this.model.set({
|
||||
'version': '', 'relocatable': true, 'schema': '',
|
||||
});
|
||||
}
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
id: 'oid', label: gettext('OID'), cell: 'string',
|
||||
type: 'text', mode: ['properties'],
|
||||
},
|
||||
{
|
||||
id: 'owner', label: gettext('Owner'), control: 'node-list-by-name',
|
||||
mode: ['properties'], node: 'role', cell: 'string',
|
||||
cache_level: 'server',
|
||||
},
|
||||
{
|
||||
id: 'comment', label: gettext('Comment'), cell: 'string',
|
||||
type: 'multiline', readonly: true,
|
||||
},
|
||||
],
|
||||
}),
|
||||
getSchema: (treeNodeInfo, itemNodeData)=>{
|
||||
let nodeObj = pgAdmin.Browser.Nodes['extension'];
|
||||
return new ExtensionsSchema(
|
||||
|
||||
@@ -13,9 +13,9 @@ import ForeignServerSchema from './foreign_server.ui';
|
||||
|
||||
define('pgadmin.node.foreign_server', [
|
||||
'sources/gettext', 'sources/url_for', 'jquery', 'underscore', 'sources/pgadmin',
|
||||
'pgadmin.browser', 'pgadmin.backform', 'pgadmin.browser.collection',
|
||||
'pgadmin.browser', 'pgadmin.browser.collection',
|
||||
'pgadmin.browser.server.privilege',
|
||||
], function(gettext, url_for, $, _, pgAdmin, pgBrowser, Backform) {
|
||||
], function(gettext, url_for, $, _, pgAdmin, pgBrowser) {
|
||||
|
||||
// Extend the browser's collection class for foreign server collection
|
||||
if (!pgBrowser.Nodes['coll-foreign_server']) {
|
||||
@@ -82,45 +82,6 @@ define('pgadmin.node.foreign_server', [
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
// Defining model for foreign server node
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
|
||||
// Default values!
|
||||
initialize: function(attrs, args) {
|
||||
var isNew = (_.size(attrs) === 0);
|
||||
|
||||
if (isNew) {
|
||||
var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
|
||||
|
||||
this.set({'fsrvowner': userInfo.name}, {silent: true});
|
||||
}
|
||||
pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
|
||||
// Defining schema for the foreign server node
|
||||
schema: [
|
||||
{
|
||||
id: 'name', label: gettext('Name'), cell: 'string',
|
||||
type: 'text', disabled: function() {
|
||||
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',
|
||||
},
|
||||
],
|
||||
}),
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@@ -12,10 +12,10 @@ import { getNodePrivilegeRoleSchema } from '../../../../static/js/privilege.ui';
|
||||
import ForeignDataWrapperSchema from './foreign_data_wrapper.ui';
|
||||
|
||||
define('pgadmin.node.foreign_data_wrapper', [
|
||||
'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
|
||||
'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform',
|
||||
'sources/gettext', 'sources/url_for', 'jquery',
|
||||
'sources/pgadmin', 'pgadmin.browser',
|
||||
'pgadmin.browser.collection', 'pgadmin.browser.server.privilege',
|
||||
], function(gettext, url_for, $, _, pgAdmin, pgBrowser, Backform) {
|
||||
], function(gettext, url_for, $, pgAdmin, pgBrowser) {
|
||||
|
||||
// Extend the browser's collection class for foreign data wrapper collection
|
||||
if (!pgBrowser.Nodes['coll-foreign_data_wrapper']) {
|
||||
@@ -87,44 +87,6 @@ define('pgadmin.node.foreign_data_wrapper', [
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
// Defining model for foreign data wrapper node
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
|
||||
// Default values!
|
||||
initialize: function(attrs, args) {
|
||||
var isNew = (_.size(attrs) === 0);
|
||||
|
||||
if (isNew) {
|
||||
var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
|
||||
|
||||
this.set({'fdwowner': userInfo.name}, {silent: true});
|
||||
}
|
||||
pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
|
||||
// Defining schema for the foreign data wrapper node
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), cell: 'string',
|
||||
type: 'text', readonly: function() {
|
||||
// name field will be disabled only if edit mode
|
||||
return (
|
||||
this.mode == 'edit'
|
||||
);
|
||||
},
|
||||
}, {
|
||||
id: 'oid', label: gettext('OID'), cell: 'string',
|
||||
type: 'text', mode: ['properties'],
|
||||
}, {
|
||||
id: 'fdwowner', 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',
|
||||
}],
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -10,13 +10,12 @@
|
||||
import { getNodeAjaxOptions, getNodeListByName } from '../../../../../../static/js/node_ajax';
|
||||
import LanguageSchema from './language.ui';
|
||||
import { getNodePrivilegeRoleSchema } from '../../../../static/js/privilege.ui';
|
||||
import _ from 'lodash';
|
||||
|
||||
define('pgadmin.node.language', [
|
||||
'sources/gettext', 'sources/url_for', 'jquery',
|
||||
'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform',
|
||||
'sources/pgadmin', 'pgadmin.browser',
|
||||
'pgadmin.browser.collection', 'pgadmin.browser.server.privilege',
|
||||
], function(gettext, url_for, $, pgAdmin, pgBrowser, Backform) {
|
||||
], function(gettext, url_for, $, pgAdmin, pgBrowser) {
|
||||
|
||||
// Extend the browser's collection class for languages collection
|
||||
if (!pgBrowser.Nodes['coll-language']) {
|
||||
@@ -71,37 +70,6 @@ define('pgadmin.node.language', [
|
||||
}]);
|
||||
},
|
||||
|
||||
// Define the model for language node
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
initialize: function(attrs, args) {
|
||||
var isNew = (_.size(attrs) === 0);
|
||||
if (isNew) {
|
||||
var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
|
||||
|
||||
this.set({'lanowner': userInfo.name}, {silent: true});
|
||||
}
|
||||
pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
|
||||
// Define the schema for the language node
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), type: 'text',
|
||||
mode: ['properties'],
|
||||
},{
|
||||
id: 'oid', label: gettext('OID'), cell: 'string', mode: ['properties'],
|
||||
type: 'text',
|
||||
},{
|
||||
id: 'lanowner', label: gettext('Owner'), type: 'text',
|
||||
control: Backform.NodeListByNameControl, node: 'role',
|
||||
mode: ['edit', 'properties', 'create'], select2: { allowClear: false },
|
||||
},
|
||||
{
|
||||
id: 'description', label: gettext('Comment'), cell: 'string',
|
||||
type: 'multiline',
|
||||
},
|
||||
],
|
||||
}),
|
||||
|
||||
getSchema: function(treeNodeInfo, itemNodeData){
|
||||
return new LanguageSchema(
|
||||
|
||||
@@ -12,9 +12,9 @@ import PublicationSchema from './publication.ui';
|
||||
|
||||
define('pgadmin.node.publication', [
|
||||
'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
|
||||
'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform',
|
||||
'sources/pgadmin', 'pgadmin.browser',
|
||||
'pgadmin.browser.collection', 'pgadmin.browser.server.privilege',
|
||||
], function(gettext, url_for, $, _, pgAdmin, pgBrowser, Backform) {
|
||||
], function(gettext, url_for, $, _, pgAdmin, pgBrowser) {
|
||||
|
||||
// Extend the browser's collection class for publications collection
|
||||
if (!pgBrowser.Nodes['coll-publication']) {
|
||||
@@ -23,7 +23,7 @@ define('pgadmin.node.publication', [
|
||||
node: 'publication',
|
||||
label: gettext('Publications'),
|
||||
type: 'coll-publication',
|
||||
columns: ['name', 'pubowner', 'pubtable', 'all_table'],
|
||||
columns: ['name', 'pubowner', 'proptable', 'all_table'],
|
||||
|
||||
});
|
||||
}
|
||||
@@ -70,82 +70,7 @@ define('pgadmin.node.publication', [
|
||||
icon: 'wcTabIcon icon-publication', data: {action: 'create'},
|
||||
}]);
|
||||
},
|
||||
// Define the model for publication node
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
|
||||
// Default values!
|
||||
initialize: function(attrs, args) {
|
||||
var isNew = (_.size(attrs) === 0);
|
||||
if (isNew) {
|
||||
var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
|
||||
|
||||
this.set({'pubowner': userInfo.name}, {silent: true});
|
||||
}
|
||||
pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
|
||||
// Define the schema for the publication node
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), type: 'text',
|
||||
mode: ['properties', 'create', 'edit'],
|
||||
visible: function() {
|
||||
if(!_.isUndefined(this.node_info) && !_.isUndefined(this.node_info.server)
|
||||
&& !_.isUndefined(this.node_info.server.version) &&
|
||||
this.node_info.server.version >= 100000) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
},{
|
||||
id: 'oid', label: gettext('OID'), cell: 'string', mode: ['properties'],
|
||||
type: 'text',
|
||||
},{
|
||||
id: 'pubowner', label: gettext('Owner'), type: 'text',
|
||||
control: Backform.NodeListByNameControl, node: 'role',
|
||||
disabled: function(m){
|
||||
if(m.isNew())
|
||||
return true;
|
||||
return false;
|
||||
},
|
||||
mode: ['edit', 'properties', 'create'], select2: { allowClear: false},
|
||||
},{
|
||||
id: 'all_table', label: gettext('All tables?'), type: 'switch',
|
||||
group: gettext('Definition'), mode: ['edit', 'properties', 'create'], deps: ['name'],
|
||||
readonly: function(m) {return !m.isNew();},
|
||||
},
|
||||
{
|
||||
id: 'pubtable', label: gettext('Tables'), type: 'text', group: gettext('Definition'),
|
||||
mode: ['properties'],
|
||||
},
|
||||
],
|
||||
|
||||
|
||||
/* validate function is used to validate the input given by
|
||||
* the user. In case of error, message will be displayed on
|
||||
* the GUI for the respective control.
|
||||
*/
|
||||
|
||||
sessChanged: function() {
|
||||
if (this.sessAttrs['pubtable'] == '' && this.origSessAttrs['pubtable'] == '')
|
||||
return false;
|
||||
return pgBrowser.DataModel.prototype.sessChanged.apply(this);
|
||||
},
|
||||
|
||||
canCreate: function(itemData, item) {
|
||||
|
||||
var treeData = pgBrowser.tree.getTreeNodeHierarchy(item),
|
||||
server = treeData['server'];
|
||||
|
||||
// If server is less than 10 then do not allow 'create' menu
|
||||
if (server && server.version < 100000)
|
||||
return false;
|
||||
|
||||
// by default we want to allow create menu
|
||||
return true;
|
||||
},
|
||||
|
||||
}),
|
||||
|
||||
getSchema: function(treeNodeInfo, itemNodeData){
|
||||
return new PublicationSchema(
|
||||
|
||||
@@ -147,7 +147,7 @@ export default class PublicationSchema extends BaseUISchema {
|
||||
group: gettext('Definition'), mode: ['edit', 'create'],
|
||||
deps: ['all_table'], disabled: obj.isAllTable,
|
||||
},{
|
||||
id: 'pubtable', label: gettext('Tables'), type: 'text', group: gettext('Definition'),
|
||||
id: 'proptable', label: gettext('Tables'), type: 'text', group: gettext('Definition'),
|
||||
mode: ['properties'],
|
||||
},{
|
||||
type: 'nested-fieldset', mode: ['create','edit', 'properties'],
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
SELECT pg_catalog.quote_ident(pgb_table.schemaname)||'.'||pg_catalog.quote_ident(pgb_table.tablename)
|
||||
AS pubtable FROM pg_catalog.pg_publication_tables pgb_table WHERE pubname = '{{ pname }}'
|
||||
AS pubtable,
|
||||
pg_catalog.quote_ident(pgb_table.schemaname)||'.'||pg_catalog.quote_ident(pgb_table.tablename)
|
||||
AS proptable
|
||||
FROM pg_catalog.pg_publication_tables pgb_table WHERE pubname = '{{ pname }}'
|
||||
AND pgb_table.schemaname NOT LIKE 'pgagent';
|
||||
|
||||
@@ -45,37 +45,6 @@ define('pgadmin.node.aggregate', [
|
||||
|
||||
this.initialized = true;
|
||||
},
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
|
||||
// Default values!
|
||||
initialize: function(attrs, args) {
|
||||
var isNew = (_.size(attrs) === 0);
|
||||
|
||||
if (isNew) {
|
||||
var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
|
||||
var schemaInfo = args.node_info.schema;
|
||||
|
||||
this.set({'owner': userInfo.name}, {silent: true});
|
||||
this.set({'schema': schemaInfo._label}, {silent: true});
|
||||
}
|
||||
pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Aggregate'), cell: 'string',
|
||||
type: 'text', mode: ['properties', 'create', 'edit'],
|
||||
},{
|
||||
id: 'owner', label: gettext('Owner'), cell: 'string',
|
||||
type: 'text', mode: ['properties', 'create', 'edit'],
|
||||
control: 'node-list-by-name',
|
||||
node: 'role',
|
||||
},{
|
||||
id: 'description', label: gettext('Comment'), cell: 'string',
|
||||
type: 'multiline', mode: ['properties', 'create', 'edit'],
|
||||
}
|
||||
],
|
||||
}),
|
||||
getSchema: ()=>{
|
||||
return new AggregateSchema();
|
||||
}
|
||||
|
||||
@@ -45,32 +45,6 @@ define('pgadmin.node.catalog_object_column', [
|
||||
getSchema: function() {
|
||||
return new CatalogObjectColumnSchema();
|
||||
},
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
defaults: {
|
||||
attname: undefined,
|
||||
attowner: undefined,
|
||||
atttypid: undefined,
|
||||
attnum: undefined,
|
||||
cltype: undefined,
|
||||
collspcname: undefined,
|
||||
attacl: undefined,
|
||||
is_sys_obj: undefined,
|
||||
description: undefined,
|
||||
},
|
||||
schema: [{
|
||||
id: 'attname', label: gettext('Column'), cell: 'string',
|
||||
type: 'text', readonly: true,
|
||||
},{
|
||||
id: 'attnum', label: gettext('Position'), cell: 'string',
|
||||
type: 'text', readonly: true,
|
||||
},{
|
||||
id: 'cltype', label: gettext('Data type'), cell: 'string',
|
||||
group: gettext('Definition'), type: 'text', readonly: true,
|
||||
},{
|
||||
id: 'description', label: gettext('Comment'), cell: 'string',
|
||||
type: 'multiline', readonly: true,
|
||||
}],
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -43,31 +43,6 @@ define('pgadmin.node.catalog_object', [
|
||||
|
||||
},
|
||||
getSchema: ()=>new CatalogObjectSchema(),
|
||||
/* Few fields are kept since the properties tab for collection is not
|
||||
yet migrated to new react schema. Once the properties for collection
|
||||
is removed, remove this model */
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
defaults: {
|
||||
name: undefined,
|
||||
namespaceowner: undefined,
|
||||
nspacl: undefined,
|
||||
description: undefined,
|
||||
},
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), cell: 'string',
|
||||
type: 'text', readonly: true,
|
||||
},{
|
||||
id: 'oid', label: gettext('OID'), cell: 'string',
|
||||
type: 'text',
|
||||
},{
|
||||
id: 'owner', label: gettext('Owner'), cell: 'string',
|
||||
type: 'text', readonly: true,
|
||||
},{
|
||||
id: 'description', label: gettext('Comment'), cell: 'string',
|
||||
type: 'multiline' , readonly: true,
|
||||
},
|
||||
],
|
||||
}),
|
||||
|
||||
});
|
||||
|
||||
|
||||
@@ -69,42 +69,6 @@ define('pgadmin.node.collation', [
|
||||
]);
|
||||
|
||||
},
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
|
||||
// Default values!
|
||||
initialize: function(attrs, args) {
|
||||
var isNew = (_.size(attrs) === 0);
|
||||
|
||||
if (isNew) {
|
||||
var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
|
||||
var schemaInfo = args.node_info.schema;
|
||||
|
||||
this.set({'owner': userInfo.name}, {silent: true});
|
||||
this.set({'schema': schemaInfo._label}, {silent: true});
|
||||
}
|
||||
pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), cell: 'string',
|
||||
type: 'text', mode: ['properties', 'create', 'edit'],
|
||||
disabled: 'inSchema',
|
||||
},{
|
||||
id: 'oid', label: gettext('OID'), cell: 'string',
|
||||
type: 'text' , mode: ['properties'],
|
||||
},{
|
||||
id: 'owner', label: gettext('Owner'), cell: 'string',
|
||||
type: 'text', mode: ['properties', 'create', 'edit'],
|
||||
disabled: 'inSchema', control: 'node-list-by-name',
|
||||
node: 'role',
|
||||
},{
|
||||
id: 'description', label: gettext('Comment'), cell: 'string',
|
||||
type: 'multiline', mode: ['properties', 'create', 'edit'],
|
||||
disabled: 'inSchema',
|
||||
}
|
||||
],
|
||||
}),
|
||||
getSchema: (treeNodeInfo, itemNodeData)=>{
|
||||
let nodeObj = pgAdmin.Browser.Nodes['collation'];
|
||||
return new CollationSchema(
|
||||
|
||||
@@ -75,43 +75,6 @@ define('pgadmin.node.domain_constraints', [
|
||||
getSchema: function() {
|
||||
return new DomainConstraintSchema();
|
||||
},
|
||||
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
// Domain Constraint Schema
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), type:'text', cell:'string',
|
||||
},{
|
||||
id: 'description', label: gettext('Comment'), type: 'multiline', cell:
|
||||
'string', mode: ['properties', 'create', 'edit'], min_version: 90500,
|
||||
}],
|
||||
// Client Side Validation
|
||||
validate: function() {
|
||||
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('consrc')) || String(this.get('consrc')).replace(/^\s+|\s+$/g, '') == '') {
|
||||
err['consrc'] = gettext('Check cannot be empty.');
|
||||
errmsg = errmsg || err['consrc'];
|
||||
|
||||
}
|
||||
|
||||
this.errorModel.clear().set(err);
|
||||
|
||||
if (_.size(err)) {
|
||||
this.trigger('on-status', {msg: errmsg});
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
},
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -98,38 +98,6 @@ define('pgadmin.node.domain', [
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
// Domain Node Model
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
initialize: function(attrs, args) {
|
||||
var isNew = (_.size(attrs) === 0);
|
||||
if (isNew) {
|
||||
// Set Selected Schema
|
||||
var schema = args.node_info.schema.label;
|
||||
this.set({'basensp': schema}, {silent: true});
|
||||
|
||||
// Set Current User
|
||||
var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
|
||||
this.set({'owner': userInfo.name}, {silent: true});
|
||||
}
|
||||
pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
// Domain Schema
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), cell: 'string',
|
||||
type: 'text', mode: ['properties', 'create', 'edit'],
|
||||
},{
|
||||
id: 'oid', label: gettext('OID'), cell: 'string',
|
||||
type: 'text' , mode: ['properties'],
|
||||
},{
|
||||
id: 'owner', label: gettext('Owner'), cell: 'string', control: Backform.NodeListByNameControl,
|
||||
node: 'role', type: 'text', mode: ['edit', 'create', 'properties'],
|
||||
},{
|
||||
id: 'description', label: gettext('Comment'), cell: 'string',
|
||||
type: 'multiline',
|
||||
}],
|
||||
}),
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@@ -10,15 +10,16 @@ import { getNodeListByName, getNodeAjaxOptions } from '../../../../../../../stat
|
||||
import { getNodeVariableSchema } from '../../../../../static/js/variable.ui';
|
||||
import { getNodePrivilegeRoleSchema } from '../../../../../static/js/privilege.ui';
|
||||
import ForeignTableSchema from './foreign_table.ui';
|
||||
import _ from 'lodash';
|
||||
|
||||
/* Create and Register Foreign Table Collection and Node. */
|
||||
define('pgadmin.node.foreign_table', [
|
||||
'sources/gettext', 'sources/url_for', 'jquery', 'underscore', 'backbone',
|
||||
'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform', 'pgadmin.backgrid',
|
||||
'sources/gettext', 'sources/url_for', 'jquery', 'backbone',
|
||||
'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backgrid',
|
||||
'pgadmin.node.schema.dir/child', 'pgadmin.node.schema.dir/schema_child_tree_node',
|
||||
'pgadmin.browser.collection',
|
||||
], function(
|
||||
gettext, url_for, $, _, Backbone, pgAdmin, pgBrowser, Backform, Backgrid,
|
||||
gettext, url_for, $, Backbone, pgAdmin, pgBrowser, Backgrid,
|
||||
schemaChild, schemaChildTreeNode
|
||||
) {
|
||||
|
||||
@@ -34,465 +35,6 @@ define('pgadmin.node.foreign_table', [
|
||||
});
|
||||
}
|
||||
|
||||
// Options Model
|
||||
var ColumnOptionsModel = pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'option',
|
||||
defaults: {
|
||||
option: undefined,
|
||||
value: undefined,
|
||||
},
|
||||
schema: [
|
||||
{id: 'option', label: gettext('Option'), type:'text', editable: true, cellHeaderClasses: 'width_percent_30'},
|
||||
{
|
||||
id: 'value', label: gettext('Value'), type: 'text', editable: true, cellHeaderClasses: 'width_percent_50',
|
||||
},
|
||||
],
|
||||
validate: function() {
|
||||
if (_.isUndefined(this.get('value')) ||
|
||||
_.isNull(this.get('value')) ||
|
||||
String(this.get('value')).replace(/^\s+|\s+$/g, '') == '') {
|
||||
var msg = 'Please enter a value.';
|
||||
|
||||
this.errorModel.set('value', msg);
|
||||
|
||||
return msg;
|
||||
} else {
|
||||
this.errorModel.unset('value');
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
});
|
||||
|
||||
// Columns Model
|
||||
var ColumnsModel = pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'attnum',
|
||||
defaults: {
|
||||
attname: undefined,
|
||||
datatype: undefined,
|
||||
typlen: undefined,
|
||||
precision: undefined,
|
||||
typdefault: undefined,
|
||||
attnotnull: undefined,
|
||||
collname: undefined,
|
||||
attnum: undefined,
|
||||
inheritedfrom: undefined,
|
||||
inheritedid: undefined,
|
||||
attstattarget: undefined,
|
||||
coloptions: [],
|
||||
},
|
||||
type_options: undefined,
|
||||
schema: [{
|
||||
id: 'attname', label: gettext('Name'), cell: 'string', type: 'text',
|
||||
editable: 'is_editable_column', cellHeaderClasses: 'width_percent_40',
|
||||
},{
|
||||
id: 'datatype', label: gettext('Data type'), cell: 'node-ajax-options',
|
||||
control: 'node-ajax-options', type: 'text', url: 'get_types',
|
||||
editable: 'is_editable_column', cellHeaderClasses: 'width_percent_0',
|
||||
group: gettext('Definition'),
|
||||
transform: function(d, self){
|
||||
self.model.type_options = d;
|
||||
return d;
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'typlen', label: gettext('Length'),
|
||||
cell: 'string', group: gettext('Definition'),
|
||||
type: 'int', deps: ['datatype'],
|
||||
disabled: function(m) {
|
||||
var val = m.get('typlen');
|
||||
// We will store type from selected from combobox
|
||||
if(!(_.isUndefined(m.get('inheritedid'))
|
||||
|| _.isNull(m.get('inheritedid'))
|
||||
|| _.isUndefined(m.get('inheritedfrom'))
|
||||
|| _.isNull(m.get('inheritedfrom')))) {
|
||||
|
||||
if (!_.isUndefined(val)) {
|
||||
setTimeout(function() {
|
||||
m.set('typlen', undefined);
|
||||
}, 10);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
var of_type = m.get('datatype'),
|
||||
has_length = false;
|
||||
if(m.type_options) {
|
||||
m.set('is_tlength', false, {silent: true});
|
||||
|
||||
// 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
|
||||
has_length = true;
|
||||
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});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (!has_length && !_.isUndefined(val)) {
|
||||
setTimeout(function() {
|
||||
m.set('typlen', undefined);
|
||||
}, 10);
|
||||
}
|
||||
|
||||
return !(m.get('is_tlength'));
|
||||
}
|
||||
if (!has_length && !_.isUndefined(val)) {
|
||||
setTimeout(function() {
|
||||
m.set('typlen', undefined);
|
||||
}, 10);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
cellHeaderClasses: 'width_percent_10',
|
||||
},
|
||||
{
|
||||
id: 'precision', label: gettext('Precision'),
|
||||
type: 'int', deps: ['datatype'],
|
||||
cell: 'string', group: gettext('Definition'),
|
||||
disabled: function(m) {
|
||||
var val = m.get('precision');
|
||||
if(!(_.isUndefined(m.get('inheritedid'))
|
||||
|| _.isNull(m.get('inheritedid'))
|
||||
|| _.isUndefined(m.get('inheritedfrom'))
|
||||
|| _.isNull(m.get('inheritedfrom')))) {
|
||||
|
||||
if (!_.isUndefined(val)) {
|
||||
setTimeout(function() {
|
||||
m.set('precision', undefined);
|
||||
}, 10);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
var of_type = m.get('datatype'),
|
||||
has_precision = false;
|
||||
|
||||
if(m.type_options) {
|
||||
m.set('is_precision', false, {silent: true});
|
||||
// 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)
|
||||
{
|
||||
has_precision = true;
|
||||
// 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});
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!has_precision && !_.isUndefined(val)) {
|
||||
setTimeout(function() {
|
||||
m.set('precision', undefined);
|
||||
}, 10);
|
||||
}
|
||||
return !(m.get('is_precision'));
|
||||
}
|
||||
if (!has_precision && !_.isUndefined(val)) {
|
||||
setTimeout(function() {
|
||||
m.set('precision', undefined);
|
||||
}, 10);
|
||||
}
|
||||
return true;
|
||||
}, cellHeaderClasses: 'width_percent_10',
|
||||
},
|
||||
{
|
||||
id: 'typdefault', label: gettext('Default'), type: 'text',
|
||||
cell: 'string', min_version: 90300, group: gettext('Definition'),
|
||||
placeholder: gettext('Enter an expression or a value.'),
|
||||
cellHeaderClasses: 'width_percent_10',
|
||||
editable: function(m) {
|
||||
if(!(_.isUndefined(m.get('inheritedid'))
|
||||
|| _.isNull(m.get('inheritedid'))
|
||||
|| _.isUndefined(m.get('inheritedfrom'))
|
||||
|| _.isNull(m.get('inheritedfrom')))) { return false; }
|
||||
if (this.get('node_info').server.version < 90300){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'attnotnull', label: gettext('Not NULL?'),
|
||||
cell: 'boolean',type: 'switch', editable: 'is_editable_column',
|
||||
cellHeaderClasses: 'width_percent_10', group: gettext('Definition'),
|
||||
},
|
||||
{
|
||||
id: 'attstattarget', label: gettext('Statistics'), min_version: 90200,
|
||||
cell: 'integer', type: 'int', group: gettext('Definition'),
|
||||
editable: function(m) {
|
||||
if (_.isUndefined(m.isNew) || m.isNew()) { return false; }
|
||||
if (this.get('node_info').server.version < 90200){
|
||||
return false;
|
||||
}
|
||||
return (_.isUndefined(m.get('inheritedid')) || _.isNull(m.get('inheritedid'))
|
||||
|| _.isUndefined(m.get('inheritedfrom')) || _.isNull(m.get('inheritedfrom'))) ? true : false;
|
||||
}, cellHeaderClasses: 'width_percent_10',
|
||||
},
|
||||
{
|
||||
id: 'collname', label: gettext('Collation'), cell: 'node-ajax-options',
|
||||
control: 'node-ajax-options', type: 'text', url: 'get_collations',
|
||||
min_version: 90300, editable: function(m) {
|
||||
if (!(_.isUndefined(m.isNew)) && !m.isNew()) { return false; }
|
||||
return (_.isUndefined(m.get('inheritedid')) || _.isNull(m.get('inheritedid'))
|
||||
|| _.isUndefined(m.get('inheritedfrom')) || _.isNull(m.get('inheritedfrom'))) ? true : false;
|
||||
},
|
||||
cellHeaderClasses: 'width_percent_20', group: gettext('Definition'),
|
||||
},
|
||||
{
|
||||
id: 'attnum', cell: 'string',type: 'text', visible: false,
|
||||
},
|
||||
{
|
||||
id: 'inheritedfrom', label: gettext('Inherited From'), cell: 'string',
|
||||
type: 'text', visible: false, mode: ['properties', 'edit'],
|
||||
cellHeaderClasses: 'width_percent_10',
|
||||
},
|
||||
{
|
||||
id: 'coloptions', label: gettext('Options'), cell: 'string',
|
||||
type: 'collection', group: gettext('Options'), mode: ['edit', 'create'],
|
||||
model: ColumnOptionsModel, canAdd: true, canDelete: true, canEdit: false,
|
||||
control: Backform.UniqueColCollectionControl, uniqueCol : ['option'],
|
||||
min_version: 90200,
|
||||
}],
|
||||
validate: function() {
|
||||
var errmsg = null;
|
||||
|
||||
if (_.isUndefined(this.get('attname')) || String(this.get('attname')).replace(/^\s+|\s+$/g, '') == '') {
|
||||
errmsg = gettext('Column Name cannot be empty.');
|
||||
this.errorModel.set('attname', errmsg);
|
||||
} else {
|
||||
this.errorModel.unset('attname');
|
||||
}
|
||||
|
||||
if (_.isUndefined(this.get('datatype')) || String(this.get('datatype'))
|
||||
.replace(/^\s+|\s+$/g, '') == '') {
|
||||
errmsg = gettext('Column Datatype cannot be empty.');
|
||||
this.errorModel.set('datatype', errmsg);
|
||||
} else {
|
||||
this.errorModel.unset('datatype');
|
||||
}
|
||||
|
||||
return errmsg;
|
||||
},
|
||||
is_editable_column: function(m) {
|
||||
return (_.isUndefined(m.get('inheritedid')) || _.isNull(m.get('inheritedid'))
|
||||
|| _.isUndefined(m.get('inheritedfrom')) || _.isNull(m.get('inheritedfrom'))) ? true : false;
|
||||
},
|
||||
toJSON: Backbone.Model.prototype.toJSON,
|
||||
});
|
||||
|
||||
|
||||
/* NodeAjaxOptionsMultipleControl is for multiple selection of Combobox.
|
||||
* This control is used to select Multiple Parent Tables to be inherited.
|
||||
* It also populates/vacates Columns on selection/deselection of the option (i.e. table name).
|
||||
* To populates the column, it calls the server and fetch the columns data
|
||||
* for the selected table.
|
||||
*/
|
||||
var NodeAjaxOptionsMultipleControl = Backform.NodeAjaxOptionsControl.extend({
|
||||
onChange: function() {
|
||||
var model = this.model,
|
||||
attrArr = this.field.get('name').split('.'),
|
||||
name = attrArr.shift(),
|
||||
path = attrArr.join('.'),
|
||||
value = this.getValueFromDOM(),
|
||||
changes = {},
|
||||
columns = model.get('columns'),
|
||||
inherits = model.get(name);
|
||||
|
||||
if (this.model.errorModel instanceof Backbone.Model) {
|
||||
if (_.isEmpty(path)) {
|
||||
this.model.errorModel.unset(name);
|
||||
} else {
|
||||
var nestedError = this.model.errorModel.get(name);
|
||||
if (nestedError) {
|
||||
this.keyPathSetter(nestedError, path, null);
|
||||
this.model.errorModel.set(name, nestedError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var self = this;
|
||||
|
||||
if (typeof(inherits) == 'string'){ inherits = JSON.parse(inherits); }
|
||||
|
||||
// Remove Columns if inherit option is deselected from the combobox
|
||||
if(_.size(value) < _.size(inherits)) {
|
||||
var dif = _.difference(inherits, value);
|
||||
var rmv_columns = columns.where({inheritedid: parseInt(dif[0])});
|
||||
columns.remove(rmv_columns);
|
||||
}
|
||||
else
|
||||
{
|
||||
_.each(value, function(i) {
|
||||
// Fetch Columns from server
|
||||
var fnd_columns = columns.where({inheritedid: parseInt(i)});
|
||||
if (fnd_columns && fnd_columns.length <= 0) {
|
||||
var inhted_columns = self.fetchColumns(i);
|
||||
columns.add(inhted_columns);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
changes[name] = _.isEmpty(path) ? value : _.clone(model.get(name)) || {};
|
||||
this.stopListening(this.model, 'change:' + name, this.render);
|
||||
model.set(changes);
|
||||
this.listenTo(this.model, 'change:' + name, this.render);
|
||||
},
|
||||
fetchColumns: function(table_id){
|
||||
var self = this,
|
||||
url = 'get_columns',
|
||||
m = self.model.top || self.model;
|
||||
|
||||
var node = this.field.get('schema_node'),
|
||||
node_info = this.field.get('node_info'),
|
||||
full_url = node.generate_url.apply(
|
||||
node, [
|
||||
null, url, this.field.get('node_data'),
|
||||
this.field.get('url_with_id') || false, node_info,
|
||||
]),
|
||||
cache_level = this.field.get('cache_level') || node.type,
|
||||
cache_node = this.field.get('cache_node');
|
||||
|
||||
cache_node = (cache_node && pgBrowser.Nodes['cache_node']) || node;
|
||||
|
||||
m.trigger('pgadmin:view:fetching', m, self.field);
|
||||
var data = {attrelid: table_id};
|
||||
|
||||
// Fetching Columns data for the selected table.
|
||||
$.ajax({
|
||||
async: false,
|
||||
url: full_url,
|
||||
data: data,
|
||||
})
|
||||
.done(function(res) {
|
||||
/*
|
||||
* We will cache this data for short period of time for avoiding
|
||||
* same calls.
|
||||
*/
|
||||
data = cache_node.cache(url, node_info, cache_level, res.data);
|
||||
|
||||
})
|
||||
.fail(function() {
|
||||
m.trigger('pgadmin:view:fetch:error', m, self.field);
|
||||
});
|
||||
m.trigger('pgadmin:view:fetched', m, self.field);
|
||||
|
||||
// To fetch only options from cache, we do not need time from 'at'
|
||||
// attribute but only options.
|
||||
//
|
||||
// It is feasible that the data may not have been fetched.
|
||||
data = (data && data.data) || [];
|
||||
return data;
|
||||
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
// Constraints Model
|
||||
var ConstraintModel = pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'conoid',
|
||||
initialize: function(attrs) {
|
||||
var isNew = (_.size(attrs) === 0);
|
||||
if (!isNew) {
|
||||
this.convalidated_default = this.get('convalidated');
|
||||
}
|
||||
pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
defaults: {
|
||||
conoid: undefined,
|
||||
conname: undefined,
|
||||
consrc: undefined,
|
||||
connoinherit: undefined,
|
||||
convalidated: true,
|
||||
conislocal: undefined,
|
||||
},
|
||||
convalidated_default: true,
|
||||
schema: [{
|
||||
id: 'conoid', type: 'text', cell: 'string', visible: false,
|
||||
},{
|
||||
id: 'conname', label: gettext('Name'), type: 'text', cell: 'string',
|
||||
editable: 'is_editable', cellHeaderClasses: 'width_percent_30',
|
||||
},{
|
||||
id: 'consrc', label: gettext('Check'), type: 'multiline',
|
||||
editable: 'is_editable', cell: Backgrid.Extension.TextareaCell,
|
||||
cellHeaderClasses: 'width_percent_30',
|
||||
},{
|
||||
id: 'connoinherit', label: gettext('No inherit?'), type: 'switch',
|
||||
cell: 'boolean', editable: 'is_editable',
|
||||
cellHeaderClasses: 'width_percent_20',
|
||||
},{
|
||||
id: 'convalidated', label: gettext('Validate?'), type: 'switch',
|
||||
cell: 'boolean', cellHeaderClasses: 'width_percent_20',
|
||||
editable: function(m) {
|
||||
if (_.isUndefined(m.isNew)) { return true; }
|
||||
if (!m.isNew()) {
|
||||
if(m.get('convalidated') && m.convalidated_default) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
},
|
||||
],
|
||||
validate: function() {
|
||||
var err = {},
|
||||
errmsg;
|
||||
|
||||
if (_.isUndefined(this.get('conname')) || String(this.get('conname')).replace(/^\s+|\s+$/g, '') == '') {
|
||||
err['conname'] = gettext('Constraint Name cannot be empty.');
|
||||
errmsg = err['conname'];
|
||||
}
|
||||
|
||||
if (_.isUndefined(this.get('consrc')) || String(this.get('consrc'))
|
||||
.replace(/^\s+|\s+$/g, '') == '') {
|
||||
err['consrc'] = gettext('Constraint Check cannot be empty.');
|
||||
errmsg = errmsg || err['consrc'];
|
||||
}
|
||||
|
||||
this.errorModel.clear().set(err);
|
||||
|
||||
return errmsg;
|
||||
},
|
||||
is_editable: function(m) {
|
||||
return _.isUndefined(m.isNew) ? true : m.isNew();
|
||||
},
|
||||
toJSON: Backbone.Model.prototype.toJSON,
|
||||
});
|
||||
|
||||
|
||||
// Options Model
|
||||
var OptionsModel = pgBrowser.Node.Model.extend({
|
||||
defaults: {
|
||||
option: undefined,
|
||||
value: undefined,
|
||||
},
|
||||
schema: [{
|
||||
id: 'option', label: gettext('Option'), cell: 'string', type: 'text',
|
||||
editable: true, cellHeaderClasses:'width_percent_50',
|
||||
},{
|
||||
id: 'value', label: gettext('Value'), cell: 'string',type: 'text',
|
||||
editable: true, cellHeaderClasses:'width_percent_50',
|
||||
},
|
||||
],
|
||||
validate: function() {
|
||||
// TODO: Add validation here
|
||||
},
|
||||
toJSON: Backbone.Model.prototype.toJSON,
|
||||
});
|
||||
|
||||
|
||||
if (!pgBrowser.Nodes['foreign_table']) {
|
||||
pgBrowser.Nodes['foreign_table'] = schemaChild.SchemaChildNode.extend({
|
||||
type: 'foreign_table',
|
||||
@@ -561,160 +103,6 @@ define('pgadmin.node.foreign_table', [
|
||||
}
|
||||
);
|
||||
},
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
initialize: function(attrs, args) {
|
||||
var isNew = (_.size(attrs) === 0);
|
||||
if (isNew) {
|
||||
var schema = args.node_info.schema._label,
|
||||
userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
|
||||
|
||||
// Set Selected Schema and Current User
|
||||
this.set({
|
||||
'basensp': schema, 'owner': userInfo.name,
|
||||
}, {silent: true});
|
||||
}
|
||||
pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
defaults: {
|
||||
name: undefined,
|
||||
oid: undefined,
|
||||
owner: undefined,
|
||||
basensp: undefined,
|
||||
is_sys_obj: undefined,
|
||||
description: undefined,
|
||||
ftsrvname: undefined,
|
||||
strftoptions: undefined,
|
||||
inherits: [],
|
||||
columns: [],
|
||||
constraints: [],
|
||||
ftoptions: [],
|
||||
relacl: [],
|
||||
stracl: [],
|
||||
seclabels: [],
|
||||
},
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), cell: 'string',
|
||||
type: 'text', mode: ['properties', 'create', 'edit'],
|
||||
},{
|
||||
id: 'oid', label: gettext('OID'), cell: 'string',
|
||||
type: 'text' , mode: ['properties'],
|
||||
},{
|
||||
id: 'owner', label: gettext('Owner'), cell: 'string',
|
||||
control: Backform.NodeListByNameControl,
|
||||
node: 'role', type: 'text', select2: { allowClear: false },
|
||||
},{
|
||||
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: 'is_sys_obj', label: gettext('System foreign table?'),
|
||||
cell:'boolean', type: 'switch', mode: ['properties'],
|
||||
},{
|
||||
id: 'description', label: gettext('Comment'), cell: 'string',
|
||||
type: 'multiline',
|
||||
},{
|
||||
id: 'ftsrvname', label: gettext('Foreign server'), cell: 'string', control: 'node-ajax-options',
|
||||
type: 'text', group: gettext('Definition'), url: 'get_foreign_servers',
|
||||
readonly: function(m) { return !m.isNew(); }, cache_node: 'database',
|
||||
},{
|
||||
id: 'inherits', label: gettext('Inherits'), group: gettext('Definition'),
|
||||
type: 'array', min_version: 90500, control: NodeAjaxOptionsMultipleControl,
|
||||
url: 'get_tables', select2: {multiple: true},
|
||||
'cache_level': 'database',
|
||||
transform: function(d) {
|
||||
if (this.field.get('mode') == 'edit') {
|
||||
var oid = this.model.get('oid');
|
||||
var s = _.findWhere(d, {'id': oid});
|
||||
if (s) {
|
||||
d = _.reject(d, s);
|
||||
}
|
||||
}
|
||||
return d;
|
||||
},
|
||||
},{
|
||||
id: 'columns', label: gettext('Columns'), cell: 'string',
|
||||
type: 'collection', group: gettext('Columns'), mode: ['edit', 'create'],
|
||||
model: ColumnsModel, canAdd: true, canDelete: true, canEdit: true,
|
||||
columns: ['attname', 'datatype', 'inheritedfrom'],
|
||||
canDeleteRow: function(m) {
|
||||
return (_.isUndefined(m.get('inheritedid')) || _.isNull(m.get('inheritedid'))
|
||||
|| _.isUndefined(m.get('inheritedfrom')) || _.isNull(m.get('inheritedfrom'))) ? true : false;
|
||||
},
|
||||
canEditRow: function(m) {
|
||||
return (_.isUndefined(m.get('inheritedid')) || _.isNull(m.get('inheritedid'))
|
||||
|| _.isUndefined(m.get('inheritedfrom')) || _.isNull(m.get('inheritedfrom'))) ? true : false;
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'constraints', label: gettext('Constraints'), cell: 'string',
|
||||
type: 'collection', group: gettext('Constraints'), mode: ['edit', 'create'],
|
||||
model: ConstraintModel, canAdd: true, canDelete: true, columns: ['conname','consrc', 'connoinherit', 'convalidated'],
|
||||
canEdit: function(o) {
|
||||
if (o instanceof Backbone.Model) {
|
||||
if (o instanceof ConstraintModel) {
|
||||
return o.isNew();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}, min_version: 90500, canDeleteRow: function(m) {
|
||||
return (m.get('conislocal') == true || _.isUndefined(m.get('conislocal'))) ? true : false;
|
||||
},
|
||||
},{
|
||||
id: 'strftoptions', label: gettext('Options'), cell: 'string',
|
||||
type: 'text', group: gettext('Definition'), mode: ['properties'],
|
||||
},{
|
||||
id: 'ftoptions', label: gettext('Options'), cell: 'string',
|
||||
type: 'collection', group: gettext('Options'), mode: ['edit', 'create'],
|
||||
model: OptionsModel, canAdd: true, canDelete: true, canEdit: false,
|
||||
control: 'unique-col-collection', uniqueCol : ['option'],
|
||||
},{
|
||||
id: 'relacl', label: gettext('Privileges'), cell: 'string',
|
||||
type: 'text', group: gettext('Security'),
|
||||
mode: ['properties'], min_version: 90200,
|
||||
}, pgBrowser.SecurityGroupSchema, {
|
||||
id: 'acl', label: gettext('Privileges'), model: pgAdmin
|
||||
.Browser.Node.PrivilegeRoleModel.extend(
|
||||
{privileges: ['a','r','w','x']}), uniqueCol : ['grantee', 'grantor'],
|
||||
editable: false, type: 'collection', group: 'security',
|
||||
mode: ['edit', 'create'],
|
||||
canAdd: true, canDelete: true, control: 'unique-col-collection',
|
||||
min_version: 90200,
|
||||
},{
|
||||
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()
|
||||
{
|
||||
var err = {},
|
||||
errmsg = null;
|
||||
|
||||
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('basensp')) || String(this.get('basensp'))
|
||||
.replace(/^\s+|\s+$/g, '') == '') {
|
||||
err['basensp'] = gettext('Schema cannot be empty.');
|
||||
errmsg = errmsg || err['basensp'];
|
||||
}
|
||||
|
||||
if (_.isUndefined(this.get('ftsrvname')) || String(this.get('ftsrvname')).replace(/^\s+|\s+$/g, '') == '') {
|
||||
err['ftsrvname'] = gettext('Foreign server cannot be empty.');
|
||||
errmsg = errmsg || err['ftsrvname'];
|
||||
}
|
||||
|
||||
this.errorModel.clear().set(err);
|
||||
|
||||
return errmsg;
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@@ -93,32 +93,6 @@ define('pgadmin.node.fts_configuration', [
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
// Defining model for FTS Configuration node
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
|
||||
initialize: function(attrs, opts) {
|
||||
var isNew = (_.size(attrs) === 0);
|
||||
pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
|
||||
|
||||
if (isNew) {
|
||||
var user = pgBrowser.serverInfo[opts.node_info.server._id].user;
|
||||
this.set({
|
||||
'owner': user.name,
|
||||
'schema': opts.node_info.schema._id,
|
||||
}, {silent: true});
|
||||
}
|
||||
},
|
||||
// Defining schema for FTS Configuration
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), cell: 'string',
|
||||
type: 'text', cellHeaderClasses: 'width_percent_50',
|
||||
}, {
|
||||
id: 'description', label: gettext('Comment'), cell: 'string',
|
||||
type: 'multiline', cellHeaderClasses: 'width_percent_50',
|
||||
}],
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -88,31 +88,6 @@ define('pgadmin.node.fts_dictionary', [
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
// Defining backform model for FTS Dictionary node
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
initialize: function(attrs, args) {
|
||||
var isNew = (_.size(attrs) === 0);
|
||||
pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
|
||||
|
||||
if (isNew) {
|
||||
var user = pgBrowser.serverInfo[args.node_info.server._id].user;
|
||||
this.set({
|
||||
'owner': user.name,
|
||||
'schema': args.node_info.schema._id,
|
||||
}, {silent: true});
|
||||
}
|
||||
},
|
||||
// Defining schema for fts dictionary
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), cell: 'string',
|
||||
type: 'text', cellHeaderClasses: 'width_percent_50',
|
||||
}, {
|
||||
id: 'description', label: gettext('Comment'), cell: 'string',
|
||||
type: 'multiline', cellHeaderClasses: 'width_percent_50',
|
||||
}],
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -70,108 +70,6 @@ define('pgadmin.node.fts_parser', [
|
||||
|
||||
},
|
||||
|
||||
// Defining backform model for fts parser node
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
defaults: {
|
||||
name: undefined, // Fts parser name
|
||||
is_sys_obj: undefined, // Is system object
|
||||
description: undefined, // Comment on parser
|
||||
},
|
||||
initialize: function(attrs, args) {
|
||||
var isNew = (_.size(attrs) === 0);
|
||||
pgAdmin.Browser.Node.Model.prototype.initialize.apply(
|
||||
this, arguments
|
||||
);
|
||||
if (isNew) {
|
||||
this.set('schema', args.node_info.schema._id);
|
||||
}
|
||||
},
|
||||
// Defining schema for fts parser
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), cell: 'string',
|
||||
type: 'text', cellHeaderClasses: 'width_percent_50',
|
||||
},{
|
||||
id: 'oid', label: gettext('OID'), cell: 'string',
|
||||
editable: false, type: 'text', mode:['properties'],
|
||||
},{
|
||||
id: 'description', label: gettext('Comment'), cell: 'string',
|
||||
type: 'multiline', cellHeaderClasses: 'width_percent_50',
|
||||
}],
|
||||
|
||||
/*
|
||||
* Triggers control specific error messages for parser name,
|
||||
* start, token, end, lextype functions and schema, if any one of them is not specified
|
||||
* while creating new fts parser
|
||||
*/
|
||||
validate: function() {
|
||||
var name = this.get('name'),
|
||||
start = this.get('prsstart'),
|
||||
token = this.get('prstoken'),
|
||||
end = this.get('prsend'),
|
||||
lextype = this.get('prslextype'),
|
||||
schema = this.get('schema'),
|
||||
msg;
|
||||
|
||||
// Validate fts parser name
|
||||
if (_.isUndefined(name) ||
|
||||
_.isNull(name) ||
|
||||
String(name).replace(/^\s+|\s+$/g, '') == '') {
|
||||
msg = gettext('Name must be specified.');
|
||||
this.errorModel.set('name', msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
// Validate start function control
|
||||
else if (_.isUndefined(start) ||
|
||||
_.isNull(start) ||
|
||||
String(start).replace(/^\s+|\s+$/g, '') == '') {
|
||||
msg = gettext('Start function must be selected.');
|
||||
this.errorModel.set('prsstart', msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
// Validate gettoken function control
|
||||
else if (_.isUndefined(token) ||
|
||||
_.isNull(token) ||
|
||||
String(token).replace(/^\s+|\s+$/g, '') == '') {
|
||||
msg = gettext('Get next token function must be selected.');
|
||||
this.errorModel.set('prstoken', msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
// Validate end function control
|
||||
else if (_.isUndefined(end) ||
|
||||
_.isNull(end) ||
|
||||
String(end).replace(/^\s+|\s+$/g, '') == '') {
|
||||
msg = gettext('End function must be selected.');
|
||||
this.errorModel.set('prsend', msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
// Validate lextype function control
|
||||
else if (_.isUndefined(lextype) ||
|
||||
_.isNull(lextype) ||
|
||||
String(lextype).replace(/^\s+|\s+$/g, '') == '') {
|
||||
msg = gettext('Lextype function must be selected.');
|
||||
this.errorModel.set('prslextype', msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
// Validate schema for fts parser
|
||||
else if (_.isUndefined(schema) ||
|
||||
_.isNull(schema) ||
|
||||
String(schema).replace(/^\s+|\s+$/g, '') == '') {
|
||||
msg = gettext('Schema must be selected.');
|
||||
this.errorModel.set('schema', msg);
|
||||
return msg;
|
||||
}
|
||||
else this.errorModel.clear();
|
||||
|
||||
this.trigger('on-status-clear');
|
||||
return null;
|
||||
},
|
||||
}),
|
||||
getSchema: (treeNodeInfo, itemNodeData) => {
|
||||
let nodeObj = pgAdmin.Browser.Nodes['fts_parser'];
|
||||
return new FTSParserSchema(
|
||||
|
||||
@@ -70,65 +70,6 @@ define('pgadmin.node.fts_template', [
|
||||
|
||||
},
|
||||
|
||||
// Defining backform model for fts template node
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
initialize: function(attrs, args) {
|
||||
var isNew = (_.size(attrs) === 0);
|
||||
pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
|
||||
if (isNew) {
|
||||
this.set('schema', args.node_info.schema._id);
|
||||
}
|
||||
},
|
||||
// Defining schema for fts template
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), cell: 'string',
|
||||
type: 'text', cellHeaderClasses: 'width_percent_50',
|
||||
},{
|
||||
id: 'oid', label: gettext('OID'), cell: 'string',
|
||||
editable: false, type: 'text', mode:['properties'],
|
||||
},{
|
||||
id: 'description', label: gettext('Comment'), cell: 'string',
|
||||
type: 'multiline', cellHeaderClasses: 'width_percent_50',
|
||||
}],
|
||||
|
||||
/*
|
||||
* Triggers control specific error messages for template name,
|
||||
* lexize function and schema, if any one of them is not specified
|
||||
* while creating new fts template
|
||||
*/
|
||||
validate: function() {
|
||||
var name = this.get('name'),
|
||||
lexize = this.get('tmpllexize'),
|
||||
schema = this.get('schema'),
|
||||
msg;
|
||||
|
||||
// Validate fts template name
|
||||
if (_.isUndefined(name) || _.isNull(name) || String(name).replace(/^\s+|\s+$/g, '') == '') {
|
||||
msg = gettext('Name must be specified.');
|
||||
this.errorModel.set('name', msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
// Validate lexize function control
|
||||
else if (_.isUndefined(lexize) || _.isNull(lexize) || String(lexize).replace(/^\s+|\s+$/g, '') == '') {
|
||||
msg = gettext('Lexize function must be selected.');
|
||||
this.errorModel.set('tmpllexize', msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
// Validate schema for fts template
|
||||
else if (_.isUndefined(schema) || _.isNull(schema) || String(schema).replace(/^\s+|\s+$/g, '') == '') {
|
||||
msg = gettext('Schema must be selected.');
|
||||
this.errorModel.set('schema', msg);
|
||||
return msg;
|
||||
}
|
||||
else this.errorModel.clear();
|
||||
|
||||
this.trigger('on-status-clear');
|
||||
return null;
|
||||
},
|
||||
}),
|
||||
getSchema: (treeNodeInfo, itemNodeData) => {
|
||||
let nodeObj = pgAdmin.Browser.Nodes['fts_template'];
|
||||
return new FTSTemplateSchema(
|
||||
|
||||
@@ -11,7 +11,6 @@ import { getNodeAjaxOptions, getNodeListByName, getNodeListById} from '../../../
|
||||
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', [
|
||||
@@ -109,44 +108,7 @@ define('pgadmin.node.function', [
|
||||
}
|
||||
);
|
||||
},
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
initialize: function(attrs, args) {
|
||||
var isNew = (_.size(attrs) === 0);
|
||||
if (isNew) {
|
||||
// Set Selected Schema
|
||||
var schema_id = args.node_info.schema._id;
|
||||
this.set({'pronamespace': schema_id}, {silent: true});
|
||||
|
||||
// Set Current User
|
||||
var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
|
||||
this.set({'funcowner': userInfo.name}, {silent: true});
|
||||
}
|
||||
pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), cell: 'string',
|
||||
type: 'text', mode: ['properties', 'create', 'edit'],
|
||||
disabled: 'isDisabled',
|
||||
},{
|
||||
id: 'oid', label: gettext('OID'), cell: 'string',
|
||||
type: 'text' , mode: ['properties'],
|
||||
},{
|
||||
id: 'funcowner', label: gettext('Owner'), cell: 'string',
|
||||
control: Backform.NodeListByNameControl, node: 'role', type:
|
||||
'text', disabled: 'isDisabled',
|
||||
},{
|
||||
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: 'description', label: gettext('Comment'), cell: 'string',
|
||||
type: 'multiline', disabled: 'isDisabled',
|
||||
}],
|
||||
}),
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return pgBrowser.Nodes['function'];
|
||||
});
|
||||
|
||||
@@ -11,7 +11,6 @@ import { getNodeAjaxOptions, getNodeListByName, getNodeListById} from '../../../
|
||||
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', [
|
||||
@@ -126,126 +125,6 @@ define('pgadmin.node.procedure', [
|
||||
);
|
||||
},
|
||||
|
||||
model: Function.model.extend({
|
||||
defaults: _.extend({},
|
||||
Function.model.prototype.defaults,
|
||||
{
|
||||
lanname: 'edbspl',
|
||||
}
|
||||
),
|
||||
canVarAdd: function() {
|
||||
var server = this.node_info.server;
|
||||
return server.version >= 90500;
|
||||
},
|
||||
isVisible: function() {
|
||||
if (this.name == 'sysfunc') { return false; }
|
||||
else if (this.name == 'sysproc') { return true; }
|
||||
return false;
|
||||
},
|
||||
isDisabled: function(m) {
|
||||
if(this.node_info && 'catalog' in this.node_info) {
|
||||
return true;
|
||||
}
|
||||
switch(this.name){
|
||||
case 'provolatile':
|
||||
case 'proisstrict':
|
||||
case 'procost':
|
||||
case 'proleakproof':
|
||||
if(this.node_info.server.version < 90500 ||
|
||||
this.node_info.server.server_type != 'ppas' ||
|
||||
m.get('lanname') != 'edbspl') {
|
||||
|
||||
setTimeout(function() {
|
||||
m.set('provolatile', null);
|
||||
m.set('proisstrict', false);
|
||||
m.set('procost', null);
|
||||
m.set('proleakproof', false);
|
||||
}, 10);
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
return false;
|
||||
}
|
||||
case 'variables':
|
||||
case 'prosecdef':
|
||||
return this.node_info.server.version < 90500;
|
||||
case 'prorows':
|
||||
var server = this.node_info.server;
|
||||
return !(server.version >= 90500 && m.get('proretset') == true);
|
||||
case 'proparallel':
|
||||
if (this.node_info.server.version < 90600 ||
|
||||
this.node_info.server.server_type != 'ppas' ||
|
||||
m.get('lanname') != 'edbspl') {
|
||||
setTimeout(function() {
|
||||
m.set('proparallel', null);
|
||||
}, 10);
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
return false;
|
||||
}
|
||||
case 'lanname':
|
||||
return this.node_info.server.version < 110000;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
},
|
||||
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('pronamespace')) || String(this.get('pronamespace')).replace(/^\s+|\s+$/g, '') == '') {
|
||||
err['pronamespace'] = gettext('Schema cannot be empty.');
|
||||
errmsg = errmsg || err['pronamespace'];
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
return null;
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@@ -107,151 +107,6 @@ define('pgadmin.node.trigger_function', [
|
||||
}
|
||||
);
|
||||
},
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
initialize: function(attrs, args) {
|
||||
var isNew = (_.size(attrs) === 0);
|
||||
if (isNew) {
|
||||
// Set Selected Schema
|
||||
var schema_id = args.node_info.schema._id;
|
||||
this.set({'pronamespace': schema_id}, {silent: true});
|
||||
|
||||
// Set Current User
|
||||
var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
|
||||
this.set({'funcowner': userInfo.name}, {silent: true});
|
||||
}
|
||||
pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
defaults: {
|
||||
name: undefined,
|
||||
oid: undefined,
|
||||
funcowner: undefined,
|
||||
description: undefined,
|
||||
},
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), cell: 'string',
|
||||
type: 'text', mode: ['properties', 'create', 'edit'],
|
||||
disabled: 'isDisabled', readonly: 'isReadonly',
|
||||
},{
|
||||
id: 'oid', label: gettext('OID'), cell: 'string',
|
||||
type: 'text' , mode: ['properties'],
|
||||
},{
|
||||
id: 'funcowner', label: gettext('Owner'), cell: 'string',
|
||||
control: Backform.NodeListByNameControl, node: 'role', type:
|
||||
'text', disabled: 'isDisabled', readonly: 'isReadonly',
|
||||
},{
|
||||
id: 'description', label: gettext('Comment'), cell: 'string',
|
||||
type: 'multiline', disabled: 'isDisabled', readonly: 'isReadonly',
|
||||
}],
|
||||
validate: function(keys)
|
||||
{
|
||||
var err = {},
|
||||
errmsg,
|
||||
seclabels = this.get('seclabels');
|
||||
|
||||
// Nothing to validate
|
||||
if(keys && keys.length == 0) {
|
||||
this.errorModel.clear();
|
||||
return null;
|
||||
}
|
||||
|
||||
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;
|
||||
},
|
||||
isReadonly: function(m) {
|
||||
switch(this.name){
|
||||
case 'proargs':
|
||||
case 'proargtypenames':
|
||||
case 'prorettypename':
|
||||
case 'proretset':
|
||||
case 'proiswindow':
|
||||
return !m.isNew();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
},
|
||||
isDisabled: function(m) {
|
||||
if(this.node_info && 'catalog' in this.node_info) {
|
||||
return true;
|
||||
}
|
||||
if (this.name === 'prorows'){
|
||||
if(m.get('proretset') == true) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
canVarAdd: function() {
|
||||
return !(this.node_info && 'catalog' in this.node_info);
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@@ -45,37 +45,6 @@ define('pgadmin.node.operator', [
|
||||
|
||||
this.initialized = true;
|
||||
},
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
|
||||
// Default values!
|
||||
initialize: function(attrs, args) {
|
||||
var isNew = (_.size(attrs) === 0);
|
||||
|
||||
if (isNew) {
|
||||
var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
|
||||
var schemaInfo = args.node_info.schema;
|
||||
|
||||
this.set({'owner': userInfo.name}, {silent: true});
|
||||
this.set({'schema': schemaInfo._label}, {silent: true});
|
||||
}
|
||||
pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Operator'), cell: 'string',
|
||||
type: 'text', mode: ['properties', 'create', 'edit'],
|
||||
},{
|
||||
id: 'owner', label: gettext('Owner'), cell: 'string',
|
||||
type: 'text', mode: ['properties', 'create', 'edit'],
|
||||
control: 'node-list-by-name',
|
||||
node: 'role',
|
||||
},{
|
||||
id: 'description', label: gettext('Comment'), cell: 'string',
|
||||
type: 'multiline', mode: ['properties', 'create', 'edit'],
|
||||
}
|
||||
],
|
||||
}),
|
||||
getSchema: ()=>{
|
||||
return new OperatorSchema();
|
||||
}
|
||||
|
||||
@@ -48,16 +48,6 @@ define('pgadmin.node.edbvar', [
|
||||
},
|
||||
canDrop: false,
|
||||
canDropCascade: false,
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), cell: 'string',
|
||||
type: 'text', mode: ['properties'],
|
||||
},{
|
||||
id: 'oid', label: gettext('OID'), cell: 'string',
|
||||
type: 'text' , mode: ['properties'],
|
||||
}]
|
||||
}),
|
||||
getSchema: () => {
|
||||
return new EDBVarSchema();
|
||||
}
|
||||
|
||||
@@ -92,41 +92,6 @@ define('pgadmin.node.package', [
|
||||
// by default we want to allow create menu
|
||||
return true;
|
||||
},
|
||||
// Define the model for package node.
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
initialize: function(attrs, args) {
|
||||
if (_.size(attrs) === 0) {
|
||||
var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
|
||||
var schemaInfo = args.node_info.schema;
|
||||
|
||||
this.set({
|
||||
'owner': userInfo.name, 'schema': schemaInfo._label,
|
||||
}, {silent: true});
|
||||
}
|
||||
pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
// Define the schema for package node.
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), cell: 'string',
|
||||
type: 'text', mode: ['properties', 'create', 'edit'],
|
||||
readonly: function(m) {
|
||||
return !m.isNew();
|
||||
},
|
||||
},{
|
||||
id: 'oid', label: gettext('OID'), cell: 'string',
|
||||
type: 'text', mode: ['properties'],
|
||||
},{
|
||||
id: 'owner', label: gettext('Owner'), cell: 'string',
|
||||
type: 'text', mode: ['properties', 'create', 'edit'],
|
||||
readonly: true, editable: false, visible: function(m) {
|
||||
return !m.isNew();
|
||||
},
|
||||
},{
|
||||
id: 'description', label: gettext('Comment'), type: 'multiline',
|
||||
mode: ['properties', 'create', 'edit'],
|
||||
}]
|
||||
}),
|
||||
getSchema: (treeNodeInfo, itemNodeData) => {
|
||||
var nodeObj = pgBrowser.Nodes['package'];
|
||||
return new PackageSchema(
|
||||
|
||||
@@ -106,41 +106,6 @@ define('pgadmin.node.sequence', [
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
// Define the model for sequence node.
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
|
||||
// Default values!
|
||||
initialize: function(attrs, args) {
|
||||
var isNew = (_.size(attrs) === 0);
|
||||
|
||||
if (isNew) {
|
||||
var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
|
||||
var schemaInfo = args.node_info.schema;
|
||||
|
||||
this.set({'seqowner': userInfo.name}, {silent: true});
|
||||
this.set({'schema': schemaInfo._label}, {silent: true});
|
||||
}
|
||||
pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
|
||||
// Define the schema for sequence node.
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), cell: 'string',
|
||||
type: 'text', mode: ['properties', 'create', 'edit'],
|
||||
},{
|
||||
id: 'oid', label: gettext('OID'), cell: 'string',
|
||||
type: 'text', mode: ['properties'],
|
||||
},{
|
||||
id: 'seqowner', label: gettext('Owner'), cell: 'string',
|
||||
type: 'text', mode: ['properties', 'create', 'edit'], node: 'role',
|
||||
control: Backform.NodeListByNameControl,
|
||||
},{
|
||||
id: 'comment', label: gettext('Comment'), type: 'multiline',
|
||||
mode: ['properties', 'create', 'edit'],
|
||||
}],
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -42,25 +42,6 @@ define('pgadmin.node.catalog', [
|
||||
this.initialized = true;
|
||||
|
||||
},
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
initialize: function(attrs, args) {
|
||||
var isNew = (_.size(attrs) === 0);
|
||||
|
||||
if (isNew) {
|
||||
var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
|
||||
|
||||
this.set({'namespaceowner': userInfo.name}, {silent: true});
|
||||
}
|
||||
pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), cell: 'string',
|
||||
type: 'text', readonly: true,
|
||||
},{
|
||||
id: 'oid', label: gettext('OID'), cell: 'string', mode: ['properties'],
|
||||
type: 'text',
|
||||
}]
|
||||
}),
|
||||
getSchema: function(treeNodeInfo) {
|
||||
return new CatalogSchema(
|
||||
{
|
||||
|
||||
@@ -361,36 +361,6 @@ define('pgadmin.node.schema', [
|
||||
can_create_schema: function(node) {
|
||||
return pgBrowser.Nodes['database'].is_conn_allow.call(this, node);
|
||||
},
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
initialize: function(attrs, args) {
|
||||
var isNew = (_.size(attrs) === 0);
|
||||
|
||||
if (isNew) {
|
||||
var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
|
||||
|
||||
this.set({'namespaceowner': userInfo.name}, {silent: true});
|
||||
}
|
||||
pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), cell: 'string',
|
||||
type: 'text',
|
||||
},{
|
||||
id: 'oid', label: gettext('OID'), cell: 'string',
|
||||
type: 'text', mode: ['properties'],
|
||||
},{
|
||||
id: 'namespaceowner', label: gettext('Owner'), cell: 'string',
|
||||
type: 'text', control: 'node-list-by-name', node: 'role',
|
||||
select2: { allowClear: false },
|
||||
},{
|
||||
id: 'is_sys_obj', label: gettext('System schema?'),
|
||||
cell: 'switch', type: 'switch', mode: ['properties'],
|
||||
},{
|
||||
id: 'description', label: gettext('Comment'), cell: 'string',
|
||||
type: 'multiline'
|
||||
}]
|
||||
}),
|
||||
getSchema: function(treeNodeInfo, itemNodeData) {
|
||||
var schemaObj = pgBrowser.Nodes['schema'];
|
||||
return new PGSchema(
|
||||
|
||||
@@ -100,54 +100,6 @@ define('pgadmin.node.synonym', [
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
isNew: function() {
|
||||
return !this.fetchFromServer;
|
||||
},
|
||||
idAttribute: 'oid',
|
||||
// Default values!
|
||||
initialize: function(attrs, args) {
|
||||
var isNew = (_.size(attrs) === 0);
|
||||
|
||||
if (isNew) {
|
||||
var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
|
||||
var schemaInfo = args.node_info.schema;
|
||||
this.set({
|
||||
'owner': userInfo.name,
|
||||
'synobjschema': schemaInfo._label,
|
||||
'schema': schemaInfo._label,
|
||||
'targettype': 'r',
|
||||
}, {silent: true});
|
||||
} else {
|
||||
this.fetchFromServer = true;
|
||||
}
|
||||
pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
|
||||
|
||||
},
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), cell: 'string',
|
||||
type: 'text', mode: ['properties', 'create', 'edit'],
|
||||
disabled: 'inSchema', readonly: function(m) { return !m.isNew(); },
|
||||
},{
|
||||
id: 'oid', label: gettext('OID'), cell: 'string',
|
||||
type: 'text', mode: ['properties'],
|
||||
},{
|
||||
id: 'owner', label: gettext('Owner'), cell: 'string',
|
||||
type: 'text', mode: ['properties', 'create', 'edit'],
|
||||
readonly: true , control: 'node-list-by-name',
|
||||
node: 'role', visible: false,
|
||||
}],
|
||||
|
||||
// We will disable everything if we are under catalog node
|
||||
inSchema: function() {
|
||||
if(this.node_info && 'catalog' in this.node_info)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
}),
|
||||
canCreate: function(itemData, item, data) {
|
||||
//If check is false then , we will allow create menu
|
||||
if (data && data.check == false)
|
||||
|
||||
@@ -98,36 +98,6 @@ define('pgadmin.node.column', [
|
||||
getSchema: function(treeNodeInfo, itemNodeData) {
|
||||
return getNodeColumnSchema(treeNodeInfo, itemNodeData, pgBrowser);
|
||||
},
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'attnum',
|
||||
|
||||
defaults: {
|
||||
name: undefined,
|
||||
attnum: undefined,
|
||||
description: undefined,
|
||||
},
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), cell: 'string',
|
||||
type: 'text', disabled: 'inSchemaWithColumnCheck',
|
||||
cellHeaderClasses:'width_percent_30',
|
||||
editable: 'editable_check_for_table',
|
||||
},{
|
||||
id: 'attnum', label: gettext('Position'), cell: 'string',
|
||||
type: 'text', disabled: 'notInSchema', mode: ['properties'],
|
||||
},{
|
||||
id: 'description', label: gettext('Comment'), cell: 'string',
|
||||
type: 'multiline', mode: ['properties', 'create', 'edit'],
|
||||
disabled: 'notInSchema',
|
||||
}],
|
||||
// We will check if we are under schema node & in 'create' mode
|
||||
notInSchema: function() {
|
||||
if(this.node_info && 'catalog' in this.node_info)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
}),
|
||||
// Below function will enable right click menu for creating column
|
||||
canCreate: function(itemData, item, data) {
|
||||
// If check is false then , we will allow create menu
|
||||
|
||||
@@ -189,16 +189,6 @@ define('pgadmin.node.compound_trigger', [
|
||||
);
|
||||
},
|
||||
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), cell: 'string',
|
||||
type: 'text',
|
||||
}, {
|
||||
id: 'description', label: gettext('Comment'), cell: 'string',
|
||||
type: 'multiline', mode: ['properties', 'create', 'edit'],
|
||||
}],
|
||||
}),
|
||||
canCreate: function(itemData, item, data) {
|
||||
//If check is false then , we will allow create menu
|
||||
if (data && data.check == false)
|
||||
|
||||
@@ -43,24 +43,6 @@ define('pgadmin.node.constraints', [
|
||||
|
||||
pgBrowser.add_menus([]);
|
||||
},
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
defaults: {
|
||||
name: undefined,
|
||||
oid: undefined,
|
||||
comment: undefined,
|
||||
},
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), type: 'text',
|
||||
mode: ['properties', 'create', 'edit'],
|
||||
},{
|
||||
id: 'oid', label: gettext('Oid'), cell: 'string',
|
||||
type: 'text' , mode: ['properties'],
|
||||
},{
|
||||
id: 'comment', label: gettext('Comment'), cell: 'string',
|
||||
type: 'multiline', mode: ['properties', 'create', 'edit'],
|
||||
}],
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -92,29 +92,6 @@ define('pgadmin.node.index', [
|
||||
},
|
||||
canDrop: SchemaChildTreeNode.isTreeItemOfChildOfSchema,
|
||||
canDropCascade: SchemaChildTreeNode.isTreeItemOfChildOfSchema,
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
|
||||
defaults: {
|
||||
name: undefined,
|
||||
oid: undefined,
|
||||
nspname: undefined,
|
||||
tabname: undefined,
|
||||
spcname: undefined,
|
||||
amname: 'btree',
|
||||
},
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), cell: 'string',
|
||||
type: 'text', disabled: 'inSchema',
|
||||
},{
|
||||
id: 'oid', label: gettext('OID'), cell: 'string',
|
||||
type: 'int', readonly: true, mode: ['properties'],
|
||||
}, {
|
||||
id: 'description', label: gettext('Comment'), cell: 'string',
|
||||
type: 'multiline', mode: ['properties', 'create', 'edit'],
|
||||
disabled: 'inSchema',
|
||||
}],
|
||||
}),
|
||||
// Below function will enable right click menu for creating column
|
||||
canCreate: function(itemData, item, data) {
|
||||
// If check is false then , we will allow create menu
|
||||
|
||||
@@ -305,49 +305,6 @@ function(
|
||||
getSchema: function(treeNodeInfo, itemNodeData) {
|
||||
return getNodePartitionTableSchema(treeNodeInfo, itemNodeData, pgBrowser);
|
||||
},
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
defaults: {
|
||||
name: undefined,
|
||||
oid: undefined,
|
||||
description: undefined,
|
||||
is_partitioned: false,
|
||||
partition_value: undefined,
|
||||
},
|
||||
// Default values!
|
||||
initialize: function(attrs, args) {
|
||||
if (_.size(attrs) === 0) {
|
||||
var userInfo = pgBrowser.serverInfo[
|
||||
args.node_info.server._id
|
||||
].user,
|
||||
schemaInfo = args.node_info.schema;
|
||||
|
||||
this.set({
|
||||
'relowner': userInfo.name, 'schema': schemaInfo._label,
|
||||
}, {silent: true});
|
||||
}
|
||||
pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
|
||||
|
||||
},
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), type: 'text',
|
||||
mode: ['properties', 'create', 'edit'],
|
||||
},{
|
||||
id: 'oid', label: gettext('OID'), type: 'text', mode: ['properties'],
|
||||
},{
|
||||
id: 'schema', label: gettext('Schema'), type: 'text', node: 'schema',
|
||||
mode: ['create', 'edit', 'properties'],
|
||||
},{
|
||||
id: 'is_partitioned', label:gettext('Partitioned table?'), cell: 'switch',
|
||||
type: 'switch', mode: ['properties', 'create', 'edit'],
|
||||
},{
|
||||
id: 'partition_value', label:gettext('Partition Scheme'),
|
||||
type: 'text', visible: false,
|
||||
},{
|
||||
id: 'description', label: gettext('Comment'), type: 'multiline',
|
||||
mode: ['properties', 'create', 'edit'],
|
||||
}],
|
||||
}),
|
||||
canCreate: SchemaChildTreeNode.isTreeItemOfChildOfSchema,
|
||||
// Check to whether table has disable trigger(s)
|
||||
canCreate_with_trigger_enable: function(itemData, item, data) {
|
||||
|
||||
@@ -88,64 +88,6 @@ define('pgadmin.node.row_security_policy', [
|
||||
}
|
||||
);
|
||||
},
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
defaults: {
|
||||
name: undefined,
|
||||
},
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), cell: 'string',
|
||||
type: 'text', readonly: true, cellHeaderClasses: 'width_percent_50',
|
||||
mode: ['properties']
|
||||
},{
|
||||
id: 'oid', label: gettext('OID'), cell: 'string',
|
||||
editable: false, type: 'text', mode: ['properties'],
|
||||
}],
|
||||
validate: function(keys) {
|
||||
var msg;
|
||||
this.errorModel.clear();
|
||||
// If nothing to validate
|
||||
if (keys && keys.length == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if(_.isUndefined(this.get('name'))
|
||||
|| String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
|
||||
msg = gettext('Name cannot be empty.');
|
||||
this.errorModel.set('name', msg);
|
||||
return msg;
|
||||
}
|
||||
if (!this.isNew() && !_.isNull(this.get('using_orig')) && this.get('using_orig') != '' && String(this.get('using')).replace(/^\s+|\s+$/g, '') == ''){
|
||||
msg = gettext('"USING" can not be empty once the value is set');
|
||||
this.errorModel.set('using', msg);
|
||||
return msg;
|
||||
}
|
||||
if (!this.isNew() && !_.isNull(this.get('withcheck_orig')) && this.get('withcheck_orig') != '' && String(this.get('withcheck')).replace(/^\s+|\s+$/g, '') == ''){
|
||||
msg = gettext('"Withcheck" can not be empty once the value is set');
|
||||
this.errorModel.set('withcheck', msg);
|
||||
return msg;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
disableWithCheck: function(m){
|
||||
var event = m.get('event');
|
||||
if ((event == 'SELECT') || (event == 'DELETE')){
|
||||
m.set('withcheck', '');
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
disableUsing: function(m){
|
||||
var event = m.get('event');
|
||||
|
||||
if (event == 'INSERT'){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
}),
|
||||
canCreate: function(itemData, item) {
|
||||
|
||||
var treeData = pgBrowser.tree.getTreeNodeHierarchy(item),
|
||||
|
||||
@@ -207,54 +207,6 @@ define('pgadmin.node.rule', [
|
||||
}
|
||||
);
|
||||
},
|
||||
/**
|
||||
Define model for the rule node and specify the node
|
||||
properties of the model in schema.
|
||||
*/
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'),
|
||||
type: 'text', disabled: function(m) {
|
||||
// disable name field it it is system rule
|
||||
if (m && m.get('name') == '_RETURN') {
|
||||
return true;
|
||||
}
|
||||
if (m.isNew && m.isNew() || m.node_info && m.node_info.server.version >= 90400) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'oid', label: gettext('OID'),
|
||||
type: 'text', mode: ['properties'],
|
||||
},
|
||||
{
|
||||
id: 'comment', label: gettext('Comment'), cell: 'string', type: 'multiline',
|
||||
},
|
||||
],
|
||||
validate: function() {
|
||||
|
||||
// Triggers specific error messages for fields
|
||||
var err = {},
|
||||
errmsg,
|
||||
field_name = this.get('name');
|
||||
if (_.isUndefined(field_name) || _.isNull(field_name) ||
|
||||
String(field_name).replace(/^\s+|\s+$/g, '') === '')
|
||||
{
|
||||
err['name'] = gettext('Please specify name.');
|
||||
errmsg = err['name'];
|
||||
this.errorModel.set('name', errmsg);
|
||||
return errmsg;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.errorModel.unset('name');
|
||||
}
|
||||
return null;
|
||||
},
|
||||
}),
|
||||
|
||||
// Show or hide create rule menu option on parent node
|
||||
canCreate: function(itemData, item, data) {
|
||||
|
||||
@@ -187,468 +187,6 @@ define('pgadmin.node.trigger', [
|
||||
},
|
||||
);
|
||||
},
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
defaults: {
|
||||
name: undefined,
|
||||
is_row_trigger: true,
|
||||
fires: 'BEFORE',
|
||||
},
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), cell: 'string',
|
||||
type: 'text', disabled: 'inSchema',
|
||||
},{
|
||||
id: 'oid', label: gettext('OID'), cell: 'string',
|
||||
type: 'int', mode: ['properties'],
|
||||
},{
|
||||
id: 'is_enable_trigger', label: gettext('Trigger enabled?'),
|
||||
mode: ['edit', 'properties'], group: gettext('Definition'),
|
||||
disabled: function() {
|
||||
if(this.node_info && ('catalog' in this.node_info || 'view' in this.node_info)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
options: [
|
||||
{label: gettext('Enable'), value: 'O'},
|
||||
{label: gettext('Enable Replica'), value: 'R'},
|
||||
{label: gettext('Enable Always'), value: 'A'},
|
||||
{label: gettext('Disable'), value: 'D'},
|
||||
],
|
||||
control: 'select2', select2: { allowClear: false, width: '100%' },
|
||||
},{
|
||||
id: 'is_row_trigger', label: gettext('Row trigger?'),
|
||||
type: 'switch', group: gettext('Definition'),
|
||||
mode: ['create','edit', 'properties'],
|
||||
deps: ['is_constraint_trigger'],
|
||||
disabled: function(m) {
|
||||
// Disabled if table is a partitioned table.
|
||||
if (!m.isNew())
|
||||
return true;
|
||||
|
||||
if (_.has(m, 'node_info') && _.has(m.node_info, 'table') &&
|
||||
_.has(m.node_info.table, 'is_partitioned') &&
|
||||
m.node_info.table.is_partitioned && m.node_info.server.version < 110000
|
||||
)
|
||||
{
|
||||
setTimeout(function(){
|
||||
m.set('is_row_trigger', false);
|
||||
},10);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// If constraint trigger is set to True then row trigger will
|
||||
// automatically set to True and becomes disable
|
||||
var is_constraint_trigger = m.get('is_constraint_trigger');
|
||||
if(!m.inSchemaWithModelCheck.apply(this, [m])) {
|
||||
if(!_.isUndefined(is_constraint_trigger) &&
|
||||
is_constraint_trigger === true) {
|
||||
// change it's model value
|
||||
setTimeout(function() { m.set('is_row_trigger', true); }, 10);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Check if it is row trigger then enabled it.
|
||||
var is_row_trigger = m.get('is_row_trigger');
|
||||
if (!_.isUndefined(is_row_trigger) && m.node_info['server']['server_type'] == 'ppas') {
|
||||
return false;
|
||||
}
|
||||
// Disable it
|
||||
return true;
|
||||
}
|
||||
},
|
||||
},{
|
||||
id: 'is_constraint_trigger', label: gettext('Constraint trigger?'),
|
||||
type: 'switch',
|
||||
mode: ['create','edit', 'properties'],
|
||||
group: gettext('Definition'),
|
||||
deps: ['tfunction'],
|
||||
disabled: function(m) {
|
||||
// Disabled if table is a partitioned table.
|
||||
var tfunction = m.get('tfunction');
|
||||
if ((_.has(m, 'node_info') && _.has(m.node_info, 'table') &&
|
||||
_.has(m.node_info.table, 'is_partitioned') &&
|
||||
m.node_info.table.is_partitioned) ||
|
||||
_.indexOf(Object.keys(m.node_info), 'view') != -1 ||
|
||||
(m.node_info.server.server_type === 'ppas' &&
|
||||
!_.isUndefined(tfunction) &&
|
||||
tfunction === 'Inline EDB-SPL')) {
|
||||
setTimeout(function(){
|
||||
m.set('is_constraint_trigger', false);
|
||||
},10);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return m.inSchemaWithModelCheck.apply(this, [m]);
|
||||
},
|
||||
},{
|
||||
id: 'tgdeferrable', label: gettext('Deferrable?'),
|
||||
type: 'switch', group: gettext('Definition'),
|
||||
mode: ['create','edit', 'properties'],
|
||||
deps: ['is_constraint_trigger'],
|
||||
disabled: function(m) {
|
||||
// If constraint trigger is set to True then only enable it
|
||||
var is_constraint_trigger = m.get('is_constraint_trigger');
|
||||
if(!m.inSchemaWithModelCheck.apply(this, [m])) {
|
||||
if(!_.isUndefined(is_constraint_trigger) &&
|
||||
is_constraint_trigger === true) {
|
||||
return false;
|
||||
} else {
|
||||
// If value is already set then reset it to false
|
||||
if(m.get('tgdeferrable')) {
|
||||
setTimeout(function() { m.set('tgdeferrable', false); }, 10);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// Disable it
|
||||
return true;
|
||||
}
|
||||
},
|
||||
},{
|
||||
id: 'tginitdeferred', label: gettext('Deferred?'),
|
||||
type: 'switch', group: gettext('Definition'),
|
||||
mode: ['create','edit', 'properties'],
|
||||
deps: ['tgdeferrable', 'is_constraint_trigger'],
|
||||
disabled: function(m) {
|
||||
// If Deferrable is set to True then only enable it
|
||||
var tgdeferrable = m.get('tgdeferrable');
|
||||
if(!m.inSchemaWithModelCheck.apply(this, [m])) {
|
||||
if(!_.isUndefined(tgdeferrable) &&
|
||||
tgdeferrable) {
|
||||
return false;
|
||||
} else {
|
||||
// If value is already set then reset it to false
|
||||
if(m.get('tginitdeferred')) {
|
||||
setTimeout(function() { m.set('tginitdeferred', false); }, 10);
|
||||
}
|
||||
// If constraint trigger is set then do not disable
|
||||
return m.get('is_constraint_trigger') ? false : true;
|
||||
}
|
||||
} else {
|
||||
// Disable it
|
||||
return true;
|
||||
}
|
||||
},
|
||||
},{
|
||||
id: 'tfunction', label: gettext('Trigger function'),
|
||||
type: 'text', disabled: 'inSchemaWithModelCheck',
|
||||
mode: ['create','edit', 'properties'], group: gettext('Definition'),
|
||||
control: 'node-ajax-options', url: 'get_triggerfunctions', url_jump_after_node: 'schema',
|
||||
cache_node: 'trigger_function',
|
||||
},{
|
||||
id: 'tgargs', label: gettext('Arguments'), cell: 'string',
|
||||
group: gettext('Definition'),
|
||||
type: 'text',mode: ['create','edit', 'properties'], deps: ['tfunction'],
|
||||
disabled: function(m) {
|
||||
// We will disable it when EDB PPAS and trigger function is
|
||||
// set to Inline EDB-SPL
|
||||
var tfunction = m.get('tfunction'),
|
||||
server_type = m.node_info['server']['server_type'];
|
||||
if(!m.inSchemaWithModelCheck.apply(this, [m])) {
|
||||
if(server_type === 'ppas' &&
|
||||
!_.isUndefined(tfunction) &&
|
||||
tfunction === 'Inline EDB-SPL') {
|
||||
// Disable and clear its value
|
||||
m.set('tgargs', undefined);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Disable it
|
||||
return true;
|
||||
}
|
||||
},
|
||||
},{
|
||||
id: 'fires', label: gettext('Fires'), deps: ['is_constraint_trigger'],
|
||||
mode: ['create','edit', 'properties'], group: gettext('Events'),
|
||||
options: function(control) {
|
||||
var table_options = [
|
||||
{label: 'BEFORE', value: 'BEFORE'},
|
||||
{label: 'AFTER', value: 'AFTER'}],
|
||||
view_options = [
|
||||
{label: 'BEFORE', value: 'BEFORE'},
|
||||
{label: 'AFTER', value: 'AFTER'},
|
||||
{label: 'INSTEAD OF', value: 'INSTEAD OF'}];
|
||||
// If we are under table then show table specific options
|
||||
if(_.indexOf(Object.keys(control.model.node_info), 'table') != -1) {
|
||||
return table_options;
|
||||
} else {
|
||||
return view_options;
|
||||
}
|
||||
},
|
||||
control: 'select2', select2: { allowClear: false, width: '100%' },
|
||||
disabled: function(m) {
|
||||
if (!m.isNew())
|
||||
return true;
|
||||
// If contraint trigger is set to True then only enable it
|
||||
var is_constraint_trigger = m.get('is_constraint_trigger');
|
||||
if(!m.inSchemaWithModelCheck.apply(this, [m])) {
|
||||
if(!_.isUndefined(is_constraint_trigger) &&
|
||||
is_constraint_trigger === true) {
|
||||
setTimeout(function() { m.set('fires', 'AFTER'); }, 10);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Check if it is row trigger then enabled it.
|
||||
var fires_ = m.get('fires');
|
||||
if (!_.isUndefined(fires_) && m.node_info['server']['server_type'] == 'ppas') {
|
||||
return false;
|
||||
}
|
||||
// Disable it
|
||||
return true;
|
||||
}
|
||||
},
|
||||
},{
|
||||
type: 'nested', control: 'fieldset', mode: ['create','edit', 'properties'],
|
||||
label: gettext('Events'), group: gettext('Events'), contentClass: 'row',
|
||||
schema:[{
|
||||
id: 'evnt_insert', label: gettext('INSERT'),
|
||||
type: 'switch', mode: ['create','edit', 'properties'],
|
||||
group: gettext('Events'),
|
||||
extraToggleClasses: 'pg-el-sm-6',
|
||||
controlLabelClassName: 'control-label pg-el-sm-5 pg-el-12',
|
||||
controlsClassName: 'pgadmin-controls pg-el-sm-7 pg-el-12',
|
||||
disabled: function(m) {
|
||||
var evn_insert = m.get('evnt_insert');
|
||||
if (!_.isUndefined(evn_insert) && m.node_info['server']['server_type'] == 'ppas' && m.isNew())
|
||||
return false;
|
||||
return m.inSchemaWithModelCheck.apply(this, [m]);
|
||||
},
|
||||
},{
|
||||
id: 'evnt_update', label: gettext('UPDATE'),
|
||||
type: 'switch', mode: ['create','edit', 'properties'],
|
||||
group: gettext('Events'),
|
||||
extraToggleClasses: 'pg-el-sm-6',
|
||||
controlLabelClassName: 'control-label pg-el-sm-5 pg-el-12',
|
||||
controlsClassName: 'pgadmin-controls pg-el-sm-7 pg-el-12',
|
||||
disabled: function(m) {
|
||||
var evn_update = m.get('evnt_update');
|
||||
if (!_.isUndefined(evn_update) && m.node_info['server']['server_type'] == 'ppas' && m.isNew())
|
||||
return false;
|
||||
return m.inSchemaWithModelCheck.apply(this, [m]);
|
||||
},
|
||||
},{
|
||||
id: 'evnt_delete', label: gettext('DELETE'),
|
||||
type: 'switch', mode: ['create','edit', 'properties'],
|
||||
group: gettext('Events'),
|
||||
extraToggleClasses: 'pg-el-sm-6',
|
||||
controlLabelClassName: 'control-label pg-el-sm-5 pg-el-12',
|
||||
controlsClassName: 'pgadmin-controls pg-el-sm-7 pg-el-12',
|
||||
disabled: function(m) {
|
||||
var evn_delete = m.get('evnt_delete');
|
||||
if (!_.isUndefined(evn_delete) && m.node_info['server']['server_type'] == 'ppas' && m.isNew())
|
||||
return false;
|
||||
return m.inSchemaWithModelCheck.apply(this, [m]);
|
||||
},
|
||||
},{
|
||||
id: 'evnt_truncate', label: gettext('TRUNCATE'),
|
||||
type: 'switch', group: gettext('Events'),deps: ['is_row_trigger', 'is_constraint_trigger'],
|
||||
extraToggleClasses: 'pg-el-sm-6',
|
||||
controlLabelClassName: 'control-label pg-el-sm-5 pg-el-12',
|
||||
controlsClassName: 'pgadmin-controls pg-el-sm-7 pg-el-12',
|
||||
disabled: function(m) {
|
||||
var is_constraint_trigger = m.get('is_constraint_trigger'),
|
||||
is_row_trigger = m.get('is_row_trigger'),
|
||||
server_type = m.node_info['server']['server_type'];
|
||||
if (is_row_trigger == true){
|
||||
setTimeout(function(){
|
||||
m.set('evnt_truncate', false);
|
||||
},10);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (server_type === 'ppas' &&
|
||||
!_.isUndefined(is_constraint_trigger) &&
|
||||
!_.isUndefined(is_row_trigger) &&
|
||||
is_constraint_trigger === false && m.isNew())
|
||||
return false;
|
||||
return m.inSchemaWithModelCheck.apply(this, [m]);
|
||||
},
|
||||
}],
|
||||
},{
|
||||
id: 'whenclause', label: gettext('When'),
|
||||
type: 'text', disabled: 'inSchemaWithModelCheck',
|
||||
mode: ['create', 'edit', 'properties'],
|
||||
control: 'sql-field', visible: true, group: gettext('Events'),
|
||||
},{
|
||||
id: 'columns', label: gettext('Columns'), url: 'nodes',
|
||||
control: 'node-list-by-name', cache_node: 'column', type: 'array',
|
||||
select2: {'multiple': true},
|
||||
deps: ['evnt_update'], node: 'column', group: gettext('Events'),
|
||||
disabled: function(m) {
|
||||
if(this.node_info && 'catalog' in this.node_info) {
|
||||
return true;
|
||||
}
|
||||
//Disable in edit mode
|
||||
if (!m.isNew()) {
|
||||
return true;
|
||||
}
|
||||
// Enable column only if update event is set true
|
||||
var isUpdate = m.get('evnt_update');
|
||||
if(!_.isUndefined(isUpdate) && isUpdate) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
},{
|
||||
id: 'tgoldtable', label: gettext('Old table'),
|
||||
type: 'text', group: gettext('Transition'),
|
||||
cell: 'string', mode: ['create', 'edit', 'properties'],
|
||||
deps: ['fires', 'is_constraint_trigger', 'evnt_insert', 'evnt_update', 'evnt_delete', 'columns'],
|
||||
disabled: 'disableTransition',
|
||||
},{
|
||||
id: 'tgnewtable', label: gettext('New table'),
|
||||
type: 'text', group: gettext('Transition'),
|
||||
cell: 'string', mode: ['create', 'edit', 'properties'],
|
||||
deps: ['fires', 'is_constraint_trigger', 'evnt_insert', 'evnt_update', 'evnt_delete', 'columns'],
|
||||
disabled: 'disableTransition',
|
||||
},{
|
||||
id: 'prosrc', label: gettext('Code'), group: gettext('Code'),
|
||||
type: 'text', mode: ['create', 'edit'], deps: ['tfunction'],
|
||||
tabPanelCodeClass: 'sql-code-control',
|
||||
control: Backform.SqlCodeControl,
|
||||
visible: true,
|
||||
disabled: function(m) {
|
||||
// We will enable it only when EDB PPAS and trigger function is
|
||||
// set to Inline EDB-SPL
|
||||
var tfunction = m.get('tfunction'),
|
||||
server_type = m.node_info['server']['server_type'];
|
||||
|
||||
return (server_type !== 'ppas' ||
|
||||
_.isUndefined(tfunction) ||
|
||||
tfunction !== 'Inline EDB-SPL');
|
||||
},
|
||||
},{
|
||||
id: 'is_sys_trigger', label: gettext('System trigger?'), cell: 'string',
|
||||
type: 'switch', disabled: 'inSchemaWithModelCheck', mode: ['properties'],
|
||||
},{
|
||||
id: 'description', label: gettext('Comment'), cell: 'string',
|
||||
type: 'multiline', mode: ['properties', 'create', 'edit'],
|
||||
disabled: 'inSchema',
|
||||
}],
|
||||
validate: function(keys) {
|
||||
var msg;
|
||||
this.errorModel.clear();
|
||||
|
||||
// If nothing to validate
|
||||
if (keys && keys.length == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if(_.isUndefined(this.get('name'))
|
||||
|| String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
|
||||
msg = gettext('Name cannot be empty.');
|
||||
this.errorModel.set('name', msg);
|
||||
return msg;
|
||||
}
|
||||
if(_.isUndefined(this.get('tfunction'))
|
||||
|| String(this.get('tfunction')).replace(/^\s+|\s+$/g, '') == '') {
|
||||
msg = gettext('Trigger function cannot be empty.');
|
||||
this.errorModel.set('tfunction', msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
if(!this.get('evnt_truncate') && !this.get('evnt_delete') &&
|
||||
!this.get('evnt_update') && !this.get('evnt_insert')) {
|
||||
msg = gettext('Specify at least one event.');
|
||||
this.errorModel.set('evnt_truncate', ' ');
|
||||
this.errorModel.set('evnt_delete', ' ');
|
||||
this.errorModel.set('evnt_update', ' ');
|
||||
this.errorModel.set('evnt_insert', msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
if(!_.isUndefined(this.get('tfunction')) &&
|
||||
this.get('tfunction') === 'Inline EDB-SPL' &&
|
||||
(_.isUndefined(this.get('prosrc'))
|
||||
|| String(this.get('prosrc')).replace(/^\s+|\s+$/g, '') == ''))
|
||||
{
|
||||
msg = gettext('Trigger code cannot be empty.');
|
||||
this.errorModel.set('prosrc', msg);
|
||||
return msg;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
// We will check if we are under schema node & in 'create' mode
|
||||
inSchema: function() {
|
||||
if(this.node_info && 'catalog' in this.node_info) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
// We will check if we are under schema node & in 'create' mode
|
||||
inSchemaWithModelCheck: function(m) {
|
||||
if(this.node_info && 'schema' in this.node_info) {
|
||||
// We will disable control if it's in 'edit' mode
|
||||
return !m.isNew();
|
||||
}
|
||||
return true;
|
||||
},
|
||||
// Checks weather to enable/disable control
|
||||
inSchemaWithColumnCheck: function(m) {
|
||||
if(this.node_info && 'schema' in this.node_info) {
|
||||
// We will disable control if it's system columns
|
||||
// ie: it's position is less then 1
|
||||
if (m.isNew()) {
|
||||
return false;
|
||||
} else {
|
||||
// if we are in edit mode
|
||||
return (_.isUndefined(m.get('attnum')) || m.get('attnum') < 1 );
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
// Disable/Enable Transition tables
|
||||
disableTransition: function(m) {
|
||||
if (!m.isNew())
|
||||
return true;
|
||||
var flag = false,
|
||||
evnt = null,
|
||||
name = this.name,
|
||||
evnt_count = 0;
|
||||
|
||||
// Disable transition tables for view trigger and PG version < 100000
|
||||
if(_.indexOf(Object.keys(m.node_info), 'table') == -1 ||
|
||||
m.node_info.server.version < 100000) return true;
|
||||
|
||||
if (name == 'tgoldtable') evnt = 'evnt_delete';
|
||||
else if (name == 'tgnewtable') evnt = 'evnt_insert';
|
||||
|
||||
if(m.get('evnt_insert')) evnt_count++;
|
||||
if(m.get('evnt_update')) evnt_count++;
|
||||
if(m.get('evnt_delete')) evnt_count++;
|
||||
|
||||
|
||||
// Disable transition tables if
|
||||
// - It is a constraint trigger
|
||||
// - Fires other than AFTER
|
||||
// - More than one events enabled
|
||||
// - Update event with the column list
|
||||
|
||||
// Disable Old transition table if both UPDATE and DELETE events are disabled
|
||||
// Disable New transition table if both UPDATE and INSERT events are disabled
|
||||
if(!m.get('is_constraint_trigger') && m.get('fires') == 'AFTER' &&
|
||||
(m.get('evnt_update') || m.get(evnt)) && evnt_count == 1) {
|
||||
flag = (m.get('evnt_update') && (_.size(m.get('columns')) >= 1 && m.get('columns')[0] != ''));
|
||||
}
|
||||
|
||||
flag && setTimeout(function() {
|
||||
if(m.get(name)) {
|
||||
m.set(name, null);
|
||||
}
|
||||
},10);
|
||||
|
||||
return flag;
|
||||
},
|
||||
}),
|
||||
canCreate: SchemaChildTreeNode.isTreeItemOfChildOfSchema,
|
||||
// Check to whether trigger is disable ?
|
||||
canCreate_with_trigger_enable: function(itemData, item, data) {
|
||||
|
||||
@@ -74,48 +74,6 @@ define('pgadmin.node.type', [
|
||||
|
||||
},
|
||||
ext_funcs: undefined,
|
||||
/* Few fields are kept since the properties tab for collection is not
|
||||
yet migrated to new react schema. Once the properties for collection
|
||||
is removed, remove this model */
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
defaults: {
|
||||
name: undefined,
|
||||
is_sys_type: false,
|
||||
typtype: undefined,
|
||||
},
|
||||
|
||||
// Default values!
|
||||
initialize: function(attrs, args) {
|
||||
if (_.size(attrs) === 0) {
|
||||
var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user,
|
||||
schemaInfo = args.node_info.schema;
|
||||
|
||||
this.set({
|
||||
'typeowner': userInfo.name, 'schema': schemaInfo._label,
|
||||
}, {silent: true});
|
||||
}
|
||||
pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), cell: 'string',
|
||||
type: 'text', mode: ['properties', 'create', 'edit'],
|
||||
disabled: 'schemaCheck',
|
||||
},{
|
||||
id: 'oid', label: gettext('OID'), cell: 'string',
|
||||
type: 'text' , mode: ['properties'],
|
||||
},{
|
||||
id: 'typeowner', label: gettext('Owner'), cell: 'string',
|
||||
control: 'node-list-by-name',
|
||||
type: 'text', mode: ['properties', 'create', 'edit'], node: 'role',
|
||||
disabled: 'inSchema', select2: {allowClear: false},
|
||||
}, {
|
||||
id: 'description', label: gettext('Comment'), cell: 'string',
|
||||
type: 'multiline', mode: ['properties', 'create', 'edit'],
|
||||
disabled: 'inSchema',
|
||||
}]
|
||||
}),
|
||||
getSchema: (treeNodeInfo, itemNodeData) => {
|
||||
let nodeObj = pgAdmin.Browser.Nodes['type'];
|
||||
return new TypeSchema(
|
||||
|
||||
@@ -146,93 +146,6 @@ define('pgadmin.node.mview', [
|
||||
}
|
||||
);
|
||||
},
|
||||
/**
|
||||
Define model for the view node and specify the
|
||||
properties of the model in schema.
|
||||
*/
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
initialize: function(attrs, args) {
|
||||
if (_.size(attrs) === 0) {
|
||||
// Set Selected Schema and Current User
|
||||
var schemaLabel = args.node_info.schema._label || 'public',
|
||||
userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
|
||||
this.set({
|
||||
'schema': schemaLabel, 'owner': userInfo.name,
|
||||
}, {silent: true});
|
||||
}
|
||||
pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
defaults: {
|
||||
spcname: undefined,
|
||||
},
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), cell: 'string',
|
||||
type: 'text', disabled: 'inSchema',
|
||||
},{
|
||||
id: 'oid', label: gettext('OID'), cell: 'string',
|
||||
type: 'text', mode: ['properties'],
|
||||
},{
|
||||
id: 'owner', label: gettext('Owner'), cell: 'string',
|
||||
control: 'node-list-by-name', select2: { allowClear: false },
|
||||
node: 'role', disabled: 'inSchema',
|
||||
},{
|
||||
id: 'comment', label: gettext('Comment'), cell: 'string',
|
||||
type: 'multiline',
|
||||
}],
|
||||
sessChanged: function() {
|
||||
/* If only custom autovacuum option is enabled the check if the options table is also changed. */
|
||||
if(_.size(this.sessAttrs) == 2 && this.sessAttrs['autovacuum_custom'] && this.sessAttrs['toast_autovacuum']) {
|
||||
return this.get('vacuum_table').sessChanged() || this.get('vacuum_toast').sessChanged();
|
||||
}
|
||||
if(_.size(this.sessAttrs) == 1 && (this.sessAttrs['autovacuum_custom'] || this.sessAttrs['toast_autovacuum'])) {
|
||||
return this.get('vacuum_table').sessChanged() || this.get('vacuum_toast').sessChanged();
|
||||
}
|
||||
return pgBrowser.DataModel.prototype.sessChanged.apply(this);
|
||||
},
|
||||
validate: function(keys) {
|
||||
|
||||
// Triggers specific error messages for fields
|
||||
var err = {},
|
||||
errmsg,
|
||||
field_name = this.get('name'),
|
||||
field_def = this.get('definition');
|
||||
|
||||
if(_.indexOf(keys, 'autovacuum_custom'))
|
||||
if (_.indexOf(keys, 'autovacuum_enabled') != -1 ||
|
||||
_.indexOf(keys, 'toast_autovacuum_enabled') != -1 )
|
||||
return null;
|
||||
|
||||
if (_.isUndefined(field_name) || _.isNull(field_name) ||
|
||||
String(field_name).replace(/^\s+|\s+$/g, '') == '') {
|
||||
err['name'] = gettext('Please specify name.');
|
||||
errmsg = err['name'];
|
||||
this.errorModel.set('name', errmsg);
|
||||
return errmsg;
|
||||
}else{
|
||||
this.errorModel.unset('name');
|
||||
}
|
||||
if (_.isUndefined(field_def) || _.isNull(field_def) ||
|
||||
String(field_def).replace(/^\s+|\s+$/g, '') == '') {
|
||||
err['definition'] = gettext('Please enter view definition.');
|
||||
errmsg = err['definition'];
|
||||
this.errorModel.set('definition', errmsg);
|
||||
return errmsg;
|
||||
}else{
|
||||
this.errorModel.unset('definition');
|
||||
}
|
||||
return null;
|
||||
},
|
||||
// We will disable everything if we are under catalog node
|
||||
inSchema: function() {
|
||||
if(this.node_info && 'catalog' in this.node_info)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
}),
|
||||
|
||||
refresh_mview: function(args) {
|
||||
var input = args || {},
|
||||
|
||||
@@ -108,163 +108,6 @@ define('pgadmin.node.view', [
|
||||
}
|
||||
);
|
||||
},
|
||||
/**
|
||||
Define model for the view node and specify the
|
||||
properties of the model in schema.
|
||||
*/
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
initialize: function(attrs, args) {
|
||||
if (_.size(attrs) === 0) {
|
||||
// Set Selected Schema and, Current User
|
||||
var schemaLabel = args.node_info.schema._label || 'public',
|
||||
userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
|
||||
this.set({
|
||||
'schema': schemaLabel, 'owner': userInfo.name,
|
||||
}, {silent: true});
|
||||
}
|
||||
pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), cell: 'string',
|
||||
type: 'text', disabled: 'notInSchema',
|
||||
},{
|
||||
id: 'oid', label: gettext('OID'), cell: 'string',
|
||||
type: 'text', mode: ['properties'],
|
||||
},{
|
||||
id: 'owner', label: gettext('Owner'), cell: 'string', control: 'node-list-by-name',
|
||||
node: 'role', disabled: 'notInSchema', select2: { allowClear: false },
|
||||
},{
|
||||
id: 'schema', label: gettext('Schema'), cell: 'string', first_empty: false,
|
||||
control: 'node-list-by-name', type: 'text', cache_level: 'database',
|
||||
node: 'schema', disabled: 'notInSchema', mode: ['create', 'edit'],
|
||||
select2: { allowClear: false }, cache_node: 'database',
|
||||
},{
|
||||
id: 'system_view', label: gettext('System view?'), cell: 'string',
|
||||
type: 'switch', mode: ['properties'],
|
||||
},{
|
||||
id: 'acl', label: gettext('Privileges'),
|
||||
mode: ['properties'], type: 'text', group: gettext('Security'),
|
||||
},{
|
||||
id: 'comment', label: gettext('Comment'), cell: 'string',
|
||||
type: 'multiline', disabled: 'notInSchema',
|
||||
},{
|
||||
id: 'security_barrier', label: gettext('Security barrier?'),
|
||||
type: 'switch', min_version: '90200', group: gettext('Definition'),
|
||||
disabled: 'notInSchema',
|
||||
},{
|
||||
id: 'check_option', label: gettext('Check options'),
|
||||
control: 'select2', group: gettext('Definition'), type: 'text',
|
||||
min_version: '90400', mode:['properties', 'create', 'edit'],
|
||||
select2: {
|
||||
// Set select2 option width to 100%
|
||||
allowClear: false,
|
||||
}, disabled: 'notInSchema',
|
||||
options:[{
|
||||
label: gettext('No'), value: 'no',
|
||||
},{
|
||||
label: gettext('Local'), value: 'local',
|
||||
},{
|
||||
label: gettext('Cascaded'), value: 'cascaded',
|
||||
}],
|
||||
},{
|
||||
id: 'definition', label: gettext('Code'), cell: 'string',
|
||||
type: 'text', mode: ['create', 'edit'], group: gettext('Code'),
|
||||
tabPanelCodeClass: 'sql-code-control',
|
||||
disabled: 'notInSchema',
|
||||
control: Backform.SqlCodeControl.extend({
|
||||
onChange: function() {
|
||||
Backform.SqlCodeControl.prototype.onChange.apply(this, arguments);
|
||||
|
||||
if (!this.model || !(
|
||||
this.model.changed &&
|
||||
this.model.node_info.server.server_type == 'pg' &&
|
||||
// No need to check this when creating a view
|
||||
this.model.get('oid') !== undefined
|
||||
) || !(
|
||||
this.model.origSessAttrs &&
|
||||
this.model.changed.definition != this.model.origSessAttrs.definition
|
||||
)) {
|
||||
this.model.warn_text = undefined;
|
||||
return;
|
||||
}
|
||||
|
||||
let old_def = this.model.origSessAttrs.definition &&
|
||||
this.model.origSessAttrs.definition.replace(
|
||||
/\s/gi, ''
|
||||
).split('FROM'),
|
||||
new_def = [];
|
||||
|
||||
if (this.model.changed.definition !== undefined) {
|
||||
new_def = this.model.changed.definition.replace(
|
||||
/\s/gi, ''
|
||||
).split('FROM');
|
||||
}
|
||||
|
||||
if ((old_def.length != new_def.length) || (
|
||||
old_def.length > 1 && (
|
||||
old_def[0] != new_def[0]
|
||||
)
|
||||
)) {
|
||||
this.model.warn_text = gettext(
|
||||
'Changing the columns in a view requires dropping and re-creating the view. This may fail if other objects are dependent upon this view, or may cause procedural functions to fail if they are not modified to take account of the changes.'
|
||||
) + '<br><br><b>' + gettext('Do you wish to continue?') +
|
||||
'</b>';
|
||||
} else {
|
||||
this.model.warn_text = undefined;
|
||||
}
|
||||
},
|
||||
}),
|
||||
}, pgBrowser.SecurityGroupSchema, {
|
||||
// Add Privilege Control
|
||||
id: 'datacl', label: gettext('Privileges'), type: 'collection',
|
||||
model: pgBrowser.Node.PrivilegeRoleModel.extend({
|
||||
privileges: ['a', 'r', 'w', 'd', 'D', 'x', 't'],
|
||||
}), uniqueCol : ['grantee'], editable: false, group: 'security',
|
||||
mode: ['edit', 'create'], canAdd: true, canDelete: true,
|
||||
control: 'unique-col-collection', disabled: 'notInSchema',
|
||||
},{
|
||||
// Add Security Labels Control
|
||||
id: 'seclabels', label: gettext('Security labels'),
|
||||
model: pgBrowser.SecLabelModel, editable: false, type: 'collection',
|
||||
canEdit: false, group: 'security', canDelete: true,
|
||||
mode: ['edit', 'create'], canAdd: true, disabled: 'notInSchema',
|
||||
control: 'unique-col-collection', uniqueCol : ['provider'],
|
||||
}],
|
||||
validate: function() {
|
||||
// Triggers specific error messages for fields
|
||||
var err = {},
|
||||
errmsg,
|
||||
field_name = this.get('name'),
|
||||
field_def = this.get('definition');
|
||||
if (_.isUndefined(field_name) || _.isNull(field_name) ||
|
||||
String(field_name).replace(/^\s+|\s+$/g, '') == '') {
|
||||
err['name'] = gettext('Please specify name.');
|
||||
errmsg = err['name'];
|
||||
this.errorModel.set('name', errmsg);
|
||||
return errmsg;
|
||||
}else{
|
||||
this.errorModel.unset('name');
|
||||
}
|
||||
if (_.isUndefined(field_def) || _.isNull(field_def) ||
|
||||
String(field_def).replace(/^\s+|\s+$/g, '') == '') {
|
||||
err['definition'] = gettext('Please enter view code.');
|
||||
errmsg = err['definition'];
|
||||
this.errorModel.set('definition', errmsg);
|
||||
return errmsg;
|
||||
}else{
|
||||
this.errorModel.unset('definition');
|
||||
}
|
||||
return null;
|
||||
},
|
||||
// We will disable everything if we are under catalog node
|
||||
notInSchema: function() {
|
||||
if(this.node_info && 'catalog' in this.node_info) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -351,45 +351,6 @@ define('pgadmin.node.database', [
|
||||
}
|
||||
);
|
||||
},
|
||||
/* Few fields are kept since the properties tab for collection is not
|
||||
yet migrated to new react schema. Once the properties for collection
|
||||
is removed, remove this model */
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'did',
|
||||
defaults: {
|
||||
name: undefined,
|
||||
owner: undefined,
|
||||
comment: undefined,
|
||||
},
|
||||
|
||||
// Default values!
|
||||
initialize: function(attrs, args) {
|
||||
var isNew = (_.size(attrs) === 0);
|
||||
|
||||
if (isNew) {
|
||||
var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
|
||||
this.set({'datowner': userInfo.name}, {silent: true});
|
||||
}
|
||||
pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
|
||||
schema: [
|
||||
{
|
||||
id: 'name', label: gettext('Database'), cell: 'string',
|
||||
editable: false, type: 'text',
|
||||
},{
|
||||
id: 'did', label: gettext('OID'), cell: 'string', mode: ['properties'],
|
||||
editable: false, type: 'text',
|
||||
},{
|
||||
id: 'datowner', label: gettext('Owner'),
|
||||
editable: false, type: 'text', node: 'role',
|
||||
control: Backform.NodeListByNameControl, select2: { allowClear: false },
|
||||
},{
|
||||
id: 'comments', label: gettext('Comment'),
|
||||
editable: false, type: 'multiline',
|
||||
},
|
||||
],
|
||||
}),
|
||||
});
|
||||
|
||||
pgBrowser.SecurityGroupSchema = {
|
||||
|
||||
@@ -95,20 +95,20 @@ export default class DatabaseSchema extends BaseUISchema {
|
||||
return [
|
||||
{
|
||||
id: 'name', label: gettext('Database'), cell: 'text',
|
||||
editable: false, type: 'text', noEmpty: true,
|
||||
editable: false, type: 'text', noEmpty: true, isCollectionProperty: true,
|
||||
},{
|
||||
id: 'did', label: gettext('OID'), cell: 'text', mode: ['properties'],
|
||||
editable: false, type: 'text',
|
||||
},{
|
||||
id: 'datowner', label: gettext('Owner'),
|
||||
editable: false, type: 'select', options: this.fieldOptions.role,
|
||||
controlProps: { allowClear: false },
|
||||
controlProps: { allowClear: false }, isCollectionProperty: true,
|
||||
},{
|
||||
id: 'is_sys_obj', label: gettext('System database?'),
|
||||
cell: 'switch', type: 'switch', mode: ['properties'],
|
||||
},{
|
||||
id: 'comments', label: gettext('Comment'),
|
||||
editable: false, type: 'multiline',
|
||||
editable: false, type: 'multiline', isCollectionProperty: true,
|
||||
},{
|
||||
id: 'encoding', label: gettext('Encoding'),
|
||||
editable: false, type: 'select', group: gettext('Definition'),
|
||||
|
||||
@@ -14,8 +14,8 @@ import Notify from '../../../../../../../static/js/helpers/Notifier';
|
||||
|
||||
define('pgadmin.node.subscription', [
|
||||
'sources/gettext', 'sources/url_for', 'jquery',
|
||||
'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform', 'pgadmin.browser.collection',
|
||||
], function(gettext, url_for, $, pgAdmin, pgBrowser, Backform) {
|
||||
'sources/pgadmin', 'pgadmin.browser', 'pgadmin.browser.collection',
|
||||
], function(gettext, url_for, $, pgAdmin, pgBrowser) {
|
||||
|
||||
// Extend the browser's collection class for subscriptions collection
|
||||
if (!pgBrowser.Nodes['coll-subscription']) {
|
||||
@@ -24,7 +24,7 @@ define('pgadmin.node.subscription', [
|
||||
node: 'subscription',
|
||||
label: gettext('Subscriptions'),
|
||||
type: 'coll-subscription',
|
||||
columns: ['name', 'subowner', 'pub', 'enabled'],
|
||||
columns: ['name', 'subowner', 'proppub', 'enabled'],
|
||||
hasStatistics: true,
|
||||
});
|
||||
}
|
||||
@@ -74,101 +74,6 @@ define('pgadmin.node.subscription', [
|
||||
enable: 'canCreate',
|
||||
}]);
|
||||
},
|
||||
// Define the model for subscription node
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
defaults: {
|
||||
name: undefined,
|
||||
subowner: undefined,
|
||||
pubtable: undefined,
|
||||
connect_timeout: 10,
|
||||
pub:[],
|
||||
enabled:true,
|
||||
create_slot: true,
|
||||
copy_data:true,
|
||||
connect:true,
|
||||
copy_data_after_refresh:false,
|
||||
sync:'off',
|
||||
refresh_pub: false,
|
||||
password: '',
|
||||
sslmode: 'prefer',
|
||||
sslcompression: false,
|
||||
sslcert: '',
|
||||
sslkey: '',
|
||||
sslrootcert: '',
|
||||
sslcrl: '',
|
||||
host: '',
|
||||
hostaddr: '',
|
||||
port: 5432,
|
||||
db: 'postgres',
|
||||
},
|
||||
|
||||
// Default values!
|
||||
initialize: function(attrs, args) {
|
||||
var isNew = (_.size(attrs) === 0);
|
||||
if (isNew) {
|
||||
var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
|
||||
|
||||
this.set({'subowner': userInfo.name}, {silent: true});
|
||||
}
|
||||
pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
|
||||
// Define the schema for the subscription node
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Name'), type: 'text',
|
||||
mode: ['properties', 'create', 'edit'],
|
||||
visible: function() {
|
||||
if(!_.isUndefined(this.node_info) && !_.isUndefined(this.node_info.server)
|
||||
&& !_.isUndefined(this.node_info.server.version) &&
|
||||
this.node_info.server.version >= 100000) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
},{
|
||||
id: 'oid', label: gettext('OID'), cell: 'string', mode: ['properties'],
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
id: 'subowner', label: gettext('Owner'), type: 'text',
|
||||
control: Backform.NodeListByNameControl, node: 'role',
|
||||
mode: ['edit', 'properties', 'create'], select2: { allowClear: false},
|
||||
disabled: function(m){
|
||||
if(m.isNew())
|
||||
return true;
|
||||
return false;
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'enabled', label: gettext('Enabled?'),
|
||||
type: 'switch', mode: ['properties'],
|
||||
group: gettext('With'),
|
||||
readonly: 'isConnect', deps :['connect'],
|
||||
helpMessage: gettext('Specifies whether the subscription should be actively replicating, or whether it should be just setup but not started yet.'),
|
||||
},
|
||||
{
|
||||
id: 'pub', label: gettext('Publication'), type: 'text', group: gettext('Connection'),
|
||||
mode: ['properties'],
|
||||
},
|
||||
],
|
||||
sessChanged: function() {
|
||||
if (!this.isNew() && _.isUndefined(this.attributes['refresh_pub']))
|
||||
return false;
|
||||
return pgBrowser.DataModel.prototype.sessChanged.apply(this);
|
||||
},
|
||||
canCreate: function(itemData, item) {
|
||||
var treeData = pgBrowser.tree.getTreeNodeHierarchy(item),
|
||||
server = treeData['server'];
|
||||
|
||||
// If server is less than 10 then do not allow 'create' menu
|
||||
if (server && server.version < 100000)
|
||||
return false;
|
||||
|
||||
// by default we want to allow create menu
|
||||
return true;
|
||||
},
|
||||
}),
|
||||
getSchema: function(treeNodeInfo, itemNodeData){
|
||||
return new SubscriptionSchema(
|
||||
{
|
||||
|
||||
@@ -176,7 +176,7 @@ export default class SubscriptionSchema extends BaseUISchema{
|
||||
mode: ['properties', 'edit', 'create'],
|
||||
},
|
||||
{
|
||||
id: 'pub', label: gettext('Publication'), type: 'text', group: gettext('Connection'),
|
||||
id: 'proppub', label: gettext('Publication'), type: 'text', group: gettext('Connection'),
|
||||
mode: ['properties'],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
SELECT sub.oid as oid,
|
||||
subname as name,
|
||||
subpublications as pub,
|
||||
subpublications as proppub,
|
||||
sub.subsynccommit as sync,
|
||||
pga.rolname as subowner,
|
||||
subslotname as slot_name,
|
||||
|
||||
@@ -582,152 +582,6 @@ define('pgadmin.node.role', [
|
||||
},
|
||||
);
|
||||
},
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
defaults: {
|
||||
oid: null,
|
||||
rolname: undefined,
|
||||
rolcanlogin: false,
|
||||
rolconnlimit: -1,
|
||||
rolsuper: false,
|
||||
rolcreaterole: false,
|
||||
rolcreatedb: false,
|
||||
rolinherit: true,
|
||||
rolcatupdate: false,
|
||||
rolreplication: false,
|
||||
rolvaliduntil: null,
|
||||
},
|
||||
schema: [{
|
||||
id: 'rolname', label: gettext('Name'), type: 'text',
|
||||
readonly: 'readonly',
|
||||
},{
|
||||
id: 'oid', label: gettext('OID'), cell: 'string', mode: ['properties'],
|
||||
editable: false, type: 'text', visible: true,
|
||||
},{
|
||||
id: 'rolvaliduntil', readonly: 'readonly', type: 'text',
|
||||
group: gettext('Definition'), label: gettext('Account expires'),
|
||||
mode: ['properties', 'edit', 'create'], control: 'datetimepicker',
|
||||
deps: ['rolcanlogin'],
|
||||
placeholder: gettext('No Expiry'),
|
||||
helpMessage: gettext('Please note that if you leave this field blank, then password will never expire.'),
|
||||
setMinDate: false,
|
||||
},{
|
||||
id: 'rolconnlimit', type: 'int', group: gettext('Definition'),
|
||||
label: gettext('Connection limit'), cell: 'integer', min : -1,
|
||||
mode: ['properties', 'edit', 'create'], readonly: 'readonly',
|
||||
},{
|
||||
id: 'rolcanlogin', label: gettext('Can login?'),
|
||||
type: 'switch',
|
||||
controlLabelClassName: 'control-label pg-el-sm-4 pg-el-12',
|
||||
controlsClassName: 'pgadmin-controls pg-el-sm-8 pg-el-12',
|
||||
group: gettext('Privileges'),
|
||||
readonly: 'readonly',
|
||||
},{
|
||||
id: 'rolsuper', label: gettext('Superuser?'),
|
||||
type: 'switch',
|
||||
controlLabelClassName: 'control-label pg-el-sm-4 pg-el-12',
|
||||
controlsClassName: 'pgadmin-controls pg-el-sm-8 pg-el-12',
|
||||
group: gettext('Privileges'),
|
||||
control: Backform.SwitchControl.extend({
|
||||
onChange: function() {
|
||||
Backform.SwitchControl.prototype.onChange.apply(this, arguments);
|
||||
|
||||
this.model.set('rolcatupdate', this.model.get('rolsuper'));
|
||||
this.model.set('rolcreaterole', this.model.get('rolsuper'));
|
||||
this.model.set('rolcreatedb', this.model.get('rolsuper'));
|
||||
},
|
||||
}),
|
||||
readonly: 'readonly',
|
||||
},{
|
||||
id: 'rolcreaterole', label: gettext('Create roles?'),
|
||||
group: gettext('Privileges'),
|
||||
type: 'switch',
|
||||
controlLabelClassName: 'control-label pg-el-sm-4 pg-el-12',
|
||||
controlsClassName: 'pgadmin-controls pg-el-sm-8 pg-el-12',
|
||||
readonly: 'readonly',
|
||||
},{
|
||||
id: 'is_sys_obj', label: gettext('System role?'),
|
||||
cell:'boolean', type: 'switch', mode: ['properties'],
|
||||
},{
|
||||
id: 'description', label: gettext('Comments'), type: 'multiline',
|
||||
group: null, mode: ['properties', 'edit', 'create'],
|
||||
readonly: 'readonly',
|
||||
},{
|
||||
id: 'rolcreatedb', label: gettext('Create databases?'),
|
||||
group: gettext('Privileges'),
|
||||
type: 'switch',
|
||||
controlLabelClassName: 'control-label pg-el-sm-4 pg-el-12',
|
||||
controlsClassName: 'pgadmin-controls pg-el-sm-8 pg-el-12',
|
||||
readonly: 'readonly',
|
||||
},{
|
||||
id: 'rolcatupdate', label: gettext('Update catalog?'),
|
||||
type: 'switch',
|
||||
controlLabelClassName: 'control-label pg-el-sm-4 pg-el-12',
|
||||
controlsClassName: 'pgadmin-controls pg-el-sm-8 pg-el-12',
|
||||
max_version: 90400,
|
||||
group: gettext('Privileges'), readonly: function(m) {
|
||||
return m.get('read_only');
|
||||
},
|
||||
disabled: function(m) {
|
||||
return !m.get('rolsuper');
|
||||
},
|
||||
},{
|
||||
id: 'rolinherit', group: gettext('Privileges'),
|
||||
label: gettext('Inherit rights from the parent roles?'),
|
||||
type: 'switch',
|
||||
controlLabelClassName: 'control-label pg-el-sm-4 pg-el-12',
|
||||
controlsClassName: 'pgadmin-controls pg-el-sm-8 pg-el-12',
|
||||
readonly: 'readonly',
|
||||
},{
|
||||
id: 'rolreplication', group: gettext('Privileges'),
|
||||
label: gettext('Can initiate streaming replication and backups?'),
|
||||
type: 'switch',
|
||||
controlLabelClassName: 'control-label pg-el-sm-4 pg-el-12',
|
||||
controlsClassName: 'pgadmin-controls pg-el-sm-8 pg-el-12',
|
||||
min_version: 90100,
|
||||
readonly: 'readonly',
|
||||
}],
|
||||
readonly: function(m) {
|
||||
if (!m.has('read_only')) {
|
||||
var user = this.node_info.server.user;
|
||||
|
||||
m.set('read_only', !(user.is_superuser || user.can_create_role));
|
||||
}
|
||||
|
||||
return m.get('read_only');
|
||||
},
|
||||
validate: function()
|
||||
{
|
||||
var err = {},
|
||||
errmsg,
|
||||
seclabels = this.get('seclabels');
|
||||
|
||||
if (_.isUndefined(this.get('rolname')) || String(this.get('rolname')).replace(/^\s+|\s+$/g, '') == '') {
|
||||
err['name'] = gettext('Name cannot be empty.');
|
||||
errmsg = err['name'];
|
||||
}
|
||||
|
||||
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;
|
||||
},
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -7,8 +7,9 @@
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
import {removeNodeView} from './node_view';
|
||||
import Notify from '../../../static/js/helpers/Notifier';
|
||||
// import {removeNodeView} from './node_view';
|
||||
// import Notify from '../../../static/js/helpers/Notifier';
|
||||
import {getPanelView} from './panel_view';
|
||||
|
||||
define([
|
||||
'sources/gettext', 'jquery', 'underscore', 'sources/pgadmin',
|
||||
@@ -91,399 +92,14 @@ define([
|
||||
canDropCascade: true,
|
||||
selectParentNodeOnDelete: false,
|
||||
showProperties: function(item, data, panel) {
|
||||
var that = this,
|
||||
j = panel.$container.find('.obj_properties').first(),
|
||||
view = j.data('obj-view'),
|
||||
content = $('<div></div>')
|
||||
.addClass('pg-prop-content col-12 has-pg-prop-btn-group'),
|
||||
node = pgBrowser.Nodes[that.node],
|
||||
$msgContainer = '',
|
||||
// This will be the URL, used for object manipulation.
|
||||
urlBase = this.generate_url(item, 'properties', data),
|
||||
info = pgBrowser.tree.getTreeNodeHierarchy(item),
|
||||
gridSchema = Backform.generateGridColumnsFromModel(
|
||||
info, node.model, 'properties', that.columns
|
||||
),
|
||||
createButtons = function(buttonsList, location, extraClasses) {
|
||||
// Arguments must be non-zero length array of type
|
||||
// object, which contains following attributes:
|
||||
// label, type, extraClasses, register
|
||||
if (buttonsList && _.isArray(buttonsList) && buttonsList.length > 0) {
|
||||
// All buttons will be created within a single
|
||||
// div area.
|
||||
var btnGroup =
|
||||
$('<div class="pg-prop-btn-group"></div>'),
|
||||
// Template used for creating a button
|
||||
tmpl = _.template([
|
||||
'<button tabindex="0" type="<%= type %>" ',
|
||||
'class="btn <%=extraClasses.join(\' \')%>"',
|
||||
'<% if (disabled) { %> disabled="disabled"<% } %> title="<%-tooltip%>">',
|
||||
'<span class="<%= icon %>" role="img"></span><% if (label != "") { %> <%-label%><% } %><span class="sr-only"><%-tooltip%></span></button>',
|
||||
].join(' '));
|
||||
if (location == 'header') {
|
||||
btnGroup.appendTo(that.header);
|
||||
} else {
|
||||
btnGroup.appendTo(that.footer);
|
||||
}
|
||||
if (extraClasses) {
|
||||
btnGroup.addClass(extraClasses);
|
||||
}
|
||||
_.each(buttonsList, function(btn) {
|
||||
// Create the actual button, and append to
|
||||
// the group div
|
||||
|
||||
// icon may not present for this button
|
||||
if (!btn.icon) {
|
||||
btn.icon = '';
|
||||
}
|
||||
var b = $(tmpl(btn));
|
||||
btnGroup.append(b);
|
||||
// Register is a callback to set callback
|
||||
// for certain operation for this button.
|
||||
btn.register(b);
|
||||
});
|
||||
return btnGroup;
|
||||
}
|
||||
return null;
|
||||
}.bind(panel);
|
||||
|
||||
that.collection = new (node.Collection.extend({
|
||||
url: urlBase,
|
||||
model: node.model,
|
||||
}))();
|
||||
// Add the new column for the multi-select menus
|
||||
if((_.isFunction(that.canDrop) ?
|
||||
that.canDrop.apply(that, [data, item]) : that.canDrop) ||
|
||||
(_.isFunction(that.canDropCascade) ?
|
||||
that.canDropCascade.apply(that, [data, item]) : that.canDropCascade)) {
|
||||
gridSchema.columns.unshift({
|
||||
name: 'oid',
|
||||
cell: Backgrid.Extension.SelectRowCell.extend({
|
||||
initialize: function (options) {
|
||||
this.column = options.column;
|
||||
if (!(this.column instanceof Backgrid.Column)) {
|
||||
this.column = new Backgrid.Column(this.column);
|
||||
}
|
||||
|
||||
var column = this.column, model = this.model, $el = this.$el;
|
||||
this.listenTo(column, 'change:renderable', function (col, renderable) {
|
||||
$el.toggleClass('renderable', renderable);
|
||||
});
|
||||
|
||||
if (Backgrid.callByNeed(column.renderable(), column, model)) $el.addClass('renderable width_percent_3');
|
||||
|
||||
this.listenTo(model, 'backgrid:select', this.toggleCheckbox);
|
||||
},
|
||||
toggleCheckbox: function(model, selected) {
|
||||
if (this.checkbox().prop('disabled') === false) {
|
||||
this.checkbox().prop('checked', selected).change();
|
||||
}
|
||||
},
|
||||
render: function() {
|
||||
let model = this.model.toJSON();
|
||||
// canDrop can be set to false for individual row from the server side to disable the checkbox
|
||||
let disabled = ('canDrop' in model && model.canDrop === false);
|
||||
let id = `row-${_.uniqueId(model.oid || model.name)}`;
|
||||
|
||||
this.$el.empty().append(`
|
||||
<div class="custom-control custom-checkbox custom-checkbox-no-label">
|
||||
<input tabindex="-1" type="checkbox" class="custom-control-input" id="${id}" ${disabled?'disabled':''}/>
|
||||
<label class="custom-control-label" for="${id}">
|
||||
<span class="sr-only">` + gettext('Select') + `<span>
|
||||
</label>
|
||||
</div>
|
||||
`);
|
||||
this.delegateEvents();
|
||||
return this;
|
||||
},
|
||||
}),
|
||||
headerCell: Backgrid.Extension.SelectAllHeaderCell,
|
||||
});
|
||||
}
|
||||
/* Columns should be always non-editable */
|
||||
gridSchema.columns.forEach((col)=>{
|
||||
col.disabled = true;
|
||||
});
|
||||
|
||||
// Get the list of selected models, before initializing the grid
|
||||
// again.
|
||||
var selectedModels = [];
|
||||
if(!_.isUndefined(that.grid) && 'collection' in that.grid){
|
||||
selectedModels = that.grid.getSelectedModels();
|
||||
}
|
||||
|
||||
// Initialize a new Grid instance
|
||||
that.grid = new Backgrid.Grid({
|
||||
emptyText: gettext('No data found'),
|
||||
columns: gridSchema.columns,
|
||||
collection: that.collection,
|
||||
className: 'backgrid table presentation table-bordered table-noouter-border table-hover',
|
||||
});
|
||||
|
||||
var gridView = {
|
||||
'remove': function() {
|
||||
if (this.grid) {
|
||||
if (this.grid.collection) {
|
||||
this.grid.collection.reset([], {silent: true});
|
||||
delete (this.grid.collection);
|
||||
}
|
||||
delete (this.grid);
|
||||
this.grid = null;
|
||||
}
|
||||
},
|
||||
grid: that.grid,
|
||||
};
|
||||
|
||||
if (view) {
|
||||
// Cache the current IDs for next time
|
||||
$(panel).data('node-prop', urlBase);
|
||||
|
||||
// Reset the data object
|
||||
j.data('obj-view', null);
|
||||
}
|
||||
|
||||
/* Remove any dom rendered by getNodeView */
|
||||
removeNodeView(j[0]);
|
||||
// Make sure the HTML element is empty.
|
||||
j.empty();
|
||||
j.data('obj-view', gridView);
|
||||
|
||||
$msgContainer = '<div role="status" class="pg-panel-message pg-panel-properties-message">' +
|
||||
gettext('Retrieving data from the server...') + '</div>';
|
||||
|
||||
$msgContainer = $($msgContainer).appendTo(j);
|
||||
|
||||
that.header = $('<div></div>').addClass(
|
||||
'pg-prop-header'
|
||||
let container = panel.$container[0];
|
||||
getPanelView(
|
||||
pgBrowser.tree,
|
||||
container,
|
||||
pgBrowser,
|
||||
panel._type
|
||||
);
|
||||
|
||||
// Render the buttons
|
||||
var buttons = [];
|
||||
|
||||
buttons.push({
|
||||
label: '',
|
||||
type: 'delete',
|
||||
tooltip: gettext('Delete/Drop'),
|
||||
extraClasses: ['btn-primary-icon m-1', 'delete_multiple'],
|
||||
icon: 'fa fa-trash-alt',
|
||||
disabled: (_.isFunction(that.canDrop)) ? !(that.canDrop.apply(self, [data, item])) : (!that.canDrop),
|
||||
register: function(btn) {
|
||||
btn.on('click',() => {
|
||||
onDrop('drop');
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
buttons.push({
|
||||
label: '',
|
||||
type: 'delete',
|
||||
tooltip: gettext('Drop Cascade'),
|
||||
extraClasses: ['btn-primary-icon m-1', 'delete_multiple_cascade'],
|
||||
icon: 'pg-font-icon icon-drop_cascade',
|
||||
disabled: (_.isFunction(that.canDropCascade)) ? !(that.canDropCascade.apply(self, [data, item])) : (!that.canDropCascade),
|
||||
register: function(btn) {
|
||||
btn.on('click',() => {
|
||||
onDrop('dropCascade');
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
createButtons(buttons, 'header', 'pg-prop-btn-group-above');
|
||||
|
||||
// Render subNode grid
|
||||
content.append('<div class="pg-prop-coll-container"></div>');
|
||||
content.find('.pg-prop-coll-container').append(that.grid.render().$el);
|
||||
|
||||
var timer;
|
||||
var getAjaxHook = function() {
|
||||
$.ajax({
|
||||
url: urlBase,
|
||||
type: 'GET',
|
||||
beforeSend: function(xhr) {
|
||||
xhr.setRequestHeader(pgAdmin.csrf_token_header, pgAdmin.csrf_token);
|
||||
// Generate a timer for the request
|
||||
timer = setTimeout(function() {
|
||||
// notify user if request is taking longer than 1 second
|
||||
|
||||
if (!$msgContainer.text()== 'Failed to retrieve data from the server.')
|
||||
$msgContainer.text(gettext('Retrieving data from the server...'));
|
||||
$msgContainer.removeClass('d-none');
|
||||
if (self.grid) {
|
||||
self.grid.remove();
|
||||
}
|
||||
}, 1000);
|
||||
},
|
||||
}).done(function(res) {
|
||||
clearTimeout(timer);
|
||||
|
||||
if (_.isUndefined(that.grid) || _.isNull(that.grid)) return;
|
||||
|
||||
that.data = res;
|
||||
|
||||
if (that.data.length > 0) {
|
||||
|
||||
if (!$msgContainer.hasClass('d-none')) {
|
||||
$msgContainer.addClass('d-none');
|
||||
}
|
||||
that.header.appendTo(j);
|
||||
j.append(content);
|
||||
|
||||
// Listen scroll event to load more rows
|
||||
$('.pg-prop-content').on('scroll', that.__loadMoreRows.bind(that));
|
||||
|
||||
that.collection.reset(that.data.splice(0, 50));
|
||||
|
||||
// Listen to select all checkbox event
|
||||
that.collection.on('backgrid:select-all', that.__loadAllRows.bind(that));
|
||||
|
||||
// Trigger the backgrid:select event for already selected items
|
||||
// as we have created a new grid instance.
|
||||
if(selectedModels.length > 0) {
|
||||
that.collection.each(function (model) {
|
||||
for(let model_val of selectedModels){
|
||||
if (model_val.id == model.id){
|
||||
model.trigger('backgrid:select', model, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// Do not listen the scroll event
|
||||
$('.pg-prop-content').off('scroll', that.__loadMoreRows);
|
||||
|
||||
$msgContainer.text(gettext('No properties are available for the selected object.'));
|
||||
|
||||
}
|
||||
selectedModels = [];
|
||||
}).fail(function(xhr, error) {
|
||||
pgBrowser.Events.trigger(
|
||||
'pgadmin:node:retrieval:error', 'properties', xhr, error.message, item, that
|
||||
);
|
||||
if (!Alertify.pgHandleItemError(xhr, error.message, {
|
||||
item: item,
|
||||
info: info,
|
||||
})) {
|
||||
Notify.pgNotifier(
|
||||
error, xhr, gettext('Error retrieving properties - %s', error.message || that.label),
|
||||
function(msg) {
|
||||
if(msg === 'CRYPTKEY_SET') {
|
||||
getAjaxHook();
|
||||
} else {
|
||||
console.warn(arguments);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
// show failed message.
|
||||
$msgContainer.text(gettext('Failed to retrieve data from the server.'));
|
||||
});
|
||||
};
|
||||
getAjaxHook();
|
||||
|
||||
var onDrop = function(type, confirm=true) {
|
||||
let sel_row_models = this.grid.getSelectedModels(),
|
||||
sel_rows = [],
|
||||
sel_item = pgBrowser.tree.selected(),
|
||||
d = sel_item ? pgBrowser.tree.itemData(sel_item) : null,
|
||||
sel_node = d && pgBrowser.Nodes[d._type],
|
||||
url = undefined,
|
||||
msg = undefined,
|
||||
title = undefined;
|
||||
|
||||
if (sel_node && sel_node.type && sel_node.type == 'coll-constraints') {
|
||||
// In order to identify the constraint type, the type should be passed to the server
|
||||
sel_rows = sel_row_models.map(row => ({id: row.get('oid'), _type: row.get('_type')}));
|
||||
}
|
||||
else {
|
||||
sel_rows = sel_row_models.map(row => row.id);
|
||||
}
|
||||
|
||||
if (sel_rows.length === 0) {
|
||||
Notify.alert(gettext('Drop Multiple'),
|
||||
gettext('Please select at least one object to delete.')
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sel_node)
|
||||
return;
|
||||
|
||||
if (type === 'dropCascade') {
|
||||
url = sel_node.generate_url(sel_item, 'delete');
|
||||
msg = gettext('Are you sure you want to drop all the selected objects and all the objects that depend on them?');
|
||||
title = gettext('DROP CASCADE multiple objects?');
|
||||
} else {
|
||||
url = sel_node.generate_url(sel_item, 'drop');
|
||||
msg = gettext('Are you sure you want to drop all the selected objects?');
|
||||
title = gettext('DROP multiple objects?');
|
||||
}
|
||||
|
||||
let dropAjaxHook = function() {
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: 'DELETE',
|
||||
data: JSON.stringify({'ids': sel_rows}),
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
}).done(function(res) {
|
||||
if (res.success == 0) {
|
||||
pgBrowser.report_error(res.errormsg, res.info);
|
||||
} else {
|
||||
$(pgBrowser.panels['properties'].panel).removeData('node-prop');
|
||||
pgBrowser.Events.trigger(
|
||||
'pgadmin:browser:tree:refresh', sel_item || pgBrowser.tree.selected(), {
|
||||
success: function() {
|
||||
setTimeout(function() {
|
||||
pgBrowser.tree.select(sel_item);
|
||||
sel_node.callbacks.selected.apply(sel_node, [sel_item]);
|
||||
}, 100);
|
||||
},
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}).fail(function(xhr, error) {
|
||||
Notify.pgNotifier(
|
||||
error, xhr,
|
||||
gettext('Error dropping %s', d._label.toLowerCase()),
|
||||
function(alertMsg) {
|
||||
if (alertMsg == 'CRYPTKEY_SET') {
|
||||
onDrop(type, false);
|
||||
} else {
|
||||
$(pgBrowser.panels['properties'].panel).removeData('node-prop');
|
||||
pgBrowser.Events.trigger(
|
||||
'pgadmin:browser:tree:refresh', sel_item || pgBrowser.tree.selected(), {
|
||||
success: function() {
|
||||
sel_node.callbacks.selected.apply(sel_node, [sel_item]);
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
if(confirm) {
|
||||
Notify.confirm(title, msg, dropAjaxHook, null);
|
||||
} else {
|
||||
dropAjaxHook();
|
||||
}
|
||||
}.bind(that);
|
||||
},
|
||||
__loadMoreRows: function(e) {
|
||||
let elem = e.currentTarget;
|
||||
if ((elem.scrollHeight - 10) < elem.scrollTop + elem.offsetHeight) {
|
||||
if (this.data.length > 0) {
|
||||
this.collection.add(this.data.splice(0, 50));
|
||||
}
|
||||
}
|
||||
},
|
||||
__loadAllRows: function(tmp, checked) {
|
||||
if (this.data.length > 0) {
|
||||
this.collection.add(this.data);
|
||||
this.collection.each(function (model) {
|
||||
model.trigger('backgrid:select', model, checked);
|
||||
});
|
||||
}
|
||||
},
|
||||
generate_url: function(item, type) {
|
||||
/*
|
||||
|
||||
@@ -1082,8 +1082,6 @@ define('pgadmin.browser.node', [
|
||||
b.panels['properties'] &&
|
||||
b.panels['properties'].panel &&
|
||||
b.panels['properties'].panel.isVisible()) {
|
||||
// Show object properties (only when the 'properties' tab
|
||||
// is active).
|
||||
this.showProperties(item, d, b.panels['properties'].panel);
|
||||
}
|
||||
}
|
||||
@@ -1259,20 +1257,20 @@ define('pgadmin.browser.node', [
|
||||
d = i && tree.itemData(i),
|
||||
treeHierarchy = tree.getTreeNodeHierarchy(i);
|
||||
|
||||
if (_.isEqual($(this).data('node-prop'), treeHierarchy)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Cache the current IDs for next time
|
||||
$(this).data('node-prop', treeHierarchy);
|
||||
|
||||
/* Remove any dom rendered by getNodeView */
|
||||
removeNodeView(j[0]);
|
||||
/* getSchema is a schema for React. Get the react node view */
|
||||
removeNodeView(pgBrowser.panels['properties'].panel.$container[0]);
|
||||
|
||||
var containerProperties = pgBrowser.panels['properties'].panel.$container;
|
||||
containerProperties.addClass('pg-panel-content pg-no-overflow pg-el-container');
|
||||
|
||||
|
||||
if(that.getSchema) {
|
||||
let treeNodeInfo = pgBrowser.tree.getTreeNodeHierarchy(item);
|
||||
getNodeView(
|
||||
that.type, treeNodeInfo, 'properties', data, 'tab', j[0], this, onEdit
|
||||
that.type, treeNodeInfo, 'properties', data, 'tab', containerProperties[0], this, onEdit
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -25,8 +25,9 @@ export function generateCollectionURL(item, type) {
|
||||
};
|
||||
var treeInfo = pgAdmin.Browser.tree.getTreeNodeHierarchy(item);
|
||||
var actionType = type in opURL ? opURL[type] : type;
|
||||
var nodeType = type === 'properties' ? nodeObj.type : nodeObj.node;
|
||||
return generate_url(
|
||||
pgAdmin.Browser.URL, treeInfo, actionType, nodeObj.node,
|
||||
pgAdmin.Browser.URL, treeInfo, actionType, nodeType,
|
||||
collectionPickFunction
|
||||
);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ import {getHelpUrl, getEPASHelpUrl} from 'pgadmin.help';
|
||||
import SchemaView from 'sources/SchemaView';
|
||||
import { generateNodeUrl } from './node_ajax';
|
||||
import Notify from '../../../static/js/helpers/Notifier';
|
||||
|
||||
import gettext from 'sources/gettext';
|
||||
import 'wcdocker';
|
||||
|
||||
|
||||
@@ -122,14 +122,32 @@ define(
|
||||
that.resizedContainer.apply(myPanel);
|
||||
}
|
||||
|
||||
// Bind events only if they are configurable
|
||||
if (that.canHide) {
|
||||
_.each([wcDocker.EVENT.CLOSED, wcDocker.EVENT.VISIBILITY_CHANGED],
|
||||
function(ev) {
|
||||
myPanel.on(ev, that.handleVisibility.bind(myPanel, ev));
|
||||
});
|
||||
|
||||
|
||||
if (myPanel._type == 'dashboard') {
|
||||
getPanelView(
|
||||
pgBrowser.tree,
|
||||
$container[0],
|
||||
pgBrowser,
|
||||
myPanel._type
|
||||
);
|
||||
}
|
||||
|
||||
// Rerender the dashboard panel when preference value 'show graph' gets changed.
|
||||
pgBrowser.onPreferencesChange('dashboards', function() {
|
||||
getPanelView(
|
||||
pgBrowser.tree,
|
||||
$container[0],
|
||||
pgBrowser,
|
||||
myPanel._type
|
||||
);
|
||||
});
|
||||
|
||||
_.each([wcDocker.EVENT.CLOSED, wcDocker.EVENT.VISIBILITY_CHANGED],
|
||||
function(ev) {
|
||||
myPanel.on(ev, that.handleVisibility.bind(myPanel, ev));
|
||||
});
|
||||
|
||||
pgBrowser.Events.on('pgadmin-browser:tree:selected', () => {
|
||||
|
||||
if(myPanel.isVisible()) {
|
||||
@@ -141,6 +159,18 @@ define(
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
pgBrowser.Events.on('pgadmin-browser:tree:refreshing', () => {
|
||||
|
||||
if(myPanel.isVisible()) {
|
||||
getPanelView(
|
||||
pgBrowser.tree,
|
||||
$container[0],
|
||||
pgBrowser,
|
||||
myPanel._type
|
||||
);
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -205,11 +235,6 @@ define(
|
||||
}
|
||||
},
|
||||
handleVisibility: function(eventName) {
|
||||
// Supported modules
|
||||
let type_module = {
|
||||
dashboard: pgAdmin.Dashboard,
|
||||
};
|
||||
let module = type_module[this._type];
|
||||
if (_.isNull(pgBrowser.tree)) return;
|
||||
|
||||
let selectedPanel = pgBrowser.docker.findPanels(this._type)[0];
|
||||
@@ -219,18 +244,6 @@ define(
|
||||
.scene()
|
||||
.find('.pg-panel-content');
|
||||
|
||||
if (this._type === 'dashboard') {
|
||||
if (eventName == 'panelClosed') {
|
||||
module.toggleVisibility.call(module, false, true);
|
||||
} else if (eventName == 'panelVisibilityChanged') {
|
||||
module.toggleVisibility.call(
|
||||
module,
|
||||
pgBrowser.docker.findPanels(this._type)[0].isVisible(),
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (isPanelVisible) {
|
||||
if (eventName == 'panelClosed') {
|
||||
removePanelView($container[0]);
|
||||
|
||||
@@ -13,6 +13,11 @@ import Theme from 'sources/Theme';
|
||||
import Dependencies from '../../../misc/dependencies/static/js/Dependencies';
|
||||
import Dependents from '../../../misc/dependents/static/js/Dependents';
|
||||
import Statistics from '../../../misc/statistics/static/js/Statistics';
|
||||
import SQL from '../../../misc/sql/static/js/SQL';
|
||||
import Dashboard from '../../../dashboard/static/js/Dashboard';
|
||||
import _ from 'lodash';
|
||||
import { CollectionNodeView } from '../../../misc/properties/CollectionNodeProperties';
|
||||
|
||||
|
||||
/* The entry point for rendering React based view in properties, called in node.js */
|
||||
export function getPanelView(
|
||||
@@ -21,10 +26,33 @@ export function getPanelView(
|
||||
pgBrowser,
|
||||
panelType
|
||||
) {
|
||||
let item = tree.selected(),
|
||||
nodeData = item && tree.itemData(item),
|
||||
node = item && nodeData && pgBrowser.Nodes[nodeData._type],
|
||||
let item = !_.isNull(tree)? tree.selected(): null,
|
||||
|
||||
nodeData, node, treeNodeInfo, preferences;
|
||||
if (item){
|
||||
nodeData = tree.itemData(item);
|
||||
node = nodeData && pgBrowser.Nodes[nodeData._type];
|
||||
treeNodeInfo = pgBrowser.tree.getTreeNodeHierarchy(item);
|
||||
preferences = pgBrowser.get_preferences_for_module('dashboards');
|
||||
}
|
||||
if (panelType == 'dashboard') {
|
||||
ReactDOM.render(
|
||||
<Theme>
|
||||
<Dashboard
|
||||
treeNodeInfo={treeNodeInfo}
|
||||
pgBrowser={pgBrowser}
|
||||
nodeData={nodeData}
|
||||
node={node}
|
||||
item={item}
|
||||
preferences={preferences}
|
||||
did={((!_.isUndefined(treeNodeInfo)) && (!_.isUndefined(treeNodeInfo['database']))) ? treeNodeInfo['database']._id: 0}
|
||||
sid={!_.isUndefined(treeNodeInfo) && !_.isUndefined(treeNodeInfo['server']) ? treeNodeInfo['server']._id : ''}
|
||||
serverConnected={!_.isUndefined(treeNodeInfo) && !_.isUndefined(treeNodeInfo['server']) ? treeNodeInfo.server.connected: false}
|
||||
/>
|
||||
</Theme>,
|
||||
container
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if (panelType == 'statistics') {
|
||||
@@ -41,6 +69,20 @@ export function getPanelView(
|
||||
container
|
||||
);
|
||||
}
|
||||
if (panelType == 'properties') {
|
||||
ReactDOM.render(
|
||||
<Theme>
|
||||
<CollectionNodeView
|
||||
treeNodeInfo={treeNodeInfo}
|
||||
item={item}
|
||||
itemNodeData={nodeData}
|
||||
node={node}
|
||||
pgBrowser={pgBrowser}
|
||||
/>
|
||||
</Theme>,
|
||||
container
|
||||
);
|
||||
}
|
||||
if (panelType == 'dependencies') {
|
||||
ReactDOM.render(
|
||||
<Theme>
|
||||
@@ -69,6 +111,20 @@ export function getPanelView(
|
||||
container
|
||||
);
|
||||
}
|
||||
if (panelType == 'sql') {
|
||||
ReactDOM.render(
|
||||
<Theme>
|
||||
<SQL
|
||||
treeNodeInfo={treeNodeInfo}
|
||||
pgBrowser={pgBrowser}
|
||||
nodeData={nodeData}
|
||||
node={node}
|
||||
item={item}
|
||||
/>
|
||||
</Theme>,
|
||||
container
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/* When switching from normal node to collection node, clean up the React mounted DOM */
|
||||
|
||||
Reference in New Issue
Block a user