mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-10 15:36:06 -06:00
Fixed all the review comments from Dave.
* Moved the Columns, and Constraint to its repective tabs. * Ensure all the labels only have a capital letter on the first word (except for keywords or acronyms). * Resolve the typo in string - 'System table'. * Error messages on fields should not be shown unless the field loses focus and has an error. * "General" section should have a limited subset of information. * Variables grids should not be on the Security tab. * Fixes the field labels that imply a question. * Privileges controls on the Properties lists should be in a "Security" group. Apart from review comments improved few other areas too: * Used in-place DepsCell functionality for columns in both index, and type node. * Improved the error handling in constraint nodes. * Added create, alert SQL Help for nodes associated with the table node.
This commit is contained in:
parent
8c077bc2df
commit
af84ba5a4f
@ -15,33 +15,6 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
});
|
||||
};
|
||||
|
||||
// Switch Cell for Primary Key selection
|
||||
var SwitchDepCell = Backgrid.BooleanCell.extend({
|
||||
initialize: function() {
|
||||
Backgrid.BooleanCell.prototype.initialize.apply(this, arguments);
|
||||
Backgrid.Extension.DependentCell.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
dependentChanged: function () {
|
||||
var model = this.model,
|
||||
column = this.column,
|
||||
editable = this.column.get("editable"),
|
||||
input = this.$el.find('input[type=checkbox]').first();
|
||||
|
||||
is_editable = _.isFunction(editable) ? !!editable.apply(column, [model]) : !!editable;
|
||||
if (is_editable) {
|
||||
this.$el.addClass("editable");
|
||||
input.prop('disabled', false);
|
||||
} else {
|
||||
this.$el.removeClass("editable");
|
||||
input.prop('disabled', true);
|
||||
}
|
||||
|
||||
this.delegateEvents();
|
||||
return this;
|
||||
},
|
||||
remove: Backgrid.Extension.DependentCell.prototype.remove
|
||||
});
|
||||
|
||||
// This Node model will be used for variable control for column
|
||||
var VariablesModel = Backform.VariablesModel = pgAdmin.Browser.Node.Model.extend({
|
||||
defaults: {
|
||||
@ -84,6 +57,8 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
type: 'column',
|
||||
label: '{{ _('Column') }}',
|
||||
hasSQL: true,
|
||||
sqlAlterHelp: 'sql-altertable.html',
|
||||
sqlCreateHelp: 'sql-altertable.html',
|
||||
canDrop: function(itemData, item, data){
|
||||
if (pgBrowser.Nodes['schema'].canChildDrop.apply(this, [itemData, item, data])) {
|
||||
var t = pgBrowser.tree, i = item, d = itemData, parents = [];
|
||||
@ -294,7 +269,9 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
});
|
||||
|
||||
flag && setTimeout(function() {
|
||||
m.set('attlen', null);
|
||||
if(m.get('attlen')) {
|
||||
m.set('attlen', null);
|
||||
}
|
||||
},10);
|
||||
|
||||
return flag;
|
||||
@ -317,8 +294,10 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
});
|
||||
|
||||
flag && setTimeout(function() {
|
||||
if(m.get('attprecision')) {
|
||||
m.set('attprecision', null);
|
||||
},10);
|
||||
}
|
||||
},10);
|
||||
return flag;
|
||||
}
|
||||
},{
|
||||
@ -338,7 +317,9 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
});
|
||||
if (flag) {
|
||||
setTimeout(function(){
|
||||
m.set('collspcname', "");
|
||||
if(m.get('collspcname') && m.get('collspcname') !== '') {
|
||||
m.set('collspcname', "");
|
||||
}
|
||||
}, 10);
|
||||
}
|
||||
return flag;
|
||||
@ -371,16 +352,20 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
]
|
||||
},{
|
||||
id: 'is_pk', label:'{{ _('Primary key?') }}',
|
||||
type: 'switch', disabled: true, mode: ['properties']
|
||||
type: 'switch', disabled: true, mode: ['properties'],
|
||||
group: '{{ _('Definition') }}'
|
||||
},{
|
||||
id: 'is_fk', label:'{{ _('Foreign key?') }}',
|
||||
type: 'switch', disabled: true, mode: ['properties']
|
||||
type: 'switch', disabled: true, mode: ['properties'],
|
||||
group: '{{ _('Definition') }}'
|
||||
},{
|
||||
id: 'is_inherited', label:'{{ _('Inherited?') }}',
|
||||
type: 'switch', disabled: true, mode: ['properties']
|
||||
type: 'switch', disabled: true, mode: ['properties'],
|
||||
group: '{{ _('Definition') }}'
|
||||
},{
|
||||
id: 'tbls_inherited', label:'{{ _('Inherited from table(s)') }}',
|
||||
type: 'text', disabled: true, mode: ['properties'], deps: ['is_inherited'],
|
||||
group: '{{ _('Definition') }}',
|
||||
visible: function(m) {
|
||||
if (!_.isUndefined(m.get('is_inherited')) && m.get('is_inherited')) {
|
||||
return true;
|
||||
@ -389,12 +374,18 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
}
|
||||
}
|
||||
},{
|
||||
id: 'is_sys_column', label:'{{ _('System Column?') }}', cell: 'string',
|
||||
id: 'is_sys_column', label:'{{ _('System column?') }}', cell: 'string',
|
||||
type: 'switch', disabled: true, mode: ['properties']
|
||||
},{
|
||||
id: 'description', label:'{{ _('Comment') }}', cell: 'string',
|
||||
type: 'multiline', mode: ['properties', 'create', 'edit'],
|
||||
disabled: 'inSchema'
|
||||
},{
|
||||
id: 'attoptions', label: 'Variables', type: 'collection',
|
||||
group: '{{ _('Variables') }}', control: 'unique-col-collection',
|
||||
model: VariablesModel, uniqueCol : ['name'],
|
||||
mode: ['edit', 'create'], canAdd: true, canEdit: false,
|
||||
canDelete: true
|
||||
},{
|
||||
id: 'attacl', label: 'Privileges', type: 'collection',
|
||||
group: '{{ _('Security') }}', control: 'unique-col-collection',
|
||||
@ -402,12 +393,6 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
privileges: ['a','r','w','x']}),
|
||||
mode: ['edit'], canAdd: true, canDelete: true,
|
||||
uniqueCol : ['grantee']
|
||||
},{
|
||||
id: 'attoptions', label: 'Variables', type: 'collection',
|
||||
group: '{{ _('Security') }}', control: 'unique-col-collection',
|
||||
model: VariablesModel, uniqueCol : ['name'],
|
||||
mode: ['edit', 'create'], canAdd: true, canEdit: false,
|
||||
canDelete: true
|
||||
},{
|
||||
id: 'seclabels', label: '{{ _('Security Labels') }}',
|
||||
model: pgAdmin.Browser.SecurityModel,
|
||||
@ -506,7 +491,7 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
var node_info = this.node_info || m.node_info || m.top.node_info;
|
||||
|
||||
// disable all fields if column is listed under view or mview
|
||||
if ('view' in node_info || 'mview' in node_info) {
|
||||
if (node_info && ('view' in node_info || 'mview' in node_info)) {
|
||||
if (this && _.has(this, 'name') && (this.name != 'defval')) {
|
||||
return true;
|
||||
}
|
||||
|
@ -111,7 +111,8 @@ function($, _, S, pgAdmin, pgBrowser, Alertify) {
|
||||
var name = m.get('name');
|
||||
if (!(name && name != '')) {
|
||||
setTimeout(function(){
|
||||
m.set('comment', null);
|
||||
if(m.get('comment') && m.get('comment') !== '')
|
||||
m.set('comment', null);
|
||||
},10);
|
||||
return true;
|
||||
} else {
|
||||
@ -127,7 +128,7 @@ function($, _, S, pgAdmin, pgBrowser, Alertify) {
|
||||
!_.isUndefined(m.get('oid'))) || (_.isFunction(m.isNew) && !m.isNew()));
|
||||
}, editable: false
|
||||
},{
|
||||
id: 'connoinherit', label: '{{ _('No Inherit') }}', type:
|
||||
id: 'connoinherit', label: '{{ _('No Inherit?') }}', type:
|
||||
'switch', cell: 'boolean', group: '{{ _('Definition') }}', mode:
|
||||
['properties', 'create', 'edit'], min_version: 90200,
|
||||
disabled: function(m) {
|
||||
@ -136,7 +137,7 @@ function($, _, S, pgAdmin, pgBrowser, Alertify) {
|
||||
!_.isUndefined(m.get('oid'))) || (_.isFunction(m.isNew) && !m.isNew()));
|
||||
}
|
||||
},{
|
||||
id: 'convalidated', label: "{{ _("Don't validate") }}", type: 'switch', cell:
|
||||
id: 'convalidated', label: "{{ _("Don't validate?") }}", type: 'switch', cell:
|
||||
'boolean', group: '{{ _('Definition') }}', min_version: 90200,
|
||||
disabled: function(m) {
|
||||
if ((_.isFunction(m.isNew) && !m.isNew()) ||
|
||||
|
@ -653,7 +653,8 @@ function($, _, S, pgAdmin, pgBrowser, Alertify) {
|
||||
var name = m.get('name');
|
||||
if (!(name && name != '')) {
|
||||
setTimeout(function(){
|
||||
m.set('comment', null);
|
||||
if(m.get('comment') && m.get('comment') !== '')
|
||||
m.set('comment', null);
|
||||
},10);
|
||||
return true;
|
||||
} else {
|
||||
@ -713,7 +714,7 @@ function($, _, S, pgAdmin, pgBrowser, Alertify) {
|
||||
id: 'fillfactor', label: '{{ _('Fill factor') }}',
|
||||
type: 'int', group: '{{ _('Definition') }}', allowNull: true
|
||||
},{
|
||||
id: 'condeferrable', label: '{{ _('Deferrable') }}',
|
||||
id: 'condeferrable', label: '{{ _('Deferrable?') }}',
|
||||
type: 'switch', group: '{{ _('Definition') }}', deps: ['index'],
|
||||
disabled: function(m) {
|
||||
return ((_.has(m, 'handler') &&
|
||||
@ -721,7 +722,7 @@ function($, _, S, pgAdmin, pgBrowser, Alertify) {
|
||||
!_.isUndefined(m.get('oid'))) || (_.isFunction(m.isNew) && !m.isNew()));
|
||||
}
|
||||
},{
|
||||
id: 'condeferred', label: '{{ _('Deferred') }}',
|
||||
id: 'condeferred', label: '{{ _('Deferred?') }}',
|
||||
type: 'switch', group: '{{ _('Definition') }}',
|
||||
deps: ['condeferrable'],
|
||||
disabled: function(m) {
|
||||
@ -736,7 +737,8 @@ function($, _, S, pgAdmin, pgBrowser, Alertify) {
|
||||
return false;
|
||||
} else {
|
||||
setTimeout(function(){
|
||||
m.set('condeferred', false);
|
||||
if(m.get('condeferred'))
|
||||
m.set('condeferred', false);
|
||||
},10);
|
||||
return true;
|
||||
}
|
||||
|
@ -21,9 +21,6 @@ function($, _, S, pgAdmin, pgBrowser, Alertify) {
|
||||
headerSelectControlTemplate = _.template([
|
||||
'<div class="<%=Backform.controlsClassName%> <%=extraClasses.join(\' \')%>">',
|
||||
' <select class="pgadmin-node-select form-control" name="<%=name%>" style="width:100%;" value="<%-value%>" <%=disabled ? "disabled" : ""%> <%=required ? "required" : ""%> >',
|
||||
' <% if (first_empty) { %>',
|
||||
' <option value="" <%="" === rawValue ? "selected" : "" %>><%- empty_value %></option>',
|
||||
' <% } %>',
|
||||
' <% for (var i=0; i < options.length; i++) { %>',
|
||||
' <% var option = options[i]; %>',
|
||||
' <option <% if (option.image) { %> data-image=<%= option.image %> <% } %> value=<%= formatter.fromRaw(option.value) %> <%=option.value === rawValue ? "selected=\'selected\'" : "" %>><%-option.label%></option>',
|
||||
@ -702,7 +699,8 @@ function($, _, S, pgAdmin, pgBrowser, Alertify) {
|
||||
var name = m.get('name');
|
||||
if (!(name && name != '')) {
|
||||
setTimeout(function(){
|
||||
m.set('comment', null);
|
||||
if(m.get('comment') && m.get('comment') !== '')
|
||||
m.set('comment', null);
|
||||
},10);
|
||||
return true;
|
||||
} else {
|
||||
@ -710,7 +708,7 @@ function($, _, S, pgAdmin, pgBrowser, Alertify) {
|
||||
}
|
||||
}
|
||||
},{
|
||||
id: 'condeferrable', label: '{{ _('Deferrable') }}',
|
||||
id: 'condeferrable', label: '{{ _('Deferrable?') }}',
|
||||
type: 'switch', group: '{{ _('Definition') }}',
|
||||
disabled: function(m) {
|
||||
// If we are in table edit mode then
|
||||
@ -723,7 +721,7 @@ function($, _, S, pgAdmin, pgBrowser, Alertify) {
|
||||
return !m.isNew();
|
||||
}
|
||||
},{
|
||||
id: 'condeferred', label: '{{ _('Deferred') }}',
|
||||
id: 'condeferred', label: '{{ _('Deferred?') }}',
|
||||
type: 'switch', group: '{{ _('Definition') }}',
|
||||
deps: ['condeferrable'],
|
||||
disabled: function(m) {
|
||||
@ -740,7 +738,8 @@ function($, _, S, pgAdmin, pgBrowser, Alertify) {
|
||||
return false;
|
||||
} else {
|
||||
setTimeout(function(){
|
||||
m.set('condeferred', false);
|
||||
if(m.get('condeferred'))
|
||||
m.set('condeferred', false);
|
||||
},10);
|
||||
return true;
|
||||
}
|
||||
@ -778,7 +777,7 @@ function($, _, S, pgAdmin, pgBrowser, Alertify) {
|
||||
return !(m.isNew() || m.get("convalidated"));
|
||||
}
|
||||
},{
|
||||
id: 'autoindex', label: '{{ _('Auto FK index') }}',
|
||||
id: 'autoindex', label: '{{ _('Auto FK index?') }}',
|
||||
type: 'switch', group: '{{ _('Definition') }}',
|
||||
deps: ['name', 'hasindex'],
|
||||
options: {
|
||||
@ -809,7 +808,8 @@ function($, _, S, pgAdmin, pgBrowser, Alertify) {
|
||||
// new constraint which should allowed for Unique
|
||||
if(_.isUndefined(m.get('oid')) && _.isUndefined(m.handler.get('oid'))) {
|
||||
setTimeout(function () {
|
||||
m.set('autoindex', false);
|
||||
if(m.get('autoindex'))
|
||||
m.set('autoindex', false);
|
||||
}, 10);
|
||||
return true;
|
||||
} else {
|
||||
|
@ -101,7 +101,9 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
|
||||
var name = m.get('name');
|
||||
if (!(name && name != '')) {
|
||||
setTimeout(function(){
|
||||
m.set('comment', null);
|
||||
if(m.get('comment') && m.get('comment') !== '') {
|
||||
m.set('comment', null);
|
||||
}
|
||||
},10);
|
||||
return true;
|
||||
} else {
|
||||
@ -207,17 +209,6 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
|
||||
}),
|
||||
canDelete: true, canAdd: true,
|
||||
control: Backform.MultiSelectAjaxControl.extend({
|
||||
formatter: {
|
||||
fromRaw: function (rawData, model) {
|
||||
var res = _.isObject(rawData) ?
|
||||
rawData : JSON.parse(rawData);
|
||||
|
||||
return _.pluck(res, 'column');
|
||||
},
|
||||
toRaw: function (formattedData, model) {
|
||||
return formattedData;
|
||||
}
|
||||
},
|
||||
defaults: _.extend(
|
||||
{},
|
||||
Backform.NodeListByNameControl.prototype.defaults,
|
||||
@ -454,7 +445,7 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
|
||||
}
|
||||
}
|
||||
},{
|
||||
id: 'condeferrable', label: '{{ _('Deferrable') }}',
|
||||
id: 'condeferrable', label: '{{ _('Deferrable?') }}',
|
||||
type: 'switch', group: '{{ _('Definition') }}', deps: ['index'],
|
||||
disabled: function(m) {
|
||||
// If we are in table edit mode then
|
||||
@ -475,13 +466,14 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
|
||||
return false;
|
||||
} else {
|
||||
setTimeout(function(){
|
||||
m.set('condeferrable', false);
|
||||
if(m.get('condeferrable'))
|
||||
m.set('condeferrable', false);
|
||||
},10);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
},{
|
||||
id: 'condeferred', label: '{{ _('Deferred') }}',
|
||||
id: 'condeferred', label: '{{ _('Deferred?') }}',
|
||||
type: 'switch', group: '{{ _('Definition') }}',
|
||||
deps: ['condeferrable'],
|
||||
disabled: function(m) {
|
||||
@ -502,7 +494,8 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
|
||||
return false;
|
||||
} else {
|
||||
setTimeout(function(){
|
||||
m.set('condeferred', false);
|
||||
if(m.get('condeferred'))
|
||||
m.set('condeferred', false);
|
||||
},10);
|
||||
return true;
|
||||
}
|
||||
|
@ -15,6 +15,34 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
});
|
||||
};
|
||||
|
||||
// Node-Ajax-Cell with Deps
|
||||
var NodeAjaxOptionsDepsCell = Backgrid.Extension.NodeAjaxOptionsCell.extend({
|
||||
initialize: function() {
|
||||
Backgrid.Extension.NodeAjaxOptionsCell.prototype.initialize.apply(this, arguments);
|
||||
Backgrid.Extension.DependentCell.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
dependentChanged: function () {
|
||||
var model = this.model,
|
||||
column = this.column,
|
||||
editable = this.column.get("editable"),
|
||||
input = this.$el.find('select').first();
|
||||
|
||||
is_editable = _.isFunction(editable) ? !!editable.apply(column, [model]) : !!editable;
|
||||
if (is_editable) {
|
||||
this.$el.addClass("editable");
|
||||
input.prop('disabled', false);
|
||||
} else {
|
||||
this.$el.removeClass("editable");
|
||||
input.prop('disabled', true);
|
||||
}
|
||||
|
||||
this.delegateEvents();
|
||||
return this;
|
||||
},
|
||||
remove: Backgrid.Extension.DependentCell.prototype.remove
|
||||
});
|
||||
|
||||
|
||||
// Model to create column collection control
|
||||
var ColumnModel = pgAdmin.Browser.Node.Model.extend({
|
||||
defaults: {
|
||||
@ -26,23 +54,38 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
id: 'colname', label:'{{ _('Column') }}', cell: 'string',
|
||||
type: 'text', disabled: 'inSchema', editable: false,
|
||||
id: 'colname', label:'{{ _('Column') }}', cell: 'node-list-by-name',
|
||||
type: 'text', disabled: 'inSchema', editable: true,
|
||||
control: 'node-list-by-name', node: 'column'
|
||||
},{
|
||||
id: 'collspcname', label:'{{ _('Collation') }}', cell: 'string',
|
||||
type: 'text', disabled: 'inSchema', editable: false,
|
||||
id: 'collspcname', label:'{{ _('Collation') }}',
|
||||
cell: NodeAjaxOptionsDepsCell,
|
||||
type: 'text', disabled: 'inSchema', editable: function(m) {
|
||||
// Header cell then skip
|
||||
if (m instanceof Backbone.Collection) {
|
||||
return false;
|
||||
}
|
||||
return !(m.inSchema.apply(this, arguments));
|
||||
},
|
||||
control: 'node-ajax-options', url: 'get_collations', node: 'index'
|
||||
},{
|
||||
id: 'op_class', label:'{{ _('Operator class') }}', cell: 'string',
|
||||
type: 'text', disabled: 'checkAccessMethod', editable: false,
|
||||
id: 'op_class', label:'{{ _('Operator class') }}',
|
||||
cell: NodeAjaxOptionsDepsCell,
|
||||
type: 'text', disabled: 'checkAccessMethod',
|
||||
editable: function(m) {
|
||||
// Header cell then skip
|
||||
if (m instanceof Backbone.Collection) {
|
||||
return false;
|
||||
}
|
||||
return !(m.checkAccessMethod.apply(this, arguments));
|
||||
},
|
||||
control: 'node-ajax-options', url: 'get_op_class', node: 'index',
|
||||
deps: ['amname'], transform: function(data) {
|
||||
deps: ['amname'], transform: function(data, control) {
|
||||
/* We need to extract data from collection according
|
||||
* to access method selected by user if not selected
|
||||
* send btree related op_class options
|
||||
*/
|
||||
var amname = this.model.handler.get('amname'),
|
||||
var amname = control.model.top.get('amname'),
|
||||
options = data['btree'];
|
||||
|
||||
if(_.isUndefined(amname))
|
||||
@ -56,21 +99,35 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
return options;
|
||||
}
|
||||
},{
|
||||
id: 'sort_order', label:'{{ _('Sort order') }}', cell: 'switch',
|
||||
type: 'switch', disabled: 'checkAccessMethod', editable: false,
|
||||
id: 'sort_order', label:'{{ _('Sort order') }}', cell: SwitchDepCell,
|
||||
type: 'switch', disabled: 'checkAccessMethod',
|
||||
editable: function(m) {
|
||||
// Header cell then skip
|
||||
if (m instanceof Backbone.Collection) {
|
||||
return false;
|
||||
}
|
||||
return !(m.checkAccessMethod.apply(this, arguments));
|
||||
},
|
||||
deps: ['amname'],
|
||||
options: {
|
||||
'onText': 'DESC', 'offText': 'ASC',
|
||||
'onColor': 'success', 'offColor': 'default',
|
||||
'onColor': 'success', 'offColor': 'primary',
|
||||
'size': 'small'
|
||||
}
|
||||
},{
|
||||
id: 'nulls', label:'{{ _('NULLs') }}', cell: 'switch',
|
||||
type: 'switch', disabled: 'checkAccessMethod', editable: false,
|
||||
id: 'nulls', label:'{{ _('NULLs') }}', cell: SwitchDepCell,
|
||||
type: 'switch', disabled: 'checkAccessMethod',
|
||||
editable: function(m) {
|
||||
// Header cell then skip
|
||||
if (m instanceof Backbone.Collection) {
|
||||
return true;
|
||||
}
|
||||
return !(m.checkAccessMethod.apply(this, arguments));
|
||||
},
|
||||
deps: ['amname', 'sort_order'],
|
||||
options: {
|
||||
'onText': 'FIRST', 'offText': 'LAST',
|
||||
'onColor': 'success', 'offColor': 'default',
|
||||
'onColor': 'success', 'offColor': 'primary',
|
||||
'size': 'small'
|
||||
}
|
||||
}
|
||||
@ -107,7 +164,7 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
// We will check if we are under schema node and added condition
|
||||
checkAccessMethod: function(m) {
|
||||
//Access method is empty or btree then do not disable field
|
||||
var parent_model = m.handler;
|
||||
var parent_model = m.top;
|
||||
if(!m.inSchema.apply(this, [m]) &&
|
||||
(_.isUndefined(parent_model.get('amname')) ||
|
||||
_.isNull(parent_model.get('amname')) ||
|
||||
@ -115,10 +172,8 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
parent_model.get('amname') === 'btree')) {
|
||||
// We need to set nulls to true if sort_order is set to desc
|
||||
// nulls first is default for desc
|
||||
if(m.get('sort_order') == true) {
|
||||
if(m.get('sort_order') == true && m.previous('sort_order') == false) {
|
||||
setTimeout(function() { m.set('nulls', true) }, 10);
|
||||
} else {
|
||||
setTimeout(function() { m.set('nulls', false) }, 10);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -130,6 +185,8 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
pgAdmin.Browser.Nodes['index'] = pgAdmin.Browser.Node.extend({
|
||||
parent_type: ['table', 'view', 'mview'],
|
||||
collection_type: ['coll-table', 'coll-view'],
|
||||
sqlAlterHelp: 'sql-alterindex.html',
|
||||
sqlCreateHelp: 'sql-createindex.html',
|
||||
type: 'index',
|
||||
label: '{{ _('Index') }}',
|
||||
hasSQL: true,
|
||||
@ -228,7 +285,8 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
})
|
||||
},{
|
||||
id: 'cols', label:'{{ _('Columns') }}', cell: 'string',
|
||||
type: 'text', disabled: 'inSchema', mode: ['properties']
|
||||
type: 'text', disabled: 'inSchema', mode: ['properties'],
|
||||
group: '{{ _('Definition') }}'
|
||||
},{
|
||||
id: 'fillfactor', label:'{{ _('Fill factor') }}', cell: 'string',
|
||||
type: 'int', disabled: 'inSchema', mode: ['create', 'edit', 'properties'],
|
||||
@ -244,15 +302,14 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
},{
|
||||
id: 'indisvalid', label:'{{ _('Valid?') }}', cell: 'string',
|
||||
type: 'switch', disabled: true, mode: ['properties'],
|
||||
|
||||
group: '{{ _('Definition') }}'
|
||||
},{
|
||||
id: 'indisprimary', label:'{{ _('Primary?') }}', cell: 'string',
|
||||
type: 'switch', disabled: true, mode: ['properties'],
|
||||
|
||||
group: '{{ _('Definition') }}'
|
||||
},{
|
||||
id: 'is_sys_idx', label:'{{ _('System index?') }}', cell: 'string',
|
||||
type: 'switch', disabled: true, mode: ['properties'],
|
||||
|
||||
type: 'switch', disabled: true, mode: ['properties']
|
||||
},{
|
||||
id: 'isconcurrent', label:'{{ _('Concurrent build?') }}', cell: 'string',
|
||||
type: 'switch', disabled: 'inSchemaWithModelCheck',
|
||||
@ -262,7 +319,7 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
type: 'text', disabled: 'inSchemaWithModelCheck', mode: ['create', 'edit'],
|
||||
control: 'sql-field', visible: true, group: '{{ _('Definition') }}'
|
||||
},{
|
||||
id: 'columns', label: 'Columns', type: 'collection',
|
||||
id: 'columns', label: 'Columns', type: 'collection', deps: ['amname'],
|
||||
group: '{{ _('Definition') }}', model: ColumnModel, mode: ['edit', 'create'],
|
||||
canAdd: function(m) {
|
||||
// We will disable it if it's in 'edit' mode
|
||||
@ -272,14 +329,7 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
canEdit: function(m) {
|
||||
// We will disable it if it's in 'edit' mode
|
||||
if (m.isNew()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
canEdit: false,
|
||||
canDelete: function(m) {
|
||||
// We will disable it if it's in 'edit' mode
|
||||
if (m.isNew()) {
|
||||
@ -288,7 +338,8 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
control: 'unique-col-collection', uniqueCol : ['colname']
|
||||
control: 'unique-col-collection', uniqueCol : ['colname'],
|
||||
columns: ['colname', 'op_class', 'sort_order', 'nulls', 'collspcname']
|
||||
},{
|
||||
id: 'description', label:'{{ _('Comment') }}', cell: 'string',
|
||||
type: 'multiline', mode: ['properties', 'create', 'edit'],
|
||||
|
@ -16,6 +16,33 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
|
||||
});
|
||||
};
|
||||
|
||||
// Switch Cell with Deps
|
||||
var SwitchDepCell = Backgrid.Extension.SwitchCell.extend({
|
||||
initialize: function() {
|
||||
Backgrid.Extension.SwitchCell.prototype.initialize.apply(this, arguments);
|
||||
Backgrid.Extension.DependentCell.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
dependentChanged: function () {
|
||||
var model = this.model,
|
||||
column = this.column,
|
||||
editable = this.column.get("editable"),
|
||||
input = this.$el.find('input[type=checkbox]').first();
|
||||
|
||||
is_editable = _.isFunction(editable) ? !!editable.apply(column, [model]) : !!editable;
|
||||
if (is_editable) {
|
||||
this.$el.addClass("editable");
|
||||
input.prop('disabled', false);
|
||||
} else {
|
||||
this.$el.removeClass("editable");
|
||||
input.prop('disabled', true);
|
||||
}
|
||||
|
||||
this.delegateEvents();
|
||||
return this;
|
||||
},
|
||||
remove: Backgrid.Extension.DependentCell.prototype.remove
|
||||
});
|
||||
|
||||
if (!pgBrowser.Nodes['table']) {
|
||||
pgAdmin.Browser.Nodes['table'] = pgBrowser.Node.extend({
|
||||
type: 'table',
|
||||
@ -385,29 +412,30 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
|
||||
disabled: 'inSchemaWithModelCheck',
|
||||
group: '{{ _('Advanced') }}'
|
||||
},{
|
||||
id: 'conname', label:'{{ _('Primary Key') }}', cell: 'string',
|
||||
type: 'text', mode: ['properties'],
|
||||
id: 'conname', label:'{{ _('Primary key') }}', cell: 'string',
|
||||
type: 'text', mode: ['properties'], group: '{{ _('Advanced') }}',
|
||||
disabled: 'inSchema'
|
||||
},{
|
||||
id: 'reltuples', label:'{{ _('Rows (estimated)') }}', cell: 'string',
|
||||
type: 'text', mode: ['properties'],
|
||||
type: 'text', mode: ['properties'], group: '{{ _('Advanced') }}',
|
||||
disabled: 'inSchema'
|
||||
},{
|
||||
id: 'rows_cnt', label:'{{ _('Rows (counted)') }}', cell: 'string',
|
||||
type: 'text', mode: ['properties'],
|
||||
type: 'text', mode: ['properties'], group: '{{ _('Advanced') }}',
|
||||
disabled: 'inSchema'
|
||||
},{
|
||||
id: 'relhassubclass', label:'{{ _('Inherits tables?') }}', cell: 'switch',
|
||||
type: 'switch', mode: ['properties'],
|
||||
type: 'switch', mode: ['properties'], group: '{{ _('Advanced') }}',
|
||||
disabled: 'inSchema'
|
||||
},{
|
||||
id: 'is_sys_table', label:'{{ _('System tabel?') }}', cell: 'switch',
|
||||
id: 'is_sys_table', label:'{{ _('System table?') }}', cell: 'switch',
|
||||
type: 'switch', mode: ['properties'],
|
||||
disabled: 'inSchema'
|
||||
},{
|
||||
id: 'coll_inherits', label: '{{ _('Inherited from table(s)') }}',
|
||||
url: 'get_inherits', type: 'array',
|
||||
url: 'get_inherits', type: 'array', group: '{{ _('Columns') }}',
|
||||
disabled: 'checkInheritance', deps: ['typname'],
|
||||
mode: ['create', 'edit'],
|
||||
select2: { multiple: true, allowClear: true,
|
||||
placeholder: '{{ _('Select to inherit from...') }}'},
|
||||
transform: function(data, cell) {
|
||||
@ -489,194 +517,193 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
|
||||
return tbl_oid;
|
||||
}
|
||||
})
|
||||
},{
|
||||
id: 'coll_inherits', label: '{{ _('Inherited from table(s)') }}',
|
||||
url: 'get_inherits', type: 'text', group: '{{ _('Advanced') }}',
|
||||
disabled: 'checkInheritance',
|
||||
mode: ['properties'],
|
||||
},{
|
||||
id: 'inherited_tables_cnt', label:'{{ _('Inherited tables count') }}', cell: 'string',
|
||||
type: 'text', mode: ['properties'],
|
||||
type: 'text', mode: ['properties'], group: '{{ _('Advanced') }}',
|
||||
disabled: 'inSchema'
|
||||
},{
|
||||
type: 'nested', control: 'fieldset', mode: ['edit', 'create'],
|
||||
schema:[{
|
||||
// Here we will create tab control for columns
|
||||
id: 'columns', label:'{{ _('Columns') }}', type: 'collection',
|
||||
group: '{{ _('Columns') }}',
|
||||
model: pgBrowser.Nodes['column'].model,
|
||||
subnode: pgBrowser.Nodes['column'].model,
|
||||
mode: ['create', 'edit'],
|
||||
disabled: 'inSchema',
|
||||
canAdd: 'check_grid_add_condition',
|
||||
canEdit: true, canDelete: true,
|
||||
// For each row edit/delete button enable/disable
|
||||
canEditRow: 'check_grid_row_edit_delete',
|
||||
canDeleteRow: 'check_grid_row_edit_delete',
|
||||
uniqueCol : ['name'],
|
||||
columns : ['name' , 'cltype', 'is_primary_key', 'inheritedfrom'],
|
||||
control: Backform.UniqueColCollectionControl.extend({
|
||||
initialize: function() {
|
||||
Backform.UniqueColCollectionControl.prototype.initialize.apply(this, arguments);
|
||||
var self = this,
|
||||
collection = self.model.get(self.field.get('name'));
|
||||
// Here we will create tab control for columns
|
||||
id: 'columns', label:'{{ _('Columns') }}', type: 'collection',
|
||||
group: '{{ _('Columns') }}',
|
||||
model: pgBrowser.Nodes['column'].model,
|
||||
subnode: pgBrowser.Nodes['column'].model,
|
||||
mode: ['create', 'edit'],
|
||||
disabled: 'inSchema',
|
||||
canAdd: 'check_grid_add_condition',
|
||||
canEdit: true, canDelete: true,
|
||||
// For each row edit/delete button enable/disable
|
||||
canEditRow: 'check_grid_row_edit_delete',
|
||||
canDeleteRow: 'check_grid_row_edit_delete',
|
||||
uniqueCol : ['name'],
|
||||
columns : ['name' , 'cltype', 'is_primary_key', 'inheritedfrom'],
|
||||
control: Backform.UniqueColCollectionControl.extend({
|
||||
initialize: function() {
|
||||
Backform.UniqueColCollectionControl.prototype.initialize.apply(this, arguments);
|
||||
var self = this,
|
||||
collection = self.model.get(self.field.get('name'));
|
||||
|
||||
collection.on("change:is_primary_key", function(m) {
|
||||
var primary_key_coll = self.model.get('primary_key'),
|
||||
column_name = m.get('name'),
|
||||
primary_key;
|
||||
collection.on("change:is_primary_key", function(m) {
|
||||
var primary_key_coll = self.model.get('primary_key'),
|
||||
column_name = m.get('name'),
|
||||
primary_key;
|
||||
|
||||
if(m.get('is_primary_key')) {
|
||||
// Add column to primary key.
|
||||
if (primary_key_coll.length < 1) {
|
||||
primary_key = new (primary_key_coll.model)({}, {
|
||||
if(m.get('is_primary_key')) {
|
||||
// Add column to primary key.
|
||||
if (primary_key_coll.length < 1) {
|
||||
primary_key = new (primary_key_coll.model)({}, {
|
||||
top: self.model,
|
||||
collection: primary_key_coll,
|
||||
handler: primary_key_coll
|
||||
});
|
||||
primary_key_coll.add(primary_key);
|
||||
} else {
|
||||
primary_key = primary_key_coll.first();
|
||||
}
|
||||
// Do not alter existing primary key columns.
|
||||
if (_.isUndefined(primary_key.get('oid'))) {
|
||||
var primary_key_column_coll = primary_key.get('columns'),
|
||||
primary_key_column_exist = primary_key_column_coll.where({column:column_name});
|
||||
|
||||
if (primary_key_column_exist.length == 0) {
|
||||
var primary_key_column = new (primary_key_column_coll.model)(
|
||||
{column: column_name}, { silent: true,
|
||||
top: self.model,
|
||||
collection: primary_key_coll,
|
||||
handler: primary_key_coll
|
||||
});
|
||||
primary_key_coll.add(primary_key);
|
||||
} else {
|
||||
primary_key = primary_key_coll.first();
|
||||
}
|
||||
// Do not alter existing primary key columns.
|
||||
if (_.isUndefined(primary_key.get('oid'))) {
|
||||
var primary_key_column_coll = primary_key.get('columns'),
|
||||
primary_key_column_exist = primary_key_column_coll.where({column:column_name});
|
||||
|
||||
if (primary_key_column_exist.length == 0) {
|
||||
var primary_key_column = new (primary_key_column_coll.model)(
|
||||
{column: column_name}, { silent: true,
|
||||
top: self.model,
|
||||
collection: primary_key_coll,
|
||||
handler: primary_key_coll
|
||||
});
|
||||
primary_key_column_coll.add(primary_key_column);
|
||||
}
|
||||
|
||||
primary_key_column_coll.add(primary_key_column);
|
||||
}
|
||||
primary_key_column_coll.trigger('pgadmin:multicolumn:updated', primary_key_column_coll);
|
||||
}
|
||||
|
||||
primary_key_column_coll.trigger('pgadmin:multicolumn:updated', primary_key_column_coll);
|
||||
}
|
||||
} else {
|
||||
// remove column from primary key.
|
||||
if (primary_key_coll.length > 0) {
|
||||
var primary_key = primary_key_coll.first();
|
||||
// Do not alter existing primary key columns.
|
||||
if (!_.isUndefined(primary_key.get('oid'))) {
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
// remove column from primary key.
|
||||
if (primary_key_coll.length > 0) {
|
||||
var primary_key = primary_key_coll.first();
|
||||
// Do not alter existing primary key columns.
|
||||
if (!_.isUndefined(primary_key.get('oid'))) {
|
||||
return;
|
||||
}
|
||||
|
||||
var primary_key_column_coll = primary_key.get('columns'),
|
||||
removedCols = primary_key_column_coll.where({column:column_name});
|
||||
if (removedCols.length > 0) {
|
||||
primary_key_column_coll.remove(removedCols);
|
||||
_.each(removedCols, function(m) {
|
||||
m.destroy();
|
||||
})
|
||||
if (primary_key_column_coll.length == 0) {
|
||||
setTimeout(function () {
|
||||
// There will be only on primary key so remove the first one.
|
||||
primary_key_coll.remove(primary_key_coll.first());
|
||||
/* Ideally above line of code should be "primary_key_coll.reset()".
|
||||
* But our custom DataCollection (extended from Backbone collection in datamodel.js)
|
||||
* does not respond to reset event, it only supports add, remove, change events.
|
||||
* And hence no custom event listeners/validators get called for reset event.
|
||||
*/
|
||||
}, 10);
|
||||
}
|
||||
}
|
||||
primary_key_column_coll.trigger('pgadmin:multicolumn:updated', primary_key_column_coll);
|
||||
var primary_key_column_coll = primary_key.get('columns'),
|
||||
removedCols = primary_key_column_coll.where({column:column_name});
|
||||
if (removedCols.length > 0) {
|
||||
primary_key_column_coll.remove(removedCols);
|
||||
_.each(removedCols, function(m) {
|
||||
m.destroy();
|
||||
})
|
||||
if (primary_key_column_coll.length == 0) {
|
||||
setTimeout(function () {
|
||||
// There will be only on primary key so remove the first one.
|
||||
primary_key_coll.remove(primary_key_coll.first());
|
||||
/* Ideally above line of code should be "primary_key_coll.reset()".
|
||||
* But our custom DataCollection (extended from Backbone collection in datamodel.js)
|
||||
* does not respond to reset event, it only supports add, remove, change events.
|
||||
* And hence no custom event listeners/validators get called for reset event.
|
||||
*/
|
||||
}, 10);
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
remove: function() {
|
||||
var collection = this.model.get(this.field.get('name'));
|
||||
if (collection) {
|
||||
collection.off("change:is_primary_key");
|
||||
primary_key_column_coll.trigger('pgadmin:multicolumn:updated', primary_key_column_coll);
|
||||
}
|
||||
|
||||
Backform.UniqueColCollectionControl.prototype.remove.apply(this, arguments);
|
||||
}
|
||||
}),
|
||||
allowMultipleEmptyRow: false
|
||||
}]
|
||||
},{
|
||||
type: 'nested', control: 'fieldset',
|
||||
schema:[{
|
||||
// Here we will create tab control for constraints
|
||||
type: 'nested', control: 'tab', group: '{{ _('Constraints') }}',
|
||||
mode: ['edit', 'create'],
|
||||
schema: [{
|
||||
id: 'primary_key', label: '{{ _('Primary Key') }}',
|
||||
model: pgBrowser.Nodes['primary_key'].model,
|
||||
subnode: pgBrowser.Nodes['primary_key'].model,
|
||||
editable: false, type: 'collection',
|
||||
group: '{{ _('Primary Key') }}', mode: ['edit', 'create'],
|
||||
canEdit: true, canDelete: true,
|
||||
control: 'unique-col-collection',
|
||||
columns : ['name', 'columns'],
|
||||
canAdd: true,
|
||||
canAddRow: function(m) {
|
||||
// User can only add one primary key
|
||||
var columns = m.get('columns');
|
||||
})
|
||||
},
|
||||
remove: function() {
|
||||
var collection = this.model.get(this.field.get('name'));
|
||||
if (collection) {
|
||||
collection.off("change:is_primary_key");
|
||||
}
|
||||
|
||||
return (m.get('primary_key') &&
|
||||
m.get('primary_key').length < 1 &&
|
||||
_.some(columns.pluck('name')));
|
||||
}
|
||||
},{
|
||||
id: 'foreign_key', label: '{{ _('Foreign Key') }}',
|
||||
model: pgBrowser.Nodes['foreign_key'].model,
|
||||
subnode: pgBrowser.Nodes['foreign_key'].model,
|
||||
editable: false, type: 'collection',
|
||||
group: '{{ _('Foreign Key') }}', mode: ['edit', 'create'],
|
||||
canEdit: true, canDelete: true,
|
||||
control: 'unique-col-collection',
|
||||
canAdd: true,
|
||||
columns : ['name', 'columns'],
|
||||
canAddRow: function(m) {
|
||||
// User can only add if there is at least one column with name.
|
||||
var columns = m.get('columns');
|
||||
return _.some(columns.pluck('name'));
|
||||
}
|
||||
},{
|
||||
id: 'check_constraint', label: '{{ _('Check Constraint') }}',
|
||||
model: pgBrowser.Nodes['check_constraints'].model,
|
||||
subnode: pgBrowser.Nodes['check_constraints'].model,
|
||||
editable: false, type: 'collection',
|
||||
group: '{{ _('Check') }}', mode: ['edit', 'create'],
|
||||
canEdit: true, canDelete: true,
|
||||
control: 'unique-col-collection',
|
||||
canAdd: true,
|
||||
columns : ['name', 'consrc']
|
||||
},{
|
||||
id: 'unique_constraint', label: '{{ _('Unique Constraint') }}',
|
||||
model: pgBrowser.Nodes['unique_constraint'].model,
|
||||
subnode: pgBrowser.Nodes['unique_constraint'].model,
|
||||
editable: false, type: 'collection',
|
||||
group: '{{ _('Unique') }}', mode: ['edit', 'create'],
|
||||
canEdit: true, canDelete: true,
|
||||
control: 'unique-col-collection',
|
||||
columns : ['name', 'columns'],
|
||||
canAdd: true,
|
||||
canAddRow: function(m) {
|
||||
// User can only add if there is at least one column with name.
|
||||
var columns = m.get('columns');
|
||||
return _.some(columns.pluck('name'));
|
||||
}
|
||||
},{
|
||||
id: 'exclude_constraint', label: '{{ _('Exclude Constraint') }}',
|
||||
model: pgBrowser.Nodes['exclusion_constraint'].model,
|
||||
subnode: pgBrowser.Nodes['exclusion_constraint'].model,
|
||||
editable: false, type: 'collection',
|
||||
group: '{{ _('Exclude') }}', mode: ['edit', 'create'],
|
||||
canEdit: true, canDelete: true,
|
||||
control: 'unique-col-collection',
|
||||
columns : ['name', 'columns', 'constraint'],
|
||||
canAdd: true,
|
||||
canAddRow: function(m) {
|
||||
// User can only add if there is at least one column with name.
|
||||
var columns = m.get('columns');
|
||||
return _.some(columns.pluck('name'));
|
||||
}
|
||||
}]
|
||||
}]
|
||||
Backform.UniqueColCollectionControl.prototype.remove.apply(this, arguments);
|
||||
}
|
||||
}),
|
||||
allowMultipleEmptyRow: false
|
||||
},{
|
||||
// Here we will create tab control for constraints
|
||||
type: 'nested', control: 'tab', group: '{{ _('Constraints') }}',
|
||||
mode: ['edit', 'create'],
|
||||
schema: [{
|
||||
id: 'primary_key', label: '{{ _('Primary key') }}',
|
||||
model: pgBrowser.Nodes['primary_key'].model,
|
||||
subnode: pgBrowser.Nodes['primary_key'].model,
|
||||
editable: false, type: 'collection',
|
||||
group: '{{ _('Primary Key') }}', mode: ['edit', 'create'],
|
||||
canEdit: true, canDelete: true,
|
||||
control: 'unique-col-collection',
|
||||
columns : ['name', 'columns'],
|
||||
canAdd: true,
|
||||
canAddRow: function(m) {
|
||||
// User can only add one primary key
|
||||
var columns = m.get('columns');
|
||||
|
||||
return (m.get('primary_key') &&
|
||||
m.get('primary_key').length < 1 &&
|
||||
_.some(columns.pluck('name')));
|
||||
}
|
||||
},{
|
||||
id: 'foreign_key', label: '{{ _('Foreign key') }}',
|
||||
model: pgBrowser.Nodes['foreign_key'].model,
|
||||
subnode: pgBrowser.Nodes['foreign_key'].model,
|
||||
editable: false, type: 'collection',
|
||||
group: '{{ _('Foreign Key') }}', mode: ['edit', 'create'],
|
||||
canEdit: true, canDelete: true,
|
||||
control: 'unique-col-collection',
|
||||
canAdd: true,
|
||||
columns : ['name', 'columns'],
|
||||
canAddRow: function(m) {
|
||||
// User can only add if there is at least one column with name.
|
||||
var columns = m.get('columns');
|
||||
return _.some(columns.pluck('name'));
|
||||
}
|
||||
},{
|
||||
id: 'check_constraint', label: '{{ _('Check constraint') }}',
|
||||
model: pgBrowser.Nodes['check_constraints'].model,
|
||||
subnode: pgBrowser.Nodes['check_constraints'].model,
|
||||
editable: false, type: 'collection',
|
||||
group: '{{ _('Check') }}', mode: ['edit', 'create'],
|
||||
canEdit: true, canDelete: true,
|
||||
control: 'unique-col-collection',
|
||||
canAdd: true,
|
||||
columns : ['name', 'consrc']
|
||||
},{
|
||||
id: 'unique_constraint', label: '{{ _('Unique constraint') }}',
|
||||
model: pgBrowser.Nodes['unique_constraint'].model,
|
||||
subnode: pgBrowser.Nodes['unique_constraint'].model,
|
||||
editable: false, type: 'collection',
|
||||
group: '{{ _('Unique') }}', mode: ['edit', 'create'],
|
||||
canEdit: true, canDelete: true,
|
||||
control: 'unique-col-collection',
|
||||
columns : ['name', 'columns'],
|
||||
canAdd: true,
|
||||
canAddRow: function(m) {
|
||||
// User can only add if there is at least one column with name.
|
||||
var columns = m.get('columns');
|
||||
return _.some(columns.pluck('name'));
|
||||
}
|
||||
},{
|
||||
id: 'exclude_constraint', label: '{{ _('Exclude constraint') }}',
|
||||
model: pgBrowser.Nodes['exclusion_constraint'].model,
|
||||
subnode: pgBrowser.Nodes['exclusion_constraint'].model,
|
||||
editable: false, type: 'collection',
|
||||
group: '{{ _('Exclude') }}', mode: ['edit', 'create'],
|
||||
canEdit: true, canDelete: true,
|
||||
control: 'unique-col-collection',
|
||||
columns : ['name', 'columns', 'constraint'],
|
||||
canAdd: true,
|
||||
canAddRow: function(m) {
|
||||
// User can only add if there is at least one column with name.
|
||||
var columns = m.get('columns');
|
||||
return _.some(columns.pluck('name'));
|
||||
}
|
||||
}]
|
||||
},{
|
||||
type: 'nested', control: 'fieldset', label: '{{ _('Like') }}',
|
||||
group: '{{ _('Advanced') }}',
|
||||
@ -686,23 +713,23 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
|
||||
control: 'node-ajax-options', url: 'get_relations',
|
||||
disabled: 'inSchemaWithModelCheck', group: '{{ _('Like') }}'
|
||||
},{
|
||||
id: 'like_default_value', label:'{{ _('With Default values?') }}', cell: 'switch',
|
||||
id: 'like_default_value', label:'{{ _('With default values?') }}', cell: 'switch',
|
||||
type: 'switch', mode: ['create', 'edit'],
|
||||
disabled: 'inSchemaWithModelCheck', group: '{{ _('Like') }}'
|
||||
},{
|
||||
id: 'like_constraints', label:'{{ _('With Constraints?') }}', cell: 'switch',
|
||||
id: 'like_constraints', label:'{{ _('With constraints?') }}', cell: 'switch',
|
||||
type: 'switch', mode: ['create', 'edit'],
|
||||
disabled: 'inSchemaWithModelCheck', group: '{{ _('Like') }}'
|
||||
},{
|
||||
id: 'like_indexes', label:'{{ _('With Indexes?') }}', cell: 'switch',
|
||||
id: 'like_indexes', label:'{{ _('With indexes?') }}', cell: 'switch',
|
||||
type: 'switch', mode: ['create', 'edit'],
|
||||
disabled: 'inSchemaWithModelCheck', group: '{{ _('Like') }}'
|
||||
},{
|
||||
id: 'like_storage', label:'{{ _('With Storage?') }}', cell: 'switch',
|
||||
id: 'like_storage', label:'{{ _('With storage?') }}', cell: 'switch',
|
||||
type: 'switch', mode: ['create', 'edit'],
|
||||
disabled: 'inSchemaWithModelCheck', group: '{{ _('Like') }}'
|
||||
},{
|
||||
id: 'like_comments', label:'{{ _('With Comments?') }}', cell: 'switch',
|
||||
id: 'like_comments', label:'{{ _('With comments?') }}', cell: 'switch',
|
||||
type: 'switch', mode: ['create', 'edit'],
|
||||
disabled: 'inSchemaWithModelCheck', group: '{{ _('Like') }}'
|
||||
}]
|
||||
@ -723,17 +750,17 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
|
||||
mode: ['edit', 'create'], canAdd: true, canDelete: true,
|
||||
uniqueCol : ['grantee']
|
||||
},{
|
||||
id: 'seclabels', label: '{{ _('Security Labels') }}',
|
||||
id: 'seclabels', label: '{{ _('Security labels') }}',
|
||||
model: pgAdmin.Browser.SecurityModel, editable: false, type: 'collection',
|
||||
group: '{{ _('Security') }}', mode: ['edit', 'create'],
|
||||
min_version: 90100, canAdd: true,
|
||||
canEdit: false, canDelete: true, control: 'unique-col-collection'
|
||||
},{
|
||||
id: 'vacuum_settings_str', label: '{{ _('Storage Settings') }}',
|
||||
id: 'vacuum_settings_str', label: '{{ _('Storage settings') }}',
|
||||
type: 'multiline', group: '{{ _('Advanced') }}', mode: ['properties']
|
||||
}
|
||||
],
|
||||
validate: function() {
|
||||
validate: function(keys) {
|
||||
var err = {},
|
||||
changedAttrs = this.changed,
|
||||
msg = undefined,
|
||||
@ -743,6 +770,14 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
|
||||
|
||||
this.errorModel.clear();
|
||||
|
||||
// If nothing to validate or VacuumSetting keys then
|
||||
// return from here
|
||||
if ( keys && (keys.length == 0
|
||||
|| _.indexOf(keys, 'autovacuum_enabled') != -1
|
||||
|| _.indexOf(keys, 'toast_autovacuum_enabled') != -1) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (_.isUndefined(name) || _.isNull(name) ||
|
||||
String(name).replace(/^\s+|\s+$/g, '') == '') {
|
||||
msg = '{{ _('Table name can not be empty.') }}';
|
||||
|
@ -113,7 +113,7 @@ class TriggerModule(CollectionNodeModule):
|
||||
"""
|
||||
Load the module node as a leaf node
|
||||
"""
|
||||
return True
|
||||
return False
|
||||
|
||||
@property
|
||||
def csssnippets(self):
|
||||
|
@ -3,6 +3,26 @@ define(
|
||||
'backform', 'alertify', 'pgadmin.browser.collection'],
|
||||
function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
|
||||
|
||||
var CustomSwitchControl = Backform.CustomSwitchControl = Backform.SwitchControl.extend({
|
||||
template: _.template([
|
||||
'<label class="<%=Backform.controlLabelClassName%> custom_switch_label_class"><%=label%></label>',
|
||||
'<div class="<%=Backform.controlsClassName%> custom_switch_control_class">',
|
||||
' <div class="checkbox">',
|
||||
' <label>',
|
||||
' <input type="checkbox" class="<%=extraClasses.join(\' \')%>"',
|
||||
' name="<%=name%>" <%=value ? "checked=\'checked\'" : ""%>',
|
||||
' <%=disabled ? "disabled" : ""%> <%=required ? "required" : ""%> />',
|
||||
' </label>',
|
||||
' </div>',
|
||||
'</div>',
|
||||
'<% if (helpMessage && helpMessage.length) { %>',
|
||||
' <span class="<%=Backform.helpMessageClassName%>"><%=helpMessage%></span>',
|
||||
'<% } %>'
|
||||
].join("\n")),
|
||||
className: 'pgadmin-control-group form-group col-xs-6'
|
||||
});
|
||||
|
||||
if (!pgBrowser.Nodes['coll-trigger']) {
|
||||
var triggers = pgAdmin.Browser.Nodes['coll-trigger'] =
|
||||
pgAdmin.Browser.Collection.extend({
|
||||
@ -162,7 +182,8 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
defaults: {
|
||||
name: undefined,
|
||||
is_row_trigger: true
|
||||
is_row_trigger: true,
|
||||
fires: 'BEFORE'
|
||||
},
|
||||
schema: [{
|
||||
id: 'name', label: '{{ _('Name') }}', cell: 'string',
|
||||
@ -172,14 +193,15 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
type: 'int', disabled: true, mode: ['properties']
|
||||
},{
|
||||
id: 'is_enable_trigger', label:'{{ _('Enable trigger?') }}',
|
||||
type: 'switch', disabled: 'inSchema', mode: ['properties']
|
||||
type: 'switch', disabled: 'inSchema', mode: ['properties'],
|
||||
group: '{{ _('Definition') }}'
|
||||
},{
|
||||
id: 'is_row_trigger', label:'{{ _('Row trigger') }}',
|
||||
id: 'is_row_trigger', label:'{{ _('Row trigger?') }}',
|
||||
type: 'switch', group: '{{ _('Definition') }}',
|
||||
mode: ['create','edit', 'properties'],
|
||||
deps: ['is_constraint_trigger'],
|
||||
disabled: function(m) {
|
||||
// If contraint trigger is set to True then row trigger will
|
||||
// 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])) {
|
||||
@ -192,54 +214,61 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Disbale it
|
||||
// Disable it
|
||||
return true;
|
||||
}
|
||||
}
|
||||
},{
|
||||
id: 'is_constraint_trigger', label:'{{ _('Constraint trigger') }}',
|
||||
id: 'is_constraint_trigger', label:'{{ _('Constraint trigger?') }}',
|
||||
type: 'switch', disabled: 'inSchemaWithModelCheck',
|
||||
mode: ['create','edit', 'properties'],
|
||||
group: '{{ _('Definition') }}'
|
||||
},{
|
||||
id: 'tgdeferrable', label:'{{ _('Deferrable') }}',
|
||||
id: 'tgdeferrable', label:'{{ _('Deferrable?') }}',
|
||||
type: 'switch', group: '{{ _('Definition') }}',
|
||||
mode: ['create','edit', 'properties'],
|
||||
deps: ['is_constraint_trigger'],
|
||||
disabled: function(m) {
|
||||
// If contraint trigger is set to True then only enable it
|
||||
// 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 {
|
||||
setTimeout(function() { m.set('tgdeferrable', false) }, 10);
|
||||
// If value is already set then reset it to false
|
||||
if(m.get('tgdeferrable')) {
|
||||
setTimeout(function() { m.set('tgdeferrable', false) }, 10);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// Disbale it
|
||||
// Disable it
|
||||
return true;
|
||||
}
|
||||
}
|
||||
},{
|
||||
id: 'tginitdeferred', label:'{{ _('Deferred') }}',
|
||||
id: 'tginitdeferred', label:'{{ _('Deferred?') }}',
|
||||
type: 'switch', group: '{{ _('Definition') }}',
|
||||
mode: ['create','edit', 'properties'],
|
||||
deps: ['tgdeferrable'],
|
||||
deps: ['tgdeferrable', 'is_constraint_trigger'],
|
||||
disabled: function(m) {
|
||||
// If contraint trigger is set to True then only enable it
|
||||
var is_constraint_trigger = m.get('tgdeferrable');
|
||||
// If Deferrable is set to True then only enable it
|
||||
var tgdeferrable = m.get('tgdeferrable');
|
||||
if(!m.inSchemaWithModelCheck.apply(this, [m])) {
|
||||
if(!_.isUndefined(is_constraint_trigger) &&
|
||||
is_constraint_trigger === true) {
|
||||
if(!_.isUndefined(tgdeferrable) &&
|
||||
tgdeferrable) {
|
||||
return false;
|
||||
} else {
|
||||
setTimeout(function() { m.set('tginitdeferred', false) }, 10);
|
||||
return true;
|
||||
// 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 {
|
||||
// Disbale it
|
||||
// Disable it
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -261,20 +290,20 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
if(server_type === 'ppas' &&
|
||||
!_.isUndefined(tfunction) &&
|
||||
tfunction === 'Inline EDB-SPL') {
|
||||
// Disbale and clear its value
|
||||
// Disable and clear its value
|
||||
m.set('tgargs', undefined)
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Disbale it
|
||||
// Disable it
|
||||
return true;
|
||||
}
|
||||
}
|
||||
},{
|
||||
id: 'fires', label:'{{ _('Fires') }}', deps: ['is_constraint_trigger'],
|
||||
mode: ['create','edit', 'properties'], group: '{{ _('Definition') }}',
|
||||
mode: ['create','edit', 'properties'], group: '{{ _('Events') }}',
|
||||
options: function(control) {
|
||||
var table_options = [
|
||||
{label: "BEFORE", value: "BEFORE"},
|
||||
@ -291,18 +320,7 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
}
|
||||
},
|
||||
// If create mode then by default open composite type
|
||||
control: Backform.Select2Control.extend({
|
||||
render: function(){
|
||||
// Initialize parent's render method
|
||||
Backform.Select2Control.prototype.render.apply(this, arguments);
|
||||
if(this.model.isNew() &&
|
||||
this.model.get('is_constraint_trigger') !== true ) {
|
||||
this.model.set({'fires': 'BEFORE'}, {silent: true});
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}),
|
||||
select2: { allowClear: false, width: "100%" },
|
||||
control: 'select2', select2: { allowClear: false, width: "100%" },
|
||||
disabled: function(m) {
|
||||
// If contraint trigger is set to True then only enable it
|
||||
var is_constraint_trigger = m.get('is_constraint_trigger');
|
||||
@ -315,17 +333,18 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Disbale it
|
||||
// Disable it
|
||||
return true;
|
||||
}
|
||||
}
|
||||
},{
|
||||
type: 'nested', control: 'fieldset', mode: ['create','edit', 'properties'],
|
||||
label: '{{ _('Events') }}', group: '{{ _('Definition') }}',
|
||||
label: '{{ _('Events') }}', group: '{{ _('Events') }}',
|
||||
schema:[{
|
||||
id: 'evnt_insert', label:'{{ _('INSERT') }}',
|
||||
type: 'switch', mode: ['create','edit', 'properties'],
|
||||
group: '{{ _('Events') }}',
|
||||
control: Backform.CustomSwitchControl,
|
||||
disabled: function(m) {
|
||||
return m.inSchemaWithModelCheck.apply(this, [m]);
|
||||
}
|
||||
@ -333,6 +352,7 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
id: 'evnt_update', label:'{{ _('UPDATE') }}',
|
||||
type: 'switch', mode: ['create','edit', 'properties'],
|
||||
group: '{{ _('Events') }}',
|
||||
control: Backform.CustomSwitchControl,
|
||||
disabled: function(m) {
|
||||
return m.inSchemaWithModelCheck.apply(this, [m]);
|
||||
}
|
||||
@ -340,12 +360,14 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
id: 'evnt_delete', label:'{{ _('DELETE') }}',
|
||||
type: 'switch', mode: ['create','edit', 'properties'],
|
||||
group: '{{ _('Events') }}',
|
||||
control: Backform.CustomSwitchControl,
|
||||
disabled: function(m) {
|
||||
return m.inSchemaWithModelCheck.apply(this, [m]);
|
||||
}
|
||||
},{
|
||||
id: 'evnt_turncate', label:'{{ _('TRUNCATE') }}',
|
||||
type: 'switch', group: '{{ _('Events') }}',
|
||||
control: Backform.CustomSwitchControl,
|
||||
disabled: function(m) {
|
||||
var is_constraint_trigger = m.get('is_constraint_trigger'),
|
||||
is_row_trigger = m.get('is_row_trigger'),
|
||||
@ -363,7 +385,7 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// Disbale it
|
||||
// Disable it
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -372,11 +394,11 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
id: 'whenclause', label:'{{ _('When') }}',
|
||||
type: 'text', disabled: 'inSchemaWithModelCheck',
|
||||
mode: ['create', 'edit', 'properties'],
|
||||
control: 'sql-field', visible: true, group: '{{ _('Definition') }}'
|
||||
control: 'sql-field', visible: true, group: '{{ _('Events') }}'
|
||||
},{
|
||||
id: 'columns', label: '{{ _('Columns') }}', url: 'nodes',
|
||||
type: 'collection', control: 'multi-select-ajax',
|
||||
deps: ['evnt_update'], node: 'column', group: '{{ _('Definition') }}',
|
||||
deps: ['evnt_update'], node: 'column', group: '{{ _('Events') }}',
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
keys: ['column'], defaults: { column: undefined }
|
||||
}),
|
||||
@ -384,7 +406,7 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
if(this.node_info && 'catalog' in this.node_info) {
|
||||
return true;
|
||||
}
|
||||
//Disbale in edit mode
|
||||
//Disable in edit mode
|
||||
if (!m.isNew()) {
|
||||
return true;
|
||||
}
|
||||
@ -414,7 +436,7 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// Disbale it
|
||||
// Disable it
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -423,17 +445,23 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
type: 'switch', disabled: 'inSchemaWithModelCheck', mode: ['properties']
|
||||
},{
|
||||
id: 'is_constarint', label:'{{ _('Constraint?') }}', cell: 'string',
|
||||
type: 'switch', disabled: 'inSchemaWithModelCheck', mode: ['properties']
|
||||
type: 'switch', disabled: 'inSchemaWithModelCheck', mode: ['properties'],
|
||||
group: '{{ _('Definition') }}'
|
||||
},{
|
||||
id: 'description', label:'{{ _('Comment') }}', cell: 'string',
|
||||
type: 'multiline', mode: ['properties', 'create', 'edit'],
|
||||
disabled: 'inSchema'
|
||||
}],
|
||||
validate: function() {
|
||||
validate: function(keys) {
|
||||
var err = {},
|
||||
msg = undefined;
|
||||
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 = '{{ _('Name can not be empty.') }}';
|
||||
|
@ -552,7 +552,8 @@ class TypeView(PGChildNodeView, DataTypeReader):
|
||||
res.append(
|
||||
{'label': row['typname'], 'value': row['typname'],
|
||||
'typval': typeval, 'precision': precision,
|
||||
'length': length, 'min_val': min_val, 'max_val': max_val
|
||||
'length': length, 'min_val': min_val, 'max_val': max_val,
|
||||
'is_collatable': row['is_collatable']
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -14,6 +14,55 @@ function($, _, S, pgAdmin, pgBrowser, alertify, Backgrid) {
|
||||
});
|
||||
};
|
||||
|
||||
// Integer Cell for Columns Length and Precision
|
||||
var IntegerDepCell = Backgrid.IntegerCell.extend({
|
||||
initialize: function() {
|
||||
Backgrid.NumberCell.prototype.initialize.apply(this, arguments);
|
||||
Backgrid.Extension.DependentCell.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
dependentChanged: function () {
|
||||
this.$el.empty();
|
||||
var model = this.model;
|
||||
var column = this.column;
|
||||
editable = this.column.get("editable");
|
||||
|
||||
is_editable = _.isFunction(editable) ? !!editable.apply(column, [model]) : !!editable;
|
||||
if (is_editable){ this.$el.addClass("editable"); }
|
||||
else { this.$el.removeClass("editable"); }
|
||||
|
||||
this.delegateEvents();
|
||||
return this;
|
||||
},
|
||||
remove: Backgrid.Extension.DependentCell.prototype.remove
|
||||
});
|
||||
|
||||
// Node-Ajax-Cell with Deps
|
||||
var NodeAjaxOptionsDepsCell = Backgrid.Extension.NodeAjaxOptionsCell.extend({
|
||||
initialize: function() {
|
||||
Backgrid.Extension.NodeAjaxOptionsCell.prototype.initialize.apply(this, arguments);
|
||||
Backgrid.Extension.DependentCell.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
dependentChanged: function () {
|
||||
var model = this.model,
|
||||
column = this.column,
|
||||
editable = this.column.get("editable"),
|
||||
input = this.$el.find('select').first();
|
||||
|
||||
is_editable = _.isFunction(editable) ? !!editable.apply(column, [model]) : !!editable;
|
||||
if (is_editable) {
|
||||
this.$el.addClass("editable");
|
||||
input.prop('disabled', false);
|
||||
} else {
|
||||
this.$el.removeClass("editable");
|
||||
input.prop('disabled', true);
|
||||
}
|
||||
|
||||
this.delegateEvents();
|
||||
return this;
|
||||
},
|
||||
remove: Backgrid.Extension.DependentCell.prototype.remove
|
||||
});
|
||||
|
||||
// Security label model declaration
|
||||
var SecurityModel = Backform.SecurityModel = pgAdmin.Browser.Node.Model.extend({
|
||||
defaults: {
|
||||
@ -64,13 +113,14 @@ function($, _, S, pgAdmin, pgBrowser, alertify, Backgrid) {
|
||||
subtypes: undefined,
|
||||
schema: [{
|
||||
id: 'member_name', label: '{{ _('Member Name') }}',
|
||||
type: 'text', disabled: false, editable: false
|
||||
type: 'text', disabled: false, editable: true
|
||||
},{
|
||||
id: 'type', label: '{{ _('Type') }}', control: 'node-ajax-options',
|
||||
type: 'text', url: 'get_types', disabled: false, node: 'type',
|
||||
editable: false,
|
||||
transform: function(d){
|
||||
this.model.type_options = d;
|
||||
cell: 'node-ajax-options',
|
||||
editable: true,
|
||||
transform: function(d, control){
|
||||
control.model.type_options = d;
|
||||
return d;
|
||||
}
|
||||
},{
|
||||
@ -78,8 +128,8 @@ function($, _, S, pgAdmin, pgBrowser, alertify, Backgrid) {
|
||||
// precision and scale. In the UI, we try to follow the docs as
|
||||
// closely as possible, therefore we use Length/Precision and Scale
|
||||
id: 'tlength', label: '{{ _('Length/precision') }}', deps: ['type'], type: 'text',
|
||||
editable: false,
|
||||
disabled: function(m) {
|
||||
disabled: false, cell: IntegerDepCell,
|
||||
editable: function(m) {
|
||||
// We will store type from selected from combobox
|
||||
var of_type = m.get('type');
|
||||
if(m.type_options) {
|
||||
@ -98,15 +148,15 @@ function($, _, S, pgAdmin, pgBrowser, alertify, Backgrid) {
|
||||
}
|
||||
});
|
||||
}
|
||||
return !m.get('is_tlength');
|
||||
return m.get('is_tlength');
|
||||
}
|
||||
},{
|
||||
// Note: There are ambiguities in the PG catalogs and docs between
|
||||
// precision and scale. In the UI, we try to follow the docs as
|
||||
// closely as possible, therefore we use Length/Precision and Scale
|
||||
id: 'precision', label: '{{ _('Scale') }}', deps: ['type'],
|
||||
type: 'text', editable: false,
|
||||
disabled: function(m) {
|
||||
type: 'text', disabled: false, cell: IntegerDepCell,
|
||||
editable: function(m) {
|
||||
// We will store type from selected from combobox
|
||||
var of_type = m.get('type');
|
||||
if(m.type_options) {
|
||||
@ -125,11 +175,32 @@ function($, _, S, pgAdmin, pgBrowser, alertify, Backgrid) {
|
||||
}
|
||||
});
|
||||
}
|
||||
return !m.get('is_precision');
|
||||
return m.get('is_precision');
|
||||
}
|
||||
},{
|
||||
id: 'collation', label: '{{ _('Collation') }}',
|
||||
control: 'node-ajax-options', editable: false,
|
||||
cell: NodeAjaxOptionsDepsCell, deps: ['type'],
|
||||
control: 'node-ajax-options', editable: function(m) {
|
||||
var of_type = m.get('type'),
|
||||
flag = false;
|
||||
if(m.type_options) {
|
||||
_.each(m.type_options, function(o) {
|
||||
if ( of_type == o.value ) {
|
||||
if(o.is_collatable)
|
||||
{
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
setTimeout(function(){
|
||||
m.set('collspcname', "");
|
||||
}, 10);
|
||||
}
|
||||
return flag;
|
||||
},
|
||||
type: 'text', disabled: false, url: 'get_collations', node: 'type'
|
||||
}],
|
||||
validate: function() {
|
||||
@ -323,7 +394,7 @@ function($, _, S, pgAdmin, pgBrowser, alertify, Backgrid) {
|
||||
model: CompositeModel, editable: true, type: 'collection',
|
||||
group: '{{ _('Definition') }}', mode: ['edit', 'create'],
|
||||
control: 'unique-col-collection', uniqueCol : ['member_name'],
|
||||
canAdd: true, canEdit: true, canDelete: true, disabled: 'inSchema',
|
||||
canAdd: true, canEdit: false, canDelete: true, disabled: 'inSchema',
|
||||
deps: ['typtype'], deps: ['typtype'],
|
||||
visible: function(m) {
|
||||
return m.get('typtype') === 'c';
|
||||
@ -358,8 +429,8 @@ function($, _, S, pgAdmin, pgBrowser, alertify, Backgrid) {
|
||||
select2: { allowClear: true, placeholder: "", width: "100%" },
|
||||
url: 'get_stypes', type: 'text', mode: ['properties', 'create', 'edit'],
|
||||
group: '{{ _('Range Type') }}', disabled: 'inSchemaWithModelCheck',
|
||||
transform: function(d){
|
||||
this.model.subtypes = d;
|
||||
transform: function(d, self){
|
||||
self.model.subtypes = d;
|
||||
return d;
|
||||
}
|
||||
},{
|
||||
|
@ -2,7 +2,8 @@ SELECT * FROM
|
||||
(SELECT format_type(t.oid,NULL) AS typname,
|
||||
CASE WHEN typelem > 0 THEN typelem ELSE t.oid END AS elemoid,
|
||||
typlen, typtype, t.oid, nspname,
|
||||
(SELECT COUNT(1) FROM pg_type t2 WHERE t2.typname = t.typname) > 1 AS isdup
|
||||
(SELECT COUNT(1) FROM pg_type t2 WHERE t2.typname = t.typname) > 1 AS isdup,
|
||||
CASE WHEN t.typcollation != 0 THEN TRUE ELSE FALSE END AS is_collatable
|
||||
FROM pg_type t
|
||||
JOIN pg_namespace nsp ON typnamespace=nsp.oid
|
||||
WHERE (NOT (typname = 'unknown' AND nspname = 'pg_catalog')) AND typisdefined AND typtype IN ('b', 'c', 'd', 'e', 'r') AND NOT EXISTS (select 1 from pg_class where relnamespace=typnamespace and relname = typname and relkind != 'c') AND (typname not like '_%' OR NOT EXISTS (select 1 from pg_class where relnamespace=typnamespace and relname = substring(typname from 2)::name and relkind != 'c')) AND nsp.nspname != 'information_schema'
|
||||
|
@ -148,24 +148,6 @@ function($, _, S, pgAdmin, alertify, pgBrowser, CodeMirror) {
|
||||
type: 'text', mode: ['create', 'edit'], group: 'Definition',
|
||||
control: Backform.SqlFieldControl, extraClasses:['sql_field_width_full']
|
||||
},
|
||||
// Add Privilege Control
|
||||
{
|
||||
id: 'datacl', label: '{{ _("Privileges") }}',
|
||||
model: pgAdmin.Browser.Node.PrivilegeRoleModel.extend(
|
||||
{privileges: ['a', 'r', 'w', 'd', 'D', 'x', 't']}), uniqueCol : ['grantee'],
|
||||
editable: false, type: 'collection', group: '{{ _("Security") }}',
|
||||
mode: ['edit', 'create'], canAdd: true, canDelete: true,
|
||||
control: 'unique-col-collection', priority: 3
|
||||
},
|
||||
|
||||
// Add Security Labels Control
|
||||
{
|
||||
id: 'seclabels', label: '{{ _("Security Labels") }}',
|
||||
model: Backform.SecurityModel, editable: false, type: 'collection',
|
||||
canEdit: false, group: '{{ _("Security") }}', canDelete: true,
|
||||
mode: ['edit', 'create'], canAdd: true,
|
||||
control: 'unique-col-collection', uniqueCol : ['provider']
|
||||
},
|
||||
{
|
||||
id: 'with_data', label: '{{ _("With Data") }}',
|
||||
group: '{{ _("Storage") }}', mode: ['edit', 'create'],
|
||||
@ -187,10 +169,28 @@ function($, _, S, pgAdmin, alertify, pgBrowser, CodeMirror) {
|
||||
},
|
||||
{
|
||||
type: 'nested', control: 'tab', id: 'materialization',
|
||||
label: '{{ _("Materialization") }}', mode: ['edit', 'create'],
|
||||
group: '{{ _("Storage") }}',
|
||||
label: '{{ _("Auto vacuum") }}', mode: ['edit', 'create'],
|
||||
group: '{{ _("Auto vacuum") }}',
|
||||
schema: Backform.VacuumSettingsSchema
|
||||
},
|
||||
// Add Privilege Control
|
||||
{
|
||||
id: 'datacl', label: '{{ _("Privileges") }}',
|
||||
model: pgAdmin.Browser.Node.PrivilegeRoleModel.extend(
|
||||
{privileges: ['a', 'r', 'w', 'd', 'D', 'x', 't']}), uniqueCol : ['grantee'],
|
||||
editable: false, type: 'collection', group: '{{ _("Security") }}',
|
||||
mode: ['edit', 'create'], canAdd: true, canDelete: true,
|
||||
control: 'unique-col-collection', priority: 3
|
||||
},
|
||||
|
||||
// Add Security Labels Control
|
||||
{
|
||||
id: 'seclabels', label: '{{ _("Security Labels") }}',
|
||||
model: Backform.SecurityModel, editable: false, type: 'collection',
|
||||
canEdit: false, group: '{{ _("Security") }}', canDelete: true,
|
||||
mode: ['edit', 'create'], canAdd: true,
|
||||
control: 'unique-col-collection', uniqueCol : ['provider']
|
||||
}
|
||||
],
|
||||
validate: function(keys) {
|
||||
|
||||
|
@ -9,13 +9,15 @@ define([
|
||||
* Hmm... this module is already been initialized, we can refer to the old
|
||||
* object from here.
|
||||
*/
|
||||
if (pgAdmin.FileManager)
|
||||
return pgAdmin.FileManager;
|
||||
if (pgAdmin.FileManager) {
|
||||
return pgAdmin.FileManager;
|
||||
}
|
||||
|
||||
pgAdmin.FileManager = {
|
||||
init: function() {
|
||||
if (this.initialized)
|
||||
if (this.initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.initialized = true;
|
||||
|
||||
@ -35,7 +37,7 @@ define([
|
||||
};
|
||||
|
||||
// Function to remove trans id from session
|
||||
var removeTransId = function() {
|
||||
var removeTransId = function(trans_id) {
|
||||
return $.ajax({
|
||||
type: "GET",
|
||||
async: false,
|
||||
@ -68,26 +70,26 @@ define([
|
||||
});
|
||||
|
||||
transId = getTransId(params);
|
||||
if (transId.readyState == 4)
|
||||
var t_res;
|
||||
if (transId.readyState == 4) {
|
||||
t_res = JSON.parse(transId.responseText);
|
||||
}
|
||||
trans_id = t_res.data.fileTransId;
|
||||
|
||||
};
|
||||
|
||||
// Dialog property
|
||||
return {
|
||||
main: function(params) {
|
||||
// Set title and button name
|
||||
if (_.isUndefined(params['dialog_title']))
|
||||
if (_.isUndefined(params['dialog_title'])) {
|
||||
params['dialog_title'] = 'Storage manager';
|
||||
}
|
||||
this.set('title', params['dialog_title']);
|
||||
if (_.isUndefined(params['btn_primary']))
|
||||
if (_.isUndefined(params['btn_primary'])) {
|
||||
params['btn_primary'] = 'Select';
|
||||
}
|
||||
this.set('label', params['btn_primary']);
|
||||
|
||||
var trans_id;
|
||||
this.title = params.dialog_title;
|
||||
|
||||
params = JSON.stringify(params);
|
||||
$container.find('.storage_content').remove();
|
||||
$container.append("<div class='storage_content'></div>");
|
||||
@ -107,6 +109,8 @@ define([
|
||||
this.__internal.buttons[0].element.innerHTML = newValue;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
setup:function() {
|
||||
@ -127,9 +131,6 @@ define([
|
||||
};
|
||||
},
|
||||
callback: function(closeEvent) {
|
||||
if (closeEvent.button.key == 13) {
|
||||
//closeEvent.cancel = true;
|
||||
}
|
||||
if (closeEvent.button.text == "{{ _('Select') }}") {
|
||||
if($('.fileinfo').data('view') == 'grid') {
|
||||
sel_file = $('.fileinfo').find('#contents li.selected p span').attr('title');
|
||||
@ -178,8 +179,10 @@ define([
|
||||
});
|
||||
|
||||
transId = getTransId(configs);
|
||||
if (transId.readyState == 4)
|
||||
var t_res;
|
||||
if (transId.readyState == 4) {
|
||||
t_res = JSON.parse(transId.responseText);
|
||||
}
|
||||
trans_id = t_res.data.fileTransId;
|
||||
};
|
||||
|
||||
@ -187,16 +190,15 @@ define([
|
||||
return {
|
||||
main: function(params) {
|
||||
// Set title and button name
|
||||
if (_.isUndefined(params['dialog_title']))
|
||||
if (_.isUndefined(params['dialog_title'])) {
|
||||
params['dialog_title'] = 'Select file';
|
||||
}
|
||||
this.set('title', params['dialog_title']);
|
||||
if (_.isUndefined(params['btn_primary']))
|
||||
if (_.isUndefined(params['btn_primary'])) {
|
||||
params['btn_primary'] = 'Select';
|
||||
}
|
||||
this.set('label', params['btn_primary']);
|
||||
|
||||
var trans_id;
|
||||
this.title = params.dialog_title;
|
||||
|
||||
params = JSON.stringify(params);
|
||||
$container.find('.storage_content').remove();
|
||||
$container.append("<div class='storage_content'></div>");
|
||||
@ -216,6 +218,8 @@ define([
|
||||
this.__internal.buttons[0].element.innerHTML = newValue;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
setup:function() {
|
||||
@ -286,24 +290,26 @@ define([
|
||||
});
|
||||
|
||||
transId = getTransId(params);
|
||||
if (transId.readyState == 4)
|
||||
var t_res;
|
||||
if (transId.readyState == 4) {
|
||||
t_res = JSON.parse(transId.responseText);
|
||||
}
|
||||
trans_id = t_res.data.fileTransId;
|
||||
|
||||
};
|
||||
|
||||
// Dialog property
|
||||
return {
|
||||
main: function(params) {
|
||||
// Set title and button name
|
||||
if (_.isUndefined(params['dialog_title']))
|
||||
if (_.isUndefined(params['dialog_title'])) {
|
||||
params['dialog_title'] = 'Select folder';
|
||||
}
|
||||
this.set('title', params['dialog_title']);
|
||||
if (_.isUndefined(params['btn_primary']))
|
||||
if (_.isUndefined(params['btn_primary'])) {
|
||||
params['btn_primary'] = 'Select';
|
||||
}
|
||||
this.set('label', params['btn_primary']);
|
||||
|
||||
var trans_id;
|
||||
params = JSON.stringify(params);
|
||||
$container.find('.storage_content').remove();
|
||||
$container.append("<div class='storage_content'></div>");
|
||||
@ -323,6 +329,8 @@ define([
|
||||
this.__internal.buttons[0].element.innerHTML = newValue;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
setup:function() {
|
||||
@ -392,10 +400,11 @@ define([
|
||||
});
|
||||
|
||||
transId = getTransId(params);
|
||||
if (transId.readyState == 4)
|
||||
var t_res;
|
||||
if (transId.readyState == 4) {
|
||||
t_res = JSON.parse(transId.responseText);
|
||||
}
|
||||
trans_id = t_res.data.fileTransId;
|
||||
|
||||
};
|
||||
|
||||
// Dialog property
|
||||
@ -403,11 +412,13 @@ define([
|
||||
main: function(params) {
|
||||
var trans_id;
|
||||
// Set title and button name
|
||||
if (_.isUndefined(params['dialog_title']))
|
||||
if (_.isUndefined(params['dialog_title'])) {
|
||||
params['dialog_title'] = 'Create file';
|
||||
}
|
||||
this.set('title', params['dialog_title']);
|
||||
if (_.isUndefined(params['btn_primary']))
|
||||
if (_.isUndefined(params['btn_primary'])) {
|
||||
params['btn_primary'] = 'Create';
|
||||
}
|
||||
this.set('label', params['btn_primary']);
|
||||
|
||||
params = JSON.stringify(params);
|
||||
@ -429,6 +440,8 @@ define([
|
||||
this.__internal.buttons[0].element.innerHTML = newValue;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
setup:function() {
|
||||
@ -455,8 +468,8 @@ define([
|
||||
$('.replace_file .btn_yes').click(function(self) {
|
||||
$('.replace_file, .fm_dimmer').hide();
|
||||
var selected_item = $('.allowed_file_types .create_input input[type="text"]').val(),
|
||||
newFile = $('.currentpath').val() + selected_item,
|
||||
newFile = newFile.substr(1);
|
||||
sel_item = $('.currentpath').val() + selected_item,
|
||||
newFile = sel_item.substr(1);
|
||||
pgAdmin.Browser.Events.trigger('pgadmin-storage:finish_btn:create_file', newFile);
|
||||
$('.file_manager_create_cancel').trigger('click');
|
||||
});
|
||||
|
@ -1269,7 +1269,8 @@ var enab_dis_level_up = function() {
|
||||
*/
|
||||
var fm_url = "{{ url_for('file_manager.index') }}get_trans_id",
|
||||
transId = loadData(fm_url),
|
||||
t_id = '';
|
||||
t_res,
|
||||
t_id;
|
||||
|
||||
if (transId.readyState == 4) {
|
||||
t_res = JSON.parse(transId.responseText);
|
||||
|
Loading…
Reference in New Issue
Block a user