UI for DHCP interfaces
This commit is contained in:
parent
1270bbad1a
commit
712493aafd
@ -149,5 +149,8 @@
|
||||
"dhcp_form_range_start": "Range start",
|
||||
"dhcp_form_range_end": "Range end",
|
||||
"dhcp_form_lease_title": "DHCP lease time (in seconds)",
|
||||
"dhcp_form_lease_input": "Lease duration"
|
||||
"dhcp_form_lease_input": "Lease duration",
|
||||
"dhcp_interface_select": "Select DHCP interface",
|
||||
"dhcp_hardware_address": "Hardware address",
|
||||
"dhcp_ip_addresses": "IP addresses"
|
||||
}
|
||||
|
@ -538,6 +538,21 @@ export const getDhcpStatus = () => async (dispatch) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const getDhcpInterfacesRequest = createAction('GET_DHCP_INTERFACES_REQUEST');
|
||||
export const getDhcpInterfacesSuccess = createAction('GET_DHCP_INTERFACES_SUCCESS');
|
||||
export const getDhcpInterfacesFailure = createAction('GET_DHCP_INTERFACES_FAILURE');
|
||||
|
||||
export const getDhcpInterfaces = () => async (dispatch) => {
|
||||
dispatch(getDhcpInterfacesRequest());
|
||||
try {
|
||||
const interfaces = await apiClient.getDhcpInterfaces();
|
||||
dispatch(getDhcpInterfacesSuccess(interfaces));
|
||||
} catch (error) {
|
||||
dispatch(addErrorToast({ error }));
|
||||
dispatch(getDhcpInterfacesFailure());
|
||||
}
|
||||
};
|
||||
|
||||
export const setDhcpConfigRequest = createAction('SET_DHCP_CONFIG_REQUEST');
|
||||
export const setDhcpConfigSuccess = createAction('SET_DHCP_CONFIG_SUCCESS');
|
||||
export const setDhcpConfigFailure = createAction('SET_DHCP_CONFIG_FAILURE');
|
||||
|
@ -307,12 +307,18 @@ export default class Api {
|
||||
DHCP_STATUS = { path: 'dhcp/status', method: 'GET' };
|
||||
DHCP_SET_CONFIG = { path: 'dhcp/set_config', method: 'POST' };
|
||||
DHCP_FIND_ACTIVE = { path: 'dhcp/find_active_dhcp', method: 'POST' };
|
||||
DHCP_INTERFACES = { path: 'dhcp/interfaces', method: 'GET' };
|
||||
|
||||
getDhcpStatus() {
|
||||
const { path, method } = this.DHCP_STATUS;
|
||||
return this.makeRequest(path, method);
|
||||
}
|
||||
|
||||
getDhcpInterfaces() {
|
||||
const { path, method } = this.DHCP_INTERFACES;
|
||||
return this.makeRequest(path, method);
|
||||
}
|
||||
|
||||
setDhcpConfig(config) {
|
||||
const { path, method } = this.DHCP_SET_CONFIG;
|
||||
const parameters = {
|
||||
|
@ -1,6 +1,7 @@
|
||||
import React, { Fragment } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Field, reduxForm } from 'redux-form';
|
||||
import { Field, reduxForm, formValueSelector } from 'redux-form';
|
||||
import { withNamespaces, Trans } from 'react-i18next';
|
||||
import flow from 'lodash/flow';
|
||||
|
||||
@ -44,14 +45,82 @@ const renderField = ({
|
||||
</Fragment>
|
||||
);
|
||||
|
||||
const Form = (props) => {
|
||||
const renderInterfaces = (interfaces => (
|
||||
Object.keys(interfaces).map((item) => {
|
||||
const option = interfaces[item];
|
||||
const { name } = option;
|
||||
let interfaceIP = option.ip_addresses[0];
|
||||
|
||||
option.ip_addresses.forEach((ip) => {
|
||||
if (!ip.includes(':')) {
|
||||
interfaceIP = ip;
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<option value={name} key={name}>
|
||||
{name} - {interfaceIP}
|
||||
</option>
|
||||
);
|
||||
})
|
||||
));
|
||||
|
||||
const renderInterfaceValues = (interfaceValues => (
|
||||
<ul className="list-unstyled mt-1 mb-0">
|
||||
<li>
|
||||
<span className="interface__title">MTU: </span>
|
||||
{interfaceValues.mtu}
|
||||
</li>
|
||||
<li>
|
||||
<span className="interface__title"><Trans>dhcp_hardware_address</Trans>: </span>
|
||||
{interfaceValues.hardware_address}
|
||||
</li>
|
||||
<li>
|
||||
<span className="interface__title"><Trans>dhcp_ip_addresses</Trans>: </span>
|
||||
{
|
||||
interfaceValues.ip_addresses
|
||||
.map(ip => <span key={ip} className="interface__ip">{ip}</span>)
|
||||
}
|
||||
</li>
|
||||
</ul>
|
||||
));
|
||||
|
||||
let Form = (props) => {
|
||||
const {
|
||||
handleSubmit, pristine, submitting, enabled, t,
|
||||
t,
|
||||
handleSubmit,
|
||||
pristine,
|
||||
submitting,
|
||||
enabled,
|
||||
interfaces,
|
||||
processing,
|
||||
interfaceValue,
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit}>
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
{!processing && interfaces &&
|
||||
<div className="row">
|
||||
<div className="col-sm-12 col-md-6">
|
||||
<div className="form__group form__group--dhcp">
|
||||
<label>{t('dhcp_interface_select')}</label>
|
||||
<Field name="interface_name" component="select" className="form-control custom-select">
|
||||
<option value="">{t('dhcp_interface_select')}</option>
|
||||
{renderInterfaces(interfaces)}
|
||||
</Field>
|
||||
</div>
|
||||
</div>
|
||||
{interfaceValue &&
|
||||
<div className="col-sm-12 col-md-6">
|
||||
{renderInterfaceValues(interfaces[interfaceValue])}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
<hr/>
|
||||
</div>
|
||||
<div className="col-lg-6">
|
||||
<div className="form__group form__group--dhcp">
|
||||
<label>{t('dhcp_form_gateway_input')}</label>
|
||||
@ -140,9 +209,21 @@ Form.propTypes = {
|
||||
pristine: PropTypes.bool,
|
||||
submitting: PropTypes.bool,
|
||||
enabled: PropTypes.bool,
|
||||
interfaces: PropTypes.object,
|
||||
processing: PropTypes.bool,
|
||||
interfaceValue: PropTypes.string,
|
||||
t: PropTypes.func,
|
||||
};
|
||||
|
||||
const selector = formValueSelector('dhcpForm');
|
||||
|
||||
Form = connect((state) => {
|
||||
const interfaceValue = selector(state, 'interface_name');
|
||||
return {
|
||||
interfaceValue,
|
||||
};
|
||||
})(Form);
|
||||
|
||||
export default flow([
|
||||
withNamespaces(),
|
||||
reduxForm({ form: 'dhcpForm' }),
|
||||
|
@ -61,6 +61,8 @@ class Dhcp extends Component {
|
||||
onSubmit={this.handleFormSubmit}
|
||||
initialValues={dhcp.config}
|
||||
enabled={dhcp.config.enabled}
|
||||
interfaces={dhcp.interfaces}
|
||||
processing={dhcp.processingInterfaces}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -31,3 +31,16 @@
|
||||
.form__message--error {
|
||||
color: #cd201f;
|
||||
}
|
||||
|
||||
.interface__title {
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.interface__ip:after {
|
||||
content: ", ";
|
||||
}
|
||||
|
||||
.interface__ip:last-child:after {
|
||||
content: "";
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ class Settings extends Component {
|
||||
componentDidMount() {
|
||||
this.props.initSettings(this.settings);
|
||||
this.props.getDhcpStatus();
|
||||
this.props.getDhcpInterfaces();
|
||||
}
|
||||
|
||||
handleUpstreamChange = (value) => {
|
||||
|
@ -8,6 +8,7 @@ import {
|
||||
addErrorToast,
|
||||
toggleDhcp,
|
||||
getDhcpStatus,
|
||||
getDhcpInterfaces,
|
||||
setDhcpConfig,
|
||||
findActiveDhcp,
|
||||
} from '../actions';
|
||||
@ -28,6 +29,7 @@ const mapDispatchToProps = {
|
||||
addErrorToast,
|
||||
toggleDhcp,
|
||||
getDhcpStatus,
|
||||
getDhcpInterfaces,
|
||||
setDhcpConfig,
|
||||
findActiveDhcp,
|
||||
};
|
||||
|
@ -272,6 +272,17 @@ const dhcp = handleActions({
|
||||
return newState;
|
||||
},
|
||||
|
||||
[actions.getDhcpInterfacesRequest]: state => ({ ...state, processingInterfaces: true }),
|
||||
[actions.getDhcpInterfacesFailure]: state => ({ ...state, processingInterfaces: false }),
|
||||
[actions.getDhcpInterfacesSuccess]: (state, { payload }) => {
|
||||
const newState = {
|
||||
...state,
|
||||
interfaces: payload,
|
||||
processingInterfaces: false,
|
||||
};
|
||||
return newState;
|
||||
},
|
||||
|
||||
[actions.findActiveDhcpRequest]: state => ({ ...state, processingStatus: true }),
|
||||
[actions.findActiveDhcpFailure]: state => ({ ...state, processingStatus: false }),
|
||||
[actions.findActiveDhcpSuccess]: (state, { payload }) => ({
|
||||
@ -289,6 +300,7 @@ const dhcp = handleActions({
|
||||
}, {
|
||||
processing: true,
|
||||
processingStatus: false,
|
||||
processingInterfaces: false,
|
||||
config: {
|
||||
enabled: false,
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user