diff --git a/docs/en_US/release_notes_5_0.rst b/docs/en_US/release_notes_5_0.rst index 4d0344ee4..2e4ae1aa5 100644 --- a/docs/en_US/release_notes_5_0.rst +++ b/docs/en_US/release_notes_5_0.rst @@ -11,6 +11,7 @@ New features | `Issue #5912 `_ - Added support for Logical Replication. | `Issue #5967 `_ - Implemented runtime using NWjs to open pgAdmin4 in a standalone window instead of the system tray and web browser. +| `Issue #6148 `_ - Added Quick Search functionality for menu items and help articles. | `Issue #6170 `_ - Rotate the logfile in the container distribution. Housekeeping diff --git a/web/pgadmin/browser/register_browser_preferences.py b/web/pgadmin/browser/register_browser_preferences.py index 7f909c41f..235db0271 100644 --- a/web/pgadmin/browser/register_browser_preferences.py +++ b/web/pgadmin/browser/register_browser_preferences.py @@ -443,6 +443,19 @@ def register_browser_preferences(self): fields=fields ) + self.preference.register( + 'keyboard_shortcuts', 'open_quick_search', + gettext('Quick Search'), 'keyboardshortcut', + { + 'alt': False, + 'shift': True, + 'control': True, + 'key': {'key_code': 70, 'char': 'f'} + }, + category_label=PREF_LABEL_KEYBOARD_SHORTCUTS, + fields=fields + ) + self.dynamic_tab_title = self.preference.register( 'tab_settings', 'dynamic_tabs', gettext("Dynamic tab size"), 'boolean', False, diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/static/js/package.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/static/js/package.js index a62ad0b80..ccdf46d90 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/static/js/package.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/static/js/package.js @@ -48,19 +48,22 @@ define('pgadmin.node.package', [ name: 'create_package_on_coll', node: 'coll-package', module: this, applies: ['object', 'context'], callback: 'show_obj_properties', category: 'create', priority: 4, label: gettext('Package...'), - icon: 'wcTabIcon icon-package', data: {action: 'create', check: true}, + icon: 'wcTabIcon icon-package', data: {action: 'create', check: true, + 'data_disabled': gettext('This option is only available on EPAS servers.')}, enable: 'canCreate', },{ name: 'create_package', node: 'package', module: this, applies: ['object', 'context'], callback: 'show_obj_properties', category: 'create', priority: 4, label: gettext('Package...'), - icon: 'wcTabIcon icon-package', data: {action: 'create', check: true}, + icon: 'wcTabIcon icon-package', data: {action: 'create', check: true, + 'data_disabled': gettext('This option is only available on EPAS servers.')}, enable: 'canCreate', },{ name: 'create_package', node: 'schema', module: this, applies: ['object', 'context'], callback: 'show_obj_properties', category: 'create', priority: 4, label: gettext('Package...'), - icon: 'wcTabIcon icon-package', data: {action: 'create', check: true}, + icon: 'wcTabIcon icon-package', data: {action: 'create', check: true, + 'data_disabled': gettext('This option is only available on EPAS servers.')}, enable: 'canCreate', }, ]); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/static/js/synonym.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/static/js/synonym.js index 0523709a0..4addef5e6 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/static/js/synonym.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/static/js/synonym.js @@ -47,19 +47,22 @@ define('pgadmin.node.synonym', [ name: 'create_synonym_on_coll', node: 'coll-synonym', module: this, applies: ['object', 'context'], callback: 'show_obj_properties', category: 'create', priority: 4, label: gettext('Synonym...'), - icon: 'wcTabIcon icon-synonym', data: {action: 'create', check: true}, + icon: 'wcTabIcon icon-synonym', data: {action: 'create', check: true, + 'data_disabled': gettext('This option is only available on EPAS servers.')}, enable: 'canCreate', },{ name: 'create_synonym', node: 'synonym', module: this, applies: ['object', 'context'], callback: 'show_obj_properties', category: 'create', priority: 4, label: gettext('Synonym...'), - icon: 'wcTabIcon icon-synonym', data: {action: 'create', check: true}, + icon: 'wcTabIcon icon-synonym', data: {action: 'create', check: true, + 'data_disabled': gettext('This option is only available on EPAS servers.')}, enable: 'canCreate', },{ name: 'create_synonym', node: 'schema', module: this, applies: ['object', 'context'], callback: 'show_obj_properties', category: 'create', priority: 4, label: gettext('Synonym...'), - icon: 'wcTabIcon icon-synonym', data: {action: 'create', check: true}, + icon: 'wcTabIcon icon-synonym', data: {action: 'create', check: true, + 'data_disabled': gettext('This option is only available on EPAS servers.')}, enable: 'canCreate', }, ]); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/static/js/compound_trigger.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/static/js/compound_trigger.js index 57d01b5a0..55d3119f6 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/static/js/compound_trigger.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/static/js/compound_trigger.js @@ -54,25 +54,29 @@ define('pgadmin.node.compound_trigger', [ name: 'create_compound_trigger_on_coll', node: 'coll-compound_trigger', module: this, applies: ['object', 'context'], callback: 'show_obj_properties', category: 'create', priority: 4, label: gettext('Compound Trigger...'), - icon: 'wcTabIcon icon-compound_trigger', data: {action: 'create', check: true}, + icon: 'wcTabIcon icon-compound_trigger', data: {action: 'create', check: true, + 'data_disabled': gettext('This option is only available on EPAS servers.')}, enable: 'canCreate', },{ name: 'create_compound_trigger', node: 'compound_trigger', module: this, applies: ['object', 'context'], callback: 'show_obj_properties', category: 'create', priority: 4, label: gettext('Compound Trigger...'), - icon: 'wcTabIcon icon-compound_trigger', data: {action: 'create', check: true}, + icon: 'wcTabIcon icon-compound_trigger', data: {action: 'create', check: true, + 'data_disabled': gettext('This option is only available on EPAS servers.')}, enable: 'canCreate', },{ name: 'create_compound_trigger_onTable', node: 'table', module: this, applies: ['object', 'context'], callback: 'show_obj_properties', category: 'create', priority: 4, label: gettext('Compound Trigger...'), - icon: 'wcTabIcon icon-compound_trigger', data: {action: 'create', check: true}, + icon: 'wcTabIcon icon-compound_trigger', data: {action: 'create', check: true, + 'data_disabled': gettext('This option is only available on EPAS servers.')}, enable: 'canCreate', },{ name: 'create_compound_trigger_onPartition', node: 'partition', module: this, applies: ['object', 'context'], callback: 'show_obj_properties', category: 'create', priority: 4, label: gettext('Compound Trigger...'), - icon: 'wcTabIcon icon-compound_trigger', data: {action: 'create', check: true}, + icon: 'wcTabIcon icon-compound_trigger', data: {action: 'create', check: true, + 'data_disabled': gettext('This option is only available on EPAS servers.')}, enable: 'canCreate', },{ name: 'enable_compound_trigger', node: 'compound_trigger', module: this, @@ -88,7 +92,8 @@ define('pgadmin.node.compound_trigger', [ name: 'create_compound_trigger_onView', node: 'view', module: this, applies: ['object', 'context'], callback: 'show_obj_properties', category: 'create', priority: 4, label: gettext('Compound Trigger...'), - icon: 'wcTabIcon icon-compound_trigger', data: {action: 'create', check: true}, + icon: 'wcTabIcon icon-compound_trigger', data: {action: 'create', check: true, + 'data_disabled': gettext('This option is only available on EPAS servers.')}, enable: 'canCreate', }, ]); 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 eab774ded..9334edcd7 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 @@ -76,12 +76,16 @@ define('pgadmin.node.database', [ name: 'connect_database', node: 'database', module: this, applies: ['object', 'context'], callback: 'connect_database', category: 'connect', priority: 4, label: gettext('Connect Database...'), - icon: 'fa fa-link', enable : 'is_not_connected', + icon: 'fa fa-link', enable : 'is_not_connected', data: { + 'data_disabled': gettext('Selected database is already connected.'), + }, },{ name: 'disconnect_database', node: 'database', module: this, applies: ['object', 'context'], callback: 'disconnect_database', category: 'drop', priority: 5, label: gettext('Disconnect Database...'), - icon: 'fa fa-unlink', enable : 'is_connected', + icon: 'fa fa-unlink', enable : 'is_connected',data: { + 'data_disabled': gettext('Selected database is already disconnected.'), + }, },{ name: 'generate_erd', node: 'database', module: this, applies: ['object', 'context'], callback: 'generate_erd', diff --git a/web/pgadmin/browser/server_groups/servers/resource_groups/static/js/resource_group.js b/web/pgadmin/browser/server_groups/servers/resource_groups/static/js/resource_group.js index 50156ca73..2752761d2 100644 --- a/web/pgadmin/browser/server_groups/servers/resource_groups/static/js/resource_group.js +++ b/web/pgadmin/browser/server_groups/servers/resource_groups/static/js/resource_group.js @@ -48,7 +48,8 @@ define('pgadmin.node.resource_group', [ name: 'create_resourcegroup_on_server', node: 'server', module: this, applies: ['object', 'context'], callback: 'show_obj_properties', category: 'create', priority: 4, label: gettext('Resource Group...'), - icon: 'wcTabIcon icon-resource_group', data: {action: 'create'}, + icon: 'wcTabIcon icon-resource_group', data: {action: 'create', + 'data_disabled': gettext('This option is only available on EPAS servers.')}, /* Function is used to check the server type and version. * Resource Group only supported in PPAS 9.4 and above. */ @@ -62,12 +63,14 @@ define('pgadmin.node.resource_group', [ name: 'create_resource_group_on_coll', node: 'coll-resource_group', module: this, applies: ['object', 'context'], callback: 'show_obj_properties', category: 'create', priority: 4, label: gettext('Resource Group...'), - icon: 'wcTabIcon icon-resource_group', data: {action: 'create'}, + icon: 'wcTabIcon icon-resource_group', data: {action: 'create', + 'data_disabled': gettext('This option is only available on EPAS servers.')}, },{ name: 'create_resource_group', node: 'resource_group', module: this, applies: ['object', 'context'], callback: 'show_obj_properties', category: 'create', priority: 4, label: gettext('Resource Group...'), - icon: 'wcTabIcon icon-resource_group', data: {action: 'create'}, + icon: 'wcTabIcon icon-resource_group', data: {action: 'create', + 'data_disabled': gettext('This option is only available on EPAS servers.')}, }, ]); }, 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 13c00c4dc..72da6ca2d 100644 --- a/web/pgadmin/browser/server_groups/servers/static/js/server.js +++ b/web/pgadmin/browser/server_groups/servers/static/js/server.js @@ -100,12 +100,16 @@ define('pgadmin.node.server', [ name: 'reload_configuration', node: 'server', module: this, applies: ['tools', 'context'], callback: 'reload_configuration', category: 'reload', priority: 6, label: gettext('Reload Configuration'), - icon: 'fa fa-redo-alt', enable : 'enable_reload_config', + icon: 'fa fa-redo-alt', enable : 'enable_reload_config',data: { + 'data_disabled': gettext('Please select a server from the browser tree to reload the configuration files.'), + }, },{ name: 'restore_point', node: 'server', module: this, applies: ['tools', 'context'], callback: 'restore_point', category: 'restore', priority: 9, label: gettext('Add Named Restore Point...'), - icon: 'fa fa-anchor', enable : 'is_applicable', + icon: 'fa fa-anchor', enable : 'is_applicable',data: { + 'data_disabled': gettext('Please select any server from the browser tree to Add Named Restore Point.'), + }, },{ name: 'change_password', node: 'server', module: this, applies: ['object'], callback: 'change_password', @@ -115,12 +119,16 @@ define('pgadmin.node.server', [ name: 'wal_replay_pause', node: 'server', module: this, applies: ['tools', 'context'], callback: 'pause_wal_replay', category: 'wal_replay_pause', priority: 7, label: gettext('Pause Replay of WAL'), - icon: 'fa fa-pause-circle', enable : 'wal_pause_enabled', + icon: 'fa fa-pause-circle', enable : 'wal_pause_enabled',data: { + 'data_disabled': gettext('Please select a connected database as a Super user and run in Recovery mode to Pause Replay of WAL.'), + }, },{ name: 'wal_replay_resume', node: 'server', module: this, applies: ['tools', 'context'], callback: 'resume_wal_replay', category: 'wal_replay_resume', priority: 8, label: gettext('Resume Replay of WAL'), - icon: 'fa fa-play-circle', enable : 'wal_resume_enabled', + icon: 'fa fa-play-circle', enable : 'wal_resume_enabled',data: { + 'data_disabled': gettext('Please select a connected database as a Super user and run in Recovery mode to Resume Replay of WAL.'), + }, },{ name: 'clear_saved_password', node: 'server', module: this, applies: ['object', 'context'], callback: 'clear_saved_password', @@ -145,6 +153,9 @@ define('pgadmin.node.server', [ } return false; }, + data: { + 'data_disabled': gettext('SSH Tunnel password is not saved for selected server.'), + }, }]); _.bindAll(this, 'connection_lost'); diff --git a/web/pgadmin/browser/static/js/browser.js b/web/pgadmin/browser/static/js/browser.js index 475412bf7..6ae092bbb 100644 --- a/web/pgadmin/browser/static/js/browser.js +++ b/web/pgadmin/browser/static/js/browser.js @@ -875,6 +875,10 @@ define('pgadmin.browser', [ var $mnu = navbar.children(o.id).first(), $dropdown = $mnu.children('.dropdown-menu').first(); $dropdown.empty(); + if(o.menu == 'help'){ + $dropdown.append('
'); + $dropdown.append(''); + } if (pgAdmin.Browser.MenuCreator( obj.Nodes, $dropdown, obj.menus[o.menu], obj.menu_categories @@ -902,6 +906,7 @@ define('pgadmin.browser', [ } else if(type == 'dialog_help') { window.open(url, 'pgadmin_help'); } + $('#live-search-field').focus(); }, _findTreeChildNode: function(_i, _d, _o) { var loaded = _o.t.wasLoad(_i), @@ -2224,6 +2229,8 @@ define('pgadmin.browser', [ if (pgBrowser.utils.useSpaces == 'True') { pgAdmin.Browser.editor_shortcut_keys.Tab = 'insertSoftTab'; } - + setTimeout(function(){ + $('#mnu_about').closest('li').before(''); + }, 100); return pgAdmin.Browser; }); diff --git a/web/pgadmin/browser/static/js/keyboard.js b/web/pgadmin/browser/static/js/keyboard.js index 3381162d0..a69c7009f 100644 --- a/web/pgadmin/browser/static/js/keyboard.js +++ b/web/pgadmin/browser/static/js/keyboard.js @@ -44,6 +44,7 @@ _.extend(pgBrowser.keyboardNavigation, { 'drop_multiple_objects': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'grid_menu_drop_multiple').value), 'drop_cascade_multiple_objects': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'grid_menu_drop_cascade_multiple').value), 'add_grid_row': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'add_grid_row').value), + 'open_quick_search': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'open_quick_search').value), }; this.shortcutMethods = { @@ -66,6 +67,7 @@ _.extend(pgBrowser.keyboardNavigation, { 'bindDropMultipleObjects': {'shortcuts': this.keyboardShortcut.drop_multiple_objects}, // Grid Menu Drop Multiple 'bindDropCascadeMultipleObjects': {'shortcuts': this.keyboardShortcut.drop_cascade_multiple_objects}, // Grid Menu Drop Cascade Multiple 'bindAddGridRow': {'shortcuts': this.keyboardShortcut.add_grid_row}, // Subnode Grid Add Row + 'bindOpenQuickSearch': {'shortcuts': this.keyboardShortcut.open_quick_search}, // Subnode Grid Refresh Row }; this.bindShortcuts(); } @@ -383,6 +385,9 @@ _.extend(pgBrowser.keyboardNavigation, { return new dialogTabNavigator.dialogTabNavigator(dialogContainer, backward_shortcut, forward_shortcut); }, + bindOpenQuickSearch: function() { + $('#search_icon').trigger('click'); + }, }); module.exports = pgAdmin.Browser.keyboardNavigation; diff --git a/web/pgadmin/browser/static/js/menu.js b/web/pgadmin/browser/static/js/menu.js index 53d40dcbe..b2f12ff47 100644 --- a/web/pgadmin/browser/static/js/menu.js +++ b/web/pgadmin/browser/static/js/menu.js @@ -67,12 +67,17 @@ define([ }, this.menu_items); this.$el = create_submenu.$el; } else { + var data_disabled = null; + if(this.data != undefined && this.data.data_disabled != undefined){ + data_disabled = this.data.data_disabled; + } var url = $('', { 'id': this.name, 'href': this.url, 'target': this.target, 'data-toggle': 'pg-menu', 'role': 'menuitem', + 'data-disabled': data_disabled, }).data('pgMenu', { module: this.module || pgAdmin.Browser, cb: this.callback, diff --git a/web/pgadmin/browser/static/js/node.js b/web/pgadmin/browser/static/js/node.js index 12226fe2f..21ff1bf87 100644 --- a/web/pgadmin/browser/static/js/node.js +++ b/web/pgadmin/browser/static/js/node.js @@ -150,6 +150,7 @@ define('pgadmin.browser.node', [ label: (self.dropAsRemove) ? gettext('Remove %s', self.label) : gettext('Delete/Drop'), data: { 'url': 'drop', + 'data_disabled': gettext('The selected tree node does not support this option.'), }, icon: 'fa fa-trash-alt', enable: _.isFunction(self.canDrop) ? @@ -232,6 +233,7 @@ define('pgadmin.browser.node', [ category: gettext('Scripts'), data: { 'script': stype, + 'data_disabled': gettext('The selected tree node does not support this option.'), }, icon: 'fa fa-pencil-alt', enable: self.check_user_permission, diff --git a/web/pgadmin/browser/static/js/quick_search.js b/web/pgadmin/browser/static/js/quick_search.js new file mode 100644 index 000000000..017c1a614 --- /dev/null +++ b/web/pgadmin/browser/static/js/quick_search.js @@ -0,0 +1,29 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2021, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +import React from 'react'; +import ReactDOM from 'react-dom'; +import {Search} from './quick_search/trigger_search'; + +// TODO: GUI, Add the logic to show loading screen while fetching result +const onResultFetch = (url, data) => { + // URL can be used for displaying all the result in new page + // data will be array of search -> + console.warn('URL = ' + url); + console.warn(data); +}; + +setTimeout(function(){ + if (document.getElementById('quick-search-component')) { + ReactDOM.render( + , + document.getElementById('quick-search-component') + ); + } +},500); diff --git a/web/pgadmin/browser/static/js/quick_search/iframe_component.js b/web/pgadmin/browser/static/js/quick_search/iframe_component.js new file mode 100644 index 000000000..faf428fa8 --- /dev/null +++ b/web/pgadmin/browser/static/js/quick_search/iframe_component.js @@ -0,0 +1,44 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2021, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +import React, {Component} from 'react'; +import PropTypes from 'prop-types'; + +// Allow us to render IFrame using React +// Here we will add the event listener on Iframe load event +export class Iframe extends Component { + static get propTypes() { + return { + id: PropTypes.string.isRequired, + srcURL: PropTypes.string.isRequired, + onLoad: PropTypes.func.isRequired, + }; + } + + render () { + const iframeStyle = { + border: '0', + display: 'block', + position:'absolute', + opacity:'0', + }; + const {id, srcURL, onLoad} = this.props; + + return ( +