Added select for listen interfaces
This commit is contained in:
committed by
Eugene Bujak
parent
5abe5af707
commit
f379d34813
@@ -19,7 +19,26 @@ class Controls extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
renderButtons(step) {
|
||||
renderPrevButton(step) {
|
||||
switch (step) {
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-secondary btn-standard btn-lg"
|
||||
onClick={this.props.prevStep}
|
||||
>
|
||||
<Trans>back</Trans>
|
||||
</button>
|
||||
);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
renderNextButton(step) {
|
||||
switch (step) {
|
||||
case 1:
|
||||
return (
|
||||
@@ -34,48 +53,30 @@ class Controls extends Component {
|
||||
case 2:
|
||||
case 3:
|
||||
return (
|
||||
<div className="btn-list">
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-secondary btn-standard btn-lg"
|
||||
onClick={this.props.prevStep}
|
||||
>
|
||||
<Trans>back</Trans>
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
className="btn btn-success btn-standard btn-lg"
|
||||
disabled={this.props.invalid || this.props.pristine}
|
||||
>
|
||||
<Trans>next</Trans>
|
||||
</button>
|
||||
</div>
|
||||
<button
|
||||
type="submit"
|
||||
className="btn btn-success btn-standard btn-lg"
|
||||
disabled={this.props.invalid || this.props.pristine}
|
||||
>
|
||||
<Trans>next</Trans>
|
||||
</button>
|
||||
);
|
||||
case 4:
|
||||
return (
|
||||
<div className="btn-list">
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-secondary btn-standard btn-lg"
|
||||
onClick={this.props.prevStep}
|
||||
>
|
||||
<Trans>back</Trans>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-success btn-standard btn-lg"
|
||||
onClick={this.props.nextStep}
|
||||
>
|
||||
<Trans>next</Trans>
|
||||
</button>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-success btn-standard btn-lg"
|
||||
onClick={this.props.nextStep}
|
||||
>
|
||||
<Trans>next</Trans>
|
||||
</button>
|
||||
);
|
||||
case 5:
|
||||
return (
|
||||
<button
|
||||
type="submit"
|
||||
type="button"
|
||||
className="btn btn-success btn-standard btn-lg"
|
||||
disabled={this.props.submitting || this.props.pristine}
|
||||
onClick={this.props.openDashboard}
|
||||
>
|
||||
<Trans>open_dashboard</Trans>
|
||||
</button>
|
||||
@@ -88,7 +89,10 @@ class Controls extends Component {
|
||||
render() {
|
||||
return (
|
||||
<div className="setup__nav">
|
||||
{this.renderButtons(this.props.step)}
|
||||
<div className="btn-list">
|
||||
{this.renderPrevButton(this.props.step)}
|
||||
{this.renderNextButton(this.props.step)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -98,9 +102,10 @@ Controls.propTypes = {
|
||||
step: PropTypes.number.isRequired,
|
||||
nextStep: PropTypes.func,
|
||||
prevStep: PropTypes.func,
|
||||
pristine: PropTypes.bool,
|
||||
openDashboard: PropTypes.func,
|
||||
submitting: PropTypes.bool,
|
||||
invalid: PropTypes.bool,
|
||||
pristine: PropTypes.bool,
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
|
||||
@@ -1,19 +1,29 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import { reduxForm, formValueSelector } from 'redux-form';
|
||||
import { Trans, withNamespaces } from 'react-i18next';
|
||||
import flow from 'lodash/flow';
|
||||
|
||||
import Tabs from '../../components/ui/Tabs';
|
||||
import Icons from '../../components/ui/Icons';
|
||||
import Controls from './Controls';
|
||||
|
||||
const Devices = () => (
|
||||
let Devices = props => (
|
||||
<div className="setup__step">
|
||||
<div className="setup__group">
|
||||
<div className="setup__subtitle">
|
||||
<Trans>install_devices_title</Trans>
|
||||
</div>
|
||||
<p className="setup__desc">
|
||||
<div className="setup__desc">
|
||||
<Trans>install_devices_desc</Trans>
|
||||
</p>
|
||||
<div className="mt-1">
|
||||
<Trans>install_devices_address</Trans>:
|
||||
</div>
|
||||
<div>
|
||||
<strong>{`${props.dnsIp}:${props.dnsPort}`}</strong>
|
||||
</div>
|
||||
</div>
|
||||
<Icons />
|
||||
<Tabs>
|
||||
<div label="Router">
|
||||
@@ -90,4 +100,28 @@ const Devices = () => (
|
||||
</div>
|
||||
);
|
||||
|
||||
export default withNamespaces()(Devices);
|
||||
Devices.propTypes = {
|
||||
dnsIp: PropTypes.string.isRequired,
|
||||
dnsPort: PropTypes.number.isRequired,
|
||||
};
|
||||
|
||||
const selector = formValueSelector('install');
|
||||
|
||||
Devices = connect((state) => {
|
||||
const dnsIp = selector(state, 'dns.ip');
|
||||
const dnsPort = selector(state, 'dns.port');
|
||||
|
||||
return {
|
||||
dnsIp,
|
||||
dnsPort,
|
||||
};
|
||||
})(Devices);
|
||||
|
||||
export default flow([
|
||||
withNamespaces(),
|
||||
reduxForm({
|
||||
form: 'install',
|
||||
destroyOnUnmount: false,
|
||||
forceUnregisterOnUnmount: true,
|
||||
}),
|
||||
])(Devices);
|
||||
|
||||
@@ -7,7 +7,6 @@ import flow from 'lodash/flow';
|
||||
|
||||
import Controls from './Controls';
|
||||
import renderField from './renderField';
|
||||
import { R_IPV4 } from '../../helpers/constants';
|
||||
|
||||
const required = (value) => {
|
||||
if (value || value === 0) {
|
||||
@@ -16,13 +15,6 @@ const required = (value) => {
|
||||
return <Trans>form_error_required</Trans>;
|
||||
};
|
||||
|
||||
const ipv4 = (value) => {
|
||||
if (value && !new RegExp(R_IPV4).test(value)) {
|
||||
return <Trans>form_error_ip_format</Trans>;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const port = (value) => {
|
||||
if (value < 1 || value > 65535) {
|
||||
return <Trans>form_error_port</Trans>;
|
||||
@@ -32,6 +24,29 @@ const port = (value) => {
|
||||
|
||||
const toNumber = value => value && parseInt(value, 10);
|
||||
|
||||
const renderInterfaces = (interfaces => (
|
||||
Object.keys(interfaces).map((item) => {
|
||||
const option = interfaces[item];
|
||||
const { name } = option;
|
||||
const onlyIPv6 = option.ip_addresses.every(ip => ip.includes(':'));
|
||||
let interfaceIP = option.ip_addresses[0];
|
||||
|
||||
if (!onlyIPv6) {
|
||||
option.ip_addresses.forEach((ip) => {
|
||||
if (!ip.includes(':')) {
|
||||
interfaceIP = ip;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<option value={interfaceIP} key={name}>
|
||||
{name} - {interfaceIP}
|
||||
</option>
|
||||
);
|
||||
})
|
||||
));
|
||||
|
||||
let Settings = (props) => {
|
||||
const {
|
||||
handleSubmit,
|
||||
@@ -39,7 +54,10 @@ let Settings = (props) => {
|
||||
interfacePort,
|
||||
dnsIp,
|
||||
dnsPort,
|
||||
interfaces,
|
||||
invalid,
|
||||
webWarning,
|
||||
dnsWarning,
|
||||
} = props;
|
||||
const dnsAddress = dnsPort && dnsPort !== 53 ? `${dnsIp}:${dnsPort}` : dnsIp;
|
||||
const interfaceAddress = interfacePort ? `http://${interfaceIp}:${interfacePort}` : `http://${interfaceIp}`;
|
||||
@@ -58,12 +76,14 @@ let Settings = (props) => {
|
||||
</label>
|
||||
<Field
|
||||
name="web.ip"
|
||||
component={renderField}
|
||||
type="text"
|
||||
className="form-control"
|
||||
placeholder="0.0.0.0"
|
||||
validate={[ipv4, required]}
|
||||
/>
|
||||
component="select"
|
||||
className="form-control custom-select"
|
||||
>
|
||||
<option value="0.0.0.0">
|
||||
<Trans>install_settings_all_interfaces</Trans>
|
||||
</option>
|
||||
{renderInterfaces(interfaces)}
|
||||
</Field>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-4">
|
||||
@@ -90,6 +110,11 @@ let Settings = (props) => {
|
||||
>
|
||||
install_settings_interface_link
|
||||
</Trans>
|
||||
{webWarning &&
|
||||
<div className="text-danger mt-2">
|
||||
{webWarning}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div className="setup__group">
|
||||
@@ -104,12 +129,14 @@ let Settings = (props) => {
|
||||
</label>
|
||||
<Field
|
||||
name="dns.ip"
|
||||
component={renderField}
|
||||
type="text"
|
||||
className="form-control"
|
||||
placeholder="0.0.0.0"
|
||||
validate={[ipv4, required]}
|
||||
/>
|
||||
component="select"
|
||||
className="form-control custom-select"
|
||||
>
|
||||
<option value="0.0.0.0" defaultValue>
|
||||
<Trans>install_settings_all_interfaces</Trans>
|
||||
</option>
|
||||
{renderInterfaces(interfaces)}
|
||||
</Field>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-4">
|
||||
@@ -129,14 +156,19 @@ let Settings = (props) => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p className="setup__desc">
|
||||
<div className="setup__desc">
|
||||
<Trans
|
||||
components={[<strong key="0">ip</strong>]}
|
||||
values={{ ip: dnsAddress }}
|
||||
>
|
||||
install_settings_dns_desc
|
||||
</Trans>
|
||||
</p>
|
||||
{dnsWarning &&
|
||||
<div className="text-danger mt-2">
|
||||
{dnsWarning}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<Controls invalid={invalid} />
|
||||
</form>
|
||||
@@ -155,17 +187,13 @@ Settings.propTypes = {
|
||||
PropTypes.string,
|
||||
PropTypes.number,
|
||||
]),
|
||||
webWarning: PropTypes.string.isRequired,
|
||||
dnsWarning: PropTypes.string.isRequired,
|
||||
interfaces: PropTypes.object.isRequired,
|
||||
invalid: PropTypes.bool.isRequired,
|
||||
initialValues: PropTypes.object,
|
||||
};
|
||||
|
||||
Settings.defaultProps = {
|
||||
interfaceIp: '192.168.0.1',
|
||||
interfacePort: 3000,
|
||||
dnsIp: '192.168.0.1',
|
||||
dnsPort: 53,
|
||||
};
|
||||
|
||||
const selector = formValueSelector('install');
|
||||
|
||||
Settings = connect((state) => {
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
}
|
||||
|
||||
.setup__desc {
|
||||
margin-bottom: 20px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,43 +1,53 @@
|
||||
import React, { Component } from 'react';
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import { reduxForm } from 'redux-form';
|
||||
import { reduxForm, formValueSelector } from 'redux-form';
|
||||
import { Trans, withNamespaces } from 'react-i18next';
|
||||
import flow from 'lodash/flow';
|
||||
|
||||
import Controls from './Controls';
|
||||
|
||||
class Submit extends Component {
|
||||
render() {
|
||||
const {
|
||||
handleSubmit,
|
||||
pristine,
|
||||
submitting,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<div className="setup__step">
|
||||
<div className="setup__group">
|
||||
<h1 className="setup__title">
|
||||
<Trans>install_submit_title</Trans>
|
||||
</h1>
|
||||
<p className="setup__desc">
|
||||
<Trans>install_submit_desc</Trans>
|
||||
</p>
|
||||
</div>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<Controls submitting={submitting} pristine={pristine} />
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
let Submit = props => (
|
||||
<div className="setup__step">
|
||||
<div className="setup__group">
|
||||
<h1 className="setup__title">
|
||||
<Trans>install_submit_title</Trans>
|
||||
</h1>
|
||||
<p className="setup__desc">
|
||||
<Trans>install_submit_desc</Trans>
|
||||
</p>
|
||||
</div>
|
||||
<form onSubmit={props.handleSubmit}>
|
||||
<Controls
|
||||
submitting={props.submitting}
|
||||
pristine={props.pristine}
|
||||
address={`http://${props.interfaceIp}`}
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
|
||||
Submit.propTypes = {
|
||||
interfaceIp: PropTypes.string.isRequired,
|
||||
interfacePort: PropTypes.number.isRequired,
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
pristine: PropTypes.bool.isRequired,
|
||||
submitting: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
const selector = formValueSelector('install');
|
||||
|
||||
Submit = connect((state) => {
|
||||
const interfaceIp = selector(state, 'web.ip');
|
||||
const interfacePort = selector(state, 'web.port');
|
||||
|
||||
return {
|
||||
interfaceIp,
|
||||
interfacePort,
|
||||
};
|
||||
})(Submit);
|
||||
|
||||
|
||||
export default flow([
|
||||
withNamespaces(),
|
||||
reduxForm({
|
||||
|
||||
@@ -29,6 +29,10 @@ class Setup extends Component {
|
||||
this.props.setAllSettings(values);
|
||||
};
|
||||
|
||||
openDashboard = () => {
|
||||
console.log('Open dashboard');
|
||||
}
|
||||
|
||||
nextStep = () => {
|
||||
if (this.props.install.step < INSTALL_TOTAL_STEPS) {
|
||||
this.props.nextStep();
|
||||
@@ -41,7 +45,7 @@ class Setup extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
renderPage(step, config) {
|
||||
renderPage(step, config, interfaces) {
|
||||
switch (step) {
|
||||
case 1:
|
||||
return <Greeting />;
|
||||
@@ -49,17 +53,20 @@ class Setup extends Component {
|
||||
return (
|
||||
<Settings
|
||||
initialValues={config}
|
||||
interfaces={interfaces}
|
||||
webWarning={config.web.warning}
|
||||
dnsWarning={config.dns.warning}
|
||||
onSubmit={this.nextStep}
|
||||
/>
|
||||
);
|
||||
case 3:
|
||||
return (
|
||||
<Auth onSubmit={this.nextStep} />
|
||||
<Auth onSubmit={this.handleFormSubmit} />
|
||||
);
|
||||
case 4:
|
||||
return <Devices />;
|
||||
case 5:
|
||||
return <Submit onSubmit={this.handleFormSubmit} />;
|
||||
return <Submit onSubmit={this.openDashboard} />;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -71,6 +78,7 @@ class Setup extends Component {
|
||||
step,
|
||||
web,
|
||||
dns,
|
||||
interfaces,
|
||||
} = this.props.install;
|
||||
|
||||
return (
|
||||
@@ -81,7 +89,7 @@ class Setup extends Component {
|
||||
<div className="setup">
|
||||
<div className="setup__container">
|
||||
<img src={logo} className="setup__logo" alt="logo" />
|
||||
{this.renderPage(step, { web, dns })}
|
||||
{this.renderPage(step, { web, dns }, interfaces)}
|
||||
<Progress step={step} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user