Fixed review comments:
1. Split the restore options/backup options into 2 tabs 2. Restore icon changes 3. feature tests issues 4. restore help link broken 5. Comment section not visible refs #7018pull/64/head
parent
f56b4030f1
commit
6528d086ba
|
@ -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%'),
|
||||
}
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 <PublishIcon />;
|
||||
}
|
||||
return <SaveIcon />;
|
||||
};
|
||||
|
||||
let ButtonIcon = getButtonIcon();
|
||||
|
||||
/* I am Groot */
|
||||
return (
|
||||
<StateUtilsContext.Provider value={stateUtils}>
|
||||
|
@ -710,7 +720,7 @@ function SchemaDialogView({
|
|||
<DefaultButton data-test="Reset" onClick={onResetClick} startIcon={<SettingsBackupRestoreIcon />} disabled={!dirty || saving} className={classes.buttonMargin}>
|
||||
{gettext('Reset')}
|
||||
</DefaultButton>
|
||||
<PrimaryButton data-test="Save" onClick={onSaveClick} startIcon={<SaveIcon />} disabled={!dirty || saving || Boolean(formErr.name) || !formReady}>
|
||||
<PrimaryButton data-test="Save" onClick={onSaveClick} startIcon={ButtonIcon} disabled={!dirty || saving || Boolean(formErr.name) || !formReady}>
|
||||
{props.customSaveBtnName ? gettext(props.customSaveBtnName) : gettext('Save')}
|
||||
</PrimaryButton>
|
||||
</Box>
|
||||
|
@ -745,6 +755,7 @@ SchemaDialogView.propTypes = {
|
|||
showFooter: PropTypes.bool,
|
||||
resetKey: PropTypes.any,
|
||||
customSaveBtnName: PropTypes.string,
|
||||
customSaveBtnIconType: PropTypes.string,
|
||||
};
|
||||
|
||||
const usePropsStyles = makeStyles((theme)=>({
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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(),
|
||||
}];
|
||||
}
|
||||
|
|
|
@ -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',
|
||||
});
|
||||
|
|
|
@ -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
|
||||
}];
|
||||
|
|
|
@ -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']"
|
||||
|
||||
|
|
Loading…
Reference in New Issue