(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', 'pgadmin.browser.node', 'pgadmin.browser.node.ui' ], function(_, $, Backbone, Backform, Backgrid, Alertify, pgAdmin, 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, pgAdmin, 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') || root.pgAdmin, pgNode = require('pgadmin.browser.node') || root.pgAdmin.Browser.Node; factory(root, _, $, Backbone, Backform, Alertify, pgAdmin, 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, pgAdmin, pgNode) { /* * cellFunction for variable control. * This function returns cell class depending on vartype. */ var cellFunction = function(model) { var self = this, name = model.get("name"), availVariables = self.get('availVariables'), variable = availVariables[name]; switch(variable && variable.vartype) { case "bool": /* * bool cell and variable can not be stateless (i.e undefined). * It should be either true or false. */ if (_.isUndefined(model.get("value"))) { model.set("value", false); } return Backgrid.Extension.SwitchCell; break; case "enum": var options = [], enumVals = variable.enumvals; _.each(enumVals, function(enumVal) { options.push([enumVal, enumVal]); }); return Backgrid.Extension.Select2Cell.extend({optionValues: options}); break; case "integer": return Backgrid.IntegerCell; break; case "real": return Backgrid.NumberCell.extend({decimals: 0}); break; case "string": return Backgrid.StringCell; break; default: return Backgrid.Cell; break; } } /** * VariableModel used to represent configuration parameters (variables tab) * for database objects. **/ var VariableModel = pgNode.VariableModel = pgNode.Model.extend({ defaults: { name: undefined, value: undefined, role: undefined, database: undefined, }, keys: ['name', 'role', 'database'], schema: [ {id: 'name', label:'Name', type:'text', editable: false, cellHeaderClasses: 'width_percent_30'}, { id: 'value', label:'Value', type: 'text', editable: true, cellFunction: cellFunction, cellHeaderClasses: 'width_percent_50' }, {id: 'database', label:'Database', type: 'text', editable: false}, {id: 'role', label:'Role', type: 'text', editable: false} ], toJSON: function() { var d = Backbone.Model.prototype.toJSON.apply(this); // Remove not defined values from model values. // i.e. // role, database if (_.isUndefined(d.database) || _.isNull(d.database)) { delete d.database; } if (_.isUndefined(d.role) || _.isNull(d.role)) { delete d.role; } return d; }, validate: function() { if (_.isUndefined(this.get('value')) || _.isNull(this.get('value')) || String(this.get('value')).replace(/^\s+|\s+$/g, '') == '') { var msg = 'Please enter some value!'; this.errorModel.set('value', msg); return msg; } else { this.errorModel.unset('value'); } return null; } }); /** * Variable Tab Control to set/update configuration values for database object. * **/ var VariableCollectionControl = Backform.VariableCollectionControl = Backform.UniqueColCollectionControl.extend({ hasDatabase: false, hasRole: false, initialize: function(opts) { var self = this, uniqueCols = ['name']; /* * Read from field schema whether user wants to use database and role * fields in Variable control. */ self.hasDatabase = opts.field.get('hasDatabase'); self.hasRole = opts.field.get('hasRole'); // Update unique coll field based on above flag status. if (self.hasDatabase) { uniqueCols.push('database') } else if (self.hasRole) { uniqueCols.push('role') } // Overriding the uniqueCol in the field if (opts && opts.field) { if (opts.field instanceof Backform.Field) { opts.field.set({ uniqueCol: uniqueCols, model: pgNode.VariableModel }, { silent: true }); } else { opts.field.extend({ uniqueCol: uniqueCols, model: pgNode.VariableModel }); } } Backform.UniqueColCollectionControl.prototype.initialize.apply( self, arguments ); self.availVariables = {}; var node = self.field.get('node').type, headerSchema = [{ id: 'name', label:'', type:'text', url: self.field.get('variable_opts') || 'vopts', control: Backform.NodeAjaxOptionsControl, cache_level: 'server', select2: { allowClear: false, width: 'style' }, availVariables: self.availVariables, node: node, first_empty: false, version_compatible: self.field.get('version_compatible'), transform: function(vars) { var self = this, opts = self.field.get('availVariables'); res = []; for (var prop in opts) { if (opts.hasOwnProperty(prop)) { delete opts[prop]; } } _.each(vars, function(v) { opts[v.name] = _.extend({}, v); res.push({ 'label': v.name, 'value': v.name }); }); return res; } }], headerDefaults = {name: null}, gridCols = ['name', 'value']; if (self.hasDatabase) { headerSchema.push({ id: 'database', label:'', type: 'text', cache_level: 'server', control: Backform.NodeListByNameControl, node: 'database', version_compatible: self.field.get('version_compatible') }); headerDefaults['database'] = null; gridCols.push('database'); } if (self.hasRole) { headerSchema.push({ id: 'role', label:'', type: 'text', cache_level: 'server', control: Backform.NodeListByNameControl, node: 'role', version_compatible: self.field.get('version_compatible') }); headerDefaults['role'] = null; gridCols.push('role'); } self.headerData = new (Backbone.Model.extend({ defaults: headerDefaults, schema: headerSchema }))({}); var headerGroups = Backform.generateViewSchema( self.field.get('node_info'), self.headerData, 'create', node, self.field.get('node_data') ), fields = []; _.each(headerGroups, function(o) { fields = fields.concat(o.fields); }); self.headerFields = new Backform.Fields(fields); self.gridSchema = Backform.generateGridColumnsFromModel( null, VariableModel, 'edit', gridCols ); // Make sure - we do have the data for variables self.getVariables(); self.controls = []; self.listenTo(self.headerData, "change", self.headerDataChanged); self.listenTo(self.headerData, "select2", self.headerDataChanged); self.listenTo(self.collection, "remove", self.onRemoveVariable); }, /* * Get the variable data for this node. */ getVariables: function() { var self = this, url = this.field.get('url'), m = self.model; if (!this.field.get('version_compatible')) return; if (url && !m.isNew()) { var node = self.field.get('node'), node_data = self.field.get('node_data'), node_info = self.field.get('node_info'), full_url = node.generate_url.apply( node, [ null, url, node_data, true, node_info ]), data, isTracking = self.collection.trackChanges; if (isTracking) { self.collection.stopSession(); } m.trigger('pgadmin-view:fetching', m, self.field); $.ajax({ async: false, url: full_url, success: function (res) { data = res.data; }, error: function() { m.trigger('pgadmin-view:fetch:error', m, self.field); } }); m.trigger('pgadmin-view:fetched', m, self.field); if (data && _.isArray(data)) { self.collection.reset(data, {silent: true}); } /* * Make sure - new data will be taken care by the session management */ if (isTracking) { self.collection.startNewSession(); } } }, generateHeader: function(data) { var header = [ '