Resolved few intialization issue with Node model data, moved the
privileges functionality out of the backform.pgadmin.js to make it more modular. Now - privileges will expect the privileges data in following format: <name_of_the_property> : [{ "privileges": [{ "privilege_type": <privilege_type>, "privilege": true, "with_grant": false }, ... ], "grantee": <grantee>, "grantor": <grantor> }, ... ] Example: acl": [{ "privileges": [{ "privilege_type": "CONNECT", "privilege": true, "with_grant": false }], "grantee": '', "grantor": 'ashesh' },{ "privileges": [{ "privilege_type": "CREATE", "privilege": true, "with_grant": false },{ "privilege": true, "privilege_type": "TEMPORARY", "with_grant": false }], "grantee": test, "grantor": ashesh }]pull/3/head
parent
bf5170bc89
commit
c51ecc69e4
|
@ -8,7 +8,8 @@
|
||||||
##########################################################################
|
##########################################################################
|
||||||
import json
|
import json
|
||||||
from abc import ABCMeta, abstractmethod, abstractproperty
|
from abc import ABCMeta, abstractmethod, abstractproperty
|
||||||
from flask import render_template, request, make_response, jsonify, current_app
|
from flask import render_template, request, make_response, jsonify, \
|
||||||
|
current_app, url_for
|
||||||
from flask.ext.security import login_required, current_user
|
from flask.ext.security import login_required, current_user
|
||||||
from pgadmin.settings.settings_model import db, Server, ServerGroup, User
|
from pgadmin.settings.settings_model import db, Server, ServerGroup, User
|
||||||
from pgadmin.utils.menu import MenuItem
|
from pgadmin.utils.menu import MenuItem
|
||||||
|
@ -84,6 +85,25 @@ class ServerModule(sg.ServerGroupPluginModule):
|
||||||
|
|
||||||
return snippets
|
return snippets
|
||||||
|
|
||||||
|
def get_own_javascripts(self):
|
||||||
|
scripts = []
|
||||||
|
|
||||||
|
scripts.extend([{
|
||||||
|
'name': 'pgadmin.node.server',
|
||||||
|
'path': url_for('browser.index') + '%s/module' % self.node_type,
|
||||||
|
'when': self.script_load
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'pgadmin.browser.server.privilege',
|
||||||
|
'path': url_for('browser.index') + 'server/static/js/privilege',
|
||||||
|
'when': self.node_type
|
||||||
|
}])
|
||||||
|
|
||||||
|
for module in self.submodules:
|
||||||
|
scripts.extend(module.get_own_javascripts())
|
||||||
|
|
||||||
|
return scripts
|
||||||
|
|
||||||
|
|
||||||
class ServerMenuItem(MenuItem):
|
class ServerMenuItem(MenuItem):
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
|
@ -606,7 +626,8 @@ class ServerNode(PGChildNodeView):
|
||||||
),
|
),
|
||||||
'connected': True,
|
'connected': True,
|
||||||
'type': manager.server_type,
|
'type': manager.server_type,
|
||||||
'version': manager.version
|
'version': manager.version,
|
||||||
|
'db': manager.db
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,431 @@
|
||||||
|
(function(root, factory) {
|
||||||
|
// Set up Backform appropriately for the environment. Start with AMD.
|
||||||
|
if (typeof define === 'function' && define.amd) {
|
||||||
|
define(['underscore', 'jquery', 'backbone', 'backform', 'backgrid', 'alertify', 'pgadmin.browser.node'],
|
||||||
|
function(_, $, Backbone, Backform, Backgrid, Alertify, pgNode) {
|
||||||
|
// Export global even in AMD case in case this script is loaded with
|
||||||
|
// others that may still expect a global Backform.
|
||||||
|
return factory(root, _, $, Backbone, Backform, Alertify, pgNode);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Next for Node.js or CommonJS. jQuery may not be needed as a module.
|
||||||
|
} else if (typeof exports !== 'undefined') {
|
||||||
|
var _ = require('underscore') || root._,
|
||||||
|
$ = root.jQuery || root.$ || root.Zepto || root.ender,
|
||||||
|
Backbone = require('backbone') || root.Backbone,
|
||||||
|
Backform = require('backform') || root.Backform;
|
||||||
|
Alertify = require('alertify') || root.Alertify;
|
||||||
|
pgAdmin = require('pgadmin.browser.node') || root.pgAdmin.Browser.Node;
|
||||||
|
factory(root, _, $, Backbone, Backform, Alertify, pgNode);
|
||||||
|
|
||||||
|
// Finally, as a browser global.
|
||||||
|
} else {
|
||||||
|
factory(root, root._, (root.jQuery || root.Zepto || root.ender || root.$), root.Backbone, root.Backform, root.pgAdmin.Browser.Node);
|
||||||
|
}
|
||||||
|
} (this, function(root, _, $, Backbone, Backform, Alertify, pgNode) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Each Privilege, supporeted by an database object, will be represented
|
||||||
|
* using this Model.
|
||||||
|
*
|
||||||
|
* Defaults:
|
||||||
|
* privilege_type -> Name of the permission
|
||||||
|
* i.e. CREATE, TEMPORARY, CONNECT, etc.
|
||||||
|
* privilege -> Has privilege? (true/false)
|
||||||
|
* with_grant -> Has privilege with grant option (true/false)
|
||||||
|
**/
|
||||||
|
var PrivilegeModel = pgNode.Model.extend({
|
||||||
|
idAttribute: 'privilege_type',
|
||||||
|
defaults: {
|
||||||
|
privilege_type: undefined,
|
||||||
|
privilege: false,
|
||||||
|
with_grant: false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A database object has privileges item list (aclitem[]).
|
||||||
|
*
|
||||||
|
* This model represents the individual privilege item (aclitem).
|
||||||
|
* It has basically three properties:
|
||||||
|
* + grantee - Role to which that privilege applies to.
|
||||||
|
* Empty value represents to PUBLIC.
|
||||||
|
* + grantor - Granter who has given this permission.
|
||||||
|
* + privileges - Privileges for that role.
|
||||||
|
**/
|
||||||
|
var PrivilegeRoleModel = pgNode.PrivilegeRoleModel = pgNode.Model.extend({
|
||||||
|
defaults: {
|
||||||
|
grantee: undefined,
|
||||||
|
grantor: undefined,
|
||||||
|
privileges: undefined
|
||||||
|
},
|
||||||
|
/*
|
||||||
|
* Each of the database object needs to extend this model, which should
|
||||||
|
* provide the type of privileges (it supports).
|
||||||
|
*/
|
||||||
|
privileges:[],
|
||||||
|
|
||||||
|
schema: [{
|
||||||
|
id: 'grantee', label:'Grantee', type:'text', group: null, cell: 'string',
|
||||||
|
disabled: true, cellHeaderClasses: 'width_percent_40'
|
||||||
|
}, {
|
||||||
|
id: 'privileges', label:'Privileges',
|
||||||
|
type: 'collection', model: PrivilegeModel, group: null,
|
||||||
|
disabled: false, cell: 'privilege', control: 'text',
|
||||||
|
cellHeaderClasses: 'width_percent_40'
|
||||||
|
},{
|
||||||
|
id: 'grantor', label: 'Granter', type: 'text', disabled: true
|
||||||
|
}],
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize the model, which will transform the privileges string to
|
||||||
|
* collection of Privilege Model.
|
||||||
|
*/
|
||||||
|
initialize: function(attrs, opts) {
|
||||||
|
|
||||||
|
pgNode.Model.prototype.initialize.apply(this, arguments);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define the collection of the privilege supported by this model
|
||||||
|
*/
|
||||||
|
var privileges = this.get('privileges') || {};
|
||||||
|
if (_.isArray(privileges)) {
|
||||||
|
privileges = new (pgNode.Collection)(
|
||||||
|
models, {
|
||||||
|
model: PrivilegeModel,
|
||||||
|
handler: this.handler || this,
|
||||||
|
silent: true,
|
||||||
|
parse: false
|
||||||
|
});
|
||||||
|
this.set('privileges', privileges, {silent: true});
|
||||||
|
}
|
||||||
|
|
||||||
|
var privs = {};
|
||||||
|
_.each(this.privileges, function(p) {
|
||||||
|
privs[p] = {
|
||||||
|
'privilige_type': p, 'privilege': false, 'with_grant': false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
privileges.each(function(m) {
|
||||||
|
delete privs[m.get('privilege_type')];
|
||||||
|
});
|
||||||
|
|
||||||
|
_.each(privs, function(p) {
|
||||||
|
privileges.add(p, {silent: true});
|
||||||
|
});
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
toJSON: function(session) {
|
||||||
|
if (session) {
|
||||||
|
return pgNode.Model.prototype.apply(this, [true, false]);
|
||||||
|
}
|
||||||
|
|
||||||
|
var privileges = [];
|
||||||
|
|
||||||
|
this.attributes['privileges'].each(
|
||||||
|
function(p) {
|
||||||
|
if (p.get('privilege')) {
|
||||||
|
privileges.push(p.toJSON());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
'grantee': this.get('grantee'),
|
||||||
|
'grantor': this.get('grantor'),
|
||||||
|
'privileges': privileges
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
Custom cell editor for editing privileges.
|
||||||
|
*/
|
||||||
|
var PrivilegeCellEditor = Backgrid.Extension.PrivilegeCellEditor =
|
||||||
|
Backgrid.CellEditor.extend({
|
||||||
|
tagName: "div",
|
||||||
|
|
||||||
|
// All available privileges in the PostgreSQL database server for
|
||||||
|
// generating the label for the specific Control
|
||||||
|
Labels: {
|
||||||
|
"C": "CREATE",
|
||||||
|
"T": "TEMP",
|
||||||
|
"c": "CONNECT",
|
||||||
|
"a": "INSERT",
|
||||||
|
"r": "SELECT",
|
||||||
|
"w": "UPDATE",
|
||||||
|
"d": "DELETE",
|
||||||
|
"D": "TRUNCATE",
|
||||||
|
"x": "REFERENCES",
|
||||||
|
"t": "TRIGGER",
|
||||||
|
"U": "USAGE",
|
||||||
|
"X": "EXECUTE"
|
||||||
|
},
|
||||||
|
|
||||||
|
template: _.template([
|
||||||
|
'<tr class="<%= header ? "header" : "" %>">',
|
||||||
|
' <td class="renderable">',
|
||||||
|
' <label>',
|
||||||
|
' <input type="checkbox" name="privilege" privilege="<%- privilege_type %>" target="<%- target %>" <%= privilege ? \'checked\' : "" %>></input>',
|
||||||
|
' <%- privilege_type %>',
|
||||||
|
' </label>',
|
||||||
|
' </td>',
|
||||||
|
' <td class="renderable">',
|
||||||
|
' <label>',
|
||||||
|
' <input type="checkbox" name="with_grant" privilege="<%- privilege_type %>" target="<%- target %>" <%= with_grant ? \'checked\' : "" %> <%= privilege ? "" : \'disabled\'%>></input>',
|
||||||
|
' WITH GRANT OPTION',
|
||||||
|
' </label>',
|
||||||
|
' </td>',
|
||||||
|
'</tr>'].join(" "), null, {variable: null}),
|
||||||
|
|
||||||
|
events: {
|
||||||
|
'change': 'privilegeChanged',
|
||||||
|
'blur': 'lostFocus'
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function () {
|
||||||
|
this.$el.empty();
|
||||||
|
this.$el.attr('tabindex', '1');
|
||||||
|
this.$el.attr('target', this.elId);
|
||||||
|
|
||||||
|
var collection = this.model.get(this.column.get("name")),
|
||||||
|
tbl = $("<table></table>").appendTo(this.$el),
|
||||||
|
self = this,
|
||||||
|
privilege = true, with_grant = true;
|
||||||
|
|
||||||
|
// For each privilege generate html template.
|
||||||
|
// List down all the Privilege model.
|
||||||
|
collection.each(function(m) {
|
||||||
|
var d = m.toJSON();
|
||||||
|
|
||||||
|
_.extend(
|
||||||
|
d, {
|
||||||
|
'target': self.cid,
|
||||||
|
'header': false
|
||||||
|
});
|
||||||
|
privilege = (privilege && d.privilege);
|
||||||
|
with_grant = (with_grant && privilege && d.with_grant);
|
||||||
|
tbl.append(self.template(d));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Preprend the ALL controls on that table
|
||||||
|
tbl.prepend(
|
||||||
|
self.template({
|
||||||
|
'target': self.cid,
|
||||||
|
'name': 'ALL',
|
||||||
|
'privilege_type': 'ALL',
|
||||||
|
'privilege': privilege,
|
||||||
|
'with_grant': with_grant,
|
||||||
|
'header': true
|
||||||
|
}));
|
||||||
|
|
||||||
|
self.$el.find('input[type=checkbox]').first().focus();
|
||||||
|
self.delegateEvents();
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Listen to the checkbox value change and update the model accordingly.
|
||||||
|
*/
|
||||||
|
privilegeChanged: function(ev) {
|
||||||
|
if (ev && ev.target) {
|
||||||
|
/*
|
||||||
|
* We're looking for checkboxes only.
|
||||||
|
*/
|
||||||
|
var $el = $(ev.target),
|
||||||
|
privilege_type = $el.attr('privilege'),
|
||||||
|
type = $el.attr('name'),
|
||||||
|
checked = $el.prop('checked'),
|
||||||
|
$tr = $el.closest('tr'),
|
||||||
|
$tbl = $tr.closest('table'),
|
||||||
|
collection = this.model.get('privileges');;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the checkbox selected/deselected is for 'ALL', we will select all
|
||||||
|
* the checkbox for each privilege.
|
||||||
|
*/
|
||||||
|
if (privilege_type == 'ALL') {
|
||||||
|
var $elGrant = $tr.find('input[name=with_grant]'),
|
||||||
|
$allPrivileges = $tbl.find(
|
||||||
|
'input[name=privilege][privilege!=\'ALL\']'
|
||||||
|
),
|
||||||
|
$allGrants = $tbl.find(
|
||||||
|
'input[name=with_grant][privilege!=\'ALL\']'
|
||||||
|
),
|
||||||
|
allPrivilege, allWithGrant;
|
||||||
|
|
||||||
|
if (type == 'privilege') {
|
||||||
|
/*
|
||||||
|
* We clicked the privilege checkbox, and not checkbox for with
|
||||||
|
* grant options.
|
||||||
|
*/
|
||||||
|
allPrivilege = checked;
|
||||||
|
allWithGrant = false;
|
||||||
|
|
||||||
|
if (checked) {
|
||||||
|
$allPrivileges.prop('checked', true);
|
||||||
|
/*
|
||||||
|
* We have clicked the ALL checkbox, we should be able to select
|
||||||
|
* the grant options too.
|
||||||
|
*/
|
||||||
|
$allGrants.prop('disabled', false);
|
||||||
|
$elGrant.prop('disabled', false);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* ALL checkbox has been deselected, hence - we need to make
|
||||||
|
* sure.
|
||||||
|
* 1. Deselect all the privileges checkboxes
|
||||||
|
* 2. Deselect and disable all with grant privilege checkboxes.
|
||||||
|
* 3. Deselect and disable the checkbox for ALL with grant privilege.
|
||||||
|
*/
|
||||||
|
$allPrivileges.prop('checked', false);
|
||||||
|
$elGrant.prop('checked', false),
|
||||||
|
$allGrants.prop('checked', false);
|
||||||
|
$elGrant.prop('disabled', true);
|
||||||
|
$allGrants.prop('disabled', true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* We were able to click the ALL with grant privilege checkbox,
|
||||||
|
* that means, privilege for Privileges are true.
|
||||||
|
*
|
||||||
|
* We need to select/deselect all the with grant options
|
||||||
|
* checkboxes, based on the current value of the ALL with grant
|
||||||
|
* privilege checkbox.
|
||||||
|
*/
|
||||||
|
allPrivilege = true;
|
||||||
|
allWithGrant = checked;
|
||||||
|
$allGrants.prop('checked', checked);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the values for each Privilege Model.
|
||||||
|
*/
|
||||||
|
collection.each(function(m) {
|
||||||
|
m.set({'privilege': allPrivilege, 'with_grant': allWithGrant});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Particular privilege has been selected/deselected, which can be
|
||||||
|
* identified using the privilege="X" attribute.
|
||||||
|
*/
|
||||||
|
var attrs = {},
|
||||||
|
$tbl = $tr.closest('table'),
|
||||||
|
$allPrivilege = $tbl.find(
|
||||||
|
'input[name=privilege][privilege=\'ALL\']'
|
||||||
|
),
|
||||||
|
$allGrant = $tbl.find(
|
||||||
|
'input[name=with_grant][privilege=\'ALL\']'
|
||||||
|
);
|
||||||
|
|
||||||
|
attrs[type] = checked;
|
||||||
|
|
||||||
|
if (type == 'privilege') {
|
||||||
|
var $elGrant = ($el.closest('tr')).find('input[name=with_grant]');
|
||||||
|
if (!checked) {
|
||||||
|
attrs['with_grant'] = false;
|
||||||
|
|
||||||
|
$elGrant.prop('checked', false).prop('disabled', true);
|
||||||
|
$allPrivilege.prop('checked', false);
|
||||||
|
$allGrant.prop('disabled', true);
|
||||||
|
$allGrant.prop('checked', false);
|
||||||
|
} else {
|
||||||
|
$elGrant.prop('disabled', false);
|
||||||
|
}
|
||||||
|
} else if (!checked) {
|
||||||
|
$allGrant.prop('checked', false);
|
||||||
|
}
|
||||||
|
collection.get(privilege_type).set(attrs);
|
||||||
|
|
||||||
|
if (checked) {
|
||||||
|
var $allPrivileges = $tbl.find(
|
||||||
|
'input[name=privilege][privilege!=\'ALL\']:checked'
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($allPrivileges.length == collection.models.length) {
|
||||||
|
|
||||||
|
$allPrivilege.prop('checked', true);
|
||||||
|
|
||||||
|
if (type == 'with_grant') {
|
||||||
|
var $allGrants = $tbl.find(
|
||||||
|
'input[name=with_grant][privilege!=\'ALL\']:checked'
|
||||||
|
);
|
||||||
|
if ($allGrants.length == collection.models.length) {
|
||||||
|
$allGrant.prop('disabled', false);
|
||||||
|
$allGrant.prop('checked', true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$allGrant.prop('disabled', false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
lostFocus: function(ev) {
|
||||||
|
/*
|
||||||
|
* We lost the focuse, it's time for us to exit the editor.
|
||||||
|
*/
|
||||||
|
var m = this.model;
|
||||||
|
m.trigger('backgrid:edited', m, this.column, new Backgrid.Command(ev));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This will help us transform the privilieges value in proper format to be
|
||||||
|
* displayed in the cell.
|
||||||
|
*/
|
||||||
|
var PrivilegeCellFormatter = Backgrid.Extension.PrivilegeCellFormatter =
|
||||||
|
function () {};
|
||||||
|
_.extend(PrivilegeCellFormatter.prototype, {
|
||||||
|
notation: {
|
||||||
|
"CREATE" : "C",
|
||||||
|
"TEMPORARY" : "T",
|
||||||
|
"CONNECT" : "c",
|
||||||
|
"INSERT" : "a",
|
||||||
|
"SELECT" : "r",
|
||||||
|
"UPDATE" : "w",
|
||||||
|
"DELETE" : "d",
|
||||||
|
"TRUNCATE" : "D",
|
||||||
|
"REFERENCES" : "x",
|
||||||
|
"TRIGGER" : "t",
|
||||||
|
"USAGE" : "U",
|
||||||
|
"EXECUTE" : "X"
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Takes a raw value from a model and returns an optionally formatted
|
||||||
|
* string for display.
|
||||||
|
*/
|
||||||
|
fromRaw: function (rawData, model) {
|
||||||
|
var res = '',
|
||||||
|
self = this;
|
||||||
|
|
||||||
|
if (rawData instanceof Backbone.Collection) {
|
||||||
|
rawData.each(function(m) {
|
||||||
|
if (m.get('privilege')) {
|
||||||
|
res += self.notation[m.get('privilege_type')];
|
||||||
|
if (m.get('with_grant')) {
|
||||||
|
res += '*';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PrivilegeCell for rendering and taking input for the privileges.
|
||||||
|
*/
|
||||||
|
var PrivilegeCell = Backgrid.Extension.PrivilegeCell = Backgrid.Cell.extend({
|
||||||
|
className: "edit-cell",
|
||||||
|
formatter: PrivilegeCellFormatter,
|
||||||
|
editor: PrivilegeCellEditor
|
||||||
|
});
|
||||||
|
|
||||||
|
return PrivilegeRoleModel;
|
||||||
|
}));
|
|
@ -443,25 +443,44 @@ OWNER TO helpdesk;\n';
|
||||||
if (d) {
|
if (d) {
|
||||||
/* Loading all the scripts registered to be loaded on this node */
|
/* Loading all the scripts registered to be loaded on this node */
|
||||||
if (obj.scripts && obj.scripts[d._type]) {
|
if (obj.scripts && obj.scripts[d._type]) {
|
||||||
_.each(obj.scripts[d._type], function(s) {
|
var scripts = _.extend({}, obj.scripts[d._type]);
|
||||||
if (!s.loaded) {
|
|
||||||
require([s.name], function(m) {
|
/*
|
||||||
s.loaded = true;
|
* We can remove it from the Browser.scripts object as
|
||||||
// Call the initialize (if present)
|
* these're about to be loaded.
|
||||||
if (m && m.init && typeof m.init == 'function') {
|
*
|
||||||
try {
|
* This will make sure that - we do check for the script for
|
||||||
m.init();
|
* loading only once.
|
||||||
} catch (err) {
|
*
|
||||||
obj.report_error(
|
*/
|
||||||
'{{ _('Error Initializing script - ') }}' + s.path, err);
|
delete obj.scripts[d._type];
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
_.each(scripts, function(s) {
|
||||||
|
if (!s.loaded) {
|
||||||
|
require([s.name], function(m) {
|
||||||
|
s.loaded = true;
|
||||||
|
// Call the initialize (if present)
|
||||||
|
if (m && m.init && typeof m.init == 'function') {
|
||||||
|
try {
|
||||||
|
m.init();
|
||||||
|
} catch (err) {
|
||||||
|
console.log("Error running module Init script for '" + s.path + "'");
|
||||||
|
console.log(err);
|
||||||
|
|
||||||
|
obj.report_error(
|
||||||
|
'{{ _('Error Initializing script - ') }}' + s.path, err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}, function() {
|
||||||
}, function() {
|
console.log("Error loading script - " + s.path);
|
||||||
obj.report_error(
|
console.log(arguments);
|
||||||
'{{ _('Error loading script - ') }}' + s.path);
|
obj.report_error(
|
||||||
});
|
'{{ _('Error loading script - ') }}' + s.path);
|
||||||
}
|
}).bind(s);
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
}, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1005,7 +1005,7 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, Backform) {
|
||||||
Model: Backbone.Model.extend({
|
Model: Backbone.Model.extend({
|
||||||
parse: function(res) {
|
parse: function(res) {
|
||||||
var self = this;
|
var self = this;
|
||||||
if ('node' in res && res['node']) {
|
if (res && _.isObject(res) && 'node' in res && res['node']) {
|
||||||
self.tnode = _.extend({}, res.node);
|
self.tnode = _.extend({}, res.node);
|
||||||
delete res.node;
|
delete res.node;
|
||||||
}
|
}
|
||||||
|
@ -1042,24 +1042,25 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, Backform) {
|
||||||
case 'model':
|
case 'model':
|
||||||
obj = self.get(s.id);
|
obj = self.get(s.id);
|
||||||
val = res[s.id];
|
val = res[s.id];
|
||||||
if (_.isArray(val) || _.isObject(val)) {
|
if (!_.isUndefined(val) && !_.isNull(val)) {
|
||||||
if (!_.isObject(obj)) {
|
if (!obj || !(obj instanceof Backbone.Model)) {
|
||||||
if (_.isString(s.model) &&
|
if (_.isString(s.model) &&
|
||||||
s.model in pgBrowser.Nodes[s.model]) {
|
s.model in pgBrowser.Nodes[s.model]) {
|
||||||
obj = new (pgBrowser.Nodes[s.model].Model)(
|
obj = new (pgBrowser.Nodes[s.model].Model)(
|
||||||
null, {handler: self.handler || self}
|
obj, {silent: true, handler: self.handler || self}
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
obj = new (s.model)(null, {handler: self.handler || self});
|
obj = new (s.model)(obj, {
|
||||||
|
silent: true, handler: self.handler || self
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
obj.set(self.get(s.id), {parse: true, silent: true});
|
obj.set(val, {parse: true, silent: true});
|
||||||
} else {
|
} else {
|
||||||
if (obj)
|
if (obj)
|
||||||
delete obj;
|
delete obj;
|
||||||
obj = null;
|
obj = null;
|
||||||
}
|
}
|
||||||
self.set(s.id, obj, {silent: true});
|
|
||||||
res[s.id] = obj;
|
res[s.id] = obj;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -1072,6 +1073,8 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, Backform) {
|
||||||
initialize: function(attributes, options) {
|
initialize: function(attributes, options) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
Backbone.Model.prototype.initialize.apply(self, arguments);
|
||||||
|
|
||||||
if (_.isUndefined(options) || _.isNull(options)) {
|
if (_.isUndefined(options) || _.isNull(options)) {
|
||||||
options = attributes || {};
|
options = attributes || {};
|
||||||
attributes = null;
|
attributes = null;
|
||||||
|
@ -1088,31 +1091,35 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, Backform) {
|
||||||
|
|
||||||
if (self.schema && _.isArray(self.schema)) {
|
if (self.schema && _.isArray(self.schema)) {
|
||||||
_.each(self.schema, function(s) {
|
_.each(self.schema, function(s) {
|
||||||
var obj = null;
|
var obj = self.get(s.id);
|
||||||
switch(s.type) {
|
switch(s.type) {
|
||||||
case 'collection':
|
case 'collection':
|
||||||
if (_.isString(s.model) &&
|
if (!obj || !(obj instanceof pgBrowser.Node.Collection)) {
|
||||||
|
if (_.isString(s.model) &&
|
||||||
s.model in pgBrowser.Nodes) {
|
s.model in pgBrowser.Nodes) {
|
||||||
var node = pgBrowser.Nodes[s.model];
|
var node = pgBrowser.Nodes[s.model];
|
||||||
obj = new (node.Collection)(null, {
|
obj = new (node.Collection)(obj, {
|
||||||
model: node.model,
|
model: node.model,
|
||||||
handler: self.handler || self
|
handler: self.handler || self
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
obj = new (pgBrowser.Node.Collection)(null, {
|
obj = new (pgBrowser.Node.Collection)(obj, {
|
||||||
model: s.model,
|
model: s.model,
|
||||||
handler: self.handler || self
|
handler: self.handler || self
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'model':
|
case 'model':
|
||||||
if (_.isString(s.model) &&
|
if (!obj || !(obj instanceof Backbone.Model)) {
|
||||||
s.model in pgBrowser.Nodes[s.model]) {
|
if (_.isString(s.model) &&
|
||||||
obj = new (pgBrowser.Nodes[s.model].Model)(
|
s.model in pgBrowser.Nodes[s.model]) {
|
||||||
null, {handler: self.handler || self}
|
obj = new (pgBrowser.Nodes[s.model].Model)(
|
||||||
);
|
obj, {handler: self.handler || self}
|
||||||
} else {
|
);
|
||||||
obj = new (s.model)(null, {handler: self.handler || self});
|
} else {
|
||||||
|
obj = new (s.model)(obj, {handler: self.handler || self});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -1148,8 +1155,12 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, Backform) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
return (_.size(self.sessAttrs) > 0 ||
|
return (_.size(self.sessAttrs) > 0 ||
|
||||||
_.some(self.objects, function(o) {
|
_.some(self.objects, function(k) {
|
||||||
return self.get(o).sessChanged();
|
var obj = self.get(k);
|
||||||
|
if (!(_.isNull(obj) || _.isUndefined(obj))) {
|
||||||
|
return obj.sessChanged();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
sessValid: function() {
|
sessValid: function() {
|
||||||
|
@ -1208,11 +1219,10 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, Backform) {
|
||||||
res = _.extend(res, self.sessAttrs);
|
res = _.extend(res, self.sessAttrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
_.each(self.objects, function(o) {
|
_.each(self.objects, function(k) {
|
||||||
var obj = self.get(o);
|
var obj = self.get(k);
|
||||||
if (session || obj)
|
res[k] = (obj && obj.toJSON(session));
|
||||||
res[o] = (obj && obj.toJSON(session));
|
});
|
||||||
});
|
|
||||||
return res;
|
return res;
|
||||||
},
|
},
|
||||||
startNewSession: function() {
|
startNewSession: function() {
|
||||||
|
@ -1229,6 +1239,10 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, Backform) {
|
||||||
_.each(self.objects, function(o) {
|
_.each(self.objects, function(o) {
|
||||||
var obj = self.get(o);
|
var obj = self.get(o);
|
||||||
|
|
||||||
|
if (_.isUndefined(obj) || _.isNull(obj)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
delete self.origSessAttrs[o];
|
delete self.origSessAttrs[o];
|
||||||
|
|
||||||
if (obj && 'startNewSession' in obj && _.isFunction(obj.startNewSession)) {
|
if (obj && 'startNewSession' in obj && _.isFunction(obj.startNewSession)) {
|
||||||
|
|
|
@ -57,6 +57,7 @@ class PGChildModule:
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.min_ver = 1000000000
|
self.min_ver = 1000000000
|
||||||
self.max_ver = 0
|
self.max_ver = 0
|
||||||
|
self.server_type = None
|
||||||
self.attributes = {}
|
self.attributes = {}
|
||||||
|
|
||||||
super(PGChildModule, self).__init__(*args, **kwargs)
|
super(PGChildModule, self).__init__(*args, **kwargs)
|
||||||
|
|
|
@ -492,7 +492,11 @@ fieldset[disabled] .form-control {
|
||||||
}
|
}
|
||||||
|
|
||||||
.backgrid td.renderable:not(.editable):not(.delete-cell) {
|
.backgrid td.renderable:not(.editable):not(.delete-cell) {
|
||||||
background-color: #eee;
|
background-color: #F1F1F1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.backgrid tr.header td.renderable:not(.editable):not(.delete-cell) {
|
||||||
|
background-color: #AAA;
|
||||||
}
|
}
|
||||||
|
|
||||||
.subnode-header {
|
.subnode-header {
|
||||||
|
@ -583,3 +587,11 @@ table.backgrid tr.new {
|
||||||
.switch-cell {
|
.switch-cell {
|
||||||
height: 0px; width: 0px;
|
height: 0px; width: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.width_percent_40 {
|
||||||
|
width: 40%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.width_percent_60 {
|
||||||
|
width: 60%;
|
||||||
|
}
|
||||||
|
|
|
@ -36,7 +36,8 @@
|
||||||
var pgAdmin = (window.pgAdmin = window.pgAdmin || {});
|
var pgAdmin = (window.pgAdmin = window.pgAdmin || {});
|
||||||
|
|
||||||
pgAdmin.editableCell = function() {
|
pgAdmin.editableCell = function() {
|
||||||
if (this.attributes && this.attributes.disabled) {
|
if (this.attributes && !_.isUndefined(this.attributes.disabled) &&
|
||||||
|
!_.isNull(this.attributes.disabled)) {
|
||||||
if(_.isFunction(this.attributes.disabled)) {
|
if(_.isFunction(this.attributes.disabled)) {
|
||||||
return !(this.attributes.disabled.apply(this, arguments));
|
return !(this.attributes.disabled.apply(this, arguments));
|
||||||
}
|
}
|
||||||
|
@ -503,14 +504,19 @@
|
||||||
initialize: function() {
|
initialize: function() {
|
||||||
Backform.Control.prototype.initialize.apply(this, arguments);
|
Backform.Control.prototype.initialize.apply(this, arguments);
|
||||||
|
|
||||||
var uniqueCol = this.field.get('uniqueCol') || [];
|
var uniqueCol = this.field.get('uniqueCol') || [],
|
||||||
|
m = this.field.get('model'),
|
||||||
|
schema = m.prototype.schema || m.__super__.schema,
|
||||||
|
columns = [];
|
||||||
|
|
||||||
|
_.each(schema, function(s) {
|
||||||
|
columns.push(s.id);
|
||||||
|
});
|
||||||
|
|
||||||
var columns = this.field.get('columns')
|
|
||||||
// Check if unique columns provided are also in model attributes.
|
// Check if unique columns provided are also in model attributes.
|
||||||
if (uniqueCol.length > _.intersection(columns, uniqueCol).length){
|
if (uniqueCol.length > _.intersection(columns, uniqueCol).length){
|
||||||
errorMsg = "Developer: Unique column/s [ "+_.difference(uniqueCol, columns)+" ] not found in collection model [ " + columns +" ]."
|
errorMsg = "Developer: Unique column/s [ "+_.difference(uniqueCol, columns)+" ] not found in collection model [ " + columns +" ]."
|
||||||
alert (errorMsg);
|
alert (errorMsg);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var collection = this.model.get(this.field.get('name')),
|
var collection = this.model.get(this.field.get('name')),
|
||||||
|
@ -747,7 +753,8 @@
|
||||||
var subnode = data.subnode.schema ? data.subnode : data.subnode.prototype,
|
var subnode = data.subnode.schema ? data.subnode : data.subnode.prototype,
|
||||||
gridSchema = Backform.generateGridColumnsFromModel(
|
gridSchema = Backform.generateGridColumnsFromModel(
|
||||||
data.node_info, subnode, this.field.get('mode'), data.columns
|
data.node_info, subnode, this.field.get('mode'), data.columns
|
||||||
);
|
), self = this,
|
||||||
|
pgBrowser = window.pgAdmin.Browser;
|
||||||
|
|
||||||
// Set visibility of Add button
|
// Set visibility of Add button
|
||||||
if (data.disabled || data.canAdd == false) {
|
if (data.disabled || data.canAdd == false) {
|
||||||
|
@ -775,7 +782,17 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var collection = this.model.get(data.name);
|
var collection = self.model.get(data.name);
|
||||||
|
|
||||||
|
if (!collection) {
|
||||||
|
collection = new (pgBrowser.Node.Collection)(null, {
|
||||||
|
handler: self.model.handler || self,
|
||||||
|
model: data.model,
|
||||||
|
silent: true
|
||||||
|
});
|
||||||
|
self.model.set(data.name, collection, {silent: true});
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize a new Grid instance
|
// Initialize a new Grid instance
|
||||||
var grid = new Backgrid.Grid({
|
var grid = new Backgrid.Grid({
|
||||||
columns: gridSchema.columns,
|
columns: gridSchema.columns,
|
||||||
|
|
|
@ -119,254 +119,6 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Custom cell formatter for privileges.
|
|
||||||
*/
|
|
||||||
var PrivilegeCellFormatter = Backgrid.Extension.PrivilegeCellFormatter = function () {};
|
|
||||||
_.extend(PrivilegeCellFormatter.prototype, {
|
|
||||||
|
|
||||||
fromRaw: function (rawData, model) {
|
|
||||||
return rawData;
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/* Convert string privileges to object privileges for manipulation.
|
|
||||||
|
|
||||||
E.g C*Tc ===> {"C":{"privilege":true,
|
|
||||||
"withGrantPrivilege":true},
|
|
||||||
"T":{"privilege":true,
|
|
||||||
"withGrantPrivilege":false},
|
|
||||||
"c":{"privilege":true,
|
|
||||||
"withGrantPrivilege":false}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
fromRawToObject: function (rawData, model) {
|
|
||||||
var objData = {};
|
|
||||||
var currentChar = "";
|
|
||||||
for (var i = 0, len = rawData.length; i < len; i++) {
|
|
||||||
if (rawData[i] == "*" && currentChar != ""){
|
|
||||||
if ( _.has(objData,currentChar)){
|
|
||||||
objData[currentChar]["withGrantPrivilege"] = true;
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
currentChar = rawData[i]
|
|
||||||
objData[currentChar] = {"privilege":true,
|
|
||||||
"withGrantPrivilege":false};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return objData;
|
|
||||||
},
|
|
||||||
|
|
||||||
toRaw: function (formattedData, model) {
|
|
||||||
return formattedData;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
Custom cell editor for editing privileges.
|
|
||||||
*/
|
|
||||||
|
|
||||||
var PrivilegeCellEditor = Backgrid.Extension.PrivilegeCellEditor = Backgrid.CellEditor.extend({
|
|
||||||
tagName: "div",
|
|
||||||
template: _.template(['<tr>',
|
|
||||||
'<td class="renderable"><label><input type="checkbox" name="<%- value %>" <%= privilege ? \'checked\' : "" %>><%- name %></label></td>',
|
|
||||||
'<td class="renderable"><label><input type="checkbox" name="<%- value %>_grant" <%= withGrantPrivilege ? \'checked\' : "" %>>WITH GRANT OPTION</label></td>',
|
|
||||||
'</tr>'].join(" "), null, {variable: null}),
|
|
||||||
|
|
||||||
initialize: function() {
|
|
||||||
Backgrid.CellEditor.prototype.initialize.apply(this, arguments);
|
|
||||||
this.elId = _.uniqueId('pgPriv_');
|
|
||||||
},
|
|
||||||
setPrivilegeOptions: function (privilegeOptions){
|
|
||||||
this.privilegeOptions = privilegeOptions;
|
|
||||||
},
|
|
||||||
|
|
||||||
render: function () {
|
|
||||||
this.$el.empty();
|
|
||||||
this.$el.attr('tabindex', '1');
|
|
||||||
this.$el.attr('id', this.elId);
|
|
||||||
this.$el.attr('privilegeseditor', '1');
|
|
||||||
|
|
||||||
var privilegeOptions = _.result(this, "privilegeOptions");
|
|
||||||
var model = this.model;
|
|
||||||
var selectedValues = this.formatter.fromRawToObject(model.get(this.column.get("name")), model),
|
|
||||||
tbl = $("<table></table>").appendTo(this.$el);
|
|
||||||
|
|
||||||
if (!_.isArray(privilegeOptions)) throw new TypeError("privilegeOptions must be an array");
|
|
||||||
self = this;
|
|
||||||
// For each privilege generate html template.
|
|
||||||
_.each(privilegeOptions, function (privilegeOption){
|
|
||||||
var templateData = {name: privilegeOption['name'],
|
|
||||||
value: privilegeOption['value'],
|
|
||||||
privilege : false,
|
|
||||||
withGrantPrivilege : false
|
|
||||||
};
|
|
||||||
|
|
||||||
if ( _.has(selectedValues,privilegeOption['value'])){
|
|
||||||
_.extend(templateData,{ privilege:selectedValues[privilegeOption['value']]["privilege"],
|
|
||||||
withGrantPrivilege:selectedValues[privilegeOption['value']]["withGrantPrivilege"]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var editorHtml = self.template(templateData);
|
|
||||||
tbl.append(editorHtml);
|
|
||||||
|
|
||||||
var $prvilegeGrantCheckbox = self.$el.find("[name='" + privilegeOption['value'] + "_grant']");
|
|
||||||
|
|
||||||
// Add event listeners on each privilege checkbox. And set initial state.
|
|
||||||
// Update model if user changes value.
|
|
||||||
$prvilegeGrantCheckbox.click(function(e) {
|
|
||||||
var addRemoveflag = $(this).is(':checked');
|
|
||||||
privilege = this.name;
|
|
||||||
self.updateModel(privilege, addRemoveflag);
|
|
||||||
});
|
|
||||||
|
|
||||||
var $prvilegeCheckbox = self.$el.find("[name='" + privilegeOption['value'] + "']");
|
|
||||||
|
|
||||||
if (!$prvilegeCheckbox.is(':checked')) {
|
|
||||||
$prvilegeGrantCheckbox.attr("disabled", true);
|
|
||||||
$prvilegeGrantCheckbox.attr("checked", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
$prvilegeCheckbox.click(function(e) {
|
|
||||||
var addRemoveflag = $(this).is(':checked');
|
|
||||||
privilege = this.name;
|
|
||||||
if (addRemoveflag) {
|
|
||||||
$prvilegeGrantCheckbox.removeAttr("disabled");
|
|
||||||
} else {
|
|
||||||
$prvilegeGrantCheckbox.attr("disabled", true);
|
|
||||||
$prvilegeGrantCheckbox.attr("checked", false);
|
|
||||||
}
|
|
||||||
self.updateModel(privilege, addRemoveflag);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
self.$el.find('input[type=checkbox]').blur(self.focusLost.bind(this)).first().focus();
|
|
||||||
self.delegateEvents();
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
updateModel: function(privilege, addRemoveflag){
|
|
||||||
// Update model with new privilege string. e.g. 'C*Tc'.
|
|
||||||
var self = this,
|
|
||||||
model = self.model,
|
|
||||||
column = self.column,
|
|
||||||
newVal = "",
|
|
||||||
withGrant = false,
|
|
||||||
privilegeConst = privilege[0];
|
|
||||||
|
|
||||||
if (privilege.length > 1){
|
|
||||||
withGrant = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
oldValObj = self.formatter.fromRawToObject(model.get(self.column.get("name")), model);
|
|
||||||
|
|
||||||
if (addRemoveflag){
|
|
||||||
if (!withGrant){
|
|
||||||
oldValObj[privilegeConst] = {"privilege": true,
|
|
||||||
"withGrantPrivilege":false};
|
|
||||||
}else{
|
|
||||||
oldValObj[privilegeConst] = {"privilege": true,
|
|
||||||
"withGrantPrivilege":true}
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
if (!withGrant){
|
|
||||||
oldValObj[privilegeConst] = {"privilege": false,
|
|
||||||
"withGrantPrivilege":false};
|
|
||||||
}else{
|
|
||||||
oldValObj[privilegeConst] = {"privilege": true,
|
|
||||||
"withGrantPrivilege":false};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0, len = model.privileges.length; i < len; i++) {
|
|
||||||
if ( _.has(oldValObj, model.privileges[i])){
|
|
||||||
if(oldValObj[model.privileges[i]]["privilege"]){
|
|
||||||
newVal = newVal + model.privileges[i]
|
|
||||||
}
|
|
||||||
if(oldValObj[model.privileges[i]]["withGrantPrivilege"]){
|
|
||||||
newVal = newVal + "*"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
model.set(column.get("name"), newVal);
|
|
||||||
},
|
|
||||||
focusLost :function(e) {
|
|
||||||
setTimeout(
|
|
||||||
function() {
|
|
||||||
var lostFocus = true;
|
|
||||||
if (document.activeElement) {
|
|
||||||
lostFocus = !(
|
|
||||||
$(document.activeElement).closest(
|
|
||||||
'div[privilegeseditor=1]'
|
|
||||||
).first().attr('id') == this.$el.attr('id')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (lostFocus) {
|
|
||||||
this.model.trigger("backgrid:edited", this.model, this.column, new Backgrid.Command(e));
|
|
||||||
}
|
|
||||||
}.bind(this), 200);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var PrivilegeCell = Backgrid.Extension.PrivilegeCell = Backgrid.Cell.extend({
|
|
||||||
className: "edit-cell",
|
|
||||||
// All available privileges.
|
|
||||||
privilegeLabels: { "C": "CREATE",
|
|
||||||
"T": "TEMP",
|
|
||||||
"c": "CONNECT",
|
|
||||||
"a": "INSERT",
|
|
||||||
"r": "SELECT",
|
|
||||||
"w": "UPDATE",
|
|
||||||
"d": "DELETE",
|
|
||||||
"D": "TRUNCATE",
|
|
||||||
"x": "REFERENCES",
|
|
||||||
"t": "TRIGGER",
|
|
||||||
"U": "USAGE",
|
|
||||||
"X": "EXECUTE"
|
|
||||||
},
|
|
||||||
|
|
||||||
formatter: PrivilegeCellFormatter,
|
|
||||||
|
|
||||||
editor: PrivilegeCellEditor,
|
|
||||||
|
|
||||||
initialize: function(options) {
|
|
||||||
Backgrid.Cell.prototype.initialize.apply(this, arguments);
|
|
||||||
|
|
||||||
var privilegeOptions = [];
|
|
||||||
var privileges = this.model.privileges || [];
|
|
||||||
self = this;
|
|
||||||
// Generate array of privileges to be shown in editor.
|
|
||||||
_.each(privileges, function(privilege){
|
|
||||||
privilegeOptions.push({name:self.privilegeLabels[privilege],
|
|
||||||
value:privilege})
|
|
||||||
})
|
|
||||||
|
|
||||||
this.listenTo(this.model, "backgrid:edit", function (model, column, cell, editor) {
|
|
||||||
if (column.get("name") == this.column.get("name"))
|
|
||||||
// Set available privilege options in editor.
|
|
||||||
editor.setPrivilegeOptions(privilegeOptions);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
render: function(){
|
|
||||||
this.$el.empty();
|
|
||||||
var model = this.model;
|
|
||||||
this.$el.text(this.formatter.fromRaw(model.get(this.column.get("name")), model));
|
|
||||||
this.delegateEvents();
|
|
||||||
if (this.grabFocus)
|
|
||||||
this.$el.focus();
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
exitEditMode: function() {
|
|
||||||
Backgrid.Cell.prototype.exitEditMode.apply(this, arguments);
|
|
||||||
this.render();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var ObjectCell = Backgrid.Extension.ObjectCell = Backgrid.Cell.extend({
|
var ObjectCell = Backgrid.Extension.ObjectCell = Backgrid.Cell.extend({
|
||||||
editorOptionDefaults: {
|
editorOptionDefaults: {
|
||||||
schema: []
|
schema: []
|
||||||
|
|
Loading…
Reference in New Issue