Remove usage of jQuery in pgAdmin.

Remove usage of Bootstrap in React components. #5701
This commit is contained in:
Aditya Toshniwal
2023-02-10 10:28:39 +05:30
committed by GitHub
parent 1806866bf5
commit 713ddb5f62
75 changed files with 1387 additions and 3477 deletions

View File

@@ -16,23 +16,26 @@ import { checkMasterPassword } from '../../../static/js/Dialogs/index';
import { pgHandleItemError } from '../../../static/js/utils';
import { Search } from './quick_search/trigger_search';
import { send_heartbeat, stop_heartbeat } from './heartbeat';
import getApiInstance from '../../../static/js/api_instance';
define('pgadmin.browser', [
'sources/gettext', 'sources/url_for', 'require', 'jquery',
'bootstrap', 'sources/pgadmin', 'bundled_codemirror',
'sources/gettext', 'sources/url_for', 'jquery',
'sources/pgadmin', 'bundled_codemirror',
'sources/check_node_visibility', './toolbar', 'pgadmin.help',
'sources/csrf', 'sources/utils', 'sources/window', 'pgadmin.authenticate.kerberos',
'sources/tree/tree_init',
'pgadmin.browser.utils', 'wcdocker', 'jquery.contextmenu',
'pgadmin.browser.utils',
'pgadmin.browser.preferences', 'pgadmin.browser.messages',
'pgadmin.browser.panel', 'pgadmin.browser.layout',
'pgadmin.browser.error', 'pgadmin.browser.frame',
'pgadmin.browser.frame',
'pgadmin.browser.node', 'pgadmin.browser.collection', 'pgadmin.browser.activity',
'sources/codemirror/addon/fold/pgadmin-sqlfoldcode',
'pgadmin.browser.keyboard', 'sources/tree/pgadmin_tree_save_state'
'pgadmin.browser.keyboard', 'sources/tree/pgadmin_tree_save_state',
/* wcDocker dependencies */
'bootstrap', 'jquery-contextmenu', 'wcdocker',
], function(
gettext, url_for, require, $,
Bootstrap, pgAdmin, codemirror,
gettext, url_for, $,
pgAdmin, codemirror,
checkNodeVisibility, toolBar, help, csrfToken, pgadminUtils, pgWindow,
Kerberos, InitTree,
) {
@@ -201,9 +204,9 @@ define('pgadmin.browser', [
icon: '',
limit: 1,
content: '<div id="tree" class="browser-tree"></div>',
onCreate: function(panel, $container) {
onCreate: function(panel, container) {
toolBar.initializeToolbar(panel, wcDocker);
$container.addClass('pg-no-overflow');
container.classList.add('pg-no-overflow');
},
}),
// Properties of the object node
@@ -216,10 +219,10 @@ define('pgadmin.browser', [
isPrivate: true,
elContainer: true,
limit: 1,
content: '<div class="obj_properties container-fluid h-100"><div role="status" class="pg-panel-message">' + select_object_msg + '</div></div>',
content: '<div class="obj_properties"><div role="status" class="pg-panel-message">' + select_object_msg + '</div></div>',
events: panelEvents,
onCreate: function(myPanel, $container) {
$container.addClass('pg-no-overflow');
onCreate: function(myPanel, container) {
container.classList.add('pg-no-overflow');
},
}),
// Statistics of the object
@@ -232,7 +235,7 @@ define('pgadmin.browser', [
isPrivate: false,
limit : 1,
canHide: true,
content: '<div class="negative-space p-2"><div role="status" class="pg-panel-message pg-panel-statistics-message">' + select_object_msg + '</div><div class="pg-panel-statistics-container d-none"></div></div>',
content: '<div></div>',
events: panelEvents,
}),
// Reversed engineered SQL for the object
@@ -244,7 +247,7 @@ define('pgadmin.browser', [
isCloseable: false,
isPrivate: true,
limit: 1,
content: '<label for="sql-textarea" class="sr-only">' + gettext('SQL Code') + '</label><div class="sql_textarea"><textarea id="sql-textarea" name="sql-textarea" title="' + gettext('SQL Code') + '"></textarea></div>',
content: '<div></div>',
}),
// Dependencies of the object
'dependencies': new pgAdmin.Browser.Panel({
@@ -256,7 +259,7 @@ define('pgadmin.browser', [
isPrivate: false,
canHide: true,
limit: 1,
content: '<div class="negative-space p-2"><div role="status" class="pg-panel-message pg-panel-depends-message">' + select_object_msg + '</div><div class="pg-panel-dependencies-container d-none"></div></div>',
content: '<div></div>',
events: panelEvents,
}),
// Dependents of the object
@@ -269,7 +272,7 @@ define('pgadmin.browser', [
isPrivate: false,
limit: 1,
canHide: true,
content: '<div class="negative-space p-2"><div role="status" class="pg-panel-message pg-panel-depends-message">' + select_object_msg + '</div><div class="pg-panel-dependents-container d-none"></div></div>',
content: '<div></div>',
events: panelEvents,
}),
// Background processes
@@ -282,7 +285,7 @@ define('pgadmin.browser', [
isPrivate: false,
limit: 1,
canHide: true,
content: '<div class="negative-space p-2"><div class="pg-panel-processes-container d-none"></div></div>',
content: '<div></div>',
events: panelEvents,
}),
},
@@ -526,17 +529,6 @@ define('pgadmin.browser', [
initializeModalProvider();
initializeNotifier();
// Syntax highlight the SQL Pane
if(document.getElementById('sql-textarea')){
obj.editor = CodeMirror.fromTextArea(
document.getElementById('sql-textarea'), {
lineNumbers: true,
mode: 'text/x-pgsql',
readOnly: true,
extraKeys: pgAdmin.Browser.editor_shortcut_keys,
screenReaderLabel: gettext('SQL'),
});
}
/* Cache may take time to load for the first time
* Reflect the changes once cache is available
*/
@@ -568,18 +560,15 @@ define('pgadmin.browser', [
// Register scripts and add menus
pgBrowser.utils.registerScripts(this);
let headers = {};
headers[pgAdmin.csrf_token_header] = pgAdmin.csrf_token;
// Ping the server every 5 minutes
setInterval(function() {
$.ajax({
url: url_for('misc.cleanup'),
type:'POST',
headers: headers,
})
.done(function() {/*This is intentional (SonarQube)*/})
.fail(function() {/*This is intentional (SonarQube)*/});
getApiInstance().post(
url_for('misc.cleanup')
).then(()=> {
/*This is intentional (SonarQube)*/
}).catch(function() {
/*This is intentional (SonarQube)*/
});
}, 300000);
obj.Events.on(
@@ -608,12 +597,9 @@ define('pgadmin.browser', [
if (this.tree) this.tree.resizeTree();
},
check_corrupted_db_file: function() {
$.ajax({
url: url_for('browser.check_corrupted_db_file'),
type: 'GET',
dataType: 'json',
contentType: 'application/json',
}).done((res)=> {
getApiInstance().get(
url_for('browser.check_corrupted_db_file')
).then(({data: res})=> {
if(res.data.length > 0) {
Notify.alert(
@@ -626,16 +612,14 @@ define('pgadmin.browser', [
res.data.substring(0, res.data.length - 14),
);
}
}).fail(function(xhr, status, error) {
}).catch(function(error) {
Notify.alert(error);
});
},
check_master_password: function(on_resp_callback) {
$.ajax({
url: url_for('browser.check_master_password'),
type: 'GET',
contentType: 'application/json',
}).done((res)=> {
getApiInstance().get(
url_for('browser.check_master_password')
).then(({data: res})=> {
if(on_resp_callback) {
if(res.data) {
on_resp_callback(true);
@@ -643,23 +627,21 @@ define('pgadmin.browser', [
on_resp_callback(false);
}
}
}).fail(function(xhr, status, error) {
Notify.pgRespErrorNotify(xhr, error);
}).catch(function(error) {
Notify.pgRespErrorNotify(error);
});
},
reset_master_password: function() {
let self = this;
$.ajax({
url: url_for('browser.set_master_password'),
type: 'DELETE',
contentType: 'application/json',
}).done((res)=> {
getApiInstance().delete(
url_for('browser.set_master_password')
).then(({data: res})=> {
if(!res.data) {
self.set_master_password('');
}
}).fail(function(xhr, status, error) {
Notify.pgRespErrorNotify(xhr, error);
}).catch(function(error) {
Notify.pgRespErrorNotify(error);
});
},
@@ -1687,59 +1669,51 @@ define('pgadmin.browser', [
});
return;
}
let api = getApiInstance();
let fetchNodeInfo = function(__i, __d, __n) {
let info = __n.getTreeNodeHierarchy(__i),
url = __n.generate_url(__i, 'nodes', __d, true);
$.ajax({
url: url,
type: 'GET',
cache: false,
dataType: 'json',
})
.done(function(res) {
api.get(
url
).then(({data: res})=> {
// Node information can come as result/data
let newData = res.result || res.data;
let newData = res.result || res.data;
newData._label = newData.label;
newData.label = _.escape(newData.label);
newData._label = newData.label;
newData.label = _.escape(newData.label);
ctx.t.setLabel(ctx.i, {label: newData.label});
ctx.t.addIcon(ctx.i, {icon: newData.icon});
ctx.t.setId(ctx.i, {id: newData.id});
if (newData.inode)
ctx.t.setInode(ctx.i, {inode: true});
ctx.t.setLabel(ctx.i, {label: newData.label});
ctx.t.addIcon(ctx.i, {icon: newData.icon});
ctx.t.setId(ctx.i, {id: newData.id});
if (newData.inode)
ctx.t.setInode(ctx.i, {inode: true});
// This will update the tree item data.
let itemData = ctx.t.itemData(ctx.i);
_.extend(itemData, newData);
// This will update the tree item data.
let itemData = ctx.t.itemData(ctx.i);
_.extend(itemData, newData);
if (
__n.can_expand && typeof(__n.can_expand) == 'function'
) {
if (!__n.can_expand(itemData)) {
ctx.t.unload(ctx.i);
return;
}
if (
__n.can_expand && typeof(__n.can_expand) == 'function'
) {
if (!__n.can_expand(itemData)) {
ctx.t.unload(ctx.i);
return;
}
ctx.b._refreshNode(ctx, ctx.branch);
let success = (ctx.o && ctx.o.success) || ctx.success;
if (success && typeof(success) == 'function') {
success();
}
})
.fail(function(xhr, error) {
if (!pgHandleItemError(
xhr, {item: __i, info: info}
)) {
let contentType = xhr.getResponseHeader('Content-Type'),
jsonResp = (
contentType &&
contentType.indexOf('application/json') == 0 &&
JSON.parse(xhr.responseText)
) || {};
if (xhr.status == 410 && jsonResp.success == 0) {
}
ctx.b._refreshNode(ctx, ctx.branch);
let success = (ctx.o && ctx.o.success) || ctx.success;
if (success && typeof(success) == 'function') {
success();
}
}).catch(function(error) {
if (!pgHandleItemError(
error, {item: __i, info: info}
)) {
if(error.response.headers['content-type'] == 'application/json') {
let jsonResp = error.response.data ?? {};
if(error.response.status == 410 && jsonResp.success == 0) {
let parent = ctx.t.parent(ctx.i);
ctx.t.remove(ctx.i, {
@@ -1755,16 +1729,17 @@ define('pgadmin.browser', [
},
});
}
Notify.pgNotifier(error, xhr, gettext('Error retrieving details for the node.'), function (msg) {
if (msg == 'CRYPTKEY_SET') {
fetchNodeInfo(__i, __d, __n);
} else {
console.warn(arguments);
}
});
}
});
Notify.pgNotifier('error', error, gettext('Error retrieving details for the node.'), function (msg) {
if (msg == 'CRYPTKEY_SET') {
fetchNodeInfo(__i, __d, __n);
} else {
console.warn(arguments);
}
});
}
});
}.bind(this);
if (n && n.collection_node) {
@@ -1935,6 +1910,7 @@ define('pgadmin.browser', [
},
addChildTreeNodes: function(_treeHierarchy, _node, _type, _arrayIds, _callback) {
let api = getApiInstance();
let module = _type in pgBrowser.Nodes && pgBrowser.Nodes[_type],
childTreeInfo = _arrayIds.length && _.extend(
{}, _.mapValues(_treeHierarchy, function(_val) {
@@ -1961,20 +1937,17 @@ define('pgadmin.browser', [
_node = _node || arguments[1];
$.ajax({
url: childNodeUrl,
dataType: 'json',
})
.done(function(res) {
if (res.success) {
arrayChildNodeData.push(res.data);
}
fetchNodeInfo(_callback);
})
.fail(function(xhr, status, error) {
Notify.pgRespErrorNotify(xhr, error);
fetchNodeInfo(_callback);
});
api.get(
childNodeUrl
).then(({data: res})=> {
if (res.success) {
arrayChildNodeData.push(res.data);
}
fetchNodeInfo(_callback);
}).catch(function(error) {
Notify.pgRespErrorNotify(error);
fetchNodeInfo(_callback);
});
};

View File

@@ -1,63 +0,0 @@
/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2023, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
import Notify from '../../../static/js/helpers/Notifier';
import _ from 'lodash';
define(
['sources/gettext', 'sources/pgadmin'],
function(gettext, pgAdmin) {
pgAdmin.Browser = pgAdmin.Browser || {};
_.extend(pgAdmin.Browser, {
report_error: function(title, message, info, callback) {
title = _.escape(title);
message = _.escape(message);
info = _.escape(info);
let text ='<div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">'
+ '<div class="panel panel-default">'
+ '<div class="panel-heading" role="tab" id="headingOne">'
+ '<h4 class="panel-title">'
+ '<a data-toggle="collapse" data-parent="#accordion" href="#collapseOne" aria-expanded="true" aria-controls="collapseOne">' + gettext('Error message') + '</a>'
+ '</h4>'
+ '</div>'
+ '<div id="collapseOne" class="panel-collapse collapse show" role="tabpanel" aria-labelledby="headingOne">'
+ '<div class="panel-body" style="overflow: auto;">' + message + '</div>'
+ '</div>'
+ '</div>';
if (info != null && info != '') {
text += '<div class="panel panel-default">'
+ '<div class="panel-heading" role="tab" id="headingTwo">'
+ '<h4 class="panel-title">'
+ '<a class="collapsed" data-toggle="collapse" data-parent="#accordion" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">' + gettext('Additional info') + '</a>'
+ '</h4>'
+ '</div>'
+ '<div id="collapseTwo" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingTwo">'
+ '<div class="panel-body" style="overflow: auto;">' + info + '</div>'
+ '</div>'
+ '</div>'
+ '</div>';
}
text += '</div>';
Notify.alert(
_.unescape(title),
text,
function() {
if(callback) {
callback();
}
}
);
},
});
return pgAdmin.Browser.report_error;
});

View File

@@ -46,7 +46,6 @@ define([
isPrivate: that.isPrivate,
isLayoutMember: that.isLayoutMember,
onCreate: function(myPanel) {
$(myPanel).data('pgAdminName', that.name);
myPanel.initSize(that.width, that.height);
if (!(myPanel.showTitle??true))
@@ -61,13 +60,17 @@ define([
myPanel.layout().addItem($frameArea);
that.panel = myPanel;
let frame = new wcIFrame($frameArea, myPanel);
$(myPanel).data('frameInitialized', false);
$(myPanel).data('embeddedFrame', frame);
myPanel.frameData = {
pgAdminName: that.name,
frameInitialized: false,
embeddedFrame: frame,
};
if (that.url != '' && that.url != 'about:blank') {
setTimeout(function() {
frame.openURL(that.url);
$(myPanel).data('frameInitialized', true);
myPanel.frameData.frameInitialized = true;
pgBrowser.Events.trigger(
'pgadmin-browser:frame:urlloaded:' + that.name, frame,
that.url, self
@@ -75,7 +78,7 @@ define([
}, 50);
} else {
frame.openURL('about:blank');
$(myPanel).data('frameInitialized', true);
myPanel.frameData.frameInitialized = true;
pgBrowser.Events.trigger(
'pgadmin-browser:frame:urlloaded:' + that.name, frame,
that.url, self
@@ -112,7 +115,7 @@ define([
}
},
eventFunc: function(eventName) {
let name = $(this).data('pgAdminName');
let name = this.frameData.pgAdminName;
try {
pgBrowser.Events.trigger('pgadmin-browser:frame', eventName, this, arguments);

View File

@@ -9,13 +9,10 @@
import _ from 'lodash';
import pgAdmin from '../../../static/js/pgadmin';
import $ from 'jquery';
import Mousetrap from 'mousetrap';
import * as commonUtils from '../../../static/js/utils';
import dialogTabNavigator from '../../../static/js/dialog_tab_navigator';
import * as keyboardFunc from 'sources/keyboard_shortcuts';
import pgWindow from 'sources/window';
import gettext from 'sources/gettext';
import pgWindow from 'sources/window';
const pgBrowser = pgAdmin.Browser = pgAdmin.Browser || {};
@@ -78,33 +75,6 @@ _.extend(pgBrowser.keyboardNavigation, {
_.each(self.shortcutMethods, (keyCombo, callback) => {
self._bindWithMousetrap(keyCombo.shortcuts, self[callback], keyCombo.bindElem);
});
/* Dropdown submenu was not working properly for up/down arrow keys.
* So up/down/right/left events for dropdown were removed from Mousetrap and were
* handled manually.
*/
const LEFT_KEY = 37,
UP_KEY = 38,
RIGHT_KEY = 39,
DOWN_KEY = 40;
$('.pg-navbar').on('keydown', (event)=> {
switch(event.keyCode) {
case LEFT_KEY:
self.bindMainMenuLeft(event);
break;
case UP_KEY:
self.bindMainMenuUpDown(event, 'up');
break;
case RIGHT_KEY:
self.bindMainMenuRight(event);
break;
case DOWN_KEY:
self.bindMainMenuUpDown(event, 'down');
break;
}
});
},
_bindWithMousetrap: function(shortcuts, callback, bindElem) {
const self = this;
@@ -179,89 +149,10 @@ _.extend(pgBrowser.keyboardNavigation, {
}
}, 1000);
},
bindMainMenuLeft: function(event) {
if ($(event.target).hasClass('nav-link')) { // Menu items
let currNavMenu = $(event.target).closest('.nav-item');
keyboardFunc._stopEventPropagation(event);
currNavMenu = currNavMenu.prev('.nav-item');
// Skip hidden menus
while(currNavMenu.hasClass('d-none')) {
currNavMenu = currNavMenu.prev('.nav-item');
}
currNavMenu.find('.dropdown-toggle').first().dropdown('toggle');
} else if($(event.target).closest('.dropdown-menu').length > 0) {
let currLi = $(event.target).closest('li');
keyboardFunc._stopEventPropagation(event);
/*close submenu*/
let currMenu = currLi.closest('.dropdown-menu');
if(currMenu.closest('.dropdown-submenu').length > 0) {
currMenu.removeClass('show');
currMenu.closest('.dropdown-submenu').removeClass('dropdown-submenu-visible');
currLi = currMenu.closest('.dropdown-submenu');
currLi.find('.dropdown-item').trigger('focus');
}
}
},
bindMainMenuRight: function(event) {
if ($(event.target).hasClass('nav-link')) { // Menu items
let currNavMenu = $(event.target).closest('.nav-item');
keyboardFunc._stopEventPropagation(event);
currNavMenu = currNavMenu.next('.nav-item');
// Skip hidden menus
while(currNavMenu.hasClass('d-none')) {
currNavMenu = currNavMenu.next('.nav-item');
}
currNavMenu.find('.dropdown-toggle').first().dropdown('toggle');
} else if($(event.target).closest('.dropdown-menu').length > 0) {
let currLi = $(event.target).closest('li');
keyboardFunc._stopEventPropagation(event);
/*open submenu if any*/
if(currLi.hasClass('dropdown-submenu')){
currLi.addClass('dropdown-submenu-visible');
currLi.find('.dropdown-menu').addClass('show');
currLi.find('.dropdown-menu .dropdown-item').first().trigger('focus');
}
}
},
bindMainMenuUpDown: function(event, combo) {
// Handle Sub-menus
if($(event.target).closest('.dropdown-menu').length > 0) {
keyboardFunc._stopEventPropagation(event);
let currLi = $(event.target).closest('li');
/*close all the submenus on movement*/
let dropMenu = $(event.target).closest('.dropdown-menu');
dropMenu.find('.show').removeClass('show');
dropMenu.find('.dropdown-submenu').removeClass('dropdown-submenu-visible');
if(combo === 'up') {
currLi = currLi.prev();
}
else if(combo === 'down'){
currLi = currLi.next();
}
/*do not focus on divider and disabled */
while(currLi.hasClass('dropdown-divider')
|| currLi.find('.dropdown-item').first().hasClass('disabled')) {
if(combo === 'up') {
currLi = currLi.prev();
}
else if(combo === 'down'){
currLi = currLi.next();
}
}
currLi.find('.dropdown-item').trigger('focus');
}
},
bindLeftTree: function() {
const tree = this.getTreeDetails();
$('#tree').trigger('focus');
document.querySelector('[id="tree"]').focus();
tree.t.select(tree.i);
},
bindSubMenuQueryTool: function() {
@@ -336,17 +227,6 @@ _.extend(pgBrowser.keyboardNavigation, {
// Call refresh object callback
pgAdmin.Browser.Node.callbacks.refresh.call(pgAdmin.Browser.Nodes[tree.t.itemData(tree.i)._type]);
},
bindContextMenu: function(event) {
const tree = this.getTreeDetails();
let _srcElement = event.srcElement || event.target;
const left = $(_srcElement).find('.aciTreeEntry').position().left + 70;
const top = $(_srcElement).find('.aciTreeEntry').position().top + 70;
tree.t.blur(tree.i);
$('#tree').trigger('blur');
// Call context menu and set position
tree.i.children().contextMenu({x: left, y: top});
},
bindDirectDebugging: function() {
const tree = this.getTreeDetails();
const type = tree.t.itemData(tree.i)._type;
@@ -359,24 +239,6 @@ _.extend(pgBrowser.keyboardNavigation, {
pgAdmin.Tools.Debugger.get_function_information(pgAdmin.Browser.Nodes[type]);
}
},
bindDropMultipleObjects: function() {
let isPropertyPanelVisible = this.isPropertyPanelVisible();
if (isPropertyPanelVisible === true && $('button.delete_multiple').length > 0) {
$('button.delete_multiple').click();
}
},
bindDropCascadeMultipleObjects: function() {
let isPropertyPanelVisible = this.isPropertyPanelVisible();
if (isPropertyPanelVisible === true && $('button.delete_multiple_cascade').length > 0) {
$('button.delete_multiple_cascade').click();
}
},
bindAddGridRow: function() {
let subNode = $(document.activeElement).closest('.object.subnode');
if ($(subNode).length) {
$(subNode).find('.add').click();
}
},
isPropertyPanelVisible: function() {
let isPanelVisible = false;
_.each(pgAdmin.Browser.docker.findPanels(), (panel) => {
@@ -396,12 +258,6 @@ _.extend(pgBrowser.keyboardNavigation, {
d: selectedTreeNodeData,
};
},
getDialogTabNavigator: function(dialogContainer) {
const backward_shortcut = pgWindow.pgAdmin.Browser.get_preference('browser', 'dialog_tab_backward').value;
const forward_shortcut = pgWindow.pgAdmin.Browser.get_preference('browser', 'dialog_tab_forward').value;
return new dialogTabNavigator.dialogTabNavigator(dialogContainer, backward_shortcut, forward_shortcut);
},
bindOpenQuickSearch: function() {
pgWindow.pgAdmin.Browser.all_menus_cache.help.mnu_quick_search_help.callback();
},

View File

@@ -9,11 +9,11 @@
import pgAdmin from 'sources/pgadmin';
import url_for from 'sources/url_for';
import $ from 'jquery';
import gettext from 'sources/gettext';
import 'wcdocker';
import pgWindow from 'sources/window';
import Notify from '../../../static/js/helpers/Notifier';
import getApiInstance from '../../../static/js/api_instance';
const pgBrowser = pgAdmin.Browser = pgAdmin.Browser || {};
@@ -50,11 +50,8 @@ _.extend(pgBrowser, {
if(docker) {
let layout = docker.save(),
settings = { setting: layout_id, value: layout };
$.ajax({
type: 'POST',
url: url_for('settings.store_bulk'),
data: settings,
});
getApiInstance().post(url_for('settings.store_bulk'), settings);
}
},
@@ -143,17 +140,15 @@ _.extend(pgBrowser, {
save_lock_layout: function(op) {
let browser = pgWindow.pgAdmin.Browser;
$.ajax({
url: url_for('browser.lock_layout'),
method: 'PUT',
contentType: 'application/json',
data: JSON.stringify({
getApiInstance().put(
url_for('browser.lock_layout'),
JSON.stringify({
'value': op,
}),
}).done(function() {
})
).then(()=> {
browser.cache_preferences('browser');
}).fail(function(xhr, error) {
Notify.pgNotifier(error, xhr, gettext('Failed to save the lock layout setting.'));
}).catch(function(error) {
Notify.pgNotifier('error', error, gettext('Failed to save the lock layout setting.'));
});
},

View File

@@ -10,13 +10,14 @@
import {getNodeView, removeNodeView} from './node_view';
import Notify from '../../../static/js/helpers/Notifier';
import _ from 'lodash';
import getApiInstance from '../../../static/js/api_instance';
define('pgadmin.browser.node', [
'sources/gettext', 'jquery', 'sources/pgadmin',
'sources/gettext', 'sources/pgadmin',
'sources/browser/generate_url', 'sources/utils',
'pgadmin.browser.utils', 'pgadmin.browser.events',
], function(
gettext, $, pgAdmin, generateUrl, commonUtils
gettext, pgAdmin, generateUrl, commonUtils
) {
let wcDocker = window.wcDocker;
@@ -354,9 +355,9 @@ define('pgadmin.browser.node', [
isLayoutMember: false,
canMaximise: true,
elContainer: true,
content: '<div class="obj_properties container-fluid h-100"><div role="status" class="pg-panel-message">' + gettext('Please wait while we fetch information ...') + '</div></div>',
onCreate: function(myPanel, $container) {
$container.addClass('pg-no-overflow');
content: '<div class="obj_properties"></div>',
onCreate: function(myPanel, container) {
container.classList.add('pg-no-overflow');
},
events: events,
});
@@ -379,9 +380,9 @@ define('pgadmin.browser.node', [
isLayoutMember: false,
canMaximise: true,
elContainer: true,
content: '<div class="obj_properties container-fluid h-100"><div role="status" class="pg-panel-message">' + gettext('Please wait while we fetch information about the node from the server...') + '</div></div>',
onCreate: function(myPanel, $container) {
$container.addClass('pg-no-overflow');
content: '<div class="obj_properties"></div>',
onCreate: function(myPanel, container) {
container.classList.add('pg-no-overflow');
},
events: events,
});
@@ -688,45 +689,41 @@ define('pgadmin.browser.node', [
}
Notify.confirm(title, msg,
function() {
$.ajax({
url: obj.generate_url(i, input.url, d, true),
type: 'DELETE',
})
.done(function(res) {
if(res.success == 2){
Notify.error(res.info, null);
return;
getApiInstance().delete(
obj.generate_url(i, input.url, d, true),
).then(({data: res})=> {
if(res.success == 2){
Notify.error(res.info, null);
return;
}
if (res.success == 0) {
Notify.alert(res.errormsg, res.info);
} else {
// Remove the node from tree and set collection node as selected.
let selectNextNode = true;
if(obj.selectParentNodeOnDelete) {
let prv_i = t.parent(i);
setTimeout(function() {
t.select(prv_i);
}, 10);
selectNextNode = false;
}
if (res.success == 0) {
pgBrowser.report_error(res.errormsg, res.info);
} else {
// Remove the node from tree and set collection node as selected.
let selectNextNode = true;
if(obj.selectParentNodeOnDelete) {
let prv_i = t.parent(i);
setTimeout(function() {
t.select(prv_i);
}, 10);
selectNextNode = false;
}
pgBrowser.removeTreeNode(i, selectNextNode);
pgBrowser.removeTreeNode(i, selectNextNode);
}
return true;
}).catch(function(xhr) {
let errmsg = xhr.responseText;
/* Error from the server */
if (xhr.status == 417 || xhr.status == 410 || xhr.status == 500) {
try {
let data = JSON.parse(xhr.responseText);
errmsg = data.info || data.errormsg;
} catch (e) {
console.warn(e.stack || e);
}
return true;
})
.fail(function(jqx) {
let errmsg = jqx.responseText;
/* Error from the server */
if (jqx.status == 417 || jqx.status == 410 || jqx.status == 500) {
try {
let data = JSON.parse(jqx.responseText);
errmsg = data.info || data.errormsg;
} catch (e) {
console.warn(e.stack || e);
}
}
pgBrowser.report_error(
gettext('Error dropping/removing %s: "%s"', obj.label, objName), errmsg);
});
}
Notify.alert(gettext('Error dropping/removing %s: "%s"', obj.label, objName), errmsg);
});
}
);
},
@@ -822,23 +819,27 @@ define('pgadmin.browser.node', [
fgcolor = serverData.icon.split(' ')[2] || '';
if (bgcolor) {
let dynamic_class = 'pga_server_' + serverData._id + '_bgcolor',
style_tag;
let dynamic_class = 'pga_server_' + serverData._id + '_bgcolor';
// Prepare dynamic style tag
style_tag = '<style id=' + dynamic_class + ' type=\'text/css\'> \n';
style_tag += '.' + dynamic_class + ' .file-label {';
style_tag += ' border-radius: 3px; margin-bottom: 2px;';
style_tag += ' background: ' + bgcolor + ' !important;} \n';
if (fgcolor) {
style_tag += '.' + dynamic_class + ' span.file-name {';
style_tag += ' color: ' + fgcolor + ' !important;} \n';
}
style_tag += '</style>';
const styleTag = document.createElement('style');
styleTag.setAttribute('id', dynamic_class);
styleTag.setAttribute('type', 'text/css');
styleTag.innerText = `
.${dynamic_class} .file-label {
border-radius: 3px;
margin-bottom: 2px;
background: ${bgcolor} !important;
}
${fgcolor ? `
.${dynamic_class} span.file-name {
color: ${fgcolor} !important;
}
`:''}
`;
// Prepare dynamic style tag using template
$('#' + dynamic_class).remove();
$(style_tag).appendTo('head');
document.querySelector(`style[id="${dynamic_class}"]`).remove();
document.head.appendChild(styleTag);
// Add dynamic class to the tree node.
pgBrowser.tree.addCssClass(item, dynamic_class);
}
@@ -895,7 +896,6 @@ define('pgadmin.browser.node', [
t = pgBrowser.tree,
data = _item && t.itemData(_item);
$(pgBrowser.panels['properties'].panel).removeData('node-prop');
pgBrowser.Events.trigger(
'pgadmin:browser:tree:refresh', _item || pgBrowser.tree.selected(), {
success: function() {

View File

@@ -63,25 +63,8 @@ export function getNodeView(nodeType, treeNodeInfo, actionType, itemNodeData, fo
} else if(err.message){
console.error('error msg', err.message);
}
if (err?.response?.data?.info == 'CRYPTKEY_MISSING') {
Notify.pgNotifier('error', err.request, 'The master password is not set', function(msg) {
setTimeout(function() {
if (msg == 'CRYPTKEY_SET') {
resolve(initData());
} else if (msg == 'CRYPTKEY_NOT_SET') {
reject(err);
}
}, 100);
});
} else if (err?.response?.data?.errormsg) {
Notify.alert(
gettext('Error'),
gettext(err.response.data.errormsg)
);
reject(err);
}
reject(err);
Notify.pgRespErrorNotify(err);
});
}
});

View File

@@ -11,8 +11,8 @@ import { getPanelView } from './panel_view';
import _ from 'lodash';
define(
['sources/pgadmin', 'jquery', 'wcdocker'],
function(pgAdmin, $) {
['sources/pgadmin', 'wcdocker'],
function(pgAdmin) {
let pgBrowser = pgAdmin.Browser = pgAdmin.Browser || {},
wcDocker = window.wcDocker;
@@ -52,7 +52,9 @@ define(
limit: that.limit,
isLayoutMember: that.isLayoutMember,
onCreate: function(myPanel) {
$(myPanel).data('pgAdminName', that.name);
myPanel.panelData = {
pgAdminName: that.name,
};
myPanel.initSize(that.width, that.height);
if (!that.showTitle)
@@ -64,18 +66,18 @@ define(
myPanel.icon(that.icon);
}
let $container = $('<div>', {
'class': 'pg-panel-content',
}).append($(that.content));
let container = document.createElement('div');
container.setAttribute('class', 'pg-panel-content');
container.innerHTML = that.content;
// Add extra classes
if (!_.isNull('extraClasses')) {
$container.addClass(that.extraClasses);
container.classList.add(that.extraClasses);
}
myPanel.maximisable(!!that.canMaximise);
myPanel.closeable(!!that.isCloseable);
myPanel.layout().addItem($container);
myPanel.layout().addItem(container);
that.panel = myPanel;
if (that.events && _.isObject(that.events)) {
_.each(that.events, function(v, k) {
@@ -99,21 +101,20 @@ define(
});
if (that.onCreate && _.isFunction(that.onCreate)) {
that.onCreate.apply(that, [myPanel, $container]);
that.onCreate.apply(that, [myPanel, container]);
}
// Prevent browser from opening the drag file.
// Using addEventListener to avoid conflict with jquery.drag
['dragover', 'drop'].forEach((eventName)=>{
$container[0].addEventListener(eventName, function(event) {
container.addEventListener(eventName, function(event) {
event.stopPropagation();
event.preventDefault();
});
});
if (that.elContainer) {
myPanel.pgElContainer = $container;
$container.addClass('pg-el-container');
myPanel.pgElContainer = container;
_.each([
wcDocker.EVENT.RESIZED, wcDocker.EVENT.ATTACHED,
wcDocker.EVENT.DETACHED, wcDocker.EVENT.VISIBILITY_CHANGED,
@@ -126,7 +127,7 @@ define(
if (myPanel._type == 'dashboard' || myPanel._type == 'processes') {
getPanelView(
pgBrowser.tree,
$container[0],
container,
pgBrowser,
myPanel._type
);
@@ -136,7 +137,7 @@ define(
pgBrowser.onPreferencesChange('dashboards', function() {
getPanelView(
pgBrowser.tree,
$container[0],
container,
pgBrowser,
myPanel._type
);
@@ -146,7 +147,7 @@ define(
pgBrowser.onPreferencesChange('graphs', function() {
getPanelView(
pgBrowser.tree,
$container[0],
container,
pgBrowser,
myPanel._type
);
@@ -162,7 +163,7 @@ define(
if(myPanel.isVisible() && myPanel._type !== 'properties') {
getPanelView(
pgBrowser.tree,
$container[0],
container,
pgBrowser,
myPanel._type
);
@@ -174,7 +175,7 @@ define(
if(myPanel.isVisible() && myPanel._type !== 'properties') {
getPanelView(
pgBrowser.tree,
$container[0],
container,
pgBrowser,
myPanel._type
);
@@ -186,7 +187,7 @@ define(
if(myPanel.isVisible() && myPanel._type !== 'properties') {
getPanelView(
pgBrowser.tree,
$container[0],
container,
pgBrowser,
myPanel._type
);
@@ -197,7 +198,7 @@ define(
}
},
eventFunc: function(eventName) {
let name = $(this).data('pgAdminName');
let name = this.panelData.pgAdminName;
try {
pgBrowser.Events.trigger(
'pgadmin-browser:panel', eventName, this, arguments
@@ -248,18 +249,16 @@ define(
elAttr = 'xl';
}
p.pgElContainer.attr('el', elAttr);
p.pgElContainer.setAttribute('el', elAttr);
},
100
);
}
},
handleVisibility: function(eventName) {
if (_.isNull(pgBrowser.tree)) return;
let selectedPanel = pgBrowser.docker.findPanels(this._type)[0];
let isPanelVisible = selectedPanel.isVisible();
let $container = selectedPanel
let container = selectedPanel
.layout()
.scene()
.find('.pg-panel-content');
@@ -268,7 +267,7 @@ define(
if (eventName == 'panelVisibilityChanged') {
getPanelView(
pgBrowser.tree,
$container[0],
container[0],
pgBrowser,
this._type
);
@@ -277,7 +276,7 @@ define(
if (eventName == 'panelClosed' && selectedPanel._type == 'dashboard') {
getPanelView(
pgBrowser.tree,
$container[0],
container[0],
pgBrowser,
this._type,
false

View File

@@ -9,12 +9,10 @@
import pgAdmin from 'sources/pgadmin';
import url_for from 'sources/url_for';
import $ from 'jquery';
import pgWindow from 'sources/window';
import Notify from '../../../static/js/helpers/Notifier';
import { calcFontSize } from '../../../static/js/utils';
import { shortcutToString } from '../../../static/js/components/ShortcutTitle';
import gettext from 'sources/gettext';
import getApiInstance from '../../../static/js/api_instance';
const pgBrowser = pgAdmin.Browser = pgAdmin.Browser || {};
@@ -78,16 +76,11 @@ _.extend(pgBrowser, {
// Get and cache the preferences
cache_preferences: function (modulesChanged) {
let self = this,
headers = {};
headers[pgAdmin.csrf_token_header] = pgAdmin.csrf_token;
let self = this;
setTimeout(function() {
$.ajax({
url: url_for('preferences.get_all'),
headers: headers,
})
.done(function(res) {
getApiInstance().get(url_for('preferences.get_all'))
.then(({data: res})=>{
self.preferences_cache = res;
self.preference_version(self.generate_preference_version());
@@ -97,43 +90,30 @@ _.extend(pgBrowser, {
pgBrowser.browserTreeState.init();
/* Once the cache is loaded after changing the preferences,
* notify the modules of the change
*/
* notify the modules of the change
*/
if(modulesChanged) {
if(typeof modulesChanged === 'string'){
$.event.trigger('prefchange:'+modulesChanged);
pgBrowser.Events.trigger('prefchange:'+modulesChanged);
} else {
_.each(modulesChanged, (val, key)=> {
$.event.trigger('prefchange:'+key);
pgBrowser.Events.trigger('prefchange:'+key);
});
}
}
})
.fail(function(xhr, status, error) {
Notify.pgRespErrorNotify(xhr, error);
.catch(function(error) {
Notify.pgRespErrorNotify(error);
});
}, 500);
},
triggerPreferencesChange: function(moduleChanged) {
$.event.trigger('prefchange:'+moduleChanged);
pgBrowser.Events.trigger('prefchange:'+moduleChanged);
},
reflectPreferences: function(module) {
let obj = this;
if(module === 'sqleditor' || module === null || typeof module === 'undefined') {
let sqlEditPreferences = obj.get_preferences_for_module('sqleditor');
$(obj?.editor?.getWrapperElement()).css(
'font-size', calcFontSize(sqlEditPreferences.sql_font_size)
);
obj?.editor?.setOption('tabSize', sqlEditPreferences.tab_size);
obj?.editor?.setOption('lineWrapping', sqlEditPreferences.wrap_code);
obj?.editor?.setOption('autoCloseBrackets', sqlEditPreferences.insert_pair_brackets);
obj?.editor?.setOption('matchBrackets', sqlEditPreferences.brace_matching);
obj?.editor?.refresh();
}
//browser preference
if(module === 'browser') {
let browserPreferences = obj.get_preferences_for_module('browser');
@@ -158,13 +138,7 @@ _.extend(pgBrowser, {
},
onPreferencesChange: function(module, eventHandler) {
let eventWindow = pgWindow;
if (window.location === window.parent?.location ) {
// The page is in a new tab
eventWindow = window;
}
$(eventWindow).on('prefchange:'+module, function(event) {
pgBrowser.Events.on('prefchange:'+module, function(event) {
eventHandler(event);
});
},

View File

@@ -52,6 +52,10 @@ samp,
border-style: solid;
border-width: 1px;
font-size: 1.15em;
color: $color-fg !important;
border-color: $border-color !important;
background-color: $color-secondary;
}
.pg-toolbar-psql {