Introduced new controls to show the list of a node type (by name and id) as properties of other node.

Resolved a typo in privileges control.
Removed duplicate lines in backform.pgadmin.js
This commit is contained in:
Ashesh Vashi 2015-12-28 01:00:20 +05:30
parent d56ddb9fa4
commit eb83d57c5a
8 changed files with 183 additions and 33 deletions

View File

@ -135,6 +135,12 @@ class BrowserModule(PgAdminModule):
'name': name, 'path': url_for('browser.static', filename=end),
'preloaded': True})
scripts.append({
'name': 'pgadmin.browser.node.ui',
'path': url_for('browser.static', filename='js/node.ui'),
'when': 'server-group'
})
for module in self.submodules:
scripts.extend(module.get_own_javascripts())
return scripts

View File

@ -96,8 +96,7 @@ class CollectionNodeModule(PgAdminModule, PGChildModule):
snippets = [
render_template(
"browser/css/collection.css",
node_type=self.node_type,
_=gettext
node_type=self.node_type
),
render_template(
"browser/css/node.css",

View File

@ -103,7 +103,7 @@
var privs = {};
_.each(this.privileges, function(p) {
privs[p] = {
'privilige_type': p, 'privilege': false, 'with_grant': false
'privilege_type': p, 'privilege': false, 'with_grant': false
}
});
@ -376,7 +376,7 @@
});
/*
* This will help us transform the privilieges value in proper format to be
* This will help us transform the privileges value in proper format to be
* displayed in the cell.
*/
var PrivilegeCellFormatter = Backgrid.Extension.PrivilegeCellFormatter =

View File

@ -40,4 +40,8 @@
.browser-tab-content {
width: 100%;
height: 100%;
}
}
.pgadmin-node-select option {
padding-left: 20px;
}

View File

@ -0,0 +1,158 @@
define(
['jquery', 'underscore', 'pgadmin', 'backbone', 'backform', 'alertify', 'pgadmin.browser.node'],
function($, _, pgAdmin, Backbone, Backform, Alertify, Node) {
var pgBrowser = pgAdmin.Browser;
/*
* NodeAjaxOptionsControl
* This control will fetch the options required to render the select
* control, from the url specific to the pgAdmin.Browser node object.
*
* In order to use this properly, schema require to set the 'url' property,
* which exposes the data for this node.
*
* In case the url is not providing the data in proper format, we can
* specify the 'transform' function too, which will convert the fetched
* data to proper 'label', 'value' format.
*/
var NodeAjaxOptionsControl = Backform.NodeAjaxOptionsControl =
Backform.SelectControl.extend({
defaults: _.extend(Backform.SelectControl.prototype.defaults, {
url: undefined,
transform: undefined
}),
initialize: function() {
/*
* Initialization from the original control.
*/
Backform.SelectControl.prototype.initialize.apply(this, arguments);
/*
* We're about to fetch the options required for this control.
*/
var self = this,
url = self.field.get('url') || self.defaults.url,
m = self.model.handler || self.model;
// Hmm - we found the url option.
// That means - we needs to fetch the options from that node.
if (url) {
var node = this.field.get('schema_node'),
full_url = node.generate_url.apply(
node, [
null, url, this.field.get('node_data'),
false, this.field.get('node_info')
]),
/*
* We needs to check, if we have already cached data for this url.
* If yes - use that, and do not bother about fetching it again,
* and use it.
*/
data = node.cache(full_url);
if (_.isUndefined(data) || _.isNull(data)) {
m.trigger('pgadmin-view:fetching', m, self.field);
$.ajax({
async: false,
url: full_url,
success: function(res) {
/*
* We will cache this data for short period of time for avoiding
* same calls.
*/
data = node.cache(full_url, res.data);
},
error: function() {
m.trigger('pgadmin-view:fetch:error', m, self.field);
}
});
m.trigger('pgadmin-view:fetched', m, self.field);
}
/*
* Transform the data
*/
transform = this.field.get('transform') || self.defaults.transform;
if (transform && _.isFunction(transform)) {
try {
data = transform.apply(self, [data]);
} catch(e) {
// Do nothing
data = []
m.trigger('pgadmin-view:transform:error', m, self.field, e);
}
}
self.field.set('options', data);
}
}
});
var NodeListByIdControl = Backform.NodeListByIdControl = NodeAjaxOptionsControl.extend({
controlClassName: 'pgadmin-node-select form-control',
template: _.template([
'<label class="<%=Backform.controlLabelClassName%>"><%=label%></label>',
'<div class="<%=Backform.controlsClassName%> <%=extraClasses.join(\' \')%>">',
' <select class="pgadmin-node-select form-control" name="<%=name%>" value="<%-value%>" <%=disabled ? "disabled" : ""%> <%=required ? "required" : ""%> >',
' <% if (first_empty) { %>',
' <option value="" <%="" === rawValue ? "selected=\'selected\'" : "" %>><%- empty_value %></option>',
' <% } %>',
' <% for (var i=0; i < options.length; i++) { %>',
' <% var option = options[i]; %>',
' <% if (!_.isUndefined(option.node)) { %>',
' <option value="<%-formatter.fromRaw(option.value)%>" <%=option.value === rawValue ? "selected=\'selected\'" : "" %> node="<%=option.node%>"><%-option.label%></option>',
' <% } else { %>',
' <option value="<%-formatter.fromRaw(option.value)%>" <%=option.value === rawValue ? "selected=\'selected\'" : "" %>><%-option.label%></option>',
' <% } %>',
' <% } %>',
' </select>',
'</div>'].join("\n")),
defaults: _.extend(NodeAjaxOptionsControl.prototype.defaults, {
first_empty: true,
empty_value: '-- None --',
url: 'nodes',
transform: function(rows) {
var self = this,
node = self.field.get('schema_node'),
res = [];
_.each(rows, function(r) {
res.push({
'value': r._id,
'node': _.isFunction(node['node_image']) ? (node['node_image']).apply(node, [r, self.model]) : node.type,
'label': (_.isFunction(node['node_label']) ?
(node['node_label']).apply(node, [r, self.model]) :
r.label)
});
});
return res;
}
})
});
var NodeListByNameControl = Backform.NodeListByNameControl = NodeListByIdControl.extend({
defaults: _.extend(NodeListByIdControl.prototype.defaults, {
transform: function(rows) {
var self = this,
node = self.field.get('schema_node'),
res = [];
_.each(rows, function(r) {
var l = _.isFunction(node['node_label']) ?
(node['node_label']).apply(node, [r, self.model]) :
r.label;
res.push({
'value': l,
'node': _.isFunction(node['node_image']) ? (node['node_image']).apply(node, [r, self.model]) : node.type,
'label': l
});
});
return res;
}
})
});
return Backform.NodeListControl;
});

View File

@ -5,3 +5,9 @@
vertical-align: middle;
height: 1.3em;
}
.pgadmin-node-select option[node="{{node_type}}"] {
background-image: url('{{ url_for('NODE-%s.static' % node_type, filename='img/%s.png' % node_type )}}') !important;
background-repeat: no-repeat;
background-position: center left;
}

View File

@ -799,7 +799,11 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, Backform) {
((_.isUndefined(item) || _.isNull(item)) ? info || {} :
this.getTreeNodeHierarchy(item)),
function(v, k, o) {
return (k != self.type);
// If you want to make sure, it generates the correct url path,
// please define 'parents' properties for this node, which will
// be an list of name of the parents, and grand parents type.
return (k != self.type ||
(self.parents && _.isArray(self.parents) && k in self.parents));
})
),
function(o) { return o.priority; }

View File

@ -130,33 +130,6 @@
' </span>',
'</div>'
].join("\n"));
Backform.Control.prototype.clearInvalid = function() {
this.$el.removeClass(Backform.errorClassName);
this.$el.find(".pgadmin-control-error-message").remove();
return this;
};
Backform.Control.prototype.updateInvalid = function() {
var self = this;
var errorModel = this.model.errorModel;
if (!(errorModel instanceof Backbone.Model)) return this;
this.clearInvalid();
this.$el.find(':input').not('button').each(function(ix, el) {
var attrArr = $(el).attr('name').split('.'),
name = attrArr.shift(),
path = attrArr.join('.'),
error = self.keyPathAccessor(errorModel.toJSON(), $(el).attr('name'));
if (_.isEmpty(error)) return;
self.$el.addClass(Backform.errorClassName).append(
$("<div></div>").addClass('pgadmin-control-error-message col-xs-12 help-block').text(error)
);
});
};
Backform.Control.prototype.clearInvalid = function() {
this.$el.removeClass(Backform.errorClassName);
this.$el.find(".pgadmin-control-error-message").remove();