mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Introduction of the privilege support for database object (Patch:
Murtuza Zabuawala), and Unique column control for backform (Harshal Dhumal). Also, includes some fixes for the model, & collection handling.
This commit is contained in:
@@ -1231,7 +1231,7 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, Backform) {
|
||||
|
||||
delete self.origSessAttrs[o];
|
||||
|
||||
if ('startNewSession' in obj && _.isFunction(obj.startNewSession)) {
|
||||
if (obj && 'startNewSession' in obj && _.isFunction(obj.startNewSession)) {
|
||||
obj.startNewSession();
|
||||
}
|
||||
});
|
||||
|
@@ -38,7 +38,7 @@
|
||||
pgAdmin.editableCell = function() {
|
||||
if (this.attributes && this.attributes.disabled) {
|
||||
if(_.isFunction(this.attributes.disabled)) {
|
||||
return !(this.attributes.disabled.apply(this, [arguments]));
|
||||
return !(this.attributes.disabled.apply(this, arguments));
|
||||
}
|
||||
if (_.isBoolean(this.attributes.disabled)) {
|
||||
return !this.attributes.disabled;
|
||||
@@ -66,6 +66,7 @@
|
||||
'options': ['readonly-option', 'select', Backgrid.Extension.PGSelectCell],
|
||||
'multiline': ['textarea', 'textarea', 'string'],
|
||||
'collection': ['sub-node-collection', 'sub-node-collection', 'string'],
|
||||
'uniqueColCollection': ['unique-col-collection', 'unique-col-collection', 'string'],
|
||||
'switch' : 'switch'
|
||||
};
|
||||
|
||||
@@ -154,6 +155,32 @@
|
||||
});
|
||||
};
|
||||
|
||||
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)
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
var ReadonlyOptionControl = Backform.ReadonlyOptionControl = Backform.SelectControl.extend({
|
||||
template: _.template([
|
||||
'<label class="<%=Backform.controlLabelClassName%>"><%=label%></label>',
|
||||
@@ -379,13 +406,78 @@
|
||||
var groups = Backform.generateViewSchema(node_info, m, type),
|
||||
schema = [],
|
||||
columns = [],
|
||||
tblCols = [],
|
||||
addAll = _.isUndefined(cols) || _.isNull(cols);
|
||||
func,
|
||||
idx = 0;
|
||||
|
||||
// Create another array if cols is of type object & store its keys in that array,
|
||||
// If cols is object then chances that we have custom width class attached with in.
|
||||
if(_.isObject(cols)) {
|
||||
tblCols = Object.keys(cols);
|
||||
if (_.isNull(cols) || _.isUndefined(cols)) {
|
||||
func = function(f) {
|
||||
f.cell_priority = idx;
|
||||
idx = idx + 1;
|
||||
|
||||
// We can also provide custom header cell class in schema itself,
|
||||
// But we will give priority to extraClass attached in cols
|
||||
// If headerCell property is already set by cols then skip extraClass property from schema
|
||||
if (!(f.headerCell) && f.cellHeaderClasses) {
|
||||
f.headerCell = Backgrid.Extension.CustomHeaderCell;
|
||||
}
|
||||
};
|
||||
} else if (_.isArray(cols)) {
|
||||
func = function(f) {
|
||||
f.cell_priority = _.indexOf(cols, f.name);
|
||||
|
||||
// We can also provide custom header cell class in schema itself,
|
||||
// But we will give priority to extraClass attached in cols
|
||||
// If headerCell property is already set by cols then skip extraClass property from schema
|
||||
if ((!f.headerCell) && f.cellHeaderClasses) {
|
||||
f.headerCell = Backgrid.Extension.CustomHeaderCell;
|
||||
}
|
||||
};
|
||||
} else if(_.isObject(cols)) {
|
||||
var tblCols = Object.keys(cols);
|
||||
func = function(f) {
|
||||
var val = (f.name in cols) && cols[f.name];
|
||||
|
||||
if (_.isNull(val) || _.isUndefined(val)) {
|
||||
f.cell_priority = -1;
|
||||
return;
|
||||
}
|
||||
if (_.isObject(val)) {
|
||||
if ('index' in val) {
|
||||
f.cell_priority = val['index'];
|
||||
idx = (idx > val['index']) ? idx + 1 : val['index'];
|
||||
} else {
|
||||
var i = _.indexOf(tblCols, f.name);
|
||||
f.cell_priority = idx = ((i > idx) ? i : idx);
|
||||
idx = idx + 1;
|
||||
}
|
||||
|
||||
// We can also provide custom header cell class in schema itself,
|
||||
// But we will give priority to extraClass attached in cols
|
||||
// If headerCell property is already set by cols then skip extraClass property from schema
|
||||
if (!f.headerCell) {
|
||||
if (f.cellHeaderClasses) {
|
||||
f.headerCell = Backgrid.Extension.CustomHeaderCell;
|
||||
}
|
||||
if ('class' in val && _.isString(val['class'])) {
|
||||
f.headerCell = Backgrid.Extension.CustomHeaderCell;
|
||||
f.cellHeaderClasses = (f.cellHeaderClasses || '') + ' ' + val['class'];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_.isString(val)) {
|
||||
var i = _.indexOf(tblCols, f.name);
|
||||
|
||||
f.cell_priority = idx = ((i > idx) ? i : idx);
|
||||
idx = idx + 1;
|
||||
|
||||
if (!f.headerCell) {
|
||||
f.headerCell = Backgrid.Extension.CustomHeaderCell;
|
||||
}
|
||||
f.cellHeaderClasses = (f.cellHeaderClasses || '') + ' ' + val;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Prepare columns for backgrid
|
||||
@@ -394,25 +486,9 @@
|
||||
if (!f.control && !f.cell) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check custom property in cols & if it is present then attach it to current cell
|
||||
if (tblCols.length > 0 && _.isString(cols[f.name])) {
|
||||
f.headerCell = Backgrid.Extension.CustomHeaderCell;
|
||||
f.cellHeaderClasses = cols[f.name];
|
||||
f.cell_priority = _.indexOf(tblCols, f.name);
|
||||
} else if(tblCols.length > 0) {
|
||||
f.cell_priority = _.indexOf(tblCols, f.name);
|
||||
} else {
|
||||
f.cell_priority = _.indexOf(cols, f.name);
|
||||
}
|
||||
// We can also provide custom header cell class in schema itself,
|
||||
// But we will give priority to extraClass attached in cols
|
||||
// If headerCell property is already set by cols then skip extraClass property from schema
|
||||
if (!(f.headerCell) && f.cellHeaderClasses) {
|
||||
f.headerCell = Backgrid.Extension.CustomHeaderCell;
|
||||
}
|
||||
|
||||
if (addAll || f.cell_priority != -1) {
|
||||
func(f);
|
||||
if (f.cell_priority != -1) {
|
||||
columns.push(f);
|
||||
}
|
||||
});
|
||||
@@ -426,6 +502,191 @@
|
||||
};
|
||||
};
|
||||
|
||||
var UniqueColCollectionControl = Backform.UniqueColCollectionControl = Backform.Control.extend({
|
||||
initialize: function() {
|
||||
Backform.Control.prototype.initialize.apply(this, arguments);
|
||||
|
||||
var uniqueCol = this.field.get('uniqueCol') || [];
|
||||
|
||||
var columns = this.field.get('columns')
|
||||
// Check if unique columns provided are also in model attributes.
|
||||
if (uniqueCol.length > _.intersection(columns, uniqueCol).length){
|
||||
errorMsg = "Developer: Unique column/s [ "+_.difference(uniqueCol, columns)+" ] not found in collection model [ " + columns +" ]."
|
||||
alert (errorMsg);
|
||||
return null;
|
||||
}
|
||||
|
||||
var collection = this.model.get(this.field.get('name')),
|
||||
self = this;
|
||||
if (!collection) {
|
||||
collection = new (pgAdmin.Browser.Node.Collection)(null, {
|
||||
model: self.field.get('model'),
|
||||
silent: true,
|
||||
handler: self.model.handler || self.model
|
||||
});
|
||||
self.model.set(self.field.get('name'), collection, {silent: true});
|
||||
}
|
||||
self.listenTo(collection, "add", self.collectionChanged);
|
||||
self.listenTo(collection, "change", self.collectionChanged);
|
||||
},
|
||||
collectionChanged: function(newModel, coll, op) {
|
||||
var uniqueCol = this.field.get('uniqueCol') || [],
|
||||
uniqueChangedAttr = [],
|
||||
changedAttr = newModel.changedAttributes();
|
||||
// Check if changed model attributes are also in unique columns. And then only check for uniqueness.
|
||||
if (changedAttr) {
|
||||
_.each(uniqueCol, function(col) {
|
||||
if ( _.has(changedAttr,col))
|
||||
{
|
||||
uniqueChangedAttr.push(col);
|
||||
}
|
||||
});
|
||||
if(uniqueChangedAttr.length == 0) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
var collection = this.model.get(this.field.get('name'));
|
||||
this.stopListening(collection, "change", this.collectionChanged);
|
||||
// Check if changed attribute's value of new/updated model also exist for another model in collection.
|
||||
// If duplicate value exists then set the attribute's value of new/updated model to it's previous values.
|
||||
collection.each(function(model) {
|
||||
if (newModel != model) {
|
||||
var duplicateAttrValues = []
|
||||
_.each(uniqueCol, function(attr) {
|
||||
attrValue = newModel.get(attr);
|
||||
if (!_.isUndefined(attrValue) && attrValue == model.get(attr)) {
|
||||
duplicateAttrValues.push(attrValue)
|
||||
}
|
||||
});
|
||||
if (duplicateAttrValues.length == uniqueCol.length){
|
||||
newModel.set(uniqueChangedAttr[0], newModel.previous(uniqueChangedAttr[0]), {silent: true});
|
||||
// TODO- Need to add notification in status bar for unique column.
|
||||
}
|
||||
}
|
||||
});
|
||||
this.listenTo(collection, "change", this.collectionChanged);
|
||||
},
|
||||
render: function() {
|
||||
var field = _.defaults(this.field.toJSON(), this.defaults),
|
||||
attributes = this.model.toJSON(),
|
||||
attrArr = field.name.split('.'),
|
||||
name = attrArr.shift(),
|
||||
path = attrArr.join('.'),
|
||||
rawValue = this.keyPathAccessor(attributes[name], path),
|
||||
data = _.extend(field, {
|
||||
rawValue: rawValue,
|
||||
value: this.formatter.fromRaw(rawValue, this.model),
|
||||
attributes: attributes,
|
||||
formatter: this.formatter
|
||||
}),
|
||||
evalF = function(f, m) {
|
||||
return (_.isFunction(f) ? !!f(m) : !!f);
|
||||
};
|
||||
|
||||
// Evaluate the disabled, visible, required, canAdd, & canDelete option
|
||||
_.extend(data, {
|
||||
disabled: evalF(data.disabled, this.model),
|
||||
visible: evalF(data.visible, this.model),
|
||||
required: evalF(data.required, this.model),
|
||||
canAdd: evalF(data.canAdd, this.model),
|
||||
canDelete: evalF(data.canDelete, this.model)
|
||||
});
|
||||
// Show Backgrid Control
|
||||
grid = (data.subnode == undefined) ? "" : this.showGridControl(data);
|
||||
|
||||
this.$el.html(grid).addClass(field.name);
|
||||
this.updateInvalid();
|
||||
|
||||
return this;
|
||||
},
|
||||
showGridControl: function(data) {
|
||||
var gridHeader = ["<div class='subnode-header'>",
|
||||
" <label class='control-label col-sm-4'>" + data.label + "</label>" ,
|
||||
" <button class='btn-sm btn-default add'>Add</buttton>",
|
||||
"</div>"].join("\n"),
|
||||
gridBody = $("<div class='pgadmin-control-group backgrid form-group col-xs-12 object subnode'></div>").append(gridHeader);
|
||||
|
||||
var subnode = data.subnode.schema ? data.subnode : data.subnode.prototype,
|
||||
gridSchema = Backform.generateGridColumnsFromModel(
|
||||
data.node_info, subnode, this.field.get('mode'), data.columns
|
||||
),
|
||||
self = this;
|
||||
|
||||
// Set visibility of Add button
|
||||
if (data.disabled || data.canAdd == false) {
|
||||
$(gridBody).find("button.add").remove();
|
||||
}
|
||||
|
||||
// Insert Delete Cell into Grid
|
||||
if (data.disabled == false && data.canDelete) {
|
||||
gridSchema.columns.unshift({
|
||||
name: "pg-backform-delete", label: "",
|
||||
cell: Backgrid.Extension.DeleteCell,
|
||||
editable: false, cell_priority: -1
|
||||
});
|
||||
}
|
||||
|
||||
var collection = this.model.get(data.name);
|
||||
// Initialize a new Grid instance
|
||||
var grid = new Backgrid.Grid({
|
||||
columns: gridSchema.columns,
|
||||
collection: collection,
|
||||
className: "backgrid table-bordered"
|
||||
});
|
||||
|
||||
// Render subNode grid
|
||||
subNodeGrid = grid.render().$el;
|
||||
|
||||
// Combine Edit and Delete Cell
|
||||
if (data.canDelete && data.canEdit) {
|
||||
$(subNodeGrid).find("th.pg-backform-delete").remove();
|
||||
}
|
||||
|
||||
$dialog = gridBody.append(subNodeGrid);
|
||||
|
||||
// Add button callback
|
||||
if (!(data.disabled || data.canAdd == false)) {
|
||||
$dialog.find('button.add').first().click(function(e) {
|
||||
e.preventDefault();
|
||||
var allowMultipleEmptyRows = !!self.field.get('allowMultipleEmptyRows');
|
||||
|
||||
// If allowMultipleEmptyRows is not set or is false then don't allow second new empty row.
|
||||
// There should be only one empty row.
|
||||
if (!allowMultipleEmptyRows && collection){
|
||||
var isEmpty = false;
|
||||
collection.each(function(model){
|
||||
var modelValues = [];
|
||||
_.each(model.attributes, function(val, key){
|
||||
modelValues.push(val);
|
||||
})
|
||||
if(!_.some(modelValues, _.identity)){
|
||||
isEmpty = true;
|
||||
}
|
||||
});
|
||||
if(isEmpty){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$(grid.body.$el.find($("tr.new"))).removeClass("new")
|
||||
var m = new (data.model)(null, {silent: true});
|
||||
collection.add(m);
|
||||
|
||||
var idx = collection.indexOf(m);
|
||||
newRow = grid.body.rows[idx].$el;
|
||||
newRow.addClass("new");
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
return $dialog;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
var SubNodeCollectionControl = Backform.SubNodeCollectionControl = Backform.Control.extend({
|
||||
render: function() {
|
||||
var field = _.defaults(this.field.toJSON(), this.defaults),
|
||||
@@ -461,6 +722,24 @@
|
||||
|
||||
return this;
|
||||
},
|
||||
updateInvalid: function() {
|
||||
var self = this;
|
||||
var errorModel = this.model.errorModel;
|
||||
if (!(errorModel instanceof Backbone.Model)) return this;
|
||||
|
||||
this.clearInvalid();
|
||||
|
||||
var attrArr = self.field.get('name').split('.'),
|
||||
name = attrArr.shift(),
|
||||
path = attrArr.join('.'),
|
||||
error = self.keyPathAccessor(errorModel.toJSON(), path);
|
||||
|
||||
if (_.isEmpty(error)) return;
|
||||
|
||||
self.$el.addClass(Backform.errorClassName).append(
|
||||
$("<div></div>").addClass('pgadmin-control-error-message col-xs-12 help-block').text(error)
|
||||
);
|
||||
},
|
||||
showGridControl: function(data) {
|
||||
var gridHeader = ["<div class='subnode-header'>",
|
||||
" <label class='control-label col-sm-4'>" + data.label + "</label>" ,
|
||||
@@ -499,11 +778,11 @@
|
||||
});
|
||||
}
|
||||
|
||||
var collections = this.model.get(data.name);
|
||||
var collection = this.model.get(data.name);
|
||||
// Initialize a new Grid instance
|
||||
var grid = new Backgrid.Grid({
|
||||
columns: gridSchema.columns,
|
||||
collection: collections,
|
||||
collection: collection,
|
||||
className: "backgrid table-bordered"
|
||||
});
|
||||
|
||||
@@ -522,7 +801,7 @@
|
||||
$dialog.find('button.add').click(function(e) {
|
||||
e.preventDefault();
|
||||
grid.insertRow({});
|
||||
newRow = $(grid.body.rows[collections.length - 1].$el);
|
||||
newRow = $(grid.body.rows[collection.length - 1].$el);
|
||||
newRow.attr("class", "new").click(function(e) {
|
||||
$(this).attr("class", "");
|
||||
});
|
||||
|
@@ -119,6 +119,254 @@
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
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({
|
||||
editorOptionDefaults: {
|
||||
schema: []
|
||||
|
Reference in New Issue
Block a user