diff --git a/web/package.json b/web/package.json index f50f3b42..72b9fb6e 100644 --- a/web/package.json +++ b/web/package.json @@ -4,12 +4,14 @@ "babel-loader": "~6.4.1", "babel-preset-es2015": "~6.24.0", "babel-preset-react": "~6.23.0", - "css-loader": "^0.28.4", + "cross-env": "^5.0.1", "enzyme": "~2.8.2", "enzyme-matchers": "^3.1.0", - "eslint": "^3.19.0", + "eslint": "3.19.0", "eslint-plugin-react": "^6.10.3", "extract-text-webpack-plugin": "^2.1.2", + "file-loader": "^0.11.2", + "image-webpack-loader": "^3.3.1", "jasmine-core": "~2.5.2", "jasmine-enzyme": "^3.1.0", "karma": "~1.5.0", @@ -22,38 +24,72 @@ "karma-sourcemap-loader": "~0.3.7", "karma-webpack": "~2.0.3", "node-sass": "^4.5.3", + "optimize-css-assets-webpack-plugin": "^2.0.0", "raw-loader": "^0.5.1", "react-addons-test-utils": "~15.4.2", "sass-loader": "^6.0.6", "style-loader": "^0.18.2", - "webpack": "~2.3.1" + "uglifyjs-webpack-plugin": "^0.4.6", + "url-loader": "^0.5.9", + "webpack": "^3.0.0" }, "dependencies": { + "acitree": "git+https://github.com/imsurinder90/jquery-aciTree.git#rc.7", + "alertifyjs": "^1.10.0", "axios": "^0.16.1", "babel-plugin-transform-es2015-modules-amd": "^6.24.1", "babel-polyfill": "^6.23.0", "babel-preset-es2015-without-strict": "~0.0.4", "babelify": "~7.3.0", + "backbone": "1.1.2", + "backform": "^0.2.0", + "backgrid": "^0.3.8", + "backgrid-filter": "^0.3.7", + "backgrid-select-all": "^0.3.5", + "backgrid-sizeable-columns": "^0.1.1", + "bignumber.js": "^4.0.2", + "bootstrap": "^3.3.7", + "bootstrap-datepicker": "^1.7.0", + "bootstrap-datetime-picker": "^2.4.4", + "bootstrap-switch": "3.3.2", "bowser": "1.6.1", "browserify": "~14.1.0", + "codemirror": "^5.27.2", + "css-loader": "0.14.0", + "cssnano": "^3.10.0", + "dropzone": "^5.1.1", "exports-loader": "~0.6.4", + "flotr2": "^0.1.0", + "font-awesome": "^4.7.0", + "font-mfizz": "^1.2.2", + "hard-source-webpack-plugin": "^0.4.9", "immutability-helper": "^2.2.0", - "imports-loader": "git+https://github.com/webpack-contrib/imports-loader.git#44d6f48463b256a17c1ba6fd9b5cc1449b4e379d", + "imports-loader": "^0.7.1", + "jquery": "1.11.2", + "jquery-contextmenu": "^2.5.0", + "jquery-ui": "^1.12.1", "moment": "^2.18.1", "react": "file:../web/pgadmin/static/vendor/react", "react-dom": "file:../web/pgadmin/static/vendor/react-dom", "react-split-pane": "^0.1.63", "requirejs": "~2.3.3", + "select2": "^4.0.3", + "shim-loader": "^1.0.1", "slickgrid": "git+https://github.com/6pac/SlickGrid.git#2.3.7", - "underscore": "~1.8.3", - "watchify": "~3.9.0" + "snapsvg": "^0.5.1", + "underscore": "^1.8.3", + "underscore.string": "^3.3.4", + "watchify": "~3.9.0", + "webcabin-docker": "^2.2.2" }, "scripts": { "linter": "yarn run eslint pgadmin/static/jsx/**/*.jsx pgadmin/static/js/selection/*.js regression/javascript/**/*.jsx regression/javascript/**/*.js *.js", "webpacker": "yarn run webpack -- --config webpack.config.js", "webpacker:dev": "yarn run webpack -- --config webpack.config.js", + "webpacker:prod": "yarn run linter && yarn run webpack -- --config webpack.config.js", "bundle": "yarn run linter && yarn run webpacker", "bundle:dev": "yarn run linter && yarn run webpacker:dev", + "bundle:prod": "cross-env NODE_ENV=production yarn run webpacker:prod", "test:karma-once": "yarn run linter && yarn run karma start -- --single-run", "test:karma": "yarn run linter && yarn run karma start", "test:feature": "yarn run bundle && python regression/runtests.py --pkg feature_tests", diff --git a/web/pgadmin/about/__init__.py b/web/pgadmin/about/__init__.py index 4d4006ab..f54418dd 100644 --- a/web/pgadmin/about/__init__.py +++ b/web/pgadmin/about/__init__.py @@ -47,6 +47,8 @@ class AboutModule(PgAdminModule): 'when': None }] + def get_exposed_url_endpoints(self): + return ['about.index'] blueprint = AboutModule(MODULE_NAME, __name__, static_url_path='') @@ -55,7 +57,7 @@ blueprint = AboutModule(MODULE_NAME, __name__, ########################################################################## # A test page ########################################################################## -@blueprint.route("/") +@blueprint.route("/", endpoint='index') @login_required def index(): """Render the about box.""" diff --git a/web/pgadmin/about/templates/about/about.js b/web/pgadmin/about/templates/about/about.js index 662469a1..a746d0f5 100644 --- a/web/pgadmin/about/templates/about/about.js +++ b/web/pgadmin/about/templates/about/about.js @@ -1,6 +1,8 @@ define( - ['jquery', 'alertify', 'pgadmin', 'sources/gettext'], - function($, alertify, pgAdmin, gettext) { + ['jquery', 'alertify', 'pgadmin', 'underscore.string', 'sources/gettext', + 'sources/url_for' + ], + function($, alertify, pgAdmin, S, gettext, url_for) { pgAdmin = pgAdmin || window.pgAdmin || {}; /* Return back, this has been called more than once */ @@ -39,9 +41,11 @@ define( } var content = ''; - $.get("{{ url_for('about.index') }}", + $.get(url_for('about.index'), function(data) { - alertify.aboutDialog(gettext("About %(appname)s", {appname: "{{ config.APP_NAME }}"}), data).resizeTo(800, 450); + alertify.aboutDialog( + S(gettext("About %s")).sprintf(pgAdmin.Browser.utils.app_name).value(), data + ).resizeTo(800, 450); }); } }; diff --git a/web/pgadmin/browser/__init__.py b/web/pgadmin/browser/__init__.py index 77e052f0..6ae14b44 100644 --- a/web/pgadmin/browser/__init__.py +++ b/web/pgadmin/browser/__init__.py @@ -523,9 +523,9 @@ def index(): return response -@blueprint.route("/js/browser.js") +@blueprint.route("/js/utils.js") @login_required -def browser_js(): +def utils(): layout = get_setting('Browser/Layout', default='') snippets = [] @@ -559,7 +559,7 @@ def browser_js(): snippets.extend(submodule.jssnippets) return make_response( render_template( - 'browser/js/browser.js', + 'browser/js/utils.js', layout=layout, jssnippets=snippets, pg_help_path=pg_help_path, @@ -569,7 +569,7 @@ def browser_js(): editor_wrap_code=editor_wrap_code, editor_brace_matching=brace_matching, editor_insert_pair_brackets=insert_pair_brackets, - _=gettext + app_name=config.APP_NAME ), 200, {'Content-Type': 'application/x-javascript'}) diff --git a/web/pgadmin/browser/server_groups/servers/databases/languages/static/js/language.js b/web/pgadmin/browser/server_groups/servers/databases/languages/static/js/language.js index 9b8aad36..835d7498 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/languages/static/js/language.js +++ b/web/pgadmin/browser/server_groups/servers/databases/languages/static/js/language.js @@ -217,7 +217,7 @@ define('pgadmin.node.language', [ } return true; } - }, pgBrowser.SecurityGroupUnderSchema, { + }, { id: 'lanacl', label: gettext('Privileges'), type: 'collection', group: 'security', control: 'unique-col-collection', mode: ['edit', 'create'], model: pgBrowser.Node.PrivilegeRoleModel.extend({ diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/collations/static/js/collation.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/collations/static/js/collation.js index ad85caa4..d0784ba7 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/collations/static/js/collation.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/collations/static/js/collation.js @@ -237,8 +237,8 @@ define('pgadmin.node.collation', [ if ('coll-collation' == d._type) { //Check if we are not child of catalog - prev_i = t.hasParent(i) ? t.parent(i) : null; - prev_d = prev_i ? t.itemData(prev_i) : null; + var prev_i = t.hasParent(i) ? t.parent(i) : null, + prev_d = prev_i ? t.itemData(prev_i) : null; if( prev_d._type == 'catalog') { return false; } else { diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/static/js/domain.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/static/js/domain.js index 03fcb5dd..af249006 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/static/js/domain.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/static/js/domain.js @@ -306,8 +306,8 @@ define('pgadmin.node.domain', [ if ('coll-domain' == d._type) { //Check if we are not child of catalog - prev_i = t.hasParent(i) ? t.parent(i) : null; - prev_d = prev_i ? t.itemData(prev_i) : null; + var prev_i = t.hasParent(i) ? t.parent(i) : null, + prev_d = prev_i ? t.itemData(prev_i) : null; if( prev_d._type == 'catalog') { return false; } else { diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/static/js/foreign-table.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/static/js/foreign-table.js index b95bce21..8796c781 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/static/js/foreign-table.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/static/js/foreign-table.js @@ -25,9 +25,9 @@ define('pgadmin.node.foreign-table', [ this.$el.empty(); var model = this.model; var column = this.column; - editable = this.column.get("editable"); + var editable = this.column.get("editable"); + var is_editable = _.isFunction(editable) ? !!editable.apply(column, [model]) : !!editable; - is_editable = _.isFunction(editable) ? !!editable.apply(column, [model]) : !!editable; if (is_editable){ this.$el.addClass("editable"); } else { this.$el.removeClass("editable"); } @@ -364,7 +364,7 @@ define('pgadmin.node.foreign-table', [ cache_node = (cache_node && pgBrowser.Nodes['cache_node']) || node; m.trigger('pgadmin:view:fetching', m, self.field); - data = {attrelid: table_id} + var data = {attrelid: table_id} // Fetching Columns data for the selected table. $.ajax({ @@ -591,8 +591,8 @@ define('pgadmin.node.foreign-table', [ 'cache_level': 'database', transform: function(d, self){ if (this.field.get('mode') == 'edit') { - oid = this.model.get('oid'); - s = _.findWhere(d, {'id': oid}); + var oid = this.model.get('oid'); + var s = _.findWhere(d, {'id': oid}); if (s) { d = _.reject(d, s); } @@ -697,8 +697,8 @@ define('pgadmin.node.foreign-table', [ if ('coll-foreign-table' == d._type) { //Check if we are not child of catalog - prev_i = t.hasParent(i) ? t.parent(i) : null; - prev_d = prev_i ? t.itemData(prev_i) : null; + var prev_i = t.hasParent(i) ? t.parent(i) : null, + prev_d = prev_i ? t.itemData(prev_i) : null; if( prev_d._type == 'catalog') { return false; } else { diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_configurations/static/js/fts_configuration.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_configurations/static/js/fts_configuration.js index 996d1f38..a7d36f42 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_configurations/static/js/fts_configuration.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_configurations/static/js/fts_configuration.js @@ -14,7 +14,7 @@ define('pgadmin.node.fts_configuration', [ // Define the schema for the token/dictionary list schema: [{ id: 'token', label:'Token', type:'text', group: null, - cellHeaderClasses:'width_percent_50', editable: true, + cellHeaderClasses:'width_percent_50', editable: false, cell: 'string', url: 'tokens' },{ id: 'dictname', label: 'Dictionaries', type: 'text', group:null, @@ -57,6 +57,7 @@ define('pgadmin.node.fts_configuration', [ this, arguments ); + var that; var self = that = this, node = 'fts_configuration', headerSchema = [{ @@ -134,7 +135,7 @@ define('pgadmin.node.fts_configuration', [ /* * Transform the data */ - transform = (this.field.get('transform') + var transform = (this.field.get('transform') || self.defaults.transform); if (transform && _.isFunction(transform)) { self.field.set('options', transform.bind(self, data)); @@ -338,7 +339,7 @@ define('pgadmin.node.fts_configuration', [ // Find if token exists in grid self.collection.each(function(m) { _.each(checkVars, function(v) { - val = m.get(v); + var val = m.get(v); if(val == token) { idx = coll.indexOf(m); } @@ -592,8 +593,8 @@ define('pgadmin.node.fts_configuration', [ if ('coll-fts_configuration' == d._type) { //Check if we are not child of catalog - prev_i = t.hasParent(i) ? t.parent(i) : null; - prev_d = prev_i ? t.itemData(prev_i) : null; + var prev_i = t.hasParent(i) ? t.parent(i) : null, + prev_d = prev_i ? t.itemData(prev_i) : null; if( prev_d._type == 'catalog') { return false; } else { diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_dictionaries/static/js/fts_dictionary.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_dictionaries/static/js/fts_dictionary.js index bdfddbd4..9f799dd4 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_dictionaries/static/js/fts_dictionary.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_dictionaries/static/js/fts_dictionary.js @@ -197,8 +197,8 @@ define('pgadmin.node.fts_dictionary', [ if ('coll-fts_dictionary' == d._type) { //Check if we are not child of catalog - prev_i = t.hasParent(i) ? t.parent(i) : null; - prev_d = prev_i ? t.itemData(prev_i) : null; + var prev_i = t.hasParent(i) ? t.parent(i) : null, + prev_d = prev_i ? t.itemData(prev_i) : null; if( prev_d._type == 'catalog') { return false; } else { diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_parser/static/js/fts_parser.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_parser/static/js/fts_parser.js index 289f8af1..d1614027 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_parser/static/js/fts_parser.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_parser/static/js/fts_parser.js @@ -112,7 +112,6 @@ define('pgadmin.node.fts_parser', [ type: 'text', disabled: function(m) { return !m.isNew(); }, control: 'node-ajax-options', url: 'end_functions', group: gettext('Definition'), cache_level: 'database', - cache_node: 'schema', cache_node: 'schema' },{ id: 'prslextype', label: gettext('Lextypes function'), @@ -214,8 +213,8 @@ define('pgadmin.node.fts_parser', [ if ('coll-fts_parser' == d._type) { //Check if we are not child of catalog - prev_i = t.hasParent(i) ? t.parent(i) : null; - prev_d = prev_i ? t.itemData(prev_i) : null; + var prev_i = t.hasParent(i) ? t.parent(i) : null, + prev_d = prev_i ? t.itemData(prev_i) : null; if( prev_d._type == 'catalog') { return false; } else { diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_templates/static/js/fts_template.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_templates/static/js/fts_template.js index d6acd1c0..b97a4db2 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_templates/static/js/fts_template.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_templates/static/js/fts_template.js @@ -153,8 +153,8 @@ define('pgadmin.node.fts_template', [ if ('coll-fts_template' == d._type) { //Check if we are not child of catalog - prev_i = t.hasParent(i) ? t.parent(i) : null; - prev_d = prev_i ? t.itemData(prev_i) : null; + var prev_i = t.hasParent(i) ? t.parent(i) : null, + prev_d = prev_i ? t.itemData(prev_i) : null; if( prev_d._type == 'catalog') { return false; } else { diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.js index 8e102cc0..416504ae 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.js @@ -34,7 +34,7 @@ define('pgadmin.node.function', [ 'node-ajax-options', cellHeaderClasses: 'width_percent_30', control: 'node-ajax-options', type: 'text', url: 'get_types', editable: function(m) { - node_info = this.get('node_info'); + var node_info = this.get('node_info'); if(node_info && 'catalog' in node_info) { return false; } @@ -49,7 +49,7 @@ define('pgadmin.node.function', [ {'label': 'INOUT', 'value': 'INOUT'}, {'label': 'VARIADIC', 'value': 'VARIADIC'} ], editable: function(m) { - node_info = this.get('node_info'); + var node_info = this.get('node_info'); if(node_info && 'catalog' in node_info) { return false; } @@ -65,7 +65,7 @@ define('pgadmin.node.function', [ ], toJSON: Backbone.Model.prototype.toJSON, isInCatalog: function(m){ - node_info = this.get('node_info'); + var node_info = this.get('node_info'); if(node_info && 'catalog' in node_info) { return false; } @@ -131,7 +131,7 @@ define('pgadmin.node.function', [ var isNew = (_.size(attrs) === 0); if (isNew) { // Set Selected Schema - schema_id = args.node_info.schema._id + var schema_id = args.node_info.schema._id; this.set({'pronamespace': schema_id}, {silent: true}); // Set Current User @@ -217,7 +217,7 @@ define('pgadmin.node.function', [ mode: ['create'], visible: 'isVisible' },{ id: 'prorettypename', label: gettext('Return type'), cell: 'string', - type: 'text', group: gettext('Definition'), disabled: true, + type: 'text', group: gettext('Definition'), mode: ['properties', 'edit'], disabled: 'isDisabled', visible: 'isVisible' }, { id: 'lanname', label: gettext('Language'), cell: 'string', @@ -457,8 +457,8 @@ define('pgadmin.node.function', [ if ('coll-function' == d._type) { //Check if we are not child of catalog - prev_i = t.hasParent(i) ? t.parent(i) : null; - prev_d = prev_i ? t.itemData(prev_i) : null; + var prev_i = t.hasParent(i) ? t.parent(i) : null, + prev_d = prev_i ? t.itemData(prev_i) : null; if( prev_d._type == 'catalog') { return false; } else { diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/procedure.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/procedure.js index 904adc49..89a1fe31 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/procedure.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/procedure.js @@ -17,7 +17,7 @@ define('pgadmin.node.procedure', [ }); }; - pgSchemaNode = pgBrowser.Nodes['schema']; + var pgSchemaNode = pgBrowser.Nodes['schema']; // Inherit Functions Node if (!pgBrowser.Nodes['procedure']) { diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/trigger_function.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/trigger_function.js index 069a2675..c6c9d2f9 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/trigger_function.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/trigger_function.js @@ -64,7 +64,7 @@ define('pgadmin.node.trigger_function', [ var isNew = (_.size(attrs) === 0); if (isNew) { // Set Selected Schema - schema_id = args.node_info.schema._id + var schema_id = args.node_info.schema._id this.set({'pronamespace': schema_id}, {silent: true}); // Set Current User @@ -153,7 +153,7 @@ define('pgadmin.node.trigger_function', [ ] },{ id: 'prorettypename', label: gettext('Return type'), cell: 'string', - type: 'text', group: gettext('Definition'), disabled: true, + type: 'text', group: gettext('Definition'), mode: ['properties', 'edit'], disabled: 'isDisabled', visible: 'isVisible' }, { id: 'lanname', label: gettext('Language'), cell: 'string', @@ -378,8 +378,8 @@ define('pgadmin.node.trigger_function', [ if ('coll-trigger_function' == d._type) { //Check if we are not child of catalog - prev_i = t.hasParent(i) ? t.parent(i) : null; - prev_d = prev_i ? t.itemData(prev_i) : null; + var prev_i = t.hasParent(i) ? t.parent(i) : null, + prev_d = prev_i ? t.itemData(prev_i) : null; if( prev_d._type == 'catalog') { return false; } else { diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/static/js/sequence.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/static/js/sequence.js index a84fb88e..36111610 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/static/js/sequence.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/static/js/sequence.js @@ -74,8 +74,8 @@ define('pgadmin.node.sequence', [ if ('coll-sequence' == d._type) { //Check if we are not child of catalog - prev_i = t.hasParent(i) ? t.parent(i) : null; - prev_d = prev_i ? t.itemData(prev_i) : null; + var prev_i = t.hasParent(i) ? t.parent(i) : null, + prev_d = prev_i ? t.itemData(prev_i) : null; if( prev_d._type == 'catalog') { return false; } else { @@ -202,7 +202,7 @@ define('pgadmin.node.sequence', [ validate: function() { var msg = undefined, minimum = this.get('minimum'), - maximum = this.get('maximum'); + maximum = this.get('maximum'), start = this.get('start'); if (_.isUndefined(this.get('name')) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/schema.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/schema.js index ef496e73..07d97a22 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/schema.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/schema.js @@ -13,7 +13,7 @@ define('pgadmin.node.schema', [ initialize: function() { Backform.Control.prototype.initialize.apply(this, arguments); var self = this, - m = this.model; + m = this.model, url = self.field.get('url'); if (url && m.isNew()) { @@ -457,9 +457,9 @@ define('pgadmin.node.schema', [ return true; //Check if we are not child of catalog - prev_i = t.hasParent(i) ? t.parent(i) : null; + var prev_i = t.hasParent(i) ? t.parent(i) : null, prev_d = prev_i ? t.itemData(prev_i) : null; - if( prev_d && prev_d._type == 'catalog') { + if(prev_d && prev_d._type == 'catalog') { return false; } i = t.hasParent(i) ? t.parent(i) : null; @@ -476,7 +476,7 @@ define('pgadmin.node.schema', [ t = pgBrowser.tree; do { - d = t.itemData(i); + var d = t.itemData(i); if ( d._type in pgBrowser.Nodes && pgBrowser.Nodes[d._type].hasId ) { @@ -509,7 +509,8 @@ define('pgadmin.node.schema', [ column = this.column, editable = this.column.get("editable"), input = this.$el.find('input[type=checkbox]').first(), - self_name = column.get('name'); + self_name = column.get('name'), + is_editable; is_editable = _.isFunction(editable) ? !!editable.apply(column, [model]) : !!editable; if (is_editable) { diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/check_constraint/templates/check_constraint/js/check_constraint.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/check_constraint/templates/check_constraint/js/check_constraint.js index 85f62f71..bd31d141 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/check_constraint/templates/check_constraint/js/check_constraint.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/check_constraint/templates/check_constraint/js/check_constraint.js @@ -51,7 +51,7 @@ define('pgadmin.node.check_constraints', [ }, callbacks: { validate_check_constraint: function(args) { - var input = args || {}; + var input = args || {}, obj = this, t = pgBrowser.tree, i = input.item || t.selected(), diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/templates/exclusion_constraint/js/exclusion_constraint.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/templates/exclusion_constraint/js/exclusion_constraint.js index 605495d7..065b6096 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/templates/exclusion_constraint/js/exclusion_constraint.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/templates/exclusion_constraint/js/exclusion_constraint.js @@ -286,7 +286,7 @@ define('pgadmin.node.exclusion_constraint', [ }, remove: function () { if(self.model.handler) { - tableCols = self.model.top.get('columns'); + var tableCols = self.model.top.get('columns'); this.stopListening(tableCols, 'remove' , this.removeColumn); this.stopListening(tableCols, 'change:name' , this.resetColOptions); this.stopListening(tableCols, 'change:cltype' , this.resetColOptions); @@ -561,7 +561,7 @@ define('pgadmin.node.exclusion_constraint', [ newRow.addClass("new"); $(newRow).pgMakeVisible('backform-tab'); } else { - delete m; + //delete m; } return false; @@ -770,7 +770,7 @@ define('pgadmin.node.exclusion_constraint', [ } },{ id: 'columns', label: gettext('Columns'), - type: 'collection', group: gettext('Columns'), disabled: false, + type: 'collection', group: gettext('Columns'), deps:['amname'], canDelete: true, editable: false, canAdd: function(m) { // We can't update columns of existing exclusion constraint. @@ -815,7 +815,7 @@ define('pgadmin.node.exclusion_constraint', [ }, 10); setTimeout(function () { - constraints = self.model.top.get("exclude_constraint"); + var constraints = self.model.top.get("exclude_constraint"); var removed = []; constraints.each(function(constraint) { if (constraint.get("columns").length == 0) { @@ -837,7 +837,7 @@ define('pgadmin.node.exclusion_constraint', [ }, 10); setTimeout(function () { - constraints = self.model.top.get("exclude_constraint"); + var constraints = self.model.top.get("exclude_constraint"); var removed = []; constraints.each(function(constraint) { if (constraint.get("columns").length == 0) { diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/templates/foreign_key/js/foreign_key.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/templates/foreign_key/js/foreign_key.js index a4bec09d..7d742632 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/templates/foreign_key/js/foreign_key.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/templates/foreign_key/js/foreign_key.js @@ -225,7 +225,7 @@ define('pgadmin.node.foreign_key', [ /* * Transform the data */ - transform = this.field.get('transform') || self.defaults.transform; + var transform = this.field.get('transform') || self.defaults.transform; if (transform && _.isFunction(transform)) { // We will transform the data later, when rendering. // It will allow us to generate different data based on the @@ -494,7 +494,7 @@ define('pgadmin.node.foreign_key', [ newRow.addClass("new"); $(newRow).pgMakeVisible('backform-tab'); } else { - delete m; + //delete m; } return false; @@ -534,7 +534,7 @@ define('pgadmin.node.foreign_key', [ var self = this, url = 'get_coveringindex', - m = self.model + m = self.model, cols = [], coveringindex = null; @@ -610,7 +610,6 @@ define('pgadmin.node.foreign_key', [ sqlCreateHelp: 'ddl-constraints.html', dialogHelp: url_for('help.static', {'filename': 'foreign_key_dialog.html'}), hasSQL: true, - hasDepends: false, parent_type: ['table','partition'], canDrop: true, canDropCascade: true, @@ -641,7 +640,7 @@ define('pgadmin.node.foreign_key', [ }, callbacks: { validate_foreign_key: function(args) { - var input = args || {}; + var input = args || {}, obj = this, t = pgBrowser.tree, i = input.item || t.selected(), @@ -926,7 +925,7 @@ define('pgadmin.node.foreign_key', [ }, 10); setTimeout(function () { - constraints = self.model.top.get("foreign_key"); + var constraints = self.model.top.get("foreign_key"); var removed = []; constraints.each(function(constraint) { if (constraint.get("columns").length == 0) { diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/primary_key.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/primary_key.js new file mode 100644 index 00000000..f588b8f4 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/primary_key.js @@ -0,0 +1,539 @@ +define('pgadmin.node.primary_key', [ + 'sources/gettext', 'sources/url_for', 'jquery', 'underscore', 'underscore.string', 'pgadmin', + 'pgadmin.browser', 'alertify', 'pgadmin.browser.collection' +], function(gettext, url_for, $, _, S, pgAdmin, pgBrowser, alertify) { + + // Extend the browser's node class for index constraint node + if (!pgBrowser.Nodes['primary_key']) { + pgAdmin.Browser.Nodes['primary_key'] = pgBrowser.Node.extend({ + type: 'primary_key', + label: gettext('Primary key'), + collection_type: 'coll-constraints', + sqlAlterHelp: 'ddl-alter.html', + sqlCreateHelp: 'ddl-constraints.html', + dialogHelp: url_for('help.static', {filename: 'primary_key_dialog.html'}), + hasSQL: true, + hasDepends: true, + hasStatistics: true, + statsPrettifyFields: ['Index size'], + parent_type: 'table', + canDrop: true, + canDropCascade: true, + Init: function() { + /* Avoid multiple registration of menus */ + if (this.initialized) + return; + + this.initialized = true; + + pgBrowser.add_menus([{ + name: 'create_primary_key_on_coll', node: 'coll-constraints', module: this, + applies: ['object', 'context'], callback: 'show_obj_properties', + category: 'create', priority: 4, label: gettext('Primary key'), + icon: 'wcTabIcon icon-primary_key', data: {action: 'create', check: true}, + enable: 'canCreate' + + } + ]); + }, + canCreate: function(itemData, item, data) { + // If check is false then , we will allow create menu + if (data && data.check == false) + return true; + + var t = pgBrowser.tree, i = item, d = itemData, parents = []; + // To iterate over tree to check parent node + while (i) { + // If it is schema then allow user to c reate table + if (_.indexOf(['schema'], d._type) > -1) { + // There should be only one primary key per table. + var children = t.children(arguments[1], false), + primary_key_found = false; + + _.each(children, function(child){ + data = pgBrowser.tree.itemData($(child)); + if (!primary_key_found && data._type == "primary_key") { + primary_key_found = true; + } + }); + return !primary_key_found; + } + parents.push(d._type); + i = t.hasParent(i) ? t.parent(i) : null; + d = i ? t.itemData(i) : null; + } + // If node is under catalog then do not allow 'create' menu + if (_.indexOf(parents, 'catalog') > -1) { + return false; + } else { + return true; + } + }, + + // Define the model for index constraint node + model: pgAdmin.Browser.Node.Model.extend({ + idAttribute: 'oid', + + defaults: { + name: undefined, + oid: undefined, + comment: undefined, + spcname: undefined, + index: undefined, + fillfactor: undefined, + condeferrable: undefined, + condeferred: undefined, + columns: [] + }, + + // Define the schema for the index constraint node + schema: [{ + id: 'name', label: gettext('Name'), type: 'text', + mode: ['properties', 'create', 'edit'], editable:true, + cellHeaderClasses:'width_percent_40', + },{ + id: 'oid', label: gettext('OID'), cell: 'string', + type: 'text' , mode: ['properties'], editable: false, + cellHeaderClasses:'width_percent_20', + },{ + id: 'comment', label: gettext('Comment'), cell: 'string', + type: 'multiline', mode: ['properties', 'create', 'edit'], + deps:['name'], disabled:function(m) { + var name = m.get('name'); + if (!(name && name != '')) { + setTimeout(function(){ + if(m.get('comment') && m.get('comment') !== '') { + m.set('comment', null); + } + },10); + return true; + } else { + return false; + } + } + },{ + id: 'columns', label: gettext('Columns'), + type: 'collection', group: gettext('Definition'), + editable: false, + cell: Backgrid.StringCell.extend({ + initialize: function() { + Backgrid.StringCell.prototype.initialize.apply(this, arguments); + + var self = this, + collection = this.model.get('columns'); + + // Do not listen for any event(s) for existing constraint. + if (_.isUndefined(self.model.get('oid'))) { + var tableCols = self.model.top.get('columns'); + self.listenTo(tableCols, 'remove' , self.removeColumn); + self.listenTo(tableCols, 'change:name', self.resetColOptions); + } + + collection.on('pgadmin:multicolumn:updated', function() { + self.render.apply(self); + }); + self.listenTo(collection, "add", self.render); + self.listenTo(collection, "remove", self.render); + }, + removeColumn: function(m) { + var self = this, + removedCols = self.model.get('columns').where( + {column: m.get('name')} + ); + + self.model.get('columns').remove(removedCols); + setTimeout(function () { + self.render(); + }, 10); + + var key = 'primary_key' + setTimeout(function () { + constraints = self.model.top.get(key); + var removed = []; + constraints.each(function(constraint) { + if (constraint.get("columns").length == 0) { + removed.push(constraint); + } + }); + constraints.remove(removed); + },100); + + }, + resetColOptions : function(m) { + var self = this, + updatedCols = self.model.get('columns').where( + {column: m.previous('name')} + ); + if (updatedCols.length > 0) { + /* + * Table column name has changed so update + * column name in primary key as well. + */ + updatedCols[0].set( + {"column": m.get('name')}, + {silent: true}); + } + + setTimeout(function () { + self.render(); + }, 10); + }, + formatter: { + fromRaw: function (rawValue, model) { + return rawValue.pluck("column").toString(); + }, + toRaw: function (val, model) { + return val; + } + }, + render: function() { + return Backgrid.StringCell.prototype.render.apply(this, arguments); + }, + remove: function() { + var tableCols = this.model.top.get('columns'), + primary_key_col = this.model.get('columns'); + + if (primary_key_col) { + primary_key_col.off('pgadmin:multicolumn:updated'); + } + + this.stopListening(tableCols, 'remove' , self.removeColumn); + this.stopListening(tableCols, 'change:name' , self.resetColOptions); + + Backgrid.StringCell.prototype.remove.apply(this, arguments); + } + }), + canDelete: true, canAdd: true, + control: Backform.MultiSelectAjaxControl.extend({ + defaults: _.extend( + {}, + Backform.NodeListByNameControl.prototype.defaults, + { + select2: { + multiple: true, + allowClear: true, + width: 'style', + placeholder: gettext('Select the column(s)'), + } + } + ), + keyPathAccessor: function(obj, path) { + var res = obj; + if(_.isArray(res)) { + return _.map(res, function(o) { return o['column'] + }); + } + path = path.split('.'); + for (var i = 0; i < path.length; i++) { + if (_.isNull(res)) return null; + if (_.isEmpty(path[i])) continue; + if (!_.isUndefined(res[path[i]])) res = res[path[i]]; + } + return _.isObject(res) && !_.isArray(res) ? null : res; + }, + initialize: function() { + // Here we will decide if we need to call URL + // Or fetch the data from parent columns collection + var self = this; + if(this.model.handler) { + Backform.Select2Control.prototype.initialize.apply(this, arguments); + // Do not listen for any event(s) for existing constraint. + if (_.isUndefined(self.model.get('oid'))) { + var tableCols = self.model.top.get('columns'); + self.listenTo(tableCols, 'remove' , self.resetColOptions); + self.listenTo(tableCols, 'change:name', self.resetColOptions); + } + + self.custom_options(); + } else { + Backform.MultiSelectAjaxControl.prototype.initialize.apply(this, arguments); + } + self.model.get('columns').on('pgadmin:multicolumn:updated', function() { + self.render.apply(self); + }); + }, + resetColOptions: function(m) { + var self = this; + + setTimeout(function () { + self.custom_options(); + self.render.apply(self); + }, 50); + + }, + custom_options: function() { + // We will add all the columns entered by user in table model + var columns = this.model.top.get('columns'), + added_columns_from_tables = []; + + if (columns.length > 0) { + _.each(columns.models, function(m) { + var col = m.get('name'); + if(!_.isUndefined(col) && !_.isNull(col)) { + added_columns_from_tables.push( + {label: col, value: col, image:'icon-column'} + ); + } + }); + } + // Set the values in to options so that user can select + this.field.set('options', added_columns_from_tables); + }, + onChange: function(e) { + var self = this, + model = this.model, + $el = $(e.target), + attrArr = this.field.get("name").split('.'), + name = attrArr.shift(), + path = attrArr.join('.'), + vals = this.getValueFromDOM(), + collection = model.get(name), + removed = []; + + this.stopListening(this.model, "change:" + name, this.render); + + /* + * Iterate through all the values, and find out how many are already + * present in the collection. + */ + collection.each(function(m) { + var column = m.get('column'), + idx = _.indexOf(vals, column); + + if (idx > -1) { + vals.splice(idx, 1); + } else { + removed.push(column); + } + }); + + /* + * Adding new values + */ + + _.each(vals, function(v) { + var m = new (self.field.get('model'))( + {column: v}, { silent: true, + top: self.model.top, + collection: collection, + handler: collection + }); + + collection.add(m); + }); + + /* + * Removing unwanted! + */ + _.each(removed, function(v) { + collection.remove(collection.where({column: v})); + }); + + this.listenTo(this.model, "change:" + name, this.render); + }, + remove: function() { + if(this.model.handler) { + var self = this, + tableCols = self.model.top.get('columns'); + self.stopListening(tableCols, 'remove' , self.resetColOptions); + self.stopListening(tableCols, 'change:name' , self.resetColOptions); + self.model.get('columns').off('pgadmin:multicolumn:updated'); + + Backform.Select2Control.prototype.remove.apply(this, arguments); + + } else { + Backform.MultiSelectAjaxControl.prototype.remove.apply(this, arguments); + } + } + }), + deps: ['index'], node: 'column', + model: pgBrowser.Node.Model.extend({ + defaults: { + column: undefined + }, + validate: function() { + return null; + } + }), + transform : function(data){ + var res = []; + if (data && _.isArray(data)) { + _.each(data, function(d) { + res.push({label: d.label, value: d.label, image:'icon-column'}); + }) + } + return res; + }, + select2:{allowClear:false}, + disabled: function(m) { + // If we are in table edit mode then + if (_.has(m, 'top') && !_.isUndefined(m.top) + && !m.top.isNew()) { + // If OID is undefined then user is trying to add + // new constraint which should be allowed for Unique + return !_.isUndefined(m.get('oid')); + } + + // We can't update columns of existing index constraint. + if (!m.isNew()) { + return true; + } + // Disable if index is selected. + var index = m.get('index'); + if(_.isUndefined(index) || index == '') { + return false; + } else { + var col = m.get('columns'); + col.reset(); + return true; + } + } + },{ + id: 'spcname', label: gettext('Tablespace'), + type: 'text', group: gettext('Definition'), + control: 'node-list-by-name', node: 'tablespace', + deps: ['index'], + select2:{allowClear:false}, + filter: function(m) { + // Don't show pg_global tablespace in selection. + if (m.label == "pg_global") return false; + else return true; + }, + disabled: function(m) { + // Disable if index is selected. + m = m.top || m; + var index = m.get('index'); + if(_.isUndefined(index) || index == '') { + return false; + } else { + setTimeout(function(){ + m.set('spcname', ''); + },10); + return true; + } + } + },{ + id: 'index', label: gettext('Index'), + type: 'text', group: gettext('Definition'), + control: Backform.NodeListByNameControl.extend({ + initialize:function() { + if (_.isUndefined(this.model.top)) { + Backform.NodeListByNameControl.prototype.initialize.apply(this,arguments); + } else { + Backform.Control.prototype.initialize.apply(this,arguments); + } + } + }), + select2:{allowClear:true}, node: 'index', + disabled: function(m) { + // If we are in table edit mode then disable it + if (_.has(m, 'top') && !_.isUndefined(m.top) + && !m.top.isNew()) { + return true; + } + + // We can't update index of existing index constraint. + return !m.isNew(); + }, + // We will not show this field in Create Table mode + visible: function(m) { + return !_.isUndefined(m.top.node_info['table']); + } + },{ + id: 'fillfactor', label: gettext('Fill factor'), deps: ['index'], + type: 'int', group: gettext('Definition'), allowNull: true, + disabled: function(m) { + // Disable if index is selected. + var index = m.get('index'); + if(_.isUndefined(index) || index == '') { + return false; + } else { + setTimeout(function(){ + m.set('fillfactor', null); + },10); + return true; + } + } + },{ + id: 'condeferrable', label: gettext('Deferrable?'), + type: 'switch', group: gettext('Definition'), deps: ['index'], + disabled: function(m) { + // If we are in table edit mode then + if (_.has(m, 'top') && !_.isUndefined(m.top) + && !m.top.isNew()) { + // If OID is undefined then user is trying to add + // new constraint which should allowed for Unique + return !_.isUndefined(m.get('oid')); + } + + // We can't update condeferrable of existing index constraint. + if (!m.isNew()) { + return true; + } + // Disable if index is selected. + var index = m.get('index'); + if(_.isUndefined(index) || index == '') { + return false; + } else { + setTimeout(function(){ + if(m.get('condeferrable')) + m.set('condeferrable', false); + },10); + return true; + } + } + },{ + id: 'condeferred', label: gettext('Deferred?'), + type: 'switch', group: gettext('Definition'), + deps: ['condeferrable'], + disabled: function(m) { + // If we are in table edit mode then + if (_.has(m, 'top') && !_.isUndefined(m.top) + && !m.top.isNew()) { + // If OID is undefined then user is trying to add + // new constraint which should allowed for Unique + return !_.isUndefined(m.get('oid')); + } + + // We can't update condeferred of existing index constraint. + if (!m.isNew()) { + return true; + } + // Disable if condeferred is false or unselected. + if(m.get('condeferrable') == true) { + return false; + } else { + setTimeout(function(){ + if(m.get('condeferred')) + m.set('condeferred', false); + },10); + return true; + } + } + } + ], + validate: function() { + this.errorModel.clear(); + // Clear parent's error as well + if (_.has(this, 'top')) { + this.top.errorModel.clear(); + } + + var columns = this.get('columns'), + index = this.get('index'); + + if ((_.isUndefined(index) || String(index).replace(/^\s+|\s+$/g, '') == '') && + (_.isUndefined(columns) || _.isNull(columns) || columns.length < 1)) { + var msg = gettext('Please specify columns for %(node)s', {node: gettext('Primary key')}); + this.errorModel.set('columns', msg); + return msg; + } + + return null; + } + }) + }); + } + + return pgBrowser.Nodes['primary_key']; +}); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/unique_constraint.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/unique_constraint.js new file mode 100644 index 00000000..69a92ac1 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/unique_constraint.js @@ -0,0 +1,529 @@ +define('pgadmin.node.unique_constraint', [ + 'sources/gettext', 'sources/url_for', 'jquery', 'underscore', 'underscore.string', 'pgadmin', + 'pgadmin.browser', 'alertify', 'pgadmin.browser.collection' +], function(gettext, url_for, $, _, S, pgAdmin, pgBrowser, alertify) { + + // Extend the browser's node class for index constraint node + if (!pgBrowser.Nodes['unique_constraint']) { + pgAdmin.Browser.Nodes['unique_constraint'] = pgBrowser.Node.extend({ + type: 'unique_constraint', + label: gettext('Unique constraint'), + collection_type: 'coll-constraints', + sqlAlterHelp: 'ddl-alter.html', + sqlCreateHelp: 'ddl-constraints.html', + dialogHelp: url_for('help.static', {filename: 'unique_constraint_dialog.html'}), + hasSQL: true, + hasDepends: true, + hasStatistics: true, + statsPrettifyFields: ['Index size'], + parent_type: 'table', + canDrop: true, + canDropCascade: true, + Init: function() { + /* Avoid multiple registration of menus */ + if (this.initialized) + return; + + this.initialized = true; + + pgBrowser.add_menus([{ + name: 'create_unique_constraint_on_coll', node: 'coll-constraints', module: this, + applies: ['object', 'context'], callback: 'show_obj_properties', + category: 'create', priority: 4, label: gettext('Unique constraint'), + icon: 'wcTabIcon icon-unique_constraint', data: {action: 'create', check: true}, + enable: 'canCreate' + + } + ]); + }, + canCreate: function(itemData, item, data) { + // If check is false then , we will allow create menu + if (data && data.check == false) + return true; + + var t = pgBrowser.tree, i = item, d = itemData, parents = []; + // To iterate over tree to check parent node + while (i) { + // If it is schema then allow user to c reate table + if (_.indexOf(['schema'], d._type) > -1) { + return true; + } + parents.push(d._type); + i = t.hasParent(i) ? t.parent(i) : null; + d = i ? t.itemData(i) : null; + } + // If node is under catalog then do not allow 'create' menu + if (_.indexOf(parents, 'catalog') > -1) { + return false; + } else { + return true; + } + }, + + // Define the model for index constraint node + model: pgAdmin.Browser.Node.Model.extend({ + idAttribute: 'oid', + + defaults: { + name: undefined, + oid: undefined, + comment: undefined, + spcname: undefined, + index: undefined, + fillfactor: undefined, + condeferrable: undefined, + condeferred: undefined, + columns: [] + }, + + // Define the schema for the index constraint node + schema: [{ + id: 'name', label: gettext('Name'), type: 'text', + mode: ['properties', 'create', 'edit'], editable:true, + cellHeaderClasses:'width_percent_40', + },{ + id: 'oid', label: gettext('OID'), cell: 'string', + type: 'text' , mode: ['properties'], editable: false, + cellHeaderClasses:'width_percent_20', + },{ + id: 'comment', label: gettext('Comment'), cell: 'string', + type: 'multiline', mode: ['properties', 'create', 'edit'], + deps:['name'], disabled:function(m) { + var name = m.get('name'); + if (!(name && name != '')) { + setTimeout(function(){ + if(m.get('comment') && m.get('comment') !== '') { + m.set('comment', null); + } + },10); + return true; + } else { + return false; + } + } + },{ + id: 'columns', label: gettext('Columns'), + type: 'collection', group: gettext('Definition'), + editable: false, + cell: Backgrid.StringCell.extend({ + initialize: function() { + Backgrid.StringCell.prototype.initialize.apply(this, arguments); + + var self = this, + collection = this.model.get('columns'); + + // Do not listen for any event(s) for existing constraint. + if (_.isUndefined(self.model.get('oid'))) { + var tableCols = self.model.top.get('columns'); + self.listenTo(tableCols, 'remove' , self.removeColumn); + self.listenTo(tableCols, 'change:name', self.resetColOptions); + } + + collection.on('pgadmin:multicolumn:updated', function() { + self.render.apply(self); + }); + self.listenTo(collection, "add", self.render); + self.listenTo(collection, "remove", self.render); + }, + removeColumn: function(m) { + var self = this, + removedCols = self.model.get('columns').where( + {column: m.get('name')} + ); + + self.model.get('columns').remove(removedCols); + setTimeout(function () { + self.render(); + }, 10); + + var key = 'unique_constraint' + setTimeout(function () { + constraints = self.model.top.get(key); + var removed = []; + constraints.each(function(constraint) { + if (constraint.get("columns").length == 0) { + removed.push(constraint); + } + }); + constraints.remove(removed); + },100); + + }, + resetColOptions : function(m) { + var self = this, + updatedCols = self.model.get('columns').where( + {column: m.previous('name')} + ); + if (updatedCols.length > 0) { + /* + * Table column name has changed so update + * column name in primary key as well. + */ + updatedCols[0].set( + {"column": m.get('name')}, + {silent: true}); + } + + setTimeout(function () { + self.render(); + }, 10); + }, + formatter: { + fromRaw: function (rawValue, model) { + return rawValue.pluck("column").toString(); + }, + toRaw: function (val, model) { + return val; + } + }, + render: function() { + return Backgrid.StringCell.prototype.render.apply(this, arguments); + }, + remove: function() { + var tableCols = this.model.top.get('columns'), + primary_key_col = this.model.get('columns'); + + if (primary_key_col) { + primary_key_col.off('pgadmin:multicolumn:updated'); + } + + this.stopListening(tableCols, 'remove' , self.removeColumn); + this.stopListening(tableCols, 'change:name' , self.resetColOptions); + + Backgrid.StringCell.prototype.remove.apply(this, arguments); + } + }), + canDelete: true, canAdd: true, + control: Backform.MultiSelectAjaxControl.extend({ + defaults: _.extend( + {}, + Backform.NodeListByNameControl.prototype.defaults, + { + select2: { + multiple: true, + allowClear: true, + width: 'style', + placeholder: gettext('Select the column(s)'), + } + } + ), + keyPathAccessor: function(obj, path) { + var res = obj; + if(_.isArray(res)) { + return _.map(res, function(o) { return o['column'] + }); + } + path = path.split('.'); + for (var i = 0; i < path.length; i++) { + if (_.isNull(res)) return null; + if (_.isEmpty(path[i])) continue; + if (!_.isUndefined(res[path[i]])) res = res[path[i]]; + } + return _.isObject(res) && !_.isArray(res) ? null : res; + }, + initialize: function() { + // Here we will decide if we need to call URL + // Or fetch the data from parent columns collection + var self = this; + if(this.model.handler) { + Backform.Select2Control.prototype.initialize.apply(this, arguments); + // Do not listen for any event(s) for existing constraint. + if (_.isUndefined(self.model.get('oid'))) { + var tableCols = self.model.top.get('columns'); + self.listenTo(tableCols, 'remove' , self.resetColOptions); + self.listenTo(tableCols, 'change:name', self.resetColOptions); + } + + self.custom_options(); + } else { + Backform.MultiSelectAjaxControl.prototype.initialize.apply(this, arguments); + } + self.model.get('columns').on('pgadmin:multicolumn:updated', function() { + self.render.apply(self); + }); + }, + resetColOptions: function(m) { + var self = this; + + setTimeout(function () { + self.custom_options(); + self.render.apply(self); + }, 50); + + }, + custom_options: function() { + // We will add all the columns entered by user in table model + var columns = this.model.top.get('columns'), + added_columns_from_tables = []; + + if (columns.length > 0) { + _.each(columns.models, function(m) { + var col = m.get('name'); + if(!_.isUndefined(col) && !_.isNull(col)) { + added_columns_from_tables.push( + {label: col, value: col, image:'icon-column'} + ); + } + }); + } + // Set the values in to options so that user can select + this.field.set('options', added_columns_from_tables); + }, + onChange: function(e) { + var self = this, + model = this.model, + $el = $(e.target), + attrArr = this.field.get("name").split('.'), + name = attrArr.shift(), + path = attrArr.join('.'), + vals = this.getValueFromDOM(), + collection = model.get(name), + removed = []; + + this.stopListening(this.model, "change:" + name, this.render); + + /* + * Iterate through all the values, and find out how many are already + * present in the collection. + */ + collection.each(function(m) { + var column = m.get('column'), + idx = _.indexOf(vals, column); + + if (idx > -1) { + vals.splice(idx, 1); + } else { + removed.push(column); + } + }); + + /* + * Adding new values + */ + + _.each(vals, function(v) { + var m = new (self.field.get('model'))( + {column: v}, { silent: true, + top: self.model.top, + collection: collection, + handler: collection + }); + + collection.add(m); + }); + + /* + * Removing unwanted! + */ + _.each(removed, function(v) { + collection.remove(collection.where({column: v})); + }); + + this.listenTo(this.model, "change:" + name, this.render); + }, + remove: function() { + if(this.model.handler) { + var self = this, + tableCols = self.model.top.get('columns'); + self.stopListening(tableCols, 'remove' , self.resetColOptions); + self.stopListening(tableCols, 'change:name' , self.resetColOptions); + self.model.get('columns').off('pgadmin:multicolumn:updated'); + + Backform.Select2Control.prototype.remove.apply(this, arguments); + + } else { + Backform.MultiSelectAjaxControl.prototype.remove.apply(this, arguments); + } + } + }), + deps: ['index'], node: 'column', + model: pgBrowser.Node.Model.extend({ + defaults: { + column: undefined + }, + validate: function() { + return null; + } + }), + transform : function(data){ + var res = []; + if (data && _.isArray(data)) { + _.each(data, function(d) { + res.push({label: d.label, value: d.label, image:'icon-column'}); + }) + } + return res; + }, + select2:{allowClear:false}, + disabled: function(m) { + // If we are in table edit mode then + if (_.has(m, 'top') && !_.isUndefined(m.top) + && !m.top.isNew()) { + // If OID is undefined then user is trying to add + // new constraint which should be allowed for Unique + return !_.isUndefined(m.get('oid')); + } + + // We can't update columns of existing index constraint. + if (!m.isNew()) { + return true; + } + // Disable if index is selected. + var index = m.get('index'); + if(_.isUndefined(index) || index == '') { + return false; + } else { + var col = m.get('columns'); + col.reset(); + return true; + } + } + },{ + id: 'spcname', label: gettext('Tablespace'), + type: 'text', group: gettext('Definition'), + control: 'node-list-by-name', node: 'tablespace', + deps: ['index'], + select2:{allowClear:false}, + filter: function(m) { + // Don't show pg_global tablespace in selection. + if (m.label == "pg_global") return false; + else return true; + }, + disabled: function(m) { + // Disable if index is selected. + m = m.top || m; + var index = m.get('index'); + if(_.isUndefined(index) || index == '') { + return false; + } else { + setTimeout(function(){ + m.set('spcname', ''); + },10); + return true; + } + } + },{ + id: 'index', label: gettext('Index'), + type: 'text', group: gettext('Definition'), + control: Backform.NodeListByNameControl.extend({ + initialize:function() { + if (_.isUndefined(this.model.top)) { + Backform.NodeListByNameControl.prototype.initialize.apply(this,arguments); + } else { + Backform.Control.prototype.initialize.apply(this,arguments); + } + } + }), + select2:{allowClear:true}, node: 'index', + disabled: function(m) { + // If we are in table edit mode then disable it + if (_.has(m, 'top') && !_.isUndefined(m.top) + && !m.top.isNew()) { + return true; + } + + // We can't update index of existing index constraint. + return !m.isNew(); + }, + // We will not show this field in Create Table mode + visible: function(m) { + return !_.isUndefined(m.top.node_info['table']); + } + },{ + id: 'fillfactor', label: gettext('Fill factor'), deps: ['index'], + type: 'int', group: gettext('Definition'), allowNull: true, + disabled: function(m) { + // Disable if index is selected. + var index = m.get('index'); + if(_.isUndefined(index) || index == '') { + return false; + } else { + setTimeout(function(){ + m.set('fillfactor', null); + },10); + return true; + } + } + },{ + id: 'condeferrable', label: gettext('Deferrable?'), + type: 'switch', group: gettext('Definition'), deps: ['index'], + disabled: function(m) { + // If we are in table edit mode then + if (_.has(m, 'top') && !_.isUndefined(m.top) + && !m.top.isNew()) { + // If OID is undefined then user is trying to add + // new constraint which should allowed for Unique + return !_.isUndefined(m.get('oid')); + } + + // We can't update condeferrable of existing index constraint. + if (!m.isNew()) { + return true; + } + // Disable if index is selected. + var index = m.get('index'); + if(_.isUndefined(index) || index == '') { + return false; + } else { + setTimeout(function(){ + if(m.get('condeferrable')) + m.set('condeferrable', false); + },10); + return true; + } + } + },{ + id: 'condeferred', label: gettext('Deferred?'), + type: 'switch', group: gettext('Definition'), + deps: ['condeferrable'], + disabled: function(m) { + // If we are in table edit mode then + if (_.has(m, 'top') && !_.isUndefined(m.top) + && !m.top.isNew()) { + // If OID is undefined then user is trying to add + // new constraint which should allowed for Unique + return !_.isUndefined(m.get('oid')); + } + + // We can't update condeferred of existing index constraint. + if (!m.isNew()) { + return true; + } + // Disable if condeferred is false or unselected. + if(m.get('condeferrable') == true) { + return false; + } else { + setTimeout(function(){ + if(m.get('condeferred')) + m.set('condeferred', false); + },10); + return true; + } + } + } + ], + validate: function() { + this.errorModel.clear(); + // Clear parent's error as well + if (_.has(this, 'top')) { + this.top.errorModel.clear(); + } + + var columns = this.get('columns'), + index = this.get('index'); + + if ((_.isUndefined(index) || String(index).replace(/^\s+|\s+$/g, '') == '') && + (_.isUndefined(columns) || _.isNull(columns) || columns.length < 1)) { + var msg = gettext('Please specify columns for %(node)s', {node: gettext('Unique constraint')}); + this.errorModel.set('columns', msg); + return msg; + } + + return null; + } + }) + }); + } + + return pgBrowser.Nodes['unique_constraint']; +}); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/templates/constraints/js/constraints.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/templates/constraints/js/constraints.js index e372b3cc..6c3af6ff 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/templates/constraints/js/constraints.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/templates/constraints/js/constraints.js @@ -1,6 +1,8 @@ define('pgadmin.node.constraints', [ 'sources/gettext', 'jquery', 'underscore', 'underscore.string', 'pgadmin', - 'pgadmin.browser', 'pgadmin.browser.collection'{% for c in constraints %}, 'pgadmin.node.{{ c|safe }}'{%endfor%} + 'pgadmin.browser', 'pgadmin.browser.collection', 'pgadmin.node.unique_constraint', + 'pgadmin.node.check_constraints', 'pgadmin.node.foreign_key', + 'pgadmin.node.exclusion_constraint', 'pgadmin.node.primary_key' ], function(gettext, $, _, S, pgAdmin, pgBrowser) { if (!pgBrowser.Nodes['coll-constraints']) { diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/templates/index/js/index.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/templates/index/js/index.js index 4fc1d54a..0bb2d40f 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/templates/index/js/index.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/templates/index/js/index.js @@ -32,7 +32,7 @@ define('pgadmin.node.index', [ editable = this.column.get("editable"), input = this.$el.find('select').first(); - is_editable = _.isFunction(editable) ? !!editable.apply(column, [model]) : !!editable; + var is_editable = _.isFunction(editable) ? !!editable.apply(column, [model]) : !!editable; if (is_editable) { this.$el.addClass("editable"); input.prop('disabled', false); @@ -165,7 +165,7 @@ define('pgadmin.node.index', [ if (_.isUndefined(this.get('colname')) || String(this.get('colname')).replace(/^\s+|\s+$/g, '') == '') { - msg = gettext('Column Name cannot be empty.'); + var msg = gettext('Column Name cannot be empty.'); this.errorModel.set('colname', msg); return msg; } diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/rules/templates/rules/js/rules.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/rules/templates/rules/js/rules.js index db91af32..19fcad2e 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/rules/templates/rules/js/rules.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/rules/templates/rules/js/rules.js @@ -230,12 +230,12 @@ define('pgadmin.node.rule', [ if ('coll-rule' == d._type) { //Check if we are not child of rule - prev_i = t.hasParent(i) ? t.parent(i) : null; - prev_d = prev_i ? t.itemData(prev_i) : null; - prev_j = t.hasParent(prev_i) ? t.parent(prev_i) : null; - prev_e = prev_j ? t.itemData(prev_j) : null; - prev_k = t.hasParent(prev_j) ? t.parent(prev_j) : null; - prev_f = prev_k ? t.itemData(prev_k) : null; + var prev_i = t.hasParent(i) ? t.parent(i) : null, + prev_d = prev_i ? t.itemData(prev_i) : null, + prev_j = t.hasParent(prev_i) ? t.parent(prev_i) : null, + prev_e = prev_j ? t.itemData(prev_j) : null, + prev_k = t.hasParent(prev_j) ? t.parent(prev_j) : null, + prev_f = prev_k ? t.itemData(prev_k) : null; if( prev_f._type == 'catalog') { return false; } else { diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/partition.utils.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/partition.utils.js index a1b7a9aa..080118a9 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/partition.utils.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/partition.utils.js @@ -1,4 +1,4 @@ -define( +define('pgadmin.node.table_partition_utils', ['sources/gettext', 'jquery', 'underscore', 'pgadmin.browser', 'backform','backgrid', 'pgadmin.browser.collection'], function(gettext, $, _, pgBrowser, Backform, Backgrid) { @@ -205,21 +205,21 @@ function(gettext, $, _, pgBrowser, Backform, Backgrid) { if (_.isUndefined(col_type) || _.isNull(col_type) || String(col_type).replace(/^\s+|\s+$/g, '') == '') { - msg = gettext('Partition key type cannot be empty.'); + var msg = gettext('Partition key type cannot be empty.'); this.errorModel.set('key_type', msg); return msg; } else if (col_type == 'column' && _.isUndefined(pt_column) || _.isNull(pt_column) || String(pt_column).replace(/^\s+|\s+$/g, '') == '') { - msg = gettext('Partition key column cannot be empty.'); + var msg = gettext('Partition key column cannot be empty.'); this.errorModel.set('pt_column', msg); return msg; } else if (col_type == 'expression' && _.isUndefined(expression) || _.isNull(expression) || String(expression).replace(/^\s+|\s+$/g, '') == '') { - msg = gettext('Partition key expression cannot be empty.'); + var msg = gettext('Partition key expression cannot be empty.'); this.errorModel.set('expression', msg); return msg; } @@ -306,7 +306,7 @@ function(gettext, $, _, pgBrowser, Backform, Backgrid) { if (_.isUndefined(partition_name) || _.isNull(partition_name) || String(partition_name).replace(/^\s+|\s+$/g, '') == '') { - msg = gettext('Partition name cannot be empty.'); + var msg = gettext('Partition name cannot be empty.'); this.errorModel.set('partition_name', msg); return msg; } @@ -314,19 +314,19 @@ function(gettext, $, _, pgBrowser, Backform, Backgrid) { if (this.top.get('partition_type') == 'range') { if (_.isUndefined(values_from) || _.isNull(values_from) || String(values_from).replace(/^\s+|\s+$/g, '') == '') { - msg = gettext('For range partition From field cannot be empty.'); + var msg = gettext('For range partition From field cannot be empty.'); this.errorModel.set('values_from', msg); return msg; } else if (_.isUndefined(values_to) || _.isNull(values_to) || String(values_to).replace(/^\s+|\s+$/g, '') == '') { - msg = gettext('For range partition To field cannot be empty.'); + var msg = gettext('For range partition To field cannot be empty.'); this.errorModel.set('values_to', msg); return msg; } } else if (this.top.get('partition_type') == 'list') { if (_.isUndefined(values_in) || _.isNull(values_in) || String(values_in).replace(/^\s+|\s+$/g, '') == '') { - msg = gettext('For list partition In field cannot be empty.'); + var msg = gettext('For list partition In field cannot be empty.'); this.errorModel.set('values_in', msg); return msg; } diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.js index faa8b7de..2bbd924d 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.js @@ -114,7 +114,7 @@ define('pgadmin.node.table', [ set_triggers: function(args, params) { // This function will send request to enable or // disable triggers on table level - var input = args || {}; + var input = args || {}, obj = this, t = pgBrowser.tree, i = input.item || t.selected(), @@ -162,7 +162,7 @@ define('pgadmin.node.table', [ this.callbacks.truncate.apply(this, [args, params]); }, truncate: function(args, params) { - var input = args || {}; + var input = args || {}, obj = this, t = pgBrowser.tree, i = input.item || t.selected(), @@ -708,7 +708,7 @@ define('pgadmin.node.table', [ }] },{ id: 'typname', label: gettext('Of type'), type: 'text', - control: 'node-ajax-options', mode: ['properties', 'create', 'edit'], + mode: ['properties', 'create', 'edit'], disabled: 'checkOfType', url: 'get_oftype', group: gettext('Advanced'), deps: ['coll_inherits'], transform: function(data, cell) { var control = cell || this, @@ -1244,7 +1244,7 @@ define('pgadmin.node.table', [ var self = this, url = 'get_columns', m = self.model.top || self.model, - old_columns = _.clone(m.get('columns')) + old_columns = _.clone(m.get('columns')), data = undefined, node = this.field.get('schema_node'), node_info = this.field.get('node_info'), @@ -1291,7 +1291,7 @@ define('pgadmin.node.table', [ if ('coll-table' == d._type) { //Check if we are not child of catalog - prev_i = t.hasParent(i) ? t.parent(i) : null; + var prev_i = t.hasParent(i) ? t.parent(i) : null, prev_d = prev_i ? t.itemData(prev_i) : null; if( prev_d._type == 'catalog') { return false; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/types/static/js/type.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/types/static/js/type.js index da24e2bf..0a0491a9 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/types/static/js/type.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/types/static/js/type.js @@ -24,9 +24,9 @@ define('pgadmin.node.type', [ this.$el.empty(); var model = this.model; var column = this.column; - editable = this.column.get("editable"); + var editable = this.column.get("editable"); - is_editable = _.isFunction(editable) ? !!editable.apply(column, [model]) : !!editable; + var is_editable = _.isFunction(editable) ? !!editable.apply(column, [model]) : !!editable; if (is_editable){ this.$el.addClass("editable"); } else { this.$el.removeClass("editable"); } @@ -48,7 +48,7 @@ define('pgadmin.node.type', [ editable = this.column.get("editable"), input = this.$el.find('select').first(); - is_editable = _.isFunction(editable) ? !!editable.apply(column, [model]) : !!editable; + var is_editable = _.isFunction(editable) ? !!editable.apply(column, [model]) : !!editable; if (is_editable) { this.$el.addClass("editable"); input.prop('disabled', false); @@ -337,7 +337,6 @@ define('pgadmin.node.type', [ id: 'typtype', label: gettext('Type'), mode: ['create','edit'], disabled: 'inSchemaWithModelCheck', group: gettext('Definition'), - mode: ['edit', 'create'], select2: { width: "50%", allowClear: false }, options: function(obj) { return [ @@ -929,7 +928,7 @@ define('pgadmin.node.type', [ if ('coll-type' == d._type) { //Check if we are not child of catalog - prev_i = t.hasParent(i) ? t.parent(i) : null; + var prev_i = t.hasParent(i) ? t.parent(i) : null, prev_d = prev_i ? t.itemData(prev_i) : null; if( prev_d._type == 'catalog') { return false; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/mview.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/mview.js index 24981071..22733268 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/mview.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/mview.js @@ -261,8 +261,8 @@ define('pgadmin.node.mview', [ if ('coll-mview' == d._type) { // Check if we are not child of view - prev_i = t.hasParent(i) ? t.parent(i) : null; - prev_d = prev_i ? t.itemData(prev_i) : null; + var prev_i = t.hasParent(i) ? t.parent(i) : null, + prev_d = prev_i ? t.itemData(prev_i) : null; if( prev_d._type == 'catalog') { return false; } else { diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/view.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/view.js index da4de276..d6c794e6 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/view.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/view.js @@ -113,8 +113,7 @@ define('pgadmin.node.view', [ id: 'schema', label: gettext('Schema'), cell: 'string', first_empty: false, control: 'node-list-by-name', type: 'text', cache_level: 'database', node: 'schema', disabled: 'notInSchema', mode: ['create', 'edit'], - select2: { allowClear: false }, cache_node: 'database', - cache_level: 'database' + select2: { allowClear: false }, cache_node: 'database' },{ id: 'system_view', label: gettext('System view?'), cell: 'string', type: 'switch', disabled: true, mode: ['properties'] @@ -221,8 +220,8 @@ define('pgadmin.node.view', [ if ('coll-view' == d._type) { // Check if we are not child of view - prev_i = t.hasParent(i) ? t.parent(i) : null; - prev_d = prev_i ? t.itemData(prev_i) : null; + var prev_i = t.hasParent(i) ? t.parent(i) : null, + prev_d = prev_i ? t.itemData(prev_i) : null; if( prev_d._type == 'catalog') { return false; } else { diff --git a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js index e3797338..d2d4c48c 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js +++ b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js @@ -1,6 +1,6 @@ define('pgadmin.node.database', [ 'sources/gettext', 'sources/url_for', 'jquery', 'underscore', - 'underscore.string', 'pgadmin', 'pgadmin.browser', 'alertify', + 'underscore.string', 'pgadmin', 'pgadmin.browser.utils', 'alertify', 'sources/alerts/alertify_wrapper', 'pgadmin.browser.collection', 'pgadmin.browser.server.privilege', diff --git a/web/pgadmin/browser/server_groups/servers/static/js/privilege.js b/web/pgadmin/browser/server_groups/servers/static/js/privilege.js index 654884c5..41cf62d8 100644 --- a/web/pgadmin/browser/server_groups/servers/static/js/privilege.js +++ b/web/pgadmin/browser/server_groups/servers/static/js/privilege.js @@ -1,31 +1,5 @@ -(function(root, factory) { - // Set up Backform appropriately for the environment. Start with AMD. - if (typeof define === 'function' && define.amd) { - define(['sources/gettext', 'underscore', 'jquery', 'backbone', 'backform', 'backgrid', 'alertify', 'pgadmin.browser.node'], - function(gettext, _, $, 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, gettext, _, $, Backbone, Backform, Backgrid, 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; - Backgrid = require('backgrid') || root.Backgrid; - Alertify = require('alertify') || root.Alertify; - pgAdmin = require('pgadmin.browser.node') || root.pgAdmin.Browser.Node, - gettext = require('sources/gettext') || root.gettext; - factory(root, gettext, _, $, Backbone, Backform, Alertify, pgNode); - - // Finally, as a browser global. - } else { - factory(root, root.gettext, root._, (root.jQuery || root.Zepto || root.ender || root.$), root.Backbone, root.Backform, root.Backgrid, root.alertify, root.pgAdmin.Browser.Node); - } -} (this, function(root, gettext, _, $, Backbone, Backform, Backgrid, Alertify, pgNode) { - +define(['sources/gettext', 'underscore', 'jquery', 'backbone', 'backform', 'backgrid', 'alertify', 'pgadmin.browser.node', 'pgadmin.browser.node.ui'], + function(gettext, _, $, Backbone, Backform, Backgrid, Alertify, pgNode) { /** * Each Privilege, supporeted by an database object, will be represented * using this Model. @@ -715,4 +689,4 @@ return PrivilegeRoleModel; -})); +}); diff --git a/web/pgadmin/browser/server_groups/servers/static/js/server.js b/web/pgadmin/browser/server_groups/servers/static/js/server.js index 0fad2f62..c57a0e24 100644 --- a/web/pgadmin/browser/server_groups/servers/static/js/server.js +++ b/web/pgadmin/browser/server_groups/servers/static/js/server.js @@ -3,7 +3,7 @@ define('pgadmin.node.server', [ 'underscore.string', 'pgadmin', 'pgadmin.browser', 'alertify', 'pgadmin.server.supported_servers', 'pgadmin.user_management.current_user', - 'sources/alerts/alertify_wrapper', + 'sources/alerts/alertify_wrapper', 'pgadmin.browser.server.privilege' ], function( gettext, url_for, $, _, S, pgAdmin, pgBrowser, alertify, supported_servers, current_user, AlertifyWrapper @@ -1037,7 +1037,7 @@ define('pgadmin.node.server', [ }; data.is_connecting = true; - url = obj.generate_url(item, "connect", data, true); + var url = obj.generate_url(item, "connect", data, true); $.post(url) .done(function(res) { if (res.success == 1) { diff --git a/web/pgadmin/browser/server_groups/servers/static/js/variable.js b/web/pgadmin/browser/server_groups/servers/static/js/variable.js index de274263..a02ba62a 100644 --- a/web/pgadmin/browser/server_groups/servers/static/js/variable.js +++ b/web/pgadmin/browser/server_groups/servers/static/js/variable.js @@ -1,36 +1,8 @@ -(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) { +define([ + 'underscore', 'jquery', 'backbone', 'backform', 'backgrid', 'alertify', + 'pgadmin', 'pgadmin.browser.node', 'pgadmin.browser.node.ui' + ], + function(_, $, Backbone, Backform, Backgrid, Alertify, pgAdmin, pgNode) { /* * cellFunction for variable control. @@ -159,7 +131,7 @@ }, schema: [ { - id: 'name', label:'Name', type:'text', editable: true, cellHeaderClasses: 'width_percent_30', + id: 'name', label:'Name', type:'text', cellHeaderClasses: 'width_percent_30', editable: function(m) { return (m instanceof Backbone.Collection) ? true : m.isNew(); }, @@ -513,8 +485,6 @@ newRow.addClass("new"); $(newRow).pgMakeVisible('backform-tab'); - } else { - delete m; } return false; @@ -522,4 +492,4 @@ }); return VariableModel; -})); +}); diff --git a/web/pgadmin/browser/server_groups/static/js/server-group.js b/web/pgadmin/browser/server_groups/static/js/server-group.js index 2c58ea87..eb551244 100644 --- a/web/pgadmin/browser/server_groups/static/js/server-group.js +++ b/web/pgadmin/browser/server_groups/static/js/server-group.js @@ -1,4 +1,4 @@ -define('pgadmin.node.server-group', [ +define('pgadmin.node.server_group', [ 'sources/gettext', 'sources/url_for', 'jquery', 'underscore', 'pgadmin', 'backbone', 'pgadmin.browser', 'pgadmin.browser.node' ], function(gettext, url_for, $, _, pgAdmin, Backbone) { diff --git a/web/pgadmin/browser/static/js/datamodel.js b/web/pgadmin/browser/static/js/datamodel.js index ad8f95f1..e47ce95b 100644 --- a/web/pgadmin/browser/static/js/datamodel.js +++ b/web/pgadmin/browser/static/js/datamodel.js @@ -52,8 +52,6 @@ function(_, S, pgAdmin, $, Backbone) { } } else { - if (obj) - delete obj; obj = null; } self.set(s.id, obj, {silent: true}); @@ -81,8 +79,6 @@ function(_, S, pgAdmin, $, Backbone) { } obj.set(val, {parse: true, silent: true}); } else { - if (obj) - delete obj; obj = null; } res[s.id] = obj; @@ -258,19 +254,16 @@ function(_, S, pgAdmin, $, Backbone) { if (opts && opts.stop) this.stopSession(); - for(id in this.objects) { + for(var id in this.objects) { obj = this.get(id); if (obj) { if (obj instanceof pgBrowser.DataModel) { obj.reset(opts); - delete obj; } else if (obj instanceof Backbone.Model) { obj.clear(opts); - delete obj; } else if (obj instanceof pgBrowser.DataCollection) { obj.reset(opts); - delete obj; } else if (obj instanceof Backbone.Collection) { obj.each(function(m) { if (m instanceof Backbone.DataModel) { @@ -280,7 +273,6 @@ function(_, S, pgAdmin, $, Backbone) { }); if (!(opts instanceof Array)){ opts = [opts] } Backbone.Collection.prototype.reset.apply(obj, opts); - delete obj; } } } @@ -331,7 +323,7 @@ function(_, S, pgAdmin, $, Backbone) { self = this, msg; - attrChanged = function(v, k) { + var attrChanged = function(v, k) { if (k in self.objects) { return; } @@ -520,7 +512,7 @@ function(_, S, pgAdmin, $, Backbone) { if (!objName) { var hasPrimaryKey = obj.primary_key && typeof(obj.primary_key) === 'function'; - key = hasPrimaryKey ? obj.primary_key() : obj.cid, + var key = hasPrimaryKey ? obj.primary_key() : obj.cid, comparator = hasPrimaryKey ? function(k) { var o = self.get('k'); @@ -570,7 +562,7 @@ function(_, S, pgAdmin, $, Backbone) { if (!objName) { var hasPrimaryKey = (obj.primary_key && (typeof(obj.primary_key) === 'function')); - key = hasPrimaryKey ? obj.primary_key() : obj.cid, + var key = hasPrimaryKey ? obj.primary_key() : obj.cid, comparator = hasPrimaryKey ? function(k) { var o = self.get('k'); @@ -614,7 +606,7 @@ function(_, S, pgAdmin, $, Backbone) { }; if (obj instanceof Backbone.Collection) { - for (idx in obj.models) { + for (var idx in obj.models) { if (validate(obj.models[idx])) break; } @@ -1248,7 +1240,7 @@ function(_, S, pgAdmin, $, Backbone) { self.clearInvalidSessionIfModelValid(m); } - new_conflicting_models = self.where(condition); + var new_conflicting_models = self.where(condition); if (new_conflicting_models.length == 0) { self.clearInvalidSessionIfModelValid(model); } else if (new_conflicting_models.length == 1) { diff --git a/web/pgadmin/browser/static/js/node.ui.js b/web/pgadmin/browser/static/js/node.ui.js index 954aacc6..0831c1b9 100644 --- a/web/pgadmin/browser/static/js/node.ui.js +++ b/web/pgadmin/browser/static/js/node.ui.js @@ -1,8 +1,8 @@ define([ - 'sources/gettext', 'jquery', 'underscore', 'pgadmin', 'backbone', 'backform', 'alertify', - 'pgadmin.browser.node' + 'sources/gettext', 'jquery', 'underscore', 'pgadmin', 'backbone', 'backform', + 'alertify', 'backgrid', 'select2', 'pgadmin.browser.node' ], -function(gettext, $, _, pgAdmin, Backbone, Backform, Alertify, Node) { +function(gettext, $, _, pgAdmin, Backbone, Backform, Alertify, Backgrid) { var pgBrowser = pgAdmin.Browser; @@ -169,7 +169,7 @@ function(gettext, $, _, pgAdmin, Backbone, Backform, Alertify, Node) { /* * Transform the data */ - transform = this.field.get('transform') || self.defaults.transform; + var transform = this.field.get('transform') || self.defaults.transform; if (transform && _.isFunction(transform)) { // We will transform the data later, when rendering. // It will allow us to generate different data based on the @@ -405,7 +405,7 @@ function(gettext, $, _, pgAdmin, Backbone, Backform, Alertify, Node) { /* * Transform the data */ - transform = column.get('transform') || self.defaults.transform; + var transform = column.get('transform') || self.defaults.transform; if (transform && _.isFunction(transform)) { // We will transform the data later, when rendering. // It will allow us to generate different data based on the diff --git a/web/pgadmin/browser/static/js/wizard.js b/web/pgadmin/browser/static/js/wizard.js index 2e65c6bf..0becb2d5 100644 --- a/web/pgadmin/browser/static/js/wizard.js +++ b/web/pgadmin/browser/static/js/wizard.js @@ -133,7 +133,7 @@ function(_, Backbone, pgAdmin, pgBrowser) { this.options.disable_prev = (this.options.disable_prev ? true : this.evalASFunc(this.currPage.disable_prev)); this.options.disable_cancel = (this.currPage.canCancel ? true : this.evalASFunc(this.currPage.disable_cancel)); - that = this; + var that = this; /* HTML Content */ if (data.html) { data.content = data.html; } @@ -149,10 +149,9 @@ function(_, Backbone, pgAdmin, pgBrowser) { return this; }, nextPage: function() { - this.options.curr_page.el = this.$el; if (!this.beforeNext()) { return false; } - page_id = this.onNext(); + var page_id = this.onNext(); if (page_id ) { this.currPage = this.collection.get(page_id).toJSON(); @@ -171,7 +170,7 @@ function(_, Backbone, pgAdmin, pgBrowser) { prevPage: function() { if (!this.beforePrev()) { return false; } - page_id = this.onPrev(); + var page_id = this.onPrev(); if (page_id){ this.currPage = this.collection.get(page_id).toJSON(); @@ -264,16 +263,16 @@ function(_, Backbone, pgAdmin, pgBrowser) { }, onDialogHelp: function() { // See if we can find an existing panel, if not, create one - pnlDialogHelp = pgBrowser.docker.findPanels('pnl_online_help')[0]; + var pnlDialogHelp = pgBrowser.docker.findPanels('pnl_online_help')[0]; if (pnlDialogHelp == null) { - pnlProperties = pgBrowser.docker.findPanels('properties')[0]; + var pnlProperties = pgBrowser.docker.findPanels('properties')[0]; pgBrowser.docker.addPanel('pnl_online_help', wcDocker.DOCK.STACKED, pnlProperties); pnlDialogHelp = pgBrowser.docker.findPanels('pnl_online_help')[0]; } // Update the panel - iframe = $(pnlDialogHelp).data('embeddedFrame'); + var iframe = $(pnlDialogHelp).data('embeddedFrame'); pnlDialogHelp.focus(); iframe.openURL(this.options.wizard_help); diff --git a/web/pgadmin/browser/templates/browser/index.html b/web/pgadmin/browser/templates/browser/index.html index 03ac6d22..54b3bd54 100644 --- a/web/pgadmin/browser/templates/browser/index.html +++ b/web/pgadmin/browser/templates/browser/index.html @@ -3,9 +3,8 @@ {% block init_script %} try { require( -['pgadmin', 'pgadmin.browser'], -function(pgAdmin, pgBrowser) { - pgBrowser.init(); +['sources/generated/app.bundle'], +function() { }, function() { /* TODO:: Show proper error dialog */ @@ -30,7 +29,13 @@ require.onResourceLoad = function (context, map, depMaps) { // is not loading anything hide the indicator and exit setTimeout(function() { if (panel != null) { - $(panel).remove(); + try{ + $(panel).remove(); + } + catch(e){ + panel.outerHTML = ""; + delete panel; + } return; } }, 500); @@ -61,6 +66,18 @@ require.onResourceLoad = function (context, map, depMaps) { }, 400) } }; +window.onload = function(e){ + setTimeout(function() { + var gravatarImg = 'Gravatar image for {{ username }} {{ username }} '; + //$('#navbar-menu .navbar-right > li > a').html(gravatarImg); + var navbarRight = document.getElementById("navbar-menu").getElementsByClassName("navbar-right")[0]; + if (navbarRight) { + var list = navbarRight.getElementsByTagName("LI")[0]; + list.getElementsByTagName("a")[0].innerHTML = gravatarImg; + } + }, 1000); +}; + {% endblock %} {% block body %}