diff --git a/web/pgadmin/browser/static/js/node.js b/web/pgadmin/browser/static/js/node.js
index 86259d32d..1051c6b5d 100644
--- a/web/pgadmin/browser/static/js/node.js
+++ b/web/pgadmin/browser/static/js/node.js
@@ -509,7 +509,7 @@ define('pgadmin.browser.node', [
w: (!_.isUndefined(width) && !_.isNull(width)) ? width :
(screen.width < 700 ? screen.width * 0.95 : screen.width * 0.5),
h: (!_.isUndefined(height) && !_.isNull(height)) ? height :
- (screen.height < 500 ? screen.height * 0.95 : screen.height * 0.35),
+ (screen.height < 500 ? screen.height * 0.95 : screen.height * 0.4),
x: (screen.width < 700 ? '2%' : '25%'),
y: (screen.height < 500 ? '2%' : '25%'),
}
diff --git a/web/pgadmin/browser/static/js/utility_view.jsx b/web/pgadmin/browser/static/js/utility_view.jsx
index bfe3dfed8..b9c92111d 100644
--- a/web/pgadmin/browser/static/js/utility_view.jsx
+++ b/web/pgadmin/browser/static/js/utility_view.jsx
@@ -26,6 +26,9 @@ export function getUtilityView(schema, treeNodeInfo, actionType, formType, conta
};
const confirmOnReset = pgAdmin.Browser.get_preferences_for_module('browser').confirm_on_properties_close;
+ /* button icons */
+ const saveBtnIcon = extraData.save_btn_icon;
+
/* on save button callback, promise required */
const onSaveClick = (isNew, data)=>new Promise((resolve, reject)=>{
return api({
@@ -90,6 +93,7 @@ export function getUtilityView(schema, treeNodeInfo, actionType, formType, conta
schema={_schema}
viewHelperProps={viewHelperProps}
customSaveBtnName={saveBtnName}
+ customSaveBtnIconType={saveBtnIcon}
onSave={onSaveClick}
onClose={()=>containerPanel.close()}
onHelp={onHelp}
diff --git a/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py b/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py
index a6490c628..75d67f09e 100644
--- a/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py
+++ b/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py
@@ -240,16 +240,24 @@ class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
self.page.fill_input_by_field_name(
NavMenuLocators.restore_file_name_txt_box_name,
- "test_backup", loose_focus=True)
+ "test_backup", input_keys=True, loose_focus=True)
+ # Click on the Restore button
restore_btn = self.page.find_by_xpath(
NavMenuLocators.restore_button_xpath)
- restore_btn.click()
-
- self.page.wait_for_element_to_disappear(
- lambda driver: driver.find_element(
- By.CSS_SELECTOR,
- NavMenuLocators.restore_file_name_txt_box_name))
+ click = True
+ retry = 3
+ while click and retry > 0:
+ try:
+ restore_btn.click()
+ if self.page.wait_for_element_to_disappear(
+ lambda driver: driver.find_element(
+ By.NAME,
+ NavMenuLocators.restore_file_name_txt_box_name)):
+ click = False
+ except Exception:
+ retry -= 1
+ pass
def _check_escaped_characters(self, source_code, string_to_find, source):
# For XSS we need to search against element's html code
diff --git a/web/pgadmin/static/js/SchemaView/index.jsx b/web/pgadmin/static/js/SchemaView/index.jsx
index a8c030260..64feeb27a 100644
--- a/web/pgadmin/static/js/SchemaView/index.jsx
+++ b/web/pgadmin/static/js/SchemaView/index.jsx
@@ -12,6 +12,7 @@ import { Box, makeStyles } from '@material-ui/core';
import {Accordion, AccordionSummary, AccordionDetails} from '@material-ui/core';
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
import SaveIcon from '@material-ui/icons/Save';
+import PublishIcon from '@material-ui/icons/Publish';
import SettingsBackupRestoreIcon from '@material-ui/icons/SettingsBackupRestore';
import CloseIcon from '@material-ui/icons/Close';
import InfoIcon from '@material-ui/icons/InfoRounded';
@@ -683,6 +684,15 @@ function SchemaDialogView({
formErr: formErr,
}), [formResetKey, formErr]);
+ const getButtonIcon = () => {
+ if(props.customSaveBtnIconType == 'upload') {
+ return ;
+ }
+ return ;
+ };
+
+ let ButtonIcon = getButtonIcon();
+
/* I am Groot */
return (
@@ -710,7 +720,7 @@ function SchemaDialogView({
} disabled={!dirty || saving} className={classes.buttonMargin}>
{gettext('Reset')}
- } disabled={!dirty || saving || Boolean(formErr.name) || !formReady}>
+
{props.customSaveBtnName ? gettext(props.customSaveBtnName) : gettext('Save')}
@@ -745,6 +755,7 @@ SchemaDialogView.propTypes = {
showFooter: PropTypes.bool,
resetKey: PropTypes.any,
customSaveBtnName: PropTypes.string,
+ customSaveBtnIconType: PropTypes.string,
};
const usePropsStyles = makeStyles((theme)=>({
diff --git a/web/pgadmin/tools/backup/static/js/backup.js b/web/pgadmin/tools/backup/static/js/backup.js
index bd0744eb5..3e51a3dda 100644
--- a/web/pgadmin/tools/backup/static/js/backup.js
+++ b/web/pgadmin/tools/backup/static/js/backup.js
@@ -142,7 +142,7 @@ define([
},
startBackupGlobal: function(action, treeItem) {
pgBrowser.Node.registerUtilityPanel();
- var panel = pgBrowser.Node.addUtilityPanel();
+ var panel = pgBrowser.Node.addUtilityPanel(pgBrowser.stdW.md);
var tree = pgBrowser.tree,
i = treeItem || tree.selected(),
data = i ? tree.itemData(i) : undefined,
@@ -159,7 +159,7 @@ define([
},
startBackupServer: function(action, treeItem) {
pgBrowser.Node.registerUtilityPanel();
- var panel = pgBrowser.Node.addUtilityPanel();
+ var panel = pgBrowser.Node.addUtilityPanel(pgBrowser.stdW.md);
var tree = pgBrowser.tree,
i = treeItem || tree.selected(),
data = i ? tree.itemData(i) : undefined,
@@ -235,7 +235,7 @@ define([
}
pgBrowser.Node.registerUtilityPanel();
- var panel = pgBrowser.Node.addUtilityPanel(),
+ var panel = pgBrowser.Node.addUtilityPanel(pgBrowser.stdW.md, pgBrowser.stdH.lg),
j = panel.$container.find('.obj_properties').first();
var schema = that.getUISchema(treeItem, 'backup_objects');
diff --git a/web/pgadmin/tools/backup/static/js/backup.ui.js b/web/pgadmin/tools/backup/static/js/backup.ui.js
index 5ea2f865b..58d9b5316 100644
--- a/web/pgadmin/tools/backup/static/js/backup.ui.js
+++ b/web/pgadmin/tools/backup/static/js/backup.ui.js
@@ -515,7 +515,7 @@ export default class BackupSchema extends BaseUISchema {
}, {
type: 'nested-fieldset',
label: gettext('Sections'),
- group: gettext('Dump options'),
+ group: gettext('Data/Objects'),
schema:new getSectionSchema(),
visible: function() {
if (!_.isUndefined(obj.backupType) && obj.backupType === 'server')
@@ -525,27 +525,27 @@ export default class BackupSchema extends BaseUISchema {
}, {
type: 'nested-fieldset',
label: gettext('Type of objects'),
- group: gettext('Dump options'),
+ group: gettext('Data/Objects'),
schema: obj.getTypeObjSchema()
}, {
type: 'nested-fieldset',
label: gettext('Do not save'),
- group: gettext('Dump options'),
+ group: gettext('Data/Objects'),
schema: obj.getSaveOptSchema(),
}, {
type: 'nested-fieldset',
label: gettext('Queries'),
- group: gettext('Dump options'),
+ group: gettext('Options'),
schema: obj.getQueryOptionSchema(),
}, {
type: 'nested-fieldset',
label: gettext('Disable'),
- group: gettext('Dump options'),
+ group: gettext('Options'),
schema: obj.getDisabledOptionSchema(),
}, {
type: 'nested-fieldset',
label: gettext('Miscellaneous'),
- group: gettext('Dump options'),
+ group: gettext('Options'),
schema: obj.getMiscellaneousSchema(),
}];
}
diff --git a/web/pgadmin/tools/restore/static/js/restore.js b/web/pgadmin/tools/restore/static/js/restore.js
index 76f00d55e..efa2e04fe 100644
--- a/web/pgadmin/tools/restore/static/js/restore.js
+++ b/web/pgadmin/tools/restore/static/js/restore.js
@@ -80,7 +80,7 @@ define('tools.restore', [
()=>getRestoreSectionSchema({selectedNodeType: itemNodeData._type}),
()=>getRestoreTypeObjSchema({selectedNodeType: itemNodeData._type}),
()=>getRestoreSaveOptSchema({nodeInfo: treeNodeInfo}),
- ()=>getRestoreQueryOptionSchema({nodeInfo: treeNodeInfo}),
+ ()=>getRestoreQueryOptionSchema({selectedNodeType: itemNodeData._type, nodeInfo: treeNodeInfo}),
()=>getRestoreDisableOptionSchema({nodeInfo: treeNodeInfo}),
()=>getRestoreMiscellaneousSchema({nodeInfo: treeNodeInfo}),
{
@@ -115,6 +115,7 @@ define('tools.restore', [
if('function' in treeInfo) {
extraData['functions'] = [nodeData._label];
}
+ extraData['save_btn_icon'] = 'upload';
return extraData;
},
url_for_utility_exists: function(id){
@@ -146,7 +147,7 @@ define('tools.restore', [
return;
}
pgBrowser.Node.registerUtilityPanel();
- var panel = pgBrowser.Node.addUtilityPanel(),
+ var panel = pgBrowser.Node.addUtilityPanel(pgBrowser.stdW.md),
j = panel.$container.find('.obj_properties').first();
var schema = that.getUISchema(treeItem);
@@ -159,7 +160,7 @@ define('tools.restore', [
}),
extraData = that.setExtraParameters(treeNodeInfo, data);
- var sqlHelpUrl = 'restore.html',
+ var sqlHelpUrl = 'backup.html',
helpUrl = url_for('help.static', {
'filename': 'restore_dialog.html',
});
diff --git a/web/pgadmin/tools/restore/static/js/restore.ui.js b/web/pgadmin/tools/restore/static/js/restore.ui.js
index d14d0e9ee..e6dbeb9dd 100644
--- a/web/pgadmin/tools/restore/static/js/restore.ui.js
+++ b/web/pgadmin/tools/restore/static/js/restore.ui.js
@@ -100,6 +100,9 @@ export class RestoreTypeObjSchema extends BaseUISchema {
group: gettext('Type of objects'),
deps: ['pre_data', 'data', 'post_data', 'only_schema'],
disabled: function(state) {
+ if(obj.selectedNodeType == 'table') {
+ state.only_data = true;
+ }
return (obj.selectedNodeType !== 'database' && obj.selectedNodeType !== 'schema') ||
(state.pre_data ||
state.data ||
@@ -114,6 +117,9 @@ export class RestoreTypeObjSchema extends BaseUISchema {
group: gettext('Type of objects'),
deps: ['pre_data', 'data', 'post_data', 'only_data'],
disabled: function(state) {
+ if(obj.selectedNodeType == 'index' || obj.selectedNodeType == 'function') {
+ state.only_schema = true;
+ }
return (obj.selectedNodeType !== 'database' && obj.selectedNodeType !== 'schema') ||
(state.pre_data ||
state.data ||
@@ -174,7 +180,7 @@ export class RestoreSaveOptSchema extends BaseUISchema {
disabled: false,
group: gettext('Do not save'),
visible: function() {
- var serverInfo = obj.fieldOptions.nodeInfo;
+ var serverInfo = obj.fieldOptions.nodeInfo.server;
return !_.isUndefined(serverInfo) && serverInfo.version >= 110000 ? true : false;
},
}];
@@ -218,9 +224,11 @@ export class RestoreQueryOptionSchema extends BaseUISchema {
label: gettext('Clean before restore'),
type: 'switch',
group: gettext('Queries'),
- disabled: function() {
- return obj.selectedNodeType === 'function'
- || obj.selectedNodeType === 'trigger_function';
+ disabled: function(state) {
+ if(obj.selectedNodeType === 'function' || obj.selectedNodeType === 'trigger_function') {
+ state.clean = true;
+ return true;
+ }
},
}, {
id: 'single_transaction',
@@ -407,37 +415,37 @@ export default class RestoreSchema extends BaseUISchema {
}, {
type: 'nested-fieldset',
label: gettext('Sections'),
- group: gettext('Restore options'),
+ group: gettext('Data/Objects'),
schema:obj.getSectionSchema(),
visible: true
}, {
type: 'nested-fieldset',
label: gettext('Type of objects'),
- group: gettext('Restore options'),
+ group: gettext('Data/Objects'),
schema:obj.getRestoreTypeObjSchema(),
visible: true
}, {
type: 'nested-fieldset',
label: gettext('Do not save'),
- group: gettext('Restore options'),
+ group: gettext('Data/Objects'),
schema:obj.getRestoreSaveOptSchema(),
visible: true
}, {
type: 'nested-fieldset',
label: gettext('Queries'),
- group: gettext('Restore options'),
+ group: gettext('Options'),
schema:obj.getRestoreQueryOptionSchema(),
visible: true
}, {
type: 'nested-fieldset',
label: gettext('Disable'),
- group: gettext('Restore options'),
+ group: gettext('Options'),
schema:obj.getRestoreDisableOptionSchema(),
visible: true
}, {
type: 'nested-fieldset',
label: gettext('Miscellaneous / Behavior'),
- group: gettext('Restore options'),
+ group: gettext('Options'),
schema:obj.getRestoreMiscellaneousSchema(),
visible: true
}];
diff --git a/web/regression/feature_utils/locators.py b/web/regression/feature_utils/locators.py
index df606a2b1..e44eac873 100644
--- a/web/regression/feature_utils/locators.py
+++ b/web/regression/feature_utils/locators.py
@@ -100,7 +100,7 @@ class NavMenuLocators:
"//following::input[@name='file']"
restore_button_xpath = \
- "//button[contains(@class,'fa-upload') and contains(.,'Restore')]"
+ "//button[ contains(.,'Restore')]"
maintenance_operation = "//label[text()='Maintenance operation']"