diff --git a/web/pgadmin/browser/templates/browser/js/browser.js b/web/pgadmin/browser/templates/browser/js/browser.js index e2242f2..ccbda73 100644 --- a/web/pgadmin/browser/templates/browser/js/browser.js +++ b/web/pgadmin/browser/templates/browser/js/browser.js @@ -300,8 +300,6 @@ function(require, $, _, S, Bootstrap, pgAdmin, alertify, CodeMirror) { // Stored layout in database from the previous session var layout = '{{ layout }}'; - obj.docker.startLoading('{{ _('Loading...') }}'); - // Try to restore the layout if there is one if (layout != '') { try { @@ -314,10 +312,6 @@ function(require, $, _, S, Bootstrap, pgAdmin, alertify, CodeMirror) { } else { obj.buildDefaultLayout() } - - obj.docker.on(wcDocker.EVENT.LOADED, function() { - obj.docker.finishLoading(500); - }); } // Syntax highlight the SQL Pane diff --git a/web/pgadmin/browser/templates/browser/js/collection.js b/web/pgadmin/browser/templates/browser/js/collection.js index 776ac4c..f62ff4a 100644 --- a/web/pgadmin/browser/templates/browser/js/collection.js +++ b/web/pgadmin/browser/templates/browser/js/collection.js @@ -91,11 +91,26 @@ function($, _, S, pgAdmin, Backbone, Alertify, Backform) { }; if (view) { - // Release the view - view.remove({data: true, internal: true, silent: true}); - // Deallocate the view - delete view; - view = null; + // Avoid unnecessary reloads + var n_type = data._type, + n_value = -1, + treeHierarchy = n.getTreeNodeHierarchy(item); + + if (_.isUndefined(treeHierarchy[n_type]) || + _.isUndefined(treeHierarchy[n_type]._id)) { + n_value = -1; + } else { + n_value = treeHierarchy[n_type]._id; + } + + if (n_value == $(panel).data(n_type)) { + return; + } + + // Cache the current IDs for next time + $(panel).data(n_type, n_value); + + panel.startLoading(); // Reset the data object j.data('obj-view', null); } @@ -107,6 +122,9 @@ function($, _, S, pgAdmin, Backbone, Alertify, Backform) { // Render subNode grid content.append(grid.render().$el); j.append(content); + setTimeout(function() { + panel.finishLoading(); + }, 1000); // Fetch Data collection.fetch({reset: true}) diff --git a/web/pgadmin/browser/templates/browser/js/node.js b/web/pgadmin/browser/templates/browser/js/node.js index 247966e..216c83f 100644 --- a/web/pgadmin/browser/templates/browser/js/node.js +++ b/web/pgadmin/browser/templates/browser/js/node.js @@ -788,8 +788,30 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, pgBrowser, Backform) { // Callback to show object properties properties = function() { - var panel = this; + // Avoid unnecessary reloads + var panel = this, + i = tree.selected(), + d = i && tree.itemData(i), + n_type = d._type, + n_value = -1, + n = i && d && pgBrowser.Nodes[d._type], + treeHierarchy = n.getTreeNodeHierarchy(i); + + if (_.isUndefined(treeHierarchy[n_type]) || + _.isUndefined(treeHierarchy[n_type]._id)) { + n_value = -1; + } else { + n_value = treeHierarchy[n_type]._id; + } + if (n_value == $(panel).data(n_type)) { + return; + } + + // Cache the current IDs for next time + $(panel).data(n_type, n_value); + + panel.startLoading(); if (!content.hasClass('has-pg-prop-btn-group')) content.addClass('has-pg-prop-btn-group'); @@ -818,6 +840,11 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, pgBrowser, Backform) { // Save it for release it later j.data('obj-view', view); + // show spinner for a second unless it cause flickering + setTimeout(function() { + panel.finishLoading(); + }, 1000); + // Create status bar createStatusBar('footer'); diff --git a/web/pgadmin/dashboard/templates/dashboard/js/dashboard.js b/web/pgadmin/dashboard/templates/dashboard/js/dashboard.js index 9a470d9..0d2e825 100644 --- a/web/pgadmin/dashboard/templates/dashboard/js/dashboard.js +++ b/web/pgadmin/dashboard/templates/dashboard/js/dashboard.js @@ -31,6 +31,7 @@ function(r, $, pgAdmin, _, Backbone) { if (dashboardPanel) { var div = dashboardPanel.layout().scene().find('.pg-panel-content'); + dashboardPanel.startLoading(); if (div) { $.ajax({ url: url, @@ -38,6 +39,9 @@ function(r, $, pgAdmin, _, Backbone) { dataType: "html", success: function (data) { $(div).html(data); + setTimeout(function() { + dashboardPanel.finishLoading(); + }, 1000); }, error: function (xhr, status) { $(div).html( @@ -102,12 +106,16 @@ function(r, $, pgAdmin, _, Backbone) { // Clear out everything so any existing timers die off $(div).empty(); + dashboardPanel.startLoading(); $.ajax({ url: url, type: "GET", dataType: "html", success: function (data) { + setTimeout(function() { + dashboardPanel.finishLoading(); + }, 1000); $(div).html(data); }, error: function (xhr, status) { diff --git a/web/pgadmin/misc/depends/static/js/depends.js b/web/pgadmin/misc/depends/static/js/depends.js index d7534c8..a0c9c14 100644 --- a/web/pgadmin/misc/depends/static/js/depends.js +++ b/web/pgadmin/misc/depends/static/js/depends.js @@ -72,8 +72,8 @@ define( */ var appendGridToPanel = function(collection, panel, is_dependent) { var $container = panel[0].layout().scene().find('.pg-panel-content'), - $gridContainer = $container.find('.pg-panel-depends-container'), - grid = new Backgrid.Grid({ + $gridContainer = $container.find('.pg-panel-depends-container'); + self.grid = grid = new Backgrid.Grid({ columns: [ { name : 'type', @@ -106,6 +106,8 @@ define( className: "backgrid presentation table backgrid-striped table-bordered table-hover", }); + panel[0].startLoading(); + // Condition is used to save grid object to change the label of the header. if (is_dependent) self.dependentGrid = grid; @@ -113,6 +115,9 @@ define( self.dependenciesGrid = grid; $gridContainer.append(grid.render().el); + setTimeout(function() { + panel[0].finishLoading(); + }, 1000); return true; }; @@ -175,11 +180,30 @@ define( }, // Fetch the actual data and update the collection - __updateCollection: function(collection, panel, url, messages, node) { + __updateCollection: function(collection, panel, url, messages, node, item, type) { var msg = messages[0], $container = panel[0].layout().scene().find('.pg-panel-content'), $msgContainer = $container.find('.pg-panel-depends-message'), $gridContainer = $container.find('.pg-panel-depends-container'); + treeHierarchy = node.getTreeNodeHierarchy(item), + n_value = -1, + n_type = type; + + // Avoid unnecessary reloads + if (_.isUndefined(treeHierarchy[n_type]) || + _.isUndefined(treeHierarchy[n_type]._id)) { + n_value = -1; + } else { + n_value = treeHierarchy[n_type]._id; + } + + if (n_value == $(panel[0]).data(n_type)) { + return; + } + + // Cache the current IDs for next time + $(panel[0]).data(n_type, n_value); + // Hide the grid container and show the default message container if (!$gridContainer.hasClass('hidden')) @@ -197,7 +221,7 @@ define( */ msg = messages[2]; $msgContainer.text(msg); - + panel[0].startLoading(); /* Updating the label for the 'field' type of the backbone model. * Label should be "Database" if the node type is tablespace or role * and dependent tab is selected. For other nodes and dependencies tab @@ -210,15 +234,18 @@ define( this.dependentGrid.columns.models[2].set({'label': 'Restriction'}); } + // Hide the message container and show the grid container. + $msgContainer.addClass('hidden'); + $gridContainer.removeClass('hidden'); // Set the url, fetch the data and update the collection collection.url = url; collection.fetch({ reset: true, success: function(res) { - - // In case of success hide the message container and show the grid container. - $gridContainer.removeClass('hidden'); - $msgContainer.addClass('hidden'); + // Hide loading icons once collection is retrieved. + setTimeout(function() { + panel[0].finishLoading(); + }, 1000); }, error: function() { } @@ -250,7 +277,9 @@ define( node.generate_url(item, 'dependent', data, true), ['No object selected.', 'No dependent information is available for the current object.', 'Fetching dependent information from the server...'], - node + node, + item, + data._type ), 400 ); }, @@ -292,7 +321,9 @@ define( node.generate_url(item, 'dependency', data, true), ['Please select an object in the tree view.', 'No dependency information is available for the current object.', 'Fetching dependency information from the server...'], - node + node, + item, + data._type ), 400 ); }, diff --git a/web/pgadmin/misc/sql/static/js/sql.js b/web/pgadmin/misc/sql/static/js/sql.js index 4e13c01..8c36a1f 100644 --- a/web/pgadmin/misc/sql/static/js/sql.js +++ b/web/pgadmin/misc/sql/static/js/sql.js @@ -16,7 +16,7 @@ function(_, $, pgBrowser) { this.initialized = true; _.bindAll(this, 'showSQL', 'sqlPanelVisibilityChanged'); - var sqlPanels = pgBrowser.docker.findPanels('sql'); + this.sqlPanels = sqlPanels = pgBrowser.docker.findPanels('sql'); // We will listend to the visibility change of the SQL panel pgBrowser.Events.on( @@ -62,6 +62,27 @@ function(_, $, pgBrowser) { sql = '-- ' + pgBrowser.messages.NODE_HAS_NO_SQL; if (node.hasSQL) { + var self = this, + n_type = data._type, + n_value = -1, + treeHierarchy = node.getTreeNodeHierarchy(item); + + // Avoid unnecessary reloads + if (_.isUndefined(treeHierarchy[n_type]) || + _.isUndefined(treeHierarchy[n_type]._id)) { + n_value = -1; + } else { + n_value = treeHierarchy[n_type]._id; + } + + if (n_value == $(sqlPanels[0]).data(n_type)) { + return; + } + + // Cache the current IDs for next time + $(this.sqlPanels[0]).data(n_type, n_value); + + this.sqlPanels[0].startLoading(); sql = ''; var url = node.generate_url(item, 'sql', data, true); @@ -70,6 +91,9 @@ function(_, $, pgBrowser) { type:'GET', success: function(res) { if (pgAdmin.Browser.editor.getValue() != res) { + setTimeout(function() { + self.sqlPanels[0].finishLoading(); + }, 1000); pgAdmin.Browser.editor.setValue(res); } }, @@ -85,6 +109,10 @@ function(_, $, pgBrowser) { if (sql != '') { pgAdmin.Browser.editor.setValue(sql); } + // stop loading icon if no data is received + setTimeout(function() { + this.sqlPanels[0].finishLoading(); + }, 1000); }, 400); }, sqlPanelVisibilityChanged: function(panel) { diff --git a/web/pgadmin/misc/statistics/static/js/statistics.js b/web/pgadmin/misc/statistics/static/js/statistics.js index 5278271..782669e 100644 --- a/web/pgadmin/misc/statistics/static/js/statistics.js +++ b/web/pgadmin/misc/statistics/static/js/statistics.js @@ -139,14 +139,15 @@ function(_, $, pgBrowser, Backgrid) { }, // Fetch the actual data and update the collection - __updateCollection: function(url, node) { + __updateCollection: function(url, node, item, node_type) { var $container = this.panel[0].layout().scene().find('.pg-panel-content'), $msgContainer = $container.find('.pg-panel-statistics-message'), $gridContainer = $container.find('.pg-panel-statistics-container'), collection = this.collection, panel = this.panel, self = this, - msg = ''; + msg = '', + n_type = node_type; if (node) { msg = pgBrowser.messages.NODE_HAS_NO_STATISTICS; @@ -154,11 +155,30 @@ function(_, $, pgBrowser, Backgrid) { * showStatistics function. */ if (node.hasStatistics) { + + // Avoid unnecessary reloads + var treeHierarchy = node.getTreeNodeHierarchy(item); + if (_.isUndefined(treeHierarchy[n_type]) || + _.isUndefined(treeHierarchy[n_type]._id)) { + n_value = undefined, + n_value = -1; + } else { + n_value = treeHierarchy[n_type]._id; + } + + if (n_value == $(this.panel[0]).data(n_type)) { + return; + } + + // Cache the current IDs for next time + $(this.panel[0]).data(n_type, n_value); + /* Set the message because ajax request may take time to * fetch the information from the server. */ msg = ''; $msgContainer.text(msg); + this.panel[0].startLoading(); // Set the url, fetch the data and update the collection $.ajax({ @@ -166,6 +186,9 @@ function(_, $, pgBrowser, Backgrid) { type:'GET', success: function(res) { if (res.data) { + setTimeout(function() { + self.panel[0].finishLoading(); + }, 1000); var data = res.data; if (node.hasCollectiveStatistics || data['rows'].length > 1) { self.__createMultiLineStatistics.call(self, data); @@ -236,7 +259,7 @@ function(_, $, pgBrowser, Backgrid) { self.timeout = setTimeout( function() { self.__updateCollection.call( - self, node.generate_url(item, 'stats', data, true), node + self, node.generate_url(item, 'stats', data, true), node, item, data._type ); }, 400); } diff --git a/web/pgadmin/static/css/overrides.css b/web/pgadmin/static/css/overrides.css index eda27e1..7b231eb 100755 --- a/web/pgadmin/static/css/overrides.css +++ b/web/pgadmin/static/css/overrides.css @@ -1349,3 +1349,7 @@ height: calc(100% - 35px); table.backgrid { overflow: auto; } + +.aciTree.aciTreeLoad { + background: none; +} diff --git a/web/pgadmin/static/css/wcDocker/Themes/pgadmin.css b/web/pgadmin/static/css/wcDocker/Themes/pgadmin.css index 7cbc7d6..d0e9691 100644 --- a/web/pgadmin/static/css/wcDocker/Themes/pgadmin.css +++ b/web/pgadmin/static/css/wcDocker/Themes/pgadmin.css @@ -342,7 +342,30 @@ span.fa.fa-arrow-left, .fa-arrow-right { visibility: hidden; } - i.wcTabIcon { min-width: 20px; -} \ No newline at end of file +} + +.wcLoadingBackground { + background: black; + opacity: 0.6 !important; +} + +.wcLoadingIcon.fa-spinner { + position: absolute; + font-size: 50px; + color: #ccc; + top: 40%; + left: calc(50% - 100px); + height: 49px !important; +} + +.wcLoadingLabel { + top: 46%; + left: 0; + color: #fff; + width: calc(100% - 131px); + font-size: 20px; + position: absolute; + text-align: center; +} diff --git a/web/pgadmin/tools/datagrid/templates/datagrid/index.html b/web/pgadmin/tools/datagrid/templates/datagrid/index.html index 473eff9..516bd8d 100644 --- a/web/pgadmin/tools/datagrid/templates/datagrid/index.html +++ b/web/pgadmin/tools/datagrid/templates/datagrid/index.html @@ -14,10 +14,10 @@ {% endif %}
-
- - +
+
+ +