From 6a071292aa414103be3f7444f121ed1f82ad3b80 Mon Sep 17 00:00:00 2001 From: Ashesh Vashi Date: Sun, 17 Jan 2016 22:21:02 +0530 Subject: [PATCH] Adding two new controls tab and fieldset for better layout management used in some of the nodes. --- .../browser/templates/browser/js/node.js | 24 ++-- web/pgadmin/static/css/overrides.css | 67 +++++++++- web/pgadmin/static/js/backform.pgadmin.js | 123 ++++++++++++++---- 3 files changed, 178 insertions(+), 36 deletions(-) diff --git a/web/pgadmin/browser/templates/browser/js/node.js b/web/pgadmin/browser/templates/browser/js/node.js index afce2884b..74fa976da 100644 --- a/web/pgadmin/browser/templates/browser/js/node.js +++ b/web/pgadmin/browser/templates/browser/js/node.js @@ -136,7 +136,7 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, Backform) { newModel = new (this.model.extend({urlRoot: urlBase})) ( attrs, {node_info: info} ), - groups = Backform.generateViewSchema( + fields = Backform.generateViewSchema( info, newModel, type, this, node ); @@ -175,18 +175,10 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, Backform) { newModel.on('pgadmin-session:invalid', onSessionInvalid); } // 'schema' has the information about how to generate the form. - if (groups) { - var fields = []; - + if (_.size(fields)) { // This will contain the actual view var view; - // Create an array from the dictionary with proper required - // structure. - _.each(groups, function(val, key) { - fields.push({label: key, fields: val}); - }); - if (formType == 'fieldset') { // It is used to show, edit, create the object in the // properties tab. @@ -668,6 +660,12 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, Backform) { // Create a view to show the properties in fieldsets view = that.getView(item, 'properties', content, data, 'fieldset'); if (view) { + panel.icon( + _.isFunction(that['node_image']) ? + (that['node_image']).apply(that, [data, view.model]) : + (that['node_image'] || ('icon-' + that.type)) + ); + // Save it for release it later j.data('obj-view', view); @@ -747,6 +745,12 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, Backform) { // Save it to release it later j.data('obj-view', view); + panel.icon( + _.isFunction(that['node_image']) ? + (that['node_image']).apply(that, [data, view.model]) : + (that['node_image'] || ('icon-' + that.type)) + ); + // Create proper buttons createButtons([{ label: '{{ _("Save") }}', type: 'save', diff --git a/web/pgadmin/static/css/overrides.css b/web/pgadmin/static/css/overrides.css index 7b0fa3117..631e2a816 100755 --- a/web/pgadmin/static/css/overrides.css +++ b/web/pgadmin/static/css/overrides.css @@ -532,7 +532,7 @@ fieldset[disabled] .form-control { } .subnode-footer { - height:38px;; + height:38px; margin: 0px, 15px; min-height:40px; vertical-align: bottom; @@ -653,3 +653,68 @@ div.rolmembership { border: 1.5px solid #faebd7; margin-top: 15px; } + +fieldset.inline-fieldset { + margin: 0px; margin-left: 2px; margin-right: 2px; + padding-right: 10px; padding-left: 10px; padding-top: 6px; padding-bottom: 12px; + border: 2px solid; border-radius: 5px; +} + +fieldset.inline-fieldset > legend { + display: block; border: 0px solid black; box-shadow: none; + box-sizing: content-box; top: auto; bottom: auto; left: auto; + font-size: 16px; font-style: normal; font-weight: 600; + height: 20px; line-height: 20px; margin: 0px; padding-bottom: 0px; + padding-left: 5px; padding-right: 5px; padding-top: 0px; + vertical-align: middle; width: auto; +} + + +fieldset.inline-fieldset > div { + padding: 0px; margin: 0px; border: 0px; +} + +div.inline-tab-panel { + float: left; width: 100%; +} + +div.inline-tab-panel > ul.nav-tabs > li { + background-color: lightgrey; border-top-left-radius: 10px; border-top-right-radius: 10px; +} + +div.inline-tab-panel > ul.nav-tabs > li:first-child { + background-color: lightgrey; border-top-left-radius: 3px; border-top-right-radius: 10px; +} + +div.inline-tab-panel > ul.nav-tabs > li > a, +div.inline-tab-panel > ul.nav-tabs > li > a:active, +div.inline-tab-panel > ul.nav-tabs > li > a:hover, +div.inline-tab-panel > ul.nav-tabs > li > a:focus { + border-top-left-radius: 10px; border-top-right-radius: 10px; +} + +div.inline-tab-panel > ul.nav-tabs > li:first-child > a, +div.inline-tab-panel > ul.nav-tabs > li:first-child > a:active, +div.inline-tab-panel > ul.nav-tabs > li:first-child > a:hover, +div.inline-tab-panel > ul.nav-tabs > li:first-child > a:focus { + border-top-left-radius: 3px; border-top-right-radius: 10px; +} + +div.inline-tab-panel > ul.tab-content { + padding-left: 5px; padding-right: 5px; border-color: #DDD; + border-bottom-left-radius: 10px; border-bottom-right-radius: 10px; + border-width: 1px; border-bottom-right-radius: 8px; + border-bottom-left-radius: 8px; border-style: solid solid outset; +} + +div.inline-tab-panel > ul.tab-content > div.tab-pane { + min-height: 300px; padding: 0px !important; +} + +div.inline-tab-panel > ul.tab-content > div.tab-pane > *:first-child { + margin-top: 5px; +} + +div.inline-tab-panel > ul.tab-content > div.tab-pane > *:last-child { + margin-bottom: 5px; +} diff --git a/web/pgadmin/static/js/backform.pgadmin.js b/web/pgadmin/static/js/backform.pgadmin.js index 59edf8399..3fbd0c560 100644 --- a/web/pgadmin/static/js/backform.pgadmin.js +++ b/web/pgadmin/static/js/backform.pgadmin.js @@ -107,8 +107,7 @@ return m[idx > len ? 0 : idx]; } - alert ("Developer: did you forget to put/implement the control type - '" + type + "' in mapper"); - return null; + return type; } @@ -379,6 +378,7 @@ tabPanelClassName: function() { return Backform.tabClassName; }, + tabIndex: 0, initialize: function(opts) { var s = opts.schema; if (s && _.isArray(s)) { @@ -415,12 +415,12 @@ controls = this.controls, tmpls = this.template, self = this, - idx=1; + idx=(this.tabIndex * 100); this.$el .empty() .attr('role', 'tabpanel') - .attr('class', this.tabPanelClassName()); + .attr('class', _.result(this, 'tabPanelClassName')); m.panelEl = this.$el; var tabHead = $('') @@ -445,6 +445,7 @@ controls.push(cntr); }); idx++; + tabHead.find('a[data-toggle="tab"]').off( 'shown.bs.tab' ).off('hidden.bs.tab').on( @@ -475,23 +476,40 @@ }); var Fieldset = Backform.Fieldset = Backform.Dialog.extend({ + className: function() { + return 'set-group col-xs-12'; + }, + tabPanelClassName: function() { + return Backform.tabClassName; + }, + fieldsetClass: Backform.setGroupClassName, + legendClass: 'badge', + contentClass: Backform.setGroupContentClassName + ' collapse in', template: { 'header': _.template([ - '
>', - ' <%=label%>', + '
>', + ' data-target="#<%=cId%>"><%=collapse ? "" : "" %><%=label%>', ' ', '
' ].join("\n")), 'content': _.template( - '
' + '
' )}, + collapse: true, render: function() { this.cleanup(); var m = this.model, $el = this.$el, tmpl = this.template, - controls = this.controls; + controls = this.controls, + data = { + 'className': _.result(this, 'className'), + 'fieldsetClass': _.result(this, 'fieldsetClass'), + 'legendClass': _.result(this, 'legendClass'), + 'contentClass': _.result(this, 'contentClass'), + 'collapse': _.result(this, 'collapse') + }; this.$el.empty(); @@ -499,9 +517,9 @@ if (!o.fields) return; - var h = $((tmpl['header'])(o)).appendTo($el), - el = $((tmpl['content'])(o)) - .appendTo(h); + var d = _.extend({}, data, o), + h = $((tmpl['header'])(d)).appendTo($el), + el = $((tmpl['content'])(d)).appendTo(h); o.fields.each(function(f) { var cntr = new (f.get("control")) ({ @@ -523,11 +541,11 @@ var generateGridColumnsFromModel = Backform.generateGridColumnsFromModel = function(node_info, m, type, cols) { - var groups = Backform.generateViewSchema(node_info, m, type), - schema = [], - columns = [], - func, - idx = 0; + var groups = Backform.generateViewSchema(node_info, m, type, null, true), + schema = [], + columns = [], + 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. @@ -603,7 +621,7 @@ // Prepare columns for backgrid _.each(groups, function(fields, key) { _.each(fields, function(f) { - if (!f.control && !f.cell) { + if (!f.cell) { return; } // Check custom property in cols & if it is present then attach it to current cell @@ -1224,10 +1242,12 @@ // // It will be used by the grid, properties, and dialog view generation // functions. - var generateViewSchema = Backform.generateViewSchema = function(node_info, Model, mode, node, treeData) { + var generateViewSchema = Backform.generateViewSchema = function( + node_info, Model, mode, node, treeData, noSQL, subschema + ) { var proto = (Model && Model.prototype) || Model, - schema = (proto && proto.schema), - groups, pgBrowser = window.pgAdmin.Browser; + schema = subschema || (proto && proto.schema), + pgBrowser = window.pgAdmin.Browser, fields = []; // 'schema' has the information about how to generate the form. if (schema && _.isArray(schema)) { @@ -1235,9 +1255,9 @@ return ((prop && proto[prop] && typeof proto[prop] == "function") ? proto[prop] : prop); }; - groups = {}, - server_info = node_info && ('server' in node_info) && - pgBrowser.serverInfo && pgBrowser.serverInfo[node_info.server._id]; + var groups = {}, + server_info = node_info && ('server' in node_info) && + pgBrowser.serverInfo && pgBrowser.serverInfo[node_info.server._id]; _.each(schema, function(s) { // Do we understand - what control, we're creating @@ -1294,6 +1314,16 @@ // Temporarily store in dictionary format for // utilizing it later. groups[group].push(o); + + if (s.type == 'uiLayout') { + delete o.name; + delete o.cell; + + o.schema = Backform.generateViewSchema( + node_info, Model, mode, node, treeData, true, s.schema + ); + o.control = o.control || 'tab'; + } } }); @@ -1302,7 +1332,8 @@ if (_.isEmpty(groups)) { return null; } - if (node && node.hasSQL && (mode == 'create' || mode == 'edit')) { + + if (!noSQL && node && node.hasSQL && (mode == 'create' || mode == 'edit')) { groups[pgBrowser.messages.SQL_TAB] = [{ name: 'sql', visible: true, @@ -1315,8 +1346,14 @@ }]; } + // Create an array from the dictionary with proper required + // structure. + _.each(groups, function(val, key) { + fields.push({label: key, fields: val}); + }); } - return groups; + + return fields; }; /* @@ -1335,5 +1372,41 @@ return this; } }); + + // Backform Tab Control (in bootstrap tabbular) + // A collection of field models. + var TabControl = Backform.TabControl = Backform.Dialog.extend({ + tagName: "div", + className: 'inline-tab-panel', + tabPanelClassName: 'inline-tab-panel', + initialize: function(opts) { + Backform.Dialog.prototype.initialize.apply( + this, [{schema: opts.field.get('schema')}] + ); + this.dialog = opts.dialog; + this.tabIndex = (opts.tabIndex || parseInt(Math.random() * 1000)) + 1; + } + }); + + var FieldsetControl = Backform.FieldsetControl = Backform.Fieldset.extend({ + initialize: function(opts) { + Backform.Dialog.prototype.initialize.apply( + this, [{schema: opts.field.get('schema')}] + ); + this.dialog = opts.dialog; + this.tabIndex = opts.tabIndex; + }, + className: function() { + return 'set-group'; + }, + tabPanelClassName: function() { + return Backform.tabClassName; + }, + fieldsetClass: 'inline-fieldset', + legendClass: '', + contentClass: '', + collapse: false + }); + return Backform; }));