mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
1) Port change password dialog to React. Fixes #7341
2) Port named restore point dialog to React. Fixes #7546
This commit is contained in:
@@ -19,7 +19,7 @@ the restore point to add* to provide a descriptive name for the restore point.
|
|||||||
|
|
||||||
For more information about using a restore point as a recovery target, please
|
For more information about using a restore point as a recovery target, please
|
||||||
see the
|
see the
|
||||||
`PostgreSQL documentation <https://www.postgresql.org/docs/current/recovery-target-settings.html#RECOVERY-TARGET-NAME>`_.
|
`PostgreSQL documentation <https://www.postgresql.org/docs/current/runtime-config-wal.html#RUNTIME-CONFIG-WAL-RECOVERY-TARGET>`_.
|
||||||
|
|
||||||
* Click the *OK* button to save the restore point.
|
* Click the *OK* button to save the restore point.
|
||||||
* Click the *Cancel* button to exit without saving work.
|
* Click the *Cancel* button to exit without saving work.
|
||||||
|
|||||||
@@ -36,5 +36,8 @@ Use the *Change Password* dialog to change your password:
|
|||||||
* Enter the desired password for in the *New Password* field.
|
* Enter the desired password for in the *New Password* field.
|
||||||
* Re-enter the new password in the *Confirm Password* field.
|
* Re-enter the new password in the *Confirm Password* field.
|
||||||
|
|
||||||
Click the *OK* button to change your password; click *Cancel* to exit the dialog
|
Click the *Save* button to change your password.
|
||||||
without changing your password.
|
|
||||||
|
Click the *Close* button to exit without changing your password.
|
||||||
|
|
||||||
|
Click the *Reset* button to reset the values.
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 24 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 37 KiB |
@@ -15,8 +15,10 @@ New features
|
|||||||
Housekeeping
|
Housekeeping
|
||||||
************
|
************
|
||||||
|
|
||||||
|
| `Issue #7341 <https://redmine.postgresql.org/issues/7341>`_ - Port change password dialog to React.
|
||||||
| `Issue #7342 <https://redmine.postgresql.org/issues/7342>`_ - Port Master Password dialog to React.
|
| `Issue #7342 <https://redmine.postgresql.org/issues/7342>`_ - Port Master Password dialog to React.
|
||||||
| `Issue #7492 <https://redmine.postgresql.org/issues/7492>`_ - Removing dynamic module loading and replacing it with static loading.
|
| `Issue #7492 <https://redmine.postgresql.org/issues/7492>`_ - Removing dynamic module loading and replacing it with static loading.
|
||||||
|
| `Issue #7546 <https://redmine.postgresql.org/issues/7546>`_ - Port named restore point dialog to React.
|
||||||
|
|
||||||
Bug fixes
|
Bug fixes
|
||||||
*********
|
*********
|
||||||
|
|||||||
@@ -1615,9 +1615,10 @@ class ServerNode(PGChildNodeView):
|
|||||||
sid: Server id
|
sid: Server id
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
if request.form and request.form['data']:
|
data = None
|
||||||
data = json.loads(request.form['data'], encoding='utf-8')
|
if request.form:
|
||||||
else:
|
data = request.form
|
||||||
|
elif request.data:
|
||||||
data = json.loads(request.data, encoding='utf-8')
|
data = json.loads(request.data, encoding='utf-8')
|
||||||
|
|
||||||
crypt_key = get_crypt_key()[1]
|
crypt_key = get_crypt_key()[1]
|
||||||
|
|||||||
@@ -10,18 +10,17 @@
|
|||||||
import { getNodeListById } from '../../../../static/js/node_ajax';
|
import { getNodeListById } from '../../../../static/js/node_ajax';
|
||||||
import ServerSchema from './server.ui';
|
import ServerSchema from './server.ui';
|
||||||
import Notify from '../../../../../static/js/helpers/Notifier';
|
import Notify from '../../../../../static/js/helpers/Notifier';
|
||||||
import { showServerPassword } from '../../../../static/js/password_dialogs';
|
import { showServerPassword, showChangeServerPassword, showNamedRestorePoint } from '../../../../static/js/password_dialogs';
|
||||||
|
|
||||||
define('pgadmin.node.server', [
|
define('pgadmin.node.server', [
|
||||||
'sources/gettext', 'sources/url_for', 'jquery', 'underscore', 'backbone',
|
'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
|
||||||
'sources/pgadmin', 'pgadmin.browser',
|
'sources/pgadmin', 'pgadmin.browser',
|
||||||
'pgadmin.user_management.current_user',
|
'pgadmin.user_management.current_user',
|
||||||
'pgadmin.alertifyjs', 'pgadmin.backform',
|
|
||||||
'pgadmin.authenticate.kerberos',
|
'pgadmin.authenticate.kerberos',
|
||||||
'pgadmin.browser.server.privilege',
|
'pgadmin.browser.server.privilege',
|
||||||
], function(
|
], function(
|
||||||
gettext, url_for, $, _, Backbone, pgAdmin, pgBrowser,
|
gettext, url_for, $, _, pgAdmin, pgBrowser,
|
||||||
current_user, Alertify, Backform, Kerberos,
|
current_user, Kerberos,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
if (!pgBrowser.Nodes['server']) {
|
if (!pgBrowser.Nodes['server']) {
|
||||||
@@ -377,34 +376,7 @@ define('pgadmin.node.server', [
|
|||||||
if (!d)
|
if (!d)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Alertify.prompt(
|
showNamedRestorePoint(gettext('Restore point name'), d, obj, i);
|
||||||
gettext('Enter the name of the restore point to add'), '',
|
|
||||||
// We will execute this function when user clicks on the OK button
|
|
||||||
function(evt, value) {
|
|
||||||
// If user has provided a value, send it to the server
|
|
||||||
if(!_.isUndefined(value) && !_.isNull(value) && value !== ''
|
|
||||||
&& String(value).replace(/^\s+|\s+$/g, '') !== '') {
|
|
||||||
$.ajax({
|
|
||||||
url: obj.generate_url(i, 'restore_point', d, true),
|
|
||||||
method:'POST',
|
|
||||||
data:{ 'value': JSON.stringify(value) },
|
|
||||||
})
|
|
||||||
.done(function(res) {
|
|
||||||
Notify.success(res.data.result, 10000);
|
|
||||||
})
|
|
||||||
.fail(function(xhr, status, error) {
|
|
||||||
Notify.pgRespErrorNotify(xhr, error);
|
|
||||||
t.unload(i);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
evt.cancel = true;
|
|
||||||
Notify.error(gettext('Please enter a valid name.'), 10000);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// We will execute this function when user clicks on the Cancel
|
|
||||||
// button. Do nothing just close it.
|
|
||||||
function(evt) { evt.cancel = false; }
|
|
||||||
).set({'title': gettext('Restore point name')});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/* Change password */
|
/* Change password */
|
||||||
@@ -414,162 +386,10 @@ define('pgadmin.node.server', [
|
|||||||
t = pgBrowser.tree,
|
t = pgBrowser.tree,
|
||||||
i = input.item || t.selected(),
|
i = input.item || t.selected(),
|
||||||
d = i ? t.itemData(i) : undefined,
|
d = i ? t.itemData(i) : undefined,
|
||||||
url = obj.generate_url(i, 'change_password', d, true),
|
|
||||||
is_pgpass_file_used = false,
|
is_pgpass_file_used = false,
|
||||||
check_pgpass_url = obj.generate_url(i, 'check_pgpass', d, true);
|
check_pgpass_url = obj.generate_url(i, 'check_pgpass', d, true);
|
||||||
|
|
||||||
if (d) {
|
if (d) {
|
||||||
if(!Alertify.changeServerPassword) {
|
|
||||||
var newPasswordModel = Backbone.Model.extend({
|
|
||||||
defaults: {
|
|
||||||
user_name: undefined,
|
|
||||||
password: undefined,
|
|
||||||
newPassword: undefined,
|
|
||||||
confirmPassword: undefined,
|
|
||||||
},
|
|
||||||
validate: function() {
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
passwordChangeFields = [{
|
|
||||||
name: 'user_name', label: gettext('User'),
|
|
||||||
type: 'text', readonly: true, control: 'input',
|
|
||||||
},{
|
|
||||||
name: 'password', label: gettext('Current Password'),
|
|
||||||
type: 'password', disabled: function() { return is_pgpass_file_used; },
|
|
||||||
control: 'input', required: true,
|
|
||||||
},{
|
|
||||||
name: 'newPassword', label: gettext('New Password'),
|
|
||||||
type: 'password', disabled: false, control: 'input',
|
|
||||||
required: true,
|
|
||||||
},{
|
|
||||||
name: 'confirmPassword', label: gettext('Confirm Password'),
|
|
||||||
type: 'password', disabled: false, control: 'input',
|
|
||||||
required: true,
|
|
||||||
}];
|
|
||||||
|
|
||||||
|
|
||||||
Alertify.dialog('changeServerPassword' ,function factory() {
|
|
||||||
return {
|
|
||||||
main: function(params) {
|
|
||||||
var title = gettext('Change Password');
|
|
||||||
this.set('title', title);
|
|
||||||
this.user_name = params.user.name;
|
|
||||||
},
|
|
||||||
setup:function() {
|
|
||||||
return {
|
|
||||||
buttons: [{
|
|
||||||
text: gettext('Cancel'), key: 27,
|
|
||||||
className: 'btn btn-secondary fa fa-times pg-alertify-button', attrs: {name: 'cancel'},
|
|
||||||
},{
|
|
||||||
text: gettext('OK'), key: 13, className: 'btn btn-primary fa fa-check pg-alertify-button',
|
|
||||||
attrs: {name:'submit'},
|
|
||||||
}],
|
|
||||||
// Set options for dialog
|
|
||||||
options: {
|
|
||||||
padding : !1,
|
|
||||||
overflow: !1,
|
|
||||||
modal:false,
|
|
||||||
resizable: true,
|
|
||||||
maximizable: true,
|
|
||||||
pinnable: false,
|
|
||||||
closableByDimmer: 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 Ok button until user provides input
|
|
||||||
this.__internal.buttons[1].element.disabled = true;
|
|
||||||
|
|
||||||
var $container = $('<div class=\'change_password\'></div>'),
|
|
||||||
newpasswordmodel = new newPasswordModel(
|
|
||||||
{'user_name': self.user_name}
|
|
||||||
),
|
|
||||||
view = this.view = new Backform.Form({
|
|
||||||
el: $container,
|
|
||||||
model: newpasswordmodel,
|
|
||||||
fields: passwordChangeFields,
|
|
||||||
});
|
|
||||||
|
|
||||||
view.render();
|
|
||||||
|
|
||||||
this.elements.content.appendChild($container.get(0));
|
|
||||||
|
|
||||||
// Listen to model & if filename is provided then enable Backup button
|
|
||||||
this.view.model.on('change', function() {
|
|
||||||
var that = this,
|
|
||||||
password = this.get('password'),
|
|
||||||
newPassword = this.get('newPassword'),
|
|
||||||
confirmPassword = this.get('confirmPassword');
|
|
||||||
|
|
||||||
// Only check password field if pgpass file is not available
|
|
||||||
if ((!is_pgpass_file_used &&
|
|
||||||
(_.isUndefined(password) || _.isNull(password) || password == '')) ||
|
|
||||||
_.isUndefined(newPassword) || _.isNull(newPassword) || newPassword == '' ||
|
|
||||||
_.isUndefined(confirmPassword) || _.isNull(confirmPassword) || confirmPassword == '') {
|
|
||||||
self.__internal.buttons[1].element.disabled = true;
|
|
||||||
} else if (newPassword != confirmPassword) {
|
|
||||||
self.__internal.buttons[1].element.disabled = true;
|
|
||||||
|
|
||||||
this.errorTimeout && clearTimeout(this.errorTimeout);
|
|
||||||
this.errorTimeout = setTimeout(function() {
|
|
||||||
that.errorModel.set('confirmPassword', gettext('Passwords do not match.'));
|
|
||||||
} ,400);
|
|
||||||
}else {
|
|
||||||
that.errorModel.clear();
|
|
||||||
self.__internal.buttons[1].element.disabled = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
// Callback functions when click on the buttons of the Alertify dialogs
|
|
||||||
callback: function(e) {
|
|
||||||
if (e.button.element.name == 'submit') {
|
|
||||||
var self = this,
|
|
||||||
alertArgs = this.view.model.toJSON();
|
|
||||||
|
|
||||||
e.cancel = true;
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
url: url,
|
|
||||||
method:'POST',
|
|
||||||
data:{'data': JSON.stringify(alertArgs) },
|
|
||||||
})
|
|
||||||
.done(function(res) {
|
|
||||||
if (res.success) {
|
|
||||||
// Notify user to update pgpass file
|
|
||||||
if(is_pgpass_file_used) {
|
|
||||||
Notify.alert(
|
|
||||||
gettext('Change Password'),
|
|
||||||
gettext('Please make sure to disconnect the server'
|
|
||||||
+ ' and update the new password in the pgpass file'
|
|
||||||
+ ' before performing any other operation')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Notify.success(res.info);
|
|
||||||
self.close();
|
|
||||||
} else {
|
|
||||||
Notify.error(res.errormsg);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.fail(function(xhr, status, error) {
|
|
||||||
Notify.pgRespErrorNotify(xhr, error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call to check if server is using pgpass file or not
|
// Call to check if server is using pgpass file or not
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: check_pgpass_url,
|
url: check_pgpass_url,
|
||||||
@@ -579,7 +399,7 @@ define('pgadmin.node.server', [
|
|||||||
if (res.success && res.data.is_pgpass) {
|
if (res.success && res.data.is_pgpass) {
|
||||||
is_pgpass_file_used = true;
|
is_pgpass_file_used = true;
|
||||||
}
|
}
|
||||||
Alertify.changeServerPassword(d).resizeTo('40%','52%');
|
showChangeServerPassword(gettext('Change Password'), d, obj, i, is_pgpass_file_used);
|
||||||
})
|
})
|
||||||
.fail(function(xhr, status, error) {
|
.fail(function(xhr, status, error) {
|
||||||
Notify.pgRespErrorNotify(xhr, error);
|
Notify.pgRespErrorNotify(xhr, error);
|
||||||
|
|||||||
99
web/pgadmin/browser/static/js/ChangePassowrdContent.jsx
Normal file
99
web/pgadmin/browser/static/js/ChangePassowrdContent.jsx
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
/////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// pgAdmin 4 - PostgreSQL Tools
|
||||||
|
//
|
||||||
|
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
|
||||||
|
// This software is released under the PostgreSQL Licence
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
import { makeStyles } from '@material-ui/core';
|
||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import gettext from 'sources/gettext';
|
||||||
|
import BaseUISchema from '../../../static/js/SchemaView/base_schema.ui';
|
||||||
|
import SchemaView from '../../../static/js/SchemaView';
|
||||||
|
|
||||||
|
class ChangePasswordSchema extends BaseUISchema {
|
||||||
|
constructor(user, isPgpassFileUsed) {
|
||||||
|
super({
|
||||||
|
user: user,
|
||||||
|
password: '',
|
||||||
|
newPassword: '',
|
||||||
|
confirmPassword: ''
|
||||||
|
});
|
||||||
|
this.isPgpassFileUsed = isPgpassFileUsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
get baseFields() {
|
||||||
|
let self = this;
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
id: 'user', label: gettext('User'), type: 'text', disabled: true
|
||||||
|
}, {
|
||||||
|
id: 'password', label: gettext('Current Password'), type: 'password',
|
||||||
|
disabled: self.isPgpassFileUsed, noEmpty: self.isPgpassFileUsed ? false : true,
|
||||||
|
controlProps: {
|
||||||
|
maxLength: null
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
id: 'newPassword', label: gettext('New Password'), type: 'password',
|
||||||
|
noEmpty: true,
|
||||||
|
controlProps: {
|
||||||
|
maxLength: null
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
id: 'confirmPassword', label: gettext('Confirm Password'), type: 'password',
|
||||||
|
noEmpty: true,
|
||||||
|
controlProps: {
|
||||||
|
maxLength: null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
validate(state, setError) {
|
||||||
|
let errmsg = null;
|
||||||
|
if (state.newPassword !== state.confirmPassword) {
|
||||||
|
errmsg = gettext('Passwords do not match.');
|
||||||
|
setError('confirmPassword', errmsg);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
setError('confirmPassword', null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const useStyles = makeStyles((theme)=>({
|
||||||
|
root: {
|
||||||
|
...theme.mixins.tabPanel,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
export default function ChangePasswordContent({onSave, onClose, userName, isPgpassFileUsed}) {
|
||||||
|
const classes = useStyles();
|
||||||
|
|
||||||
|
return<SchemaView
|
||||||
|
formType={'dialog'}
|
||||||
|
getInitData={() => { /*This is intentional (SonarQube)*/ }}
|
||||||
|
schema={new ChangePasswordSchema(userName, isPgpassFileUsed)}
|
||||||
|
viewHelperProps={{
|
||||||
|
mode: 'create',
|
||||||
|
}}
|
||||||
|
onSave={onSave}
|
||||||
|
onClose={onClose}
|
||||||
|
hasSQL={false}
|
||||||
|
disableSqlHelp={true}
|
||||||
|
disableDialogHelp={true}
|
||||||
|
isTabView={false}
|
||||||
|
formClassName={classes.root}
|
||||||
|
/>;
|
||||||
|
}
|
||||||
|
ChangePasswordContent.propTypes = {
|
||||||
|
onSave: PropTypes.func,
|
||||||
|
onClose: PropTypes.func,
|
||||||
|
userName: PropTypes.string,
|
||||||
|
isPgpassFileUsed: PropTypes.bool
|
||||||
|
};
|
||||||
@@ -1,3 +1,12 @@
|
|||||||
|
/////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// pgAdmin 4 - PostgreSQL Tools
|
||||||
|
//
|
||||||
|
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
|
||||||
|
// This software is released under the PostgreSQL Licence
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
import React, { useState, useRef, useEffect } from 'react';
|
import React, { useState, useRef, useEffect } from 'react';
|
||||||
import gettext from 'sources/gettext';
|
import gettext from 'sources/gettext';
|
||||||
import { Box } from '@material-ui/core';
|
import { Box } from '@material-ui/core';
|
||||||
|
|||||||
@@ -1,3 +1,12 @@
|
|||||||
|
/////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// pgAdmin 4 - PostgreSQL Tools
|
||||||
|
//
|
||||||
|
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
|
||||||
|
// This software is released under the PostgreSQL Licence
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
import React, { useState, useRef, useEffect } from 'react';
|
import React, { useState, useRef, useEffect } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import gettext from 'sources/gettext';
|
import gettext from 'sources/gettext';
|
||||||
|
|||||||
90
web/pgadmin/browser/static/js/NamedRestoreContent.jsx
Normal file
90
web/pgadmin/browser/static/js/NamedRestoreContent.jsx
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
/////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// pgAdmin 4 - PostgreSQL Tools
|
||||||
|
//
|
||||||
|
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
|
||||||
|
// This software is released under the PostgreSQL Licence
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
import React, { useState, useRef, useEffect } from 'react';
|
||||||
|
import gettext from 'sources/gettext';
|
||||||
|
import { Box } from '@material-ui/core';
|
||||||
|
import { DefaultButton, PrimaryButton } from '../../../static/js/components/Buttons';
|
||||||
|
import CloseIcon from '@material-ui/icons/CloseRounded';
|
||||||
|
import CheckRoundedIcon from '@material-ui/icons/CheckRounded';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { useModalStyles } from '../../../static/js/helpers/ModalProvider';
|
||||||
|
import { InputText } from '../../../static/js/components/FormComponents';
|
||||||
|
import { isEmptyString } from '../../../static/js/validators';
|
||||||
|
|
||||||
|
export default function NamedRestoreContent({closeModal, onOK, setHeight}) {
|
||||||
|
const classes = useModalStyles();
|
||||||
|
const containerRef = useRef();
|
||||||
|
const firstEleRef = useRef();
|
||||||
|
const okBtnRef = useRef();
|
||||||
|
const [formData, setFormData] = useState({
|
||||||
|
namedRestorePoint: ''
|
||||||
|
});
|
||||||
|
|
||||||
|
const onTextChange = (e, id) => {
|
||||||
|
let val = e;
|
||||||
|
if(e && e.target) {
|
||||||
|
val = e.target.value;
|
||||||
|
}
|
||||||
|
setFormData((prev)=>({...prev, [id]: val}));
|
||||||
|
};
|
||||||
|
|
||||||
|
const onKeyDown = (e) => {
|
||||||
|
// If enter key is pressed then click on OK button
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
okBtnRef.current?.click();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
setTimeout(()=>{
|
||||||
|
firstEleRef.current && firstEleRef.current.focus();
|
||||||
|
}, 275);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
setHeight?.(containerRef.current?.offsetHeight);
|
||||||
|
}, [containerRef.current]);
|
||||||
|
|
||||||
|
const isOKDisabled = isEmptyString(formData.namedRestorePoint);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box display="flex" flexDirection="column" className={classes.container} ref={containerRef}>
|
||||||
|
<Box flexGrow="1" p={2}>
|
||||||
|
<Box>
|
||||||
|
<span style={{fontWeight: 'bold'}}>
|
||||||
|
{gettext('Enter the name of the restore point to add')}
|
||||||
|
</span>
|
||||||
|
</Box>
|
||||||
|
<Box marginTop='12px'>
|
||||||
|
<InputText inputRef={firstEleRef} type="text" value={formData['namedRestorePoint']}
|
||||||
|
onChange={(e)=>onTextChange(e, 'namedRestorePoint')} onKeyDown={(e)=>onKeyDown(e)}/>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
<Box className={classes.footer}>
|
||||||
|
<DefaultButton data-test="close" startIcon={<CloseIcon />} onClick={()=>{
|
||||||
|
closeModal();
|
||||||
|
}} >{gettext('Cancel')}</DefaultButton>
|
||||||
|
<PrimaryButton ref={okBtnRef} data-test="save" disabled={isOKDisabled} className={classes.margin} startIcon={<CheckRoundedIcon />} onClick={()=>{
|
||||||
|
let postFormData = new FormData();
|
||||||
|
postFormData.append('value', formData.namedRestorePoint);
|
||||||
|
onOK?.(postFormData);
|
||||||
|
closeModal();
|
||||||
|
}} >{gettext('OK')}</PrimaryButton>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
NamedRestoreContent.propTypes = {
|
||||||
|
closeModal: PropTypes.func,
|
||||||
|
data: PropTypes.object,
|
||||||
|
onOK: PropTypes.func,
|
||||||
|
setHeight: PropTypes.func
|
||||||
|
};
|
||||||
@@ -17,6 +17,8 @@ import gettext from 'sources/gettext';
|
|||||||
|
|
||||||
import getApiInstance from '../../../static/js/api_instance';
|
import getApiInstance from '../../../static/js/api_instance';
|
||||||
import MasterPasswordContent from './MasterPassowrdContent';
|
import MasterPasswordContent from './MasterPassowrdContent';
|
||||||
|
import ChangePasswordContent from './ChangePassowrdContent';
|
||||||
|
import NamedRestoreContent from './NamedRestoreContent';
|
||||||
import Notify from '../../../static/js/helpers/Notifier';
|
import Notify from '../../../static/js/helpers/Notifier';
|
||||||
|
|
||||||
function setNewSize(panel, width, height) {
|
function setNewSize(panel, width, height) {
|
||||||
@@ -154,6 +156,7 @@ export function checkMasterPassword(data, masterpass_callback_queue, cancel_call
|
|||||||
Notify.pgRespErrorNotify(xhr, error);
|
Notify.pgRespErrorNotify(xhr, error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// This functions is used to show the master password dialog.
|
// This functions is used to show the master password dialog.
|
||||||
export function showMasterPassword(isPWDPresent, errmsg=null, masterpass_callback_queue, cancel_callback) {
|
export function showMasterPassword(isPWDPresent, errmsg=null, masterpass_callback_queue, cancel_callback) {
|
||||||
const api = getApiInstance();
|
const api = getApiInstance();
|
||||||
@@ -204,22 +207,98 @@ export function showMasterPassword(isPWDPresent, errmsg=null, masterpass_callbac
|
|||||||
onOK={(formData) => {
|
onOK={(formData) => {
|
||||||
panel.close();
|
panel.close();
|
||||||
checkMasterPassword(formData, masterpass_callback_queue, cancel_callback);
|
checkMasterPassword(formData, masterpass_callback_queue, cancel_callback);
|
||||||
// var _url = url_for('browser.set_master_password');
|
|
||||||
|
|
||||||
// api.post(_url, formData)
|
|
||||||
// .then(res => {
|
|
||||||
// panel.close();
|
|
||||||
// if(res.data.data.is_error) {
|
|
||||||
// showMasterPassword(true, res.data.data.errmsg, masterpass_callback_queue, cancel_callback);
|
|
||||||
// } else {
|
|
||||||
// masterPassCallbacks(masterpass_callback_queue);
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// .catch((err) => {
|
|
||||||
// Notify.error(err.message);
|
|
||||||
// });
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Theme>, j[0]);
|
</Theme>, j[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function showChangeServerPassword() {
|
||||||
|
var pgBrowser = pgAdmin.Browser,
|
||||||
|
title = arguments[0],
|
||||||
|
nodeData = arguments[1],
|
||||||
|
nodeObj = arguments[2],
|
||||||
|
itemNodeData = arguments[3],
|
||||||
|
isPgPassFileUsed = arguments[4];
|
||||||
|
|
||||||
|
// Register dialog panel
|
||||||
|
pgBrowser.Node.registerUtilityPanel();
|
||||||
|
var panel = pgBrowser.Node.addUtilityPanel(pgBrowser.stdW.md),
|
||||||
|
j = panel.$container.find('.obj_properties').first();
|
||||||
|
panel.title(title);
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
<Theme>
|
||||||
|
<ChangePasswordContent
|
||||||
|
onClose={()=>{
|
||||||
|
panel.close();
|
||||||
|
}}
|
||||||
|
onSave={(isNew, data)=>{
|
||||||
|
return new Promise((resolve, reject)=>{
|
||||||
|
const api = getApiInstance();
|
||||||
|
var _url = nodeObj.generate_url(itemNodeData, 'change_password', nodeData, true);
|
||||||
|
|
||||||
|
api.post(_url, data)
|
||||||
|
.then(({data: respData})=>{
|
||||||
|
Notify.success(respData.info);
|
||||||
|
// Notify user to update pgpass file
|
||||||
|
if(isPgPassFileUsed) {
|
||||||
|
Notify.alert(
|
||||||
|
gettext('Change Password'),
|
||||||
|
gettext('Please make sure to disconnect the server'
|
||||||
|
+ ' and update the new password in the pgpass file'
|
||||||
|
+ ' before performing any other operation')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(respData.data);
|
||||||
|
panel.close();
|
||||||
|
})
|
||||||
|
.catch((error)=>{
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
userName={nodeData.user.name}
|
||||||
|
isPgpassFileUsed={isPgPassFileUsed}
|
||||||
|
/>
|
||||||
|
</Theme>, j[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function showNamedRestorePoint() {
|
||||||
|
var pgBrowser = pgAdmin.Browser,
|
||||||
|
title = arguments[0],
|
||||||
|
nodeData = arguments[1],
|
||||||
|
nodeObj = arguments[2],
|
||||||
|
itemNodeData = arguments[3];
|
||||||
|
|
||||||
|
// Register dialog panel
|
||||||
|
pgBrowser.Node.registerUtilityPanel();
|
||||||
|
var panel = pgBrowser.Node.addUtilityPanel(pgBrowser.stdW.md),
|
||||||
|
j = panel.$container.find('.obj_properties').first();
|
||||||
|
panel.title(title);
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
<Theme>
|
||||||
|
<NamedRestoreContent
|
||||||
|
setHeight={(containerHeight)=>{
|
||||||
|
setNewSize(panel, pgBrowser.stdW.md, containerHeight);
|
||||||
|
}}
|
||||||
|
closeModal={()=>{
|
||||||
|
panel.close();
|
||||||
|
}}
|
||||||
|
onOK={(formData)=>{
|
||||||
|
const api = getApiInstance();
|
||||||
|
var _url = nodeObj.generate_url(itemNodeData, 'restore_point', nodeData, true);
|
||||||
|
|
||||||
|
api.post(_url, formData)
|
||||||
|
.then(res=>{
|
||||||
|
panel.close();
|
||||||
|
Notify.success(res.data.data.result);
|
||||||
|
})
|
||||||
|
.catch(function(xhr, status, error) {
|
||||||
|
Notify.pgRespErrorNotify(xhr, error);
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Theme>, j[0]);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user