Add shortcuts for View Data and the Query tool to the Browser header bar. Fixes #3564

This commit is contained in:
Akshay Joshi
2018-09-10 15:16:13 +01:00
committed by Dave Page
parent 1850a3a995
commit 532cbe216a
15 changed files with 287 additions and 24 deletions

View File

@@ -74,6 +74,7 @@ Contents:
browser browser
pgadmin_menu_bar pgadmin_menu_bar
pgadmin_toolbar
pgadmin_tabbed_browser pgadmin_tabbed_browser
pgadmin_tree_control pgadmin_tree_control
preferences preferences

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 189 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View File

@@ -0,0 +1,16 @@
.. _pgadmin_toolbar:
*************************
`pgAdmin Toolbar`:index:
*************************
The pgAdmin toolbar provides shortcut buttons for frequently used features like View Data and the Query Tool
which are most frequently used in pgAdmin.
This toolbar is visible on the Browser panel. Buttons get enabled/disabled based on the selected browser node.
.. image:: /images/pgadmin_toolbar.png
:alt: pgAdmin Toolbar
* Use the :ref:`Query Tool <query_tool>` button to open the Query Tool in the current database context.
* Use the :ref:`View Data <editgrid>` button to view/edit the data stored in a selected table.
* Use the :ref:`Filtered Rows <editgrid>` button to access the Data Filter popup to apply a filter to a set of data for viewing/editing.

View File

@@ -12,6 +12,7 @@ Features
| `Feature #2927 <https://redmine.postgresql.org/issues/2927>`_ - Move all CSS into SCSS files for consistency and ease of colour maintenance etc. | `Feature #2927 <https://redmine.postgresql.org/issues/2927>`_ - Move all CSS into SCSS files for consistency and ease of colour maintenance etc.
| `Feature #3514 <https://redmine.postgresql.org/issues/3514>`_ - Add optional data point markers and mouse-over tooltips to display values on graphs. | `Feature #3514 <https://redmine.postgresql.org/issues/3514>`_ - Add optional data point markers and mouse-over tooltips to display values on graphs.
| `Feature #3564 <https://redmine.postgresql.org/issues/3564>`_ - Add shortcuts for View Data and the Query tool to the Browser header bar.
Bug fixes Bug fixes
********* *********

View File

@@ -94,7 +94,7 @@
"underscore": "^1.8.3", "underscore": "^1.8.3",
"underscore.string": "^3.3.4", "underscore.string": "^3.3.4",
"watchify": "~3.9.0", "watchify": "~3.9.0",
"webcabin-docker": "git+https://github.com/EnterpriseDB/wcDocker", "webcabin-docker": "git+https://github.com/EnterpriseDB/wcDocker/#5fbdf05a6757464d2fa2c2b017322c97688b2105",
"wkx": "^0.4.5" "wkx": "^0.4.5"
}, },
"scripts": { "scripts": {

View File

@@ -60,3 +60,18 @@
.pgadmin_header_logo { .pgadmin_header_logo {
cursor: default; cursor: default;
} }
.pg-toolbar-btn {
width: 25px !important;
height: 23px !important;
border: 1px solid !important;
background-color: #fff !important;
font-size: 14px !important;
color: #333 !important;
border-color: #adadad !important;
}
.pg-toolbar-btn:hover {
border: 1px solid $color-gray-light !important;
background-color: #e6e6e6 !important;
}

View File

@@ -2,7 +2,7 @@ define('pgadmin.browser', [
'sources/tree/tree', 'sources/tree/tree',
'sources/gettext', 'sources/url_for', 'require', 'jquery', 'underscore', 'underscore.string', 'sources/gettext', 'sources/url_for', 'require', 'jquery', 'underscore', 'underscore.string',
'bootstrap', 'sources/pgadmin', 'pgadmin.alertifyjs', 'bundled_codemirror', 'bootstrap', 'sources/pgadmin', 'pgadmin.alertifyjs', 'bundled_codemirror',
'sources/check_node_visibility', 'pgadmin.browser.utils', 'wcdocker', 'sources/check_node_visibility', './toolbar', 'pgadmin.browser.utils', 'wcdocker',
'jquery.contextmenu', 'jquery.aciplugin', 'jquery.acitree', 'pgadmin.browser.preferences', 'jquery.contextmenu', 'jquery.aciplugin', 'jquery.acitree', 'pgadmin.browser.preferences',
'pgadmin.browser.messages', 'pgadmin.browser.messages',
'pgadmin.browser.menu', 'pgadmin.browser.panel', 'pgadmin.browser.menu', 'pgadmin.browser.panel',
@@ -13,7 +13,7 @@ define('pgadmin.browser', [
], function( ], function(
tree, tree,
gettext, url_for, require, $, _, S, Bootstrap, pgAdmin, Alertify, gettext, url_for, require, $, _, S, Bootstrap, pgAdmin, Alertify,
codemirror, checkNodeVisibility codemirror, checkNodeVisibility, toolBar
) { ) {
window.jQuery = window.$ = $; window.jQuery = window.$ = $;
// Some scripts do export their object in the window only. // Some scripts do export their object in the window only.
@@ -119,6 +119,9 @@ define('pgadmin.browser', [
isPrivate: true, isPrivate: true,
icon: 'fa fa-binoculars', icon: 'fa fa-binoculars',
content: '<div id="tree" class="aciTree"></div>', content: '<div id="tree" class="aciTree"></div>',
onCreate: function(panel) {
toolBar.initializeToolbar(panel, wcDocker);
},
}), }),
// Properties of the object node // Properties of the object node
'properties': new pgAdmin.Browser.Panel({ 'properties': new pgAdmin.Browser.Panel({
@@ -289,6 +292,9 @@ define('pgadmin.browser', [
} }
}; };
toolBar.enable(gettext('View Data'), false);
toolBar.enable(gettext('Filtered Rows'), false);
// All menus from the object menus (except the create drop-down // All menus from the object menus (except the create drop-down
// menu) needs to be removed. // menu) needs to be removed.
$obj_mnu.empty(); $obj_mnu.empty();

View File

@@ -0,0 +1,90 @@
import gettext from 'sources/gettext';
import _ from 'underscore';
import pgAdmin from 'sources/pgadmin';
let _toolbarButtons = {};
let _browserPanel = null;
// Default Tool Bar Buttons.
let _defaultToolBarButtons = [
{
label: gettext('Filtered Rows'),
btnClass: 'fa fa-filter',
text: '',
toggled: false,
toggleClass: '',
parentClass: 'pg-toolbar-btn',
enabled: false,
},
{
label: gettext('View Data'),
btnClass: 'fa fa-table',
text: '',
toggled: false,
toggleClass: '',
parentClass: 'pg-toolbar-btn',
enabled: false,
},
{
label: gettext('Query Tool'),
btnClass: 'fa fa-bolt',
text: '',
toggled: false,
toggleClass: '',
parentClass: 'pg-toolbar-btn',
enabled: false,
},
];
// Place holder for non default tool bar buttons.
let _otherToolbarButtons = [];
// This function is used to add button into the browser panel.
function registerToolBarButton(btn) {
if (!(btn.label in _toolbarButtons)) {
_browserPanel.addButton(
btn.label, btn.btnClass, btn.text, btn.label, btn.toggled,
btn.toggleClass, btn.parentClass, btn.enabled
);
_toolbarButtons[btn.label] = btn;
}
}
// This function is used to add tool bar button and
// listen on the button event.
export function initializeToolbar(panel, wcDocker) {
_browserPanel = panel;
// Iterate through default tool bar buttons and add them into the
// browser panel.
_.each(_defaultToolBarButtons, (btn) => {
registerToolBarButton(btn);
});
// Iterate through other tool bar buttons and add them into the
// browser panel.
_.each(_otherToolbarButtons, (btn) => {
registerToolBarButton(btn);
});
// Listen on button click event.
panel.on(wcDocker.EVENT.BUTTON, function(data) {
if ('name' in data && data.name === 'Query Tool')
pgAdmin.DataGrid.show_query_tool('', pgAdmin.Browser.tree.selected());
else if ('name' in data && data.name === 'View Data')
pgAdmin.DataGrid.show_data_grid({mnuid: 1}, pgAdmin.Browser.tree.selected());
else if ('name' in data && data.name === 'Filtered Rows')
pgAdmin.DataGrid.show_filtered_row({mnuid: 4}, pgAdmin.Browser.tree.selected());
});
}
// This function is used to enable/disable the specific button
// based on their label.
export function enable(label, enable) {
if (label in _toolbarButtons) {
_browserPanel.buttonEnable(label, enable);
} else {
console.warn('Developer warning: No tool button found with label: ' + label);
}
}

View File

@@ -0,0 +1,115 @@
##########################################################################
#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#
##########################################################################
from __future__ import print_function
import sys
import random
import time
from regression.python_test_utils import test_utils
from regression.feature_utils.base_feature_test import BaseFeatureTest
from selenium.common.exceptions import TimeoutException, \
StaleElementReferenceException
class BrowserToolBarFeatureTest(BaseFeatureTest):
"""
This feature test will test the tool bar on Browser panel.
"""
scenarios = [
("Browser tool bar feature test", dict())
]
test_table_name = ""
def before(self):
self.page.wait_for_spinner_to_disappear()
self.page.add_server(self.server)
self.test_table_name = "test_table" + str(random.randint(1000, 3000))
test_utils.create_table(self.server, self.test_db,
self.test_table_name)
def runTest(self):
# Check for query tool button
print("\nQuery Tool ToolBar Button ",
file=sys.stderr, end="")
self.test_query_tool_button()
print("OK.", file=sys.stderr)
# Check for view data button
print("\nView Data ToolBar Button ",
file=sys.stderr, end="")
self.test_view_data_tool_button()
print("OK.", file=sys.stderr)
# Check for filtered rows button
print("\nFiltered Rows ToolBar Button ",
file=sys.stderr, end="")
self.test_filtered_rows_tool_button()
print("OK.", file=sys.stderr)
def after(self):
self.page.remove_server(self.server)
def _locate_database_tree_node(self):
self.page.toggle_open_tree_item(self.server['name'])
self.page.toggle_open_tree_item('Databases')
self.page.toggle_open_tree_item(self.test_db)
def test_query_tool_button(self):
self._locate_database_tree_node()
retry_count = 0
while retry_count < 5:
try:
self.page.find_by_xpath(
"//*[contains(@class,'pg-toolbar-btn') and "
"contains(@title, 'Query Tool')]").click()
break
except StaleElementReferenceException:
retry_count += 1
time.sleep(0.5)
self.page.find_by_xpath("//*[contains(@class,'wcTabIcon fa fa-bolt')]")
def test_view_data_tool_button(self):
self.page.toggle_open_tree_item('Schemas')
self.page.toggle_open_tree_item('public')
self.page.toggle_open_tree_item('Tables')
self.page.select_tree_item(self.test_table_name)
retry_count = 0
while retry_count < 5:
try:
self.page.find_by_xpath(
"//*[contains(@class,'pg-toolbar-btn') and "
"contains(@title, 'View Data')]").click()
break
except StaleElementReferenceException:
retry_count += 1
time.sleep(0.5)
self.page.find_by_xpath("//*[contains(@class,'wcTabIcon fa fa-bolt')]")
def test_filtered_rows_tool_button(self):
retry_count = 0
while retry_count < 5:
try:
self.page.find_by_xpath(
"//*[contains(@class,'pg-toolbar-btn') and "
"contains(@title, 'Filtered Rows')]").click()
break
except StaleElementReferenceException:
retry_count += 1
time.sleep(0.5)
self.page.find_by_xpath("//*[contains(@class, 'ajs-header') and "
"contains(., 'Data Filter')]")
self.page.click_modal('Cancel')

View File

@@ -13,8 +13,6 @@ import random
from selenium.webdriver import ActionChains from selenium.webdriver import ActionChains
from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from regression.python_test_utils import test_utils from regression.python_test_utils import test_utils
from regression.feature_utils.base_feature_test import BaseFeatureTest from regression.feature_utils.base_feature_test import BaseFeatureTest

View File

@@ -43,6 +43,11 @@
margin-right: 2px; margin-right: 2px;
} }
.wcFrameButton.disabled {
pointer-events: none;
opacity: 0.4;
}
.wcFrameMiniButton { .wcFrameMiniButton {
width: 8px; width: 8px;
} }
@@ -289,7 +294,10 @@ ul.dropdown-menu > li.menu-item > a > i.wcTabIcon {
width: 14px; width: 14px;
} }
.wcFrameButton .fa.fa-close { .wcFrameButton .fa.fa-close,
.wcFrameButton .fa.fa-filter,
.wcFrameButton .fa.fa-table,
.wcFrameButton .fa.fa-bolt {
margin-top: 3.5px; margin-top: 3.5px;
padding-left: 1px; padding-left: 1px;
} }

View File

@@ -4,11 +4,11 @@ define('pgadmin.datagrid', [
'sources/sqleditor_utils', 'backbone', 'sources/sqleditor_utils', 'backbone',
'tools/datagrid/static/js/show_data', 'tools/datagrid/static/js/show_data',
'tools/datagrid/static/js/get_panel_title', 'tools/datagrid/static/js/get_panel_title',
'tools/datagrid/static/js/show_query_tool', 'tools/datagrid/static/js/show_query_tool', 'pgadmin.browser.toolbar',
'wcdocker', 'wcdocker',
], function( ], function(
gettext, url_for, $, _, alertify, pgAdmin, codemirror, sqlEditorUtils, gettext, url_for, $, _, alertify, pgAdmin, codemirror, sqlEditorUtils,
Backbone, showData, panelTitle, showQueryTool Backbone, showData, panelTitle, showQueryTool, toolBar
) { ) {
// Some scripts do export their object in the window only. // Some scripts do export their object in the window only.
// Generally the one, which do no have AMD support. // Generally the one, which do no have AMD support.
@@ -64,10 +64,16 @@ define('pgadmin.datagrid', [
* otherwise disabled. * otherwise disabled.
*/ */
view_menu_enabled = function(obj) { view_menu_enabled = function(obj) {
if (!_.isUndefined(obj) && !_.isNull(obj)) var isEnabled = (() => {
return (_.indexOf(supported_nodes, obj._type) !== -1 ? true : false); if (!_.isUndefined(obj) && !_.isNull(obj))
else return (_.indexOf(supported_nodes, obj._type) !== -1 ? true : false);
return false; else
return false;
})();
toolBar.enable(gettext('View Data'), isEnabled);
toolBar.enable(gettext('Filtered Rows'), isEnabled);
return isEnabled;
}, },
/* Enable/disable Query tool menu in tools based /* Enable/disable Query tool menu in tools based
@@ -76,20 +82,26 @@ define('pgadmin.datagrid', [
* otherwise enabled. * otherwise enabled.
*/ */
query_tool_menu_enabled = function(obj) { query_tool_menu_enabled = function(obj) {
if (!_.isUndefined(obj) && !_.isNull(obj)) { var isEnabled = (() => {
if (_.indexOf(pgAdmin.unsupported_nodes, obj._type) == -1) { if (!_.isUndefined(obj) && !_.isNull(obj)) {
if (obj._type == 'database' && obj.allowConn) if (_.indexOf(pgAdmin.unsupported_nodes, obj._type) == -1) {
return true; if (obj._type == 'database' && obj.allowConn) {
else if (obj._type != 'database') return true;
return true; } else if (obj._type != 'database') {
else return true;
} else {
return false;
}
} else {
return false; return false;
}
} else { } else {
return false; return false;
} }
} else { })();
return false;
} toolBar.enable(gettext('Query Tool'), isEnabled);
return isEnabled;
}; };
// Define the nodes on which the menus to be appear // Define the nodes on which the menus to be appear

View File

@@ -189,6 +189,7 @@ var webpackShimConfig = {
'pgadmin.browser.object_sql': path.join(__dirname, './pgadmin/misc/sql/static/js/sql'), 'pgadmin.browser.object_sql': path.join(__dirname, './pgadmin/misc/sql/static/js/sql'),
'pgadmin.browser.object_statistics': path.join(__dirname, './pgadmin/misc/statistics/static/js/statistics'), 'pgadmin.browser.object_statistics': path.join(__dirname, './pgadmin/misc/statistics/static/js/statistics'),
'pgadmin.browser.panel': path.join(__dirname, './pgadmin/browser/static/js/panel'), 'pgadmin.browser.panel': path.join(__dirname, './pgadmin/browser/static/js/panel'),
'pgadmin.browser.toolbar': path.join(__dirname, './pgadmin/browser/static/js/toolbar'),
'pgadmin.browser.server.privilege': path.join(__dirname, './pgadmin/browser/server_groups/servers/static/js/privilege'), 'pgadmin.browser.server.privilege': path.join(__dirname, './pgadmin/browser/server_groups/servers/static/js/privilege'),
'pgadmin.browser.server.variable': path.join(__dirname, './pgadmin/browser/server_groups/servers/static/js/variable'), 'pgadmin.browser.server.variable': path.join(__dirname, './pgadmin/browser/server_groups/servers/static/js/variable'),
'pgadmin.browser.table.partition.utils': path.join(__dirname, './pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/partition.utils'), 'pgadmin.browser.table.partition.utils': path.join(__dirname, './pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/partition.utils'),

View File

@@ -9517,9 +9517,9 @@ watchpack@^1.4.0:
graceful-fs "^4.1.2" graceful-fs "^4.1.2"
neo-async "^2.5.0" neo-async "^2.5.0"
"webcabin-docker@git+https://github.com/EnterpriseDB/wcDocker": "webcabin-docker@git+https://github.com/EnterpriseDB/wcDocker/#5fbdf05a6757464d2fa2c2b017322c97688b2105":
version "2.2.4-dev" version "2.2.4-dev"
resolved "git+https://github.com/EnterpriseDB/wcDocker#447cb46953537b6a0e007890910787ac0ab18f38" resolved "git+https://github.com/EnterpriseDB/wcDocker/#5fbdf05a6757464d2fa2c2b017322c97688b2105"
dependencies: dependencies:
FileSaver "^0.10.0" FileSaver "^0.10.0"
font-awesome "^4.7.0" font-awesome "^4.7.0"