Port connect server password dialog to React. Fixes #7337

This commit is contained in:
Akshay Joshi
2022-05-16 16:21:14 +05:30
parent 7686c33cbd
commit 44f9ba4a57
14 changed files with 205 additions and 218 deletions

View File

@@ -1,4 +1,4 @@
import React, { useState } from 'react';
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';
@@ -8,8 +8,10 @@ import PropTypes from 'prop-types';
import { useModalStyles } from '../../../static/js/helpers/ModalProvider';
import { FormFooterMessage, InputCheckbox, InputText, MESSAGE_TYPE } from '../../../static/js/components/FormComponents';
export default function ConnectServerContent({closeModal, data, onOK}) {
export default function ConnectServerContent({closeModal, data, onOK, setHeight}) {
const classes = useModalStyles();
const containerRef = useRef();
const firstEleRef = useRef();
const [formData, setFormData] = useState({
tunnel_password: '',
save_tunnel_password: false,
@@ -25,12 +27,22 @@ export default function ConnectServerContent({closeModal, data, onOK}) {
setFormData((prev)=>({...prev, [id]: val}));
};
useEffect(()=>{
setTimeout(()=>{
firstEleRef.current && firstEleRef.current.focus();
}, 275);
}, []);
useEffect(()=>{
setHeight?.(containerRef.current?.offsetHeight);
}, [containerRef.current]);
if(!data) {
return <>No data</>;
}
return (
<Box display="flex" flexDirection="column" height="100%">
<Box display="flex" flexDirection="column" className={classes.container} ref={containerRef}>
<Box flexGrow="1" p={2}>
{data.prompt_tunnel_password && <>
<Box>
@@ -42,10 +54,10 @@ export default function ConnectServerContent({closeModal, data, onOK}) {
</span>
</Box>
<Box marginTop='12px'>
<InputText type="password" value={formData['tunnel_password']} maxLength={null}
onChange={(e)=>onTextChange(e, 'tunnel_password')} autoFocus />
<InputText inputRef={firstEleRef} type="password" value={formData['tunnel_password']} maxLength={null}
onChange={(e)=>onTextChange(e, 'tunnel_password')} />
</Box>
<Box marginTop='12px'>
<Box marginTop='12px' marginBottom='12px'>
<InputCheckbox controlProps={{label: gettext('Save Password')}} value={formData['save_tunnel_password']}
onChange={(e)=>onTextChange(e.target.checked, 'save_tunnel_password')} disabled={!data.allow_save_tunnel_password} />
</Box>
@@ -60,8 +72,13 @@ export default function ConnectServerContent({closeModal, data, onOK}) {
</span>
</Box>
<Box marginTop='12px'>
<InputText type="password" value={formData['password']} maxLength={null}
onChange={(e)=>onTextChange(e, 'password')} autoFocus />
<InputText inputRef={(ele)=>{
if(!data.prompt_tunnel_password) {
/* Set only if no tunnel password asked */
firstEleRef.current = ele;
}
}} type="password" value={formData['password']} maxLength={null}
onChange={(e)=>onTextChange(e, 'password')} />
</Box>
<Box marginTop='12px'>
<InputCheckbox controlProps={{label: gettext('Save Password')}} value={formData['save_password']}
@@ -99,5 +116,6 @@ export default function ConnectServerContent({closeModal, data, onOK}) {
ConnectServerContent.propTypes = {
closeModal: PropTypes.func,
data: PropTypes.object,
onOK: PropTypes.func
onOK: PropTypes.func,
setHeight: PropTypes.func
};

View File

@@ -498,9 +498,10 @@ define('pgadmin.browser.node', [
return null;
},
addUtilityPanel: function(width, height) {
addUtilityPanel: function(width, height, docker) {
var body = window.document.body,
el = document.createElement('div');
el = document.createElement('div'),
dockerObject = docker || pgBrowser.docker;
body.insertBefore(el, body.firstChild);
@@ -513,7 +514,7 @@ define('pgadmin.browser.node', [
new_height = height;
}
var new_panel = pgBrowser.docker.addPanel(
var new_panel = dockerObject.addPanel(
'utility_props', window.wcDocker.DOCK.FLOAT, undefined, {
w: new_width,
h: new_height,
@@ -548,8 +549,8 @@ define('pgadmin.browser.node', [
}
},
registerUtilityPanel: function() {
var w = pgBrowser.docker,
registerUtilityPanel: function(docker) {
var w = docker || pgBrowser.docker,
p = w.findPanels('utility_props');
if (p && p.length == 1)
@@ -572,7 +573,7 @@ define('pgadmin.browser.node', [
},
events: events,
});
p.load(pgBrowser.docker);
p.load(w);
},
register_node_panel: function() {
var w = pgBrowser.docker,

View File

@@ -0,0 +1,132 @@
/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
import React from 'react';
import ReactDOM from 'react-dom';
import pgAdmin from 'sources/pgadmin';
import ConnectServerContent from './ConnectServerContent';
import Theme from 'sources/Theme';
import url_for from 'sources/url_for';
import getApiInstance from '../../../static/js/api_instance';
function setNewSize(panel, width, height) {
// Add height of the header
let newHeight = height + 31;
// Set min and max size of the panel
panel.minSize(width, newHeight);
panel.maxSize(width, newHeight);
panel.maximisable(false);
/* No other way to update size, below is the only way */
panel._parent._size.x = width;
panel._parent._size.y = newHeight;
panel._parent.__update();
}
// This functions is used to show the connect server password dialog.
export function showServerPassword() {
var pgBrowser = pgAdmin.Browser,
title = arguments[0],
formJson = arguments[1],
nodeObj = arguments[2],
nodeData = arguments[3],
treeNodeInfo = arguments[4],
itemNodeData = arguments[5],
status = arguments[6],
onSuccess = arguments[7],
onFailure = arguments[8];
// 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>
<ConnectServerContent
setHeight={(containerHeight)=>{
setNewSize(panel, pgBrowser.stdW.md, containerHeight);
}}
closeModal={()=>{
panel.close();
}}
data={formJson}
onOK={(formData)=>{
const api = getApiInstance();
var _url = nodeObj.generate_url(itemNodeData, 'connect', nodeData, true);
if (!status) {
treeNodeInfo.setLeaf(itemNodeData);
treeNodeInfo.removeIcon(itemNodeData);
treeNodeInfo.addIcon(itemNodeData, {icon: 'icon-server-connecting'});
}
api.post(_url, formData)
.then(res=>{
panel.close();
return onSuccess(
res.data, nodeObj, nodeData, treeNodeInfo, itemNodeData, status
);
})
.catch((err)=>{
return onFailure(
err.response.request, status, err, nodeObj, nodeData, treeNodeInfo,
itemNodeData, status
);
});
}}
/>
</Theme>, j[0]);
}
// This functions is used to show the connect server password dialog when
// launch from Schema Diff tool.
export function showSchemaDiffServerPassword() {
var pgBrowser = pgAdmin.Browser,
docker = arguments[0],
title = arguments[1],
formJson = arguments[2],
serverID = arguments[3],
successCallback = arguments[4],
onSuccess = arguments[5],
onFailure = arguments[6];
// Register dialog panel
pgBrowser.Node.registerUtilityPanel(docker);
var panel = pgBrowser.Node.addUtilityPanel(pgBrowser.stdW.md, undefined, docker),
j = panel.$container.find('.obj_properties').first();
panel.title(title);
ReactDOM.render(
<Theme>
<ConnectServerContent
setHeight={(containerHeight)=>{
setNewSize(panel, pgBrowser.stdW.md, containerHeight);
}}
closeModal={()=>{
panel.close();
}}
data={formJson}
onOK={(formData)=>{
const api = getApiInstance();
var _url = url_for('schema_diff.connect_server', {'sid': serverID});
api.post(_url, formData)
.then(res=>{
panel.close();
return onSuccess(res.data, successCallback);
})
.catch((err)=>{
return onFailure(
err.response.request, status, err, serverID, successCallback
);
});
}}
/>
</Theme>, j[0]);
}