From 712493aafd74d5c4a1e0ed32da6fb2bdbfffbc7f Mon Sep 17 00:00:00 2001 From: Ildar Kamalov Date: Mon, 24 Dec 2018 11:48:23 +0300 Subject: [PATCH] UI for DHCP interfaces --- client/src/__locales/en.json | 5 +- client/src/actions/index.js | 15 ++++ client/src/api/Api.js | 6 ++ client/src/components/Settings/Dhcp/Form.js | 87 +++++++++++++++++++- client/src/components/Settings/Dhcp/index.js | 2 + client/src/components/Settings/Settings.css | 13 +++ client/src/components/Settings/index.js | 1 + client/src/containers/Settings.js | 2 + client/src/reducers/index.js | 12 +++ 9 files changed, 139 insertions(+), 4 deletions(-) diff --git a/client/src/__locales/en.json b/client/src/__locales/en.json index 0ffe12f7..463ccc1a 100644 --- a/client/src/__locales/en.json +++ b/client/src/__locales/en.json @@ -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" } diff --git a/client/src/actions/index.js b/client/src/actions/index.js index 7e07c6a0..bb9d9bbb 100644 --- a/client/src/actions/index.js +++ b/client/src/actions/index.js @@ -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'); diff --git a/client/src/api/Api.js b/client/src/api/Api.js index 4aac23f5..2bb0277a 100644 --- a/client/src/api/Api.js +++ b/client/src/api/Api.js @@ -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 = { diff --git a/client/src/components/Settings/Dhcp/Form.js b/client/src/components/Settings/Dhcp/Form.js index da761892..93140580 100644 --- a/client/src/components/Settings/Dhcp/Form.js +++ b/client/src/components/Settings/Dhcp/Form.js @@ -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 = ({ ); -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 ( + + ); + }) +)); + +const renderInterfaceValues = (interfaceValues => ( + +)); + +let Form = (props) => { const { - handleSubmit, pristine, submitting, enabled, t, + t, + handleSubmit, + pristine, + submitting, + enabled, + interfaces, + processing, + interfaceValue, } = props; return (
+
+ {!processing && interfaces && +
+
+
+ + + + {renderInterfaces(interfaces)} + +
+
+ {interfaceValue && +
+ {renderInterfaceValues(interfaces[interfaceValue])} +
+ } +
+ } +
+
@@ -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' }), diff --git a/client/src/components/Settings/Dhcp/index.js b/client/src/components/Settings/Dhcp/index.js index 4b4eea67..e0317cd7 100644 --- a/client/src/components/Settings/Dhcp/index.js +++ b/client/src/components/Settings/Dhcp/index.js @@ -61,6 +61,8 @@ class Dhcp extends Component { onSubmit={this.handleFormSubmit} initialValues={dhcp.config} enabled={dhcp.config.enabled} + interfaces={dhcp.interfaces} + processing={dhcp.processingInterfaces} />
diff --git a/client/src/components/Settings/Settings.css b/client/src/components/Settings/Settings.css index f9b50007..22e15b16 100644 --- a/client/src/components/Settings/Settings.css +++ b/client/src/components/Settings/Settings.css @@ -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: ""; +} diff --git a/client/src/components/Settings/index.js b/client/src/components/Settings/index.js index aafc64e2..24e56329 100644 --- a/client/src/components/Settings/index.js +++ b/client/src/components/Settings/index.js @@ -36,6 +36,7 @@ class Settings extends Component { componentDidMount() { this.props.initSettings(this.settings); this.props.getDhcpStatus(); + this.props.getDhcpInterfaces(); } handleUpstreamChange = (value) => { diff --git a/client/src/containers/Settings.js b/client/src/containers/Settings.js index 062fc2f2..7d46b751 100644 --- a/client/src/containers/Settings.js +++ b/client/src/containers/Settings.js @@ -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, }; diff --git a/client/src/reducers/index.js b/client/src/reducers/index.js index 6f0f61d4..53ba15ca 100644 --- a/client/src/reducers/index.js +++ b/client/src/reducers/index.js @@ -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, },