Refactor dialogs

This commit is contained in:
2021-05-04 01:15:06 -05:00
parent 8ffdd321b3
commit c6fb1d08e7
12 changed files with 371 additions and 397 deletions

View File

@@ -5,7 +5,7 @@ import DropDown from '../../components/UI/DropDown/DropDown';
import PropTypes from 'prop-types';
import Text from '../../components/UI/Text/Text';
import { Component } from 'react';
import { addEditHost, completeAddEditHost } from '../../redux/actions/host_actions';
import { addEditHostAction } from '../../redux/actions/host_actions';
import { connect } from 'react-redux';
import { createDismissDisplay } from '../../utils.jsx';
import { notifyError } from '../../redux/actions/error_actions';
@@ -217,8 +217,8 @@ const mapStateToProps = (state) => {
const mapDispatchToProps = (dispatch) => {
return {
Close: () => dispatch(addEditHost(false)),
completeAddEditHost: (host_data) => dispatch(completeAddEditHost(true, host_data)),
Close: () => dispatch(addEditHostAction.complete(false)),
completeAddEditHost: (host_data) => dispatch(addEditHostAction.complete(true, { host_data })),
notifyError: (msg) => dispatch(notifyError(msg)),
};
};

View File

@@ -1,4 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Component } from 'react';
import './AddMount.css';
import { connect } from 'react-redux';
@@ -11,6 +12,272 @@ import { createModalConditionally } from '../../utils.jsx';
import DropDown from '../../components/UI/DropDown/DropDown';
import * as Constants from '../../constants';
const default_state = {
AccessKey: '',
BucketName: '',
DisplayRemote: false,
DisplayS3: false,
HostNameOrIp: '',
Name: '',
Port: 20000,
Provider: Constants.S3_PROVIDER_LIST[0],
Region: Constants.S3_REGION_PROVIDER_REGION[0],
SecretKey: '',
Token: '',
};
class AddMount extends Component {
state = {
...default_state,
};
addRemoteMount = () => {
if (this.state.HostNameOrIp.length === 0) {
this.props.notifyError('Hostname or IP cannot be empty.');
} else {
const provider = 'Remote' + this.state.HostNameOrIp + ':' + this.state.Port;
if (this.props.RemoteMounts.includes(provider)) {
this.props.notifyError('Remote host already exists');
} else {
this.setState(
{
DisplayRemote: false,
},
() => {
this.props.addRemoteMount(this.state.HostNameOrIp, this.state.Port, this.state.Token);
this.setState({
...default_state,
});
}
);
}
}
};
addS3Mount = () => {
if (this.state.Name.length === 0) {
this.props.notifyError('Name cannot be empty.');
} else if (this.state.AccessKey.length === 0) {
this.props.notifyError('AccessKey cannot be empty.');
} else if (this.state.SecretKey.length === 0) {
this.props.notifyError('SecretKey cannot be empty.');
} else {
const provider = 'S3' + this.state.Name;
if (this.props.S3Mounts.includes(provider)) {
this.props.notifyError('Remote host already exists');
} else {
this.setState(
{
DisplayS3: false,
},
() => {
this.props.addS3Mount(
this.state.Name,
this.state.AccessKey,
this.state.SecretKey,
this.state.Region,
this.state.BucketName,
Constants.S3_PROVIDER_URL[this.state.Provider]
);
this.setState({
...default_state,
});
}
);
}
}
};
handleAddS3Mount = () => {
this.setState({
DisplayRemote: false,
DisplayS3: true,
});
};
handleAddRemoteMount = () => {
this.setState({
DisplayRemote: true,
DisplayS3: false,
});
};
render() {
const displayAddRemote = createModalConditionally(
this.state.DisplayRemote,
<Box
dxDark
dxStyle={{
width: 'auto',
height: 'auto',
padding: 'var(--default_spacing)',
}}>
<h1
style={{
textAlign: 'center',
paddingBottom: 'var(--default_spacing)',
}}>
Add Remote Mount
</h1>
<Text text={'Hostname or IP'} textAlign={'left'} type={'Heading2'} />
<input
onChange={(e) => this.setState({ HostNameOrIp: e.target.value.trim() })}
className={'ConfigurationItemInput'}
type={'text'}
value={this.state.HostNameOrIp}
/>
<div style={{ paddingTop: 'var(--default_spacing)' }} />
<Text text={'Port'} textAlign={'left'} type={'Heading2'} />
<input
max={65535}
min={1025}
onChange={(e) => this.setState({ Port: e.target.value })}
className={'ConfigurationItemInput'}
type={'number'}
value={this.state.Port}
/>
<div style={{ paddingTop: 'var(--default_spacing)' }} />
<Text text={'Remote Token'} textAlign={'left'} type={'Heading2'} />
<input
onChange={(e) => this.setState({ Token: e.target.value })}
className={'ConfigurationItemInput'}
type={'text'}
value={this.state.Token}
/>
<div style={{ paddingTop: 'var(--default_spacing)' }} />
<div style={{ display: 'flex', flexDirection: 'row' }}>
<Button buttonStyles={{ width: '100%' }} clicked={() => this.addRemoteMount()}>
OK
</Button>
<div style={{ paddingLeft: 'var(--default_spacing)' }} />
<Button
buttonStyles={{ width: '100%' }}
clicked={() => this.setState({ DisplayRemote: false })}>
Cancel
</Button>
</div>
</Box>
);
const displayAddS3 = createModalConditionally(
this.state.DisplayS3,
<Box
dxDark
dxStyle={{
width: 'auto',
height: 'auto',
padding: 'var(--default_spacing)',
}}>
<h1
style={{
textAlign: 'center',
paddingBottom: 'var(--default_spacing)',
}}>
Add S3 Mount
</h1>
<div style={{ display: 'flex', flexDirection: 'row' }}>
<Text text={'Name'} textAlign={'left'} type={'Heading2'} />
<div style={{ paddingLeft: 'var(--default_spacing)' }} />
<Text text={'Provider'} textAlign={'left'} type={'Heading2'} />
</div>
<div style={{ display: 'flex', flexDirection: 'row' }}>
<input
onChange={(e) => this.setState({ Name: e.target.value.trim() })}
className={'ConfigurationItemInput'}
style={{ width: '100%' }}
type={'text'}
value={this.state.Name}
/>
<div style={{ paddingLeft: 'var(--default_spacing)' }} />
<DropDown
changed={(e) => this.setState({ Provider: e.target.value })}
items={Constants.S3_PROVIDER_LIST}
selected={this.state.Provider}
/>
</div>
<div style={{ paddingTop: 'var(--default_spacing)' }} />
<div style={{ display: 'flex', flexDirection: 'row' }}>
<Text text={'Bucket Name (optional)'} textAlign={'left'} type={'Heading2'} />
<div style={{ paddingLeft: 'var(--default_spacing)' }} />
<Text text={'Region'} textAlign={'left'} type={'Heading2'} />
</div>
<div style={{ display: 'flex', flexDirection: 'row' }}>
<input
onChange={(e) => this.setState({ BucketName: e.target.value })}
className={'ConfigurationItemInput'}
style={{ width: '100%' }}
type={'text'}
value={this.state.BucketName}
/>
<div style={{ paddingLeft: 'var(--default_spacing)' }} />
<input
onChange={(e) => this.setState({ Region: e.target.value })}
className={'ConfigurationItemInput'}
type={'text'}
value={this.state.Region}
/>
</div>
<div style={{ paddingTop: 'var(--default_spacing)' }} />
<div style={{ display: 'flex', flexDirection: 'row' }}>
<Text text={'Access Key'} textAlign={'left'} type={'Heading2'} />
<div style={{ paddingLeft: 'var(--default_spacing)' }} />
<Text text={'Secret Key'} textAlign={'left'} type={'Heading2'} />
</div>
<div style={{ display: 'flex', flexDirection: 'row' }}>
<input
onChange={(e) => this.setState({ AccessKey: e.target.value })}
className={'ConfigurationItemInput'}
type={'text'}
value={this.state.AccessKey}
/>
<div style={{ paddingLeft: 'var(--default_spacing)' }} />
<input
onChange={(e) => this.setState({ SecretKey: e.target.value })}
className={'ConfigurationItemInput'}
type={'text'}
value={this.state.SecretKey}
/>
</div>
<div style={{ paddingTop: 'calc(var(--default_spacing) * 2)' }} />
<div style={{ display: 'flex', flexDirection: 'row' }}>
<div style={{ width: '200%' }} />
<Button buttonStyles={{ width: '100%' }} clicked={() => this.addS3Mount()}>
OK
</Button>
<div style={{ paddingLeft: 'var(--default_spacing)' }} />
<Button
buttonStyles={{ width: '100%' }}
clicked={() => this.setState({ DisplayS3: false })}>
Cancel
</Button>
</div>
</Box>
);
return (
<div className={'AddMount'}>
{displayAddRemote}
{displayAddS3}
<div className={'AddMountButtons'}>
{this.props.remoteSupported ? (
<Button className={'AddMountButton'} clicked={this.handleAddRemoteMount}>
Add Remote Mount
</Button>
) : null}
{this.props.remoteSupported && this.props.s3Supported ? (
<div style={{ paddingRight: 'var(--default_spacing)' }} />
) : null}
{this.props.s3Supported ? (
<Button className={'AddMountButton'} clicked={this.handleAddS3Mount}>
Add S3 Mount
</Button>
) : null}
</div>
</div>
);
}
}
const mapStateToProps = (state) => {
return {
RemoteMounts: state.mounts.RemoteMounts,
@@ -28,273 +295,14 @@ const mapDispatchToProps = (dispatch) => {
};
};
const default_state = {
AccessKey: '',
BucketName: '',
DisplayRemote: false,
DisplayS3: false,
HostNameOrIp: '',
Name: '',
Port: 2000,
Provider: Constants.S3_PROVIDER_LIST[0],
Region: Constants.S3_REGION_PROVIDER_REGION[0],
SecretKey: '',
Token: '',
AddMount.propTypes = {
RemoteMounts: PropTypes.array.isRequired,
S3Mounts: PropTypes.array.isRequired,
addRemoteMount: PropTypes.func.isRequired,
addS3Mount: PropTypes.func.isRequired,
notifyError: PropTypes.func.isRequired,
remoteSupported: PropTypes.bool,
s3Supported: PropTypes.bool,
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(
class AddMount extends Component {
state = {
...default_state,
};
addRemoteMount = () => {
if (this.state.HostNameOrIp.length === 0) {
this.props.notifyError('Hostname or IP cannot be empty.');
} else {
const provider = 'Remote' + this.state.HostNameOrIp + ':' + this.state.Port;
if (this.props.RemoteMounts.includes(provider)) {
this.props.notifyError('Remote host already exists');
} else {
this.setState(
{
DisplayRemote: false,
},
() => {
this.props.addRemoteMount(this.state.HostNameOrIp, this.state.Port, this.state.Token);
this.setState({
...default_state,
});
}
);
}
}
};
addS3Mount = () => {
if (this.state.Name.length === 0) {
this.props.notifyError('Name cannot be empty.');
} else if (this.state.AccessKey.length === 0) {
this.props.notifyError('AccessKey cannot be empty.');
} else if (this.state.SecretKey.length === 0) {
this.props.notifyError('SecretKey cannot be empty.');
} else {
const provider = 'S3' + this.state.Name;
if (this.props.S3Mounts.includes(provider)) {
this.props.notifyError('Remote host already exists');
} else {
this.setState(
{
DisplayS3: false,
},
() => {
this.props.addS3Mount(
this.state.Name,
this.state.AccessKey,
this.state.SecretKey,
this.state.Region,
this.state.BucketName,
Constants.S3_PROVIDER_URL[this.state.Provider]
);
this.setState({
...default_state,
});
}
);
}
}
};
handleAddS3Mount = () => {
this.setState({
DisplayRemote: false,
DisplayS3: true,
});
};
handleAddRemoteMount = () => {
this.setState({
DisplayRemote: true,
DisplayS3: false,
});
};
render() {
const displayAddRemote = createModalConditionally(
this.state.DisplayRemote,
<Box
dxDark
dxStyle={{
width: 'auto',
height: 'auto',
padding: 'var(--default_spacing)',
}}>
<h1
style={{
textAlign: 'center',
paddingBottom: 'var(--default_spacing)',
}}>
Add Remote Mount
</h1>
<Text text={'Hostname or IP'} textAlign={'left'} type={'Heading2'} />
<input
onChange={(e) => this.setState({ HostNameOrIp: e.target.value.trim() })}
className={'ConfigurationItemInput'}
type={'text'}
value={this.state.HostNameOrIp}
/>
<div style={{ paddingTop: 'var(--default_spacing)' }} />
<Text text={'Port'} textAlign={'left'} type={'Heading2'} />
<input
max={65535}
min={1025}
onChange={(e) => this.setState({ Port: e.target.value })}
className={'ConfigurationItemInput'}
type={'number'}
value={this.state.Port}
/>
<div style={{ paddingTop: 'var(--default_spacing)' }} />
<Text text={'Remote Token'} textAlign={'left'} type={'Heading2'} />
<input
onChange={(e) => this.setState({ Token: e.target.value })}
className={'ConfigurationItemInput'}
type={'text'}
value={this.state.Token}
/>
<div style={{ paddingTop: 'var(--default_spacing)' }} />
<div style={{ display: 'flex', flexDirection: 'row' }}>
<Button buttonStyles={{ width: '100%' }} clicked={() => this.addRemoteMount()}>
OK
</Button>
<div style={{ paddingLeft: 'var(--default_spacing)' }} />
<Button
buttonStyles={{ width: '100%' }}
clicked={() => this.setState({ DisplayRemote: false })}>
Cancel
</Button>
</div>
</Box>
);
const displayAddS3 = createModalConditionally(
this.state.DisplayS3,
<Box
dxDark
dxStyle={{
width: 'auto',
height: 'auto',
padding: 'var(--default_spacing)',
}}>
<h1
style={{
textAlign: 'center',
paddingBottom: 'var(--default_spacing)',
}}>
Add S3 Mount
</h1>
<div style={{ display: 'flex', flexDirection: 'row' }}>
<Text text={'Name'} textAlign={'left'} type={'Heading2'} />
<div style={{ paddingLeft: 'var(--default_spacing)' }} />
<Text text={'Provider'} textAlign={'left'} type={'Heading2'} />
</div>
<div style={{ display: 'flex', flexDirection: 'row' }}>
<input
onChange={(e) => this.setState({ Name: e.target.value.trim() })}
className={'ConfigurationItemInput'}
style={{ width: '100%' }}
type={'text'}
value={this.state.Name}
/>
<div style={{ paddingLeft: 'var(--default_spacing)' }} />
<DropDown
changed={(e) => this.setState({ Provider: e.target.value })}
items={Constants.S3_PROVIDER_LIST}
selected={this.state.Provider}
/>
</div>
<div style={{ paddingTop: 'var(--default_spacing)' }} />
<div style={{ display: 'flex', flexDirection: 'row' }}>
<Text text={'Bucket Name (optional)'} textAlign={'left'} type={'Heading2'} />
<div style={{ paddingLeft: 'var(--default_spacing)' }} />
<Text text={'Region'} textAlign={'left'} type={'Heading2'} />
</div>
<div style={{ display: 'flex', flexDirection: 'row' }}>
<input
onChange={(e) => this.setState({ BucketName: e.target.value })}
className={'ConfigurationItemInput'}
style={{ width: '100%' }}
type={'text'}
value={this.state.BucketName}
/>
<div style={{ paddingLeft: 'var(--default_spacing)' }} />
<input
onChange={(e) => this.setState({ Region: e.target.value })}
className={'ConfigurationItemInput'}
type={'text'}
value={this.state.Region}
/>
</div>
<div style={{ paddingTop: 'var(--default_spacing)' }} />
<div style={{ display: 'flex', flexDirection: 'row' }}>
<Text text={'Access Key'} textAlign={'left'} type={'Heading2'} />
<div style={{ paddingLeft: 'var(--default_spacing)' }} />
<Text text={'Secret Key'} textAlign={'left'} type={'Heading2'} />
</div>
<div style={{ display: 'flex', flexDirection: 'row' }}>
<input
onChange={(e) => this.setState({ AccessKey: e.target.value })}
className={'ConfigurationItemInput'}
type={'text'}
value={this.state.AccessKey}
/>
<div style={{ paddingLeft: 'var(--default_spacing)' }} />
<input
onChange={(e) => this.setState({ SecretKey: e.target.value })}
className={'ConfigurationItemInput'}
type={'text'}
value={this.state.SecretKey}
/>
</div>
<div style={{ paddingTop: 'calc(var(--default_spacing) * 2)' }} />
<div style={{ display: 'flex', flexDirection: 'row' }}>
<div style={{ width: '200%' }} />
<Button buttonStyles={{ width: '100%' }} clicked={() => this.addS3Mount()}>
OK
</Button>
<div style={{ paddingLeft: 'var(--default_spacing)' }} />
<Button
buttonStyles={{ width: '100%' }}
clicked={() => this.setState({ DisplayS3: false })}>
Cancel
</Button>
</div>
</Box>
);
return (
<div className={'AddMount'}>
{displayAddRemote}
{displayAddS3}
<div className={'AddMountButtons'}>
{this.props.remoteSupported ? (
<Button className={'AddMountButton'} clicked={this.handleAddRemoteMount}>
Add Remote Mount
</Button>
) : null}
{this.props.remoteSupported && this.props.s3Supported ? (
<div style={{ paddingRight: 'var(--default_spacing)' }} />
) : null}
{this.props.s3Supported ? (
<Button className={'AddMountButton'} clicked={this.handleAddS3Mount}>
Add S3 Mount
</Button>
) : null}
</div>
</div>
);
}
}
);
export default connect(mapStateToProps, mapDispatchToProps)(AddMount);

View File

@@ -1,24 +1,20 @@
import React from 'react';
import PropTypes from 'prop-types';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { addEditHost } from '../../../redux/actions/host_actions';
import { addEditHostAction } from '../../../redux/actions/host_actions';
import { connect } from 'react-redux';
import { faTrashAlt, faEdit } from '@fortawesome/free-solid-svg-icons';
// const mapStateToProps = (state) => {
// return {};
// };
//
const mapDispatchToProps = (dispatch) => {
return {
addEditHost: (host_list, host_data, cb) =>
dispatch(addEditHost(true, host_list, host_data, cb)),
editHost: (host_list, host_data, cb) =>
dispatch(addEditHostAction.display(true, cb, { host_list, host_data })),
};
};
const Host = ({ allowDelete, addEditHost, host_list, host_data, onChange, onDelete }) => {
const Host = ({ allowDelete, editHost, host_list, host_data, onChange, onDelete }) => {
const handleEditHost = () => {
addEditHost(host_list, host_data, (changed, host_data) => {
editHost(host_list, host_data, (changed, { host_data }) => {
if (changed) {
onChange(host_data);
}
@@ -74,7 +70,7 @@ const Host = ({ allowDelete, addEditHost, host_list, host_data, onChange, onDele
Host.propTypes = {
allowDelete: PropTypes.bool.isRequired,
addEditHost: PropTypes.func.isRequired,
editHost: PropTypes.func.isRequired,
onChange: PropTypes.func.isRequired,
onDelete: PropTypes.func.isRequired,
host_data: PropTypes.object.isRequired,

View File

@@ -4,9 +4,9 @@ import Host from './Host/Host';
import PropTypes from 'prop-types';
import { Component } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { confirmYesNo } from '../../redux/actions/common_actions';
import { confirmYesNoAction } from '../../redux/actions/common_actions';
import { connect } from 'react-redux';
import { addEditHost } from '../../redux/actions/host_actions';
import { addEditHostAction } from '../../redux/actions/host_actions';
import { faPlusCircle } from '@fortawesome/free-solid-svg-icons';
class HostList extends Component {
@@ -24,7 +24,7 @@ class HostList extends Component {
componentWillUnmount() {}
handleAddHost = () => {
this.props.addEditHost(this.state.items, (changed, host_data) => {
this.props.AddHost(this.state.items, (changed, host_data) => {
if (changed) {
const items = [...this.state.items, host_data];
this.updateItems(items);
@@ -104,13 +104,13 @@ class HostList extends Component {
const mapDispatchToProps = (dispatch) => {
return {
addEditHost: (list, cb) => dispatch(addEditHost(true, list, null, cb)),
ConfirmRemoveHost: (title, cb) => dispatch(confirmYesNo(title, cb)),
AddHost: (host_list, cb) => dispatch(addEditHostAction.display(true, cb, { host_list })),
ConfirmRemoveHost: (title, cb) => dispatch(confirmYesNoAction.display(true, cb, { title })),
};
};
HostList.propTypes = {
addEditHost: PropTypes.func.isRequired,
AddHost: PropTypes.func.isRequired,
ConfirmRemoveHost: PropTypes.func.isRequired,
onChange: PropTypes.func.isRequired,
value: PropTypes.array.isRequired,