mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Extract the tests and refactor some of the methods.
Extract some of the ACI Tree functionalities, and decouple it from the main source. Also - create some abstractions from the repeated code around the enable/disable the schema children object create/edit/delete functionalities, and also created the dialog wrappers for backup and restore dialogs. Reviewed by: Khushboo and Ashesh Refactored by: Ashesh
This commit is contained in:
committed by
Ashesh Vashi
parent
920934759f
commit
7dd6372eeb
@@ -3,9 +3,12 @@ define([
|
||||
'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
|
||||
'underscore.string', 'pgadmin.alertifyjs', 'backbone', 'pgadmin.backgrid',
|
||||
'pgadmin.backform', 'pgadmin.browser', 'sources/utils',
|
||||
'tools/backup/static/js/menu_utils',
|
||||
'tools/backup/static/js/backup_dialog',
|
||||
'sources/nodes/supported_database_node',
|
||||
], function(
|
||||
gettext, url_for, $, _, S, alertify, Backbone, Backgrid, Backform, pgBrowser,
|
||||
commonUtils
|
||||
commonUtils, menuUtils, globalBackupDialog, supportedNodes
|
||||
) {
|
||||
|
||||
// if module is already initialized, refer to that.
|
||||
@@ -394,48 +397,6 @@ commonUtils
|
||||
|
||||
this.initialized = true;
|
||||
|
||||
// Define list of nodes on which backup context menu option appears
|
||||
var backup_supported_nodes = [
|
||||
'database', 'schema', 'table', 'partition',
|
||||
];
|
||||
|
||||
/**
|
||||
Enable/disable backup menu in tools based
|
||||
on node selected
|
||||
if selected node is present in supported_nodes,
|
||||
menu will be enabled otherwise disabled.
|
||||
Also, hide it for system view in catalogs
|
||||
*/
|
||||
var menu_enabled = function(itemData, item) {
|
||||
var t = pgBrowser.tree,
|
||||
i = item,
|
||||
d = itemData,
|
||||
parent_item = t.hasParent(i) ? t.parent(i) : null,
|
||||
parent_data = parent_item ? t.itemData(parent_item) : null;
|
||||
|
||||
if (!_.isUndefined(d) && !_.isNull(d) && !_.isNull(parent_data)) {
|
||||
if (_.indexOf(backup_supported_nodes, d._type) !== -1 &&
|
||||
parent_data._type != 'catalog') {
|
||||
if (d._type == 'database' && d.allowConn)
|
||||
return true;
|
||||
else if (d._type != 'database')
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
} else
|
||||
return false;
|
||||
} else
|
||||
return false;
|
||||
};
|
||||
|
||||
var menu_enabled_server = function(itemData) {
|
||||
// If server node selected && connected
|
||||
if (!_.isUndefined(itemData) && !_.isNull(itemData))
|
||||
return (('server' === itemData._type) && itemData.connected);
|
||||
else
|
||||
return false;
|
||||
};
|
||||
|
||||
// Define the nodes on which the menus to be appear
|
||||
var menus = [{
|
||||
name: 'backup_global',
|
||||
@@ -445,7 +406,7 @@ commonUtils
|
||||
priority: 12,
|
||||
label: gettext('Backup Globals...'),
|
||||
icon: 'fa fa-floppy-o',
|
||||
enable: menu_enabled_server,
|
||||
enable: menuUtils.menuEnabledServer,
|
||||
}, {
|
||||
name: 'backup_server',
|
||||
module: this,
|
||||
@@ -454,7 +415,7 @@ commonUtils
|
||||
priority: 12,
|
||||
label: gettext('Backup Server...'),
|
||||
icon: 'fa fa-floppy-o',
|
||||
enable: menu_enabled_server,
|
||||
enable: menuUtils.menuEnabledServer,
|
||||
}, {
|
||||
name: 'backup_global_ctx',
|
||||
module: this,
|
||||
@@ -464,7 +425,7 @@ commonUtils
|
||||
priority: 12,
|
||||
label: gettext('Backup Globals...'),
|
||||
icon: 'fa fa-floppy-o',
|
||||
enable: menu_enabled_server,
|
||||
enable: menuUtils.menuEnabledServer,
|
||||
}, {
|
||||
name: 'backup_server_ctx',
|
||||
module: this,
|
||||
@@ -474,7 +435,7 @@ commonUtils
|
||||
priority: 12,
|
||||
label: gettext('Backup Server...'),
|
||||
icon: 'fa fa-floppy-o',
|
||||
enable: menu_enabled_server,
|
||||
enable: menuUtils.menuEnabledServer,
|
||||
}, {
|
||||
name: 'backup_object',
|
||||
module: this,
|
||||
@@ -483,20 +444,24 @@ commonUtils
|
||||
priority: 11,
|
||||
label: gettext('Backup...'),
|
||||
icon: 'fa fa-floppy-o',
|
||||
enable: menu_enabled,
|
||||
enable: supportedNodes.enabled.bind(
|
||||
null, pgBrowser.treeMenu, menuUtils.backupSupportedNodes
|
||||
),
|
||||
}];
|
||||
|
||||
for (var idx = 0; idx < backup_supported_nodes.length; idx++) {
|
||||
for (var idx = 0; idx < menuUtils.backupSupportedNodes.length; idx++) {
|
||||
menus.push({
|
||||
name: 'backup_' + backup_supported_nodes[idx],
|
||||
node: backup_supported_nodes[idx],
|
||||
name: 'backup_' + menuUtils.backupSupportedNodes[idx],
|
||||
node: menuUtils.backupSupportedNodes[idx],
|
||||
module: this,
|
||||
applies: ['context'],
|
||||
callback: 'backup_objects',
|
||||
priority: 11,
|
||||
label: gettext('Backup...'),
|
||||
icon: 'fa fa-floppy-o',
|
||||
enable: menu_enabled,
|
||||
enable: supportedNodes.enabled.bind(
|
||||
null, pgBrowser.treeMenu, menuUtils.backupSupportedNodes
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -521,542 +486,25 @@ commonUtils
|
||||
},
|
||||
|
||||
// Callback to draw Backup Dialog for globals/server
|
||||
start_backup_global_server: function(action, item, params) {
|
||||
var i = item || pgBrowser.tree.selected(),
|
||||
server_data = null;
|
||||
|
||||
while (i) {
|
||||
var node_data = pgBrowser.tree.itemData(i);
|
||||
if (node_data._type == 'server') {
|
||||
server_data = node_data;
|
||||
break;
|
||||
}
|
||||
|
||||
if (pgBrowser.tree.hasParent(i)) {
|
||||
i = $(pgBrowser.tree.parent(i));
|
||||
} else {
|
||||
alertify.alert(
|
||||
gettext('Backup Error'),
|
||||
gettext('Please select server or child node from the browser tree.')
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!server_data) {
|
||||
return;
|
||||
}
|
||||
|
||||
var module = 'paths',
|
||||
preference_name = 'pg_bin_dir',
|
||||
msg = gettext('Please configure the PostgreSQL Binary Path in the Preferences dialog.');
|
||||
|
||||
if ((server_data.type && server_data.type == 'ppas') ||
|
||||
server_data.server_type == 'ppas') {
|
||||
preference_name = 'ppas_bin_dir';
|
||||
msg = gettext('Please configure the EDB Advanced Server Binary Path in the Preferences dialog.');
|
||||
}
|
||||
|
||||
var preference = pgBrowser.get_preference(module, preference_name);
|
||||
|
||||
if (preference) {
|
||||
if (!preference.value) {
|
||||
alertify.alert(gettext('Configuration required'), msg);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
alertify.alert(
|
||||
gettext('Backup Error'),
|
||||
S(gettext('Failed to load preference %s of module %s')).sprintf(preference_name, module).value()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
var of_type = undefined;
|
||||
|
||||
// Set Notes according to type of backup
|
||||
if (!_.isUndefined(params['globals']) && params['globals']) {
|
||||
of_type = 'globals';
|
||||
} else {
|
||||
of_type = 'server';
|
||||
}
|
||||
|
||||
var DialogName = 'BackupDialog_' + of_type,
|
||||
DialogTitle = ((of_type == 'globals') ?
|
||||
gettext('Backup Globals...') :
|
||||
gettext('Backup Server...'));
|
||||
|
||||
if (!alertify[DialogName]) {
|
||||
alertify.dialog(DialogName, function factory() {
|
||||
return {
|
||||
main: function(title) {
|
||||
this.set('title', title);
|
||||
},
|
||||
build: function() {
|
||||
alertify.pgDialogBuild.apply(this);
|
||||
},
|
||||
setup: function() {
|
||||
return {
|
||||
buttons: [{
|
||||
text: '',
|
||||
className: 'btn btn-default pull-left fa fa-lg fa-info',
|
||||
attrs: {
|
||||
name: 'object_help',
|
||||
type: 'button',
|
||||
url: 'backup.html',
|
||||
label: gettext('Backup'),
|
||||
},
|
||||
}, {
|
||||
text: '',
|
||||
key: 112,
|
||||
className: 'btn btn-default pull-left fa fa-lg fa-question',
|
||||
attrs: {
|
||||
name: 'dialog_help',
|
||||
type: 'button',
|
||||
label: gettext('Backup'),
|
||||
url: url_for('help.static', {
|
||||
'filename': 'backup_dialog.html',
|
||||
}),
|
||||
},
|
||||
}, {
|
||||
text: gettext('Backup'),
|
||||
key: 13,
|
||||
className: 'btn btn-primary fa fa-lg fa-save pg-alertify-button',
|
||||
'data-btn-name': 'backup',
|
||||
}, {
|
||||
text: gettext('Cancel'),
|
||||
key: 27,
|
||||
className: 'btn btn-danger fa fa-lg fa-times pg-alertify-button',
|
||||
'data-btn-name': 'cancel',
|
||||
}],
|
||||
// Set options for dialog
|
||||
options: {
|
||||
title: DialogTitle,
|
||||
//disable both padding and overflow control.
|
||||
padding: !1,
|
||||
overflow: !1,
|
||||
model: 0,
|
||||
resizable: true,
|
||||
maximizable: true,
|
||||
pinnable: false,
|
||||
closableByDimmer: false,
|
||||
modal: false,
|
||||
},
|
||||
};
|
||||
},
|
||||
hooks: {
|
||||
// Triggered when the dialog is closed
|
||||
onclose: function() {
|
||||
if (this.view) {
|
||||
// clear our backform model/view
|
||||
this.view.remove({
|
||||
data: true,
|
||||
internal: true,
|
||||
silent: true,
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
prepare: function() {
|
||||
var self = this;
|
||||
// Disable Backup button until user provides Filename
|
||||
this.__internal.buttons[2].element.disabled = true;
|
||||
|
||||
var $container = $('<div class=\'backup_dialog\'></div>');
|
||||
// Find current/selected node
|
||||
var t = pgBrowser.tree,
|
||||
i = t.selected(),
|
||||
d = i && i.length == 1 ? t.itemData(i) : undefined,
|
||||
node = d && pgBrowser.Nodes[d._type];
|
||||
|
||||
if (!d)
|
||||
return;
|
||||
// Create treeInfo
|
||||
var treeInfo = node.getTreeNodeHierarchy.apply(node, [i]);
|
||||
// Instance of backbone model
|
||||
var newModel = new BackupModel({
|
||||
type: of_type,
|
||||
}, {
|
||||
node_info: treeInfo,
|
||||
}),
|
||||
fields = Backform.generateViewSchema(
|
||||
treeInfo, newModel, 'create', node, treeInfo.server, true
|
||||
);
|
||||
|
||||
var view = this.view = new Backform.Dialog({
|
||||
el: $container,
|
||||
model: newModel,
|
||||
schema: fields,
|
||||
});
|
||||
// Add our class to alertify
|
||||
$(this.elements.body.childNodes[0]).addClass(
|
||||
'alertify_tools_dialog_properties obj_properties'
|
||||
);
|
||||
// Render dialog
|
||||
view.render();
|
||||
|
||||
this.elements.content.appendChild($container.get(0));
|
||||
|
||||
var container = view.$el.find('.tab-content:first > .tab-pane.active:first');
|
||||
commonUtils.findAndSetFocus(container);
|
||||
|
||||
// Listen to model & if filename is provided then enable Backup button
|
||||
this.view.model.on('change', function() {
|
||||
if (!_.isUndefined(this.get('file')) && this.get('file') !== '') {
|
||||
this.errorModel.clear();
|
||||
self.__internal.buttons[2].element.disabled = false;
|
||||
} else {
|
||||
self.__internal.buttons[2].element.disabled = true;
|
||||
this.errorModel.set('file', gettext('Please provide a filename'));
|
||||
}
|
||||
});
|
||||
},
|
||||
// Callback functions when click on the buttons of the Alertify dialogs
|
||||
callback: function(e) {
|
||||
// Fetch current server id
|
||||
var t = pgBrowser.tree,
|
||||
i = t.selected(),
|
||||
d = i && i.length == 1 ? t.itemData(i) : undefined,
|
||||
node = d && pgBrowser.Nodes[d._type];
|
||||
|
||||
if (e.button.element.name == 'dialog_help' || e.button.element.name == 'object_help') {
|
||||
e.cancel = true;
|
||||
pgBrowser.showHelp(e.button.element.name, e.button.element.getAttribute('url'),
|
||||
node, i, e.button.element.getAttribute('label'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.button['data-btn-name'] === 'backup') {
|
||||
|
||||
if (!d)
|
||||
return;
|
||||
|
||||
var treeInfo = node.getTreeNodeHierarchy.apply(node, [i]);
|
||||
|
||||
var self = this,
|
||||
baseUrl = url_for('backup.create_server_job', {
|
||||
'sid': treeInfo.server._id,
|
||||
}),
|
||||
args = this.view.model.toJSON();
|
||||
|
||||
$.ajax({
|
||||
url: baseUrl,
|
||||
method: 'POST',
|
||||
data: {
|
||||
'data': JSON.stringify(args),
|
||||
},
|
||||
success: function(res) {
|
||||
if (res.success) {
|
||||
alertify.success(gettext('Backup job created.'), 5);
|
||||
pgBrowser.Events.trigger('pgadmin-bgprocess:created', self);
|
||||
} else {
|
||||
console.warn(res);
|
||||
}
|
||||
},
|
||||
error: function(xhr) {
|
||||
try {
|
||||
var err = JSON.parse(xhr.responseText);
|
||||
alertify.alert(
|
||||
gettext('Backup job failed.'),
|
||||
err.errormsg
|
||||
);
|
||||
} catch (e) {
|
||||
console.warn(e.stack || e);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
alertify[DialogName](true).resizeTo('60%', '50%');
|
||||
start_backup_global_server: function(action, treeItem, params) {
|
||||
let dialog = new globalBackupDialog.BackupDialog(
|
||||
pgBrowser,
|
||||
$,
|
||||
alertify,
|
||||
BackupModel
|
||||
);
|
||||
dialog.draw(action, treeItem, params);
|
||||
},
|
||||
|
||||
// Callback to draw Backup Dialog for objects
|
||||
backup_objects: function(action, treeItem) {
|
||||
|
||||
var i = treeItem || pgBrowser.tree.selected(),
|
||||
server_data = null;
|
||||
|
||||
while (i) {
|
||||
var node_data = pgBrowser.tree.itemData(i);
|
||||
if (node_data._type == 'server') {
|
||||
server_data = node_data;
|
||||
break;
|
||||
}
|
||||
|
||||
if (pgBrowser.tree.hasParent(i)) {
|
||||
i = $(pgBrowser.tree.parent(i));
|
||||
} else {
|
||||
alertify.alert(
|
||||
gettext('Backup Error'),
|
||||
gettext('Please select server or child node from tree.')
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!server_data) {
|
||||
return;
|
||||
}
|
||||
|
||||
var module = 'paths',
|
||||
preference_name = 'pg_bin_dir',
|
||||
msg = gettext('Please set binary path for PostgreSQL Server from preferences.');
|
||||
|
||||
if ((server_data.type && server_data.type == 'ppas') ||
|
||||
server_data.server_type == 'ppas') {
|
||||
preference_name = 'ppas_bin_dir';
|
||||
msg = gettext('Please set binary path for EDB Postgres Advanced Server from preferences.');
|
||||
}
|
||||
|
||||
var preference = pgBrowser.get_preference(module, preference_name);
|
||||
|
||||
if (preference) {
|
||||
if (!preference.value) {
|
||||
alertify.alert(gettext('Configuration required'), msg);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
alertify.alert(
|
||||
gettext('Backup Error'),
|
||||
S(gettext('Failed to load preference %s of module %s')).sprintf(preference_name, module).value()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
var title = S(gettext('Backup (%s: %s)')),
|
||||
tree = pgBrowser.tree,
|
||||
item = treeItem || tree.selected(),
|
||||
data = item && item.length == 1 && tree.itemData(item),
|
||||
node = data && data._type && pgBrowser.Nodes[data._type];
|
||||
|
||||
if (!node)
|
||||
return;
|
||||
|
||||
var treeInfo = node.getTreeNodeHierarchy.apply(node, [item]);
|
||||
|
||||
if (treeInfo.database._label.indexOf('=') >= 0) {
|
||||
alertify.alert(
|
||||
gettext('Backup error'),
|
||||
gettext('Backup job creation failed. '+
|
||||
'Databases with = symbols in the name cannot be backed up using this utility.')
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
title = title.sprintf(node.label, data.label).value();
|
||||
|
||||
if (!alertify.backup_objects) {
|
||||
// Create Dialog title on the fly with node details
|
||||
alertify.dialog('backup_objects', function factory() {
|
||||
return {
|
||||
main: function(title) {
|
||||
this.set('title', title);
|
||||
},
|
||||
build: function() {
|
||||
alertify.pgDialogBuild.apply(this);
|
||||
},
|
||||
setup: function() {
|
||||
return {
|
||||
buttons: [{
|
||||
text: '',
|
||||
className: 'btn btn-default pull-left fa fa-lg fa-info',
|
||||
attrs: {
|
||||
name: 'object_help',
|
||||
type: 'button',
|
||||
url: 'backup.html',
|
||||
label: gettext('Backup'),
|
||||
},
|
||||
}, {
|
||||
text: '',
|
||||
key: 112,
|
||||
className: 'btn btn-default pull-left fa fa-lg fa-question',
|
||||
attrs: {
|
||||
name: 'dialog_help',
|
||||
type: 'button',
|
||||
label: gettext('Backup'),
|
||||
url: url_for('help.static', {
|
||||
'filename': 'backup_dialog.html',
|
||||
}),
|
||||
},
|
||||
}, {
|
||||
text: gettext('Backup'),
|
||||
key: 13,
|
||||
className: 'btn btn-primary fa fa-lg fa-save pg-alertify-button',
|
||||
'data-btn-name': 'backup',
|
||||
}, {
|
||||
text: gettext('Cancel'),
|
||||
key: 27,
|
||||
className: 'btn btn-danger fa fa-lg fa-times pg-alertify-button',
|
||||
'data-btn-name': 'cancel',
|
||||
}],
|
||||
// Set options for dialog
|
||||
options: {
|
||||
title: title,
|
||||
//disable both padding and overflow control.
|
||||
padding: !1,
|
||||
overflow: !1,
|
||||
model: 0,
|
||||
resizable: true,
|
||||
maximizable: true,
|
||||
pinnable: false,
|
||||
closableByDimmer: false,
|
||||
modal: false,
|
||||
},
|
||||
};
|
||||
},
|
||||
hooks: {
|
||||
// triggered when the dialog is closed
|
||||
onclose: function() {
|
||||
if (this.view) {
|
||||
this.view.remove({
|
||||
data: true,
|
||||
internal: true,
|
||||
silent: true,
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
prepare: function() {
|
||||
var self = this;
|
||||
// Disable Backup button until user provides Filename
|
||||
this.__internal.buttons[2].element.disabled = true;
|
||||
var $container = $('<div class=\'backup_dialog\'></div>');
|
||||
var t = pgBrowser.tree,
|
||||
i = t.selected(),
|
||||
d = i && i.length == 1 ? t.itemData(i) : undefined,
|
||||
node = d && pgBrowser.Nodes[d._type];
|
||||
|
||||
if (!d)
|
||||
return;
|
||||
|
||||
var treeInfo = node.getTreeNodeHierarchy.apply(node, [i]);
|
||||
|
||||
var newModel = new BackupObjectModel({}, {
|
||||
node_info: treeInfo,
|
||||
}),
|
||||
fields = Backform.generateViewSchema(
|
||||
treeInfo, newModel, 'create', node, treeInfo.server, true
|
||||
);
|
||||
|
||||
var view = this.view = new Backform.Dialog({
|
||||
el: $container,
|
||||
model: newModel,
|
||||
schema: fields,
|
||||
});
|
||||
|
||||
$(this.elements.body.childNodes[0]).addClass(
|
||||
'alertify_tools_dialog_properties obj_properties'
|
||||
);
|
||||
|
||||
view.render();
|
||||
|
||||
this.elements.content.appendChild($container.get(0));
|
||||
|
||||
if(view) {
|
||||
view.$el.attr('tabindex', -1);
|
||||
// var dialogTabNavigator = pgBrowser.keyboardNavigation.getDialogTabNavigator(view);
|
||||
pgBrowser.keyboardNavigation.getDialogTabNavigator(view);
|
||||
var container = view.$el.find('.tab-content:first > .tab-pane.active:first');
|
||||
commonUtils.findAndSetFocus(container);
|
||||
}
|
||||
// Listen to model & if filename is provided then enable Backup button
|
||||
this.view.model.on('change', function() {
|
||||
if (!_.isUndefined(this.get('file')) && this.get('file') !== '') {
|
||||
this.errorModel.clear();
|
||||
self.__internal.buttons[2].element.disabled = false;
|
||||
} else {
|
||||
self.__internal.buttons[2].element.disabled = true;
|
||||
this.errorModel.set('file', gettext('Please provide filename'));
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
// Callback functions when click on the buttons of the Alertify dialogs
|
||||
callback: function(e) {
|
||||
// Fetch current server id
|
||||
var t = pgBrowser.tree,
|
||||
i = t.selected(),
|
||||
d = i && i.length == 1 ? t.itemData(i) : undefined,
|
||||
node = d && pgBrowser.Nodes[d._type];
|
||||
|
||||
if (e.button.element.name == 'dialog_help' || e.button.element.name == 'object_help') {
|
||||
e.cancel = true;
|
||||
pgBrowser.showHelp(e.button.element.name, e.button.element.getAttribute('url'),
|
||||
node, i, e.button.element.getAttribute('label'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.button['data-btn-name'] === 'backup') {
|
||||
if (!d)
|
||||
return;
|
||||
|
||||
var treeInfo = node.getTreeNodeHierarchy.apply(node, [i]);
|
||||
|
||||
// Set current database into model
|
||||
this.view.model.set('database', treeInfo.database._label);
|
||||
|
||||
// We will remove once object tree is implemented
|
||||
// If selected node is Schema then add it in model
|
||||
if (d._type == 'schema') {
|
||||
var schemas = [];
|
||||
schemas.push(d._label);
|
||||
this.view.model.set('schemas', schemas);
|
||||
}
|
||||
// If selected node is Table then add it in model along with
|
||||
// its schema
|
||||
if (d._type == 'table') {
|
||||
this.view.model.set(
|
||||
'tables', [
|
||||
[treeInfo.schema._label, d._label],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
// Remove ratio attribute from model if it has empty string.
|
||||
// The valid value can be between 0 to 9.
|
||||
if (_.isEmpty(this.view.model.get('ratio'))) {
|
||||
this.view.model.unset('ratio');
|
||||
}
|
||||
|
||||
var self = this,
|
||||
baseUrl = url_for('backup.create_object_job', {
|
||||
'sid': treeInfo.server._id,
|
||||
}),
|
||||
args = this.view.model.toJSON();
|
||||
|
||||
$.ajax({
|
||||
url: baseUrl,
|
||||
method: 'POST',
|
||||
data: {
|
||||
'data': JSON.stringify(args),
|
||||
},
|
||||
success: function(res) {
|
||||
if (res.success) {
|
||||
alertify.success(gettext('Backup job created.'), 5);
|
||||
pgBrowser.Events.trigger('pgadmin-bgprocess:created', self);
|
||||
}
|
||||
},
|
||||
error: function(xhr) {
|
||||
try {
|
||||
var err = JSON.parse(xhr.responseText);
|
||||
alertify.alert(
|
||||
gettext('Backup job failed.'),
|
||||
err.errormsg
|
||||
);
|
||||
} catch (e) {
|
||||
console.warn(e.stack || e);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
alertify.backup_objects(title).resizeTo('65%', '60%');
|
||||
let dialog = new globalBackupDialog.BackupDialog(
|
||||
pgBrowser,
|
||||
$,
|
||||
alertify,
|
||||
BackupObjectModel
|
||||
);
|
||||
dialog.draw(action, treeItem, null);
|
||||
},
|
||||
};
|
||||
return pgBrowser.Backup;
|
||||
|
||||
72
web/pgadmin/tools/backup/static/js/backup_dialog.js
Normal file
72
web/pgadmin/tools/backup/static/js/backup_dialog.js
Normal file
@@ -0,0 +1,72 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
import gettext from '../../../../static/js/gettext';
|
||||
import Backform from '../../../../static/js/backform.pgadmin';
|
||||
import {Dialog} from '../../../../static/js/alertify/dialog';
|
||||
|
||||
export class BackupDialog extends Dialog {
|
||||
constructor(pgBrowser, $, alertify, BackupModel, backform = Backform) {
|
||||
super('Backup Error',
|
||||
'<div class=\'backup_dialog\'></div>',
|
||||
pgBrowser, $, alertify, BackupModel, backform
|
||||
);
|
||||
}
|
||||
|
||||
draw(action, aciTreeItem, params) {
|
||||
const serverInformation = this.retrieveAncestorOfTypeServer(aciTreeItem);
|
||||
|
||||
if (!serverInformation) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.hasBinariesConfiguration(serverInformation)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const typeOfDialog = BackupDialog.typeOfDialog(params);
|
||||
|
||||
if (!this.canExecuteOnCurrentDatabase(aciTreeItem)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const dialog = this.createOrGetDialog(
|
||||
BackupDialog.dialogTitle(typeOfDialog),
|
||||
typeOfDialog
|
||||
);
|
||||
dialog(true).resizeTo('60%', '50%');
|
||||
}
|
||||
|
||||
static typeOfDialog(params) {
|
||||
if (params === null) {
|
||||
return 'backup_objects';
|
||||
}
|
||||
let typeOfDialog = 'server';
|
||||
if (!_.isUndefined(params['globals']) && params['globals']) {
|
||||
typeOfDialog = 'globals';
|
||||
}
|
||||
return typeOfDialog;
|
||||
}
|
||||
|
||||
static dialogTitle(typeOfDialog) {
|
||||
if (typeOfDialog === 'backup_objects') {
|
||||
return null;
|
||||
}
|
||||
return ((typeOfDialog === 'globals') ?
|
||||
gettext('Backup Globals...') :
|
||||
gettext('Backup Server...'));
|
||||
}
|
||||
|
||||
dialogName(typeOfDialog) {
|
||||
if (typeOfDialog === 'backup_objects') {
|
||||
return typeOfDialog;
|
||||
}
|
||||
return 'BackupDialog_' + typeOfDialog;
|
||||
}
|
||||
}
|
||||
258
web/pgadmin/tools/backup/static/js/backup_dialog_wrapper.js
Normal file
258
web/pgadmin/tools/backup/static/js/backup_dialog_wrapper.js
Normal file
@@ -0,0 +1,258 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
import {getTreeNodeHierarchyFromElement} from '../../../../static/js/tree/pgadmin_tree_node';
|
||||
import axios from 'axios/index';
|
||||
import gettext from '../../../../static/js/gettext';
|
||||
import url_for from '../../../../static/js/url_for';
|
||||
import _ from 'underscore';
|
||||
import {DialogWrapper} from '../../../../static/js/alertify/dialog_wrapper';
|
||||
|
||||
export class BackupDialogWrapper extends DialogWrapper {
|
||||
constructor(dialogContainerSelector, dialogTitle, typeOfDialog,
|
||||
jquery, pgBrowser, alertify, dialogModel, backform) {
|
||||
super(dialogContainerSelector, dialogTitle, jquery,
|
||||
pgBrowser, alertify, dialogModel, backform);
|
||||
this.typeOfDialog = typeOfDialog;
|
||||
}
|
||||
|
||||
main(title) {
|
||||
this.set('title', title);
|
||||
}
|
||||
|
||||
setup() {
|
||||
return {
|
||||
buttons: [{
|
||||
text: '',
|
||||
className: 'btn btn-default pull-left fa fa-lg fa-info',
|
||||
attrs: {
|
||||
name: 'object_help',
|
||||
type: 'button',
|
||||
url: 'backup.html',
|
||||
label: gettext('Backup'),
|
||||
},
|
||||
}, {
|
||||
text: '',
|
||||
key: 112,
|
||||
className: 'btn btn-default pull-left fa fa-lg fa-question',
|
||||
attrs: {
|
||||
name: 'dialog_help',
|
||||
type: 'button',
|
||||
label: gettext('Backup'),
|
||||
url: url_for('help.static', {
|
||||
'filename': 'backup_dialog.html',
|
||||
}),
|
||||
},
|
||||
}, {
|
||||
text: gettext('Backup'),
|
||||
key: 13,
|
||||
className: 'btn btn-primary fa fa-lg fa-save pg-alertify-button',
|
||||
'data-btn-name': 'backup',
|
||||
}, {
|
||||
text: gettext('Cancel'),
|
||||
key: 27,
|
||||
className: 'btn btn-danger fa fa-lg fa-times pg-alertify-button',
|
||||
'data-btn-name': 'cancel',
|
||||
}],
|
||||
// Set options for dialog
|
||||
options: {
|
||||
title: this.dialogTitle,
|
||||
//disable both padding and overflow control.
|
||||
padding: !1,
|
||||
overflow: !1,
|
||||
model: 0,
|
||||
resizable: true,
|
||||
maximizable: true,
|
||||
pinnable: false,
|
||||
closableByDimmer: false,
|
||||
modal: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
prepare() {
|
||||
this.disableBackupButton();
|
||||
|
||||
const $container = this.jquery(this.dialogContainerSelector);
|
||||
const selectedTreeNode = this.getSelectedNode();
|
||||
const selectedTreeNodeData = this.getSelectedNodeData(selectedTreeNode);
|
||||
if (!selectedTreeNodeData) {
|
||||
return;
|
||||
}
|
||||
|
||||
const node = this.pgBrowser.Nodes[selectedTreeNodeData._type];
|
||||
if (this.dialogTitle === null) {
|
||||
const title = `Backup (${node.label}: ${selectedTreeNodeData.label})`;
|
||||
this.main(title);
|
||||
}
|
||||
|
||||
const treeInfo = getTreeNodeHierarchyFromElement(this.pgBrowser, selectedTreeNode);
|
||||
const dialog = this.createDialog(node, treeInfo, this.typeOfDialog, $container);
|
||||
this.addAlertifyClassToBackupNodeChildNodes();
|
||||
dialog.render();
|
||||
|
||||
this.elements.content.appendChild($container.get(0));
|
||||
|
||||
this.focusOnDialog(dialog);
|
||||
this.setListenersForFilenameChanges();
|
||||
}
|
||||
|
||||
callback(event) {
|
||||
const selectedTreeNode = this.getSelectedNode();
|
||||
const selectedTreeNodeData = this.getSelectedNodeData(selectedTreeNode);
|
||||
const node = selectedTreeNodeData && this.pgBrowser.Nodes[selectedTreeNodeData._type];
|
||||
|
||||
if (this.wasHelpButtonPressed(event)) {
|
||||
event.cancel = true;
|
||||
this.pgBrowser.showHelp(
|
||||
event.button.element.name,
|
||||
event.button.element.getAttribute('url'),
|
||||
node,
|
||||
selectedTreeNode,
|
||||
event.button.element.getAttribute('label')
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.wasBackupButtonPressed(event)) {
|
||||
|
||||
if (!selectedTreeNodeData)
|
||||
return;
|
||||
|
||||
const serverIdentifier = this.retrieveServerIdentifier(node, selectedTreeNode);
|
||||
|
||||
const dialog = this;
|
||||
let urlShortcut = 'backup.create_server_job';
|
||||
if (this.typeOfDialog === 'backup_objects') {
|
||||
urlShortcut = 'backup.create_object_job';
|
||||
}
|
||||
const baseUrl = url_for(urlShortcut, {
|
||||
'sid': serverIdentifier,
|
||||
});
|
||||
|
||||
const treeInfo = getTreeNodeHierarchyFromElement(
|
||||
this.pgBrowser,
|
||||
selectedTreeNode
|
||||
);
|
||||
|
||||
this.setExtraParameters(selectedTreeNode, treeInfo);
|
||||
|
||||
let service = axios.create({});
|
||||
service.post(
|
||||
baseUrl,
|
||||
this.view.model.toJSON()
|
||||
).then(function () {
|
||||
dialog.alertify.success(gettext('Backup job created.'), 5);
|
||||
dialog.pgBrowser.Events.trigger('pgadmin-bgprocess:created', dialog);
|
||||
}).catch(function (error) {
|
||||
try {
|
||||
const err = error.response.data;
|
||||
dialog.alertify.alert(
|
||||
gettext('Backup job failed.'),
|
||||
err.errormsg
|
||||
);
|
||||
} catch (e) {
|
||||
console.warn(e.stack || e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
addAlertifyClassToBackupNodeChildNodes() {
|
||||
this.jquery(this.elements.body.childNodes[0]).addClass(
|
||||
'alertify_tools_dialog_properties obj_properties'
|
||||
);
|
||||
}
|
||||
|
||||
getSelectedNode() {
|
||||
const tree = this.pgBrowser.treeMenu;
|
||||
const selectedNode = tree.selected();
|
||||
if (selectedNode) {
|
||||
return tree.findNodeByDomElement(selectedNode);
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
disableBackupButton() {
|
||||
this.__internal.buttons[2].element.disabled = true;
|
||||
}
|
||||
|
||||
enableBackupButton() {
|
||||
this.__internal.buttons[2].element.disabled = false;
|
||||
}
|
||||
|
||||
createDialog(node, treeInfo, typeOfDialog, $container) {
|
||||
let attributes = {};
|
||||
if (typeOfDialog !== 'backup_objects') {
|
||||
attributes['type'] = typeOfDialog;
|
||||
}
|
||||
// Instance of backbone model
|
||||
const newModel = new this.dialogModel(attributes, {
|
||||
node_info: treeInfo,
|
||||
});
|
||||
const fields = this.backform.generateViewSchema(
|
||||
treeInfo, newModel, 'create', node, treeInfo.server, true
|
||||
);
|
||||
|
||||
return this.view = new this.backform.Dialog({
|
||||
el: $container,
|
||||
model: newModel,
|
||||
schema: fields,
|
||||
});
|
||||
}
|
||||
|
||||
retrieveServerIdentifier(node, selectedTreeNode) {
|
||||
const treeInfo = getTreeNodeHierarchyFromElement(
|
||||
this.pgBrowser,
|
||||
selectedTreeNode
|
||||
);
|
||||
return treeInfo.server._id;
|
||||
}
|
||||
|
||||
setListenersForFilenameChanges() {
|
||||
const self = this;
|
||||
|
||||
this.view.model.on('change', function () {
|
||||
if (!_.isUndefined(this.get('file')) && this.get('file') !== '') {
|
||||
this.errorModel.clear();
|
||||
self.enableBackupButton();
|
||||
} else {
|
||||
self.disableBackupButton();
|
||||
this.errorModel.set('file', gettext('Please provide a filename'));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
setExtraParameters(selectedTreeNode, treeInfo) {
|
||||
if (this.typeOfDialog === 'backup_objects') {
|
||||
|
||||
this.view.model.set('database', treeInfo.database._label);
|
||||
|
||||
const nodeData = selectedTreeNode.getData();
|
||||
if (nodeData._type === 'schema') {
|
||||
this.view.model.set('schemas', [nodeData._label]);
|
||||
}
|
||||
|
||||
if (nodeData._type === 'table') {
|
||||
this.view.model.set('tables', [
|
||||
[treeInfo.schema._label, nodeData._label],
|
||||
]);
|
||||
}
|
||||
|
||||
if (_.isEmpty(this.view.model.get('ratio'))) {
|
||||
this.view.model.unset('ratio');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wasBackupButtonPressed(event) {
|
||||
return event.button['data-btn-name'] === 'backup';
|
||||
}
|
||||
}
|
||||
23
web/pgadmin/tools/backup/static/js/menu_utils.js
Normal file
23
web/pgadmin/tools/backup/static/js/menu_utils.js
Normal file
@@ -0,0 +1,23 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
import {isValidTreeNodeData} from '../../../../static/js/tree/tree';
|
||||
|
||||
export const backupSupportedNodes = [
|
||||
'database', 'schema', 'table', 'partition',
|
||||
];
|
||||
|
||||
function isNodeAServerAndConnected(treeNodeData) {
|
||||
return (('server' === treeNodeData._type) && treeNodeData.connected);
|
||||
}
|
||||
|
||||
export function menuEnabledServer(treeNodeData) {
|
||||
return isValidTreeNodeData(treeNodeData)
|
||||
&& isNodeAServerAndConnected(treeNodeData);
|
||||
}
|
||||
@@ -1,10 +1,14 @@
|
||||
define('pgadmin.datagrid', [
|
||||
'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
|
||||
'pgadmin.alertifyjs', 'sources/pgadmin', 'bundled_codemirror',
|
||||
'sources/sqleditor_utils', 'backbone', 'wcdocker',
|
||||
'sources/sqleditor_utils', 'backbone',
|
||||
'tools/datagrid/static/js/show_data',
|
||||
'tools/datagrid/static/js/get_panel_title',
|
||||
'tools/datagrid/static/js/show_query_tool',
|
||||
'wcdocker',
|
||||
], function(
|
||||
gettext, url_for, $, _, alertify, pgAdmin, codemirror, sqlEditorUtils,
|
||||
Backbone
|
||||
Backbone, showData, panelTitle, showQueryTool
|
||||
) {
|
||||
// Some scripts do export their object in the window only.
|
||||
// Generally the one, which do no have AMD support.
|
||||
@@ -161,55 +165,7 @@ define('pgadmin.datagrid', [
|
||||
|
||||
// This is a callback function to show data when user click on menu item.
|
||||
show_data_grid: function(data, i) {
|
||||
var self = this,
|
||||
d = pgAdmin.Browser.tree.itemData(i);
|
||||
if (d === undefined) {
|
||||
alertify.alert(
|
||||
gettext('Data Grid Error'),
|
||||
gettext('No object selected.')
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the parent data from the tree node hierarchy.
|
||||
var node = pgBrowser.Nodes[d._type],
|
||||
parentData = node.getTreeNodeHierarchy(i);
|
||||
|
||||
// If server, database or schema is undefined then return from the function.
|
||||
if (parentData.server === undefined || parentData.database === undefined) {
|
||||
return;
|
||||
}
|
||||
// If schema, view, catalog object all are undefined then return from the function.
|
||||
if (parentData.schema === undefined && parentData.view === undefined &&
|
||||
parentData.catalog === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
var nsp_name = '';
|
||||
|
||||
if (parentData.schema != undefined) {
|
||||
nsp_name = parentData.schema.label;
|
||||
}
|
||||
else if (parentData.view != undefined) {
|
||||
nsp_name = parentData.view.label;
|
||||
}
|
||||
else if (parentData.catalog != undefined) {
|
||||
nsp_name = parentData.catalog.label;
|
||||
}
|
||||
var url_params = {
|
||||
'cmd_type': data.mnuid,
|
||||
'obj_type': d._type,
|
||||
'sgid': parentData.server_group._id,
|
||||
'sid': parentData.server._id,
|
||||
'did': parentData.database._id,
|
||||
'obj_id': d._id,
|
||||
};
|
||||
|
||||
var baseUrl = url_for('datagrid.initialize_datagrid', url_params);
|
||||
var grid_title = parentData.server.label + ' - ' + parentData.database.label + ' - '
|
||||
+ nsp_name + '.' + d.label;
|
||||
|
||||
self.create_transaction(baseUrl, null, 'false', parentData.server.server_type, '', grid_title, '');
|
||||
showData.showDataGrid(this, pgBrowser, alertify, data, i);
|
||||
},
|
||||
|
||||
// This is a callback function to show filtered data when user click on menu item.
|
||||
@@ -384,63 +340,12 @@ define('pgadmin.datagrid', [
|
||||
},
|
||||
|
||||
get_panel_title: function() {
|
||||
// Get the parent data from the tree node hierarchy.
|
||||
var tree = pgAdmin.Browser.tree,
|
||||
selected_item = tree.selected(),
|
||||
item_data = tree.itemData(selected_item);
|
||||
|
||||
var node = pgBrowser.Nodes[item_data._type],
|
||||
parentData = node.getTreeNodeHierarchy(selected_item);
|
||||
|
||||
// If server, database is undefined then return from the function.
|
||||
if (parentData.server === undefined) {
|
||||
return;
|
||||
}
|
||||
// If Database is not available then use default db
|
||||
var db_label = parentData.database ? parentData.database.label
|
||||
: parentData.server.db;
|
||||
|
||||
var grid_title = db_label + ' on ' + parentData.server.user.name + '@' +
|
||||
parentData.server.label;
|
||||
return grid_title;
|
||||
return panelTitle.getPanelTitle(pgBrowser);
|
||||
},
|
||||
// This is a callback function to show query tool when user click on menu item.
|
||||
show_query_tool: function(url, i, panel_title) {
|
||||
var sURL = url || '',
|
||||
d = pgAdmin.Browser.tree.itemData(i);
|
||||
|
||||
panel_title = panel_title || '';
|
||||
if (d === undefined) {
|
||||
alertify.alert(
|
||||
gettext('Query Tool Error'),
|
||||
gettext('No object selected.')
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the parent data from the tree node hierarchy.
|
||||
var node = pgBrowser.Nodes[d._type],
|
||||
parentData = node.getTreeNodeHierarchy(i);
|
||||
|
||||
// If server, database is undefined then return from the function.
|
||||
if (parentData.server === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
var url_params = {
|
||||
'sgid': parentData.server_group._id,
|
||||
'sid': parentData.server._id,
|
||||
},
|
||||
url_endpoint = 'datagrid.initialize_query_tool';
|
||||
// If database not present then use Maintenance database
|
||||
// We will handle this at server side
|
||||
if (parentData.database) {
|
||||
url_params['did'] = parentData.database._id;
|
||||
url_endpoint = 'datagrid.initialize_query_tool_with_did';
|
||||
}
|
||||
var baseUrl = url_for(url_endpoint, url_params);
|
||||
|
||||
this.create_transaction(baseUrl, null, 'true', parentData.server.server_type, sURL, panel_title, '', false);
|
||||
show_query_tool: function(url, aciTreeIdentifier, panelTitle) {
|
||||
showQueryTool.showQueryTool(this, pgBrowser, alertify, url,
|
||||
aciTreeIdentifier, panelTitle);
|
||||
},
|
||||
create_transaction: function(baseUrl, target, is_query_tool, server_type, sURL, panel_title, sql_filter, recreate) {
|
||||
var self = this;
|
||||
|
||||
33
web/pgadmin/tools/datagrid/static/js/get_panel_title.js
Normal file
33
web/pgadmin/tools/datagrid/static/js/get_panel_title.js
Normal file
@@ -0,0 +1,33 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
import {getTreeNodeHierarchyFromIdentifier} from '../../../../static/js/tree/pgadmin_tree_node';
|
||||
|
||||
function getDatabaseLabel(parentData) {
|
||||
return parentData.database ? parentData.database.label
|
||||
: parentData.server.db;
|
||||
}
|
||||
|
||||
function isServerInformationAvailable(parentData) {
|
||||
return parentData.server === undefined;
|
||||
}
|
||||
|
||||
export function getPanelTitle(pgBrowser) {
|
||||
const selected_item = pgBrowser.treeMenu.selected();
|
||||
|
||||
const parentData = getTreeNodeHierarchyFromIdentifier
|
||||
.call(pgBrowser, selected_item);
|
||||
if (isServerInformationAvailable(parentData)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const db_label = getDatabaseLabel(parentData);
|
||||
|
||||
return `${db_label} on ${parentData.server.user.name}@${parentData.server.label}`;
|
||||
}
|
||||
92
web/pgadmin/tools/datagrid/static/js/show_data.js
Normal file
92
web/pgadmin/tools/datagrid/static/js/show_data.js
Normal file
@@ -0,0 +1,92 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
import gettext from '../../../../static/js/gettext';
|
||||
import url_for from '../../../../static/js/url_for';
|
||||
import {getTreeNodeHierarchyFromIdentifier} from '../../../../static/js/tree/pgadmin_tree_node';
|
||||
|
||||
export function showDataGrid(
|
||||
datagrid,
|
||||
pgBrowser,
|
||||
alertify,
|
||||
connectionData,
|
||||
aciTreeIdentifier
|
||||
) {
|
||||
const node = pgBrowser.treeMenu.findNodeByDomElement(aciTreeIdentifier);
|
||||
if (node === undefined || !node.getData()) {
|
||||
alertify.alert(
|
||||
gettext('Data Grid Error'),
|
||||
gettext('No object selected.')
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const parentData = getTreeNodeHierarchyFromIdentifier.call(
|
||||
pgBrowser,
|
||||
aciTreeIdentifier
|
||||
);
|
||||
|
||||
if (hasServerOrDatabaseConfiguration(parentData)
|
||||
|| !hasSchemaOrCatalogOrViewInformation(parentData)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let namespaceName = retrieveNameSpaceName(parentData);
|
||||
const baseUrl = generateUrl(connectionData, node.getData(), parentData);
|
||||
const grid_title = generateDatagridTitle(parentData, namespaceName, node.getData());
|
||||
|
||||
datagrid.create_transaction(
|
||||
baseUrl,
|
||||
null,
|
||||
'false',
|
||||
parentData.server.server_type,
|
||||
'',
|
||||
grid_title,
|
||||
''
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function retrieveNameSpaceName(parentData) {
|
||||
if (parentData.schema !== undefined) {
|
||||
return parentData.schema.label;
|
||||
}
|
||||
else if (parentData.view !== undefined) {
|
||||
return parentData.view.label;
|
||||
}
|
||||
else if (parentData.catalog !== undefined) {
|
||||
return parentData.catalog.label;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function generateUrl(connectionData, nodeData, parentData) {
|
||||
const url_params = {
|
||||
'cmd_type': connectionData.mnuid,
|
||||
'obj_type': nodeData._type,
|
||||
'sgid': parentData.server_group._id,
|
||||
'sid': parentData.server._id,
|
||||
'did': parentData.database._id,
|
||||
'obj_id': nodeData._id,
|
||||
};
|
||||
|
||||
return url_for('datagrid.initialize_datagrid', url_params);
|
||||
}
|
||||
|
||||
function hasServerOrDatabaseConfiguration(parentData) {
|
||||
return parentData.server === undefined || parentData.database === undefined;
|
||||
}
|
||||
|
||||
function hasSchemaOrCatalogOrViewInformation(parentData) {
|
||||
return parentData.schema !== undefined || parentData.view !== undefined ||
|
||||
parentData.catalog !== undefined;
|
||||
}
|
||||
|
||||
function generateDatagridTitle(parentData, namespaceName, nodeData) {
|
||||
return `${parentData.server.label} - ${parentData.database.label} - ${namespaceName}.${nodeData.label}`;
|
||||
}
|
||||
63
web/pgadmin/tools/datagrid/static/js/show_query_tool.js
Normal file
63
web/pgadmin/tools/datagrid/static/js/show_query_tool.js
Normal file
@@ -0,0 +1,63 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
import gettext from '../../../../static/js/gettext';
|
||||
import url_for from '../../../../static/js/url_for';
|
||||
import {getTreeNodeHierarchyFromIdentifier} from '../../../../static/js/tree/pgadmin_tree_node';
|
||||
|
||||
function hasDatabaseInformation(parentData) {
|
||||
return parentData.database;
|
||||
}
|
||||
|
||||
function generateUrl(parentData) {
|
||||
let url_endpoint = 'datagrid.initialize_query_tool';
|
||||
let url_params = {
|
||||
'sgid': parentData.server_group._id,
|
||||
'sid': parentData.server._id,
|
||||
};
|
||||
|
||||
if (hasDatabaseInformation(parentData)) {
|
||||
url_params['did'] = parentData.database._id;
|
||||
url_endpoint = 'datagrid.initialize_query_tool_with_did';
|
||||
}
|
||||
|
||||
return url_for(url_endpoint, url_params);
|
||||
}
|
||||
|
||||
function hasServerInformations(parentData) {
|
||||
return parentData.server === undefined;
|
||||
}
|
||||
|
||||
export function showQueryTool(datagrid, pgBrowser, alertify, url,
|
||||
aciTreeIdentifier, panelTitle) {
|
||||
const sURL = url || '';
|
||||
const queryToolTitle = panelTitle || '';
|
||||
|
||||
const currentNode = pgBrowser.treeMenu.findNodeByDomElement(aciTreeIdentifier);
|
||||
if (currentNode === undefined) {
|
||||
alertify.alert(
|
||||
gettext('Query Tool Error'),
|
||||
gettext('No object selected.')
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const parentData = getTreeNodeHierarchyFromIdentifier.call(
|
||||
pgBrowser, aciTreeIdentifier);
|
||||
|
||||
if (hasServerInformations(parentData)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const baseUrl = generateUrl(parentData);
|
||||
|
||||
datagrid.create_transaction(
|
||||
baseUrl, null, 'true',
|
||||
parentData.server.server_type, sURL, queryToolTitle, '', false);
|
||||
}
|
||||
@@ -2,12 +2,15 @@
|
||||
define([
|
||||
'sources/gettext', 'sources/url_for', 'jquery', 'underscore', 'backbone',
|
||||
'pgadmin.alertifyjs', 'pgadmin.backgrid', 'pgadmin.backform',
|
||||
'pgadmin.browser', 'pgadmin.browser.node', 'backgrid.select.all',
|
||||
'pgadmin.browser', 'pgadmin.browser.node',
|
||||
'tools/grant_wizard/static/js/menu_utils',
|
||||
'sources/nodes/supported_database_node',
|
||||
'backgrid.select.all',
|
||||
'backgrid.filter', 'pgadmin.browser.server.privilege',
|
||||
'pgadmin.browser.wizard',
|
||||
], function(
|
||||
gettext, url_for, $, _, Backbone, Alertify, Backgrid, Backform, pgBrowser,
|
||||
pgNode
|
||||
pgNode, menuUtils, supportedNodes
|
||||
) {
|
||||
|
||||
// if module is already initialized, refer to that.
|
||||
@@ -143,41 +146,6 @@ define([
|
||||
|
||||
this.initialized = true;
|
||||
|
||||
// Define list of nodes on which grant wizard context menu option appears
|
||||
var supported_nodes = [
|
||||
'schema', 'coll-function', 'coll-sequence',
|
||||
'coll-table', 'coll-view', 'coll-procedure',
|
||||
'coll-mview', 'database', 'coll-trigger_function',
|
||||
],
|
||||
|
||||
/**
|
||||
Enable/disable grantwizard menu in tools based
|
||||
on node selected
|
||||
if selected node is present in supported_nodes,
|
||||
menu will be enabled otherwise disabled.
|
||||
Also, hide it for system view in catalogs
|
||||
*/
|
||||
menu_enabled = function(itemData, item) {
|
||||
var t = pgBrowser.tree,
|
||||
i = item,
|
||||
d = itemData;
|
||||
var parent_item = t.hasParent(i) ? t.parent(i) : null,
|
||||
parent_data = parent_item ? t.itemData(parent_item) : null;
|
||||
if (!_.isUndefined(d) && !_.isNull(d) && !_.isNull(parent_data)) {
|
||||
if (_.indexOf(supported_nodes, d._type) !== -1 &&
|
||||
parent_data._type != 'catalog') {
|
||||
if (d._type == 'database' && d.allowConn)
|
||||
return true;
|
||||
else if (d._type != 'database')
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
} else
|
||||
return false;
|
||||
} else
|
||||
return false;
|
||||
};
|
||||
|
||||
// Define the nodes on which the menus to be appear
|
||||
var menus = [{
|
||||
name: 'grant_wizard_schema',
|
||||
@@ -187,21 +155,25 @@ define([
|
||||
priority: 14,
|
||||
label: gettext('Grant Wizard...'),
|
||||
icon: 'fa fa-unlock-alt',
|
||||
enable: menu_enabled,
|
||||
enable: supportedNodes.enabled.bind(
|
||||
null, pgBrowser.treeMenu, menuUtils.supportedNodes
|
||||
),
|
||||
}];
|
||||
|
||||
// Add supported menus into the menus list
|
||||
for (var idx = 0; idx < supported_nodes.length; idx++) {
|
||||
for (var idx = 0; idx < menuUtils.supportedNodes.length; idx++) {
|
||||
menus.push({
|
||||
name: 'grant_wizard_schema_context_' + supported_nodes[idx],
|
||||
node: supported_nodes[idx],
|
||||
name: 'grant_wizard_schema_context_' + menuUtils.supportedNodes[idx],
|
||||
node: menuUtils.supportedNodes[idx],
|
||||
module: this,
|
||||
applies: ['context'],
|
||||
callback: 'start_grant_wizard',
|
||||
priority: 14,
|
||||
label: gettext('Grant Wizard...'),
|
||||
icon: 'fa fa-unlock-alt',
|
||||
enable: menu_enabled,
|
||||
enable: supportedNodes.enabled.bind(
|
||||
null, pgBrowser.treeMenu, menuUtils.supportedNodes
|
||||
),
|
||||
});
|
||||
}
|
||||
pgBrowser.add_menus(menus);
|
||||
|
||||
16
web/pgadmin/tools/grant_wizard/static/js/menu_utils.js
Normal file
16
web/pgadmin/tools/grant_wizard/static/js/menu_utils.js
Normal file
@@ -0,0 +1,16 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
export const supportedNodes = [
|
||||
'schema', 'coll-function', 'coll-sequence',
|
||||
'coll-table', 'coll-view', 'coll-procedure',
|
||||
'coll-mview', 'database', 'coll-trigger_function',
|
||||
];
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
define([
|
||||
'sources/gettext', 'sources/url_for', 'jquery', 'underscore', 'underscore.string', 'pgadmin.alertifyjs',
|
||||
'sources/pgadmin', 'pgadmin.browser', 'backbone', 'backgrid', 'backform',
|
||||
'sources/utils', 'pgadmin.backform', 'pgadmin.backgrid', 'pgadmin.browser.node.ui',
|
||||
'sources/utils',
|
||||
'sources/nodes/supported_database_node',
|
||||
'pgadmin.backform', 'pgadmin.backgrid', 'pgadmin.browser.node.ui',
|
||||
], function(
|
||||
gettext, url_for, $, _, S, Alertify, pgAdmin, pgBrowser, Backbone, Backgrid,
|
||||
Backform, commonUtils
|
||||
Backform, commonUtils, supportedNodes
|
||||
) {
|
||||
|
||||
pgAdmin = pgAdmin || window.pgAdmin || {};
|
||||
@@ -383,25 +385,6 @@ Backform, commonUtils
|
||||
|
||||
this.initialized = true;
|
||||
|
||||
/*
|
||||
* Enable/disable import menu in tools based on node selected. Import
|
||||
* menu will be enabled only when user select table node.
|
||||
*/
|
||||
var menu_enabled = function(itemData, item) {
|
||||
var t = pgBrowser.tree,
|
||||
i = item,
|
||||
d = itemData;
|
||||
var parent_item = t.hasParent(i) ? t.parent(i) : null,
|
||||
parent_data = parent_item ? t.itemData(parent_item) : null;
|
||||
if (!_.isUndefined(d) && !_.isNull(d) && !_.isNull(parent_data))
|
||||
return (
|
||||
(_.indexOf(['table'], d._type) !== -1 &&
|
||||
parent_data._type != 'catalog') ? true : false
|
||||
);
|
||||
else
|
||||
return false;
|
||||
};
|
||||
|
||||
// Initialize the context menu to display the import options when user open the context menu for table
|
||||
pgBrowser.add_menus([{
|
||||
name: 'import',
|
||||
@@ -413,7 +396,9 @@ Backform, commonUtils
|
||||
priority: 10,
|
||||
label: gettext('Import/Export...'),
|
||||
icon: 'fa fa-shopping-cart',
|
||||
enable: menu_enabled,
|
||||
enable: supportedNodes.enabled.bind(
|
||||
null, pgBrowser.treeMenu, ['table']
|
||||
),
|
||||
}]);
|
||||
},
|
||||
|
||||
|
||||
@@ -2,11 +2,14 @@ define([
|
||||
'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
|
||||
'underscore.string', 'pgadmin.alertifyjs', 'sources/pgadmin', 'pgadmin.browser', 'backbone',
|
||||
'backgrid', 'backform', 'sources/utils',
|
||||
'tools/maintenance/static/js/menu_utils',
|
||||
'sources/nodes/supported_database_node',
|
||||
'pgadmin.backform', 'pgadmin.backgrid',
|
||||
'pgadmin.browser.node.ui',
|
||||
], function(
|
||||
gettext, url_for, $, _, S, Alertify, pgAdmin, pgBrowser, Backbone, Backgrid,
|
||||
Backform, commonUtils
|
||||
Backform, commonUtils,
|
||||
menuUtils, supportedNodes
|
||||
) {
|
||||
|
||||
pgAdmin = pgAdmin || window.pgAdmin || {};
|
||||
@@ -168,36 +171,6 @@ define([
|
||||
|
||||
this.initialized = true;
|
||||
|
||||
var maintenance_supported_nodes = [
|
||||
'database', 'table', 'primary_key',
|
||||
'unique_constraint', 'index', 'partition',
|
||||
];
|
||||
|
||||
/**
|
||||
Enable/disable Maintenance menu in tools based on node selected.
|
||||
Maintenance menu will be enabled only when user select table and database node.
|
||||
*/
|
||||
var menu_enabled = function(itemData, item) {
|
||||
var t = pgBrowser.tree,
|
||||
i = item,
|
||||
d = itemData;
|
||||
var parent_item = t.hasParent(i) ? t.parent(i) : null,
|
||||
parent_data = parent_item ? t.itemData(parent_item) : null;
|
||||
if (!_.isUndefined(d) && !_.isNull(d) && !_.isNull(parent_data)) {
|
||||
if (_.indexOf(maintenance_supported_nodes, d._type) !== -1 &&
|
||||
parent_data._type != 'catalog') {
|
||||
if (d._type == 'database' && d.allowConn)
|
||||
return true;
|
||||
else if (d._type != 'database')
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
} else
|
||||
return false;
|
||||
} else
|
||||
return false;
|
||||
};
|
||||
|
||||
var menus = [{
|
||||
name: 'maintenance',
|
||||
module: this,
|
||||
@@ -206,21 +179,25 @@ define([
|
||||
priority: 10,
|
||||
label: gettext('Maintenance...'),
|
||||
icon: 'fa fa-wrench',
|
||||
enable: menu_enabled,
|
||||
enable: supportedNodes.enabled.bind(
|
||||
null, pgBrowser.treeMenu, menuUtils.maintenanceSupportedNodes
|
||||
),
|
||||
}];
|
||||
|
||||
// Add supported menus into the menus list
|
||||
for (var idx = 0; idx < maintenance_supported_nodes.length; idx++) {
|
||||
for (var idx = 0; idx < menuUtils.maintenanceSupportedNodes.length; idx++) {
|
||||
menus.push({
|
||||
name: 'maintenance_context_' + maintenance_supported_nodes[idx],
|
||||
node: maintenance_supported_nodes[idx],
|
||||
name: 'maintenance_context_' + menuUtils.maintenanceSupportedNodes[idx],
|
||||
node: menuUtils.maintenanceSupportedNodes[idx],
|
||||
module: this,
|
||||
applies: ['context'],
|
||||
callback: 'callback_maintenance',
|
||||
priority: 10,
|
||||
label: gettext('Maintenance...'),
|
||||
icon: 'fa fa-wrench',
|
||||
enable: menu_enabled,
|
||||
enable: supportedNodes.enabled.bind(
|
||||
null, pgBrowser.treeMenu, menuUtils.maintenanceSupportedNodes
|
||||
),
|
||||
});
|
||||
}
|
||||
pgBrowser.add_menus(menus);
|
||||
|
||||
13
web/pgadmin/tools/maintenance/static/js/menu_utils.js
Normal file
13
web/pgadmin/tools/maintenance/static/js/menu_utils.js
Normal file
@@ -0,0 +1,13 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
export const maintenanceSupportedNodes = [
|
||||
'database', 'table', 'primary_key',
|
||||
'unique_constraint', 'index', 'partition',
|
||||
];
|
||||
18
web/pgadmin/tools/restore/static/js/menu_utils.js
Normal file
18
web/pgadmin/tools/restore/static/js/menu_utils.js
Normal file
@@ -0,0 +1,18 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
export const restoreSupportedNodes = [
|
||||
'database',
|
||||
'schema',
|
||||
'table',
|
||||
'function',
|
||||
'trigger',
|
||||
'index',
|
||||
'partition',
|
||||
];
|
||||
@@ -1,11 +1,13 @@
|
||||
// Restore dialog
|
||||
define('tools.restore', [
|
||||
'sources/gettext', 'sources/url_for', 'jquery', 'underscore', 'backbone',
|
||||
'underscore.string', 'pgadmin.alertifyjs', 'pgadmin.browser',
|
||||
'pgadmin.backgrid', 'pgadmin.backform', 'sources/utils',
|
||||
'tools/restore/static/js/menu_utils',
|
||||
'sources/nodes/supported_database_node',
|
||||
'tools/restore/static/js/restore_dialog',
|
||||
], function(
|
||||
gettext, url_for, $, _, Backbone, S, alertify, pgBrowser, Backgrid, Backform,
|
||||
commonUtils
|
||||
commonUtils, menuUtils, supportedNodes, restoreDialog
|
||||
) {
|
||||
|
||||
// if module is already initialized, refer to that.
|
||||
@@ -307,59 +309,6 @@ commonUtils
|
||||
|
||||
this.initialized = true;
|
||||
|
||||
// Define list of nodes on which restore context menu option appears
|
||||
var restore_supported_nodes = [
|
||||
'database', 'schema',
|
||||
'table', 'function',
|
||||
'trigger', 'index',
|
||||
'partition',
|
||||
];
|
||||
|
||||
/**
|
||||
Enable/disable restore menu in tools based
|
||||
on node selected
|
||||
if selected node is present in supported_nodes,
|
||||
menu will be enabled otherwise disabled.
|
||||
Also, hide it for system view in catalogs
|
||||
*/
|
||||
var menu_enabled = function(itemData, item, data) {
|
||||
var t = pgBrowser.tree,
|
||||
i = item,
|
||||
d = itemData;
|
||||
var parent_item = t.hasParent(i) ? t.parent(i) : null,
|
||||
parent_data = parent_item ? t.itemData(parent_item) : null;
|
||||
if (!_.isUndefined(d) && !_.isNull(d) && !_.isNull(parent_data)) {
|
||||
if (_.indexOf(restore_supported_nodes, d._type) !== -1 &&
|
||||
is_parent_catalog(itemData, item, data)) {
|
||||
if (d._type == 'database' && d.allowConn)
|
||||
return true;
|
||||
else if (d._type != 'database')
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
} else
|
||||
return false;
|
||||
} else
|
||||
return false;
|
||||
};
|
||||
|
||||
var is_parent_catalog = function(itemData, item) {
|
||||
var t = pgBrowser.tree,
|
||||
i = item,
|
||||
d = itemData;
|
||||
|
||||
// To iterate over tree to check parent node
|
||||
while (i) {
|
||||
// If it is schema then allow user to restore
|
||||
if (_.indexOf(['catalog'], d._type) > -1)
|
||||
return false;
|
||||
i = t.hasParent(i) ? t.parent(i) : null;
|
||||
d = i ? t.itemData(i) : null;
|
||||
}
|
||||
// by default we do not want to allow create menu
|
||||
return true;
|
||||
};
|
||||
|
||||
// Define the nodes on which the menus to be appear
|
||||
var menus = [{
|
||||
name: 'restore_object',
|
||||
@@ -369,20 +318,24 @@ commonUtils
|
||||
priority: 13,
|
||||
label: gettext('Restore...'),
|
||||
icon: 'fa fa-upload',
|
||||
enable: menu_enabled,
|
||||
enable: supportedNodes.enabled.bind(
|
||||
null, pgBrowser.treeMenu, menuUtils.restoreSupportedNodes
|
||||
),
|
||||
}];
|
||||
|
||||
for (var idx = 0; idx < restore_supported_nodes.length; idx++) {
|
||||
for (var idx = 0; idx < menuUtils.restoreSupportedNodes.length; idx++) {
|
||||
menus.push({
|
||||
name: 'restore_' + restore_supported_nodes[idx],
|
||||
node: restore_supported_nodes[idx],
|
||||
name: 'restore_' + menuUtils.restoreSupportedNodes[idx],
|
||||
node: menuUtils.restoreSupportedNodes[idx],
|
||||
module: this,
|
||||
applies: ['context'],
|
||||
callback: 'restore_objects',
|
||||
priority: 13,
|
||||
label: gettext('Restore...'),
|
||||
icon: 'fa fa-upload',
|
||||
enable: menu_enabled,
|
||||
enable: supportedNodes.enabled.bind(
|
||||
null, pgBrowser.treeMenu, menuUtils.restoreSupportedNodes
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -391,318 +344,10 @@ commonUtils
|
||||
},
|
||||
// Callback to draw Backup Dialog for objects
|
||||
restore_objects: function(action, treeItem) {
|
||||
|
||||
var i = treeItem || pgBrowser.tree.selected(),
|
||||
server_data = null;
|
||||
|
||||
while (i) {
|
||||
var node_data = pgBrowser.tree.itemData(i);
|
||||
if (node_data._type == 'server') {
|
||||
server_data = node_data;
|
||||
break;
|
||||
}
|
||||
|
||||
if (pgBrowser.tree.hasParent(i)) {
|
||||
i = $(pgBrowser.tree.parent(i));
|
||||
} else {
|
||||
alertify.alert(
|
||||
gettext('Restore Error'),
|
||||
gettext('Please select server or child node from tree.')
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!server_data) {
|
||||
return;
|
||||
}
|
||||
|
||||
var module = 'paths',
|
||||
preference_name = 'pg_bin_dir',
|
||||
msg = gettext('Please configure the PostgreSQL Binary Path in the Preferences dialog.');
|
||||
|
||||
if ((server_data.type && server_data.type == 'ppas') ||
|
||||
server_data.server_type == 'ppas') {
|
||||
preference_name = 'ppas_bin_dir';
|
||||
msg = gettext('Please configure the EDB Advanced Server Binary Path in the Preferences dialog.');
|
||||
}
|
||||
|
||||
var preference = pgBrowser.get_preference(module, preference_name);
|
||||
|
||||
if (preference) {
|
||||
if (!preference.value) {
|
||||
alertify.alert(gettext('Configuration required'), msg);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
alertify.alert(
|
||||
gettext('Restore Error'),
|
||||
S(gettext('Failed to load preference %s of module %s')).sprintf(preference_name, module).value()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
var title = S(gettext('Restore (%s: %s)')),
|
||||
tree = pgBrowser.tree,
|
||||
item = treeItem || tree.selected(),
|
||||
data = item && item.length == 1 && tree.itemData(item),
|
||||
node = data && data._type && pgBrowser.Nodes[data._type];
|
||||
|
||||
if (!node)
|
||||
return;
|
||||
|
||||
var treeInfo = node.getTreeNodeHierarchy.apply(node, [item]);
|
||||
|
||||
if (treeInfo.database._label.indexOf('=') >= 0) {
|
||||
alertify.alert(
|
||||
gettext('Restore error'),
|
||||
gettext('Restore job creation failed. '+
|
||||
'Databases with = symbols in the name cannot be restored using this utility.')
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
title = title.sprintf(node.label, data.label).value();
|
||||
|
||||
if (!alertify.pg_restore) {
|
||||
// Create Dialog title on the fly with node details
|
||||
alertify.dialog('pg_restore', function factory() {
|
||||
return {
|
||||
main: function(title, item, data, node) {
|
||||
this.set('title', title);
|
||||
this.setting('pg_node', node);
|
||||
this.setting('pg_item', item);
|
||||
this.setting('pg_item_data', data);
|
||||
},
|
||||
build: function() {
|
||||
alertify.pgDialogBuild.apply(this);
|
||||
},
|
||||
setup: function() {
|
||||
return {
|
||||
buttons: [{
|
||||
text: '',
|
||||
className: 'btn btn-default pull-left fa fa-lg fa-info',
|
||||
attrs: {
|
||||
name: 'object_help',
|
||||
type: 'button',
|
||||
url: 'backup.html',
|
||||
label: gettext('Restore'),
|
||||
},
|
||||
}, {
|
||||
text: '',
|
||||
key: 112,
|
||||
className: 'btn btn-default pull-left fa fa-lg fa-question',
|
||||
attrs: {
|
||||
name: 'dialog_help',
|
||||
type: 'button',
|
||||
label: gettext('Restore'),
|
||||
url: url_for('help.static', {
|
||||
'filename': 'restore_dialog.html',
|
||||
}),
|
||||
},
|
||||
}, {
|
||||
text: gettext('Restore'),
|
||||
key: 13,
|
||||
className: 'btn btn-primary fa fa-upload pg-alertify-button',
|
||||
restore: true,
|
||||
'data-btn-name': 'restore',
|
||||
}, {
|
||||
text: gettext('Cancel'),
|
||||
key: 27,
|
||||
className: 'btn btn-danger fa fa-lg fa-times pg-alertify-button',
|
||||
restore: false,
|
||||
'data-btn-name': 'cancel',
|
||||
}],
|
||||
// Set options for dialog
|
||||
options: {
|
||||
title: title,
|
||||
//disable both padding and overflow control.
|
||||
padding: !1,
|
||||
overflow: !1,
|
||||
model: 0,
|
||||
resizable: true,
|
||||
maximizable: true,
|
||||
pinnable: false,
|
||||
closableByDimmer: false,
|
||||
modal: false,
|
||||
},
|
||||
};
|
||||
},
|
||||
hooks: {
|
||||
// triggered when the dialog is closed
|
||||
onclose: function() {
|
||||
if (this.view) {
|
||||
this.view.remove({
|
||||
data: true,
|
||||
internal: true,
|
||||
silent: true,
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
settings: {
|
||||
pg_node: null,
|
||||
pg_item: null,
|
||||
pg_item_data: null,
|
||||
},
|
||||
prepare: function() {
|
||||
|
||||
var self = this;
|
||||
// Disable Backup button until user provides Filename
|
||||
this.__internal.buttons[2].element.disabled = true;
|
||||
var $container = $('<div class=\'restore_dialog\'></div>');
|
||||
var t = pgBrowser.tree,
|
||||
i = t.selected(),
|
||||
d = i && i.length == 1 ? t.itemData(i) : undefined,
|
||||
node = d && pgBrowser.Nodes[d._type];
|
||||
|
||||
if (!d)
|
||||
return;
|
||||
|
||||
var treeInfo = node.getTreeNodeHierarchy.apply(node, [i]);
|
||||
|
||||
var newModel = new RestoreObjectModel({
|
||||
node_data: node,
|
||||
}, {
|
||||
node_info: treeInfo,
|
||||
}),
|
||||
fields = Backform.generateViewSchema(
|
||||
treeInfo, newModel, 'create', node, treeInfo.server, true
|
||||
);
|
||||
|
||||
var view = this.view = new Backform.Dialog({
|
||||
el: $container,
|
||||
model: newModel,
|
||||
schema: fields,
|
||||
});
|
||||
|
||||
$(this.elements.body.childNodes[0]).addClass(
|
||||
'alertify_tools_dialog_properties obj_properties'
|
||||
);
|
||||
|
||||
view.render();
|
||||
|
||||
this.elements.content.appendChild($container.get(0));
|
||||
|
||||
view.$el.attr('tabindex', -1);
|
||||
// var dialogTabNavigator = pgBrowser.keyboardNavigation.getDialogTabNavigator(view);
|
||||
pgBrowser.keyboardNavigation.getDialogTabNavigator(view);
|
||||
var container = view.$el.find('.tab-content:first > .tab-pane.active:first');
|
||||
commonUtils.findAndSetFocus(container);
|
||||
|
||||
// Listen to model & if filename is provided then enable Backup button
|
||||
this.view.model.on('change', function() {
|
||||
if (!_.isUndefined(this.get('file')) && this.get('file') !== '') {
|
||||
this.errorModel.clear();
|
||||
self.__internal.buttons[2].element.disabled = false;
|
||||
} else {
|
||||
self.__internal.buttons[2].element.disabled = true;
|
||||
this.errorModel.set('file', gettext('Please provide filename'));
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
// Callback functions when click on the buttons of the Alertify dialogs
|
||||
callback: function(e) {
|
||||
// Fetch current server id
|
||||
var t = pgBrowser.tree,
|
||||
i = this.settings['pg_item'] || t.selected(),
|
||||
d = this.settings['pg_item_data'] || (
|
||||
i && i.length == 1 ? t.itemData(i) : undefined
|
||||
),
|
||||
node = this.settings['pg_node'] || (
|
||||
d && pgBrowser.Nodes[d._type]
|
||||
);
|
||||
|
||||
if (e.button.element.name == 'dialog_help' || e.button.element.name == 'object_help') {
|
||||
e.cancel = true;
|
||||
pgBrowser.showHelp(e.button.element.name, e.button.element.getAttribute('url'),
|
||||
node, i, e.button.element.getAttribute('label'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.button['data-btn-name'] === 'restore') {
|
||||
if (!d)
|
||||
return;
|
||||
|
||||
var info = node.getTreeNodeHierarchy.apply(node, [i]),
|
||||
m = this.view.model;
|
||||
// Set current node info into model
|
||||
m.set('database', info.database._label);
|
||||
if (!m.get('custom')) {
|
||||
switch (d._type) {
|
||||
case 'schema':
|
||||
m.set('schemas', [d._label]);
|
||||
break;
|
||||
case 'table':
|
||||
m.set('schemas', [info.schema._label]);
|
||||
m.set('tables', [d._label]);
|
||||
break;
|
||||
case 'function':
|
||||
m.set('schemas', [info.schema._label]);
|
||||
m.set('functions', [d._label]);
|
||||
break;
|
||||
case 'index':
|
||||
m.set('schemas', [info.schema._label]);
|
||||
m.set('indexes', [d._label]);
|
||||
break;
|
||||
case 'trigger':
|
||||
m.set('schemas', [info.schema._label]);
|
||||
m.set('triggers', [d._label]);
|
||||
break;
|
||||
case 'trigger_func':
|
||||
m.set('schemas', [info.schema._label]);
|
||||
m.set('trigger_funcs', [d._label]);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// TODO::
|
||||
// When we will implement the object selection in the
|
||||
// import dialog, we will need to select the objects from
|
||||
// the tree selection tab.
|
||||
}
|
||||
|
||||
var self = this,
|
||||
baseUrl = url_for('restore.create_job', {
|
||||
'sid': info.server._id,
|
||||
}),
|
||||
args = this.view.model.toJSON();
|
||||
|
||||
$.ajax({
|
||||
url: baseUrl,
|
||||
method: 'POST',
|
||||
data: {
|
||||
'data': JSON.stringify(args),
|
||||
},
|
||||
success: function(res) {
|
||||
if (res.success) {
|
||||
alertify.success(
|
||||
gettext('Restore job created.'), 5
|
||||
);
|
||||
pgBrowser.Events.trigger('pgadmin-bgprocess:created', self);
|
||||
} else {
|
||||
console.warn(res);
|
||||
}
|
||||
},
|
||||
error: function(xhr) {
|
||||
try {
|
||||
var err = JSON.parse(xhr.responseText);
|
||||
alertify.alert(
|
||||
gettext('Restore failed.'),
|
||||
err.errormsg
|
||||
);
|
||||
} catch (e) {
|
||||
console.warn(e.stack || e);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
alertify.pg_restore(title, item, data, node).resizeTo('65%', '60%');
|
||||
let dialog = new restoreDialog.RestoreDialog(
|
||||
pgBrowser, $, alertify, RestoreObjectModel
|
||||
);
|
||||
dialog.draw(action, treeItem);
|
||||
},
|
||||
};
|
||||
return pgBrowser.Restore;
|
||||
|
||||
322
web/pgadmin/tools/restore/static/js/restore.js.rej
Normal file
322
web/pgadmin/tools/restore/static/js/restore.js.rej
Normal file
@@ -0,0 +1,322 @@
|
||||
diff a/web/pgadmin/tools/restore/static/js/restore.js b/web/pgadmin/tools/restore/static/js/restore.js (rejected hunks)
|
||||
@@ -391,318 +344,8 @@ commonUtils
|
||||
},
|
||||
// Callback to draw Backup Dialog for objects
|
||||
restore_objects: function(action, treeItem) {
|
||||
-
|
||||
- var i = treeItem || pgBrowser.tree.selected(),
|
||||
- server_data = null;
|
||||
-
|
||||
- while (i) {
|
||||
- var node_data = pgBrowser.tree.itemData(i);
|
||||
- if (node_data._type == 'server') {
|
||||
- server_data = node_data;
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- if (pgBrowser.tree.hasParent(i)) {
|
||||
- i = $(pgBrowser.tree.parent(i));
|
||||
- } else {
|
||||
- alertify.alert(
|
||||
- gettext('Restore Error'),
|
||||
- gettext('Please select server or child node from tree.')
|
||||
- );
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (!server_data) {
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- var module = 'paths',
|
||||
- preference_name = 'pg_bin_dir',
|
||||
- msg = gettext('Please configure the PostgreSQL Binary Path in the Preferences dialog.');
|
||||
-
|
||||
- if ((server_data.type && server_data.type == 'ppas') ||
|
||||
- server_data.server_type == 'ppas') {
|
||||
- preference_name = 'ppas_bin_dir';
|
||||
- msg = gettext('Please configure the EDB Advanced Server Binary Path in the Preferences dialog.');
|
||||
- }
|
||||
-
|
||||
- var preference = pgBrowser.get_preference(module, preference_name);
|
||||
-
|
||||
- if (preference) {
|
||||
- if (!preference.value) {
|
||||
- alertify.alert(gettext('Configuration required'), msg);
|
||||
- return;
|
||||
- }
|
||||
- } else {
|
||||
- alertify.alert(
|
||||
- gettext('Restore Error'),
|
||||
- S(gettext('Failed to load preference %s of module %s')).sprintf(preference_name, module).value()
|
||||
- );
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- var title = S(gettext('Restore (%s: %s)')),
|
||||
- tree = pgBrowser.tree,
|
||||
- item = treeItem || tree.selected(),
|
||||
- data = item && item.length == 1 && tree.itemData(item),
|
||||
- node = data && data._type && pgBrowser.Nodes[data._type];
|
||||
-
|
||||
- if (!node)
|
||||
- return;
|
||||
-
|
||||
- var treeInfo = node.getTreeNodeHierarchy.apply(node, [item]);
|
||||
-
|
||||
- if (treeInfo.database._label.indexOf('=') >= 0) {
|
||||
- alertify.alert(
|
||||
- gettext('Restore error'),
|
||||
- gettext('Restore job creation failed. '+
|
||||
- 'Databases with = symbols in the name cannot be restored using this utility.')
|
||||
- );
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- title = title.sprintf(node.label, data.label).value();
|
||||
-
|
||||
- if (!alertify.pg_restore) {
|
||||
- // Create Dialog title on the fly with node details
|
||||
- alertify.dialog('pg_restore', function factory() {
|
||||
- return {
|
||||
- main: function(title, item, data, node) {
|
||||
- this.set('title', title);
|
||||
- this.setting('pg_node', node);
|
||||
- this.setting('pg_item', item);
|
||||
- this.setting('pg_item_data', data);
|
||||
- },
|
||||
- build: function() {
|
||||
- alertify.pgDialogBuild.apply(this);
|
||||
- },
|
||||
- setup: function() {
|
||||
- return {
|
||||
- buttons: [{
|
||||
- text: '',
|
||||
- className: 'btn btn-default pull-left fa fa-lg fa-info',
|
||||
- attrs: {
|
||||
- name: 'object_help',
|
||||
- type: 'button',
|
||||
- url: 'backup.html',
|
||||
- label: gettext('Restore'),
|
||||
- },
|
||||
- }, {
|
||||
- text: '',
|
||||
- key: 112,
|
||||
- className: 'btn btn-default pull-left fa fa-lg fa-question',
|
||||
- attrs: {
|
||||
- name: 'dialog_help',
|
||||
- type: 'button',
|
||||
- label: gettext('Restore'),
|
||||
- url: url_for('help.static', {
|
||||
- 'filename': 'restore_dialog.html',
|
||||
- }),
|
||||
- },
|
||||
- }, {
|
||||
- text: gettext('Restore'),
|
||||
- key: 13,
|
||||
- className: 'btn btn-primary fa fa-upload pg-alertify-button',
|
||||
- restore: true,
|
||||
- 'data-btn-name': 'restore',
|
||||
- }, {
|
||||
- text: gettext('Cancel'),
|
||||
- key: 27,
|
||||
- className: 'btn btn-danger fa fa-lg fa-times pg-alertify-button',
|
||||
- restore: false,
|
||||
- 'data-btn-name': 'cancel',
|
||||
- }],
|
||||
- // Set options for dialog
|
||||
- options: {
|
||||
- title: title,
|
||||
- //disable both padding and overflow control.
|
||||
- padding: !1,
|
||||
- overflow: !1,
|
||||
- model: 0,
|
||||
- resizable: true,
|
||||
- maximizable: true,
|
||||
- pinnable: false,
|
||||
- closableByDimmer: false,
|
||||
- modal: false,
|
||||
- },
|
||||
- };
|
||||
- },
|
||||
- hooks: {
|
||||
- // triggered when the dialog is closed
|
||||
- onclose: function() {
|
||||
- if (this.view) {
|
||||
- this.view.remove({
|
||||
- data: true,
|
||||
- internal: true,
|
||||
- silent: true,
|
||||
- });
|
||||
- }
|
||||
- },
|
||||
- },
|
||||
- settings: {
|
||||
- pg_node: null,
|
||||
- pg_item: null,
|
||||
- pg_item_data: null,
|
||||
- },
|
||||
- prepare: function() {
|
||||
-
|
||||
- var self = this;
|
||||
- // Disable Backup button until user provides Filename
|
||||
- this.__internal.buttons[2].element.disabled = true;
|
||||
- var $container = $('<div class=\'restore_dialog\'></div>');
|
||||
- var t = pgBrowser.tree,
|
||||
- i = t.selected(),
|
||||
- d = i && i.length == 1 ? t.itemData(i) : undefined,
|
||||
- node = d && pgBrowser.Nodes[d._type];
|
||||
-
|
||||
- if (!d)
|
||||
- return;
|
||||
-
|
||||
- var treeInfo = node.getTreeNodeHierarchy.apply(node, [i]);
|
||||
-
|
||||
- var newModel = new RestoreObjectModel({
|
||||
- node_data: node,
|
||||
- }, {
|
||||
- node_info: treeInfo,
|
||||
- }),
|
||||
- fields = Backform.generateViewSchema(
|
||||
- treeInfo, newModel, 'create', node, treeInfo.server, true
|
||||
- );
|
||||
-
|
||||
- var view = this.view = new Backform.Dialog({
|
||||
- el: $container,
|
||||
- model: newModel,
|
||||
- schema: fields,
|
||||
- });
|
||||
-
|
||||
- $(this.elements.body.childNodes[0]).addClass(
|
||||
- 'alertify_tools_dialog_properties obj_properties'
|
||||
- );
|
||||
-
|
||||
- view.render();
|
||||
-
|
||||
- this.elements.content.appendChild($container.get(0));
|
||||
-
|
||||
- view.$el.attr('tabindex', -1);
|
||||
- // var dialogTabNavigator = pgBrowser.keyboardNavigation.getDialogTabNavigator(view);
|
||||
- pgBrowser.keyboardNavigation.getDialogTabNavigator(view);
|
||||
- var container = view.$el.find('.tab-content:first > .tab-pane.active:first');
|
||||
- commonUtils.findAndSetFocus(container);
|
||||
-
|
||||
- // Listen to model & if filename is provided then enable Backup button
|
||||
- this.view.model.on('change', function() {
|
||||
- if (!_.isUndefined(this.get('file')) && this.get('file') !== '') {
|
||||
- this.errorModel.clear();
|
||||
- self.__internal.buttons[2].element.disabled = false;
|
||||
- } else {
|
||||
- self.__internal.buttons[2].element.disabled = true;
|
||||
- this.errorModel.set('file', gettext('Please provide filename'));
|
||||
- }
|
||||
- });
|
||||
-
|
||||
- },
|
||||
- // Callback functions when click on the buttons of the Alertify dialogs
|
||||
- callback: function(e) {
|
||||
- // Fetch current server id
|
||||
- var t = pgBrowser.tree,
|
||||
- i = this.settings['pg_item'] || t.selected(),
|
||||
- d = this.settings['pg_item_data'] || (
|
||||
- i && i.length == 1 ? t.itemData(i) : undefined
|
||||
- ),
|
||||
- node = this.settings['pg_node'] || (
|
||||
- d && pgBrowser.Nodes[d._type]
|
||||
- );
|
||||
-
|
||||
- if (e.button.element.name == 'dialog_help' || e.button.element.name == 'object_help') {
|
||||
- e.cancel = true;
|
||||
- pgBrowser.showHelp(e.button.element.name, e.button.element.getAttribute('url'),
|
||||
- node, i, e.button.element.getAttribute('label'));
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- if (e.button['data-btn-name'] === 'restore') {
|
||||
- if (!d)
|
||||
- return;
|
||||
-
|
||||
- var info = node.getTreeNodeHierarchy.apply(node, [i]),
|
||||
- m = this.view.model;
|
||||
- // Set current node info into model
|
||||
- m.set('database', info.database._label);
|
||||
- if (!m.get('custom')) {
|
||||
- switch (d._type) {
|
||||
- case 'schema':
|
||||
- m.set('schemas', [d._label]);
|
||||
- break;
|
||||
- case 'table':
|
||||
- m.set('schemas', [info.schema._label]);
|
||||
- m.set('tables', [d._label]);
|
||||
- break;
|
||||
- case 'function':
|
||||
- m.set('schemas', [info.schema._label]);
|
||||
- m.set('functions', [d._label]);
|
||||
- break;
|
||||
- case 'index':
|
||||
- m.set('schemas', [info.schema._label]);
|
||||
- m.set('indexes', [d._label]);
|
||||
- break;
|
||||
- case 'trigger':
|
||||
- m.set('schemas', [info.schema._label]);
|
||||
- m.set('triggers', [d._label]);
|
||||
- break;
|
||||
- case 'trigger_func':
|
||||
- m.set('schemas', [info.schema._label]);
|
||||
- m.set('trigger_funcs', [d._label]);
|
||||
- break;
|
||||
- }
|
||||
- } else {
|
||||
- // TODO::
|
||||
- // When we will implement the object selection in the
|
||||
- // import dialog, we will need to select the objects from
|
||||
- // the tree selection tab.
|
||||
- }
|
||||
-
|
||||
- var self = this,
|
||||
- baseUrl = url_for('restore.create_job', {
|
||||
- 'sid': info.server._id,
|
||||
- }),
|
||||
- args = this.view.model.toJSON();
|
||||
-
|
||||
- $.ajax({
|
||||
- url: baseUrl,
|
||||
- method: 'POST',
|
||||
- data: {
|
||||
- 'data': JSON.stringify(args),
|
||||
- },
|
||||
- success: function(res) {
|
||||
- if (res.success) {
|
||||
- alertify.success(
|
||||
- gettext('Restore job created.'), 5
|
||||
- );
|
||||
- pgBrowser.Events.trigger('pgadmin-bgprocess:created', self);
|
||||
- } else {
|
||||
- console.warn(res);
|
||||
- }
|
||||
- },
|
||||
- error: function(xhr) {
|
||||
- try {
|
||||
- var err = $.parseJSON(xhr.responseText);
|
||||
- alertify.alert(
|
||||
- gettext('Restore failed.'),
|
||||
- err.errormsg
|
||||
- );
|
||||
- } catch (e) {
|
||||
- console.warn(e.stack || e);
|
||||
- }
|
||||
- },
|
||||
- });
|
||||
- }
|
||||
- },
|
||||
- };
|
||||
- });
|
||||
- }
|
||||
-
|
||||
- alertify.pg_restore(title, item, data, node).resizeTo('65%', '60%');
|
||||
+ let dialog = new restoreDialog.RestoreDialog(pgBrowser, $, alertify, RestoreObjectModel);
|
||||
+ dialog.draw(action, treeItem);
|
||||
},
|
||||
};
|
||||
return pgBrowser.Restore;
|
||||
57
web/pgadmin/tools/restore/static/js/restore_dialog.js
Normal file
57
web/pgadmin/tools/restore/static/js/restore_dialog.js
Normal file
@@ -0,0 +1,57 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
import gettext from '../../../../static/js/gettext';
|
||||
import {sprintf} from 'sprintf-js';
|
||||
import Backform from '../../../../static/js/backform.pgadmin';
|
||||
import {Dialog} from '../../../../static/js/alertify/dialog';
|
||||
|
||||
export class RestoreDialog extends Dialog {
|
||||
constructor(pgBrowser, $, alertify, RestoreModel, backform = Backform) {
|
||||
super('Restore Error',
|
||||
'<div class=\'restore_dialog\'></div>',
|
||||
pgBrowser, $, alertify, RestoreModel, backform);
|
||||
}
|
||||
|
||||
draw(action, aciTreeItem) {
|
||||
|
||||
const serverInformation = this.retrieveAncestorOfTypeServer(aciTreeItem);
|
||||
|
||||
if (!serverInformation) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.hasBinariesConfiguration(serverInformation)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.canExecuteOnCurrentDatabase(aciTreeItem)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let aciTreeItem1 = aciTreeItem || this.pgBrowser.treeMenu.selected();
|
||||
let item = this.pgBrowser.treeMenu.findNodeByDomElement(aciTreeItem1);
|
||||
const data = item.getData();
|
||||
const node = this.pgBrowser.Nodes[data._type];
|
||||
|
||||
if (!node)
|
||||
return;
|
||||
|
||||
let title = sprintf(gettext('Restore (%s: %s)'), node.label, data.label);
|
||||
|
||||
this.createOrGetDialog(title, 'restore');
|
||||
|
||||
this.alertify.pg_restore(title, aciTreeItem1, data, node).resizeTo('65%', '60%');
|
||||
}
|
||||
|
||||
dialogName() {
|
||||
return 'pg_restore';
|
||||
}
|
||||
}
|
||||
|
||||
255
web/pgadmin/tools/restore/static/js/restore_dialog_wrapper.js
Normal file
255
web/pgadmin/tools/restore/static/js/restore_dialog_wrapper.js
Normal file
@@ -0,0 +1,255 @@
|
||||
import {getTreeNodeHierarchyFromElement} from '../../../../static/js/tree/pgadmin_tree_node';
|
||||
import axios from 'axios/index';
|
||||
import _ from 'underscore';
|
||||
import gettext from '../../../../static/js/gettext';
|
||||
import url_for from '../../../../static/js/url_for';
|
||||
import {DialogWrapper} from '../../../../static/js/alertify/dialog_wrapper';
|
||||
|
||||
export class RestoreDialogWrapper extends DialogWrapper {
|
||||
constructor(dialogContainerSelector, dialogTitle, typeOfDialog,
|
||||
jquery, pgBrowser, alertify, dialogModel, backform) {
|
||||
super(dialogContainerSelector, dialogTitle, jquery,
|
||||
pgBrowser, alertify, dialogModel, backform);
|
||||
}
|
||||
|
||||
main(title, item, data, node) {
|
||||
this.set('title', title);
|
||||
this.setting('pg_node', node);
|
||||
this.setting('pg_item', item);
|
||||
this.setting('pg_item_data', data);
|
||||
}
|
||||
|
||||
setup() {
|
||||
return {
|
||||
buttons: [{
|
||||
text: '',
|
||||
className: 'btn btn-default pull-left fa fa-lg fa-info',
|
||||
attrs: {
|
||||
name: 'object_help',
|
||||
type: 'button',
|
||||
url: 'backup.html',
|
||||
label: gettext('Restore'),
|
||||
},
|
||||
}, {
|
||||
text: '',
|
||||
key: 112,
|
||||
className: 'btn btn-default pull-left fa fa-lg fa-question',
|
||||
attrs: {
|
||||
name: 'dialog_help',
|
||||
type: 'button',
|
||||
label: gettext('Restore'),
|
||||
url: url_for('help.static', {
|
||||
'filename': 'restore_dialog.html',
|
||||
}),
|
||||
},
|
||||
}, {
|
||||
text: gettext('Restore'),
|
||||
key: 13,
|
||||
className: 'btn btn-primary fa fa-upload pg-alertify-button',
|
||||
restore: true,
|
||||
'data-btn-name': 'restore',
|
||||
}, {
|
||||
text: gettext('Cancel'),
|
||||
key: 27,
|
||||
className: 'btn btn-danger fa fa-lg fa-times pg-alertify-button',
|
||||
restore: false,
|
||||
'data-btn-name': 'cancel',
|
||||
}],
|
||||
// Set options for dialog
|
||||
options: {
|
||||
title: this.dialogTitle,
|
||||
//disable both padding and overflow control.
|
||||
padding: !1,
|
||||
overflow: !1,
|
||||
model: 0,
|
||||
resizable: true,
|
||||
maximizable: true,
|
||||
pinnable: false,
|
||||
closableByDimmer: false,
|
||||
modal: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
prepare() {
|
||||
this.disableRestoreButton();
|
||||
|
||||
const $container = this.jquery(this.dialogContainerSelector);
|
||||
const selectedTreeNode = this.getSelectedNode();
|
||||
const selectedTreeNodeData = this.getSelectedNodeData(selectedTreeNode);
|
||||
if (!selectedTreeNodeData) {
|
||||
return;
|
||||
}
|
||||
|
||||
const node = this.pgBrowser.Nodes[selectedTreeNodeData._type];
|
||||
|
||||
const treeInfo = getTreeNodeHierarchyFromElement(this.pgBrowser, selectedTreeNode);
|
||||
const dialog = this.createDialog(node, treeInfo, $container);
|
||||
this.addAlertifyClassToRestoreNodeChildNodes();
|
||||
dialog.render();
|
||||
|
||||
this.elements.content.appendChild($container.get(0));
|
||||
|
||||
this.focusOnDialog(dialog);
|
||||
this.setListenersForFilenameChanges();
|
||||
}
|
||||
|
||||
callback(event) {
|
||||
const selectedTreeNode = this.getSelectedNode();
|
||||
const selectedTreeNodeData = this.getSelectedNodeData(selectedTreeNode);
|
||||
const node = selectedTreeNodeData && this.pgBrowser.Nodes[selectedTreeNodeData._type];
|
||||
|
||||
if (this.wasHelpButtonPressed(event)) {
|
||||
event.cancel = true;
|
||||
this.pgBrowser.showHelp(
|
||||
event.button.element.name,
|
||||
event.button.element.getAttribute('url'),
|
||||
node,
|
||||
selectedTreeNode,
|
||||
event.button.element.getAttribute('label')
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.wasRestoreButtonPressed(event)) {
|
||||
|
||||
if (!selectedTreeNodeData)
|
||||
return;
|
||||
|
||||
const serverIdentifier = this.retrieveServerIdentifier(node, selectedTreeNode);
|
||||
|
||||
const dialogWrapper = this;
|
||||
let urlShortcut = 'restore.create_job';
|
||||
|
||||
const baseUrl = url_for(urlShortcut, {
|
||||
'sid': serverIdentifier,
|
||||
});
|
||||
|
||||
const treeInfo = getTreeNodeHierarchyFromElement(
|
||||
this.pgBrowser,
|
||||
selectedTreeNode
|
||||
);
|
||||
|
||||
this.setExtraParameters(selectedTreeNode, treeInfo);
|
||||
|
||||
let service = axios.create({});
|
||||
service.post(
|
||||
baseUrl,
|
||||
this.view.model.toJSON()
|
||||
).then(function () {
|
||||
dialogWrapper.alertify.success(gettext('Restore job created.'), 5);
|
||||
dialogWrapper.pgBrowser.Events.trigger('pgadmin-bgprocess:created', dialogWrapper);
|
||||
}).catch(function (error) {
|
||||
try {
|
||||
const err = error.response.data;
|
||||
dialogWrapper.alertify.alert(
|
||||
gettext('Restore job failed.'),
|
||||
err.errormsg
|
||||
);
|
||||
} catch (e) {
|
||||
console.warn(e.stack || e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
addAlertifyClassToRestoreNodeChildNodes() {
|
||||
this.jquery(this.elements.body.childNodes[0]).addClass(
|
||||
'alertify_tools_dialog_properties obj_properties'
|
||||
);
|
||||
}
|
||||
|
||||
getSelectedNode() {
|
||||
const tree = this.pgBrowser.treeMenu;
|
||||
const selectedNode = tree.selected();
|
||||
if (selectedNode) {
|
||||
return tree.findNodeByDomElement(selectedNode);
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
disableRestoreButton() {
|
||||
this.__internal.buttons[2].element.disabled = true;
|
||||
}
|
||||
|
||||
enableRestoreButton() {
|
||||
this.__internal.buttons[2].element.disabled = false;
|
||||
}
|
||||
|
||||
createDialog(node, treeInfo, $container) {
|
||||
const newModel = new this.dialogModel({
|
||||
node_data: node,
|
||||
}, {
|
||||
node_info: treeInfo,
|
||||
});
|
||||
const fields = this.backform.generateViewSchema(
|
||||
treeInfo, newModel, 'create', node, treeInfo.server, true
|
||||
);
|
||||
|
||||
return this.view = new this.backform.Dialog({
|
||||
el: $container,
|
||||
model: newModel,
|
||||
schema: fields,
|
||||
});
|
||||
}
|
||||
|
||||
retrieveServerIdentifier(node, selectedTreeNode) {
|
||||
const treeInfo = getTreeNodeHierarchyFromElement(
|
||||
this.pgBrowser,
|
||||
selectedTreeNode
|
||||
);
|
||||
return treeInfo.server._id;
|
||||
}
|
||||
|
||||
setListenersForFilenameChanges() {
|
||||
const self = this;
|
||||
|
||||
this.view.model.on('change', function () {
|
||||
if (!_.isUndefined(this.get('file')) && this.get('file') !== '') {
|
||||
this.errorModel.clear();
|
||||
self.enableRestoreButton();
|
||||
} else {
|
||||
self.disableRestoreButton();
|
||||
this.errorModel.set('file', gettext('Please provide a filename'));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
setExtraParameters(selectedTreeNode, treeInfo) {
|
||||
this.view.model.set('database', treeInfo.database._label);
|
||||
if (!this.view.model.get('custom')) {
|
||||
const nodeData = selectedTreeNode.getData();
|
||||
|
||||
switch (nodeData._type) {
|
||||
case 'schema':
|
||||
this.view.model.set('schemas', [nodeData._label]);
|
||||
break;
|
||||
case 'table':
|
||||
this.view.model.set('schemas', [treeInfo.schema._label]);
|
||||
this.view.model.set('tables', [nodeData._label]);
|
||||
break;
|
||||
case 'function':
|
||||
this.view.model.set('schemas', [treeInfo.schema._label]);
|
||||
this.view.model.set('functions', [nodeData._label]);
|
||||
break;
|
||||
case 'index':
|
||||
this.view.model.set('schemas', [treeInfo.schema._label]);
|
||||
this.view.model.set('indexes', [nodeData._label]);
|
||||
break;
|
||||
case 'trigger':
|
||||
this.view.model.set('schemas', [treeInfo.schema._label]);
|
||||
this.view.model.set('triggers', [nodeData._label]);
|
||||
break;
|
||||
case 'trigger_func':
|
||||
this.view.model.set('schemas', [treeInfo.schema._label]);
|
||||
this.view.model.set('trigger_funcs', [nodeData._label]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wasRestoreButtonPressed(event) {
|
||||
return event.button['data-btn-name'] === 'restore';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user