Ensure that keyboard shortcuts are displayed in tooltips, context menus, and the main menu. #1923

pull/8965/head
Rohit Bhati 2025-07-16 17:51:26 +05:30 committed by GitHub
parent ced002a6ad
commit 770a0f27af
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
51 changed files with 162 additions and 18 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View File

@ -59,11 +59,13 @@ define('pgadmin.node.cast', [
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Cast...'),
data: {action: 'create'},
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_cast', node: 'cast', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Cast...'),
data: {action: 'create'},
shortcut_preference: ['browser', 'sub_menu_create'],
}]);
},

View File

@ -52,11 +52,13 @@ define('pgadmin.node.event_trigger', [
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Event Trigger...'),
data: {action: 'create'},
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_event_trigger', node: 'event_trigger', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Event Trigger...'),
data: {action: 'create'},
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_event_trigger', node: 'database', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',

View File

@ -77,11 +77,13 @@ define('pgadmin.node.extension', [
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Extension...'),
data: {action: 'create'},
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_extension', node: 'extension', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Extension...'),
data: {action: 'create'},
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_extension', node: 'database', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',

View File

@ -56,11 +56,13 @@ define('pgadmin.node.foreign_data_wrapper', [
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Foreign Data Wrapper...'),
data: {action: 'create'},
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_foreign_data_wrapper', node: 'foreign_data_wrapper', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Foreign Data Wrapper...'),
data: {action: 'create'},
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_foreign_data_wrapper', node: 'database', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',

View File

@ -61,11 +61,13 @@ define('pgadmin.node.language', [
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Language...'),
data: {action: 'create'},
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_language', node: 'language', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Language...'),
data: {action: 'create'},
shortcut_preference: ['browser', 'sub_menu_create'],
}]);
},

View File

@ -62,11 +62,13 @@ define('pgadmin.node.publication', [
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Publication...'),
data: {action: 'create'},
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_publication', node: 'publication', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Publication...'),
data: {action: 'create'},
shortcut_preference: ['browser', 'sub_menu_create'],
}]);
},

View File

@ -52,11 +52,13 @@ define('pgadmin.node.collation', [
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Collation...'),
data: {action: 'create', check: true}, enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_collation', node: 'collation', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Collation...'),
data: {action: 'create', check: true}, enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_collation', node: 'schema', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',

View File

@ -53,6 +53,7 @@ define('pgadmin.node.domain_constraints', [
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 5, label: gettext('Domain Constraint...'),
data: {action: 'create', check: true}, enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_domain_constraints', node: 'domain_constraints', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
@ -63,6 +64,7 @@ define('pgadmin.node.domain_constraints', [
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 5, label: gettext('Domain Constraint...'),
data: {action: 'create', check: false}, enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},
]);

View File

@ -55,11 +55,13 @@ define('pgadmin.node.domain', [
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Domain...'),
data: {action: 'create', check: true}, enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_domain', node: 'domain', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Domain...'),
data: {action: 'create', check: true}, enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_domain', node: 'schema', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',

View File

@ -60,11 +60,13 @@ define('pgadmin.node.foreign_table', ['pgadmin.tables.js/enable_disable_triggers
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Foreign Table...'),
data: {action: 'create', check: true}, enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_foreign_table', node: 'foreign_table', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Foreign Table...'),
data: {action: 'create', check: true}, enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_foreign_table', node: 'schema', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',

View File

@ -62,12 +62,14 @@ define('pgadmin.node.fts_configuration', [
callback: 'show_obj_properties', category: 'create',
label: gettext('FTS Configuration...'), data: {action: 'create'},
enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_fts_configuration', node: 'fts_configuration',
module: this, applies: ['object', 'context'],
callback: 'show_obj_properties', category: 'create', priority: 4,
label: gettext('FTS Configuration...'), data: {action: 'create'},
enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
}]);
},

View File

@ -62,12 +62,14 @@ define('pgadmin.node.fts_dictionary', [
callback: 'show_obj_properties', category: 'create',
label: gettext('FTS Dictionary...'), data: {action: 'create'},
enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_fts_dictionary', node: 'fts_dictionary', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('FTS Dictionary...'),
data: {action: 'create'},
enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
}]);
},

View File

@ -58,11 +58,13 @@ define('pgadmin.node.fts_parser', [
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('FTS Parser...'),
data: {action: 'create'}, module: this, enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_fts_parser', node: 'fts_parser', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('FTS Parser...'),
data: {action: 'create'}, enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
}]);
},

View File

@ -58,11 +58,13 @@ define('pgadmin.node.fts_template', [
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('FTS Template...'),
data: {action: 'create'}, enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_fts_template', node: 'fts_template', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('FTS Template...'),
data: {action: 'create'}, enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
}]);
},

View File

@ -59,11 +59,13 @@ define('pgadmin.node.function', [
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Function...'),
data: {action: 'create', check: true}, enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_function', node: 'function', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Function...'),
data: {action: 'create', check: true}, enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_function', node: 'schema', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',

View File

@ -60,11 +60,13 @@ define('pgadmin.node.procedure', [
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Procedure...'),
data: {action: 'create', check: false}, enable: 'canCreateProc',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_procedure', node: 'procedure', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Procedure...'),
data: {action: 'create', check: true}, enable: 'canCreateProc',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_procedure', node: 'schema', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',

View File

@ -66,11 +66,13 @@ define('pgadmin.node.trigger_function', [
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Trigger function...'),
data: {action: 'create', check: true}, enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_trigger_function', node: 'trigger_function', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Trigger function...'),
data: {action: 'create', check: true}, enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_trigger_function', node: 'schema', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',

View File

@ -57,11 +57,13 @@ define('pgadmin.node.sequence', [
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Sequence...'),
data: {action: 'create', check: true}, enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_sequence', node: 'sequence', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Sequence...'),
data: {action: 'create', check: true}, enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_sequence', node: 'schema', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',

View File

@ -52,11 +52,13 @@ define('pgadmin.node.schema', [
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 1, label: gettext('Schema...'),
data: {action: 'create'},
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_schema', node: 'schema', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 1, label: gettext('Schema...'),
data: {action: 'create'},
shortcut_preference: ['browser', 'sub_menu_create'],
data: {action: 'create'},
},{
name: 'create_schema', node: 'database', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',

View File

@ -74,11 +74,13 @@ define('pgadmin.node.column', [
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Column...'),
data: {action: 'create', check: true}, enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_column', node: 'column', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Column...'),
data: {action: 'create', check: true}, enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_column_onTable', node: 'table', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',

View File

@ -61,11 +61,13 @@ define('pgadmin.node.index', [
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Index...'),
data: {action: 'create', check: true}, enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_index', node: 'index', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Index...'),
data: {action: 'create', check: true}, enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_index_onTable', node: 'table', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',

View File

@ -56,11 +56,13 @@ define('pgadmin.node.row_security_policy', [
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 1, label: gettext('RLS Policy...'),
data: {action: 'create', check: true}, enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_row_security_policy', node: 'row_security_policy', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 1, label: gettext('RLS Policy...'),
data: {action: 'create', check: true}, enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},
{
name: 'create_row_security_policy_on_coll', node: 'table', module: this,

View File

@ -87,6 +87,7 @@ define('pgadmin.node.rule', [
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 1, label: gettext('Rule...'),
data: {action: 'create', check: true}, enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_rule_onView', node: 'view', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
@ -97,6 +98,7 @@ define('pgadmin.node.rule', [
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 1, label: gettext('Rule...'),
data: {action: 'create', check: true}, enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_rule', node: 'table', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',

View File

@ -68,12 +68,14 @@ define('pgadmin.node.table', [
category: 'create', priority: 1, label: gettext('Table...'),
data: {action: 'create', check: true},
enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_table', node: 'table', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 1, label: gettext('Table...'),
data: {action: 'create', check: true},
enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_table__on_schema', node: 'schema', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',

View File

@ -58,12 +58,14 @@ define('pgadmin.node.trigger', [
category: 'create', priority: 4, label: gettext('Trigger...'),
data: {action: 'create', check: true},
enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_trigger', node: 'trigger', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Trigger...'),
data: {action: 'create', check: true},
enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_trigger_onTable', node: 'table', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',

View File

@ -55,12 +55,14 @@ define('pgadmin.node.type', [
category: 'create', priority: 4, label: gettext('Type...'),
data: {action: 'create', check: true},
enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_type', node: 'type', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Type...'),
data: {action: 'create', check: true},
enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_type', node: 'schema', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',

View File

@ -97,12 +97,14 @@ define('pgadmin.node.mview', [
category: 'create', priority: 1,
data: {action: 'create', check: true}, enable: 'canCreate',
label: gettext('Materialized View...'),
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_mview', node: 'mview', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 1,
data: {action: 'create', check: true}, enable: 'canCreate',
label: gettext('Materialized View...'),
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_mview', node: 'schema', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',

View File

@ -78,12 +78,14 @@ define('pgadmin.node.view', [
category: 'create', priority: 1, label: gettext('View...'),
data: {action: 'create', check: true},
enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_view', node: 'view', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 1, label: gettext('View...'),
data: {action: 'create', check: true},
enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_view', node: 'schema', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',

View File

@ -85,12 +85,14 @@ define('pgadmin.node.database', [
category: 'create', priority: 4, label: gettext('Database...'),
data: {action: 'create'},
enable: 'can_create_database',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_database', node: 'database', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Database...'),
data: {action: 'create'},
enable: 'can_create_database',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'connect_database', node: 'database', module: this,
applies: ['object', 'context'], callback: 'connect_database',

View File

@ -66,12 +66,14 @@ define('pgadmin.node.subscription', [
category: 'create', priority: 4, label: gettext('Subscription...'),
data: {action: 'create'},
enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_subscription', node: 'subscription', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Subscription...'),
data: {action: 'create'},
enable: 'canCreate',
shortcut_preference: ['browser', 'sub_menu_create'],
}]);
},
getSchema: function(treeNodeInfo, itemNodeData){

View File

@ -96,12 +96,14 @@ define('pgadmin.node.role', [
category: 'create', priority: 4, label: gettext('Login/Group Role...'),
data: {action: 'create'},
enable: 'can_create_role',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_role', node: 'role', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Login/Group Role...'),
data: {action: 'create'},
enable: 'can_create_role',
shortcut_preference: ['browser', 'sub_menu_create'],
}, {
name: 'reassign_role', node: 'role', module: this,
applies: ['object', 'context'], callback: 'reassign_role',

View File

@ -92,6 +92,7 @@ define('pgadmin.node.server', [
name: 'create_server', node: 'server', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'register', priority: 3, label: gettext('Server...'),
shortcut_preference: ['browser', 'sub_menu_create'],
data: {action: 'create'}, enable: 'canCreate', permission: AllPermissionTypes.OBJECT_REGISTER_SERVER
},{
name: 'connect_server', node: 'server', module: this,

View File

@ -65,12 +65,14 @@ define('pgadmin.node.tablespace', [
category: 'create', priority: 4, label: gettext('Tablespace...'),
data: {action: 'create'},
enable: 'can_create_tablespace',
shortcut_preference: ['browser', 'sub_menu_create'],
},{
name: 'create_tablespace', node: 'tablespace', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: gettext('Tablespace...'),
data: {action: 'create'},
enable: 'can_create_tablespace',
shortcut_preference: ['browser', 'sub_menu_create'],
},
]);
},

View File

@ -35,6 +35,7 @@ define('pgadmin.node.server_group', [
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 1, label: gettext('Server Group...'),
data: {'action': 'create'},
shortcut_preference: ['browser', 'sub_menu_create'],
}]);
},
getSchema: ()=>new ServerGroupSchema(),

View File

@ -12,6 +12,7 @@ import Menu, { MenuItem } from '../../../static/js/helpers/Menu';
import getApiInstance from '../../../static/js/api_instance';
import url_for from 'sources/url_for';
import withCheckPermission from './withCheckPermission';
import usePreferences from '../../../preferences/static/js/store';
const MAIN_MENUS = [
{ label: gettext('File'), name: 'file', id: 'mnu_file', index: 0, addSeprator: true, hasDynamicMenuItems: false },
@ -97,6 +98,33 @@ export default class MainMenuFactory {
});
}
static updateShortcutsFromPreferences(prefStore) {
const updateShortcuts = (item) => {
if (!item || typeof item !== 'object') return;
Object.values(item).forEach((menuItem) => {
if (!menuItem || typeof menuItem !== 'object') return;
if (menuItem?.shortcut_preference) {
const [module, key] = menuItem.shortcut_preference;
menuItem.shortcut = prefStore.getPreferences(module, key)?.value || null;
}
// Recurse only if it's a nested object.
if (!menuItem.name) {
updateShortcuts(menuItem);
}
});
};
let allMenus = pgAdmin.Browser?.all_menus_cache || {};
Object.values(allMenus).forEach(updateShortcuts);
};
// Assign and Update menu shortcuts using preference.
static subscribeShortcutChanges() {
MainMenuFactory.updateShortcutsFromPreferences(usePreferences.getState());
usePreferences.subscribe(MainMenuFactory.updateShortcutsFromPreferences);
}
static enableDisableMenus(item) {
let itemData = item ? pgAdmin.Browser.tree.itemData(item) : undefined;

View File

@ -206,6 +206,14 @@ define('pgadmin.browser', [
uiloaded: function() {
this.set_master_password('');
this.check_version_update();
const prefStore = usePreferences.getState();
let save_the_workspace = prefStore.getPreferencesForModule('misc').save_app_state;
if(save_the_workspace){
this.restore_pgadmin_state();
pgBrowser.docker.default_workspace.focus();
}
// Assign and Update shortcuts from preferences.
MainMenuFactory.subscribeShortcutChanges();
},
check_corrupted_db_file: function() {
getApiInstance().get(
@ -392,6 +400,8 @@ define('pgadmin.browser', [
below: _m.below,
applies: _m.applies,
permission: _m.permission,
shortcut_preference: _m.shortcut_preference,
shortcut:_m.shortcut
};
};
@ -406,7 +416,7 @@ define('pgadmin.browser', [
}
_menus[m.name]['menu_items'] = sub_menu_items;
}
} else {
} else {
console.warn(
'Developer warning: Category \'' +
a +

View File

@ -45,6 +45,7 @@ define([
name: 'refresh', node: this.type, module: this,
applies: ['object', 'context'], callback: 'refresh',
priority: 2, label: gettext('Refresh'),
shortcut_preference: ['browser', 'sub_menu_refresh'],
}]);
// show query tool only in context menu of supported nodes.
@ -55,6 +56,7 @@ define([
applies: ['context'], callback: 'show_query_tool',
priority: 998, label: gettext('Query Tool'),
permission: AllPermissionTypes.TOOLS_QUERY_TOOL,
shortcut_preference: ['browser', 'sub_menu_query_tool'],
}]);
// show search objects same as query tool
@ -63,6 +65,7 @@ define([
applies: ['context'], callback: 'show_search_objects',
priority: 997, label: gettext('Search Objects...'),
permission: AllPermissionTypes.TOOLS_SEARCH_OBJECTS,
shortcut_preference: ['browser', 'sub_menu_search_objects'],
}]);
// show psql tool same as query tool.

View File

@ -250,6 +250,14 @@ _.extend(pgBrowser.keyboardNavigation, {
if (!tree.d){
return;
} else if(node_obj.collection_node === true) {
const menuItems = pgAdmin.Browser.all_menus_cache.context?.[node_obj.type];
// Filter all items with category 'create'.
const createMenuItems = Object.values(menuItems || {}).filter(
item => item.category === 'create'
);
// If more than 1 create menu, ignore shortcut.
if(createMenuItems.length > 1) return;
if(node_obj.node) {
node_obj = pgAdmin.Browser.Nodes[node_obj.node];
} else {

View File

@ -113,7 +113,7 @@ define('pgadmin.browser.node', [
if (self.node_initialized)
return;
self.node_initialized = true;
pgAdmin.Browser.add_menus([{
name: 'refresh',
node: self.type,
@ -122,6 +122,7 @@ define('pgadmin.browser.node', [
callback: 'refresh',
priority: 2,
label: gettext('Refresh...'),
shortcut_preference: ['browser', 'sub_menu_refresh'],
enable: true,
}]);
@ -137,6 +138,7 @@ define('pgadmin.browser.node', [
data: {
'action': 'edit',
},
shortcut_preference: ['browser', 'sub_menu_properties'],
enable: _.isFunction(self.canEdit) ?
function() {
return !!(self.canEdit(...arguments));
@ -158,6 +160,7 @@ define('pgadmin.browser.node', [
'url': 'drop',
data_disabled: gettext('The selected tree node does not support this option.'),
},
shortcut_preference: ['browser', 'sub_menu_delete'],
enable: _.isFunction(self.canDrop) ?
function() {
return !!(self.canDrop(...arguments));
@ -205,6 +208,7 @@ define('pgadmin.browser.node', [
label: gettext('Query Tool'),
enable: enable,
permission: AllPermissionTypes.TOOLS_QUERY_TOOL,
shortcut_preference: ['browser', 'sub_menu_query_tool'],
}]);
// show search objects same as query tool
@ -214,6 +218,7 @@ define('pgadmin.browser.node', [
priority: 997, label: gettext('Search Objects...'),
icon: 'fa fa-search', enable: enable,
permission: AllPermissionTypes.TOOLS_SEARCH_OBJECTS,
shortcut_preference: ['browser', 'sub_menu_search_objects'],
}]);
if(pgAdmin['enable_psql']) {

View File

@ -90,6 +90,7 @@ export default function AppMenuBar() {
hasCheck={hasCheck}
checked={menuItem.checked}
closeOnCheck={true}
shortcut={menuItem.shortcut}
>{menuItem.label}</PgMenuItem>;
};

View File

@ -112,7 +112,7 @@ export function DataGridFormHeader({tableEleRef, rows}) {
}, [canAddRow, rows?.length, addOnTop]);
useEffect(() => {
if (newRowIndex.current < -1) return;
if (isNaN(newRowIndex.current) || newRowIndex.current <= -1) return;
virtualizer.scrollToIndex(newRowIndex.current);

View File

@ -56,7 +56,7 @@ export function DataGridHeader({tableEleRef}) {
}, [canAddRow, rows?.length]);
useEffect(() => {
if (newRowIndex.current < -1) return;
if (isNaN(newRowIndex.current) || newRowIndex.current <= -1) return;
virtualizer.scrollToIndex(newRowIndex.current);

View File

@ -27,6 +27,7 @@ export default function ContextMenu({menuItems, position, onClose, label='contex
}}
hasCheck={hasCheck}
checked={menuItem.checked}
shortcut={menuItem.shortcut}
>{menuItem.label}</PgMenuItem>;
};

View File

@ -20,6 +20,7 @@ import {
export {MenuDivider as PgMenuDivider} from '@szhsin/react-menu';
import { shortcutToString } from './ShortcutTitle';
import CustomPropTypes from '../custom_prop_types';
import { Box } from '@mui/material';
export function PgMenu({open, className='', label, menuButton=null, ...props}) {
const state = open ? 'open' : 'closed';
@ -81,9 +82,26 @@ export const PgMenuItem = (({hasCheck=false, checked=false, accesskey, shortcut,
return <MenuItem {...props} onClick={onClick} data-label={dataLabel} data-checked={checked}>
{hasCheck && <CheckIcon style={checked ? {} : {visibility: 'hidden', width: '1.3rem'}} data-label="CheckIcon"/>}
{children}
<div style={{ marginLeft:'auto', fontSize:'0.8em', paddingLeft:'12px'}}>
{keyVal ? `(${keyVal})` : ''}
</div>
<Box
sx={{
marginLeft: 'auto',
fontSize: '0.8em',
paddingLeft: '12px',
display: 'flex',
gap: '1px',
color: 'text.muted',
'.szh-menu__item--hover &': {
color: 'primary.contrastText',
},
}}
>
{Array.isArray(keyVal)
? keyVal.map((key, idx) => (
<Box key={idx} component="div">{key}</Box>
))
: <Box component="div"> {keyVal ? `${keyVal}` : ''}</Box>
}
</Box>
</MenuItem>;
});

View File

@ -59,19 +59,19 @@ export function shortcutToString(shortcut, accesskey=null, asArray=false) {
keys = getBrowserAccesskey();
keys.push(_.capitalize(accesskey?.toUpperCase()));
} else if(shortcut) {
shortcut.alt && keys.push((isMac() ? 'Option' : 'Alt'));
if(shortcut.alt) keys.push(isMac() ? '⌥' : 'Alt');
if(isMac() && shortcut.ctrl_is_meta) {
shortcut.control && keys.push('Cmd');
if(shortcut.control) keys.push('⌘');
} else {
shortcut.control && keys.push('Ctrl');
if(shortcut.control) keys.push(isMac() ? '⌃' : 'Ctrl');
}
shortcut.shift && keys.push('Shift');
if(shortcut.shift) keys.push(isMac() ? '⇧' : 'Shift');
keys.push(_.capitalize(shortcut.key.char));
} else {
return '';
}
return asArray ? keys : keys.join(' + ');
return asArray || isMac() ? keys : keys.join(' + ');
}
/* The tooltip content to show shortcut details */
@ -82,8 +82,8 @@ export default function ShortcutTitle({title, shortcut, accesskey}) {
(<Root>
<div className='ShortcutTitle-title'>{title}</div>
<div className='ShortcutTitle-shortcut'>
{keys.map((key)=>{
return <div key={key} className='ShortcutTitle-key'>{key}</div>;
{keys.map((key, idx)=>{
return <div key={idx} className='ShortcutTitle-key'>{key}</div>;
})}
</div>
</Root>)

View File

@ -124,6 +124,7 @@ export class MenuItem {
'checked', 'below', 'menu_items', 'is_checkbox', 'action', 'applies', 'is_native_only', 'type',
'permission',
];
this.shortcut = options.shortcut;
let defaults = {
url: '#',
target: '_self',

View File

@ -48,6 +48,7 @@ export default class SearchObjectModule {
data_disabled: gettext('Please select a database from the object explorer to search the database objects.'),
},
permission: 'tools_search_objects',
shortcut_preference: ['browser', 'sub_menu_search_objects'],
}];
pgBrowser.add_menus(menus);

View File

@ -107,6 +107,7 @@ export default class SQLEditor {
data_disabled: gettext('Please select a database from the object explorer to access Query Tool.'),
},
permission: AllPermissionTypes.TOOLS_QUERY_TOOL,
shortcut_preference: ['browser', 'sub_menu_query_tool'],
}];
// Create context menu
@ -125,7 +126,8 @@ export default class SQLEditor {
priority: 101,
label: gettext('All Rows'),
permission: AllPermissionTypes.TOOLS_QUERY_TOOL,
},{
shortcut_preference: ['browser', 'sub_menu_view_data'],
}, {
name: 'view_first_100_rows_context_' + supportedNode,
node: supportedNode,
module: this,

View File

@ -82,7 +82,7 @@ describe('Menu', ()=>{
}
});
const menuItem = screen.getByRole('menuitem');
expect(menuItem.textContent).toBe('Test(Ctrl + Shift + K)');
expect(menuItem.textContent).toBe('Test Ctrl + Shift + K');
});
it('not checked', ()=>{

View File

@ -59,7 +59,7 @@ describe('ShortcutTitle', ()=>{
it('mac meta key', ()=>{
shortcut.ctrl_is_meta = true;
jest.spyOn(keyShort, 'isMac').mockReturnValue(true);
expect(shortcutToString(shortcut)).toBe('Cmd + Shift + K');
expect(shortcutToString(shortcut)).toEqual(['⌘', '⇧', 'K']);
});
});
});